collide: Fix false negative when sphere is fully inside box

Fixes #1335
This commit is contained in:
rdb 2022-08-31 16:17:18 +02:00
parent ba8c1f0325
commit 88ba7badd4

View File

@ -230,10 +230,12 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
bool intersect; bool intersect;
LPlane plane; LPlane plane;
LVector3 normal; LVector3 normal;
bool fully_inside = true;
for(ip = 0, intersect = false; ip < 6 && !intersect; ip++) { for(ip = 0, intersect = false; ip < 6 && !intersect; ip++) {
plane = get_plane( ip ); plane = get_plane( ip );
if (_points[ip].size() < 3) { if (_points[ip].size() < 3) {
fully_inside = false;
continue; continue;
} }
if (wrt_prev_space != wrt_space) { if (wrt_prev_space != wrt_space) {
@ -248,6 +250,7 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
// moving in the same direction as the plane's normal. // moving in the same direction as the plane's normal.
PN_stdfloat dot = delta.dot(plane.get_normal()); PN_stdfloat dot = delta.dot(plane.get_normal());
if (dot > 0.1f) { if (dot > 0.1f) {
fully_inside = false;
continue; // no intersection continue; // no intersection
} }
@ -304,13 +307,19 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) { if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) {
// No intersection with plane? This means the plane's effective normal // No intersection with plane? This means the plane's effective normal
// was within the plane itself. A useless polygon. // was within the plane itself. A useless polygon.
fully_inside = false;
continue; continue;
} }
if (dist > from_radius || dist < -from_radius) { if (dist > from_radius) {
// No intersection with the plane. // Fully outside this plane, there can not be an intersection.
return nullptr;
}
if (dist < -from_radius) {
// Fully inside this plane.
continue; continue;
} }
fully_inside = false;
LPoint2 p = to_2d(from_center - dist * plane.get_normal(), ip); LPoint2 p = to_2d(from_center - dist * plane.get_normal(), ip);
PN_stdfloat edge_dist = 0.0f; PN_stdfloat edge_dist = 0.0f;
@ -366,8 +375,9 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
} }
intersect = true; intersect = true;
} }
if( !intersect ) if (!fully_inside && !intersect) {
return nullptr; return nullptr;
}
if (collide_cat.is_debug()) { if (collide_cat.is_debug()) {
collide_cat.debug() collide_cat.debug()