Better damping implementation for Bullet rigid bodies
This commit is contained in:
parent
6abe73f5b8
commit
8f0f2bf4ef
|
@ -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;
|
||||||
|
|
|
@ -342,6 +342,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.) {
|
||||||
|
|
||||||
|
@ -379,8 +381,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;
|
||||||
|
@ -401,8 +406,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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue