Indeterminate Schism Posted May 14, 2011 Share Posted May 14, 2011 The script below allows you to set, or restore, the scaling of all prims in a linkset along selectable axis - that is, control X, Y and Z rescaling independently. Two or all axes may be selected and controlled at once if desired. This script may be controlled by menu or link-messages (see comments in script).NB: There is a major restriction on the utility of this script - all prims to be resized must be at 'cardinal point' rotations relative to the root - each axis must be 0, 90, 180 or 270 degrees. At the moment there is no known solution that will handle all rotations. // Resize Cardinal // // =============== // // Version 1.2 // By Indeterminate Schism of Script Sisters group // Developed from earlier work by Void Singer, Dora Gustafson, Brilliant Scientist, Ann Otoole, Maestro Linden // and probably others whose names have got lost in all the excitement // Independent selection of x, y, z axes for scaling linksets // Restore to original sizes/positions option (per axis) // NB: RESTRICTION - all prims must be rotated at cardinal points (0, 90, 180, 270 degrees) relative to the root prim // Menu displays maxima, current and minima scaling for each axis // Delete script menu option with confirm/cancel sub-menu // Includes menu-timeout to close menu listener // Uses hovertext to store original sizes, rotations and positions (removed when script deleted through menu) // Accepts llMessageLinked() string "RESIZE:<scale>", eg; RESIZE:<1.5, 2.0, -0.5> (checked for maxima/minima bounds before processing) // Settings may be queried with string "RESIZEQUERY" - returns string consisting of <maxima>_<current>_<minima> vectors // Global Variables // ---------------- vector Axes = ZERO_VECTOR; // Axes along which object is being resized integer Delete = FALSE; // Flag for script-delete menu string MapAxis; // Axis-mapping for the prim being calculated vector Maxima = ZERO_VECTOR; // Maximum dimensions in the object, read at state_entry integer MenuListen; // Handle to remove menu-listen vector Minima; // Minimum dimensions in the object, read at state_entry vector Scale; // Amount by which to resize each axis CloseListen(){ // Stop the timer and listener and reset the handle llSetTimerEvent(0.0); if(MenuListen){ llListenRemove(MenuListen); MenuListen = 0; } } float Map(integer Axis){ // Return the scale axis for this mapping string Use = llGetSubString(MapAxis, Axis, Axis); if("X" == Use){return Scale.x;} if("Y" == Use){return Scale.y;} if("Z" == Use){return Scale.z;} llOwnerSay("Map Failure: " + (string) MapAxis); return 1.0; } Menu(){ // 'Standard' menu buttons - 99% of the time these are the values that will be used list MenuButtons = ["Restore", "Exit", "Delete"]; string MenuMessage = "Scale:\nMax: " + (string) Maxima + "\nNow: " + (string) Scale + "\nMin: " + (string) Minima; if(Delete){ // Delete-confirmation menu MenuButtons = ["Confirm", "Cancel"]; MenuMessage = "Are you sure you want to delete this resize script?"; }else{ // Axes and scale buttons if(Axes.x){MenuButtons += ["X •"];}else{MenuButtons += ["X"];} if(Axes.y){MenuButtons += ["Y •"];}else{MenuButtons += ["Y"];} if(Axes.z){MenuButtons += ["Z •"];}else{MenuButtons += ["Z"];} MenuButtons += ["-0.05","-0.10","-0.25", "+0.05","+0.10","+0.25"]; } // Show the menu integer MenuChannel = -(integer) (llFrand(999999999.9) + 1); MenuListen = llListen(MenuChannel, "", llGetOwner(), ""); llDialog(llGetOwner(), MenuMessage, MenuButtons, MenuChannel); llSetTimerEvent(30.0); } Resize(){ // Check scaling is within maxima/minima bounds if(Scale.x < Minima.x){Scale.x = Minima.x;}else if(Scale.x > Maxima.x){Scale.x = Maxima.x;} if(Scale.y < Minima.y){Scale.y = Minima.y;}else if(Scale.y > Maxima.y){Scale.y = Maxima.y;} if(Scale.z < Minima.z){Scale.z = Minima.z;}else if(Scale.z > Maxima.z){Scale.z = Maxima.z;} // Resize and position everything string Axis; integer Counter = llGetNumberOfPrims(); integer Index; vector NewPos; vector NewSize; list Originals; rotation RootRot = llGetRootRotation(); if(1 == Counter){ // Single-prim, just scale it Originals = llParseString2List(llList2String(llGetLinkPrimitiveParams(0, [PRIM_TEXT]), 0), ["?"], []); NewSize = (vector) llList2String(Originals, 0); NewSize.x *= Scale.x; NewSize.y *= Scale.y; NewSize.z *= Scale.z; llSetLinkPrimitiveParamsFast(0, [PRIM_SIZE, NewSize]); }else{ // Resize the mapped axis for each prim and then reposition it relative to the root while(Counter){ Originals = llParseString2List(llList2String(llGetLinkPrimitiveParams(Counter, [PRIM_TEXT]), 0), ["?"], []); NewSize = (vector) llList2String(Originals, 0); MapAxis = llList2String(Originals, 1); // Find the axis-mapping for this prim's rotation - don't resize the prim if at unmapped rotation if("!!!" != MapAxis){ NewSize.x *= Map(0); NewSize.y *= Map(1); NewSize.z *= Map(2); } NewPos = (vector) llList2String(Originals, 2); NewPos.x *= Scale.x; NewPos.y *= Scale.y; NewPos.z *= Scale.z; if(1 == Counter){ // Just rescale the root llSetLinkPrimitiveParamsFast(Counter--, [PRIM_SIZE, NewSize]); }else{ // Rescale and reposition everything else llSetLinkPrimitiveParamsFast(Counter--, [PRIM_SIZE, NewSize, PRIM_POSITION, NewPos]); } } } // Redisplay the menu for next command Menu(); } string RoundVec(vector In){ return "<" + (string) llRound(In.x) + "," + (string) llRound(In.y) + "," + (string) llRound(In.z) + ">"; } string TrimFloat(float In){ // Remove trailing-zeros and possible decimal point from a float string Temp = (string) In; while("0" == llGetSubString(Temp, -1, -1)){Temp = llDeleteSubString(Temp, -1, -1);} if("." == llGetSubString(Temp, -1, -1)){Temp = llDeleteSubString(Temp, -1, -1);} return Temp; } string TrimVec(vector In){ // Trim each float in a vector return "<" + TrimFloat(In.x) + "," + TrimFloat(In.y) + "," + TrimFloat(In.z) + ">"; } default{ link_message(integer FromPrim, integer Number, string Text, key UUID){ // Only the Text parameter is relevant if("RESIZEQUERY" == Text){ // Return <maxima>_<current>_<minima> vectors llMessageLinked(FromPrim, Number, (string) Maxima + "_" + (string) Scale + "_" + (string) Minima, UUID); }else if("RESIZE:" == llGetSubString(Text, 0, 6)){ // Scale to given vector Scale = (vector) llDeleteSubString(Text, 0, 6); Resize(); } } listen(integer ChannelIn, string FromName, key FromID, string Message){ // Process menu selections CloseListen(); if((float) Message){ // A numeric, therefore a scaling factor if(Axes.x){Scale.x += (float) Message;} if(Axes.y){Scale.y += (float) Message;} if(Axes.z){Scale.z += (float) Message;} Resize(); }else{ // Must be some other command if("Cancel" == Message){ // Cancel script-deletion Delete = FALSE; Menu(); }else if("Confirm" == Message){ // Delete this script, but first remove all the prim text integer Counter = llGetNumberOfPrims(); if(1 == Counter){ llSetLinkPrimitiveParamsFast(0, [PRIM_TEXT, "", ZERO_VECTOR, 0.0]); }else{ while(Counter){ llSetLinkPrimitiveParamsFast(Counter--, [PRIM_TEXT, "", ZERO_VECTOR, 0.0]); } } llOwnerSay("Script deleted"); llRemoveInventory(llGetScriptName()); }else if("Delete" == Message){ // Show delete-confirmation menu Delete = TRUE; Menu(); }else if("Exit" == Message){ // Do nothing }else if("Restore" == Message){ // Reset the sizes and positions to the original values if(Axes.x){Scale.x = 1.0;} if(Axes.y){Scale.y = 1.0;} if(Axes.z){Scale.z = 1.0;} Resize(); }else{ Message = llGetSubString(Message, 0, 0); if("X" == Message){Axes.x = !(integer) Axes.x;} else if("Y" == Message){Axes.y = !(integer) Axes.y;} else if("Z" == Message){Axes.z = !(integer) Axes.z;} Menu(); } } } state_entry(){ // Initiaisation llOwnerSay("Initialising, please wait ..."); integer Counter = llGetNumberOfPrims(); float MaxDim = 10.0; float MinDim = 0.01; if(1 == Counter){ // I don't know why anyone would use this for a single prim, but it's here anyway Maxima = llList2Vector(llGetLinkPrimitiveParams(0, [PRIM_SIZE]), 0); Minima = Maxima; llSetLinkPrimitiveParamsFast(Counter, [PRIM_TEXT, TrimVec(Maxima), ZERO_VECTOR, 0.0]); }else{ // Check each prim in the linkset - temporarily set the object to zero rotation to minimise rounding errors list AxisMap = ["<0,0,0>", "XYZ", "<0,0,90>", "YXZ", "<0,0,180>", "XYZ", "<0,0,-90>", "YXZ", "<0,90,0>", "ZYX", "<0,90,90>", "YZX", "<0,90,-180>", "ZYX", "<0,90,-90>", "YZX", "<180,0,180>", "XYZ", "<180,0,-90>", "YXZ", "<180,0,0>", "XYZ", "<-180,0,90>", "YXZ", "<0,-90,0>", "ZYX", "<0,-90,90>", "YZX", "<0,-90,-180>", "ZYX", "<0,-90,180>", "ZYX", "<0,-90,-90>", "YZX", "<90,0,0>", "XZY", "<90,0,90>", "ZXY", "<90,0,180>", "XZY", "<90,0,-90>", "ZXY", "<-90,0,180>", "XZY", "<-90,0,-90>", "ZXY", "<-90,0,0>", "XZY", "<-90,0,90>", "ZXY", "<-180,0,0>", "XYZ"]; integer Index; string LinkRot; vector LinkScale; Minima = <MaxDim, MaxDim, MaxDim>; vector RootPos = llGetPos(); rotation WasRot = llGetRot(); llSetRot(ZERO_ROTATION); while(Counter){ // Find the axis-mapping for the prim. Prim-rotation (reduced to a vector) is rounded to reduce 'insignificant' variations LinkRot = RoundVec(llRot2Euler(llList2Rot(llGetLinkPrimitiveParams(Counter, [PRIM_ROTATION]), 0) / ZERO_ROTATION) * RAD_TO_DEG); LinkScale = llList2Vector(llGetLinkPrimitiveParams(Counter, [PRIM_SIZE]), 0); Index = llListFindList(AxisMap, [LinkRot]); if(++Index){ // Valid mapping - include this in minima/maxima calculations Scale = LinkScale; MapAxis = llList2String(AxisMap, Index); LinkScale.x = Map(0); LinkScale.y = Map(1); LinkScale.z = Map(2); if(LinkScale.x < Minima.x){Minima.x = LinkScale.x;}else if(LinkScale.x > Maxima.x){Maxima.x = LinkScale.x;} if(LinkScale.y < Minima.y){Minima.y = LinkScale.y;}else if(LinkScale.y > Maxima.y){Maxima.y = LinkScale.y;} if(LinkScale.z < Minima.z){Minima.z = LinkScale.z;}else if(LinkScale.z > Maxima.z){Maxima.z = LinkScale.z;} }else{ // Mark this prim not to be resized MapAxis = "!!!"; llOwnerSay("Link " + (string) Counter + " unhandled rotation " + LinkRot + " - won't be resized"); } llSetLinkPrimitiveParamsFast(Counter, [PRIM_TEXT, TrimVec(LinkScale) + "?" + MapAxis + "?" + TrimVec((llList2Vector(llGetLinkPrimitiveParams(Counter--, [PRIM_POSITION]), 0) - RootPos) / ZERO_ROTATION), ZERO_VECTOR, 0.0]); } llSetRot(WasRot); } // Convert those to valid scaling bounds Maxima.x = MaxDim / Maxima.x; Maxima.y = MaxDim / Maxima.y; Maxima.z = MaxDim / Maxima.z; Minima.x = MinDim / Minima.x; Minima.y = MinDim / Minima.y; Minima.z = MinDim / Minima.z; Scale = <1.0, 1.0, 1.0>; llOwnerSay("Ready - touch for menu"); } timer(){ // Menu time-out llOwnerSay("Menu timed-out. Touch again to reactivate it"); Delete = FALSE; CloseListen(); } touch_start(integer HowMany){ // Show the menu to the owner if(llDetectedKey(0) == llGetOwner()){ CloseListen(); Menu(); } } } 1 1 Link to comment Share on other sites More sharing options...
Sassy Romano Posted May 15, 2011 Share Posted May 15, 2011 Hmm, fails to compile for me failing at any link with llGetLInkPrimitiveParams or llSetLinkPrimitiveParams Link to comment Share on other sites More sharing options...
Indeterminate Schism Posted May 15, 2011 Author Share Posted May 15, 2011 I'm sorry, what line do you have an error on? This has just been checked by another couple of people in response to your post and we have no problems with it. Link to comment Share on other sites More sharing options...
Sassy Romano Posted May 15, 2011 Share Posted May 15, 2011 Any of the 3 lines with llGetLinkPrimitiveParams or llSetLinkPrimitiveParams. First one is:- (86, 70) Syntax error with the cursor on the v of llGetLinkPrimitiveParams. If you want to pass me the same script inworld, i'd be interested to see what the difference is. I had an idea while offline that it was text conversion between copying and pasting and losing carriage returns but it doesn't appear to be. Link to comment Share on other sites More sharing options...
Cerise1488303085 Posted May 15, 2011 Share Posted May 15, 2011 On occasion a third party viewer will still try to do the old style client side compilation, and many viewers have old function tables that will choke on the newer functions. If you are using a TPV, especially one of the less mainstream ones, try a different viewer to make sure the server is performing the compilation. This can also happen on OpenSim servers that do not track LL function changes closely. Link to comment Share on other sites More sharing options...
Sassy Romano Posted May 15, 2011 Share Posted May 15, 2011 This is Phoenix 1050... I'll try with Viewer 2 but i'd be surprised if it won't compile in Phoenix. Link to comment Share on other sites More sharing options...
Sassy Romano Posted May 15, 2011 Share Posted May 15, 2011 Same problem in viewer 2. I don't doubt that it's a copy/paste something getting mangled problem Link to comment Share on other sites More sharing options...
Void Singer Posted May 16, 2011 Share Posted May 16, 2011 I'm not having the problem mentioned, winXPPro, FF 4x and Phoenix 908 (yeah I know I need to update) although I will note that the cursor position ending up in the middle of a fucntion name like that on a syntax error is more than a little odd.... I've never seen that happen before =/ (to make sure I counted the lines and reference positions noted above, and that's where it would place it) Link to comment Share on other sites More sharing options...
Catwise Yoshikawa Posted June 14, 2011 Share Posted June 14, 2011 I tried this and I just can get it resize to minimun size, no matter what button I press. I click and my box goes tiny ^^' Link to comment Share on other sites More sharing options...
Juggernutz Ivanovic Posted October 23, 2011 Share Posted October 23, 2011 I am getting script:Resize Cardinal 1.2] Script run-time error Math Error does this work with attachments? well, script compiles in a simple cube but then shrinks it to a .01 cube on any command. Link to comment Share on other sites More sharing options...
PeterCanessa Oh Posted November 9, 2011 Share Posted November 9, 2011 I have asked Inde (who I know RL) about this and she's emailed me this updated script. I have no idea if it works with attachments but apparently it does work for single prims, works faster in less memory and probably has added squiggle-glit, which is preferred by 8 out of 10 cats. Or something. Don't ask me, this is all tl;dr for me. Inde has severe download-limit problems at the moment (so she says) but I'll attempt to pass-on anything else that comes up here. // Resize Cardinal //// =============== //// Version 1.3// By Indeterminate Schism of Script Sisters group// Developed from earlier work by Void Singer, Dora Gustafson, Brilliant Scientist, Ann Otoole, Maestro Linden// and probably others whose names have got lost in all the excitement// Independent selection of x, y, z axes for scaling linksets// Restore to original sizes/positions option (per axis)// NB: RESTRICTION - all prims must be rotated at cardinal points (0, 90, 180, 270 degrees) relative to the root prim// Menu displays maxima, current and minima scaling for each axis// Delete script menu option with confirm/cancel sub-menu// Includes menu-timeout to close menu listener// Uses hovertext to store original sizes, rotations and positions (removed when script deleted through menu)// Accepts llMessageLinked() string "RESIZE:<scale>", eg; RESIZE:<1.5, 2.0, -0.5> (checked for maxima/minima bounds before processing)// Settings may be queried with string "RESIZEQUERY" - returns string consisting of <maxima>_<current>_<minima> vectors// v1.3 - link-messages do not cause the menu to open// Global Variables// ----------------vector Axes = ZERO_VECTOR; // Axes along which object is being resizedinteger Delete = FALSE; // Flag for script-delete menustring MapAxis; // Axis-mapping for the prim being calculatedvector Maxima = ZERO_VECTOR; // Maximum dimensions in the object, read at state_entryinteger MenuListen; // Handle to remove menu-listenvector Minima; // Minimum dimensions in the object, read at state_entryvector Scale; // Amount by which to resize each axisCloseListen(){ // Stop the timer and listener and reset the handle llSetTimerEvent(0.0); if(MenuListen){ llListenRemove(MenuListen); MenuListen = 0; }}float Map(integer Axis){ // Return the scale axis for this mapping string Use = llGetSubString(MapAxis, Axis, Axis); if("X" == Use){return Scale.x;} if("Y" == Use){return Scale.y;} if("Z" == Use){return Scale.z;} llOwnerSay("Map Failure: " + (string) MapAxis); return 1.0;}Menu(){ // 'Standard' menu buttons - 99% of the time these are the values that will be used list MenuButtons = ["Restore", "Exit", "Delete"]; string MenuMessage = "Scale:\nMax: " + (string) Maxima + "\nNow: " + (string) Scale + "\nMin: " + (string) Minima; if(Delete){ // Delete-confirmation menu MenuButtons = ["Confirm", "Cancel"]; MenuMessage = "Are you sure you want to delete this resize script?"; }else{ // Axes and scale buttons if(Axes.x){MenuButtons += ["X •"];}else{MenuButtons += ["X"];} if(Axes.y){MenuButtons += ["Y •"];}else{MenuButtons += ["Y"];} if(Axes.z){MenuButtons += ["Z •"];}else{MenuButtons += ["Z"];} MenuButtons += ["-0.05","-0.10","-0.25", "+0.05","+0.10","+0.25"]; } // Show the menu integer MenuChannel = -(integer) (llFrand(999999999.9) + 1); MenuListen = llListen(MenuChannel, "", llGetOwner(), ""); llDialog(llGetOwner(), MenuMessage, MenuButtons, MenuChannel); llSetTimerEvent(30.0);}Resize(integer IsMenu){ // Check scaling is within maxima/minima bounds if(Scale.x < Minima.x){Scale.x = Minima.x;}else if(Scale.x > Maxima.x){Scale.x = Maxima.x;} if(Scale.y < Minima.y){Scale.y = Minima.y;}else if(Scale.y > Maxima.y){Scale.y = Maxima.y;} if(Scale.z < Minima.z){Scale.z = Minima.z;}else if(Scale.z > Maxima.z){Scale.z = Maxima.z;} // Resize and position everything integer Counter = llGetNumberOfPrims(); vector NewSize; list Originals; if(1 == Counter){ // Single-prim, just scale it Originals = llParseString2List(llList2String(llGetLinkPrimitiveParams(0, [PRIM_TEXT]), 0), ["?"], []); NewSize = (vector) llList2String(Originals, 0); NewSize.x *= Scale.x; NewSize.y *= Scale.y; NewSize.z *= Scale.z; llSetLinkPrimitiveParamsFast(0, [PRIM_SIZE, NewSize]); }else{ // Resize the mapped axis for each prim and then reposition it relative to the root while(Counter){ Originals = llParseString2List(llList2String(llGetLinkPrimitiveParams(Counter, [PRIM_TEXT]), 0), ["?"], []); MapAxis = llList2String(Originals, 0); NewSize = (vector) llList2String(Originals, 1); // Find the axis-mapping for this prim's rotation - don't resize the prim if at unmapped rotation if("!!!" != MapAxis){ NewSize.x *= Map(0); NewSize.y *= Map(1); NewSize.z *= Map(2); } vector NewPos = (vector) llList2String(Originals, 2); NewPos.x *= Scale.x; NewPos.y *= Scale.y; NewPos.z *= Scale.z; if(1 == Counter){ // Just rescale the root llSetLinkPrimitiveParamsFast(Counter--, [PRIM_SIZE, NewSize]); }else{ // Rescale and reposition everything else llSetLinkPrimitiveParamsFast(Counter--, [PRIM_SIZE, NewSize, PRIM_POSITION, NewPos]); } } } // Redisplay the menu for next command unless controlled by link-message if(IsMenu){ Menu(); }}string TrimFloat(float In){ // Remove trailing-zeros and possible decimal point from a float string Temp = (string) In; while("0" == llGetSubString(Temp, -1, -1)){Temp = llDeleteSubString(Temp, -1, -1);} if("." == llGetSubString(Temp, -1, -1)){Temp = llDeleteSubString(Temp, -1, -1);} return Temp;}string TrimVec(vector In){ // Trim each float in a vector return "<" + TrimFloat(In.x) + "," + TrimFloat(In.y) + "," + TrimFloat(In.z) + ">";}default{ link_message(integer FromPrim, integer Number, string Text, key UUID){ // Only the Text parameter is relevant if("RESIZEQUERY" == Text){ // Return <maxima>_<current>_<minima> vectors llMessageLinked(FromPrim, Number, (string) Maxima + "_" + (string) Scale + "_" + (string) Minima, UUID); }else if("RESIZE:" == llGetSubString(Text, 0, 6)){ // Scale to given vector Scale = (vector) llDeleteSubString(Text, 0, 6); Resize(FALSE); llMessageLinked(FromPrim, Number, (string) Maxima + "_" + (string) Scale + "_" + (string) Minima, UUID); } } listen(integer ChannelIn, string FromName, key FromID, string Message){ // Process menu selections CloseListen(); if((float) Message){ // A numeric, therefore a scaling factor if(Axes.x){Scale.x += (float) Message;} if(Axes.y){Scale.y += (float) Message;} if(Axes.z){Scale.z += (float) Message;} Resize(TRUE); }else{ // Must be some other command if("Cancel" == Message){ // Cancel script-deletion Delete = FALSE; Menu(); }else if("Confirm" == Message){ // Delete this script, but first remove all the prim text integer Counter = llGetNumberOfPrims(); if(1 == Counter){ llSetLinkPrimitiveParamsFast(0, [PRIM_TEXT, "", ZERO_VECTOR, 0.0]); }else{ while(Counter){ llSetLinkPrimitiveParamsFast(Counter--, [PRIM_TEXT, "", ZERO_VECTOR, 0.0]); } } llOwnerSay("Script deleted"); llRemoveInventory(llGetScriptName()); }else if("Delete" == Message){ // Show delete-confirmation menu Delete = TRUE; Menu(); }else if("Exit" == Message){ // Do nothing }else if("Restore" == Message){ // Reset the sizes and positions to the original values if(Axes.x){Scale.x = 1.0;} if(Axes.y){Scale.y = 1.0;} if(Axes.z){Scale.z = 1.0;} Resize(TRUE); }else{ // Toggle selected axis Message = llGetSubString(Message, 0, 0); if("X" == Message){Axes.x = !(integer) Axes.x;} else if("Y" == Message){Axes.y = !(integer) Axes.y;} else if("Z" == Message){Axes.z = !(integer) Axes.z;} Menu(); } } } state_entry(){ // Initiaisation llOwnerSay("Initialising, please wait ..."); integer Counter = llGetNumberOfPrims(); float MaxDim = 10.0; float MinDim = 0.01; if(1 == Counter){ // I don't know why anyone would use this for a single prim, but it's here anyway Maxima = llList2Vector(llGetLinkPrimitiveParams(--Counter, [PRIM_SIZE]), 0); Minima = Maxima; llSetLinkPrimitiveParamsFast(Counter, [PRIM_TEXT, TrimVec(Maxima), ZERO_VECTOR, 0.0]); }else{ // Check each prim in the linkset - temporarily set the object to zero rotation to minimise rounding errors list AxisMap = ["<0,0,0>", "XYZ", "<0,0,90>", "YXZ", "<0,0,180>", "XYZ", "<0,0,-90>", "YXZ", "<0,90,0>", "ZYX", "<0,90,90>", "YZX", "<0,90,-180>", "ZYX", "<0,90,-90>", "YZX", "<180,0,180>", "XYZ", "<180,0,-90>", "YXZ", "<180,0,0>", "XYZ", "<-180,0,90>", "YXZ", "<0,-90,0>", "ZYX", "<0,-90,90>", "YZX", "<0,-90,-180>", "ZYX", "<0,-90,180>", "ZYX", "<0,-90,-90>", "YZX", "<90,0,0>", "XZY", "<90,0,90>", "ZXY", "<90,0,180>", "XZY", "<90,0,-90>", "ZXY", "<-90,0,180>", "XZY", "<-90,0,-90>", "ZXY", "<-90,0,0>", "XZY", "<-90,0,90>", "ZXY", "<-180,0,0>", "XYZ"]; integer Index; string LinkRot; vector LinkScale; Minima = <MaxDim, MaxDim, MaxDim>; rotation WasRot = llGetRot(); llSetRot(ZERO_ROTATION); while(Counter){ // Find the axis-mapping for the prim. Prim-rotation (reduced to a vector) is rounded to reduce 'insignificant' variations LinkScale = llRot2Euler(llList2Rot(llGetLinkPrimitiveParams(Counter, [PRIM_ROTATION]), 0) / ZERO_ROTATION) * RAD_TO_DEG; LinkRot = "<" + (string) llRound(LinkScale.x) + "," + (string) llRound(LinkScale.y) + "," + (string) llRound(LinkScale.z) + ">"; Scale = llList2Vector(llGetLinkPrimitiveParams(Counter, [PRIM_SIZE]), 0); Index = llListFindList(AxisMap, [LinkRot]); if(++Index){ // Valid mapping - include this in minima/maxima calculations MapAxis = llList2String(AxisMap, Index); LinkScale.x = Map(0); LinkScale.y = Map(1); LinkScale.z = Map(2); if(LinkScale.x < Minima.x){Minima.x = LinkScale.x;}else if(LinkScale.x > Maxima.x){Maxima.x = LinkScale.x;} if(LinkScale.y < Minima.y){Minima.y = LinkScale.y;}else if(LinkScale.y > Maxima.y){Maxima.y = LinkScale.y;} if(LinkScale.z < Minima.z){Minima.z = LinkScale.z;}else if(LinkScale.z > Maxima.z){Maxima.z = LinkScale.z;} }else{ // Mark this prim not to be resized MapAxis = "!!!"; llOwnerSay("Link " + (string) Counter + " unhandled rotation " + LinkRot + " - won't be resized"); } llSetLinkPrimitiveParamsFast(Counter, [PRIM_TEXT, MapAxis + "?" + TrimVec(LinkScale) + "?" + TrimVec((llList2Vector(llGetLinkPrimitiveParams(Counter--, [PRIM_POSITION]), 0) - llGetPos()) / ZERO_ROTATION), ZERO_VECTOR, 0.0]); } llSetRot(WasRot); } // Convert those to valid scaling bounds Maxima.x = MaxDim / Maxima.x; Maxima.y = MaxDim / Maxima.y; Maxima.z = MaxDim / Maxima.z; Minima.x = MinDim / Minima.x; Minima.y = MinDim / Minima.y; Minima.z = MinDim / Minima.z; Scale = <1.0, 1.0, 1.0>; llOwnerSay("Ready - touch for menu"); } timer(){ // Menu time-out llOwnerSay("Menu timed-out. Touch again to reactivate it"); Delete = FALSE; CloseListen(); } touch_start(integer HowMany){ // Show the menu to the owner if(llDetectedKey(0) == llGetOwner()){ CloseListen(); Menu(); } }} Link to comment Share on other sites More sharing options...
PeterCanessa Oh Posted March 26, 2012 Share Posted March 26, 2012 Version 1.4 corrects bounds errors for minima/maximum calculations. Easiest to just say replace the state_entry() event handler with the one below. I seem to have inherited this :-( state_entry(){ // Initiaisation llOwnerSay("Initialising, please wait ..."); integer Counter = llGetNumberOfPrims(); float MaxDim = 10.0; float MinDim = 0.01; if(1 == Counter){ // I don't know why anyone would use this for a single prim, but it's here anyway Maxima = llList2Vector(llGetLinkPrimitiveParams(--Counter, [PRIM_SIZE]), 0); Minima = Maxima; llSetLinkPrimitiveParamsFast(Counter, [PRIM_TEXT, TrimVec(Maxima), ZERO_VECTOR, 0.0]); }else{ // Check each prim in the linkset - temporarily set the object to zero rotation to minimise rounding errors list AxisMap = ["<0,0,0>", "XYZ", "<0,0,90>", "YXZ", "<0,0,180>", "XYZ", "<0,0,-90>", "YXZ", "<0,90,0>", "ZYX", "<0,90,90>", "YZX", "<0,90,-180>", "ZYX", "<0,90,-90>", "YZX", "<180,0,180>", "XYZ", "<180,0,-90>", "YXZ", "<180,0,0>", "XYZ", "<-180,0,90>", "YXZ", "<0,-90,0>", "ZYX", "<0,-90,90>", "YZX", "<0,-90,-180>", "ZYX", "<0,-90,180>", "ZYX", "<0,-90,-90>", "YZX", "<90,0,0>", "XZY", "<90,0,90>", "ZXY", "<90,0,180>", "XZY", "<90,0,-90>", "ZXY", "<-90,0,180>", "XZY", "<-90,0,-90>", "ZXY", "<-90,0,0>", "XZY", "<-90,0,90>", "ZXY", "<-180,0,0>", "XYZ"]; integer Index; string LinkRot; vector LinkScale; Minima = <MaxDim, MaxDim, MaxDim>; rotation WasRot = llGetRot(); llSetRot(ZERO_ROTATION); while(Counter){ // Find the axis-mapping for the prim. Prim-rotation (reduced to a vector) is rounded to reduce 'insignificant' variations LinkScale = llRot2Euler(llList2Rot(llGetLinkPrimitiveParams(Counter, [PRIM_ROTATION]), 0) / ZERO_ROTATION) * RAD_TO_DEG; LinkRot = "<" + (string) llRound(LinkScale.x) + "," + (string) llRound(LinkScale.y) + "," + (string) llRound(LinkScale.z) + ">"; Scale = llList2Vector(llGetLinkPrimitiveParams(Counter, [PRIM_SIZE]), 0); Index = llListFindList(AxisMap, [LinkRot]); if(++Index){ // Valid mapping - include this in minima/maxima calculations MapAxis = llList2String(AxisMap, Index); LinkScale.x = Map(0); LinkScale.y = Map(1); LinkScale.z = Map(2); if(LinkScale.x < Minima.x){Minima.x = LinkScale.x;} if(LinkScale.x > Maxima.x){Maxima.x = LinkScale.x;} if(LinkScale.y < Minima.y){Minima.y = LinkScale.y;} if(LinkScale.y > Maxima.y){Maxima.y = LinkScale.y;} if(LinkScale.z < Minima.z){Minima.z = LinkScale.z;} if(LinkScale.z > Maxima.z){Maxima.z = LinkScale.z;} }else{ // Mark this prim not to be resized MapAxis = "!!!"; llOwnerSay("Link " + (string) Counter + " unhandled rotation " + LinkRot + " - won't be resized"); } llSetLinkPrimitiveParamsFast(Counter, [PRIM_TEXT, MapAxis + "?" + TrimVec(LinkScale) + "?" + TrimVec((llList2Vector(llGetLinkPrimitiveParams(Counter--, [PRIM_POSITION]), 0) - llGetPos()) / ZERO_ROTATION), ZERO_VECTOR, 0.0]); } llSetRot(WasRot); } // Convert those to valid scaling bounds Maxima.x = MaxDim / Maxima.x; Maxima.y = MaxDim / Maxima.y; Maxima.z = MaxDim / Maxima.z; Minima.x = MinDim / Minima.x; Minima.y = MinDim / Minima.y; Minima.z = MinDim / Minima.z; Scale = <1.0, 1.0, 1.0>; llOwnerSay("Ready - touch for menu"); } Link to comment Share on other sites More sharing options...
Icky Spot Posted April 17, 2012 Share Posted April 17, 2012 This is a nice script, but yeah, it fails to work on linksets... only for single prims. Thanks, though. Link to comment Share on other sites More sharing options...
PeterCanessa Oh Posted April 17, 2012 Share Posted April 17, 2012 It's working for most people. In fact the first problem reported was that it didn't work for a single prim. Any clues as to how "it fails to work?" Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now