mirror of
https://github.com/bulletphysics/bullet3.git
synced 2026-10-17 14:25:46 +00:00
Implementing a simple velocity clamping to reduce floating point errors
This commit is contained in:
@@ -24,6 +24,7 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
|
||||
#MESSAGE("CMAKE_CXX_FLAGS_DEBUG="+${CMAKE_CXX_FLAGS_DEBUG})
|
||||
|
||||
OPTION(USE_DOUBLE_PRECISION "Use double precision" OFF)
|
||||
SET(CLAMP_VELOCITIES "0" CACHE STRING "Clamp rigid bodies' velocity to this value, if larger than zero. Useful to prevent floating point errors or in general runaway velocities in complex scenarios")
|
||||
OPTION(USE_GRAPHICAL_BENCHMARK "Use Graphical Benchmark" ON)
|
||||
OPTION(BUILD_SHARED_LIBS "Use shared libraries" OFF)
|
||||
OPTION(USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD "Use btSoftMultiBodyDynamicsWorld" ON)
|
||||
@@ -212,6 +213,10 @@ IF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
ADD_DEFINITIONS( -DBT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
ENDIF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
|
||||
IF (CLAMP_VELOCITIES)
|
||||
ADD_DEFINITIONS( -DBT_CLAMP_VELOCITY_TO=${CLAMP_VELOCITIES})
|
||||
ENDIF (CLAMP_VELOCITIES)
|
||||
|
||||
IF (USE_DOUBLE_PRECISION)
|
||||
ADD_DEFINITIONS( -DBT_USE_DOUBLE_PRECISION)
|
||||
SET( BULLET_DOUBLE_DEF "-DBT_USE_DOUBLE_PRECISION")
|
||||
|
||||
@@ -337,6 +337,12 @@ end
|
||||
trigger = "double",
|
||||
description = "Double precision version of Bullet"
|
||||
}
|
||||
|
||||
newoption
|
||||
{
|
||||
trigger = "clamp-velocities",
|
||||
description = "Limit maximum velocities to reduce FP exception risk"
|
||||
}
|
||||
|
||||
newoption
|
||||
{
|
||||
@@ -360,6 +366,9 @@ end
|
||||
if _OPTIONS["double"] then
|
||||
defines {"BT_USE_DOUBLE_PRECISION"}
|
||||
end
|
||||
if _OPTIONS["clamp-velocities"] then
|
||||
defines {"BT_CLAMP_VELOCITY_TO=9999"}
|
||||
end
|
||||
|
||||
configurations {"Release", "Debug"}
|
||||
configuration "Release"
|
||||
|
||||
@@ -380,6 +380,9 @@ void btRigidBody::integrateVelocities(btScalar step)
|
||||
{
|
||||
m_angularVelocity *= (MAX_ANGVEL / step) / angvel;
|
||||
}
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_angularVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
btQuaternion btRigidBody::getOrientation() const
|
||||
|
||||
@@ -305,6 +305,9 @@ public:
|
||||
void applyTorque(const btVector3& torque)
|
||||
{
|
||||
m_totalTorque += torque * m_angularFactor;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_totalTorque);
|
||||
#endif
|
||||
}
|
||||
|
||||
void applyForce(const btVector3& force, const btVector3& rel_pos)
|
||||
@@ -316,11 +319,17 @@ public:
|
||||
void applyCentralImpulse(const btVector3& impulse)
|
||||
{
|
||||
m_linearVelocity += impulse * m_linearFactor * m_inverseMass;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_linearVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
void applyTorqueImpulse(const btVector3& torque)
|
||||
{
|
||||
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_angularVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
|
||||
@@ -361,20 +370,46 @@ public:
|
||||
{
|
||||
m_pushVelocity = v;
|
||||
}
|
||||
|
||||
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
void clampVelocity(btVector3& v) const {
|
||||
v.setX(
|
||||
fmax(-BT_CLAMP_VELOCITY_TO,
|
||||
fmin(BT_CLAMP_VELOCITY_TO, v.getX()))
|
||||
);
|
||||
v.setY(
|
||||
fmax(-BT_CLAMP_VELOCITY_TO,
|
||||
fmin(BT_CLAMP_VELOCITY_TO, v.getY()))
|
||||
);
|
||||
v.setZ(
|
||||
fmax(-BT_CLAMP_VELOCITY_TO,
|
||||
fmin(BT_CLAMP_VELOCITY_TO, v.getZ()))
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setTurnVelocity(const btVector3& v)
|
||||
{
|
||||
m_turnVelocity = v;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_turnVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
void applyCentralPushImpulse(const btVector3& impulse)
|
||||
{
|
||||
m_pushVelocity += impulse * m_linearFactor * m_inverseMass;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_pushVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
void applyTorqueTurnImpulse(const btVector3& torque)
|
||||
{
|
||||
m_turnVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_turnVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
void clearForces()
|
||||
@@ -408,12 +443,18 @@ public:
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_linearVelocity = lin_vel;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_linearVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void setAngularVelocity(const btVector3& ang_vel)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_angularVelocity = ang_vel;
|
||||
#if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
|
||||
clampVelocity(m_angularVelocity);
|
||||
#endif
|
||||
}
|
||||
|
||||
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
|
||||
|
||||
Reference in New Issue
Block a user