Merge pull request #39084 from madmiraal/backport-37314

[3.2] Better damping implementation for Bullet rigid bodies
This commit is contained in:
Rémi Verschelde 2020-07-02 13:26:03 +02:00 committed by GitHub
commit 44a516986d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 28 deletions

View File

@ -203,6 +203,8 @@ if env["builtin_bullet"]:
# if env['target'] == "debug" or env['target'] == "release_debug": # if env['target'] == "debug" or env['target'] == "release_debug":
# env_bullet.Append(CPPDEFINES=['BT_DEBUG']) # env_bullet.Append(CPPDEFINES=['BT_DEBUG'])
env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD"])
env_thirdparty = env_bullet.Clone() env_thirdparty = env_bullet.Clone()
env_thirdparty.disable_warnings() env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)

View File

@ -503,15 +503,18 @@ void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_v
} }
case PhysicsServer::BODY_PARAM_LINEAR_DAMP: case PhysicsServer::BODY_PARAM_LINEAR_DAMP:
linearDamp = p_value; linearDamp = p_value;
btBody->setDamping(linearDamp, angularDamp); // Mark for updating total linear damping.
scratch_space_override_modificator();
break; break;
case PhysicsServer::BODY_PARAM_ANGULAR_DAMP: case PhysicsServer::BODY_PARAM_ANGULAR_DAMP:
angularDamp = p_value; angularDamp = p_value;
btBody->setDamping(linearDamp, angularDamp); // Mark for updating total angular damping.
scratch_space_override_modificator();
break; break;
case PhysicsServer::BODY_PARAM_GRAVITY_SCALE: case PhysicsServer::BODY_PARAM_GRAVITY_SCALE:
gravity_scale = p_value; gravity_scale = p_value;
/// The Bullet gravity will be is set by reload_space_override_modificator // The Bullet gravity will be is set by reload_space_override_modificator.
// Mark for updating total gravity scale.
scratch_space_override_modificator(); scratch_space_override_modificator();
break; break;
default: default:
@ -902,21 +905,20 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
} }
void RigidBodyBullet::reload_space_override_modificator() { void RigidBodyBullet::reload_space_override_modificator() {
// Make sure that kinematic bodies have their total gravity calculated // Make sure that kinematic bodies have their total gravity calculated
if (!is_active() && PhysicsServer::BODY_MODE_KINEMATIC != mode) if (!is_active() && PhysicsServer::BODY_MODE_KINEMATIC != mode)
return; return;
Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude()); Vector3 newGravity(0.0, 0.0, 0.0);
real_t newLinearDamp(linearDamp); real_t newLinearDamp = MAX(0.0, linearDamp);
real_t newAngularDamp(angularDamp); real_t newAngularDamp = MAX(0.0, angularDamp);
AreaBullet *currentArea; AreaBullet *currentArea;
// Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer // Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer
Vector3 support_gravity(0, 0, 0); Vector3 support_gravity(0, 0, 0);
int countCombined(0); bool stopped = false;
for (int i = areaWhereIamCount - 1; 0 <= i; --i) { for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) {
currentArea = areasWhereIam[i]; currentArea = areasWhereIam[i];
@ -965,7 +967,6 @@ void RigidBodyBullet::reload_space_override_modificator() {
newGravity += support_gravity; newGravity += support_gravity;
newLinearDamp += currentArea->get_spOv_linearDamp(); newLinearDamp += currentArea->get_spOv_linearDamp();
newAngularDamp += currentArea->get_spOv_angularDamp(); newAngularDamp += currentArea->get_spOv_angularDamp();
++countCombined;
break; break;
case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE:
/// This area adds its gravity/damp values to whatever has been calculated /// This area adds its gravity/damp values to whatever has been calculated
@ -974,32 +975,31 @@ void RigidBodyBullet::reload_space_override_modificator() {
newGravity += support_gravity; newGravity += support_gravity;
newLinearDamp += currentArea->get_spOv_linearDamp(); newLinearDamp += currentArea->get_spOv_linearDamp();
newAngularDamp += currentArea->get_spOv_angularDamp(); newAngularDamp += currentArea->get_spOv_angularDamp();
++countCombined; stopped = true;
goto endAreasCycle; break;
case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE: case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE:
/// This area replaces any gravity/damp, even the default one, and /// This area replaces any gravity/damp, even the default one, and
/// stops taking into account the rest of the areas. /// stops taking into account the rest of the areas.
newGravity = support_gravity; newGravity = support_gravity;
newLinearDamp = currentArea->get_spOv_linearDamp(); newLinearDamp = currentArea->get_spOv_linearDamp();
newAngularDamp = currentArea->get_spOv_angularDamp(); newAngularDamp = currentArea->get_spOv_angularDamp();
countCombined = 1; stopped = true;
goto endAreasCycle; break;
case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE_COMBINE:
/// This area replaces any gravity/damp calculated so far, but keeps /// This area replaces any gravity/damp calculated so far, but keeps
/// calculating the rest of the areas, down to the default one. /// calculating the rest of the areas, down to the default one.
newGravity = support_gravity; newGravity = support_gravity;
newLinearDamp = currentArea->get_spOv_linearDamp(); newLinearDamp = currentArea->get_spOv_linearDamp();
newAngularDamp = currentArea->get_spOv_angularDamp(); newAngularDamp = currentArea->get_spOv_angularDamp();
countCombined = 1;
break; break;
} }
} }
endAreasCycle:
if (1 < countCombined) { // Add default gravity and damping from space.
newGravity /= countCombined; if (!stopped) {
newLinearDamp /= countCombined; newGravity += space->get_gravity_direction() * space->get_gravity_magnitude();
newAngularDamp /= countCombined; newLinearDamp += space->get_linear_damp();
newAngularDamp += space->get_angular_damp();
} }
btVector3 newBtGravity; btVector3 newBtGravity;

View File

@ -353,6 +353,8 @@ SpaceBullet::SpaceBullet() :
godotFilterCallback(NULL), godotFilterCallback(NULL),
gravityDirection(0, -1, 0), gravityDirection(0, -1, 0),
gravityMagnitude(10), gravityMagnitude(10),
linear_damp(0.0),
angular_damp(0.0),
contactDebugCount(0), contactDebugCount(0),
delta_time(0.) { delta_time(0.) {
@ -390,8 +392,11 @@ void SpaceBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant
update_gravity(); update_gravity();
break; break;
case PhysicsServer::AREA_PARAM_LINEAR_DAMP: case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
linear_damp = p_value;
break;
case PhysicsServer::AREA_PARAM_ANGULAR_DAMP: case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
break; // No damp angular_damp = p_value;
break;
case PhysicsServer::AREA_PARAM_PRIORITY: case PhysicsServer::AREA_PARAM_PRIORITY:
// Priority is always 0, the lower // Priority is always 0, the lower
break; break;
@ -412,8 +417,9 @@ Variant SpaceBullet::get_param(PhysicsServer::AreaParameter p_param) {
case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR: case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR:
return gravityDirection; return gravityDirection;
case PhysicsServer::AREA_PARAM_LINEAR_DAMP: case PhysicsServer::AREA_PARAM_LINEAR_DAMP:
return linear_damp;
case PhysicsServer::AREA_PARAM_ANGULAR_DAMP: case PhysicsServer::AREA_PARAM_ANGULAR_DAMP:
return 0; // No damp return angular_damp;
case PhysicsServer::AREA_PARAM_PRIORITY: case PhysicsServer::AREA_PARAM_PRIORITY:
return 0; // Priority is always 0, the lower return 0; // Priority is always 0, the lower
case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT:

View File

@ -108,6 +108,9 @@ class SpaceBullet : public RIDBullet {
Vector3 gravityDirection; Vector3 gravityDirection;
real_t gravityMagnitude; real_t gravityMagnitude;
real_t linear_damp;
real_t angular_damp;
Vector<AreaBullet *> areas; Vector<AreaBullet *> areas;
Vector<Vector3> contactDebug; Vector<Vector3> contactDebug;
@ -177,6 +180,9 @@ public:
void update_gravity(); void update_gravity();
real_t get_linear_damp() const { return linear_damp; }
real_t get_angular_damp() const { return angular_damp; }
bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes); bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes);
int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer::SeparationResult *r_results, int p_result_max, float p_margin); int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer::SeparationResult *r_results, int p_result_max, float p_margin);

View File

@ -0,0 +1,34 @@
diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
index 9e8705b001..f1b50b39c8 100644
--- a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
+++ b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
@@ -136,8 +136,13 @@ void btRigidBody::setGravity(const btVector3& acceleration)
void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
{
- m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
- m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+#ifdef BT_USE_OLD_DAMPING_METHOD
+ m_linearDamping = btMax(lin_damping, btScalar(0.0));
+ m_angularDamping = btMax(ang_damping, btScalar(0.0));
+#else
+ m_linearDamping = btClamped(lin_damping, btScalar(0.0), btScalar(1.0));
+ m_angularDamping = btClamped(ang_damping, btScalar(0.0), btScalar(1.0));
+#endif
}
///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
@@ -146,10 +151,9 @@ void btRigidBody::applyDamping(btScalar timeStep)
//On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
//todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
-//#define USE_OLD_DAMPING_METHOD 1
-#ifdef USE_OLD_DAMPING_METHOD
- m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
- m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+#ifdef BT_USE_OLD_DAMPING_METHOD
+ m_linearVelocity *= btMax((btScalar(1.0) - timeStep * m_linearDamping), btScalar(0.0));
+ m_angularVelocity *= btMax((btScalar(1.0) - timeStep * m_angularDamping), btScalar(0.0));
#else
m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep);
m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep);

View File

@ -136,8 +136,13 @@ void btRigidBody::setGravity(const btVector3& acceleration)
void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping) void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
{ {
m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); #ifdef BT_USE_OLD_DAMPING_METHOD
m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); m_linearDamping = btMax(lin_damping, btScalar(0.0));
m_angularDamping = btMax(ang_damping, btScalar(0.0));
#else
m_linearDamping = btClamped(lin_damping, btScalar(0.0), btScalar(1.0));
m_angularDamping = btClamped(ang_damping, btScalar(0.0), btScalar(1.0));
#endif
} }
///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping ///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
@ -146,10 +151,9 @@ void btRigidBody::applyDamping(btScalar timeStep)
//On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74 //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
//todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
//#define USE_OLD_DAMPING_METHOD 1 #ifdef BT_USE_OLD_DAMPING_METHOD
#ifdef USE_OLD_DAMPING_METHOD m_linearVelocity *= btMax((btScalar(1.0) - timeStep * m_linearDamping), btScalar(0.0));
m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); m_angularVelocity *= btMax((btScalar(1.0) - timeStep * m_angularDamping), btScalar(0.0));
m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
#else #else
m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep); m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep);
m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep); m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep);