From ff82253a66ee51fe2f0c088ca964402d53545845 Mon Sep 17 00:00:00 2001 From: Matthew Kosarek Date: Thu, 24 Jun 2021 11:30:36 -0400 Subject: (mkosarek) Rigidbody with rotations --- 2d/rigidbody/rigidbody_2/dist/output.wasm | Bin 48126 -> 50226 bytes 2d/rigidbody/rigidbody_2/main.cpp | 80 ++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 16 deletions(-) (limited to '2d/rigidbody/rigidbody_2') diff --git a/2d/rigidbody/rigidbody_2/dist/output.wasm b/2d/rigidbody/rigidbody_2/dist/output.wasm index f7dcbd9..29c319a 100755 Binary files a/2d/rigidbody/rigidbody_2/dist/output.wasm and b/2d/rigidbody/rigidbody_2/dist/output.wasm differ diff --git a/2d/rigidbody/rigidbody_2/main.cpp b/2d/rigidbody/rigidbody_2/main.cpp index 5f875b8..bad6949 100644 --- a/2d/rigidbody/rigidbody_2/main.cpp +++ b/2d/rigidbody/rigidbody_2/main.cpp @@ -11,46 +11,90 @@ #include #include +struct Impulse { + Vector2 force = { 0, 0 }; + Vector2 pointOfApplication = { 0, 0 }; + float32 timeOfApplicationSeconds = 0.25f; + float32 timeAppliedSeconds = 0.f; + bool isDead = false; +}; + +const int32 NUM_IMPULSES = 4; + struct Rigidbody { - Vector2 linearForce = { 0, 0 }; + int32 numImpulses = 0; + Impulse activeImpulses[NUM_IMPULSES]; Vector2 velocity = { 0, 0 }; Vector2 position = { 0, 0 }; float32 mass = 1.f; - float32 torque = 0.f; float32 rotationalVelocity = 0.f; float32 rotation = 0.f; float32 momentOfInertia = 1.f; void reset() { - linearForce = { 0, 0 }; + numImpulses = 0; velocity = { 0, 0 }; rotationalVelocity = 0.f; rotation = 0.f; } - void applyForce(Vector2 force, Vector2 pointOfApplication) { - linearForce += force; - torque += pointOfApplication.getPerp().dot(force); + void applyImpulse(Impulse i) { + if (numImpulses > NUM_IMPULSES) { + printf("Unable to apply impulse. Buffer full.\n"); + return; + } + + activeImpulses[numImpulses] = i; + numImpulses++; } - void applyGravity() { - applyForce(Vector2 { 0.f, -100.f }, Vector2 { 0.f, 0.f }); + void applyGravity(float32 deltaTimeSeconds) { + velocity += (Vector2 { 0.f, -9.8f } * deltaTimeSeconds); } void update(float32 deltaTimeSeconds) { - applyGravity(); + applyGravity(deltaTimeSeconds); + + Vector2 force; + float32 torque = 0.f; + for (int32 idx = 0; idx < numImpulses; idx++) { + Impulse& i = activeImpulses[idx]; + + float32 nextTimeAppliedSeconds = i.timeAppliedSeconds + deltaTimeSeconds; + if (nextTimeAppliedSeconds >= i.timeOfApplicationSeconds) { + nextTimeAppliedSeconds = i.timeOfApplicationSeconds; // Do the remainder of the time + i.isDead = true; + } + + float32 impulseDtSeconds = nextTimeAppliedSeconds - i.timeAppliedSeconds; + Vector2 forceToApply = i.force * (impulseDtSeconds / i.timeOfApplicationSeconds); + force += forceToApply * impulseDtSeconds; + torque += i.pointOfApplication.getPerp().dot(forceToApply); + + i.timeAppliedSeconds = nextTimeAppliedSeconds; + } - Vector2 acceleration = linearForce / mass; + Vector2 acceleration = force / mass; velocity += (acceleration * deltaTimeSeconds); position += (velocity * deltaTimeSeconds); - linearForce = Vector2 { 0.f, 0.f }; - // New: Update the rotational velocity as well + // New: Update the rotational velocity as well float32 rotationalAcceleration = torque / momentOfInertia; rotationalVelocity += (rotationalAcceleration * deltaTimeSeconds); rotation += (rotationalVelocity * deltaTimeSeconds); - torque = 0.f; + + // Cleanup any impulses that have expired in the mean time + for (int32 idx = 0; idx < numImpulses; idx++) { + if (activeImpulses[idx].isDead) { + for (int j = idx + 1; j < numImpulses; j++) { + activeImpulses[j - 1] = activeImpulses[j]; + } + + idx = idx - 1; + numImpulses--; + } + } } }; @@ -112,6 +156,7 @@ struct Rectangle { struct Circle { OrthographicShape shape; Rigidbody body; + Vector2 force; float32 radius = 5.f; @@ -211,7 +256,10 @@ void update(float32 deltaTimeSeconds, void* userData) { if (!isIntersectingPointer) { isIntersectingPointer = true; Vector2 pointOfApplication = pointer.body.position - rectangle.body.position; - rectangle.body.applyForce(pointer.body.linearForce, pointOfApplication); + Impulse i; + i.force = pointer.force; + i.pointOfApplication = pointOfApplication; + rectangle.body.applyImpulse(i); } } else if (isIntersectingPointer) { isIntersectingPointer = false; @@ -270,8 +318,8 @@ EM_BOOL onMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void return true; } - pointer.body.linearForce.x = static_cast(mouseEvent->movementX) * 1000.f; - pointer.body.linearForce.y = static_cast(-mouseEvent->movementY) * 1000.f; + pointer.force.x = static_cast(mouseEvent->movementX) * 1000.f; + pointer.force.y = static_cast(-mouseEvent->movementY) * 1000.f; pointer.body.position.x = static_cast(mouseEvent->targetX); pointer.body.position.y = static_cast(600.f - mouseEvent->targetY); -- cgit v1.2.1