Jump to content

llSetKeyframedMotion() isn't Very Smooth


Haravikk Mistral
 Share

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

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

Recommended Posts

Okay, so while I was on a haitus for a bit, llSetKeyframedMotion finally got released to the main grid, so I figured I'd give it a try.

I opted to make a simple clock, thinking this would be a good way to get an idea of how it works, and also to see how reliable it is in terms of a need to re-synchronise.

So I came up with the following simple script for a clock-hand; I'm using a long half-cut box positioned to rotate around its Y-axis.

list animation = [
    <0.00000, 0.99996, 0.00000, -0.00873>, 20.0,
    <0.00000, 0.99996, 0.00000, -0.00873>, 20.0,
    <0.00000, 0.99996, 0.00000, -0.00873>, 20.0
];

rotation normRot(rotation r) {
    float mag = llSqrt(r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s);
    return <r.x / mag, r.y / mag, r.z / mag, r.s / mag>;
}

default {
    state_entry() {
        llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]);
        llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, llEuler2Rot(<0.0, 270.0, 0.0> * DEG_TO_RAD)]);

        // Make sure rotations are normalized
        integer i; integer l = animation != [];
        for (i = 0; i < l; i += 2) 
            animation = llListReplaceList(animation, [normRot(llList2Rot(animation, i))], i, i);

        float time = llGetTimeOfDay();
        float wait = 60.0 - (time - ((integer)(time / 60.0) * 60.0));
        
        if (wait > 0.0) llSleep(wait);
        llSetKeyframedMotion(animation, [KFM_MODE, KFM_LOOP, KFM_DATA, KFM_ROTATION]);
    }
}

 Note that the script waits in order to try to start the animation at the start of a new minute, simply comment out the wait if you'd like it to start right away.

It works okay, but even in a sim with a lot of free time and constant physics rate of 45.0fps, I'm seeing a lot of stuttering in the animation, with the object stopping for several seconds before continuing its movement.

I don't understand why though; like I say my current sim has time to spare, and the physics engine in particular is running extremely smoothly, but for some reason my keyframed motion isn't.

Are there some caveats I'm missing? I'm probably not going to use this for anything as slow as this example, but some of the examples listed on the wiki page include using it for an elevator, which I can't imagine would be very good with the amount of pausing I'm seeing.

Link to comment
Share on other sites

I can confirm that a slow spin like that doesn't work like one could wish for
I tried a completely different script but with same spin-rate and it looks awful
The prim rests longer than it spins

I am not sure it always was like that but with up to date viewer and server it is

Second Life 3.7.19 (295700) Oct 20 2014 13:37:20 (Second Life Release)
Release Notes

You are at 33.3, 40.3, 1,279.9 in Nautilus - Suniaton located at sim10091.agni.lindenlab.com (216.82.48.157:13001)
SLURL: http://maps.secondlife.com/secondlife/Nautilus%20-%20Suniaton/33/40/1280
(global coordinates 287,777.0, 268,328.0, 1,279.9)
Second Life RC LeTigre 14.10.24.295913
Retrieving...

CPU: Intel® Core i7-2600 CPU @ 3.40GHz (3392.28 MHz)
Memory: 8174 MB
OS Version: Microsoft Windows 8.1 64-bit  (Build 9600)
Graphics Card Vendor: NVIDIA Corporation
Graphics Card: GeForce GTX 660/PCIe/SSE2

Windows Graphics Driver Version: 9.18.0013.4411
OpenGL Version: 4.4.0 NVIDIA 344.11

libcurl Version: libcurl/7.38.0 OpenSSL/1.0.1h zlib/1.2.8
J2C Decoder Version: KDU v7.0
Audio Driver Version: FMOD Ex 4.44.31
Qt Webkit Version: 4.7.1 (version number hard-coded)
Voice Server Version: Not Connected
Built with MSVC version 1600
Packets Lost: 163/132,897 (0.1%)

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

I don't know what is cooking
The following script makes a prim complete a circular path in 1 minute and it works perfectly
The malfunctioning script only rotates about one axis and has no translation like this one

// frames for circular motion, plane, script by Dora Gustafson, Studio Dora 2014// function computes relative moves and rotations for a Key Framed Motion// function takes arguments: velocity, some radius-vector and angle for motion in degrees// the turning can be in any plane in space. Plane given by the two vectors// The two vectors must not point in same or opposite direction// turns prim forward before motion startvector Velocity = <0.0, -0.10471975512, 0.0>;vector Radius = <1.0, 0.0, 0.0>;float Angle = 360;integer rev;list L;list framesCircular( vector velocity, vector radius, float angle ){    // Compute circle center and first position    vector center = llVecMag(radius)*llVecNorm((velocity%radius)%velocity);    vector startRadiusVector = -center;    // Compute time per step    float arch = angle*DEG_TO_RAD;    float steps = (float)llRound(arch/(10.0*DEG_TO_RAD));    float dT = arch*llVecMag(radius)/llVecMag(velocity)/steps;    dT = llRound(45.0*dT)/45.0;    if ( dT < 0.11111111 ) dT = 0.11111111;    // initialize loop    list KFMlist = [];    vector axis = velocity%radius;    rotation baserot = llGetRot();    vector U = center+startRadiusVector;    rotation rotU = baserot;    vector V;    rotation rotV;    float step = 0.0;    while ( step < steps )    {        step += 1.0;        rotV = llAxisAngle2Rot( axis, arch*step/steps);        V = center+startRadiusVector*rotV;        rotV = baserot*rotV;        KFMlist += [V-U, rotV/rotU, dT];        rotU = rotV;        U = V;    }    return KFMlist;}default{    touch_start( integer n)    {        llSetKeyframedMotion( [], []);        llSleep(0.2);        if ( rev ) llSetKeyframedMotion( L, [KFM_MODE, KFM_REVERSE]);        else        {            // first turn prim correct, X-axis in velocity's direction            llSetRot( llAxes2Rot( llVecNorm( Velocity), llVecNorm(( Velocity%Radius)%Velocity), llVecNorm( Velocity%Radius)));            // then do the motion            L = framesCircular( Velocity, Radius, Angle);            llSetKeyframedMotion( L, []);        }        rev = !rev;    }}

 :smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

No , there is no link with the translations

Your rotation velocity is too small  and the half cosinus , or half sinus needed to compute the intermediar rotations may be rounded to 1 or 0:

 

llOwnerSay(llList2CSV(
[ "angle (radians)", llRot2Angle(normRot(<0.00000, 0.99996, 0.00000, -0.00873>)), "\n",
"angle (rad) / frame",llRot2Angle(normRot(<0.00000, 0.99996, 0.00000, -0.00873>))/(20.0*45), "\n",
"half cosinus angle / frame ", llCos( 0.5 * llRot2Angle(normRot(<0.00000, 0.99996, 0.00000, -0.00873>))/(20.0*45) )
]));

 

angle (radians), 3.124133,
, angle (rad) / frame, 0.003471,
, cosinus half  angle / frame , 0,99999849379559389750526410095037 <--- may be rounded to 1 and so make no rotations

 

LLSetKeyframedMotion work by an impulsion; if the rotation impulsion is very small , your object can move and stop at the half of its run

Watch my Jira  https://jira.secondlife.com/browse/SVC-7471

 

 

It s the same problem for every physical rotations :
there is a limit to 9 degrees per seconds.
Maybe use 64 bits float and not 32 bits float may fix it

Link to comment
Share on other sites

It is easy to specify a 1 RPM motion nowhere near causing rounding errors

// one RPM script by Dora Gustafson, Studio Dora 2014integer S;list KFMlist = [];default{    state_entry()    {        integer frams = 3;        list L = [llAxisAngle2Rot( <0.0, 1.0, 0.0>, TWO_PI/(float)frams), 60.0/(float)frams];        llOwnerSay("Rotation and time per frame= "+llDumpList2String( L, ", ")+" by "+(string)frams+" frames");        while ( frams-- ) KFMlist += L;    }    touch_end( integer n)    {        llSetKeyframedMotion( [], []);        llSleep( 0.2 );        S = !S;        if ( S ) llSetKeyframedMotion( KFMlist, [KFM_DATA, KFM_ROTATION, KFM_MODE, KFM_LOOP]);    }} 

You get these data
Rotation and time per frame= <0.000000, 0.866025, 0.000000, 0.500000>, 20.000000 by 3 frames
And still there is no rotation most of the time

Try it with 36 frames(one for each 10 degrees) and you get:
Rotation and time per frame= <0.000000, 0.087156, 0.000000, 0.996195>, 1.666667 by 36 frames
Still nowhere near to rounding problems and still no smooth rotation

Funny because the script I posted previously

// frames for circular motion, plane, script by Dora Gustafson, Studio Dora 2014// function computes relative moves and rotations for a Key Framed Motion// function takes arguments: velocity, some radius-vector and angle for motion in degrees// the turning can be in any plane in space. Plane given by the two vectors// The two vectors must not point in same or opposite direction// turn prim forward before motion startvector Velocity = <0.0, -0.10471975512, 0.0>;vector Radius = <1.0, 0.0, 0.0>;float Angle = 360;integer rev;list L;list framesCircular( vector velocity, vector radius, float angle ){    // Compute circle center and first position    vector center = llVecMag(radius)*llVecNorm((velocity%radius)%velocity);    vector startRadiusVector = -center;    // Compute time per step    float arch = angle*DEG_TO_RAD;    float steps = (float)llRound(arch/(10.0*DEG_TO_RAD));    float dT = arch*llVecMag(radius)/llVecMag(velocity)/steps;    dT = llRound(45.0*dT)/45.0;    if ( dT < 0.11111111 ) dT = 0.11111111;    // initialize loop    list KFMlist = [];    vector axis = velocity%radius;    rotation baserot = llGetRot();    vector U = center+startRadiusVector;    rotation rotU = baserot;    vector V;    rotation rotV;    float step = 0.0;    while ( step < steps )    {        step += 1.0;        rotV = llAxisAngle2Rot( axis, arch*step/steps);        V = center+startRadiusVector*rotV;        rotV = baserot*rotV;        KFMlist += [V-U, rotV/rotU, dT];        rotU = rotV;        U = V;    }    return KFMlist;}default{    touch_start( integer n)    {        llSetKeyframedMotion( [], []);        llSleep(0.2);        if ( rev ) llSetKeyframedMotion( L, [KFM_MODE, KFM_REVERSE]);        else        {            // first turn prim correct, X-axis in velocity's direction            llSetRot( llAxes2Rot( llVecNorm( Velocity), llVecNorm(( Velocity%Radius)%Velocity), llVecNorm( Velocity%Radius)));            // then do the motion            L = framesCircular( Velocity, Radius, Angle);            llSetKeyframedMotion( L, []);        }        rev = !rev;    }}

has a frame for each 10 degrees and the object rotates nicely as it moves along the circle
so obviously rotation and translation are linked

I will not guess about server-side rounding problems, I have no way of knowing and I consider every server-side problem to be handled by LL

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

Dora , i am talking about frames of simulator ( so 45 frames per seconds ) ; i am not talking about frames as input/ parameters of llsetkeyframedmotion.
If you prefer it s the time in seconds of your frame as input of llsetkeyframemotion multiplied by 45 :

if i take your script dated at 12/Nov/14 12:55 PM :
rotation r = llAxisAngle2Rot( <0.0, 1.0, 0.0>, TWO_PI/(float)frams);
float angle = llRot2Angle® * RAD_TO_DEG;
float time = 60.0/(float)frams;
float velocity_by_frame = angle / time;
llOwnerSay(llList2CSV( [ "angle (deg)", angle, "time (seconds)", time, "velocity rotation (deg/frame )",velocity_by_frame ]));

=> will display
angle (deg), 120.000008, time (seconds), 20.000000, velocity rotation (deg/frame ), 6.000000

you are at 6 deg per seconds< 9 deg per seconds => so , you meet the problem here

If i take you second daatas :
rotation r = <0.000000, 0.087156, 0.000000, 0.996195>;
float angle = llRot2Angle® * RAD_TO_DEG;
float time = 1.666667 ;
float velocity_by_frame = angle / time;
llOwnerSay(llList2CSV( [ "angle (deg)", angle, "time (seconds)", time, "velocity rotation (deg/frame )",velocity_by_frame ]));

=> will display
angle (deg), 9.999578, time (seconds), 1.666667, velocity rotation (deg/frame ), 5.999746
you are at 5.997 deg per seconds< 9 deg per seconds => so , you meet the problem here too

In your script in your link , your move does both a translation and a rotation . So to compute the velocity of rotation in the right coordinates ; in local coordinates the velocity is different of region coordinates

Change your linear( translation) Velocity
vector Velocity = <0.0, -0.10471975512, 0.0>;
by
vector Velocity = <0.0, -0.01471975512, 0.0>; and you will watch your prim starting and stopping

 

 

// frames for circular motion, plane, script by Dora Gustafson, Studio Dora 2014// function computes relative moves and rotations for a Key Framed Motion// function takes arguments: velocity, some radius-vector and angle for motion in degrees// the turning can be in any plane in space. Plane given by the two vectors// The two vectors must not point in same or opposite direction// turns prim forward before motion startvector Velocity = <0.0, -0.01471975512, 0.0>;vector Radius = <1.0, 0.0, 0.0>;float Angle = 360;integer rev;list L;list framesCircular( vector velocity, vector radius, float angle ){    // Compute circle center and first position    vector center = llVecMag(radius)*llVecNorm((velocity%radius)%velocity);    vector startRadiusVector = -center;    // Compute time per step    float arch = angle*DEG_TO_RAD;    float steps = (float)llRound(arch/(10.0*DEG_TO_RAD));    float dT = arch*llVecMag(radius)/llVecMag(velocity)/steps;    dT = llRound(45.0*dT)/45.0;    if ( dT < 0.11111111 ) dT = 0.11111111;    // initialize loop    list KFMlist = [];    vector axis = velocity%radius;    rotation baserot = llGetRot();    vector U = center+startRadiusVector;    rotation rotU = baserot;    vector V;    rotation rotV;    float step = 0.0;    while ( step < steps )    {        step += 1.0;        rotV = llAxisAngle2Rot( axis, arch*step/steps);        V = center+startRadiusVector*rotV;        rotV = baserot*rotV;        KFMlist += [V-U, rotV/rotU, dT];        rotU = rotV;        U = V;    }    return KFMlist;}default{    touch_start( integer n)    {        llSetKeyframedMotion( [], []);        llSleep(0.2);        if ( rev ) llSetKeyframedMotion( L, [KFM_MODE, KFM_REVERSE]);        else        {            // first turn prim correct, X-axis in velocity's direction            llSetRot( llAxes2Rot( llVecNorm( Velocity), llVecNorm(( Velocity%Radius)%Velocity), llVecNorm( Velocity%Radius)));            // then do the motion            L = framesCircular( Velocity, Radius, Angle);            llSetTimerEvent(1/45.0);            llSetKeyframedMotion( L, []);        }        rev = !rev;    }    timer()    {        llSetLinkPrimitiveParamsFast(LINK_THIS,         [ PRIM_TEXT, llList2CSV([ llVecMag(llGetVel()), llGetOmega()]), <1.0,1.0,1.0>, 1.0        ]);    }}

 

 

And i repeat : with llTargetOmega , we meet the same problem , and with llSetAngularVelocity we meet the same problem.
it stops too soon for low velocity.

It s a common bug/limit for every rotations in second life

 

Link to comment
Share on other sites

I will not argue about the facts you have found about the angular velocity limit
It looks like a imperial fact and should be noted as such by any scripter.

Still the limit should be violated in the script that moves a prim on a circle and simultaneously rotate the prim one revolution, all completed during one minute.
The motion is composed of a translation (round the circle) and a rotation (round the prim axis)
The rotation is 360/60 = 6 degrees per second which is definitely lower than 9 degrees per second, but it doesn't produce any stutter.

Your observation about the phenomena being linked to a moving coordinate system would show that rotation and translation in fact are linked.
The idea to me looks like sheer speculation at this point.

One could hope for better slow rotations, but you and I know it is not likely to happen within the SL we know, so this discussion is purely academic.

There should always be room for an academic discussion

The angular velocity limit being the same for llSetKeyFramedMotion(), llTargetOmega() and llSetAngularVelocity() makes me think that an ancient routine for rotation is reused in all rotations. This is only speculation of course.

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

To demonstate better my opinion that the problem with llsetkeyframedmotion is the same with other physics rotations :

i ve done 2 seamless scripts :
It fixes a rotation while 5 seconds and tests with different angular velocities .
It returns when ( in frames of simulator ) the motion has been stopped ( more precisely when llGetOmega is null vector )

By defaut , an iteration of test is 0.5 seconds , so 0.5 * 45 FPS = 225 frames of simulator

Rez a prim ; move it to let it float on the air without friction with the ground or other objects ; put the script inside and touch it to start the tests


/

/ we ll do succesive tests// From an angularvelocity of INITIALANGULARVELOCITY =0.5, we are turning along STEPTIMETEST seconds.// A timer is setup to count the number of frames in simulator :// if STEPTIMETEST is reached , we stop the motion , wait until it stops rotation and we go to the next test // If STEPTIMETEST is not reached and we reach a NULL llGetOmega before this, we stop the current test and we start the next test .// At every test , we display the angular velocity and the time in frames between the start of the current test and when the object has stopped to turn with llGetOmega = ZERO_VECTORfloat STEPANGULARVELOCITY = 0.01;float STEPTIMETEST = 5.0;float INITIALANGULARVELOCITY = 0.5;float angularvelocity;integer count;integer framestart;integer frameend;list keyframes;list buildKeyframes(float seconds, float angular_velocity){list l;rotation r = llEuler2Rot(<0,0,PI_BY_TWO>);float totalangle = seconds * angular_velocity;while ( totalangle > PI_BY_TWO ){l += [ r, PI_BY_TWO / angular_velocity ];totalangle -= PI_BY_TWO;}if ( totalangle > 0.0){float timekeyframe = totalangle / angular_velocity;if ( timekeyframe <= 0.111111 ) timekeyframe = 10/9.0;l += [ llEuler2Rot(<0,0,totalangle>), timekeyframe ] ;}return l;}default{state_entry(){llSetObjectName("test keyframemotion - low angular velocity");llSetStatus(STATUS_PHYSICS, FALSE);llSetRot(ZERO_ROTATION);llSetStatus(STATUS_PHANTOM, TRUE);llSetStatus(STATUS_BLOCK_GRAB, TRUE);}touch_end(integer total_number){llResetTime();llSetTimerEvent(2/45.0);angularvelocity = INITIALANGULARVELOCITY; framestart = (integer)llGetEnv("frame_number");llSetKeyframedMotion( buildKeyframes( STEPTIMETEST, angularvelocity ) , [ KFM_DATA, KFM_ROTATION ] );}timer(){if ( llGetTime() > STEPTIMETEST ){llSetKeyframedMotion( [], [ ] );while ( llGetOmega() != ZERO_VECTOR ) llSleep( 1/45.0);llResetTime();}frameend = (integer)llGetEnv("frame_number");if ( ( llGetOmega() == ZERO_VECTOR ) && ( frameend - framestart > 3 ) ){llOwnerSay(llList2CSV(["angularvelocity", RAD_TO_DEG* angularvelocity, "frames", frameend-framestart ]));angularvelocity -= STEPANGULARVELOCITY; if ( angularvelocity > 0.0 ){framestart = (integer)llGetEnv("frame_number");llSetKeyframedMotion( buildKeyframes( 5.0, angularvelocity ) , [ KFM_DATA, KFM_ROTATION ] );}else {llSetTimerEvent(0.0);llOwnerSay("end test");}}}}

 Results with llSetKeyframemotion

 

angularvelocity, 28.647890, frames, 225[16:16] test keyframemotion - low angular velocity: angularvelocity, 28.074932, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 27.501976, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 26.929018, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 26.356062, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 25.783104, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 25.210146, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 24.637190, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 24.064232, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 23.491274, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 22.918318, frames, 226[16:16] test keyframemotion - low angular velocity: angularvelocity, 22.345360, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 21.772404, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 21.199446, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 20.626488, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 20.053532, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 19.480574, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 18.907618, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 18.334660, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 17.761702, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 17.188745, frames, 226[16:17] test keyframemotion - low angular velocity: angularvelocity, 16.615788, frames, 225[16:17] test keyframemotion - low angular velocity: angularvelocity, 16.042831, frames, 225[16:17] test keyframemotion - low angular velocity: angularvelocity, 15.469873, frames, 224[16:18] test keyframemotion - low angular velocity: angularvelocity, 14.896916, frames, 224[16:18] test keyframemotion - low angular velocity: angularvelocity, 14.323958, frames, 225[16:18] test keyframemotion - low angular velocity: angularvelocity, 13.751000, frames, 226[16:18] test keyframemotion - low angular velocity: angularvelocity, 13.178042, frames, 226[16:18] test keyframemotion - low angular velocity: angularvelocity, 12.605084, frames, 225[16:18] test keyframemotion - low angular velocity: angularvelocity, 12.032126, frames, 225[16:18] test keyframemotion - low angular velocity: angularvelocity, 11.459168, frames, 225[16:18] test keyframemotion - low angular velocity: angularvelocity, 10.886210, frames, 226[16:18] test keyframemotion - low angular velocity: angularvelocity, 10.313251, frames, 226[16:18] test keyframemotion - low angular velocity: angularvelocity, 9.740294, frames, 226[16:18] test keyframemotion - low angular velocity: angularvelocity, 9.167336, frames, 126[16:18] test keyframemotion - low angular velocity: angularvelocity, 8.594378, frames, 100[16:18] test keyframemotion - low angular velocity: angularvelocity, 8.021420, frames, 15[16:18] test keyframemotion - low angular velocity: angularvelocity, 7.448462, frames, 72[16:18] test keyframemotion - low angular velocity: angularvelocity, 6.875504, frames, 42[16:18] test keyframemotion - low angular velocity: angularvelocity, 6.302546, frames, 48[16:18] test keyframemotion - low angular velocity: angularvelocity, 5.729589, frames, 43[16:18] test keyframemotion - low angular velocity: angularvelocity, 5.156631, frames, 4[16:18] test keyframemotion - low angular velocity: angularvelocity, 4.583673, frames, 56[16:18] test keyframemotion - low angular velocity: angularvelocity, 4.010715, frames, 50[16:19] test keyframemotion - low angular velocity: angularvelocity, 3.437758, frames, 60[16:19] test keyframemotion - low angular velocity: angularvelocity, 2.864800, frames, 36[16:19] test keyframemotion - low angular velocity: angularvelocity, 2.291842, frames, 22[16:19] test keyframemotion - low angular velocity: angularvelocity, 1.718884, frames, 25[16:19] test keyframemotion - low angular velocity: angularvelocity, 1.145927, frames, 35[16:19] test keyframemotion - low angular velocity: angularvelocity, 0.572969, frames, 34[16:19] test keyframemotion - low angular velocity: angularvelocity, 0.000011, frames, 4[16:19] test keyframemotion - low angular velocity: end test

 

 



The same test with llsetangularvelocity.
Rez a prim ; move it to let it float on the air without friction with the ground or other objects ; put the script inside and touch it to start the tests .
The script is lightly different because the motion is full physics , but it s the same algorithm

// we ll do succesive tests// From an angularvelocity of INITIALANGULARVELOCITY =0.5, we are turning along STEPTIMETEST seconds.// A timer is setup to count the number of frames in simulator :// if STEPTIMETEST is reached , we stop the motion , wait until it stops rotation and we go to the next test // If STEPTIMETEST is not reached and we reach a NULL llGetOmega before this, we stop the current test and we start the next test .// At every test , we display the angular velocity and the time in frames between the start of the current test and when the object has stopped to turn with llGetOmega = ZERO_VECTORfloat STEPANGULARVELOCITY = 0.01;float STEPTIMETEST = 5.0; float INITIALANGULARVELOCITY = 0.5;float angularvelocity;integer count;integer framestart;integer frameend; default{state_entry(){llSetObjectName("test setangularvelocity - low angular velocity");llSetStatus(STATUS_PHYSICS, FALSE);llSetRot(ZERO_ROTATION);llSetStatus(STATUS_PHYSICS, TRUE);llSetStatus(STATUS_PHANTOM, TRUE);llSetStatus(STATUS_BLOCK_GRAB, TRUE);llSetPhysicsMaterial(GRAVITY_MULTIPLIER, 0.0,0.0,0.0,0.0);}touch_end(integer total_number){llResetTime();llSetTimerEvent(2/45.0);angularvelocity = INITIALANGULARVELOCITY; framestart = (integer)llGetEnv("frame_number");llSetAngularVelocity(<0,0,angularvelocity>, TRUE);}timer(){if ( llGetTime() > STEPTIMETEST ){llSetAngularVelocity(ZERO_VECTOR,TRUE);while ( llGetOmega() != ZERO_VECTOR ) llSleep( 1/45.0);llResetTime();}frameend = (integer)llGetEnv("frame_number");if ( ( llGetOmega() == ZERO_VECTOR ) && ( frameend - framestart > 3 ) ){llOwnerSay(llList2CSV(["angularvelocity", RAD_TO_DEG* angularvelocity, "frames", frameend-framestart ]));angularvelocity -= STEPANGULARVELOCITY; if ( angularvelocity > 0.0 ){framestart = (integer)llGetEnv("frame_number");llSetAngularVelocity(<0,0,angularvelocity>, TRUE);}else {llSetTimerEvent(0.0);llOwnerSay("end test");}}}}

 

Results

 

angularvelocity, 28.647890, frames, 228[16:25] test setangularvelocity - low angular velocity: angularvelocity, 28.074932, frames, 230[16:25] test setangularvelocity - low angular velocity: angularvelocity, 27.501976, frames, 229[16:25] test setangularvelocity - low angular velocity: angularvelocity, 26.929018, frames, 227[16:25] test setangularvelocity - low angular velocity: angularvelocity, 26.356062, frames, 228[16:25] test setangularvelocity - low angular velocity: angularvelocity, 25.783104, frames, 227[16:25] test setangularvelocity - low angular velocity: angularvelocity, 25.210146, frames, 210[16:25] test setangularvelocity - low angular velocity: angularvelocity, 24.637190, frames, 228[16:25] test setangularvelocity - low angular velocity: angularvelocity, 24.064232, frames, 227[16:25] test setangularvelocity - low angular velocity: angularvelocity, 23.491274, frames, 227[16:26] test setangularvelocity - low angular velocity: angularvelocity, 22.918318, frames, 228[16:26] test setangularvelocity - low angular velocity: angularvelocity, 22.345360, frames, 226[16:26] test setangularvelocity - low angular velocity: angularvelocity, 21.772404, frames, 228[16:26] test setangularvelocity - low angular velocity: angularvelocity, 21.199446, frames, 227[16:26] test setangularvelocity - low angular velocity: angularvelocity, 20.626488, frames, 227[16:26] test setangularvelocity - low angular velocity: angularvelocity, 20.053532, frames, 227[16:26] test setangularvelocity - low angular velocity: angularvelocity, 19.480574, frames, 227[16:26] test setangularvelocity - low angular velocity: angularvelocity, 18.907618, frames, 228[16:26] test setangularvelocity - low angular velocity: angularvelocity, 18.334660, frames, 227[16:26] test setangularvelocity - low angular velocity: angularvelocity, 17.761702, frames, 228[16:26] test setangularvelocity - low angular velocity: angularvelocity, 17.188745, frames, 226[16:26] test setangularvelocity - low angular velocity: angularvelocity, 16.615788, frames, 227[16:27] test setangularvelocity - low angular velocity: angularvelocity, 16.042831, frames, 228[16:27] test setangularvelocity - low angular velocity: angularvelocity, 15.469873, frames, 227[16:27] test setangularvelocity - low angular velocity: angularvelocity, 14.896916, frames, 227[16:27] test setangularvelocity - low angular velocity: angularvelocity, 14.323958, frames, 227[16:27] test setangularvelocity - low angular velocity: angularvelocity, 13.751000, frames, 228[16:27] test setangularvelocity - low angular velocity: angularvelocity, 13.178042, frames, 228[16:27] test setangularvelocity - low angular velocity: angularvelocity, 12.605084, frames, 226[16:27] test setangularvelocity - low angular velocity: angularvelocity, 12.032126, frames, 227[16:27] test setangularvelocity - low angular velocity: angularvelocity, 11.459168, frames, 228[16:27] test setangularvelocity - low angular velocity: angularvelocity, 10.886210, frames, 221[16:27] test setangularvelocity - low angular velocity: angularvelocity, 10.313251, frames, 6[16:27] test setangularvelocity - low angular velocity: angularvelocity, 9.740294, frames, 205[16:27] test setangularvelocity - low angular velocity: angularvelocity, 9.167336, frames, 22[16:27] test setangularvelocity - low angular velocity: angularvelocity, 8.594378, frames, 93[16:27] test setangularvelocity - low angular velocity: angularvelocity, 8.021420, frames, 114[16:27] test setangularvelocity - low angular velocity: angularvelocity, 7.448462, frames, 22[16:27] test setangularvelocity - low angular velocity: angularvelocity, 6.875504, frames, 49[16:27] test setangularvelocity - low angular velocity: angularvelocity, 6.302546, frames, 40[16:28] test setangularvelocity - low angular velocity: angularvelocity, 5.729589, frames, 40[16:28] test setangularvelocity - low angular velocity: angularvelocity, 5.156631, frames, 48[16:28] test setangularvelocity - low angular velocity: angularvelocity, 4.583673, frames, 51[16:28] test setangularvelocity - low angular velocity: angularvelocity, 4.010715, frames, 63[16:28] test setangularvelocity - low angular velocity: angularvelocity, 3.437758, frames, 68[16:28] test setangularvelocity - low angular velocity: angularvelocity, 2.864800, frames, 68[16:28] test setangularvelocity - low angular velocity: angularvelocity, 2.291842, frames, 30[16:28] test setangularvelocity - low angular velocity: angularvelocity, 1.718884, frames, 5[16:28] test setangularvelocity - low angular velocity: angularvelocity, 1.145927, frames, 68[16:28] test setangularvelocity - low angular velocity: angularvelocity, 0.572969, frames, 36[16:28] test setangularvelocity - low angular velocity: angularvelocity, 0.000011, frames, 36[16:28] test setangularvelocity - low angular velocity: end test

 

In the both motions , with llsetangularvelocity or with llsetkeyframedmotion , the problems appear below 9 degrees per seconds of simulator.
I ve not done a script with llTargetomega , but , by experience , i ve met the same comportment there too.

 

 

No ,  the question is not purely academic :

a clock turning at 60 beats per minute , so 6 degrees per seconds , and everybody can visually count the motions.

It s neither the rotation of a wheel , neither the rotation of a motor, rotations who are undetectable to the sight.

The error on rotations is huge.

Personnaly i have no ideas how developpers on other games deal this case : are they switching non-physics motions ? are they  changing the size of floats ? are they using some accumulators ? are they changing dynamically the interpolation time : not 1/45 per second but 1/22.5 seconds to avoid floating errors?

 

 

The stuttering is done because havarrik does a KFM_LOOP,  and llsetkeyframedmotion will send to the viewer every tiny impulsion. If he did without KFM_LOOP ; the motion will be stopped

 

Link to comment
Share on other sites

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