Skip to content

Commit

Permalink
Changed body_test_motion to discard by angle rather than depth
Browse files Browse the repository at this point in the history
  • Loading branch information
mihe committed Mar 20, 2024
1 parent e5f3998 commit c766eb3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
42 changes: 24 additions & 18 deletions src/spaces/jolt_physics_direct_space_state_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ bool JoltPhysicsDirectSpaceState3D::test_body_motion(
collided = _body_motion_collide(
p_body,
transform.translated(p_motion * unsafe_fraction),
(float)p_motion.length(),
p_motion,
p_margin,
p_max_collisions,
p_result
Expand Down Expand Up @@ -946,7 +946,7 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_recover(
const real_t distance_to_1 = penetration_axis.dot(point_on_1 + recovery);
const real_t distance_to_2 = penetration_axis.dot(point_on_2);

const auto penetration_depth = float(distance_to_1 - distance_to_2);
const auto penetration_depth = float(distance_to_1 - distance_to_2) - CMP_EPSILON;

if (penetration_depth <= 0.0f) {
continue;
Expand Down Expand Up @@ -1052,11 +1052,15 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_cast(
bool JoltPhysicsDirectSpaceState3D::_body_motion_collide(
const JoltBodyImpl3D& p_body,
const Transform3D& p_transform,
float p_distance,
const Vector3& p_motion,
float p_margin,
int32_t p_max_collisions,
PhysicsServer3DExtensionMotionResult* p_result
) const {
if (p_max_collisions == 0) {
return false;
}

const JPH::Shape* jolt_shape = p_body.get_jolt_shape();

const Vector3 com_scaled = to_godot(jolt_shape->GetCenterOfMass());
Expand Down Expand Up @@ -1091,19 +1095,27 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_collide(
return collided;
}

// HACK(mihe): Without this minimum contact depth we can sometimes end up with very shallow
// contacts that end up affecting the outcome of things like `floor_block_on_wall`, where after
// one of the recovery iterations (in Godot, not here) we can still find ourselves penetrating a
// wall ever so slightly, which `move_and_slide` will interpret as being trapped in a corner and
// stop the character altogether. We still need distances smaller than this (like none at all)
// to actually emit contacts though, so we clamp it by the distance moved.
const float min_contact_depth = MIN(0.0001f, p_distance);

int32_t count = 0;

for (int32_t i = 0; i < collector.get_hit_count(); ++i) {
const JPH::CollideShapeResult& hit = collector.get_hit(i);

const float penetration_depth = hit.mPenetrationDepth + p_margin;

if (penetration_depth <= 0.0f) {
continue;
}

const Vector3 normal = to_godot(-hit.mPenetrationAxis.Normalized());

if (p_motion.length_squared() > 0) {
const Vector3 direction = p_motion.normalized();

if (direction.dot(normal) >= -CMP_EPSILON) {
continue;
}
}

JPH::ContactPoints contact_points1;
JPH::ContactPoints contact_points2;

Expand All @@ -1121,12 +1133,6 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_collide(
contact_points2.push_back(hit.mContactPointOn2);
}

const float penetration_depth = hit.mPenetrationDepth + p_margin - min_contact_depth;

if (penetration_depth <= 0.0f) {
continue;
}

const JoltReadableBody3D collider_jolt_body = space->read_body(hit.mBodyID2);
const JoltShapedObjectImpl3D* collider = collider_jolt_body.as_shaped();
ERR_FAIL_NULL_D(collider);
Expand All @@ -1143,7 +1149,7 @@ bool JoltPhysicsDirectSpaceState3D::_body_motion_collide(
PhysicsServer3DExtensionMotionCollision& collision = p_result->collisions[count++];

collision.position = position;
collision.normal = to_godot(-hit.mPenetrationAxis.Normalized());
collision.normal = normal;
collision.collider_velocity = collider->get_velocity_at_position(position);
collision.collider_angular_velocity = collider->get_angular_velocity();
collision.depth = penetration_depth;
Expand Down
2 changes: 1 addition & 1 deletion src/spaces/jolt_physics_direct_space_state_3d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class JoltPhysicsDirectSpaceState3D final : public PhysicsDirectSpaceState3DExte
bool _body_motion_collide(
const JoltBodyImpl3D& p_body,
const Transform3D& p_transform,
float p_distance,
const Vector3& p_motion,
float p_margin,
int32_t p_max_collisions,
PhysicsServer3DExtensionMotionResult* p_result
Expand Down

0 comments on commit c766eb3

Please sign in to comment.