Jump to content

llMoveToTarget Judder


giniskinnytart
 Share

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

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

Recommended Posts

I am sure I am missing something obvious but I'll ask anyway.

I am scripting a very simple lift (elevator) and thought I would try using a touch-activated llMoveToTarget to move the thing up and down; the target vector being where I want the lift to stop; the tau value being calculated to move the lift up/down at 1m/s.

And I have to say it works beautifully, apart from one minor annoyance. On reaching the desired floor level, my lift doesn't stop as I was expecting, but sort of judders up and down indefinitely by some tiny fraction of a metre. Is there any way to stop that?

I have tried using llStopMoveToTarget() after the llMoveToTarget call (with and without a little llSleep and a llSetPos, hoping to fix the final position that way) but that appears to disable all movement so my lift remains in its  original position.

Thoughts anyone?

I know there are other ways to move my lift but llMoveToTarget seemed so beautifully simple, I am reluctant to give up on it unless I absolutely have to. 

 

 

 

Link to comment
Share on other sites

MoveToTarget is a physics engine function and those are inherently imprecise, I wouldn't use those for an elevator. The tau parameter is more of a request to reach the destination in tau seconds and depending on distances and other physics conditions might happen early or not at all (resulting in vibration).

For a simple elevator that's not running all the time I'd just skip the physics engine and do SetRegionPos movement in steps, it might not be as elegant as a single call but it's not far. Keyframed motion would be most elegant, but it's annoying to set up.

default
{
    touch_start(integer _) {
        vector here = llGetPos();
        // assign random location within a 1m cube as destination
        vector there = here + <llFrand(2), llFrand(2), llFrand(2)> - <1, 1, 1>;

        integer step;
        // granularity of movement
        integer max_steps = 10;
        // delay = travel time/max steps
        float delay = 1.0/max_steps; 
        float interpolation;
        for(step = 0; step <= max_steps; ++step) {
            interpolation = (float)step/max_steps;
            // lerp between locations
            llSetRegionPos((1-interpolation)*here+interpolation*there);
            llSleep(delay);
        }
    }
}

You could of course move the loop into a timer to allow other events to happen during movement and optimize away many of the variables.

Edited to amend: I didn't really consider fully that it's an *elevator* , position warping doesn't really move any unseated avatars on the object and relies on bounding boxes to make sure no one clips into the elevator floor while moving up and everyone will constantly fall a little while moving down, so it's not the cleanest looking... might want to do the llTarget+events approach as suggested by Qie after all.

Edited by Frionil Fang
  • Like 1
Link to comment
Share on other sites

38 minutes ago, Qie Niangao said:

Are you handling the at_target event? If you check that event handler's sample code you'll find where llStopMoveToTarget should work in this case.

Short answer. no! Smacked bottom for my research assistant I think, for failing to mention that such an event exists. 

So thank you Qie! Given that my next question was going to be "How does one know when an object has reached its target?", I think you have just solved my problem. :D

PS: Thanks anyway, Frionil Fang. Your method is how I normally move stuff but llMoveToTarget just struck me so much more elegant.

PPS:  And thank you, elleevelyn. That is my plan! 

Edited by giniskinnytart
  • Like 1
Link to comment
Share on other sites

This seems pretty much solved, but my own 2 cents:

  • Make sure your elevator has gravity set to 0 (there is a known "bug" where gravity affects how long llMoveToTarget takes), high mass/density, and rotation turned off (see llSetStatus and PhysicsMaterial)
  • Turn physics off when the elevator isn't moving (llSetStatus(STATUS_PHYSICS,FALSE);), turn it on before it does move.
  • I vaguely remember someone complaining that the at_target() event didn't always fire correctly some years ago. the fix is of course a timer and then when you 'should be' at the destination, turn physics off, then llSetRegionPos() to the final destination.
  • IIRC llMoveToTarget speeds up and then slows down as it moves from a to b. For extremely long distances, this can be less than ideal (too slow on the ends (why isn't it moving yet?) and/or too fast in the middle (shaky ride) )
Edited by Quistess Alpha
  • Like 1
Link to comment
Share on other sites

1 hour ago, Quistess Alpha said:
  • IIRC llMoveToTarget speeds up and then slows down as it moves from a to b. For extremely long distances, this can be less than ideal (too slow on the ends (why isn't it moving yet?) and/or too fast in the middle (shaky ride) )

Yeah, it can only handle targets within 65m, so I remember kludging around that with a sequence of calculated hops and intermediate llTarget()s to get a reasonably smooth ride to the "real" target.

The operative word here being "remember" because I don't think I've used llMoveToTarget since llSetKeyframedMotion which, while not physical, seems to move the avatar along with the object at least as well as the alternatives. (On the other hand, the smoothly damped motion of llMoveToTarget, if that's valuable, is more work to emulate with KFM.)

  • Like 2
Link to comment
Share on other sites

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