Jump to content

Question: Updating rotation speed with llTargetOmega


Vic Taurog
 Share

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

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

Recommended Posts

I'm making an anemometer and would like the speed of rotation to be updated as the wind changes speed.  I tried doing this by essentially putting llTargetOmega in a timer event and update the rotation speed every second or so.

 

I had thought that the rotation speed would just be updated from wherever the rotation happened to be at the time of the call.  Unfortunately, the prim seems to reset itself to the zero position every time the call is made.  Is there any way around this with llTargetOmega to be able to achieve a smooth rotation speed while being able to update the speed regularly.

 

I thought of using the rotation abilities within llSetLinkedPrimitiveParamsFast (like llSetRot or llSetLocalRot) but this seems significantly more complicated and would look jerky unless I tripped the event at a pretty good clip.

 

Does anyone have any suggestions on how to update the rotation speed of a prim so that it looks pretty smooth?

Link to comment
Share on other sites

You may get smoother results if it's physical. llTargetOmega switches to server-side motion in that case. llSetAngularVelocity can also be good for something like this that receives frequent changes, the slowdown is very gradual and virtually invisible with regular refreshes. Set it phantom, use llSetStatus to turn off X and Y movement, and you'll need a bit llMoveToTarget to nudge it into its intended place.

Link to comment
Share on other sites

Hi Vic,

Rolig Loon was having trouble with llTargetOmega, which prompted me to code up a quick experiment. I sent you a copy of it, which produces the sort of rotation changes you desire. Why your code doesn't do what you want I can't say, but perhaps my demo will give you some insight.

As I mentioned in my IM to you, be careful about high rotation rates. llTargetOmega is sampled by the scene's frame rate, and if that falls sufficiently, you will see erratic rotation. Imagine your anemometer has three cups and spins three times per second. If you happen to have a frame rate of 9fps, it will appear to stand still, as each cup will have moved to exactly the position of the previous one at each new frame.

Link to comment
Share on other sites

Your particular problem is slightly different from the one I was wrestling with last night and have now hacked my way around.  Your anemometer isn't stalling; it's resetting to its zero location when you change speeds.  That's unfortunately what it is supposed to do.  The rotation is entirely client side unless your object is physical. When you stop the rotation, therefore, the servers are blissfully unaware that you ever did anything.  Your object appears exactly where is was before you applied llTargetOmega

Take a look at the smooth rotating door script that's in the LSL wiki to see one solution.  It will take a bit of work to wrap your head around what's happening, but basically the server is performing stepwise rotations with llSetLocalRot while your client is using llTargetOmega to make the movement look smooth.  It works nicely in a door.  With luck you'd be able to adapt the idea to an anemometer too.

Link to comment
Share on other sites


Rolig Loon wrote:

Your particular problem is slightly different from
and have now hacked my way around.  Your anemometer isn't stalling; it's resetting to its zero location when you change speeds.  That's unfortunately what it is supposed to do.  The rotation is entirely client side unless your object is physical. When you stop the rotation, therefore, the servers are blissfully unaware that you ever did anything.  Your object appears exactly where is was before you applied
llTargetOmega

Take a look at the
script that's in the LSL wiki to see one solution.  It will take a bit of work to wrap your head around what's happening, but basically the server is performing stepwise rotations with
llSetLocalRot
while your client is using
llTargetOmega
to make the movement look smooth.  It works nicely in a door.  With luck you'd be able to adapt the idea to an anemometer too.

Rolig, I haven't observed the behavior you mention. Long go, I scripted a globe that could be set to rotate once per day/SL day/hour/minute. The globe never reset to zero on a speed change, but just took on the new speed from whatever orientation it currently had. The little demo I created this morning also works that way for me. I have seen objects swing around to zero before starting to spin, but I've no idea what makes that happen and have not observed it in the few spinny things I've made.

There's something going on here we may not yet have our finger on.

Link to comment
Share on other sites

I have just been searching for a thread that I thought was in this forum within the past year.  The OP asked this same question and there was a lot of debate about whether the observed snap back to zero position was a bug or "expected behavior".  The consensus was "expected".  Now I can't find the thread, which either means that I imagined it or that it was in another forum (SLU?), or that I simply haven't looked hard enough.  In any case, your little experiment does add a layer of confusion because you are managing to stop rotation speed without snapping back to the zero position.   I'm momentarily at a loss.

Link to comment
Share on other sites

I have noticed two things that causes a snap back to zero (most likely other things can cause it as well):

Using more than one state - upon re-entering the default state, the snap back would happen. I don't remember if I also reset to ZERO_ROTATION inside the state entry or not, but I might have - I believe it was happening either way;

Upon reset of a script in the prim - doesn't have to be the same script that is setting the rotation. I was resetting a script to release animation permission when an avatar stood which then caused the snap back even though it was a different script.

Link to comment
Share on other sites


Erik Verity wrote:

I have noticed two things that causes a snap back to zero (most likely other things can cause it as well):

Using more than one state - upon re-entering the default state, the snap back would happen. I don't remember if I also reset to ZERO_ROTATION inside the state entry or not, but I might have - I believe it was happening either way;

Upon reset of a script in the prim - doesn't have to be the same script that is setting the rotation. I was resetting a script to release animation permission when an avatar stood which then caused the snap back even though it was a different script.

I've never done either of those things in my creations (except resetting when editing), so that would explain my not seeing snap-back if you're right. My scripts are generally quite simple. I got the impression Rolig's was rather complex, so there may be opportunity for something else to happen which triggers a rezero of the object's local rotation.

Link to comment
Share on other sites

Thanks for all your comments folks.  You all got me thinking that perhaps there was something more to this than I had assumed.  

Actually my build and script is quite a bit more complicated than what I suggested here.  It's more like a windmill with a propeller and a tail to keep it oriented to the wind direction.  So besides rotating the "propeller" I'm also constantly rotating it around a point relative to a shaft to keep it aligned with the wind direction.  The propeller revolves around a fixed point in the build while also rotating around its own axis.  I did all this as an excersise in learning how to do rotations better.  The story of my life is to take on a project that is quite complicated before learning the basics.

 

You all forced me to go back to the basics.  I wrote this little script as an experiment:

 

//Experiments with rotations, translations and llTargetOmega
//Vic Taurog

//This was done on a disk whose axis of rotation is along the z axis

float anglePerPeriod = 0.2; // in radians
float TIMERPERIOD = 2.0;

integer isOn = FALSE;

default
{
state_entry()
{
llSetLinkPrimitiveParams(0,[PRIM_ROTATION, ZERO_ROTATION, PRIM_OMEGA, <0.0,0.0,1.0>, 0.0, 1.0]);
}

touch_start(integer total_number)
{
if (!isOn)
llSetTimerEvent(TIMERPERIOD);
else
{
llSetTimerEvent(0.0);
llSetLinkPrimitiveParams(0,[PRIM_OMEGA, <0.0,0.0,1.0>, 0.0, 1.0]);
}
isOn = !isOn;
}

timer()
{
float radiansToRotate = anglePerPeriod * TIMERPERIOD;
float omega = anglePerPeriod / TIMERPERIOD;
rotation rot = llGetRot() * llEuler2Rot(<0.0,0.0, radiansToRotate>);
rotation otherRot = llGetRot() * llEuler2Rot(<0.0,0.0, 1.0>);


// llSetLinkPrimitiveParamsFast(0,[PRIM_ROTATION, rot]);
// llSetLinkPrimitiveParamsFast(0,[PRIM_OMEGA, <0.0,0.0,1.0>, omega, 1.0]);
// llSetLinkPrimitiveParamsFast(0,[PRIM_ROTATION, ZERO_ROTATION, PRIM_OMEGA, <0.0,0.0,1.0>, omega, 1.0]);

// llSetLinkPrimitiveParamsFast(0,[PRIM_ROTATION, otherRot, PRIM_OMEGA, <0.0,0.0,1.0>, omega, 1.0]);
// llSetLinkPrimitiveParamsFast(0,[PRIM_POSITION, llGetPos()+<0.1,0.0,0.0>, PRIM_OMEGA, <0.0,0.0,1.0>, omega, 1.0]);
// llSetLinkPrimitiveParamsFast(0,[PRIM_POSITION, llGetPos()+<0.1,0.0,0.0>, PRIM_ROTATION, rot, PRIM_OMEGA, <0.0,0.0,1.0>, omega, 1.0]);
llSetLinkPrimitiveParamsFast(0,[PRIM_POSITION, llGetPos()+<0.1,0.0,0.0>, PRIM_ROTATION, otherRot, PRIM_OMEGA, <0.0,0.0,1.0>, omega, 1.0]);

}

The only SLPPF call that causes the rotation to skip is the last one where I'm moving the object and rotating it at an angle that is not in synch witht the omega.  In my original script, I was not taking into account of doing an actual rotation around the axis of rotation of the propeller while it revolved and was expecting targetOmega to handle that.  I'll try to incorporate this finding into my original script and let you know how it turns out.

 

Link to comment
Share on other sites

This makes sense, Vic. I could imagine that, during creation of the viewer, the designers found it easier to start from zero whenever the prim containing llTargetOmega actually moved, than to do the coordinate conversions on the current rotation.

Rolig also noticed that script resets and touch events on the prim reset the position. Resets make sense, and it could be that the touch event rezeros the prim so that functions like llDetectedTouchFace can work. If the servers don't know the current viewer rotation of a spinning prim, they can't determine which face has been touched, so they cause the viewer to rezero the prim to obtain agreement with the server model of the scene.

So, we may have an explanation for snap back of llTargetOmega prims, but we're still without an explanation for Rolig's observation that some llTargetOmega calls simply don't seen to stick.

Link to comment
Share on other sites


Madelaine McMasters wrote:

[ .... ]

So, we may have an explanation for snap back of llTargetOmega prims, but we're still without an explanation for Rolig's observation that some llTargetOmega calls simply don't seen to stick.

That has to be a bug in the viewer code.  I can get errant prims to rotate properly if I right click on them or if I either TP away from the sim or relog.  Or if I stop llTargetOmega totally (llTargetOmega(ZERO_ROTATION,0.0,0.0) ) and wait for a second or more before restarting the rotation. For my immediate purposes, that's enough of a fix, but it would be nice to not have the bug to deal with.

Link to comment
Share on other sites


Rolig Loon wrote:


Madelaine McMasters wrote:

[ .... ]

So, we may have an explanation for snap back of llTargetOmega prims, but we're still without an explanation for Rolig's observation that some llTargetOmega calls simply don't seen to stick.

That has to be a bug in the viewer code.  I can get errant prims to rotate properly if I right click on them or if I either TP away from the sim or relog.  Or if I stop
llTargetOmega
totally (
llTargetOmega(ZERO_ROTATION,0.0,0.0)
) and wait for a second or more before restarting the rotation. For my immediate purposes, that's enough of a fix, but it would be nice to not have the bug to deal with.

Rolig, is it that you must stop the rotation, or simply not call llTargetOmega rapidly? I modified that example I sent you to NOT stop rotation and it still works every time.

Link to comment
Share on other sites

Yiou're right.  It's not the stopping that counts.  It's the delay.  The viewer seems to need time to think about your request. It's as if there is some undocumented delay in llTargetOmega that can sometimes prevent a change from being processed if the viewer has something else to do at the time.  As LepreKhaun commented in a different thread, this is a recognized problem with llSetTextureAnim as well.

Link to comment
Share on other sites

I modified the code in my original project so the "propeller" actually gets rotated by an angle proportional to the windspeed within the timer period.  So the prim rotates to actually keep in sync with the omega part.  Result is that it now rotates smoothly.

Here's a picture of my prototype "weather vane" for those having trouble visualizing what I am doing.  The excercise was to build this using rotations relative to the base so that I could rotate or resize the base and it would keep working fine.WeatherVanePrototype_001.png

As for Rolig's problem, I can't help but think that it's related to the recent problem of objects a first appearing invisible until you right click on them.  Somehow the viewer is not getting the message to redraw the screen until you right click it.  Perhaps when LL solves the invisible prim problem, Rolig's problem will be solved too.

Link to comment
Share on other sites

Nice work, Vic!  I love these practice problems.  That's a good one.

As for my own, I doubt that it has anything to do with the invisible objects issue, which is a fairly recent annoyance.  That one is recognized as a problem in rendering priorities, something that wasn't much of an issue until LL started moving everything over to Server Side Appearance last winter. The issue with llTargetOmega and llSetTextureAnim has been around in one form or another for much longer.  At least, I can find questions about it (but no helpful answers) in forum archives.  It seems to be expected (though annoying) behavior.  For the purposes of my current project, I'm satisfied with being able to build in a short pause to work around it.

Link to comment
Share on other sites


Vic Taurog wrote:

As for Rolig's problem, I can't help but think that it's related to the recent problem of objects a first appearing invisible until you right click on them.  Somehow the viewer is not getting the message to redraw the screen until you right click it.  Perhaps when LL solves the invisible prim problem, Rolig's problem will be solved too.

Yeah, I wondered if this was another "interest list" issue, but I figured that if the viewer knew it should be drawn, it would know it should be rotated.

I love the windmill, Vic!

;-)

Link to comment
Share on other sites

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