Linkset Resizer 2

From Second Life Wiki
Jump to navigation Jump to search

About

Resizer by Emma Nowhere

Yet another object resizer script. Seeing as I was the person who originally opened the JIRA for LLGetLinkPrimitiveParams I thought I should put it to good use. I like it more than the other resizer scripts out there, but of course, I'm biased. In any case, it never hurts to have more code being shared.

How to use with menu:

  1. Install this script in the root prim of a linked set of prims (aka "linkset")
  2. Type /1resizer to show the menu
  3. Hit the appropriate buttons to scale up or down the linkset
  4. Hit the "Finish" button to remove the script and finalize prim sizes

Optionally, enter the percentage directly via chat by typing /1resizer x% where x is the percentage of the original size you want to resize to.

IMPORTANT: You should always make a backup copy of the object before using this script.

Resizer

<lsl> /////////////////////////////////////////////////////////////////////////////// // Resizer // by Emma Nowhere // // Last modified: 5/30/2010 // // How to use with menu: // 1. Install this script in the root prim of a linked set of prims (aka "linkset") // 2. Type /1resizer to show the menu // 3. Hit the appropriate buttons to scale up or down the linkset // 4. Hit the "Finish" button to remove the script and finalize prim sizes // // Optionally, enter the percentage directly via chat by typing /1resizer x% // where x is the percentage of the original size you want to resize to. //

float MIN_SIZE = .01; float MAX_SIZE = 10; float MAX_DISTANCE = 10; float MIN_SCALE = .1;

integer CHANNEL = 1; integer MENU_CHANNEL = -1001;

list backupPrims = []; integer backupStored = FALSE;

float scale = 1.0;

backup() {

   if (!backupStored) {
       llOwnerSay("Backing up prim positions and sizes.");
       backupPrims = [];
       integer p = llGetNumberOfPrims();
       integer i = 0;
       vector root_pos = <0, 0, 0>;
       for (i = 1; i <= p; i++)
       {
           list params = llGetLinkPrimitiveParams(i, [PRIM_POSITION, PRIM_SIZE]);
           vector pos = llList2Vector(params, 0);
           vector size = llList2Vector(params, 1);
           if (i == 1)
           {
               root_pos = pos;
           }
           else {
               pos = pos - root_pos;
           }
           backupPrims = backupPrims + pos + size;
       }
       backupStored = TRUE;
       llOwnerSay("Prim positions and sizes backed up.");
   }

}

restore() {

   if (backupStored) {
       llOwnerSay("Restoring previously backed up positions and sizes.");
       integer p = llGetNumberOfPrims();
       integer i = 0;
       for (i = 1; i <= p; i++)
       {
           vector pos = llList2Vector(backupPrims, (i - 1) * 2);
           vector size = llList2Vector(backupPrims, ((i - 1) * 2) + 1);
           if (i == 1) {
               llSetLinkPrimitiveParamsFast(i, [PRIM_SIZE, size]);
           }
           else {
               llSetLinkPrimitiveParamsFast(i, [PRIM_POSITION, pos, PRIM_SIZE, size]);
           }
       }
       llOwnerSay("Previously backed up prim positions and sizes restored.");
   }
   scale = 1;

}

finish() {

   llOwnerSay("Deleting Resizer script.");
   llRemoveInventory(llGetScriptName()); 

}

float min(float a, float b) {

   if (a < b) return a;
   return b;

}

float max(float a, float b) {

   if (a > b) return a;
   return b;

}

float constrainMinMax(float value, float min, float max) {

   value = max(value, min);
   value = min(value, max);
   return value;

}

float constrainSize(float size) {

   return constrainMinMax(size, MIN_SIZE, MAX_SIZE);

}

float constrainDistance(float distance) {

   return min(distance, MAX_DISTANCE);

}

process() {

   backup();

   llOwnerSay("Resizing prims to " + (string)llRound(scale * 100) + "% of original size.");
   integer p = llGetNumberOfPrims();
   integer i = 0;
   for (i = 1; i <= p; i++)
   {
       vector pos = llList2Vector(backupPrims, (i - 1) * 2);
       vector size = llList2Vector(backupPrims, ((i - 1) * 2) + 1);

       size.x = constrainSize(size.x * scale);
       size.y = constrainSize(size.y * scale);
       size.z = constrainSize(size.z * scale);
       if (i == 1) {
           llSetLinkPrimitiveParamsFast(i, [PRIM_SIZE, size]);
       }
       else {
           pos = pos * scale;
           pos.x = constrainDistance(pos.x);
           pos.y = constrainDistance(pos.y);
           pos.z = constrainDistance(pos.z);
           llSetLinkPrimitiveParamsFast(i, [PRIM_POSITION, pos, PRIM_SIZE, size]);
       }
   }
   llOwnerSay("Prims resized.");

}

menu() {

   llDialog(llGetOwner(),
   "Resizer\n\nMake a backup of your object first.\n\nPlease choose an option:\n",
   ["Restore", "-", "Finish", "-1%", "-5%", "-10%", "+1%", "+5%", "+10%"], MENU_CHANNEL);

}

default {

   state_entry() 
   {
       llListen(CHANNEL, "", llGetOwner(), "");
       llListen(MENU_CHANNEL, "", llGetOwner(), "");
       llOwnerSay("Resizer Ready");
       llOwnerSay("Type /" + (string)CHANNEL + "resizer for menu.");
   }

   on_rez(integer start_param) {
       llOwnerSay("Resizer Installed");
       llOwnerSay("Type /" + (string)CHANNEL + "resizer for menu.");
   }    

   listen(integer channel, string name, key id, string message) 
   {
       if (message == "resizer") {
           menu();
       }
       else if (message == "Restore") {
           restore();
           menu();
       }
       else if (message == "Finish") {        
           finish();                    
       }
       else if (llSubStringIndex(message, "resizer") == 0) {  
           list params = llParseString2List(message, [" "], [] );
           if (llGetListLength(params) == 2) {
               string scale_param = llList2String(params, 1);
               if (llGetSubString(scale_param, -1, -1) == "%") {
                   scale = (((float)llGetSubString(scale_param, 0, -2)) / 100);
                   scale = max(scale, MIN_SCALE);
                   process();
               }
           }
       }
       else if (llGetSubString(message, -1, -1) == "%") {
           scale = scale + (((float)llGetSubString(message, 0, -2)) / 100);
           scale = max(scale, MIN_SCALE);
           process();
           menu();
       }

   }

}

</lsl>