Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Build in symmetry and revolution

Rohacan Hirons
Registered User
Join date: 13 Jun 2007
Posts: 10
10-25-2007 07:20
Hello,

a lot of my friends builder would like a script able to copy in symmetry their build.
I made a script that work, but there is still a problem when a prim as a revolution biger than 1, the cut path fix it most of the time, but it happens that a cut path negative is necessary. But cut path are limited from 0 to 1, would it be possible to autorise a cut path from -1 to 1 ? It would also allow to open a prim from any place, which would be very accommodating for the cubes prim too.

Thanks
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
10-25-2007 07:33
Being able to use negative cut values would be incredibly useful. It would make it possible to create doors using hollowed cubes! Sounds a silly thing but, for low-prim building, very handy.
_____________________
Computer (Mac Pro):
2 x Quad Core 3.2ghz Xeon
10gb DDR2 800mhz FB-DIMMS
4 x 750gb, 32mb cache hard-drives (RAID-0/striped)
NVidia GeForce 8800GT (512mb)
Rohacan Hirons
Registered User
Join date: 13 Jun 2007
Posts: 10
10-26-2007 00:36
I made more test, I have to fix it with cut path only when revolution isn't an integer, with 1, 2, 3 or 4 it's ok.
I have find an other way to fix it, with rotation, but this work only when top shear x and y are set to "0" :-/

Edit ***************************
More test.... When I change cut path to fix the problem and taper x or y isn't set to 0, the symmetry isn't ok :-(
Is there any way to make the exact symmetry of a prim that use revolution ? (excepted integer values, 1, 2, 3 or 4)

(sorry for my poor english ;-) )
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
10-26-2007 02:19
There is a field on the top, I think just below the Cut fields, that you can enter a negative value into and reverse the direction of the helix. This is how you can make symmetric tori.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
Rohacan Hirons
Registered User
Join date: 13 Jun 2007
Posts: 10
10-26-2007 02:24
I know this but just reverse the direction is not enought.
I want to make the exact symmetry of a prim that use revolution, top shear, taper, cut path, profil cut,...

Try this :
make a tori, set taper and top shear values to 0. Set revolution to 1.11 for example, copy the prim and reverse the direction (0.52 => -0.52) you'll have to turn the prim by 180° on x and z axes (<45,45,45> => <225,45,225> for example, or in script : llGetRot()*llEuler2Rot(<180,0,180>*DEG_TO_RAD) ) cause if you don't turn it you'll have problem with profile cut values (if not set to B=0 and E=1)
=> you'll see that's not the exact symmetry of the first prim

One solution is to turn the second prim, it's ok with top shear values set to 0, but if you try with top shear x set to 0.5 for example, you'll see there is a problem with top shear now
An other solution is to change the cut path values, it's ok but only if taper values are set to 0. And if taper values are set to 0 it happens that we need a negative value (impossible)

=> Each solution make a new problem :-/
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
10-26-2007 05:57
Try this on for size (just put a prim called "Mirror" in the vicinity):

CODE

//================================================== ==========================
// Prim Mirroring Script Set
// Written by Jeffrey Gomez
//
// Permissions Granted to Edit, Copy, Transfer, and Sell this script
// to any user, so long as this comment set remains intact, and is
// granted WITHOUT ANY WARRANTY. USE AT OWN RISK. And enjoy. =]
//
//
// Original Date of Creation: March 8th, 2005
// Last Date of Revision: January 9th, 2005
//
// Any unauthorized or illegal usage of this script, as dictated by
// International Laws of Copyright or Linden Labs voids any license to use
// this script. Creator of this script is not responsible for said use.
//
// So please, don't come after me. =)
//
//
// Forum Thread URL(s):
// http://forums.secondlife.com/showthread.php?t=38165
//
//
// Script Purpose and Usage:
// This script is used to mirror prims. That's about it!
//
// To use this script set place the Prim Mirror Code in a second prim.
// That's it! Now when you want to mirror something (relative to this second
// prim), merely drop the appropriate Mirror Code into the item (primitive)
// that you wish to mirror. The script will do the work for you.
//
// You may rotate the mirror prim around to get different angles, or scale it
// to get different sizes of mirroring. Note scaling appears odd for this -
// that's a factor of how prims work, so don't blame me!
//
// Script Limitations:
// - This Script DOES NOT support Prim Torturing in ANY form.
//================================================== ==========================




//====================== Constants.Begin =====================

vector AXIS = <0,1,0>; // Defines axis to mirror (X,Y,Z). Checks Booleans only!
float RANGE = 30.0; // Defines range of sensor for mirroring.
string KEY = // Key value for sensor
"";

string NAME = // Name value for sensor
"Mirror";

string MESSAGE = // Error message if not in range.
"Hey! You need to have the mirror rezzed and nearby to use this! How else do I know what to mirror against? Touch to continue.";

//====================== Constants.End =====================




//====================== Global_Variables.Begin =====================

vector pos; // Current Prim's Position
rotation rot; // Current Prim's Rotation
vector size; // Current Prim's Scale
integer type; // Current Prim's Prim Type
integer holeshape; // Current Prim's Hollow Shape
float hollow; // Current Prim's Hollow Size
vector holesize; // Current Prim's Wrap Radius
vector cut; // Current Prim's Cut
vector twist; // Current Prim's Twist
vector topsize; // Current Prim's Top Size
vector topshear; // Current Prim's Top Shear
vector dimple; // Current Prim's Dimple
vector advancedcut; // Current Prim's Advanced Cut
vector taper; // Current Prim's Taper
float revolutions; // Current Prim's Number of Revolutions
float radiusoffset; // Current Prim's Radius Delta
float skew; // Current Prim's Skew

//====================== Global_Variables.End =====================




//====================== Global_Functions.Begin =====================

// GetParams: Fills global variable namespaces with current primitive params
GetParams()
{
// Dump our params to a list and return ...
list params = llGetPrimitiveParams([PRIM_POSITION,PRIM_ROTATION,PRIM_SIZE,PRIM_TYPE]);


pos = llList2Vector(params,0); // ... position...
rot = llList2Rot(params,1); // ... rotation ...
size = llList2Vector(params,2); // ... scale ...
type = llList2Integer(params,3); // ... type ...
holeshape = llList2Integer(params,4); // ... holeshape ...
cut = llList2Vector(params,5); // ... cut ...
hollow = llList2Float(params,6); // ... hole amount ...
twist = llList2Vector(params,7); // ... twist ...


// ... and use the type to check the next series of operations
if(type < 3) // If this is a box, cylinder, or prism, return ...
{
topsize = llList2Vector(params,8); // ... top size ...
topshear = llList2Vector(params,9); // ... and top shear.
}
else if(type == 3) // If this is a sphere, return...
{
dimple = llList2Vector(params,8); // ... dimple.
}
else if(type > 3) // If this is a tube, torus, or ring, return ...
{
holesize = llList2Vector(params,8); // ... hole size ...
topshear = llList2Vector(params,9); // ... top shear ...
advancedcut = llList2Vector(params,10); // ... advanced cut ...
taper = llList2Vector(params,11); // ... taper ...
revolutions = llList2Float(params,12); // ... revolutions ...
radiusoffset = llList2Float(params,13); // ... radius delta ...
skew = llList2Float(params,14); // ... and skew.
}
}

//====================== Global_Functions.End =====================




//====================== State_Functions.Begin =====================


default
{
sensor(integer total_number) // Sensor_Event.begin
{

// Local_Variables.begin

integer i; // Top level loop count
integer j; // Nested loop count
vector relPos; // Relative frame position
rotation relRot; // Relative frame rotation
vector relRot2; // Rotation as a Euler
integer count = // Sums booleans for flip loops
llAbs((integer)AXIS.x) + llAbs((integer)AXIS.y) + llAbs((integer)AXIS.z);

// Local_Variables.end



// Statements.begin

GetParams(); // Calls GetParams

for(i = 0; i < total_number; ++i) // Sensor_Loop.begin
{
if(llDetectedGroup(i)) // Group_If.begin
{
// Gets position relative to mirror
relPos = (pos - llDetectedPos(i)) / llDetectedRot(i);

// Gets rotation relative to mirror
relRot = rot / llDetectedRot(i);

// Stores this rotation as a Euler
relRot2 = llRot2Euler(relRot);

// Box, Cylinder, Prism:
if(type < 3)
{
for(j = 0; j < count; ++j) // Nest_Loop.begin
{
// Flips stuff based on number of times mirroring
cut = <1 - cut.y, 1 - cut.x, 0>;
topshear = <topshear.y,topshear.x,0>;
topsize = <topsize.y,topsize.x,0>;
twist *= -1;
size = <size.y,size.x,size.z>;
} // Nest_Loop.end

if(AXIS.x) // If X Axis option is set...
{
relPos.x *= -1;
relRot2.y *= -1;
relRot2.z *= -1;
relRot2 = llRot2Euler(<0.00000, 0.00000, 0.70711, 0.70711> * llEuler2Rot(relRot2));
}
if(AXIS.y) // If Y Axis option is set...
{
relPos.y *= -1;
relRot2.x *= -1;
relRot2.z *= -1;
relRot2 = llRot2Euler(<0.00000, 0.00000, -0.70711, 0.70711> * llEuler2Rot(relRot2));
}
if(AXIS.z) // If Z Axis option is set...
{
relPos.z *= -1;
relRot2.x *= -1;
relRot2.y *= -1;
relRot2 = llRot2Euler(<-0.70711, -0.70711, -0.00000, 0.00000> * llEuler2Rot(relRot2));
}


if(type == 2 || type == 1) // If this is a cylinder or prism:
{
for(j = 0; j < count; ++j) // Nest_Loop.begin
{
topshear = <topshear.y,-1 * topshear.x,0>;
topsize = <topsize.y,topsize.x,0>;
relRot2.z += PI_BY_TWO;
size = <size.y,size.x,size.z>;
} // Nest_Loop.end
}
}
// Sphere:
else if(type == 3)
{
for(j = 0; j < count; ++j) // Nest_Loop.begin
{
cut = <1 - cut.y, 1 - cut.x, 0>;
twist = <twist.y,twist.x,0>;
} // Nest_Loop.end

if(AXIS.x) // If X Axis option is set...
{
relPos.x *= -1;
relRot2.z *= -1;
relRot2.y *= -1;
relRot2 = llRot2Euler(<-0.00000, -1.00000, -0.00000, 0.00000> * llEuler2Rot(relRot2));
}
if(AXIS.y) // If Y Axis option is set...
{
relPos.y *= -1;
relRot2.x *= -1;
relRot2.z *= -1;
relRot2 = llRot2Euler(<1.00000, -0.00000, -0.00000, 0.00000> * llEuler2Rot(relRot2));
}
if(AXIS.z) // If Z Axis option is set...
{
relPos.z *= -1;
relRot2.x *= -1;
relRot2.y *= -1;
}
}
// Torus, tube, ring:
else if(type > 3)
{
for(j = 0; j < count; ++j) // Nest_Loop.begin
{
cut = <1 - cut.y, 1 - cut.x, 0>;
twist = <twist.y,twist.x,0>;
topshear = <topshear.x * -1,topshear.y * -1,0>;
taper *= -1;
radiusoffset *= -1;
skew *= -1;
} // Nest_Loop.end

if(AXIS.x) // If X Axis option is set...
{
relPos.x *= -1;
relRot2.y *= -1;
relRot2.y += PI;
}
if(AXIS.y) // If Y Axis option is set...
{
relPos.y *= -1;
relRot2.x *= -1;
relRot2.x += PI;
relRot2.y *= -1;
}
if(AXIS.z) // If Z Axis option is set...
{
relPos.z *= -1;
relRot2.x *= -1;
relRot2 += <PI,PI,PI>;
}
}

// Set back the relative rotation
relRot = llEuler2Rot(relRot2);

// Set the sim-level position
pos = llDetectedPos(i) + (relPos * llDetectedRot(i));

// Set the sim-level rotation
rot = relRot * llDetectedRot(i);


// Uncomment for items exceeding 10m
// NOTE you may need to take globals into account!

while(llGetPos() != pos)
llSetPos(pos);


if(type < 3) // Box, Cylinder, Prism:
{
llSetPrimitiveParams([PRIM_POSITION,pos,PRIM_ROTATION,rot,PRIM_SIZE,size ,PRIM_TYPE,type,holeshape,cut,hollow,twist,topsize ,topshear]);
}
else if(type == 3) // Sphere:
{
llSetPrimitiveParams([PRIM_POSITION,pos,PRIM_ROTATION,rot,PRIM_SIZE,size ,PRIM_TYPE,type,holeshape,cut,hollow,twist,dimple]);
}
else if(type > 3) // Tube, Torus, Ring:
{
llSetPrimitiveParams([PRIM_POSITION,pos,PRIM_ROTATION,rot,PRIM_SIZE,size ,PRIM_TYPE,type,holeshape,cut,hollow,twist,holesize,topshear,advancedcut,taper,revolutions,radiusoffset,skew]);
}

// If we got here, remove this script from inventory
llRemoveInventory(llGetScriptName());

// Statements.end

} // Group_If.end

} // Sensor_Loop.end

} // Sensor_Event.end


state_entry() // Always called at start of script
{
llSensor(NAME,KEY,ACTIVE | PASSIVE, RANGE, TWO_PI); // Call sensor
}


touch_start(integer total_number) // Frustration mode catcher
{
llSensor(NAME,KEY,ACTIVE | PASSIVE, RANGE, TWO_PI); // Call sensor
}


no_sensor() // Called if mirror not in range
{
llOwnerSay(MESSAGE); // If not found, send the owner a cute little message
}
}
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
Rohacan Hirons
Registered User
Join date: 13 Jun 2007
Posts: 10
10-26-2007 07:02
Thanks, but my script work better ;-)

You build your object, put my script in each prim, rez the mirror and touch it, no need to unlink all pieces, the symmetry is rezzed on the other side of the mirror, like if you look in a real mirror. All works, textures (except a little default with some taper values), colors, size, twist, ... The only big problem is with revolution, and with your script there is the same problem in the symmetrie, if revolution isn't an integer value the symmetric prim isn't an exact symmetry of the first prim :-/
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
10-26-2007 07:34
Oh, that's not my script. But I can modify it a bit and make it use a looped llSetLinkPrimitiveParams so that it can mirror whole linksets in one pass. No need to do tedious script-dropping :P

I'll look into the problem more closely anyway, thanks for bringing it up.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
Rohacan Hirons
Registered User
Join date: 13 Jun 2007
Posts: 10
10-26-2007 10:04
From: Jesrad Seraph
Oh, that's not my script. But I can modify it a bit and make it use a looped llSetLinkPrimitiveParams so that it can mirror whole linksets in one pass. No need to do tedious script-dropping :P

I'll look into the problem more closely anyway, thanks for bringing it up.


Ok, but how will you get linked params ? There is no function llGetLinkPrimitiveParams()
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
10-27-2007 04:37
Well, there ought to be one :o
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
Rohacan Hirons
Registered User
Join date: 13 Jun 2007
Posts: 10
10-28-2007 00:08
From: Jesrad Seraph
Well, there ought to be one :o


The only way to get all params of linked parts is to put a script in each part. I had tryed with a looped llGiveInventory(child,"script";) but the script in all children is inactive, and there is no function for the script in the main prim to active a script in a linked part :-/

I'll certainly make a hud as other build tools, user will directly rez prim with my script in

Many people want this function, llGetLinkPrimitiveParams(), but many others (silly ? lol) think that it isn't a good idea :
https://jira.secondlife.com/browse/SVC-224