Linkset resizer
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Rescale every prim in an object
by Maestro Linden 20:55, 12 March 2010 (UTC)
This script uses the llGetLinkPrimitiveParams() and llSetLinkPrimitiveParamsFast() functions (introduced in server 1.38) to rescale every prim in a linkset. This script works for both nonphysical objects rezzed on a parcel and attached objects.
<lsl>
// Linkset Resizer, by Maestro Linden, 2010.03.12
// This script rescales all prims in a linkset, using a scaling factor specified
// by the user over chat. The script does some basic sanity checks (ensuring
// that each prim stays within the allowed PRIM_SIZE range of 0.01m to 10m, although
// it does *not* check the prim linkability rules, which are described in:
// http://wiki.secondlife.com/wiki/Linkability_Rules
integer LISTEN_CHANNEL=4; // channel to listen on float MIN_DIMENSION=0.01; // the minimum scale of a prim allowed, in any dimension float MAX_DIMENSION=10.0; // the maximum scale of a prim allowed, in any dimension
list link_positions; list link_scales; float min_original_scale=10.0; // minimum x/y/z component of the scales in the linkset float max_original_scale=0.0; // minimum x/y/z component of the scales in the linkset float min_rescale_factor; float max_rescale_factor;
scanLinkset() {
vector link_pos; vector link_scale; integer total_links=llGetNumberOfPrims(); integer link; link_positions=[]; link_scales=[];
for(link=1; link<=total_links; link++) { link_pos=llList2Vector(llGetLinkPrimitiveParams(link,[PRIM_POSITION]),0); link_scale=llList2Vector(llGetLinkPrimitiveParams(link,[PRIM_SIZE]),0); // determine the minimum and maximum prim scales in the linkset, // so that rescaling doesn't fail due to prim scale limitations // NOTE: the full linkability rules are _not_ checked by this script: // http://wiki.secondlife.com/wiki/Linkability_Rules if(link_scale.x<min_original_scale) min_original_scale=link_scale.x; else if(link_scale.x>max_original_scale) max_original_scale=link_scale.x; if(link_scale.y<min_original_scale) min_original_scale=link_scale.y; else if(link_scale.y>max_original_scale) max_original_scale=link_scale.y; if(link_scale.z<min_original_scale) min_original_scale=link_scale.z; else if(link_scale.z>max_original_scale) max_original_scale=link_scale.z; link_scales+=[link_scale]; link_positions+=[(link_pos-llGetRootPosition())/llGetRootRotation()]; } max_rescale_factor=MAX_DIMENSION/max_original_scale; min_rescale_factor=MIN_DIMENSION/min_original_scale;
}
rescaleLinkset(float scale) {
integer link; vector pos_to_set; vector scale_to_set; integer total_links=llGetListLength(link_positions); for(link=1; link<=total_links; link++) { scale_to_set=llList2Vector(link_scales,link-1)*scale; pos_to_set=llList2Vector(link_positions,link-1)*scale; // don't move the root prim if(link==1) llSetLinkPrimitiveParamsFast(link,[PRIM_SIZE,scale_to_set]); else { llSetLinkPrimitiveParamsFast(link,[PRIM_POSITION,pos_to_set,PRIM_SIZE,scale_to_set]); } }
}
init() {
llListen(LISTEN_CHANNEL,"",llGetOwner(),""); llOwnerSay("Say the scale that you want in channel "+(string)LISTEN_CHANNEL +" chat (e.g. \"/"+(string)LISTEN_CHANNEL+" 0.8\"), relative to the original scale."); llOwnerSay("The allowed rescaling range for this object is " +(string)min_rescale_factor+" - "+(string)max_rescale_factor);
}
default {
state_entry() { scanLinkset(); init(); }
on_rez(integer reznum) { init(); }
listen(integer channel, string name, key id, string msg) { float scale=(float)msg; if(scale<min_rescale_factor*0.999) { llOwnerSay("ERROR: Cannot rescale to "+(string)scale +". The minimum allowed rescale factor for this object is "+(string)min_rescale_factor); } else if(scale>max_rescale_factor/0.999) { llOwnerSay("ERROR: Cannot rescale to "+(string)scale +". The maximum allowed rescale factor for this object is "+(string)max_rescale_factor); } else { integer total_links=llGetListLength(link_positions); llOwnerSay("Setting "+(string)total_links+" prims to scale "+(string)scale+".."); rescaleLinkset(scale); llOwnerSay("..done"); } }
} </lsl>