Jump to content

How do I negotiate a bend with KeyFramedMotion?


Innula Zenovka
 Share

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

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

Recommended Posts

Specifically, if I have a vehicle travelling on a track and it has to negotiate a bend that, when it's completed it, puts my vehicle at a position x metres on its positive x axis and y metres on its positive y axis of where it was then it started,  how do I calculate the angle through which it needs to turn while it's negotiating the curved track so it's facing the right way when it comes out of the bend and onto the straight again?

ETA:  This seems to do the trick -- simpler than I thought, unless I've done something wrong:

I had done something wrong -- see below

 

default
{
    state_entry()
    {
      llSetLinkPrimitiveParamsFast(LINK_THIS,
    [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);
    }

    touch_start(integer total_number)
    {
      // llSetRot(ZERO_ROTATION);
       vector pos = llGetPos();
       vector offset = <2.0,5.0,0.0>;
       vector target = pos+offset*llGetRot();
       rotation r = llRotBetween(<1.0,0.0,0.0>,llVecNorm(<target.x-pos.x, target.y-pos.y,0.0>));//wrong -- see below
       llSetKeyframedMotion([offset,r,5.0],[]); //wrong -- see below
    }
}

 

 ETA 2

ACK.. I was doubly mistaken.   First, I got the formula wrong -- it should be 

 

default
{
    state_entry()
    {
      llSetLinkPrimitiveParamsFast(LINK_THIS,
    [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]);
    }

    touch_start(integer total_number)
    {
       llSetKeyframedMotion([],[]);
       vector pos = llGetPos();
       vector offset = <5.0,5.0,0.0>;
       vector target = pos+offset*llGetRot();
       rotation r = llRotBetween(<1.0,0.0,0.0>*llGetRot(),llVecNorm(<target.x-pos.x, target.y-pos.y,0.0>));
       llSetKeyframedMotion([offset*llGetRot(),r,5.0],[]);
    }
}

 Second, this puts me where I want to be, but I move in a straight line, not along a sector of a curve.   So I am back to where I started.

 

Link to comment
Share on other sites

That's a nice solution, Innula.  I'll have to remember it.  What I have done is much more empirical.  I just pop this script into my vehicle. Then I move the vehicle  manually from one waypoint to the next, adjusting the rotation as I go. At each point, I drop out of edit mode and click the vehicle to record the change in local pos and rot.  When I'm all done, I click and hold to report the whole KFM list in chat.  It saves me calculating anything.  All I have to do is add a time value to each line as I copy it into a notecard or a list in my script later.

list gKFM;vector gOldPos;rotation gOldRot;default{    state_entry()    {        gOldPos = llGetPos();        gOldRot = llGetRot();    }        touch_start(integer total_number)    {        llResetTime();    }        touch_end(integer num)    {        if (llGetTime() > 1.0)        {            integer i;            while ( i < llGetListLength(gKFM))            {                llSay(0,llList2String(gKFM,i));                ++i;            }        }        else        {            vector Pos = llGetPos() - gOldPos;            rotation Rot = llGetRot()/gOldRot;            gKFM += [(string)Pos + "|"+(string)(llRot2Euler(Rot)*RAD_TO_DEG)];            gOldPos = llGetPos();            gOldRot = llGetRot();        }    }}

 

Link to comment
Share on other sites

How did you construct your curve? There is a center point and a radius and an angle. If you don't have that you need to set markers or set a rectangular triangle (prim) and calculate the curve parameters.

Then make a list of waypoints for llSetKeyFramedMotion between starting and ending angle of the curve. Maybe every 2° or 5°? you need to test if it looks smooth enough.

so we have an angle a in deg - like starting at 10° and ending at 100° in a global direction, like a compass increase by 2..5 maybe for every waypoint.
xofs, yofs = center of the curver = radius of the curve

to calculate a point for an angle you do:

x = sin ( a * PI / 180 ) * r + xofs
y = cos ( a * PI / 180 ) * r + yofs

you can get rid of the PI/180 of course when you use radians instead of degrees

The length or the bow is: length = a (in radians) * r

The travel time for the whole curve is: time (s) = length (m) / speed (m/s)

Thats the math. Getting that into LSL is the next step but I'm waaaaayyyy to tired for that :D

 

Link to comment
Share on other sites

Thanks, both.   I think the both of you posted while I was correcting my stupid mistake.

I'm trying to avoid waypoints if I can, at least while negotiating the bend, since I've been asked to help with a vehicle to be sold with its own track pieces.    I am reasoning that when my vehicle reaches a particular piece of track, I can tell it what sort of curve it is, and the script can calculate from that how to negotiate it.   I know, or I will do, the dimensions and angle of each particular type of track, so I was thinking I should be able to work it out from that.   It looks like I will do, using your suggestions as a basis.

 

 

Link to comment
Share on other sites

OK, I see what you're doing.  I tried doing the same thing a while ago where I had pre-cut pieces of curved track that I was going to be using several times.  I ended up laying out a full-size template for each curve piece and then setting waypoints along it, dividing the curve up so that the vehicle would have to rotate the same amount at each waypoint but never more than 10 degrees.  That essentially meant writing a separate KFM path for each curve and then piecing them together in the final script. 

Piecing them together was the tricky part.  I'm still not sure that I did it the smartest way. Because each curve is a separate modular part of the track, I ended up having to sense the global rotation and position of a marker prim at the start of each curve and using that to begin the curve's KFM segment. Stopping one KFM segment and passing control to the next one smoothly was a bear of a job. 

Link to comment
Share on other sites

Thanks, irihapeti, that looks really promising!   I was looking for some sort of formula I can simply plug values into, if possible, rather than have to calculate everything with waypoints, and that looks as it if does pretty much what I need to do, at least if the builder I'm working with can make sufficiently regular curved pieces of track.

Link to comment
Share on other sites

if is irregular arc then can plot from current rotation to the end rotation as it moves. Updating the current interpolation(s) in a timing loop

+

another thing that can be done with this (the updating) is when the target is moving (or has moved since previous) as well. Say if is a thread-the-rings course for example . Where the positions and orientation of the ring changes after go thru it. So that the next time round is a little bit different course

is quite a bit more thought/work to get it to do this but can make some pretty interesting stuff this way

Link to comment
Share on other sites

Movement and rotation and independant from each other.

It doesnt matter how you rotate your object. The rotation of the object has nothing to do with the movement of the object. The movement is always in a straight line from point A to point B. If you want to simulate a curve you need to chop the movement into many short little pieces so it will only look like moving in a curve.

The rotation has nothing do do with that movement but of course you need to calculate that so the object will point into the direction of movement. To keep that in sync you need to chop the rotation into the same amount of many little pieces than the movement.

The only way to avoid that is to use physical movement. Then the physics engine and the viewer will do the work for you.

Link to comment
Share on other sites

You have 2 straight lines and want to connect them with a curve. You will always need a mathematical funcion to do that.

Cubic splines will do fine but the math will cause a heavy headache - well - for me. Bezier curves look easier but not sure if that isn't too much for LSL. A circle is very easy to calculate but you need to arrange the center and radius of the circle in a way that your straight lines are tangents to the circle segment. -  If that's not the case it isn't smooth.
You need to calculate the tangent of a given point as well since that gives the rotation for that specific point but thats a piece of cake for a circle.

I'd like to have a function that delivers a waypoint list. I need to think about it. :) Maybe there are easier ways for less accurate results too.

 

 

Link to comment
Share on other sites

Given the radius of the curve and the length of the segment along it (or the length of the chord that defines its endpoints), it shouldn't be hard to write a routine that calculates the relative positions and rotations for waypoints along it.  That's a good idea, Nova.  If I find some free time, I might sit down to do that myself.  I could use a routine like that.

Link to comment
Share on other sites

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