summaryrefslogtreecommitdiff
path: root/2d/_collisions/polygon_polygon
diff options
context:
space:
mode:
authorMatthew Kosarek <mattkae@protonmail.com>2021-06-27 15:24:07 -0400
committerMatthew Kosarek <mattkae@protonmail.com>2021-06-27 15:24:07 -0400
commit52d43a63d02e973f28aa30b768eddc042a4f155b (patch)
tree852de9a02ff9c6298c5b41dcc466786ed8af3be6 /2d/_collisions/polygon_polygon
parent28d0d84638ba1ba45696f3fa86cb18e694f280a5 (diff)
Some minor updates to SAT explanation, and made icons work everywhere
Diffstat (limited to '2d/_collisions/polygon_polygon')
-rwxr-xr-x2d/_collisions/polygon_polygon/dist/output.wasmbin57485 -> 57700 bytes
-rw-r--r--2d/_collisions/polygon_polygon/main.cpp27
-rw-r--r--2d/_collisions/polygon_polygon/snippet1.cpp52
3 files changed, 65 insertions, 14 deletions
diff --git a/2d/_collisions/polygon_polygon/dist/output.wasm b/2d/_collisions/polygon_polygon/dist/output.wasm
index a30f0c4..8e0443b 100755
--- a/2d/_collisions/polygon_polygon/dist/output.wasm
+++ b/2d/_collisions/polygon_polygon/dist/output.wasm
Binary files differ
diff --git a/2d/_collisions/polygon_polygon/main.cpp b/2d/_collisions/polygon_polygon/main.cpp
index c458299..348e8d2 100644
--- a/2d/_collisions/polygon_polygon/main.cpp
+++ b/2d/_collisions/polygon_polygon/main.cpp
@@ -34,6 +34,7 @@ struct Rigidbody {
void reset() {
numImpulses = 0;
velocity = { 0, 0 };
+ rotationalVelocity = 0.f;
}
void setMomentOfInertia(float32 moi) {
@@ -158,7 +159,7 @@ struct ConvexPolygon {
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);
+ body.momentOfInertia = (PI * (width * height * body.mass)) / 4.f;
}
void update(float32 dtSeconds) {
@@ -223,31 +224,29 @@ void load() {
renderer.load(&context);
for (int index = 0; index < 4; index++) {
- polygons[index].width = 50.f;
- polygons[index].height = 50.f;
+ polygons[index].body.reset();
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].width = (polygons[index].body.mass / 2.f) * 20.f;
+ polygons[index].height = (polygons[index].body.mass / 2.f) * 20.f;
+
polygons[index].numVertices = (index + 1) * 3;
polygons[index].color = Vector4 {
index == 0 || index == 3 ? 255.f : 0.f,
@@ -284,9 +283,9 @@ bool projectionsOverlap(Vector2 first, Vector2 second) {
}
float32 getProjectionOverlap(Vector2 first, Vector2 second) {
- float32 firstOverlap = fabs(first.x - second.y);
- float32 secondOverlap = fabs(second.x - first.y);
- return firstOverlap > secondOverlap ? secondOverlap : firstOverlap;
+ float32 e = MIN(first.y, second.y);
+ float32 f = MAX(first.x, second.x);
+ return e - f;
}
const float32 EPSILON = 1.f;
@@ -374,13 +373,12 @@ void resolveCollision(Rigidbody* first, Rigidbody* second, IntersectionResult* i
float32 linearDenomPart = collisionNormal.dot(collisionNormal * (1.f / first->mass + 1.f / second->mass));
float32 rotationalDenomPart = (firstPerpNorm * firstPerpNorm) / first->momentOfInertia + (sndPerpNorm * sndPerpNorm) / second->momentOfInertia;
- // @TODO: Most of my 2D rotational work is pretty broken. Let's ignore it for the time being;
- float32 impulseMagnitude = numerator / (linearDenomPart);// + rotationalDenomPart);
+ float32 impulseMagnitude = numerator / (linearDenomPart + rotationalDenomPart);
first->velocity = first->velocity + (collisionNormal * (impulseMagnitude / first->mass));
second->velocity = second->velocity - (collisionNormal * (impulseMagnitude / second->mass));
- // first->rotationalVelocity = first->rotationalVelocity + firstPerp.dot(collisionNormal * impulseMagnitude) / first->momentOfInertia;
- // second->rotationalVelocity = second->rotationalVelocity - secondPerp.dot(collisionNormal * impulseMagnitude) / second->momentOfInertia;
+ first->rotationalVelocity = first->rotationalVelocity + firstPerp.dot(collisionNormal * impulseMagnitude) / first->momentOfInertia;
+ second->rotationalVelocity = second->rotationalVelocity - secondPerp.dot(collisionNormal * impulseMagnitude) / second->momentOfInertia;
}
void update(float32 deltaTimeSeconds, void* userData) {
@@ -430,6 +428,7 @@ void update(float32 deltaTimeSeconds, void* userData) {
first->update(frameTimeRemaining);
second->update(frameTimeRemaining);
+ i = 0;
}
}
diff --git a/2d/_collisions/polygon_polygon/snippet1.cpp b/2d/_collisions/polygon_polygon/snippet1.cpp
new file mode 100644
index 0000000..3277cf9
--- /dev/null
+++ b/2d/_collisions/polygon_polygon/snippet1.cpp
@@ -0,0 +1,52 @@
+
+Vector2 getProjection(Vector2* vertices, int numVertices, Vector2 axis) {
+ // Find the min and max vertex projections
+ float32 min = axis.dot(vertices[0]);
+ float32 max = min;
+
+ for (int v = 1; v < numVertices; v++) {
+ float32 d = axis.dot(vertices[v]);
+
+ if (d < min) {
+ min = d;
+ } else if (d > max) {
+ max = d;
+ }
+ }
+
+ return Vector2 { min, max };
+}
+
+bool projectionsOverlap(Vector2 first, Vector2 second) {
+ return first.x <= second.y && second.x <= first.y;
+}
+
+bool doIntersect(ConvexPolygon* first, ConvexPolygon* second) {
+ IntersectionResult ir;
+
+ // Check agaisnt the edges of the first polygon
+ for (int i = 0; i < first->numVertices; i++) {
+ Vector2 normal = first->edges[i].normal;
+
+ Vector2 firstProj = getProjection(first->transformedVertices, first->numVertices, normal);
+ Vector2 secondProj = getProjection(second->transformedVertices, second->numVertices, normal);
+
+ if (!projectionsOverlap(firstProj, secondProj)) {
+ return false;
+ }
+ }
+
+ // Check against the edges of the second polygon
+ for (int i = 0; i < second->numVertices; i++) {
+ Vector2 normal = second->edges[i].normal;
+
+ Vector2 firstProj = getProjection(first->transformedVertices, first->numVertices, normal);
+ Vector2 secondProj = getProjection(second->transformedVertices, second->numVertices, normal);
+
+ if (!projectionsOverlap(firstProj, secondProj)) {
+ return false;
+ }
+ }
+
+ return true;
+}