Jump to content
Sign in to follow this  
Teflonhotpocket

llSetKeyFramedMotion spacial relation not being exact

Recommended Posts

///////////
vector pos_A;
vector pos_B;


integer toggle = 0;
//////////
 
float speed = 10;            



vector pos;



 
default{
    
touch_start(integer poops)
{
            if(toggle == 0)
            {
                pos_A = llGetLocalPos();
                llSay(0, "Aset"+(string)pos_A);
                toggle = 1;
                
            }
            else if(toggle == 1)
            {
                pos_B = llGetLocalPos();
                toggle = 2;
                llSay(0, "Bset"+(string)pos_A+(string)pos_B);
            }
            else if(toggle == 2)
            {
                
                pos = llGetLocalPos();
                llSay(0, "posset"+(string)pos_A+(string)pos_B+(string)pos);
                if (pos == pos_A){
                       llSetKeyframedMotion([pos_B - pos, speed],[KFM_DATA,KFM_TRANSLATION]);
                                       llSay(0, "Ago");
                }
                else if (pos == pos_B){
                    llSetKeyframedMotion([pos_A - pos, speed],[KFM_DATA,KFM_TRANSLATION]);
                                    llSay(0, "Bgo");
                 }
                else
                {
                    
                                    llSay(0, "Doom");
            }
        } 
    }
}

 ...Pretty straight forward what I'm attempting, you touch to set two positions then it moves from one position to the other...


I've never messed with the keyframe scripts before, and the problem I face they way the code is written is that it relies on the placement to be exact which apparently the keyframe motion cant do properly at all, is there away to get its placement more precise or am I just going about this entirely wrong?

Share this post


Link to post
Share on other sites

In my opinion your problem arise from comparing vectors the way you do
You would have the same problem also if you moved by llSetPos(), llSetRegionPos(), llMoveToTarget() or any llSetPrimitiveParams() variation

It is bad enough to compare two float numbers for equality
Compairing vectors is the same as comparing three float numbers to three float numbers for equality

One way to overcome this is to compare the vector difference to some small number

if ( llVecDist( pos, pos_A) < 0.0001 )

 :smileysurprised::):smileyvery-happy:

Share this post


Link to post
Share on other sites

I've just tried with this sample script:

vector offset = <5.0,-3.0, 0.0>;default{    state_entry()    {       llSetLinkPrimitiveParams(LINK_SET, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);    }    touch_start(integer total_number)    {                llOwnerSay((string)llGetPos());        {            llSetKeyframedMotion([],[]);            llSetKeyframedMotion([offset,5.0], [KFM_DATA,KFM_TRANSLATION,KFM_MODE,KFM_FORWARD]);            offset.x*=-1.0;            offset.y*=-1.0;        }    }}

 with the following results:

[12:26] Object: <235.00000, 195.00000, 651.12890>[12:26] Object: <239.99880, 191.99940, 651.12890>[12:26] Object: <235.00000, 195.00000, 651.12890>[12:26] Object: <239.99880, 191.99940, 651.12890>[12:27] Object: <235.00000, 195.00000, 651.12890>[12:27] Object: <239.99880, 191.99940, 651.12890>

 Looks pretty accurate to me.

Share this post


Link to post
Share on other sites

Bare in mind that these results are converted from binary to decimal and rounded to max 7 decimal digits
The float numbers compared in the OP are binary and contains more information (valid or not)

:smileysurprised::):smileyvery-happy:

Share this post


Link to post
Share on other sites

There is some drift, it's even worse when rotating objects, such as in a large pendulum. All I can suggest is that at the end of each keyframed movement you then use llSetPos() ands llSetRot() to get your object to the precise position you want it.

 

From my own moving objects, such as said pendulum and a funicular, I see the problem comes with the moving_end state, the way this gets triggered suggests to me that the server is struggling with detecting exactly when an object stops, and has a "good enough" algorithm that doesn't really suit all cases.

Share this post


Link to post
Share on other sites

There is a drift sometimes. Except for llSetPos/llSetRot - but only if you test it :D

The next sim restart will shift/rotate most of your prims by 0.0001 or something. So you should NEVER compare any float/vector/rotation by using "==" !

It may even work if you do. Often. At least until the sim is restarted.

 

Share this post


Link to post
Share on other sites

So what would be the best way to compare vectors?

 

I mean this line worked for what I'm doing, along side rewriting how I set the two positions, but it seems like the slight variation when it happens will eventually cause the object to move out of its place over time. Is there a better way to get smooth movement that would be more useful besides the keyframe motion? I've tried setting up an incremental set position, but no mater how I work it it always looks incredibly choppy.

if ( llVecDist( pos, pos_A) < 0.0001 )

Share this post


Link to post
Share on other sites

  1. There really is no alternative to perform a smoother motion
  2. Key Framed Motions are bound to drift sooner or later
  3. Drifting can be addressed as mentioned by Profaitchikenz Haiku in their posting here

This script is basically the same as in the OP only vector compare is changed and drifting is addressed

///////////vector pos_A;vector pos_B;integer toggle = 0;//////////float speed = 10;vector pos;default{    touch_start(integer poops)    {        if(toggle == 0)        {            pos_A = llGetPos();            llSay(0, "Aset"+(string)pos_A);            toggle = 1;        }        else if(toggle == 1)        {            pos_B = llGetPos();            toggle = 2;            llSay(0, "Bset"+(string)pos_A+(string)pos_B);        }        else if(toggle == 2)        {            pos = llGetPos();            llSay(0, "posset"+(string)pos_A+(string)pos_B+(string)pos);            if ( llVecDist( pos, pos_A) < 0.001 )            {                llSetPos( pos_A);                llSetKeyframedMotion([pos_B - pos, speed],[KFM_DATA,KFM_TRANSLATION]);                llSay(0, "Ago");            }            else if ( llVecDist( pos, pos_B) < 0.001 )            {                llSetPos( pos_B);                llSetKeyframedMotion([pos_A - pos, speed],[KFM_DATA,KFM_TRANSLATION]);                llSay(0, "Bgo");            }            else llSay(0, "Doom");        }    }}

 Note that drift correction is before the KFM starts

If we put is after we had to detect when the motion had stopped before doing it

I assume the drift on a single motion can be neglected

 

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...