ChangeLog

9 November 2014

  • Fix for root scaling.

1 November 2014

  • Code maintenance.

Introduction

This script was tested and works on OpenSim version 0.7.4!

The notable difference between this script and Briliant Scientist's resize script is that I do not store a list of sizes and positions but perform the resize on the fly. Of course, a regrettable side-effect is that by using this script, you do not have a revert or restore option to put the size of the prim back the way it was. Consequently, make sure you create a backup of the object you are manipulating, in case something goes wrong.

Overview of Features

All the options in one single pane.

  • One of the limitations that we have found with resizer scripts, in particular when having to resize attachments and clothes, is that there is a fixed list of ratios to resize by: sometimes that little +.05 resize is just insufficient and you just want to be able to specify a +.02 instead which would work better in your case.

This script solves that problem by adding the [ + ] and [ - ] options which increment or decrement all the button values by .01. That is, although one of the default sizes is +.05, you can press the [ - ] button and all the values will be pulled down by .01 so that you will get a +.04 button.

  • When creating a large object or using an in-world resale generator, you sometimes want to change the name or the description of the primitives along with it.
  • The script does not bound the resize and rescale values to any value.

Originally, we wanted to be able to crunch objects like we did with Briliant Scientist's script, in order to be able to compress and object even if a primitive in the link set has reached its minimal value. It is a good idea to keep the object backed-up in case you have not achieved the desired effect. The script is meant as a tool for builders and not a script that you should incorporate into a product since there are no fail-proof safety mechanisms in place.

Programming Notes

  • One problem when using my minimalist coding style, is that there are two options [ + ] and [ - ] which, for each, a loop had to be executed in order to increment or decrement the value buttons. The easiest solution is to simply write the "similar" loop twice in an if-clause, once for [ + ] and once for [ - ]. We did not like that because, in effect, we would be duplicating code just to decrease a value instead of increase. The best solution was the following:
        // For both cases of + and -
        if(strb == "[ + ]" || strb == "[ - ]") {
            // We get the sign of the operation, concatenate the sign
            // with the string of the value we want to modify with
            // and then we block-cast evertying to float. Cowabunga!
            float mod = (float)(llGetSubString(strb, 2, 2) + (string).01);

which uses llGetSubString to extract the + or - sign from the strb string (yes, just the character as a string). It then concatenates the + or - character with the string value of .01. So after the concatenation we get the string:

+.01

if the button contained a + character, or:

-.01

if the button contained a - character.

Which is great, because we can then cast that string to a float which will give us either the positive or negative value. For example:

(float)"-.01"

gives us the negative float value of the string -.01.

That way, we can write the loop just once and just add the value depending on the button symbol.

  • Another thing to mention is that we do not use a function to perform the operation but use a timer with the smallest possible value:
llSetTimerEvent(1.175494351E-38);

This has been discussed previously on the teleport script and the idea is that on OpenSim, for example, event handlers like state_entry go away after a while. Thus, if you are resizing an object with a lot of linked primitives, the script may just stop mid-way because the function simply timed out. We also find it more elegant to use a timer, regardless of the small value because it does not block the VM. To understand that, you can contrast sleeping using llSleep with using a timer.

Code

resizerescaleredescribe.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
float MAXIMUM_PRIMITIVE_SIZE =  64;
float MINIMUM_PRIMITIVE_SIZE = .01;
 
list menu = ["-.05", "-.10", "-.25", "+.05", "+.10", "+.25", "[✔] SECURE", "[ + ]", "[ - ]", "DELETE", "RENAME", "DESCRIBE" ];
float scale = 1;
key id = NULL_KEY;
 
default {
    state_entry() {
        if(id == NULL_KEY) return;
        integer channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(channel, "", id, "");
        llDialog(id, "\n            Resize, Rename and Redescribe.\nCreated in 2014 by Wizardry and Steamworks\n            1 November 2014: Version: 1.1", menu, channel);
    }
    touch_start(integer num) {
        id = llDetectedKey(0);
        if(id != llGetOwner()) return;
        integer channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(channel, "", id, "");
        llDialog(id, "\n            Resize, Rename and Redescribe.\nCreated in 2014 by Wizardry and Steamworks\n            1 November 2014: Version: 1.1", menu, channel);
    }
    listen(integer channel, string name, key id, string message) {
        if(message == "DELETE") {
            llRemoveInventory(llGetScriptName());
            return;
        }
        if(message == "[✔] SECURE") {
            menu = llListReplaceList(menu, (list)"[✖︎] SECURE", 6, 6);
            jump remenu;
        }
        if(message == "[✖︎] SECURE") {
            menu = llListReplaceList(menu, (list)"[✔] SECURE", 6, 6);
            jump remenu;
        }
        if(message == "RENAME") state rename;
        if(message == "DESCRIBE") state describe;
        if(message == "[ + ]" || message == "[ - ]") {
            // Check primitive limitations before chaning the ratio.
            float mod = (float)(llGetSubString(message, 2, 2) + (string).01);
            integer i = 5;
            do {
                if(llFabs(llList2Float(menu, i)) + mod < MINIMUM_PRIMITIVE_SIZE ||
                    llFabs(llList2Float(menu, i)) + mod > MAXIMUM_PRIMITIVE_SIZE)
                    jump remenu;
            } while(--i>-1);
            i = 5;
            do {
                string scaler = llGetSubString(llList2String(menu, i), 0, 0);
                string modify = llGetSubString((string)(llFabs(llList2Float(menu, i)) + mod), 0, 3);
                menu = llListReplaceList(menu, (list)(scaler + modify), i, i);
            } while(--i>-1);
            jump remenu;
        }
        if((float)message) {
            scale += (float)message;
            state resize;
        }
@remenu;
        llDialog(id, "\n            Resize, Rename and Redescribe.\nCreated in 2014 by Wizardry and Steamworks\n            1 November 2014: Version: 1.1", menu, channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state resize {
    state_entry() {
        integer i;
        if(llList2String(menu, 6) == "[✔] SECURE") {
            i = llGetNumberOfPrims();
            vector dim;
            do {
                if(i != 1) {
                    dim = scale * llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_SIZE]), 0);
                    jump check;
                }
                dim = scale * llGetScale();
@check;
                // If the resize should be performed securely, any primitive that would
                // have a size smaller than .01 or 64 on all axes will deform the object.
                if(dim.x < MINIMUM_PRIMITIVE_SIZE ||
                    dim.y < MINIMUM_PRIMITIVE_SIZE || 
                    dim.z < MINIMUM_PRIMITIVE_SIZE || 
                    dim.x > MAXIMUM_PRIMITIVE_SIZE ||
                    dim.y > MAXIMUM_PRIMITIVE_SIZE ||
                    dim.z > MAXIMUM_PRIMITIVE_SIZE) jump bail;
            } while(--i>0);
        }
        i = llGetNumberOfPrims();
        do {
            list data = llGetLinkPrimitiveParams(i, [PRIM_SIZE, PRIM_POS_LOCAL]);
            llSetLinkPrimitiveParamsFast(i, 
                [
                    PRIM_SIZE, scale * llList2Vector(data, 0), 
                    PRIM_POSITION, scale * llList2Vector(data, 1)
                ]
            );
        } while(--i>1);
        llSetScale(scale * llGetScale());
@bail;
        scale = 1;
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state rename {
    state_entry() {
        integer channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(channel, "", id, "");
        llTextBox(id, "\n            Resize, Rename and Redescribe.\nCreated in 2014 by Wizardry and Steamworks\n            1 November 2014: Version: 1.1\n\nPlease type a new name that will be given to all the linked primitives.", channel);
    }
    touch_start(integer num) {
        state default;
    }
    listen(integer channel, string name, key id, string message) {
        integer i = llGetNumberOfPrims();
        do {
            llSetLinkPrimitiveParamsFast(i, [PRIM_NAME, message]);
        } while(--i>-1);
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state describe {
    state_entry() {
        integer channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(channel, "", id, "");
        llTextBox(id, "\n            Resize, Rename and Redescribe.\nCreated in 2014 by Wizardry and Steamworks\n            1 November 2014: Version: 1.1\n\nPlease type a new description that will be given to all the linked primitives.", channel);
    }
    touch_start(integer num) {
        state default;
    }
    listen(integer channel, string name, key id, string message) {
        integer i = llGetNumberOfPrims();
        do {
            llSetLinkPrimitiveParamsFast(i, [PRIM_DESC, message]);
        } while(--i>-1);
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}

secondlife/resize_rename_redescribe.txt · Last modified: 2022/11/24 07:46 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.