Merge pull request #25788 from aqnuep/rayshape_fix

Fix RayShape collision when used with a KinematicBody (Bullet Physics)
This commit is contained in:
Rémi Verschelde 2019-02-19 14:42:04 +01:00 committed by GitHub
commit 2f9b7e6b63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 29 deletions

View File

@ -79,7 +79,7 @@ void btRayShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVecto
void btRayShape::getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const {
#define MARGIN_BROADPHASE 0.1
btVector3 localAabbMin(0, 0, 0);
btVector3 localAabbMax(m_shapeAxis * m_length);
btVector3 localAabbMax(m_shapeAxis * (m_cacheScaledLength + m_collisionMargin));
btTransformAabb(localAabbMin, localAabbMax, MARGIN_BROADPHASE, t, aabbMin, aabbMax);
}
@ -97,8 +97,8 @@ void btRayShape::getPreferredPenetrationDirection(int index, btVector3 &penetrat
void btRayShape::reload_cache() {
m_cacheScaledLength = m_length * m_localScaling[2] + m_collisionMargin;
m_cacheScaledLength = m_length * m_localScaling[2];
m_cacheSupportPoint.setIdentity();
m_cacheSupportPoint.setOrigin(m_shapeAxis * m_cacheScaledLength);
m_cacheSupportPoint.setOrigin(m_shapeAxis * (m_cacheScaledLength + m_collisionMargin));
}

View File

@ -35,8 +35,6 @@
#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
#define RAY_STABILITY_MARGIN 0.1
/**
@author AndreaCatania
*/
@ -102,8 +100,8 @@ void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *bo
btScalar depth(ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1));
if (depth >= -RAY_STABILITY_MARGIN)
depth = 0;
if (depth >= -ray_shape->getMargin())
depth *= 0.5;
if (ray_shape->getSlipsOnSlope())
resultOut->addContactPoint(btResult.m_hitNormalWorld, btResult.m_hitPointWorld, depth);

View File

@ -333,14 +333,6 @@ void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3
m_other_compound_shape_index = isSwapped ? m_index0 : m_index1;
m_pointWorld = isSwapped ? (pointInWorldOnB + (normalOnBInWorld * depth)) : pointInWorldOnB;
const btCollisionObjectWrapper *bw0 = m_body0Wrap;
if (isSwapped)
bw0 = m_body1Wrap;
if (bw0->getCollisionShape()->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) {
m_pointNormalWorld = bw0->m_worldTransform.getBasis().transpose() * btVector3(0, 0, 1);
} else {
m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld;
}
m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld;
}
}

View File

@ -1246,6 +1246,21 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
return false;
}
void SpaceBullet::convert_to_separation_result(PhysicsServer::SeparationResult *r_result, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const {
const btRigidBody *btRigid = static_cast<const btRigidBody *>(p_other_object);
CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(p_other_object->getUserPointer());
r_result->collision_depth = p_recover_result.penetration_distance;
B_TO_G(p_recover_result.pointWorld, r_result->collision_point);
B_TO_G(p_recover_result.normal, r_result->collision_normal);
B_TO_G(btRigid->getVelocityInLocalPoint(p_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity);
r_result->collision_local_shape = p_shape_id;
r_result->collider_id = collisionObject->get_instance_id();
r_result->collider = collisionObject->get_self();
r_result->collider_shape = p_recover_result.other_compound_shape_index;
}
int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer::SeparationResult *r_results) {
RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask());
@ -1297,22 +1312,19 @@ int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btT
btCompoundShape *cs = static_cast<btCompoundShape *>(otherObject->getCollisionShape());
for (int x = cs->getNumChildShapes() - 1; 0 <= x; --x) {
RecoverResult r_recover_result;
if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_delta_recover_movement, &r_recover_result)) {
RecoverResult recover_result;
if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), p_recover_movement_scale, r_delta_recover_movement, &recover_result)) {
const btRigidBody *btRigid = static_cast<const btRigidBody *>(otherObject);
CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(otherObject->getUserPointer());
r_results[ray_index].collision_depth = r_recover_result.penetration_distance;
B_TO_G(r_recover_result.pointWorld, r_results[ray_index].collision_point);
B_TO_G(r_recover_result.normal, r_results[ray_index].collision_normal);
B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_results[ray_index].collider_velocity);
r_results[ray_index].collision_local_shape = kinIndex;
r_results[ray_index].collider_id = collisionObject->get_instance_id();
r_results[ray_index].collider = collisionObject->get_self();
r_results[ray_index].collider_shape = r_recover_result.other_compound_shape_index;
convert_to_separation_result(&r_results[ray_index], recover_result, kinIndex, otherObject);
}
}
} else {
RecoverResult recover_result;
if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, body_shape_position, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, &recover_result)) {
convert_to_separation_result(&r_results[ray_index], recover_result, kinIndex, otherObject);
}
}
}

View File

@ -212,6 +212,7 @@ private:
/// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm
bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = NULL);
void convert_to_separation_result(PhysicsServer::SeparationResult *r_result, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const;
int recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer::SeparationResult *r_results);
};
#endif