Difference between revisions of "Linkset Resizer 2"

From Second Life Wiki
Jump to navigation Jump to search
m (<lsl> tag to <source>)
 
(One intermediate revision by one other user not shown)
Line 30: Line 30:
== Resizer ==
== Resizer ==
<div style="padding: 0.5em">
<div style="padding: 0.5em">
<lsl>
<source lang="lsl2">
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Resizer
// Resizer
Line 105: Line 105:
         say_status("Prim positions and sizes backed up.");
         say_status("Prim positions and sizes backed up.");
     }
     }
}
restore() {
    if (backupStored) {
        say_status("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]);
            }
        }
        say_status("Previously backed up prim positions and sizes restored.");
    }
    scale = 1;
}
finish() {
    say_status("Deleting Resizer script.");
    llRemoveInventory(llGetScriptName());
}
}
   
   
Line 163: Line 137:
}
}
   
   
process() {
process(integer restore) {
     backup();
     backup();
 
     say_status("Resizing prims to " + (string)llRound(scale * 100) + "% of original size.");
     if (restore) {
        say_status("Restoring previously backed up positions and sizes.");
        scale = 1;
    }
    else {
        say_status("Resizing prims to " + (string)llRound(scale * 100) + "% of original size.");
    }
       
     integer p = llGetNumberOfPrims();
     integer p = llGetNumberOfPrims();
     integer i = 0;
     integer i = 0;
Line 174: Line 155:
         vector size = llList2Vector(backupPrims, ((i - 1) * 2) + 1);
         vector size = llList2Vector(backupPrims, ((i - 1) * 2) + 1);
   
   
         size = constrainSize(size * scale);
         if (!restore) size = constrainSize(size * scale);
   
   
         if (i == 1) {
         if (i == 1) {
Line 180: Line 161:
         }
         }
         else {
         else {
             pos = constrainDistance(pos * scale);
             if (!restore) pos = constrainDistance(pos * scale);
             llSetLinkPrimitiveParamsFast(i, [PRIM_POSITION, pos, PRIM_SIZE, size]);
             llSetLinkPrimitiveParamsFast(i, [PRIM_POSITION, pos, PRIM_SIZE, size]);
         }
         }
     }
     }
     say_status("Prims resized.");
      
    if (restore) {
        say_status("Previously backed up prim positions and sizes restored.");
    }
    else {
        say_status("Prims resized.");
    }
}
finish() {
    say_status("Deleting Resizer script.");
    llRemoveInventory(llGetScriptName());  
}
}
   
   
Line 206: Line 198:
                     scale = (((float)llGetSubString(scale_param, 0, -2)) / 100);
                     scale = (((float)llGetSubString(scale_param, 0, -2)) / 100);
                     scale = max(scale, MIN_SCALE);
                     scale = max(scale, MIN_SCALE);
                     process();
                     process(FALSE);
                 }
                 }
             }
             }
Line 213: Line 205:
     else if (channel == MENU_CHANNEL) {
     else if (channel == MENU_CHANNEL) {
         if (message == "Revert") {
         if (message == "Revert") {
             restore();
             process(TRUE);
             menu();
             menu();
         }
         }
Line 222: Line 214:
             scale = scale + (((float)llGetSubString(message, 0, -2)) / 100);
             scale = scale + (((float)llGetSubString(message, 0, -2)) / 100);
             scale = max(scale, MIN_SCALE);
             scale = max(scale, MIN_SCALE);
             process();
             process(FALSE);
             menu();
             menu();
         }
         }
Line 292: Line 284:




</lsl>
</source>
</div></div>
</div></div>
{{#vardefine:sort|Link Resizer 2}}{{LSLC|Library}}
{{#vardefine:sort|Link Resizer 2}}{{LSLC|Library}}

Latest revision as of 23:30, 24 January 2015

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.

The script below is configured to be used as a drop-in script for a user or builder that wants to resize something for themselves. If putting into a product, you may want to set START_ON_TOUCH to be TRUE so that your customers can just touch the object to start resizing. You may also want to set SAY_STATUS to FALSE so that a bunch of text doesn't get sent to the chat window (only seen by the owner, but can still be annoying to the end-user).

Resizer

///////////////////////////////////////////////////////////////////////////////
// Resizer
// by Emma Nowhere
//
// Last modified: 6/1/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.
//
// If using in a product with no other scripts, change START_ON_TOUCH below to TRUE
// so user can initiate resizing by just touching the object.
 
integer START_ON_TOUCH = FALSE;
 
// Display status messages in chat window (to owner only)
 
integer SAY_STATUS = TRUE;
 
// Channel to listen for commands on
 
integer CHAT_CHANNEL = 1;
 
// SL constraints
 
float MIN_SIZE = .01;
float MAX_SIZE = 10;
float MAX_DISTANCE = 10; 
float MIN_SCALE = .1;
 
integer MENU_CHANNEL = -1001;
 
list backupPrims = [];
integer backupStored = FALSE;
 
float scale = 1.0;
 
init_menu_channel() {
    MENU_CHANNEL = ((integer)("0x" + llGetSubString((string)llGetKey(), -8, -1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
}
 
say_status(string msg) {
    if (SAY_STATUS) llOwnerSay(msg);
}
 
backup() {
    if (!backupStored) {
        say_status("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;
        say_status("Prim positions and sizes backed up.");
    }
}
 
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;
}
 
vector constrainSize(vector size) {
    size.x = constrainMinMax(size.x, MIN_SIZE, MAX_SIZE);
    size.y = constrainMinMax(size.y, MIN_SIZE, MAX_SIZE);
    size.z = constrainMinMax(size.z, MIN_SIZE, MAX_SIZE);
    return size;
}
 
vector constrainDistance(vector delta) {
    delta.x = min(delta.x, MAX_DISTANCE);
    delta.y = min(delta.y, MAX_DISTANCE);
    delta.z = min(delta.z, MAX_DISTANCE);
    return delta;
}
 
process(integer restore) {
    backup();

    if (restore) {
        say_status("Restoring previously backed up positions and sizes.");
        scale = 1;
    }
    else {
        say_status("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);
 
        if (!restore) size = constrainSize(size * scale);
 
        if (i == 1) {
            llSetLinkPrimitiveParamsFast(i, [PRIM_SIZE, size]);
        }
        else {
            if (!restore) pos = constrainDistance(pos * scale);
            llSetLinkPrimitiveParamsFast(i, [PRIM_POSITION, pos, PRIM_SIZE, size]);
        }
    }
    
    if (restore) {
        say_status("Previously backed up prim positions and sizes restored.");
    }
    else {
        say_status("Prims resized.");
    }
}
 
finish() {
    say_status("Deleting Resizer script.");
    llRemoveInventory(llGetScriptName()); 
}
 
menu() {
    llDialog(llGetOwner(),
    "Resizer\n\nMake a backup of your object first.\n\nPlease choose an option:\n",
    ["Revert", "-", "Finish", "-1%", "-5%", "-10%", "+1%", "+5%", "+10%"], MENU_CHANNEL);
}
 
handle_message(integer channel, string name, key id, string message) 
{
    if (channel == CHAT_CHANNEL) {
        if (message == "resizer") {
            menu();
        }
        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(FALSE);
                }
            }
        }
    }
    else if (channel == MENU_CHANNEL) {
        if (message == "Revert") {
            process(TRUE);
            menu();
        }
        else if (message == "Finish") {        
            finish();                    
        }
        else if (llGetSubString(message, -1, -1) == "%") {
            scale = scale + (((float)llGetSubString(message, 0, -2)) / 100);
            scale = max(scale, MIN_SCALE);
            process(FALSE);
            menu();
        }
    }
 
}
 
default
{
    state_entry() 
    {
        if (START_ON_TOUCH) {
            // we only want a touch_start handler if we're going to use it
            // so change state rather than just testing inside touch_start
            // for START_ON_TOUCH to be true.
            state start_on_touch;
        }
        else {
            llListen(CHAT_CHANNEL, "", llGetOwner(), "");
 
            init_menu_channel();
            llListen(MENU_CHANNEL, "", llGetOwner(), "");
 
            llOwnerSay("Resizer Ready");
            llOwnerSay("Type /" + (string)CHAT_CHANNEL + "resizer for menu.");
        }
    }
 
    on_rez(integer start_param) {
        llOwnerSay("Resizer Installed");
        llOwnerSay("Type /" + (string)CHAT_CHANNEL + "resizer for menu.");
    }    
 
    listen(integer channel, string name, key id, string message) 
    {
        handle_message(channel, name, id, message);
    }
}
 
state start_on_touch
{
    state_entry() 
    {
        llListen(CHAT_CHANNEL, "", llGetOwner(), "");
 
        init_menu_channel();
        llListen(MENU_CHANNEL, "", llGetOwner(), "");
 
        llOwnerSay("Resizer Ready");
        llOwnerSay("Touch for resizer menu.");
    }
 
    on_rez(integer start_param) {
        llOwnerSay("Resizer Installed");
        llOwnerSay("Touch for resizer menu.");
    }    
 
    listen(integer channel, string name, key id, string message) 
    {
        handle_message(channel, name, id, message);
    }
 
    touch_start(integer num_detected)
    {
        menu();
    }
 
}