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.
(cherry picked from commit 0c354047e1
)
This commit is contained in:
parent
2025648d6d
commit
e11662ad77
2 changed files with 28 additions and 16 deletions
|
@ -34,6 +34,7 @@
|
|||
#include "core/project_settings.h"
|
||||
#include "physics_server_sw.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(CollisionObjectSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
|
||||
|
@ -434,10 +435,12 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
|
|||
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
|
||||
ERR_FAIL_COND_V(!shape, 0);
|
||||
|
||||
real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
real_t margin = MAX(p_margin, TEST_MOTION_MARGIN_MIN_VALUE);
|
||||
|
||||
real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
|
||||
AABB aabb = p_shape_xform.xform(shape->get_aabb());
|
||||
aabb = aabb.grow(p_margin);
|
||||
aabb = aabb.grow(margin);
|
||||
|
||||
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
|
||||
|
||||
|
@ -461,7 +464,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
|
|||
|
||||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
bool sc = CollisionSolverSW::solve_static(shape, p_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_margin);
|
||||
bool sc = CollisionSolverSW::solve_static(shape, p_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;
|
||||
}
|
||||
|
@ -730,6 +733,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
|
|||
r_result->collider_id = 0;
|
||||
r_result->collider_shape = 0;
|
||||
}
|
||||
|
||||
AABB body_aabb;
|
||||
bool shapes_found = false;
|
||||
|
||||
|
@ -755,11 +759,13 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
|
|||
return false;
|
||||
}
|
||||
|
||||
real_t margin = MAX(p_margin, TEST_MOTION_MARGIN_MIN_VALUE);
|
||||
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_margin);
|
||||
body_aabb = body_aabb.grow(margin);
|
||||
|
||||
real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
|
||||
float motion_length = p_motion.length();
|
||||
Vector3 motion_normal = p_motion / motion_length;
|
||||
|
@ -813,7 +819,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
|
|||
}
|
||||
}
|
||||
|
||||
if (CollisionSolverSW::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_margin)) {
|
||||
if (CollisionSolverSW::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;
|
||||
}
|
||||
}
|
||||
|
@ -1036,7 +1042,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
|
|||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
rcd.local_shape = j;
|
||||
bool sc = CollisionSolverSW::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_margin);
|
||||
bool sc = CollisionSolverSW::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;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "core/pair.h"
|
||||
#include "physics_2d_server_sw.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(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
|
||||
|
@ -438,11 +439,13 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
|
|||
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
|
||||
ERR_FAIL_COND_V(!shape, 0);
|
||||
|
||||
real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
real_t margin = MAX(p_margin, TEST_MOTION_MARGIN_MIN_VALUE);
|
||||
|
||||
real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
|
||||
Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
|
||||
aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
|
||||
aabb = aabb.grow(p_margin);
|
||||
aabb = aabb.grow(margin);
|
||||
|
||||
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
|
||||
|
||||
|
@ -468,7 +471,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
|
|||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
rcd.local_shape = 0;
|
||||
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin);
|
||||
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, margin);
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
|
@ -729,6 +732,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
r_result->collider_id = 0;
|
||||
r_result->collider_shape = 0;
|
||||
}
|
||||
|
||||
Rect2 body_aabb;
|
||||
|
||||
bool shapes_found = false;
|
||||
|
@ -758,15 +762,17 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
return false;
|
||||
}
|
||||
|
||||
real_t margin = MAX(p_margin, TEST_MOTION_MARGIN_MIN_VALUE);
|
||||
|
||||
// Undo the currently transform the physics server is aware of and apply the provided one
|
||||
body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
|
||||
body_aabb = body_aabb.grow(p_margin);
|
||||
body_aabb = body_aabb.grow(margin);
|
||||
|
||||
static const int max_excluded_shape_pairs = 32;
|
||||
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
|
||||
int excluded_shape_pair_count = 0;
|
||||
|
||||
real_t min_contact_depth = p_margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
|
||||
|
||||
float motion_length = p_motion.length();
|
||||
Vector2 motion_normal = p_motion / motion_length;
|
||||
|
@ -829,7 +835,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
|
||||
|
||||
float owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
|
||||
cbk.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work
|
||||
cbk.valid_depth = MAX(owc_margin, margin); //user specified, but never less than actual margin or it won't work
|
||||
cbk.invalid_by_dir = 0;
|
||||
|
||||
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
||||
|
@ -854,7 +860,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
bool did_collide = false;
|
||||
|
||||
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
|
||||
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_margin)) {
|
||||
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, margin)) {
|
||||
did_collide = cbk.passed > current_passed; //more passed, so collision actually existed
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1139,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
|
||||
|
||||
float owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
|
||||
rcd.valid_depth = MAX(owc_margin, p_margin); //user specified, but never less than actual margin or it won't work
|
||||
rcd.valid_depth = MAX(owc_margin, margin); //user specified, but never less than actual margin or it won't work
|
||||
|
||||
if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
|
||||
const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
|
||||
|
@ -1155,7 +1161,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
|
|||
rcd.object = col_obj;
|
||||
rcd.shape = shape_idx;
|
||||
rcd.local_shape = j;
|
||||
bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin);
|
||||
bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, margin);
|
||||
if (!sc) {
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue