From 0f2fd45969be658ecb3d371eaf93f76d2d82c994 Mon Sep 17 00:00:00 2001
From: Matthew Kosarek <mattkae@protonmail.com>
Date: Thu, 6 May 2021 20:35:19 -0400
Subject: Semi-decent wall collisions, just for fun

---
 frontend/2d/_collisions/rectangle_rectangle.html   |   1 +
 .../_collisions/rectangle_rectangle.html.content   |   1 +
 .../rectangle_rectangle/dist/output.wasm           | Bin 51583 -> 55475 bytes
 .../2d/_collisions/rectangle_rectangle/main.cpp    |  68 +++++++++++++++++++--
 4 files changed, 64 insertions(+), 6 deletions(-)

(limited to 'frontend/2d')

diff --git a/frontend/2d/_collisions/rectangle_rectangle.html b/frontend/2d/_collisions/rectangle_rectangle.html
index 8b10ab6..51cac77 100644
--- a/frontend/2d/_collisions/rectangle_rectangle.html
+++ b/frontend/2d/_collisions/rectangle_rectangle.html
@@ -120,6 +120,7 @@ Vector2 getNormalToLineSegment(LineSegment* segment) {
       <h2>References</h2>
       <ul>
 		<li><a href="https://dyn4j.org/2010/01/sat/">Great SAT Explanation</a></li>
+        <li><a href="https://www.gamedev.net/forums/topic/588070-seperating-axis-theorem---how-to-resolve-contact-points/">SAT Finding Collision Points</a></li>
       </ul>
     </footer>
   </section>
diff --git a/frontend/2d/_collisions/rectangle_rectangle.html.content b/frontend/2d/_collisions/rectangle_rectangle.html.content
index b994f45..2cc5847 100644
--- a/frontend/2d/_collisions/rectangle_rectangle.html.content
+++ b/frontend/2d/_collisions/rectangle_rectangle.html.content
@@ -70,6 +70,7 @@ Vector2 getNormalToLineSegment(LineSegment* segment) {
       <h2>References</h2>
       <ul>
 		<li><a href="https://dyn4j.org/2010/01/sat/">Great SAT Explanation</a></li>
+        <li><a href="https://www.gamedev.net/forums/topic/588070-seperating-axis-theorem---how-to-resolve-contact-points/">SAT Finding Collision Points</a></li>
       </ul>
     </footer>
   </section>
diff --git a/frontend/2d/_collisions/rectangle_rectangle/dist/output.wasm b/frontend/2d/_collisions/rectangle_rectangle/dist/output.wasm
index c13cd15..66f6ab8 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 6b7b8dd..9f6db62 100644
--- a/frontend/2d/_collisions/rectangle_rectangle/main.cpp
+++ b/frontend/2d/_collisions/rectangle_rectangle/main.cpp
@@ -112,6 +112,19 @@ struct Rectangle {
 		body = previousBody;
 	}
 
+    Vector2 getPoint(int index) {
+        switch (index) {
+            case 0: return shape.model * Vector2 { -width / 2.f, -height / 2.f };
+            case 1: return shape.model * Vector2 { -width / 2.f, height / 2.f };
+            case 2: return  shape.model * Vector2 { width / 2.f, height / 2.f };
+            case 3: return  shape.model * Vector2 { width / 2.f, -height / 2.f };
+            default: {
+                printf("Unable to find point: index=%d", index);
+                return Vector2();
+            }
+        }
+    }
+
 	// Note that these getters are needlessly verbose for demonstration's sake
 	void getPoints(Vector2* pointList) {
 		Vector2 botLeft = shape.model * Vector2 { -width / 2.f, -height / 2.f };
@@ -148,7 +161,6 @@ struct Rectangle {
 	}
 };
 
-
 EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
 EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
 
@@ -236,6 +248,8 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) {
 
 	float32 minOverlap = FLT_MAX;
 	Vector2 minOverlapAxis;
+    bool minOverlapAxisIsFromFirstRectangle = true;
+    
 
 	for (int i = 0; i < 4; i++) {
 		Vector2 normal = firstNormals[i];
@@ -251,6 +265,7 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) {
 		if (overlap < minOverlap) {
 			minOverlap = overlap;
 			minOverlapAxis = normal;
+            minOverlapAxisIsFromFirstRectangle = true;
 		}
 	}
 
@@ -268,6 +283,7 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) {
 		if (overlap < minOverlap) {
 			minOverlap = overlap;
 			minOverlapAxis = normal;
+            minOverlapAxisIsFromFirstRectangle = false;
 		}
 	}
 
@@ -275,6 +291,29 @@ IntersectionResult getIntersection(Rectangle* first, Rectangle* second) {
 	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.
+    //
+    Vector2 topPlane;
+    Vector2 bottomPlane;
+
+    for (int p = 0; p < 4; p++) {
+        Vector2 point = minOverlapAxisIsFromFirstRectangle ? first->getPoint(p) : second->getPoint(p);
+
+    }
+
+    ir.firstPointOfApplication = Vector2();
+    ir.secondPointOfApplication = Vector2();
+
 	return ir;
 }
 
@@ -289,14 +328,14 @@ void resolveCollision(Rigidbody* first, Rigidbody* second, IntersectionResult* i
     float32 cofOfRestition = (first->cofOfRestition + second->cofOfRestition) / 2.f;
     float32 numerator = (relativeVelocity * (-1 * (1.f + cofOfRestition))).dot(collisionNormal);
     float32 linearDenomPart = collisionNormal.dot(collisionNormal * (1.f / first->mass + 1.f / second->mass));
-	//float32 rotationalDenomPart = (firstPerpNorm * firstPerpNorm) / first->momentOfInertia + (sndPerpNorm * sndPerpNorm) / second->momentOfInertia;
+	float32 rotationalDenomPart = (firstPerpNorm * firstPerpNorm) / first->momentOfInertia + (sndPerpNorm * sndPerpNorm) / second->momentOfInertia;
 
-    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) {
@@ -305,7 +344,7 @@ void update(float32 deltaTimeSeconds, void* userData) {
 		rectangleList[r].update(deltaTimeSeconds);
 	}
 
-	// Check collisions
+	// Check collisions with other rectangles
 	for (int i = 0; i < 4; i++) {
 		Rectangle* first = &rectangleList[i];
 		for (int j = i + 1; j < 4; j++) {
@@ -348,6 +387,23 @@ void update(float32 deltaTimeSeconds, void* userData) {
 			second->update(frameTimeRemaining);
 		}
 	}
+
+    // Check collisions with walls
+    for (int r = 0; r < 4; r++) {
+        Rectangle* rect = &rectangleList[r];
+        if (rect->body.position.x <= 0.f) {
+            rect->body.velocity = rect->body.velocity - Vector2 { 1.f, 0.f } * (2 * (rect->body.velocity.dot(Vector2 { 1.f, 0.f })));
+        }
+        if (rect->body.position.y <= 0.f) {
+            rect->body.velocity = rect->body.velocity - Vector2 { 0.f, 1.f } * (2 * (rect->body.velocity.dot(Vector2 { 0.f, 1.f })));
+        } 
+        if (rect->body.position.x >= 640.f) {
+            rect->body.velocity = rect->body.velocity - Vector2 { -1.f, 0.f } * (2 * (rect->body.velocity.dot(Vector2{ -1.f, 0.f })));
+        }
+        if (rect->body.position.y >= 480.f) {
+            rect->body.velocity = rect->body.velocity - Vector2 { 0.f, -1.f } * (2 * (rect->body.velocity.dot(Vector2 { 0.f, -1.f }))) ;
+        }
+    }
 	
 	// Renderer
 	renderer.render();
-- 
cgit v1.2.1