Vehicle physics bug (vehicle sticking to terrain or objects)
by Vis · in Torque Game Engine · 07/12/2007 (10:25 am) · 8 replies
If a flyingVehical ever comes to rest ..... by removing the hover code or flying into another object slowly, the vehicle will stop and not move again, irrespective of user input.
The problem resides in Vehicle::updatePos()
Once mRigid.atRest has been set, no new changes to mRigid.force or mRigid.torque will be applied by mRigid.integrate();
Theres a bunch of ways this could be fixed, I did it this way:
On a clean TGE install version 1.52
I added a flag to the Vehicle class (vehicle.h line 170 : bool mUserInput;)
initialized it to false in the constructor (vehicle.cc line 466 mUserInput = false;)
added a test at the top of Vehicle::updateMove() to set the flag if there is any user input to move the vehicle:
then changed vehicle.cc at line 963 from
to ....
I am a relatively inexperienced programmer so there's probably a much more elegant way to do this.
(EDIT: just realized theres an SDK bugs forum - sorry !)
The problem resides in Vehicle::updatePos()
....
....
if (!mRigid.atRest) {
collided = updateCollision(dt);
// Now that all the forces have been processed, lets
// see if we're at rest. Basically, if the kinetic energy of
// the vehicles is less than some percentage of the energy added
// by gravity for a short period, we're considered at rest.
// This should really be part of the rigid class...
if (mCollisionList.count) {
F32 k = mRigid.getKineticEnergy();
F32 G = sVehicleGravity * dt;
F32 Kg = 0.5 * mRigid.mass * G * G;
if (k < sRestTol * Kg && ++restCount > sRestCount)
mRigid.setAtRest();
}
else
restCount = 0;
}
if (!mRigid.atRest)
mRigid.integrate(dt);
.....
.....Once mRigid.atRest has been set, no new changes to mRigid.force or mRigid.torque will be applied by mRigid.integrate();
Theres a bunch of ways this could be fixed, I did it this way:
On a clean TGE install version 1.52
I added a flag to the Vehicle class (vehicle.h line 170 : bool mUserInput;)
initialized it to false in the constructor (vehicle.cc line 466 mUserInput = false;)
added a test at the top of Vehicle::updateMove() to set the flag if there is any user input to move the vehicle:
if(move->x || move->y || move->z || move->roll || move->pitch || move->yaw)
mUserInput = true;then changed vehicle.cc at line 963 from
// Integrate forward
if (!mRigid.atRest)
mRigid.integrate(dt);to ....
// Integrate forward
if (!mRigid.atRest [b]|| mUserInput[/b])
{
mRigid.integrate(dt);
mUserInput = false;
}I am a relatively inexperienced programmer so there's probably a much more elegant way to do this.
(EDIT: just realized theres an SDK bugs forum - sorry !)
#2
Should be like this:
Otherwise, good catch. I've seen that happen myself, but assumed it was part of the larger vehicle collision bug (where you get a freeze sometimes).
09/04/2007 (2:54 pm)
Yeah, I think that this line:if (!mRigid.atRest)
Should be like this:
if (!mRigid.atRest || mUserInput)
Otherwise, good catch. I've seen that happen myself, but assumed it was part of the larger vehicle collision bug (where you get a freeze sometimes).
#3
and thanks Brian for fixing it
( I have corrected the original post )
09/08/2007 (4:49 am)
@ Ron ... its is .... it was a long day ! ....and thanks Brian for fixing it
( I have corrected the original post )
#4
10/03/2007 (9:22 am)
Fantastic fix, works bloody awesome. Thanks.
#5
to this
12/26/2009 (3:57 pm)
I changed this lineif(move->x || move->y || move->z || move->roll || move->pitch || move->yaw)
mUserInput = true;to this
mUserInput = (move->x || move->y || move->z || move->roll || move->pitch || move->yaw)
#6
even though my programming is limited wouldnt that make mUserInput equal to the integer value of one of those instead of true?
12/27/2009 (12:18 am)
@thomaseven though my programming is limited wouldnt that make mUserInput equal to the integer value of one of those instead of true?
#7
The point to get here is that 'true' is represented by any value other than zero.
I prefer to use an if statement for no other reason than readability, both will provide the same result.
12/27/2009 (7:53 am)
@Scooby,The point to get here is that 'true' is represented by any value other than zero.
I prefer to use an if statement for no other reason than readability, both will provide the same result.
#8
12/27/2009 (8:26 am)
(move->x || move->y || move->z || move->roll || move->pitch || move->yaw)Evaluates as
((move->x != 0) || (move->y != 0) || ... etc etcIf I'm not mistaken.
Torque Owner Ronald J Nelson
Code Hammer Games
It seems to be incomplete.