Handle test body motion with 0 margin
Margin needs to have a high enough value for test body motion to work properly (separate using the margin, move without then gather rest info with the margin again). Fixes issues with test motion returning no collision in some cases with margin equal to 0.
This commit is contained in:
parent
f1e3c87244
commit
0c354047e1
2 changed files with 27 additions and 16 deletions
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
|
||||
#define TEST_MOTION_MARGIN_MIN_VALUE 0.0001
|
||||
#define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05
|
||||
|
||||
_FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject3D *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
|
||||
|
|
@ -507,8 +508,10 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_paramete
|
|||
GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
|
||||
ERR_FAIL_COND_V(!shape, 0);
|
||||
|
||||
real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE);
|
||||
|
||||
AABB aabb = p_parameters.transform.xform(shape->get_aabb());
|
||||
aabb = aabb.grow(p_parameters.margin);
|
||||
aabb = aabb.grow(margin);
|
||||
|
||||
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
|
||||
|
||||
|
|
@ -516,7 +519,7 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_paramete
|
|||
|
||||
// Allowed depth can't be lower than motion length, in order to handle contacts at low speed.
|
||||
real_t motion_length = p_parameters.motion.length();
|
||||
real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
rcd.min_allowed_depth = MIN(motion_length, min_contact_depth);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
|
|
@ -534,7 +537,7 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_paramete
|
|||
|
||||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
bool sc = GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
|
||||
bool sc = GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, margin);
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -677,11 +680,13 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
|
|||
return false;
|
||||
}
|
||||
|
||||
real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE);
|
||||
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_parameters.margin);
|
||||
body_aabb = body_aabb.grow(margin);
|
||||
|
||||
real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
|
||||
real_t motion_length = p_parameters.motion.length();
|
||||
Vector3 motion_normal = p_parameters.motion / motion_length;
|
||||
|
|
@ -729,7 +734,7 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
|
|||
|
||||
int shape_idx = intersection_query_subindex_results[i];
|
||||
|
||||
if (GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_parameters.margin)) {
|
||||
if (GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, margin)) {
|
||||
collided = cbk.amount > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -949,7 +954,7 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
|
|||
|
||||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
bool sc = GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
|
||||
bool sc = GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, margin);
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue