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): //================================================== ========================== // 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  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  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 
_____________________
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  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
|