diff --git a/doc/classes/PhysicsDirectBodyState.xml b/doc/classes/PhysicsDirectBodyState.xml
index 486804f1964..aa2970b000e 100644
--- a/doc/classes/PhysicsDirectBodyState.xml
+++ b/doc/classes/PhysicsDirectBodyState.xml
@@ -91,6 +91,15 @@
+
+
+
+
+
+
+ Impulse created by the contact. Only implemented for Bullet physics.
+
+
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index f2115a5d506..fd7f1ded09b 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -146,6 +146,10 @@ Vector3 BulletPhysicsDirectBodyState::get_contact_local_normal(int p_contact_idx
return body->collisions[p_contact_idx].hitNormal;
}
+float BulletPhysicsDirectBodyState::get_contact_impulse(int p_contact_idx) const {
+ return body->collisions[p_contact_idx].appliedImpulse;
+}
+
int BulletPhysicsDirectBodyState::get_contact_local_shape(int p_contact_idx) const {
return body->collisions[p_contact_idx].local_shape;
}
@@ -388,7 +392,7 @@ void RigidBodyBullet::on_collision_checker_start() {
collisionsCount = 0;
}
-bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, int p_other_shape_index, int p_local_shape_index) {
+bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) {
if (collisionsCount >= maxCollisionsDetection) {
return false;
@@ -399,6 +403,7 @@ bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const
cd.otherObject = p_otherObject;
cd.hitWorldLocation = p_hitWorldLocation;
cd.hitNormal = p_hitNormal;
+ cd.appliedImpulse = p_appliedImpulse;
cd.other_object_shape = p_other_shape_index;
cd.local_shape = p_local_shape_index;
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index eb9417e3914..66275d56135 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -121,6 +121,7 @@ public:
virtual Vector3 get_contact_local_position(int p_contact_idx) const;
virtual Vector3 get_contact_local_normal(int p_contact_idx) const;
+ virtual float get_contact_impulse(int p_contact_idx) const;
virtual int get_contact_local_shape(int p_contact_idx) const;
virtual RID get_contact_collider(int p_contact_idx) const;
@@ -147,6 +148,7 @@ public:
Vector3 hitLocalLocation;
Vector3 hitWorldLocation;
Vector3 hitNormal;
+ float appliedImpulse;
};
struct ForceIntegrationCallback {
@@ -245,7 +247,7 @@ public:
}
bool can_add_collision() { return collisionsCount < maxCollisionsDetection; }
- bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, int p_other_shape_index, int p_local_shape_index);
+ bool add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index);
void assert_no_constraints();
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index d60d8ba0e2c..dec8e66c71b 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -751,19 +751,20 @@ void SpaceBullet::check_body_collision() {
Vector3 collisionWorldPosition;
Vector3 collisionLocalPosition;
Vector3 normalOnB;
+ float appliedImpulse = pt.m_appliedImpulse;
B_TO_G(pt.m_normalWorldOnB, normalOnB);
if (bodyA->can_add_collision()) {
B_TO_G(pt.getPositionWorldOnB(), collisionWorldPosition);
/// pt.m_localPointB Doesn't report the exact point in local space
B_TO_G(pt.getPositionWorldOnB() - contactManifold->getBody1()->getWorldTransform().getOrigin(), collisionLocalPosition);
- bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, pt.m_index1, pt.m_index0);
+ bodyA->add_collision_object(bodyB, collisionWorldPosition, collisionLocalPosition, normalOnB, appliedImpulse, pt.m_index1, pt.m_index0);
}
if (bodyB->can_add_collision()) {
B_TO_G(pt.getPositionWorldOnA(), collisionWorldPosition);
/// pt.m_localPointA Doesn't report the exact point in local space
B_TO_G(pt.getPositionWorldOnA() - contactManifold->getBody0()->getWorldTransform().getOrigin(), collisionLocalPosition);
- bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, pt.m_index0, pt.m_index1);
+ bodyB->add_collision_object(bodyA, collisionWorldPosition, collisionLocalPosition, normalOnB * -1, appliedImpulse * -1, pt.m_index0, pt.m_index1);
}
#ifdef DEBUG_ENABLED
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index e8ea5531e56..ff989ec5bb5 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -418,6 +418,9 @@ public:
ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Vector3());
return body->contacts[p_contact_idx].local_normal;
}
+ virtual float get_contact_impulse(int p_contact_idx) const {
+ return 0.0f; // Only implemented for bullet
+ }
virtual int get_contact_local_shape(int p_contact_idx) const {
ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, -1);
return body->contacts[p_contact_idx].local_shape;
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index 9d4807fcf0e..d5c687a1949 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -103,6 +103,7 @@ void PhysicsDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_contact_local_position", "contact_idx"), &PhysicsDirectBodyState::get_contact_local_position);
ClassDB::bind_method(D_METHOD("get_contact_local_normal", "contact_idx"), &PhysicsDirectBodyState::get_contact_local_normal);
+ ClassDB::bind_method(D_METHOD("get_contact_impulse", "contact_idx"), &PhysicsDirectBodyState::get_contact_impulse);
ClassDB::bind_method(D_METHOD("get_contact_local_shape", "contact_idx"), &PhysicsDirectBodyState::get_contact_local_shape);
ClassDB::bind_method(D_METHOD("get_contact_collider", "contact_idx"), &PhysicsDirectBodyState::get_contact_collider);
ClassDB::bind_method(D_METHOD("get_contact_collider_position", "contact_idx"), &PhysicsDirectBodyState::get_contact_collider_position);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 8b8b8f856d2..b0f8bc23699 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -74,6 +74,7 @@ public:
virtual Vector3 get_contact_local_position(int p_contact_idx) const = 0;
virtual Vector3 get_contact_local_normal(int p_contact_idx) const = 0;
+ virtual float get_contact_impulse(int p_contact_idx) const = 0;
virtual int get_contact_local_shape(int p_contact_idx) const = 0;
virtual RID get_contact_collider(int p_contact_idx) const = 0;