Browse Source

Expose PhysicsDirectBodyState.get_contact_impulse

Lee Pugh 7 years ago
parent
commit
ac26bf0fb4

+ 9 - 0
doc/classes/PhysicsDirectBodyState.xml

@@ -91,6 +91,15 @@
 			<description>
 			</description>
 		</method>
+		<method name="get_contact_impulse" qualifiers="const">
+			<return type="float">
+			</return>
+			<argument index="0" name="contact_idx" type="int">
+			</argument>
+			<description>
+			Impulse created by the contact. Only implemented for Bullet physics.
+			</description>
+		</method>
 		<method name="get_contact_local_normal" qualifiers="const">
 			<return type="Vector3">
 			</return>

+ 6 - 1
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;
 

+ 3 - 1
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();
 

+ 3 - 2
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

+ 3 - 0
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;

+ 1 - 0
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);

+ 1 - 0
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;