Linkset resizer

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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.

// 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;
integer listener;
  
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()
{
   llListenRemove(listener);
   listener=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");
       }
   }
}