Saturday, February 04, 2006

Looking at solutions

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.

Me with rocket launcher

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.

Crucible rocket

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?


Post a Comment

<< Home