Jump to content
Sign in to follow this  
Indeterminate Schism

Selectable-axis Resizer

Recommended Posts

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();
		}
	}
}

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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)

Share this post


Link to post
Share on other sites

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();		}	}}

 

Share this post


Link to post
Share on other sites

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");	}

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...