Game Development Community

FlyingVehicle maxSpeed

by Guimo · in Torque Game Engine · 09/25/2006 (1:39 pm) · 1 replies

Hi,
I'm creating a space game using the flyingvehicle buy I have a problem with the maxSpeed value. I need to limit the max velocity of the vehicle but can't get it working. Some attributes like maxForwardSpeed just won't work with flyingVehicles.

The docs tell me this about the max speed:

maneuveringForce: The force generated by movements in the x or y (horizontal) directions. Also used to determine the FlyingVehicle's maximum speed, by dividing with minDrag (defined in VehicleData).

minDrag: The minimum drag acting on the vehicle at all times. At present, this field is only used by FlyingVehicleData and helps determine it's maxSpeed and movement force.


The maxSpeed attribute is defined in flyingvehicle.h (line 64), in the FlyingVehicleData structure as:
F32 maxSpeed;

This is initialized in the constructor:
maxSpeed = 100;

And then the value is updated in the fliyngvehicle.cc (line 139), in the FlyingVehicleData::preload method:
maxSpeed = maneuveringForce / minDrag;

Notice this is exactly what the docs say. Here is my first question.
A. When and how many times is preload executed? I guess its updated once each time a sim is started but please confirm it.

But then why this just won't work? Because in a space sim... there is no drag. I set:
minDrag = 0.1
horizontalSurfaceForce = 0;
verticalSurfaceForce = 0;

This means my vehicle of mass 100 just slides almost forever and the movement is just what I want in the game. But also means the maxSped get too high. And there came my surprise. When I tried to change the maxSpeed in line 139 to a constant value like 100 the vehicle kept speeding up (and finally locking the engine due to a bug in the engine).

So I wanted to know why it wont slow down and found in fliyngvehicle.cc line 619 in the FlyingVehicle::updateJet:

F32 speed = mFabs(mDot(yv,mRigid.linVelocity));
F32 trail = 0;
if (speed > mDataBlock->minTrailSpeed) {
trail = dt;
if (speed < mDataBlock->maxSpeed)
trail *= (speed - mDataBlock->minTrailSpeed) / mDataBlock->maxSpeed;
}

This is the only usage of the maxSpeed attribute... if the ship speed is faster than the minTrailSpeed (in the datablock) then the trail lenght is computed... not what I was expecting... but I find a new misterious value: mRigid.linVelocity.

Still trying to find the minDrag relation, I found this in the flyingvehicle.cc line 430, in the FlyingVehicle::updateForces:
F32 speed = mRigid.linVelocity.len();
Point3F force = Point3F(0, 0, sFlyingVehicleGravity * mRigid.mass * mGravityMod);
force -= mRigid.linVelocity * mDataBlock->minDrag;

Thats the nefarious relation between the both terms!!! THis
Then it does a LOT of things with this force computing many other factors and finally doing (line 505):
mRigid.force = force;

My questions here would be:
B. Is the updateForces run each frame or each time the integrator value is set in the datablock?
C. Which one is better: to manually change the mRigid.linVelocity value by hand, like this:
if(mRigid.linVelocity>mDatablock->myMaxSpeed)
mRigid.linVelocity = mDatablock->myMaxSpeed;

or maybe by cancelling the thrust force at line 479:
// Maneuvering jets
if(mRigid.linVelocitymyMaxSpeed)
{
force += yv * (mThrust.y * mDataBlock->maneuveringForce * mCeilingFactor);
force += xv * (mThrust.x * mDataBlock->maneuveringForce * mCeilingFactor);
}

That is... apply manuvering force only if the speed is lower than the maximum speed.

Please tell me where may I find more info about this subject. This will help me understand the engine internals.

Luck!
Guimo

#1
09/26/2006 (7:41 am)
After long study of the code, I found this:

A. As suspected, the preload method is executed once each time the mission is started.
B. The updateForces is computed each 'integrator' value.
C. In order to decrease the speed don't mess with the mRigid.linVelocity and don't try to limit your thruster force as it can work in unexpected ways. Its better just to counter the velocity applying an adequate force against the linear velocity:

force += yv * (mThrust.y * mDataBlock->maneuveringForce * mCeilingFactor);
force += xv * (mThrust.x * mDataBlock->maneuveringForce * mCeilingFactor);
if(mRigid.linVelocity.len() < mDatablock->topSpeed)
force -= mRigid.linVelocity.len()*50;

After these and some other bug corrections my movement is ready. Time to go and solve other problems.

Luck!
Guimo