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. Any combination of scales is allowed.

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.

Its not rocket surgery

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 object in any way, other than simply repacking for sale. You may include this object as part of a sellable object in any form, including full permission. This was made with no promise of readability or assistance with modification.