Don't click here unless you want to be banned.

LSL Wiki : LibrarySenRot

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl801.us.archive.org

Functional Warper/Smooth Movement Demo


This is a warppos that is functional without using the llSetPrimitiveParams hack found in 'warppos'. As an alternative, it utilizes parallel calls to llSetPos().

There are two scripts involved. The first script controls the second script, in response to a touch. To change the rotation, you can rotate the root prim
of your object, or you can modify the openrotvec and closerotvec. Both will have some effect; you may need to play around a little to get it right.

The second script does all of the actual rotation, and there should be multiple copies of it inside your object - it's the "parallel" script. See below for details.


Here's script 1, MasterRotate:
float howlong = 2.0;
integer continuous = 0;


vector vecTime()
{
    vector tsp;
    list tsv;

    tsv = llParseString2List( llGetTimestamp(), ["T", ":", "Z"], [] );

    tsp.x = llList2Integer(tsv, 1) - 8;
    if( tsp.x < 0 ) {
        tsp.x += 24;
    }
    tsp.y = llList2Integer(tsv, 2);
    tsp.z = llList2Float(tsv, 3);

    return tsp;
}


// returns the rotation needed to get to a point.
rotation rotTo( rotation tgtrot )
{
    return llGetLocalRot() / tgtrot;
}

// sleek as shit:
smoothRot( vector vOrigin, float timetotake, rotation rotoffset, integer repeats )
{
    vector vTime = vecTime();
    vTime.z += 1.5;
    llMessageLinked( LINK_SET, 999,
        rot2str(llGetLocalRot())
        + "~" + vec2str(llRot2Axis(rotoffset))
        + "~" + (string)( llRot2Angle(rotoffset) / timetotake )
        + "~" + (string)timetotake
        + "~" + (string)repeats
        + "~" + vec2str(vOrigin)
        + "~" + vec2str(llGetLocalPos() - vOrigin)
        + "~" + vec2str(vTime)
        
        ,NULL_KEY );
}


string vec2str(vector v)
{
    return (string)v.x + "," + (string)v.y + "," + (string)v.z;
}
string rot2str(rotation r)
{
    return (string)r.x + "," + (string)r.y + "," + (string)r.z + "," + (string)r.s;
}

integer touchstate=0;

default
{
    state_entry()
    {
        llSay(0, "Smooth Rotation Tester Online.");
        if( continuous == 1 ) {
            llSetTimerEvent(10.0);
        }
    }
    
    timer()
    {
        if( touchstate == 0 ) {
            llTriggerSound("Door open", 0.8);
            smoothRot( <0,0,0>, howlong, llEuler2Rot( <0,PI_BY_TWO,0> ), (integer)howlong*4 );
            touchstate = 1;
        } else {
            llTriggerSound("Door close", 0.8);
            smoothRot( <0,0,0>, howlong, llEuler2Rot( <0,-PI_BY_TWO,0> ), (integer)howlong*4 );
            touchstate = 0;
        }
    }

    touch_start(integer total_number)
    {
        if( continuous == 0 ) {
            if( touchstate == 0 ) {
                smoothRot( <0,0,0>, howlong, llEuler2Rot( <PI_BY_TWO,0,0> ), (integer)howlong*4 );
                llSleep(1.0);
                llTriggerSound("Door open", 0.8);
                touchstate = 1;
                llSleep(4.0);
            } else {
                smoothRot( <0,0,0>, howlong, llEuler2Rot( <-PI_BY_TWO,0,0> ), (integer)howlong*4 );
                llSleep(1.0);
                llTriggerSound("Door close", 0.8);
                touchstate = 0;
                llSleep(4.0);
            }
        }
    }
}

Put that script into an object.

This second script is our parallel script. We will want multiple copies of it in each prim that is going to be rotating.

The names of the scripts must be the same except with a space and a number after them, for instance:

SmoothRotate 1
SmoothRotate 2
SmoothRotate 3
... etc

I'd put at least 4 scripts in, you can use as many as you like though. Play around and see what works well for your object. You may have to reset the scripts when you add more or remove some, or rotation will get jumpy. You shouldn't need to change anything in this script!

SmoothRotate:
vector vecTime()
{
    vector tsp;
    list tsv;

    tsv = llParseString2List( llGetTimestamp(), ["T", ":", "Z"], [] );

    tsp.x = llList2Integer(tsv, 1) - 8;
    if( tsp.x < 0 ) {
        tsp.x += 24;
    }
    tsp.y = llList2Integer(tsv, 2);
    tsp.z = llList2Float(tsv, 3);

    return tsp;
}

float timeDiffNow( vector vTarget )
{
    vector vTime = vecTime();
    return (vTarget.x - vTime.x)*3600.0 + (vTarget.y - vTime.y) * 60.0 + (vTarget.z - vTime.z);
}

vector str2vec(string s)
{
    list l;
    l = llParseString2List( s, [","], [] );
    return < llList2Float(l, 0), llList2Float(l, 1), llList2Float(l, 2) >;
}

rotation str2rot(string s)
{
    list l;
    l = llParseString2List(s, [","], []);
    return < llList2Float(l, 0), llList2Float(l, 1), llList2Float(l, 2), llList2Float(l, 3) >;
}

integer scriptid;
integer scriptcount;
countScripts()
{
    integer invcount = llGetInventoryNumber(INVENTORY_SCRIPT);
    integer i;
    string myfirstname = llList2String( llParseString2List(llGetScriptName(), [" "], []), 0 );
    string ofirstname;
    
    scriptcount=0;
    for( i = 0 ; i < invcount; ++i ) {
        ofirstname = llList2String( llParseString2List(llGetInventoryName(INVENTORY_SCRIPT, i), [" "], []), 0 );
        if( ofirstname == myfirstname ) {
            scriptcount++;
        }
    }
}

default {
    state_entry()
    {
        scriptid = llList2Integer( llParseString2List(llGetScriptName(), [" "], []), 1 );
        countScripts();
    }
    timer()
    {
    }
    link_message( integer sp, integer num, string str, key id )
    {
        if( num == 999 ) {
            list lMsg = llParseString2List(str, ["~"], []);
            rotation rStartRot;
            float fAnglesPerSec;
            vector vAxis;
            vector vStartTime;
            float fTimeToTake;
            integer repeats;
            integer count;
            vector basicoffset = llGetLocalPos();
            float secs;
    
            rStartRot = str2rot( llList2String(lMsg, 0) );
            vAxis = str2vec( llList2String(lMsg, 1) );
            fAnglesPerSec = llList2Float(lMsg,2);
            fTimeToTake = llList2Float(lMsg,3);
            repeats = llList2Integer(lMsg,4);
            vector vOrigin = str2vec( llList2String(lMsg,5) );
            vector vArmVector = llGetLocalPos() - vOrigin; // str2vec( llList2String(lMsg,6) ); //llGetLocalPos() - vOrigin;
            vStartTime = str2vec( llList2String(lMsg,7) );
            secs = 0.0;

            // Offset time.
            float timeperhit = fTimeToTake/(float)repeats;
            float myoffset = ( timeperhit / (float)scriptcount ) * (float)scriptid;
//            llOwnerSay((string)scriptid + ", offset = " + (string)myoffset + ", timeperhit: " + (string)timeperhit);
//            llOwnerSay("Scriptcount = " + (string)scriptcount);
            for( count = 0; count < repeats && secs < fTimeToTake; count++ ) {
                secs = -timeDiffNow( vStartTime );
                // should we be moving yet?
                while( secs < (float)count*timeperhit + myoffset ) {
                    secs = -timeDiffNow( vStartTime );
                }
//                llOwnerSay((string)scriptid + " and count = " + (string)count + " at " + (string)secs + ", minimum " + (string)(count*timeperhit+myoffset) );
                if( secs > fTimeToTake ) {
                    secs = fTimeToTake;
                }
                
                rotation rAmount = llAxisAngle2Rot( vAxis, fAnglesPerSec*secs );
//                llSetLocalRot(rTarget);
                llSetPrimitiveParams( [ PRIM_POSITION, vOrigin + vArmVector*rAmount,
                                         PRIM_ROTATION, rStartRot * rAmount / llGetRootRotation() ] );
            }
        }
    }
}



Back to your regularly scheduled programming: ScriptLibrary

<b>Update: fixed the problem in the comment below about the first script not compiling.
Comments [Hide comments/form]
The "master rotate" script does not compile when "dropped into a prim" as instructed. The "openrot" and "closerot" variables in the default state code section are not defined.
-- cpe-76-83-127-213.bak.res.rr.com (2007-06-18 08:21:46)
Attach a comment to this page: