Jump to content

Smooth Rotation Problem.


Shymus Roffo
 Share

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

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

Recommended Posts

I have been experimenting with rotations, during that time while trying to make a "swivel" gate or a traffic gate that would be on something like RR crossings; i came across a problem with my function to rotate the arm.

 

ffSetRot(integer n,rotation sr,rotation er) {
    rotation b = ( sr / ZERO_ROTATION) * er;
    vector ax = llRot2Axis(b);
    float an = llRot2Angle(b);
    integer j;
    for(j=0;j<=n;++j) {
        llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROT_LOCAL,sr * llAxisAngle2Rot(ax,((float)j) / ((float)n) * an)]);
        llSleep(0.01);
    }
}

integer open = FALSE;
integer speed = 35;
rotation r_open = ZERO_ROTATION;
rotation r_closed = ZERO_ROTATION;

default {
    state_entry() {
        r_open = llEuler2Rot(<0,-90,0>*DEG_TO_RAD);
        r_closed = llEuler2Rot(<0,0,0>*DEG_TO_RAD);
    } 
    touch_start(integer s) {
        if(llDetectedKey(0) == llGetOwner()) {
            if(!open) {
                ffSetRot(speed,llGetLocalRot(),r_open);
            } else {
                ffSetRot(speed,llGetLocalRot(),r_closed);
            }
            open = !open;
        }
    }
}

 If you were to click this enough times, the rotations would change, then they would slowly offset. I'm not the best with rotations, so i don't really know what the function does, my friend did that for me. If you are able to explain it better then that would really help.

Link to comment
Share on other sites

What's your question?  The script works as written.  It rotates a prim 90 degrees around its local Y axis and then rotates it back the next time you click it.  If I were writing it, I might have used a timer event instead of a loop with a llSleep built into it, but this script gives good smooth motion and it works, so it's just as good for what you want.  I suggest that you slice the bottom half of your rotating prim away so that what's left appears to rotate from its end instead of its middle.

Link to comment
Share on other sites

Yeah, it works. But after a bit, it will not work. If you click it a few times the rotations go off. I would have to straighten it for it to work. Yes, the prim is cut so it rotates on the access. :smileywink:

I used a sleep so it would ignore chat. The normal script uses a listener and waits for a command.

My question is, how would you fix it from doing that issue with the rotation setting off after a few clicks.

Link to comment
Share on other sites

Well, I'd guess that if you are having a problem it's because of roundoff errors.  You have decided that your speed (the number of steps) is going to be 35.  The total change you are making is 90 degrees, so each step is 90.0/35.0 = 2.571428571428...... degrees, or its equivalent in radians. It's not a nice round number.  Do that enough times and you'll gradually accumulate enough roundoff errors to come back to a different rotation than you started with.  The cure is to store your object's initial rotation somewhere and then reset the object to that value every time it finishes a cycle.

Link to comment
Share on other sites

A nice "evenly divisible with no remainder" number, like 90.0/30.0 = 3.0000000..... or 90.0/45.0 = 2.000000 . :)  If you rotate by some odd value like 2.257142857142.... degrees each time, the roundoff errors will add up over time.  You won't come back to exactly where you started. So yes, reset the global rotation to your saved value after the animation is done.  That's what I suggested.  It should work.

Link to comment
Share on other sites


Rolig Loon wrote:

A nice "evenly divisible with no remainder" number, like 90.0/30.0 = 3.0000000..... or 90.0/45.0 = 2.000000 .
:)
  If you rotate by some odd value like 2.257142857142.... degrees each time, the roundoff errors will add up over time.  You won't come back to exactly where you started. So yes, reset the global rotation to your saved value after the animation is done.  That's what I suggested.  It should work.

To extend your caveat a bit further, the only numbers you can trust in a floating point calculation, whether they're on the left or right side of the equals sign, are integers. The number 0.1 looks innocuous enough, and one might expect that if you multiply 0.1 by three, you'll get 0.3. But it's the rare computer that will agree.

Insert this script into a prim and touch it for proof...

// a function to test whether a*b==c and report our opiniontest(float a, float b, float c){    llOwnerSay((string)a+"x"+(string)b+"="+(string)c+"?");    if(a*b==c){        llOwnerSay("Yep");    }    else{        llOwnerSay("Nope");    }    llOwnerSay(" ");}        default {    state_entry() {        llSay(0, "Hello, Avatar!");    }    touch_start(integer total_number) {        // Let's do some test to see if...        //     a  *  b  = c        test(0.1,  2.0, 0.2 );        test(0.1,  3.0, 0.3 );        test(0.25, 3.0, 0.75);    }}

All three tests should be true, right?

Oops!

So, even numbers that don't look odd may produce errors that add up over time.

Link to comment
Share on other sites

The decimal numbers in this thread are represented in a binary form in a float. You will always get small number drifts. Even prims that are not moved at all can get a drift. The precision of the float is much higher than the precision of the sim.

I have a number of linked doors that all use the root or a reference prim (like the doorframe) as an anchor. So I can not build up drifts over time. I noticed that the script sometimes did not detect the open/close state after a sim restart. (no questions why I need that!)

Ok, my bad, if you compare vector1==vector2 that will work fine, except there was a sim restart. The position.x is no longer 5.000 but 4.998 for example (sometimes not always). So I replaced that by an "unsharp" compare for vectors and rotations.

Now imagine you never reset the position and always move relative like the OP's script does. One day your door will fall out of the hinges. :D

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3609 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...