Game Development Community

dev|Pro Game Development Curriculum

Wheeled Vehicle Down Force

by Martin "Founder" Hoover · 06/11/2004 (10:47 pm) · 27 comments

First let me say that I'm really not a programmer, so if there are any obvious blunders, please feel free to tell me.

This is not a proper implementation of downforce. For that you would need to pick a couple points on the front and/or rear of the vehicle model and apply a "downward" force to them. This is much easier as it simply increases the vehicles' gravity as its' speed increases. The first obvious problem this will create is that as the vehicle reaches very high speeds, the downforce will fully compress its' springs, making for a rather bumpy ride. (Though it will still stay stuck to the ground.) To compensate for this I stiffen the springs so the vehicle will still maintain enough of a spring extension to absorb bumps.

First add a new datablock variable so we can control the amount of downforce applied.

In WheeledVehicle.h near the bottom of the definition for WheeledVehicleData add following the sequence variable:

S32 steeringSequence;         // Steering animation

F32 downForce;

Now move into wheeledVehicle.cc.

Initialize the new variable at the bottom of WheeledVehicleData::WheeledVehicleData()

brakeLightSequence = -1;
  downForce = 0.1;

Add a persistent field for it after the brakeTorque in: void WheeledVehicleData::initPersistFields()

addField("downForce", TypeF32, Offset(downForce, WheeledVehicleData));

Now we add it to the datablock pack and unPack methods. If you have not messed with adding variables to the pack/unPack methods, it is important to note that the order in which you pack the variables is the order you must use to unPack them. In this case I chose to add it after brakeTorque.

void WheeledVehicleData::packData(BitStream* stream)

stream->write(brakeTorque);
   
   stream->write(downForce);

Then unPack it.

void WheeledVehicleData::unpackData(BitStream* stream)

stream->read(&brakeTorque);
   
   stream->read(&downForce);

Since I decided to stiffen the springs to compensate for the vehicles extra weight, the calculations must be done early in the updateForces function so it can be used for every wheel/spring combination that has ground contact. Then near the bottom it will be applied to the vehicles gravity.

void WheeledVehicle::updateForces(F32 dt)

Find where the following loop begins...

// Sum up spring and wheel torque forces
   for (Wheel* wheel = mWheel; wheel < wend; wheel++)  {
      if (!wheel->tire || !wheel->spring)
         continue;

Above that insert the following:

//calculate here so we can stiffen the springs a bit based on
   //the final amount of downforce
   //get the speed
   F32 downForce = mRigid.linVelocity.len() <= 1 ? 1 : mRigid.linVelocity.len();
   //grab the datablock var
   downForce *= mDataBlock->downForce;
   //make it a smaller number so we can multiply gravity by it
   downForce = mSqrt(downForce);
   downForce /= 3;
   //ensure that it is not smaller then one, cause mulltiplying gravity by fractions is baaaad
   downForce = downForce < 1 ? 1 : downForce;

// Sum up spring and wheel torque forces
   for (Wheel* wheel = mWheel; wheel < wend; wheel++)  {
      if (!wheel->tire || !wheel->spring)
         continue;

Next, inside the wheel loop find the following:

// Spring force & damping
         F32 spring  = wheel->spring->force * (1 - wheel->extension);

Change to the following:

// Spring force & damping
         F32 spring  = wheel->spring->force * (1 - wheel->extension);
         //Add some stiffness to the springs in accordance with the downforce
         //so we don't bottom out at higher speeds.
         //you can adjust the fraction in the following to stiffen or weaken the springs. Since I am not making a
         //car simulator I have no need to make this adjustable, but it could easily be made a datablock variable
         spring += (spring * downForce) * 0.3f;

Next, to actually apply the extra downforce to the vehicles gravity find:

// Gravity
   mRigid.force += Point3F(0, 0, sWheeledVehicleGravity * mRigid.mass);

Change to:

// Container drag & buoyancy
   //Founder- implement downforce with the gravity to make a nice uniform pressure
   mRigid.force += Point3F(0, 0, (sWheeledVehicleGravity * mRigid.mass) * downForce);

DataBlocks

Now you have a new datablock variable for playing around with the downforce amount. Just slap downforce = x.xx; into a wheeledVehicle datablock and you're set.

A value of 0.01 effectively kills the downforce effect, though if you are very astute you might still notice some downforce at obscenely high speeds.

The most effective range for this is between 0.1 and 1.0, going higher really doesn't gain you much, and if you need it that much higher, you might consider upping the mass of your vehicle.


And now we're done!
My calculations could probably stand some improvements, as they are not based on anything other then achieving numbers that work well for the downforce effect. If you can improve on it, please share.
Page «Previous 1 2
#1
06/12/2004 (3:44 am)
Would you stick to the ground if you try to jump a ramp?
#2
06/12/2004 (5:01 am)
No actually you would go flying through the air. This provides enough downforce to make for a stable ride, but if you hit too big of a bump (or something like a ramp) you will go airborne.
#3
06/13/2004 (6:34 am)
Looks like helpful code, especially to people who are doing racing games, and don't want the vehicles flying around....
#4
06/14/2004 (12:37 pm)
Oooh! Thanks! This also helps things like tanks and other heavier vehicles. You don't want those bouncing around like some kind of lightweight buggy.

Increase the vehicle's overall mass will help, but I found that my tank would still tumble around if I went over a steep enough slope. Unless I cranked the mass up really high, which meant it was a bear to get moving...
#5
06/17/2004 (3:29 pm)
I just added a little blurb above about the range of numbers to use for the new datablock parameter for this. Should give everyone an idea of where to start with it.
#6
07/16/2004 (5:39 am)
Thanks thats nice. will a negative number make less gravity?
#7
07/16/2004 (12:58 pm)
Yes it will, however it is currently setup to not allow negative values, or any value lower then 1.

You would need to comment out the line that reads:

downForce = downForce < 1 ? 1 : downForce;

Though I must warn you, when wheeled vehicles don't have enough gravity force (mass * gravity value) the tires get very little traction and it tends to float off the terrain.
#8
07/17/2004 (5:23 am)
thanks, with tanks is it a whole different class name to do treads cause this is wheeled vehicles class right?
#9
07/17/2004 (11:21 am)
Yes this is for wheeled vehicles, but could easily be applied to any class that uses gravity. The main idea being to increase the vehicles' mass as its' speed increases.
#10
07/17/2004 (5:17 pm)
Would the engine do the tread animatian for me...
And whats the class name?
#11
07/17/2004 (5:52 pm)
There is no class for tanks in base Torque, thus there is no special support for tread animations. However, before very long, Bravetree should be releasing their tank content pack which is based off their class from Think Tanks. Personally, I would suggest working on other aspects of your game while waiting for the content pack, then use it as the basis for your own.
#12
07/17/2004 (6:00 pm)
1. Will it be free?

2. On power-ups and objects what does elasticity do?

3. My game will be futuristic I guess I will make'em hover

4. Thanks a lot.
#13
07/17/2004 (6:08 pm)
Can you have up force? That would be sweeeeeet!!! Hit a bump and boom ten feet off the ground...
#14
07/17/2004 (7:33 pm)
1) No. I imagine it will be in the $20-30 range, but cannot say for sure. Also it will probably be directed more toward TGE owners, though they may include a demo with the included changes, if not, it won't do you much good to purchase it unless you have a Torque lisence.

2) Used to simulate the physical property of an object's collision elasticity. In physical collisions, resultant velocity is scaled by elasticity. Valid range is 0 to 1. Supposedly, the more elastic it is, the more it bounces.

3) Cool, interesting things can be done with hovers.

4) no problemo.
And in answer to your last...
Sure you can have upforce, but it might be a bit tricky to implement for wheeled vehicles. If you don't have enough mass and gravity, you don't get much friction so the tires can hardly move the vehicle. Of course you could decrease the gravity as the vehicle goes faster, then it would go flying from the least little bump, but you would also go flying if you turned very sharp.

Now hovers do have the capability to do the behaviors you describe, so they may very well be just what you are looking for. :)
#15
07/19/2004 (6:41 am)
like in halo is that why the warthog peels out or is that lack of traction?
#16
07/19/2004 (10:05 am)
Well, I imagine Halo's phyics are a bit different then Torques'. The TGE wheeled vehicle physics are pretty generic, and not real accurate the way a simulator is. That's not to say they are bad, they just need some tweaks. (Actually it's a good thing the vehicle physics are generic, that way they are easy to modify to fit your game.)

In any case, for Halo I imagine it's a case where the power going to the wheels overcomes the tire friction until the vehicles' speed catches up to the wheel speed. I kind of doubt that the gravity/mass is too low, but then again, I have not ever looked into the guts of that game.
#17
07/19/2004 (10:22 am)
thanks
#18
10/05/2004 (9:21 am)
Mmmm, could you add this to planes?
#19
10/05/2004 (3:51 pm)
Well yeah, this can be added to basically anything that moves, but I would question applying it to fliers. This method applies more downforce the faster the vehicle travels. If you are wanting a flier to have the tendancy to fall to earth I would suggest to start by playing with the gravity for the class. (It should be near the top of the .cc file)
#20
02/11/2005 (3:03 am)
Page «Previous 1 2