Support multiple ray shapes in kinematicbody, fixes #25050

This commit is contained in:
Juan Linietsky 2019-02-16 16:14:57 -03:00
parent bf53132217
commit 6d4eaebe1e
2 changed files with 30 additions and 14 deletions

View file

@ -597,7 +597,6 @@ int SpaceSW::test_body_ray_separation(BodySW *p_body, const Transform &p_transfo
bool collided = false; bool collided = false;
int amount = _cull_aabb_for_body(p_body, body_aabb); int amount = _cull_aabb_for_body(p_body, body_aabb);
int ray_index = 0;
for (int j = 0; j < p_body->get_shape_count(); j++) { for (int j = 0; j < p_body->get_shape_count(); j++) {
if (p_body->is_shape_set_as_disabled(j)) if (p_body->is_shape_set_as_disabled(j))
@ -631,7 +630,19 @@ int SpaceSW::test_body_ray_separation(BodySW *p_body, const Transform &p_transfo
collided = true; collided = true;
} }
if (ray_index < p_result_max) { int ray_index = -1; //reuse shape
for (int k = 0; k < rays_found; k++) {
if (r_results[ray_index].collision_local_shape == j) {
ray_index = k;
}
}
if (ray_index == -1 && rays_found < p_result_max) {
ray_index = rays_found;
rays_found++;
}
if (ray_index != -1) {
PhysicsServer::SeparationResult &result = r_results[ray_index]; PhysicsServer::SeparationResult &result = r_results[ray_index];
for (int k = 0; k < cbk.amount; k++) { for (int k = 0; k < cbk.amount; k++) {
@ -646,9 +657,10 @@ int SpaceSW::test_body_ray_separation(BodySW *p_body, const Transform &p_transfo
result.collision_depth = depth; result.collision_depth = depth;
result.collision_point = b; result.collision_point = b;
result.collision_normal = (b - a).normalized(); result.collision_normal = (b - a).normalized();
result.collision_local_shape = shape_idx; result.collision_local_shape = j;
result.collider = col_obj->get_self(); result.collider = col_obj->get_self();
result.collider_id = col_obj->get_instance_id(); result.collider_id = col_obj->get_instance_id();
result.collider_shape = shape_idx;
//result.collider_metadata = col_obj->get_shape_metadata(shape_idx); //result.collider_metadata = col_obj->get_shape_metadata(shape_idx);
if (col_obj->get_type() == CollisionObjectSW::TYPE_BODY) { if (col_obj->get_type() == CollisionObjectSW::TYPE_BODY) {
BodySW *body = (BodySW *)col_obj; BodySW *body = (BodySW *)col_obj;
@ -662,12 +674,8 @@ int SpaceSW::test_body_ray_separation(BodySW *p_body, const Transform &p_transfo
} }
} }
} }
ray_index++;
} }
rays_found = MAX(ray_index, rays_found);
if (!collided || recover_motion == Vector3()) { if (!collided || recover_motion == Vector3()) {
break; break;
} }

View file

@ -561,7 +561,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
bool collided = false; bool collided = false;
int amount = _cull_aabb_for_body(p_body, body_aabb); int amount = _cull_aabb_for_body(p_body, body_aabb);
int ray_index = 0;
for (int j = 0; j < p_body->get_shape_count(); j++) { for (int j = 0; j < p_body->get_shape_count(); j++) {
if (p_body->is_shape_set_as_disabled(j)) if (p_body->is_shape_set_as_disabled(j))
@ -620,7 +619,19 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
collided = true; collided = true;
} }
if (ray_index < p_result_max) { int ray_index = -1; //reuse shape
for (int k = 0; k < rays_found; k++) {
if (r_results[ray_index].collision_local_shape == j) {
ray_index = k;
}
}
if (ray_index == -1 && rays_found < p_result_max) {
ray_index = rays_found;
rays_found++;
}
if (ray_index != -1) {
Physics2DServer::SeparationResult &result = r_results[ray_index]; Physics2DServer::SeparationResult &result = r_results[ray_index];
for (int k = 0; k < cbk.amount; k++) { for (int k = 0; k < cbk.amount; k++) {
@ -635,7 +646,8 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
result.collision_depth = depth; result.collision_depth = depth;
result.collision_point = b; result.collision_point = b;
result.collision_normal = (b - a).normalized(); result.collision_normal = (b - a).normalized();
result.collision_local_shape = shape_idx; result.collision_local_shape = j;
result.collider_shape = shape_idx;
result.collider = col_obj->get_self(); result.collider = col_obj->get_self();
result.collider_id = col_obj->get_instance_id(); result.collider_id = col_obj->get_instance_id();
result.collider_metadata = col_obj->get_shape_metadata(shape_idx); result.collider_metadata = col_obj->get_shape_metadata(shape_idx);
@ -650,12 +662,8 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
} }
} }
} }
ray_index++;
} }
rays_found = MAX(ray_index, rays_found);
if (!collided || recover_motion == Vector2()) { if (!collided || recover_motion == Vector2()) {
break; break;
} }