Jump to content

llSetKeyFramedMotion() Help


Shymus Roffo
 Share

You are about to reply to a thread that has been inactive for 4571 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi, llSetKeyframedMotion is still a little glitchy, but it looks like it really can make a nice drawbridge. This would be serious overkill for a regular door, but I like the idea of a bridge you can try to rush while it is is raising :)

First, here is a picture of the bridge I tested on. I built it with the root prim at zero rotation to make life simpler, it can be moved when it's finished. The narrow blue prim on the left is the root, and serves as the hinge. I colored one side red just for reference, that will line up with the red move arrow at zero rotation. The big yellowish plank is the child.

I set the physics shape of the root prim to convex hull, to force the new style physics. You could also set some child prims to another type, whatever it takes to get the build to exist under the new style accounting.

drawbridge.jpg

 

And, here is the script I ended up using, with comments.

// After you have this all set up:// -- position the bridge where you want it, in the horizontal position.// -- reset the script to initialize it.// How far from flat to open the bridge, in degrees.  I suggest// rotating along the root's X axis as I've done here, rotating// along Y looked glitchy in my tests.vector gRaisedAngle = <75., 0., 0.>;// How long the entire open or close sequence should takefloat gSwingTime = 20.;// I don't know if this is a bug or an undocumented limit, but// llSetKeyframedMotion was stalling if I used more than a few// seconds in a single step. So, I'm going to split the motion// up into smaller pieces. This is how long each step should// run.float gStallSeconds = 5.0;// ---------------- End setup stuff ----------------// Working globalsrotation gLoweredRot;rotation gRaisedRot;rotation gFinalRot;integer gBridgeLowered = TRUE;integer gBridgeMoving = FALSE;integer gMovementSteps;list gOpenSequence;list gCloseSequence;default{    state_entry()    {        gLoweredRot = llGetRot(); // initial horizontal position        gRaisedRot = llEuler2Rot(gRaisedAngle * DEG_TO_RAD);        // garbage to split motion into shorter steps.        integer moveSteps = 1 + (integer)(gSwingTime / gStallSeconds);        float stepTime = gSwingTime / moveSteps;        vector raisedAngle = gRaisedAngle / moveSteps;        rotation raiseRot = llEuler2Rot(raisedAngle * DEG_TO_RAD);        rotation lowerRot =  ZERO_ROTATION / raiseRot;        integer i;        for (i = 0; i < moveSteps; i++)        {            gOpenSequence += [ZERO_VECTOR, raiseRot, stepTime];            gCloseSequence += [ZERO_VECTOR, lowerRot, stepTime];        }            }    touch_start(integer total_number)    {        if (!gBridgeMoving)  // only start if not already moving        {            if (gBridgeLowered)// time to raise            {                gFinalRot = gRaisedRot * gLoweredRot;                llSetKeyframedMotion(gOpenSequence, []);                gBridgeMoving = TRUE;                // This time could need adjustment to account for lag.                llSetTimerEvent(gSwingTime + 0.1);            }            else // time to lower            {                gFinalRot = gLoweredRot;                llSetKeyframedMotion(gCloseSequence, []);                gBridgeMoving = TRUE;                llSetTimerEvent(gSwingTime + 0.1);            }        }    }    timer()    {        llSetTimerEvent(0.);        llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_PAUSE]);        gBridgeLowered = (!gBridgeLowered); // mark new position        // touch up rotation just in case        gBridgeMoving = FALSE;        llSetRot(gFinalRot);        llSay(0, "done");    }}

 

Link to comment
Share on other sites

Thank for your script cerise .

 

If you allow me some remarks :

- probably your script could be simpler and easier if you didn t use llSetKeyFramedMotion but if you  play with Omega

- your rotation is slow, jerky and halted in every steps .  You are doing several steps , but every step is halted before its end .  Be aware , because llSetKeyFramedMotion  is bugged for rotation with angular velocity below 0.16 rad/seconds  (around 9-10 degrees /seconds). The rotation is stopped when it s below.

see https://jira.secondlife.com/browse/SVC-7471

note the bug is related by the angular velocity of the frame , not directly the angle or the time of the frame

- if you right click when your motion is paused , it will continue its movement , and your initial rotation of the bridge is lost. Use KMD_CMD_STOP in replacement

 

Link to comment
Share on other sites


shymus Roffo wrote:

I have used llTargetOmega and I couldn't figure out how to make it stop or set a target destination for it

You can try this old script from Lex Neva, it uses llTargetOmega to try to hide the jerky motions that come with llSetRot. This approach can be disappointing, lag can make the targetomega motion undershoot or overshoot. Sometimes it ends up looking worse than llSetKeyframedMotion, expecially for the slow movements like these drawbridges, and the physics can't match the object appearance during the transition.

Link to comment
Share on other sites


Miranda Umino wrote:

- probably your script could be simpler and easier if you didn t use llSetKeyFramedMotion but if you  play with Omega

 

It would be a shorter script but less functional. When you walk or drive on the keyframed bridge while it is raising or lowering, you move with it. llTargetOmega fakes it on the client side, and you either walk or fall through the object if it is in motion.

- your rotation is slow, jerky and halted in every steps .  You are doing several steps , but every step is halted before its end .  Be aware , because llSetKeyFramedMotion  is bugged for rotation with angular velocity below 0.16 rad/seconds  (around 9-10 degrees /seconds). The rotation is stopped when it s below.

The problems I experienced were not due to too low of a rate of roation, but too long a time. And indeed the smoothness or lack thereof was the same with a single or multiple steps. This is not an issue with the script but in server side behavior that needs more refinement. It is very much dependent on how loaded the simulator is. It is, however, no worse than earlier methods for working drawbridges using stepped rotations.

see 

note the bug is related by the angular velocity of the frame , not directly the angle or the time of the frame

Low velocities do work in shorter steps, hence their use.

Link to comment
Share on other sites

Well .. if your script was what you have wanted , its perfect.

 

I ve just said that because your script does 75 degrees in 20 seconds .

With 5 steps it should do 15 degrees in 4 seconds per step.

But  when i run your script it does 5-6 degrees and stops , wait the rest of the time until 5 seconds,

resumes and oes 5-6 degrees again and stops , wait the rest of the time until 5 seconds etc ...

.. And this 5 fimes ..

and finally the rotation is repositionned with llsetpos in doing more than45 degres in one call .

I tell you just what i have in my screen ..You may check your llGetRot each 4 seconds to verify .

 

In fact i see  each keyframe has been stopped . But of course a keyframe stopped doesn t stop the whole list of keyframes . So , no : low velocities don t work in several keyframes. Rotation of PI radians in 19 seconds is  not halted . Rotation of PI/12 radians in 2 seconds is halted

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4571 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...