diff options
author | Matthew Kosarek <mattkae@protonmail.com> | 2021-05-18 20:30:33 -0400 |
---|---|---|
committer | Matthew Kosarek <mattkae@protonmail.com> | 2021-05-18 20:30:33 -0400 |
commit | df671b9de03f5db479878cff826e11c30602e010 (patch) | |
tree | cf8fe4bb748074bf5112533dee7ca11bb4894366 /2d/_collisions/polygon_polygon/main.cpp | |
parent | a00c0aab1eb5a7a55bef8ca08115bdd722ab5699 (diff) |
(mkosarek) Just need better calculations for moment of inertia and I will be good
Diffstat (limited to '2d/_collisions/polygon_polygon/main.cpp')
-rw-r--r-- | 2d/_collisions/polygon_polygon/main.cpp | 146 |
1 files changed, 85 insertions, 61 deletions
diff --git a/2d/_collisions/polygon_polygon/main.cpp b/2d/_collisions/polygon_polygon/main.cpp index b7e3ce5..916a057 100644 --- a/2d/_collisions/polygon_polygon/main.cpp +++ b/2d/_collisions/polygon_polygon/main.cpp @@ -19,7 +19,7 @@ struct Rigidbody { float32 rotation = 0.f; float32 mass = 1.f; float32 cofOfRestition = 1.f; - float32 momentOfInertia = 0.f; + float32 momentOfInertia = 1.f; void reset() { force = { 0, 0 }; @@ -75,7 +75,14 @@ struct ConvexPolygon { float32 width = 0.f; float32 height = 0.f; + Vector2* originalVertices; + Vector2* transformedVertices; + Edge* edges; + void load(OrthographicRenderer* renderer) { + transformedVertices = new Vector2[numVertices]; // This will be used for SAT calculations later + originalVertices = new Vector2[numVertices]; + // Generate the shape with numVertices many sides in a "fan" shape (i.e. 3 vertices per vertex) // The shape will have all equal sides, just to make it easier on me. Therefore, it will fit inside // the conditions of a circle, which is fun. Before anyone gets mad: I know I can avoid recalculating @@ -83,26 +90,33 @@ struct ConvexPolygon { // is the 2k lines of JavaScript that are required to display it. int32 verticesNeeded = numVertices * 3; float32 angleIncrements = (2.f * PI) / static_cast<float32>(numVertices); - OrthographicVertex* vertices = new OrthographicVertex[verticesNeeded]; + OrthographicVertex* shaderVertices = new OrthographicVertex[verticesNeeded]; for (int32 vidx = 0; vidx < numVertices; vidx++) { int32 indexPosition = vidx * 3; float32 firstAngle = angleIncrements * vidx; - vertices[indexPosition].position = { cosf(firstAngle) * width, sinf(firstAngle) * height }; + shaderVertices[indexPosition].position = { cosf(firstAngle) * width, sinf(firstAngle) * height }; - vertices[indexPosition + 1].position = { 0.f, 0.f }; + originalVertices[vidx] = shaderVertices[indexPosition].position; + + shaderVertices[indexPosition + 1].position = { 0.f, 0.f }; float32 secondAngle = angleIncrements * (vidx + 1); - vertices[indexPosition + 2].position = { cosf(secondAngle) * width, sinf(secondAngle) * height }; + shaderVertices[indexPosition + 2].position = { cosf(secondAngle) * width, sinf(secondAngle) * height }; // Apply some global stylings for (int subIdx = 0; subIdx < 3; subIdx++) { - vertices[indexPosition + subIdx].color = color.toNormalizedColor(); + shaderVertices[indexPosition + subIdx].color = color.toNormalizedColor(); } } - shape.load(vertices, verticesNeeded, renderer); - delete[] vertices; + shape.load(shaderVertices, verticesNeeded, renderer); + delete[] shaderVertices; + + edges = new Edge[numVertices]; // This will be filled in later when we are doing our SAT calculation. + + // Calculate moment of inertia + body.setMomentOfInertia((PI * body.mass) / 2.f); } void update(float32 dtSeconds) { @@ -110,18 +124,38 @@ struct ConvexPolygon { body.update(dtSeconds); shape.model = Mat4x4().translateByVec2(body.position).rotate2D(body.rotation); + + // Populate the current position of our edges + for (int vidx = 0; vidx < numVertices; vidx++) { + Vector2 start = shape.model * originalVertices[vidx]; + transformedVertices[vidx] = start; + + Vector2 end = shape.model * originalVertices[vidx == numVertices - 1 ? 0 : vidx + 1]; + edges[vidx] = { (end - start).getPerp().normalize(), start, end }; + } } + void restorePreviousBody() { + body = previousBody; + } + void render(OrthographicRenderer* renderer) { shape.render(renderer); } void unload() { shape.unload(); - } -}; + delete[] originalVertices; + originalVertices = NULL; + delete[] transformedVertices; + transformedVertices = NULL; + + delete[] edges; + edges = NULL; + } +}; EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); @@ -151,12 +185,24 @@ void load() { if (index == 0) { polygons[index].body.position = { context.width / 4.f, context.height / 4.f }; + polygons[index].body.velocity = { 100.f, 200.f }; + polygons[index].body.mass = 2.f; + polygons[index].body.rotationalVelocity = 0.2f; } else if (index == 1) { polygons[index].body.position = { context.width / 4.f, context.height * (3.f /4.f) }; + polygons[index].body.velocity = { 50.f, -50.f }; + polygons[index].body.mass = 4.f; + polygons[index].body.rotationalVelocity = -0.5f; } else if (index == 2) { polygons[index].body.position = { context.width * (3.f / 4.f), context.height * (3.f / 4.f) }; + polygons[index].body.velocity = { -100.f, -50.f }; + polygons[index].body.mass = 6.f; + polygons[index].body.rotationalVelocity = 0.9f; } else if (index == 3) { polygons[index].body.position = { context.width * (3.f / 4.f), context.height / 4.f }; + polygons[index].body.velocity = { -150.f, 50.f }; + polygons[index].body.mass = 8.f; + polygons[index].body.rotationalVelocity = 1.4f; } polygons[index].numVertices = (index + 1) * 3; @@ -168,14 +214,16 @@ void load() { }; polygons[index].load(&renderer); } + + printf("Main loop beginning\n"); mainLoop.run(update); } -Vector2 getProjection(Vector2* vertices, Vector2 axis) { +Vector2 getProjection(Vector2* vertices, int numVertices, Vector2 axis) { float32 min = axis.dot(vertices[0]); float32 max = min; - for (int v = 1; v < 4; v++) { + for (int v = 1; v < numVertices; v++) { float32 d = axis.dot(vertices[v]); if (d < min) { @@ -188,7 +236,7 @@ Vector2 getProjection(Vector2* vertices, Vector2 axis) { return Vector2 { min, max }; } -/*bool projectionsOverlap(Vector2 first, Vector2 second) { +bool projectionsOverlap(Vector2 first, Vector2 second) { return first.x <= second.y && second.x <= first.y; } @@ -199,30 +247,19 @@ float32 getProjectionOverlap(Vector2 first, Vector2 second) { } const float32 EPSILON = 1.f; -IntersectionResult getIntersection(Rectangle* first, Po* second) { +IntersectionResult getIntersection(ConvexPolygon* first, ConvexPolygon* second) { IntersectionResult ir; // For two rectangles to overlap, it means that at least one of the corners of one is inside of the other - Edge firstEdges[4]; - first->getEdges(firstEdges); - Vector2 firstPoints[4]; - first->getPoints(firstPoints); - - Edge secondEdges[4]; - second->getEdges(secondEdges); - Vector2 secondPoints[4]; - second->getPoints(secondPoints); - float32 minOverlap = FLT_MAX; - Vector2 minOverlapAxis; Edge* minOverlapEdge = NULL; - bool minOverlapWasFirstRect = false; + bool minOverlapWasFirst = false; - for (int i = 0; i < 4; i++) { - Vector2 normal = firstEdges[i].normal; + for (int i = 0; i < first->numVertices; i++) { + Vector2 normal = first->edges[i].normal; - Vector2 firstProj = getProjection(firstPoints, normal); - Vector2 secondProj = getProjection(secondPoints, normal); + Vector2 firstProj = getProjection(first->transformedVertices, first->numVertices, normal); + Vector2 secondProj = getProjection(second->transformedVertices, second->numVertices, normal); if (!projectionsOverlap(firstProj, secondProj)) { return ir; @@ -231,17 +268,16 @@ IntersectionResult getIntersection(Rectangle* first, Po* second) { float32 overlap = getProjectionOverlap(firstProj, secondProj); if (overlap < minOverlap) { minOverlap = overlap; - minOverlapAxis = normal; - minOverlapEdge = &firstEdges[i]; - minOverlapWasFirstRect = true; + minOverlapEdge = &first->edges[i]; + minOverlapWasFirst = true; } } - for (int i = 0; i < 4; i++) { - Vector2 normal = secondEdges[i].normal; + for (int i = 0; i < second->numVertices; i++) { + Vector2 normal = second->edges[i].normal; - Vector2 firstProj = getProjection(firstPoints, normal); - Vector2 secondProj = getProjection(secondPoints, normal); + Vector2 firstProj = getProjection(first->transformedVertices, first->numVertices, normal); + Vector2 secondProj = getProjection(second->transformedVertices, second->numVertices, normal); if (!projectionsOverlap(firstProj, secondProj)) { return ir; @@ -250,33 +286,21 @@ IntersectionResult getIntersection(Rectangle* first, Po* second) { float32 overlap = getProjectionOverlap(firstProj, secondProj); if (overlap < minOverlap) { minOverlap = overlap; - minOverlapAxis = normal; - minOverlapEdge = &secondEdges[i]; + minOverlapEdge = &second->edges[i]; } } ir.intersect = true; ir.relativeVelocity = first->body.velocity - second->body.velocity; - ir.collisionNormal = minOverlapAxis; - - // Find the point of collision, this is kind of tricky, and it is just an approximation for now. - // At this point, we know that we intersected along the minOverlapAxis, but we do not know where - // that exactly happened. To remedy this will, we create two parallel lines: one at the top of the - // normal area, and one at the bottom. For point on both of the Rectangles, we will check: - // (1) if it is between these two planes - // (2) if, for that rectangle, it is the closest point to the original normal vector - // (3) or if it is equally distant from normal vector as another point (then this is a "flat" collision) - // - // The collision point MUST be between these two planes. We can then say the corner/face of the non-monoverlapAxis - // 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. - // + ir.collisionNormal = minOverlapEdge->normal; + // Time to find just where we intersected Vector2 closestPoint; float32 minDistance = FLT_MAX; - for (int p = 0; p < 4; p++) { - Vector2 point = minOverlapWasFirstRect ? secondPoints[p] : firstPoints[p]; + + for (int p = 0; p < (minOverlapWasFirst ? second->numVertices : first->numVertices); p++) { + Vector2 point = minOverlapWasFirst ? second->transformedVertices[p] : first->transformedVertices[p]; float32 distFromPointToStart = (minOverlapEdge->start - point).length(); float32 distFromPointToEnd = (minOverlapEdge->end - point).length(); @@ -287,12 +311,12 @@ IntersectionResult getIntersection(Rectangle* first, Po* second) { minDistance = potentialMin; } } - + ir.firstPointOfApplication = closestPoint - first->body.position; ir.secondPointOfApplication = closestPoint - second->body.position;; return ir; -}*/ +} void resolveCollision(Rigidbody* first, Rigidbody* second, IntersectionResult* ir) { Vector2 relativeVelocity = ir->relativeVelocity; @@ -322,10 +346,10 @@ void update(float32 deltaTimeSeconds, void* userData) { } // Check collisions with other rectangles - /*for (int i = 0; i < 4; i++) { - Rectangle* first = &rectangleList[i]; + for (int i = 0; i < 4; i++) { + ConvexPolygon* first = &polygons[i]; for (int j = i + 1; j < 4; j++) { - Rectangle* second = &rectangleList[j]; + ConvexPolygon* second = &polygons[j]; IntersectionResult ir = getIntersection(first, second); if (!ir.intersect) { @@ -363,7 +387,7 @@ void update(float32 deltaTimeSeconds, void* userData) { first->update(frameTimeRemaining); second->update(frameTimeRemaining); } - }*/ + } // Check collisions with walls for (int p = 0; p < 4; p++) { |