I tried and could not get the physics engine to move smoothly. On SL I have used llMoveToTarget, but it never was designed for linear motion, it always decays. (There is that trick everyone uses in SL of telling it to move twice as far as you want, then stopping it and re-starting it half way.) I experimented with it in OpenSim and it behaves very strangely. Not even moving in straight lines on long moves, and running away from me on short moves. Does anyone have experience with llMoveToTarget that will help?
llKeyframedMotion is not implemented on OpenSim yet. So what is a scripter to do?
I tried running my movements more often by giving llSetTimerEvent small time steps. But I discovered that no matter what value I give it, it never triggers timer() more often than once every 0.5 seconds. What is with this? llGetRegionFPS() says that my server FPS is 53, which should allow a timer of 0.01 seconds. Is 0.5 some configuration setting?
So in desperation, I llSetTimerEvent(0.5) and then moved my build 5 times every timer event with a llSleep(0.1) after every move (except the last one). This is not ideal, but the best I have found so far. Below is a sample script that does this. Now imagine 200 lines of code instead of that dumb circle calculation. Then imagine inside the for loop I also interpolate the rotation of the build so that it always faces the direction it is moving. I have some nice swimming and flying critters that use this and avoid or chase avatars, stay inside the parcel they are over, avoid running into the ground, stay above or below the water, etc.
Everything works great for a while, then I discovered that when too many of these things are running they all start to move in spits and starts. It turns out that when I ask for a timer of 0.5 seconds, sometimes I get 1.0 or even 2.0 seconds. Meanwhile llGetRegionTimeDilation() is always returning 1.0. Ignoring that, I'm still apparently exceeding some sim resource limit. But What can I do? Must I abandon building things that need a script to move then around?
Code:
//sort of smooth motion test. Put in a small sphere above the ground
// (to give it room to move without running into the terrain)
vector origin;
vector radius=<2,0,0>;
default
{
state_entry()
{
origin=llGetPos();
llSetTimerEvent(0.5);
llGetAndResetTime();
}
timer()
{
llSetText(llGetSubString((string)llGetAndResetTime(),0,3),<0,1,0>,1);
vector old=radius;
//Believe it or don't, the following two lines implements “circular” motion
//Try to guess why!
radius.x = radius.x + radius.y/8.0;
radius.y = radius.y - radius.x/8.0;
integer i;
vector del=(radius-old)/5.0;
for (i=1;i<=5;i++) //break each timer call up into 5 micro-steps
{
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,origin+old+del*i]);
if (i<5) //don't sleep on the last one, the timer will come back then
llSleep(0.1);
}
}
}