User:Pazako Karu/LinksetResizer

From Second Life Wiki
Jump to navigation Jump to search

This resizeObject(vector) function resizes a linkset in X,Y,Z as desired without any configuration.
The vector given is the scale of the <x,y,z> relative to the default <1.0, 1.0, 1.0> is default scale.
It requires scanLinkset() to have been run beforehand, as that's when data is saved as 'default scale'.
The 'true max' of a small item may be hilariously large; fair warning if you try 1000x, it might work.

For Non-scripters

For a working version with auto-config you can just drop into an object: Linkset Resizer w/ Menu

Code

// Linkset Resizer without Menu
// by: Pazako Karu
// This script resizes a linkset in X,Y,Z as desired without any configuration

float max_scale;
float min_scale;
vector scale = <1,1,1>;

list link_scales = [];
list link_positions = [];
scanLinkset()
{
    integer links = llGetNumberOfPrims();
    integer link;
    integer offset = (links != 1); // add 1 if more than one prim (as linksets start numbering with 1)
    list params;

    for (link = 0; link < links; ++link)
    {
        params = llGetLinkPrimitiveParams(link + offset, [PRIM_POS_LOCAL, PRIM_SIZE]);
        link_positions += llList2Vector(params, 0);
        link_scales    += llList2Vector(params, 1);
    }
    max_scale = llGetMaxScaleFactor() * 0.999999;
    min_scale = llGetMinScaleFactor() * 1.000001;
}
resizeObject(vector scale)
{
    integer links = llGetNumberOfPrims();
    integer link;
    integer offset = (links != 1);
    
    // scale the root
    llSetLinkPrimitiveParamsFast(offset, [PRIM_SIZE, notDot(scale,llList2Vector(link_scales, 0))]);
    
    // scale all but the root
    for (link = 1; link < links; link++)
    {
        llSetLinkPrimitiveParamsFast(link + offset,
            [PRIM_SIZE,      notDot(scale, llList2Vector(link_scales,    link)),
             PRIM_POS_LOCAL, notDot(scale, llList2Vector(link_positions, link))]);
    }
}
vector notDot(vector A, vector B)
{
    return <A.x*B.x, A.y*B.y, A.z*B.z>;
}
float limit(float input)
{
    if (input > max_scale) return max_scale;
    if (input < min_scale) return min_scale;
    return input;
}
default
{
    state_entry()
    {
        scanLinkset();
    }
    touch_start(integer total)
    {
        if (llDetectedKey(0) == llGetOwner())
        {
            // If a scale is unachievable, it will cap at the max and do the rest as though it weren't.
            // Uncomment whatever you like to test, or build into your own script

            // resizeObject(<0.1,0.1,0.1>); // Make 10% of original size
            // resizeObject(<10,10,10>); // Make 10x of original size
            
            // resizeObject(< 10,  1,  1>); // Stretch only X to 10 times wider
            // resizeObject(<  1, 10,  1>); // Stretch only Y to 10 times wider
            // resizeObject(<  1,  1, 10>); // Stretch only Z to 10 times wider
            
            // resizeObject(<1,1,1>); // Restore default size (from time of scan)
        }
    }
}

License

You may use, abuse, and distribute this script in any way, other than simply repacking for sale.
You may include this as part of a sellable object in any form, including full permission.
This was made with no promise of readability or assistance with modification.
Its not rocket surgery