Jump to content
Sign in to follow this  
khonsuu

accumulative rotations in llSetKeyframedMotion()

Recommended Posts

I understand that the rotations in llSetKeyframedMotion() are accumulative.  These rotations are added on to previous rotations, rather than setting orientations directly.

I would like to implement world-Z-axis rotations on an object undergoing motion in llSetKeyframedMotion().  

Consider the following code: 

vector   kspan = <5,0,0>;
float     ktime  = 5.0;
vector   krotE   = <0,0,31> 
rotation krot    = llEuler2Rot( krotE );
//
llSetKeyframedMotion( [],[] );
llSetKeyframedMotion( [kspan,krot,ktime],
[KFM_MODE, KFM_FORWARD] );

The above code will cause most "fresh" prims to rotate smoothly and end up at the end with an accumulated world-Z-axis rotation of 31 degrees. However, if the object is an "unfresh" cone that has been previously tilted to the side, the Z-rotation is performed so that the cone is spun about its tip. (This looks like a local rotation rather than a revolving around the world-Z-axis).  To get a world-Z rotation on a previously-tipped object, something unusual must be performed on the 'krotE', the 'krot', or both.

Anyone have any idea how to go about this?  Thanks for the help!

 

 

 

 

Share this post


Link to post
Share on other sites

Without first trying it I will say that you must eliminate the prim's initial rotation:

llSetKeyframedMotion( [kspan, krot / llGetRot(), ktime], [KFM_MODE, KFM_FORWARD]);

 

Share this post


Link to post
Share on other sites

There may be a more concise way to torture the quarternions, but what I think you're after is illustrated:

vector   kspan = <0,0,0>;float     ktime  = 1.0;vector   krotE   = <0,0,31> ;rotation normRot(rotation Q){    float MagQ = llSqrt(Q.x*Q.x + Q.y*Q.y +Q.z*Q.z + Q.s*Q.s);    return <Q.x/MagQ, Q.y/MagQ, Q.z/MagQ, Q.s/MagQ>;}//default{    state_entry()    {        rotation grot =             (llGetRot() * (llEuler2Rot( krotE ))            / llGetRot());        llSetKeyframedMotion( [],[] );        llSetKeyframedMotion( [kspan, normRot(grot), ktime], [KFM_MODE, KFM_LOOP] );    }}

 I threw in the normRot cliche, just to prevent a possible runtime error (which may not even apply here; not sure).

[EDIT: Eww. Maybe not.  I just tried it, and it seems to be drifting off the spin axis I was trying to set. Hmm.]

[EDIT 2: I guess, with KFM_LOOP, any slight error in the incremental rotation would compound over time, but I'm not sure that accounts for the drift.]

Share this post


Link to post
Share on other sites

I'm still not quite sure what rotation the OP is looking for, but this works and gives a nice smooth rotation....

float     ktime  = 1.0;vector   krotE   = <0,0,31> ;list KFMlist;default{    state_entry()    {        llSetLinkPrimitiveParamsFast(LINK_SET, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);   //Set door in Prim Equivalence system        integer i;        for (i=0;i<10;++i)        {            rotation grot = (llGetRot() * (llEuler2Rot( krotE ))/ llGetRot());            KFMlist += [grot,ktime];        }        llSetTimerEvent(10.1);    }        timer()    {        llSetKeyframedMotion( [],[] );        llSetKeyframedMotion( KFMlist, [KFM_DATA,KFM_ROTATION] );    }}

 

Share this post


Link to post
Share on other sites
default{    state_entry()    {         llSetLinkPrimitiveParamsFast(            LINK_THIS,             [ PRIM_PHYSICS_SHAPE_TYPE,               PRIM_PHYSICS_SHAPE_CONVEX ] );     }    touch_start(integer total_number)    {        vector  kspan   = <2,0,0>;        float   ktime   = 5.0;        vector  krotE   = <0,0,(140*DEG_TO_RAD)>;        rotation krot   = llEuler2Rot( krotE );        //        llSetKeyframedMotion( [], [] );        llSetKeyframedMotion( [kspan, krot, ktime],                               [KFM_MODE, KFM_FORWARD] );    }}

 

OP here.  I'm going to use a neologism in this post - "fresh prim".  A fresh prim is a prim that you just created with the creation wand in world.. You have neither scaled nor rotated it, or done any other tomfoolery with its parameters.

local tip rotation

 

-

World Z rotation

-

After several days of contemplation, I have decided this is not possible. llSetKeyframedMotion() takes accumulated rotations as arguments. It has no power to set rotations.

Fortunately, there is a work-around. Your build has been rotated to strange places out in left field. You can take this wacker-jawed build and link it to a FRESH PRIM box, such that the fresh-prim-box is root.  You can set the box fully transparent and then perform your keyframe script from inside it.  Voila.

Share this post


Link to post
Share on other sites

No, it's absolutely possible, just try either Rolig's script or mine. It will do what you describe. It's only a question of precision, and I suspect Rolig's omission of normRot() will reduce floating-point error.

I admit that I introduced some unnecessary parentheses into the formula, intending to make it more obvious what was going on--but I only managed to make it more obscure by putting the parens in the wrong places.

Anyway, here's how it works: You want to apply an incremental rotation--as you say, "accumulative"--so the formula for the desired incremental rotation must calculate the difference (quaternion division) between the desired rotation (llGetRot() * rotationRelativeToWorldAxes) and the current rotation (llGetRot()).

[EDIT: I renamed to "rotationRelativeToWorldAxes" in hopes it's clearer than what I used before. Anyway, in this case, it's just the z-axis-only spin.]

Share this post


Link to post
Share on other sites

What is the problem? It works for me.
I modified your script a bit and used Rolig's calculation:

vector   kspan = <0.05,0,0>;float    ktime  = 5.0;vector   krotE   = <0,0,90> ;rotation krot;default{    state_entry()    {        llSetPrimitiveParams([PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);        krot = llEuler2Rot( krotE * DEG_TO_RAD );    }    touch_start( integer n)    {        llSetKeyframedMotion( [],[] );        llSetKeyframedMotion( [kspan, llGetRot()*krot/llGetRot(), ktime], []);    }}

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...