Difference between revisions of "LlScaleByFactor"

From Second Life Wiki
Jump to navigation Jump to search
m (<lsl> tag to <source>)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{LSL_Function|mode=request
{{LSL_Function
|inject-2=
|inject-2=
|func_id=|func_sleep=0.0|func_energy=10.0
|func_id=|func_sleep=0.0|func_energy=10.0
Line 6: Line 6:
|p1_type=float|p1_name=scaling_factor|p1_desc=The multiplier to be used with the prim sizes and their local positions.
|p1_type=float|p1_name=scaling_factor|p1_desc=The multiplier to be used with the prim sizes and their local positions.
|func_desc=Attempts to resize the entire object by {{LSLP|scaling_factor}}, maintaining the size-position ratios of the prims.
|func_desc=Attempts to resize the entire object by {{LSLP|scaling_factor}}, maintaining the size-position ratios of the prims.
Resizing is subject to prim scale limits and linkability limits. This function can not resize the object if the linkset is physical, a pathfinding character, in a keyframed motion, or if resizing would cause the parcel to overflow.
|return_type=integer
|return_type=integer
|return_subtype=boolean
|return_subtype=boolean
|return_text=[[TRUE]] if it succeeds, [[FALSE]] if it fails.
|return_text=[[TRUE]] if it succeeds, [[FALSE]] if it fails.
|spec
|spec
|caveats
|caveats=
* Rescaling fails if the linkset is physical, a pathfinding character, in a keyframed motion, or if rescaling would cause the parcel to overflow.
*Due to floating point precision issues (often, sqrt(x*x) != x), avoid rescaling by the values returned by [[llGetMinScaleFactor]] and [[llGetMaxScaleFactor]].  To guarantee successful rescaling, use values slightly within the limits returned by those functions.
* Due to floating point precision issues (because sqrt(x*x) != x), avoid rescaling by the values returned by [[llGetMinScaleFactor]] and [[llGetMaxScaleFactor]].  To guarantee successful rescaling, use values slightly within the limits returned by those functions).
|constants
|constants
|examples
|examples=
<source lang="lsl2">//  Touching this script causes the object to double or halve in size.
 
integer growing;
 
default
{
    state_entry()
    {
        llSay(PUBLIC_CHANNEL, "Touch to toggle scale.");
    }
 
    touch_start(integer num_detected)
    {
        growing = !growing;
 
        float min_factor = llGetMinScaleFactor();
        float max_factor = llGetMaxScaleFactor();
 
        llSay(PUBLIC_CHANNEL, "min_scale_factor = " + (string)min_factor
                            + "\nmax_scale_factor = " + (string)max_factor);
 
        integer success;
 
        if (growing) success = llScaleByFactor(2.0);
        else        success = llScaleByFactor(0.5);
 
        if (!success) llSay(PUBLIC_CHANNEL, "Scaling failed!");
    }
}</source>
|helpers
|helpers
|also_functions=
|also_functions=
Line 30: Line 60:
|cat5
|cat5
|deepnotes=This function is roughly equivalent to the following:
|deepnotes=This function is roughly equivalent to the following:
<lsl>
<source lang="lsl2">
float VectorAbsStatistics(integer flag, vector a){
float VectorAbsStatistics(integer flag, vector a){
     return llListStatistics(flag, [llFabs(a.x), llFabs(a.y), llFabs(a.z)]);
     return llListStatistics(flag, [llFabs(a.x), llFabs(a.y), llFabs(a.z)]);
Line 37: Line 67:
integer ScaleByFactor(float scale) {
integer ScaleByFactor(float scale) {
     vector root = llGetScale() * scale;
     vector root = llGetScale() * scale;
     if(VectorAbsStatistics(LIST_STAT_MAX, root) > 64 || VectorAbsStatistics(LIST_STAT_MIN, root) < 0.01 || scale <= 0) return ERR_MALFORMED_PARAMS;
 
     if (VectorAbsStatistics(LIST_STAT_MAX, root) > 64
        || VectorAbsStatistics(LIST_STAT_MIN, root) < 0.01
        || scale <= 0)
    {
        return ERR_MALFORMED_PARAMS;
    }


     integer prims = llGetNumberOfPrims();
     integer prims = llGetNumberOfPrims();
     list set = [PRIM_LINK_TARGET, prims > 1, PRIM_SIZE, root];
     list set = [PRIM_LINK_TARGET, prims > 1, PRIM_SIZE, root];
   
 
     if(prims > 1) {
     if (prims > 1) {
         list get = [];
         list get = [];
         integer count = prims;
         integer count = prims;
Line 52: Line 88:
         do {
         do {
             vector size = llList2Vector(get, ++count) * scale;
             vector size = llList2Vector(get, ++count) * scale;
             vector pos = llList2Vector(get, ++count) * scale;
             vector pos = llList2Vector(get, ++count) * scale;
             if(VectorAbsStatistics(LIST_STAT_MAX, size) > 64 || VectorAbsStatistics(LIST_STAT_MIN, size) < 0.01 || VectorAbsStatistics(LIST_STAT_MAX, pos) > 54 )
 
             if (VectorAbsStatistics(LIST_STAT_MAX, size) > 64
                || VectorAbsStatistics(LIST_STAT_MIN, size) < 0.01
                || VectorAbsStatistics(LIST_STAT_MAX, pos) > 54 )
            {
                 return ERR_MALFORMED_PARAMS;
                 return ERR_MALFORMED_PARAMS;
             set += [PRIM_LINK_TARGET, prims, PRIM_POS_LOCAL, pos, PRIM_SIZE, size];
            }
         } while(--prims > 1);
 
             set += [PRIM_LINK_TARGET, prims,
                        PRIM_POS_LOCAL, pos,
                        PRIM_SIZE, size];
         } while(--prims > 1);
     }
     }
     llSetPrimitiveParams(set);
     llSetPrimitiveParams(set);
     return TRUE;
     return TRUE;
}
}
</lsl>
</source>
|history=
|history=
*Mentioned in [[Simulator_User_Group/Transcripts/2013.12.10]]
*Mentioned in [[Simulator_User_Group/Transcripts/2013.12.10]]
*Mentioned in [[Simulator_User_Group/Transcripts/2013.12.17]]
*Mentioned in [[Simulator_User_Group/Transcripts/2013.12.17]]
}}
}}

Latest revision as of 14:42, 22 January 2015

Summary

Function: integer llScaleByFactor( float scaling_factor );

Attempts to resize the entire object by scaling_factor, maintaining the size-position ratios of the prims.

Resizing is subject to prim scale limits and linkability limits. This function can not resize the object if the linkset is physical, a pathfinding character, in a keyframed motion, or if resizing would cause the parcel to overflow.
Returns a boolean (an integer) TRUE if it succeeds, FALSE if it fails.

• float scaling_factor The multiplier to be used with the prim sizes and their local positions.

Caveats

  • Due to floating point precision issues (often, sqrt(x*x) != x), avoid rescaling by the values returned by llGetMinScaleFactor and llGetMaxScaleFactor. To guarantee successful rescaling, use values slightly within the limits returned by those functions.
All Issues ~ Search JIRA for related Bugs

Examples

//  Touching this script causes the object to double or halve in size.

integer growing;

default
{
    state_entry()
    {
        llSay(PUBLIC_CHANNEL, "Touch to toggle scale.");
    }

    touch_start(integer num_detected)
    {
        growing = !growing;

        float min_factor = llGetMinScaleFactor();
        float max_factor = llGetMaxScaleFactor();

        llSay(PUBLIC_CHANNEL, "min_scale_factor = " + (string)min_factor
                            + "\nmax_scale_factor = " + (string)max_factor);

        integer success;

        if (growing) success = llScaleByFactor(2.0);
        else         success = llScaleByFactor(0.5);

        if (!success) llSay(PUBLIC_CHANNEL, "Scaling failed!");
    }
}

See Also

Deep Notes

This function is roughly equivalent to the following:

float VectorAbsStatistics(integer flag, vector a){
    return llListStatistics(flag, [llFabs(a.x), llFabs(a.y), llFabs(a.z)]);
}

integer ScaleByFactor(float scale) {
    vector root = llGetScale() * scale;

    if (VectorAbsStatistics(LIST_STAT_MAX, root) > 64
        || VectorAbsStatistics(LIST_STAT_MIN, root) < 0.01
        || scale <= 0)
    {
        return ERR_MALFORMED_PARAMS;
    }

    integer prims = llGetNumberOfPrims();
    list set = [PRIM_LINK_TARGET, prims > 1, PRIM_SIZE, root];

    if (prims > 1) {
        list get = [];
        integer count = prims;
        do {
            get += [PRIM_LINK_TARGET, count, PRIM_SIZE, PRIM_POS_LOCAL];
        } while(--count);
        get = llGetPrimitiveParams(get);
        count = 0;
        do {
            vector size = llList2Vector(get, ++count) * scale;
            vector pos  = llList2Vector(get, ++count) * scale;

            if (VectorAbsStatistics(LIST_STAT_MAX, size) > 64
                || VectorAbsStatistics(LIST_STAT_MIN, size) < 0.01
                || VectorAbsStatistics(LIST_STAT_MAX, pos) > 54 )
            {
                return ERR_MALFORMED_PARAMS;
            }

            set += [PRIM_LINK_TARGET, prims,
                        PRIM_POS_LOCAL, pos,
                        PRIM_SIZE, size];
        } while(--prims > 1);
    }
    llSetPrimitiveParams(set);
    return TRUE;
}

History

Search JIRA for related Issues

Signature

function integer llScaleByFactor( float scaling_factor );