Edit: Turning problems detailed in this post have been solved, and some of the conclusions proved incorrect - see above.---
One would think that
llLookAt
and
llRotLookAt
would be the ideal functions for use with a guided physical projectile that one wishes to have pointing in a certain direction. Certainly,
in the wiki, it says "this function works for both physical and non-physical objects".
Does it? No, unless I'm doing something horribly wrong.
This evening I have been engaging in a little rocket science, trying to build a projectile that
(a) accelerates constantly in the direction that it is pointing until it runs out of fuel. This is fairly straightforward, it just requires using
llSetForce
. I added in a drag co-efficient that represents air resistance, proportional to the current velocity, as well, so as to limit the speed.
(b) moves to point in the direction that it is moving in, more or less. (Aerodynamic objects tend to do this - think paper aeroplanes.) It's easy to make vehicles do this, there are automatic parameters to set, but for physical objects I can't see any mechanism apart from applying a force or impulse myself. And that's where I'm having the problem.
First things first; the basic motor. (I was told earlier on today that I didn't post enough code examples so I'm doing a little of that now.) Here are my global variables:
float gFuel; // current fuel
float gFuelMax = 10.0; // seconds of flight time
float gMaxSpeed; // calculated based on FPS
float gAcceln = 10; // metres per second per second
float gTimer = 0.2; // check every X seconds
On entry,
gFuel
is set to
gFuelMax
, and
gMaxSpeed
... well, that is set to
llGetRegionFPS() * 1.5
. Why? Well, the rocket itself has an invisible central prim that is 1.5m long, for collision detection, and I am assuming that
llGetRegionFPS()
will give me the physics framerate. Any faster than the above and there will be "gaps" between the positions of the rocket meaning that a collision might not be detected. See the previous post that I made about bullets for more on this.
Anyway, also on entry we set a timer with a frequency of
gTimer
. All that the timer event does is call
set_engine(llRot2Fwd(llGetRot()))
, to set the engine going in the rocket's current forward direction.
set_engine
is a function that takes a direction as a parameter and consists of the following code:
set_engine(vector dir)
{
vector vel = llGetVel();
vector drag = vel / gMaxSpeed;
llSetForce((dir - drag) * gAcceln * gTimer, FALSE);
gFuel -= gTimer;
if (gFuel <= 0) explode();
}
The value of the vector
drag
varies depending on the current velocity, and is a push in the opposite direction to the rocket's current
movement - note, not the direction parameter sent to the function. At maximum speed,
drag
will have a magnitude of 1, which should cancel out the rocket motor if that is acting in that direction. Okay, the drag should really be different for different directions, since the forward drag on a rocket is much less than the drag on other axes, but give me a break, it's only alive for a few seconds. Er, I mean, that's an optional project for advanced students.
That all works fairly well it seems. The problem is that the rocket should really turn in the direction of movement - real rockets do that. Only I can't seem to get that working. I can't use
llSetRot
, that's only for non-physical objects, and when I try to use
llLookAt
or
llRotLookAt
, they just don't do anything at all. I tried building a sensor object that used those functions to look at the nearest avatar to test this. When it was non-physical, it turned fine (and I've used this many times before). When it was physical, it just didn't move.
I don't know if I'm screwing up some parameters or not - I'm
sure I've used
llLookAt
with physical objects before - but it is annoying me greatly at the moment. Once I find a solution (if ever) that doesn't involve the use of
llApplyRotationalImpulse
, which I don't understand and which scares me, I'll post something on the matter.
As a post scriptum,
hold_R_bazooka
is all very well as an animation, but why on earth does
aim_R_bazooka
have to involve your left hand entirely changing position?