diff options
| author | Matthew Kosarek <mattkae@protonmail.com> | 2021-04-18 15:10:25 -0400 | 
|---|---|---|
| committer | Matthew Kosarek <mattkae@protonmail.com> | 2021-04-18 15:10:25 -0400 | 
| commit | db4bcc0073fa1042e9779453af1dcdef7582fbd1 (patch) | |
| tree | 752f51d9b7e95c0c7ed3d8d5216f23f21627050c /frontend | |
| parent | e7c1e9cc3a90f3e5f638f43f21054a4032f9d9f8 (diff) | |
Have 2D pill collisions working pretty well now
Diffstat (limited to 'frontend')
| -rwxr-xr-x | frontend/2d/_collisions/pill_line/dist/output.wasm | bin | 59663 -> 58666 bytes | |||
| -rw-r--r-- | frontend/2d/_collisions/pill_line/main.cpp | 73 | ||||
| -rw-r--r-- | frontend/shared_cpp/WebglHelper.h | 6 | ||||
| -rw-r--r-- | frontend/shared_cpp/mathlib.h | 7 | 
4 files changed, 53 insertions, 33 deletions
diff --git a/frontend/2d/_collisions/pill_line/dist/output.wasm b/frontend/2d/_collisions/pill_line/dist/output.wasm Binary files differindex 89ef8ce..ddf862c 100755 --- a/frontend/2d/_collisions/pill_line/dist/output.wasm +++ b/frontend/2d/_collisions/pill_line/dist/output.wasm diff --git a/frontend/2d/_collisions/pill_line/main.cpp b/frontend/2d/_collisions/pill_line/main.cpp index 8700649..9f585f1 100644 --- a/frontend/2d/_collisions/pill_line/main.cpp +++ b/frontend/2d/_collisions/pill_line/main.cpp @@ -33,11 +33,13 @@ struct Rigidbody {          force += f;      } -    void applyGravity() { -        force += Vector2 { 0.f, -100.f }; +    void applyGravity(float32 deltaTimeSeconds) { +        velocity += (Vector2 { 0.f, -96.f } * deltaTimeSeconds);      }      void update(float32 deltaTimeSeconds) { +        applyGravity(deltaTimeSeconds); +                  Vector2 acceleration = force / mass;          velocity += (acceleration * deltaTimeSeconds);          position += (velocity * deltaTimeSeconds); @@ -103,7 +105,7 @@ struct Pill {          shape.load(vertices, numVertices, renderer);          body.reset(); -        // https://byjus.com/jee/moment-of-inertia-of-ellipse/ +        body.mass = 100.f;          body.momentOfInertia = (body.mass * (a * a + b * b)) / 4.f;          a = width / 2.f; @@ -151,7 +153,7 @@ struct LineSegment {          shape.load(vertices, 2, renderer);          body.reset(); -        body.mass = 100000.f; +        body.mass = 1000000000.f;          body.cofOfRestition = 1.f;          body.rotationalVelocity = 0;          body.velocity = Vector2(); @@ -172,6 +174,10 @@ struct LineSegment {              start.y + (end.y - start.y) * t,          };      } + +    Vector2 getNormal() { +        return (end - start).getPerp().normalize(); +    }  };  struct IntersectionResult { @@ -208,9 +214,8 @@ int main() {  void load() {      renderer.load(&context); -    pill.body.position = Vector2 { context.width / 2.f, context.height / 2.f }; +    pill.body.position = Vector2 { context.width / 4.f, context.height / 2.f };      pill.load(&renderer, 64, 100.f, 50.f); -	pill.body.rotationalVelocity = 0.3f;      segmentList[0].load(&renderer, Vector4().fromColor(191, 251, 146, 255.f), Vector2 { 50.f, 0.f }, Vector2 { 50.f, static_cast<float>(context.height) });      segmentList[1].load(&renderer, Vector4().fromColor(159, 224, 210, 255.f), Vector2 { context.width - 50.f, 0.f }, Vector2 { context.width - 50.f, static_cast<float>(context.height) }); @@ -220,11 +225,6 @@ void load() {      mainLoop.run(update);  } -float32 areaOfTriangle(Vector2 a, Vector2 b, Vector2 c) { -    // Refernce for this for the formula: https://www.onlinemath4all.com/area-of-triangle-using-determinant-formula.html -    return ABS(0.5 * (a.x * b.y - b.x * a.y + b.x * c.y - c.x * b.y + c.x * a.y - a.x * c.y)); -} -  IntersectionResult getIntersection(Pill* pill, LineSegment* segment) {      IntersectionResult result;      Mat4x4 inverseModel = pill->shape.model.inverse(); @@ -241,22 +241,28 @@ IntersectionResult getIntersection(Pill* pill, LineSegment* segment) {          return result;      } -    float32 t1 = (-B + sqrtf(determinant)) / (2 * A); -    float32 t2 = (-B - sqrtf(determinant)) / (2 * A); +    float32 t; +    if (determinant < 0.001f) { +        t = -B / (2.f * A); +    } else { +        t = (-B + sqrtf(determinant)) / (2.f * A); +        // Or: t = (-B - sqrtf(determinant)) / (2 * A); +    } + +    Vector2 pointOnLine = segment->getPointOnLine(t); // This point is in world space and line space, since the line is in world space -    Vector2 pointOnLine = segment->getPointOnLine(t1); // This point is in world space and line space, since the line is in world space -    Vector2 pointOnEllipse = pointOnLine - pill->body.position; // This point is in ellipse space -    pointOnEllipse.printDebug("Point on ellipse"); +    Vector2 pointOnTransformedLine = { +        start.x + (end.x - start.x) * t, +        start.y + (end.y - start.y) * t +    }; -    float32 parametricTEllipse = atan2f( pointOnEllipse.y / pill->b , pointOnEllipse.x / pill->a ); -    Vector2 tangent = { -pill->a * sinf(parametricTEllipse), pill->b * cosf(parametricTEllipse) }; -    Vector2 normal = tangent.getPerp(); -	normal.printDebug("Normal"); -    // or: Vector2 normal = { pointOnEllipse.x * (pill->b / pill->a), pointOnEllipse.y * (pill->a / pill->b) }; +    Vector2 pointOnEllipse = (pointOnTransformedLine); + +    Vector2 normal = segment->getNormal();      result.intersect = true; -    result.relativeVelocity = pill->body.velocity - segment->body.velocity;; -    result.collisionNormal = normal.normalize(); +    result.relativeVelocity = pill->body.velocity - segment->body.velocity; +    result.collisionNormal = normal;      result.firstPointOfApplication = pointOnEllipse;      result.secondPointOfApplication = pointOnLine; @@ -270,24 +276,24 @@ void resolveCollision(Rigidbody* first, Rigidbody* second, IntersectionResult* i      Vector2 secondPerp       = ir->secondPointOfApplication.getPerp();      float32 cofOfRestition = (first->cofOfRestition + second->cofOfRestition) / 2.f; -    float32 lNumerator = (relativeVelocity * -(1.0 + cofOfRestition)).dot(collisionNormal); -    float32 lLinearDenomPart = collisionNormal.dot(collisionNormal * (1 / first->mass + 1 / second->mass)); -    float32 lRotationalDenomPart = powf(firstPerp.dot(collisionNormal), 2) / first->momentOfInertia + powf(secondPerp.dot(collisionNormal), 2) / second->momentOfInertia; +    float32 lNumerator = (relativeVelocity * -(1.f + cofOfRestition)).dot(collisionNormal); +    float32 lLinearDenomPart = collisionNormal.dot(collisionNormal * (1.f / first->mass + 1.f / second->mass)); +    float32 lRotationalDenomPart = powf(firstPerp.dot(collisionNormal), 2.f) / first->momentOfInertia + powf(secondPerp.dot(collisionNormal), 2) / second->momentOfInertia; + +    //ir->firstPointOfApplication.printDebug("PoA"); +    //firstPerp.printDebug("PoA Perp"); +    //collisionNormal.printDebug("Normal"); +    //printf("Dot: %f\n", firstPerp.dot(collisionNormal));      float32 lImpulseMagnitude = lNumerator / (lLinearDenomPart + lRotationalDenomPart);      first->velocity = first->velocity + (collisionNormal * (lImpulseMagnitude / first->mass));      second->velocity = second->velocity - (collisionNormal * (lImpulseMagnitude / second->mass)); -      first->rotationalVelocity = first->rotationalVelocity + firstPerp.dot(collisionNormal * lImpulseMagnitude) / first->momentOfInertia;      second->rotationalVelocity = second->rotationalVelocity - secondPerp.dot(collisionNormal * lImpulseMagnitude) / second->momentOfInertia;  }  void update(float32 deltaTimeSeconds, void* userData) { - -    // Input -    pill.body.applyGravity(); -      // Update      Pill copyPill = pill.copy();      pill.update(deltaTimeSeconds); @@ -308,7 +314,7 @@ void update(float32 deltaTimeSeconds, void* userData) {                  pill.update(subdividedTimeSeconds);                  subIr = getIntersection(&pill, &segmentList[lineIdx]); -                if (subdividedTimeSeconds == 0.f) { +                if (subdividedTimeSeconds <= 0.f) {                      printf("Error: Should not be happening.\n");                      break;                  } @@ -316,7 +322,8 @@ void update(float32 deltaTimeSeconds, void* userData) {              printf("Found intersection at timestamp: %f\n", subdividedTimeSeconds);              resolveCollision(&pill.body, &segmentList[lineIdx].body, &ir); -            pill.update(deltaTimeSeconds - subdividedTimeSeconds); +            deltaTimeSeconds = deltaTimeSeconds - subdividedTimeSeconds; +            pill.update(deltaTimeSeconds);          }      } diff --git a/frontend/shared_cpp/WebglHelper.h b/frontend/shared_cpp/WebglHelper.h new file mode 100644 index 0000000..dbdb23f --- /dev/null +++ b/frontend/shared_cpp/WebglHelper.h @@ -0,0 +1,6 @@ +#pragma once +#include "mathlib.h" + +struct OrthographicRenderer; + +void render2DArrow(Vector2 start, Vector2 end, OrthographicRenderer* renderer); diff --git a/frontend/shared_cpp/mathlib.h b/frontend/shared_cpp/mathlib.h index 383c880..b9f3fee 100644 --- a/frontend/shared_cpp/mathlib.h +++ b/frontend/shared_cpp/mathlib.h @@ -57,6 +57,13 @@ struct Vector2 {          return { -y, x };      } +    Vector2 rotate(float angle) { +        return { +            x * cosf(angle) - y * sinf(angle), +            x * sinf(angle) + y * cosf(angle) +        }; +    } +      void printDebug(const char* name) {          printf("%s=Vector2(%f, %f)\n", name, x, y);      }  | 
