From 02adb0e361ed77beba4282bcd12131255c3857b6 Mon Sep 17 00:00:00 2001 From: PouleyKetchoupp Date: Wed, 18 Aug 2021 13:09:27 -0700 Subject: [PATCH] Add collision depth and safe/unsafe fraction to Bullet body_test_motion It was only implemented for godot physics before. --- modules/bullet/space_bullet.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 9a6a11eb4da..ae72da90228 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -978,6 +978,9 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f btVector3 motion; G_TO_B(p_motion, motion); + real_t total_length = motion.length(); + real_t unsafe_fraction = 1.0; + real_t safe_fraction = 1.0; { // Phase two - sweep test, from a secure position without margin @@ -1027,6 +1030,15 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f dynamicsWorld->convexSweepTest(convex_shape_test, shape_world_from, shape_world_to, btResult, dynamicsWorld->getDispatchInfo().m_allowedCcdPenetration); if (btResult.hasHit()) { + if (total_length > CMP_EPSILON) { + real_t hit_fraction = btResult.m_closestHitFraction * motion.length() / total_length; + if (hit_fraction < unsafe_fraction) { + unsafe_fraction = hit_fraction; + real_t margin = p_body->get_kinematic_utilities()->safe_margin; + safe_fraction = MAX(hit_fraction - (1 - ((total_length - margin) / total_length)), 0); + } + } + /// Since for each sweep test I fix the motion of new shapes in base the recover result, /// if another shape will hit something it means that has a deepest penetration respect the previous shape motion *= btResult.m_closestHitFraction; @@ -1063,6 +1075,9 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f r_result->collider_id = collisionObject->get_instance_id(); r_result->collider_shape = r_recover_result.other_compound_shape_index; r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; + r_result->collision_depth = Math::abs(r_recover_result.penetration_distance); + r_result->collision_safe_fraction = safe_fraction; + r_result->collision_unsafe_fraction = unsafe_fraction; #if debug_test_motion Vector3 sup_line2;