Table of Contents

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.

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.

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

        // 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.

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();
    }
}