Game Development Community

Possible flying vehicle improvement?

by David Barr · in Torque Game Engine · 05/21/2005 (6:33 am) · 11 replies

I have been digging around in the flying vehicle code to see if I could resolve the annoying tendancy of certain flying vehicles to either not hover in one place when the are stationary at hover height, drift off erratically on their own or sink into terrain/interiors when left to their own devices.

I think I have found the problem in flyingVehicle.cc but thought i would post here first instead of bugs to see if my fix causes any other issues. The code referred to below is still the same in the 1.4 CVS code.


The problem is inside FlyingVehicle::updateForces. In the current code, force is first initialised with gravity acting on the vehicle in the z direction:-

...
Point3F force  = Point3F(0, 0, sFlyingVehicleGravity * mRigid.mass * mGravityMod);
...

This seems a very reasonable starting point since we want our flying vehicle to fall naturally under the influence of gravity BUT, later on in the function, we take the vehicles orientation into account (using zv from getTransform) when applying the hover forces :-

"...
   // Hovering Jet
   F32 vf = -sFlyingVehicleGravity * mRigid.mass * mGravityMod;
   F32 h  = getHeight();
   if (h <= 1) {
      if (h > 0) {
         vf -= vf * h * 0.1;
      } else {
         vf += mDataBlock->jetForce * -h;
      }
   }
   force += zv * vf;

// Damping "surfaces"
..."

Since the vehicle is always at some orientation other than perfectly aligned up/down, this applied hover force includes x and y components and does not therefore cancel out the vertical only gravity force we started out with. The result is that it nevers hovers in one place as I think was the intention of the hovering jet code but moves around while it tries in vain to cancel out gravity (and generally does all sorts of strange things).

To fix this, first you need to set up the initial force variable to include gravity in the same manner that the 'anti gravity' force for hover is calculated later in the code.


At the beginning of FlyingVehicle::updateForces where force is initialised :-

"...
//Point3F force  = Point3F(0, 0, sFlyingVehicleGravity * mRigid.mass * mGravityMod); //Hover fix
Point3F force  = Point3F(0, 0, 0);
F32 vf = -sFlyingVehicleGravity * mRigid.mass * mGravityMod; //vf def moved to here
force += zv * -vf;  //gravity force now in relation to orientation
..."

This change sets up the initial gravity force to take into account orientation. I have moved the definition of vf to this point in the code so I can use it here as well as later in the function. The original definition of force is commented out in the snippet above and the new lines added immediately after.


Further down FlyingVehicle::updateForces, we change the Hover Jet part of the function.

The new code looks like this :-

"...
   // Hovering Jet
   F32 h  = getHeight();
   if (h <= 1) { //true if we are hovering
      if (h > 0) {
         vf -= vf * h * 0.1;
      } else {
         vf += mDataBlock->jetForce * -h;
      }
   force += zv * vf; //cancel oriented gravity, scaled to hover
   }
   else //we are not hovering so change gravity back to vertical
   {
   force += zv * vf; //cancel oriented gravity
   force +=Point3F(0,0,-vf); //add z component of gravity only
   }

   // Damping "surfaces"
..."

In the snippet above if we are hovering we apply an oriented hover force to cancel out our initial
oriented gravity. If we are not hovering, we remove our oriented gravity and apply vertical gravity instead. Notice that the braces are now slightly different from the original code.

With this change, flying vehicles hover in one place when at their hover height and fall under gravity when above hover height. I have noticed less of a tendancy for the vehicle to disappear into terrain and/or surfaces after this fix but it will still do it if you try hard enough.

Now, if only someone could fix the collision freezing as well :)

#1
05/21/2005 (1:17 pm)
Cool beans. I've put this on the list to look at when I get back into TGE mode. Thanks for the research!
#2
05/21/2005 (3:12 pm)
The collision freezing is, I believe, a result of inaccuracy in the collision detection. There is a vehicle datablock property in Torque (Ben, help me out here, please! :p), I think it is called "integration" which controls how often the engine does a collision check. If the time between collision checks is too long, the vehicle gets a chance to fly too far (because it's speed is too high) and therefore to get stuck because the engine did not detect the collision at the right time. Second, there is a property called "collisionTol", which controls the collision tolerance. You can probably decrease the chance of your vehicle getting stuck by tweaking these values.
#3
05/21/2005 (5:01 pm)
David,

Good going. I'm happy someone else is also looking the flying/hover vehicles!

Quote:
The collision freezing is, I believe, a result of inaccuracy in the collision detection.

The problem is that flying/hover vehicles integrates forces into the rigid body after resolving their collisions. This does not apply to the wheeled vehicles, because they applied their own collision solution rather than deriving from the base vehicle code (which is broken). If you apply large enough forces to the vehicle, you could potentially break the algorithm and head trough the surface of an object.

This was most visible on terrain, but also on DIF interiors, and to some degree DTS shapes. You'll head into an infinite loop and the engine will crash. Anything that doesn't change this bug is just a workaround, especially be wary of solutions that propose increasing the integration rate.. which just causes more steps involving smaller forces, which in return only makes the problem worse and also lags down the server and client if you have alot of these objects.

I'll quote Brad Shapcott on the problem from our email conversation:
Quote:
The step I believe needs to be made is to supress small forces, because
these can be spurious due to precision errors in force and torque calculations,
but these errors get into a feedback loop and cause the NaN problems I've seen
mentioned. This usually can be solved by tinkering with the datablock, but the
concern is the NaN problem appears for what should be reasonable value for
physical properties.

One of the most promising suggestions I saw on the forums was changing
ConvexFeature::testVertex, which appears reasonable on first blush.

Edit:

This might be to some use for you if you're going to continue working on the physics code.
#4
05/21/2005 (6:16 pm)
Nonetheless, anything that stops the weird behaviour of falling flying vehicles is great. The feeling is more akin to falling down an invisible hill (often backwards), rather than dropping out of the sky.

Good work David, I might play around with this when I have more spare time.
#5
05/22/2005 (1:46 am)
@Stephan - I remember posting an 'integration fixes flying problems' type post when I was new to the code - much to your annoyance ;) Hope this makes up for it a bit - I think I will dig some more.

@Vernon

You can tweak the amount of gravity quite easily now that its separate from the hover -

force +=Point3F(0,0,-vf); //add z component of gravity only

That is where normal gravity is put into the force calculations (in the hover jet code above). If you want it to drop like a stone then just put more -vf in there. For a space sim you could comment that line out and let the hover code just take care of parking your flyer above a surface when docked (which is the main thing I am using it for now).

If you do tweak gravity, you may need to adjust your hovering power as you could end up coming down a bit faster than the hover can correct for. You do this by adjusting the 'jetForce' value in the flyers datablock (mine is 3000 for a mass 500 vehicle).

It may also be worth checking to see that there actually is a jetForce value in your datablock because it defaults to 500 if you dont specify anything which is a bit low for good hover control. I know for a fact (I am using it) that the standard warsparrow datablock does not come with a jetforce var.
#6
05/23/2005 (11:46 am)
Sounds like you found a way to work around this bug that I fixed seven months ago which still has not been updated in 1.3 or 1.4.


In FlyingVehicle.cc, at line 523 in the FlyingVehicle::getHeight() function, replace this line....


if (!mContainer->castRay(sp,ep,0,&collision))


with this line...


if(!mContainer->castRay(sp, ep, ~TerrainObjectType, &collision) == true)



www.garagegames.com/blogs/18447/6615


Start with the stock code and make that one change and your hover is fixed.
#7
05/23/2005 (12:44 pm)
Gonzo - I put your height fix in while I was searching through flying vehicle threads.

This is what is in my getheight() at the moment :-

..
U32 mask = TerrainObjectType |
              InteriorObjectType |
              StaticShapeObjectType |
              PlayerObjectType |
              VehicleObjectType;
   if (!mContainer->castRay(sp,ep,mask,&collision))
      collision.t = 1;
..

Even with that fix in there the hover forces still seem to be unbalanced with updateForces as it was originally written. My vehicle tried to hover at about the right height but wandered about all over the place due to the x and y forces coming from the hover section of the code. With the change to the hover forces it sits where you put it even on slopes.
#8
07/21/2005 (10:10 pm)
I'm revisiting this stuff... Hmm. Aren't hover vehicles supposed to tend to float around? It seems like it might not be actually correct to make it so they won't slide on a hill.

Anyway, I've checked in Gonzo's fix. Thanks, Gonzo!
#9
07/22/2005 (8:06 am)
@ Ben - Thats why I put it here and not in bugs but it is a flying vehicle not a hover vehicle.

If it was meant to glide down slopes when left to its own devices then I would have thought that the hoverjet code would look to ground slope not vehicle orientation to apply the hover force.


As it is written, the upward force does not cancel out the gravity force. Whether this was the intention or not I have no idea :)
#10
06/12/2006 (2:36 am)
After an hour of googling I will try here..

Does anyone know how (or where I need to look) to make a flyingvehicle remain in constant forward motion.. ie. not stop and hover.. I have yet to find any ideas on using the flyingvehicle in an air environment where if you slow.. you fall..

The warsparrow handles perfectly after some tweaking... but for my project I need to stop the player from coming to a standstill.. or even worse hovering..

maybe an idea on setting up a minimum speed and putting the vehicle in motion using transforms when they first log in..
#11
12/14/2006 (12:36 am)
I'm finding applyImpulse an extremely useful script command. Could be made to do this fairly easily, I think.