User:Dora Gustafson/universal hinged motion

From Second Life Wiki
Jump to navigation Jump to search

Universal hinged motion in 8 key frames

Using llSetKeyFramedMotion()

// Universal hinged motion by Dora Gustafson, Studio Dora 2012
// will turn a box prim around one edge parallel to the prim's Y-axis
// for any prim orientation
// note that the smallest accepted time per frame is 1/9=0.11111111 and NOT 0.1
// v1.03 tuned for wiki
// v1.04 time tuning

float angleEnd=PI_BY_TWO;
float speed=0.2; // m/S
float steps=8.0; // number of Key Frames
float step=0.0;
list KFMlist=[];
vector V;
integer open=TRUE;
vector basePos;
rotation baseRot;

float motion_time( float mt)
{
    mt = llRound(45.0*mt)/45.0;
    if ( mt > 0.11111111 ) return mt;
    else return 0.11111111;
}

default
{
    state_entry()
    {
        llSetMemoryLimit(0x2000);
        llOwnerSay((string)llGetFreeMemory());
        llSetPrimitiveParams([PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);
        basePos = llGetPos();
        baseRot = llGetRot();
        vector v1 = 0.5*llGetScale()*llGetRot();
        rotation deltaRot = llEuler2Rot(< 0.0, angleEnd/steps, 0.0>);
        while ( step < steps )
        {
            V = v1*llAxisAngle2Rot(llRot2Left(llGetRot()), angleEnd*step/steps);
            V = v1*llAxisAngle2Rot(llRot2Left(llGetRot()), angleEnd*(step+1.0)/steps) - V;
            KFMlist += [V, deltaRot, motion_time(llVecMag(V)/speed)];
            step += 1.0;
        }
    }
    touch_end( integer n)
    {
        llSetKeyframedMotion( [], []);
        if ( open )
        {
            llSetPrimitiveParams([PRIM_POSITION, basePos, PRIM_ROTATION, baseRot]);
            llSetKeyframedMotion( KFMlist, []);
        }
        else
        {
            llSetKeyframedMotion( KFMlist, [KFM_MODE, KFM_REVERSE]);
        }
        open = !open;
    }
    on_rez( integer n) { llResetScript(); }
}

After editing prim position, rotation and/or size the script should be reset in order to update the motion