This applies to Bullet version 2.77.
wheelInfo.m_rollInfluence is used to dampen the vertical component of the friction contact force on the vehicle, so that the new contact force is closer to the same height as the vehicle's center of mass, thus inducing less roll. The problem is that the rel_pos (relative position of the contact point) is a world-space offset from the center of mass, and damping the vertical/Y component of this offset is only valid on flat ground. If your vehicle is driving in any direction on an incline, the new contact point might actually be further away from the relative height of the center of mass. The observed behavior is that when turning quickly on a ramp, the vehicle rolls into the ramp; doing exactly what we were trying to avoid! The solution is to put the contact point offset into local space, then apply roll influence, and transform back into world space to apply the friction force.
Note that they way I applied this fix changes the fwd/back (accel/decel) behavior as well as the side forces, because I'm applying the roll influence before either force is used. This was intentional on my part (to keep my car from doing wheelies), but might not be correct for others.
A similar change probably needs to happen to rel_pos2, regarding the force that is applied to the ground, but since I don't have any moving ground, I haven't bothered to try to fix it.
--- btRaycastVehicle-bug-2.77.cpp 2010-09-07 18:38:16.000000000 -0600
+++ btRaycastVehicle-fixed-2.77.cpp 2010-10-25 12:09:50.233339900 -0600
@@ -677,8 +677,10 @@
{
btWheelInfo& wheelInfo = m_wheelInfo[wheel];
- btVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS -
- m_chassisBody->getCenterOfMassPosition();
+ btTransform worldToChassis = getChassisWorldTransform().inverse();
+ btVector3 relPosLocal = worldToChassis * wheelInfo.m_raycastInfo.m_contactPointWS;
+ relPosLocal[1] *= wheelInfo.m_rollInfluence;
+ btVector3 rel_pos = getChassisWorldTransform() * relPosLocal - m_chassisBody->getCenterOfMassPosition();
if (m_forwardImpulse[wheel] != btScalar(0.))
{
@@ -694,7 +696,6 @@
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
- rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
m_chassisBody->applyImpulse(sideImp,rel_pos);
//apply friction impulse on the ground
--
David.