From f40037a4a04933d66b6025873d2483169848fb74 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Wed, 12 May 2021 20:28:30 -0400 Subject: Decently good interaction between rectangles. I am happy for now --- .../rectangle_rectangle/dist/output.wasm | Bin 55475 -> 55719 bytes .../2d/_collisions/rectangle_rectangle/main.cpp | 62 ++++++++++++--------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/frontend/2d/_collisions/rectangle_rectangle/dist/output.wasm b/frontend/2d/_collisions/rectangle_rectangle/dist/output.wasm index 66f6ab8..a6d85e9 100755 Binary files a/frontend/2d/_collisions/rectangle_rectangle/dist/output.wasm and b/frontend/2d/_collisions/rectangle_rectangle/dist/output.wasm differ diff --git a/frontend/2d/_collisions/rectangle_rectangle/main.cpp b/frontend/2d/_collisions/rectangle_rectangle/main.cpp index 9f6db62..37cce89 100644 --- a/frontend/2d/_collisions/rectangle_rectangle/main.cpp +++ b/frontend/2d/_collisions/rectangle_rectangle/main.cpp @@ -60,6 +60,12 @@ struct IntersectionResult { Vector2 secondPointOfApplication; }; +struct Edge { + Vector2 normal; + Vector2 start; + Vector2 end; +}; + struct Rectangle { OrthographicShape shape; Rigidbody body; @@ -138,25 +144,19 @@ struct Rectangle { pointList[3] = botRight; } - void getEdges(Vector2* edgeList) { + void getEdges(Edge* edgeList) { Vector2 pointsList[4]; getPoints(pointsList); for (int i = 0; i < 4; i++) { + edgeList[i].start = pointsList[i]; if (i + 1 == 4) { - edgeList[i] = pointsList[i] - pointsList[0]; + edgeList[i].end = pointsList[0]; } else { - edgeList[i] = pointsList[i] - pointsList[i + 1]; + edgeList[i].end = pointsList[i + 1]; } - } - } - - void getNormals(Vector2* normalList) { - Vector2 edgeList[4]; - getEdges(edgeList); - for (int i = 0; i < 4; i++) { - normalList[i] = edgeList[i].getPerp().normalize(); + edgeList[i].normal = (edgeList[i].end - edgeList[i].start).getPerp().normalize(); } } }; @@ -236,23 +236,23 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) { IntersectionResult ir; // For two rectangles to overlap, it means that at least one of the corners of one is inside of the other - Vector2 firstNormals[4]; - first->getNormals(firstNormals); + Edge firstEdges[4]; + first->getEdges(firstEdges); Vector2 firstPoints[4]; first->getPoints(firstPoints); - Vector2 secondNormals[4]; - second->getNormals(secondNormals); + Edge secondEdges[4]; + second->getEdges(secondEdges); Vector2 secondPoints[4]; second->getPoints(secondPoints); float32 minOverlap = FLT_MAX; Vector2 minOverlapAxis; - bool minOverlapAxisIsFromFirstRectangle = true; + Edge* minOverlapEdge = NULL; + bool minOverlapWasFirstRect = false; - for (int i = 0; i < 4; i++) { - Vector2 normal = firstNormals[i]; + Vector2 normal = firstEdges[i].normal; Vector2 firstProj = getProjection(firstPoints, normal); Vector2 secondProj = getProjection(secondPoints, normal); @@ -265,12 +265,13 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) { if (overlap < minOverlap) { minOverlap = overlap; minOverlapAxis = normal; - minOverlapAxisIsFromFirstRectangle = true; + minOverlapEdge = &firstEdges[i]; + minOverlapWasFirstRect = true; } } for (int i = 0; i < 4; i++) { - Vector2 normal = secondNormals[i]; + Vector2 normal = secondEdges[i].normal; Vector2 firstProj = getProjection(firstPoints, normal); Vector2 secondProj = getProjection(secondPoints, normal); @@ -283,7 +284,7 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) { if (overlap < minOverlap) { minOverlap = overlap; minOverlapAxis = normal; - minOverlapAxisIsFromFirstRectangle = false; + minOverlapEdge = &secondEdges[i]; } } @@ -303,16 +304,25 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) { // Rectangle is the collision point. This enables us to then solve for their respective points of application fairly // easily. If the collision "point" is an entire face, we make the collision point be the center point. // - Vector2 topPlane; - Vector2 bottomPlane; + + Vector2 closestPoint; + float32 minDistance = FLT_MAX; for (int p = 0; p < 4; p++) { - Vector2 point = minOverlapAxisIsFromFirstRectangle ? first->getPoint(p) : second->getPoint(p); + Vector2 point = minOverlapWasFirstRect ? secondPoints[p] : firstPoints[p]; + float32 distFromPointToStart = (minOverlapEdge->start - point).length(); + float32 distFromPointToEnd = (minOverlapEdge->end - point).length(); + float32 potentialMin = MIN(distFromPointToStart, distFromPointToEnd); + + if (potentialMin < minDistance) { + closestPoint = point; + minDistance = potentialMin; + } } - ir.firstPointOfApplication = Vector2(); - ir.secondPointOfApplication = Vector2(); + ir.firstPointOfApplication = closestPoint - first->body.position; + ir.secondPointOfApplication = closestPoint - second->body.position;; return ir; } -- cgit v1.2.1