diff options
Diffstat (limited to '2d/rigidbody/rigidbody_1')
-rwxr-xr-x | 2d/rigidbody/rigidbody_1/dist/output.wasm | bin | 47394 -> 48588 bytes | |||
-rw-r--r-- | 2d/rigidbody/rigidbody_1/main.cpp | 73 | ||||
-rw-r--r-- | 2d/rigidbody/rigidbody_1/snippet1.cpp | 1 | ||||
-rw-r--r-- | 2d/rigidbody/rigidbody_1/snippet2.cpp | 16 | ||||
-rw-r--r-- | 2d/rigidbody/rigidbody_1/snippet3.cpp | 66 |
5 files changed, 129 insertions, 27 deletions
diff --git a/2d/rigidbody/rigidbody_1/dist/output.wasm b/2d/rigidbody/rigidbody_1/dist/output.wasm Binary files differindex c2fa2dd..5ceed51 100755 --- a/2d/rigidbody/rigidbody_1/dist/output.wasm +++ b/2d/rigidbody/rigidbody_1/dist/output.wasm diff --git a/2d/rigidbody/rigidbody_1/main.cpp b/2d/rigidbody/rigidbody_1/main.cpp index 321e3e5..b3ed359 100644 --- a/2d/rigidbody/rigidbody_1/main.cpp +++ b/2d/rigidbody/rigidbody_1/main.cpp @@ -11,42 +11,76 @@ #include <cmath> #include <cfloat> -const float32 MAX_VELOCITY = 200.f; +struct Impulse { + Vector2 force = { 0, 0 }; + float32 timeOfApplicationSeconds = 0.25f; + float32 timeAppliedSeconds = 0.f; + bool isDead = false; +}; + +const int32 NUM_IMPULSES = 4; struct Rigidbody { - Vector2 force = { 0, 0 }; + int32 numImpulses = 0; + Impulse activeImpulses[NUM_IMPULSES]; Vector2 velocity = { 0, 0 }; Vector2 position = { 0, 0 }; float32 mass = 1.f; void reset() { - force = { 0, 0 }; + numImpulses = 0; velocity = { 0, 0 }; } - void applyForce(Vector2 f) { - force += f; + void applyImpulse(Impulse i) { + if (numImpulses > NUM_IMPULSES) { + printf("Unable to apply impulse. Buffer full.\n"); + return; + } + + activeImpulses[numImpulses] = i; + numImpulses++; } void applyGravity(float32 deltaTimeSeconds) { - velocity += (Vector2 { 0.f, -50.f } * deltaTimeSeconds); + velocity += (Vector2 { 0.f, -9.8f } * deltaTimeSeconds); } void update(float32 deltaTimeSeconds) { applyGravity(deltaTimeSeconds); - - Vector2 acceleration = force / mass; - velocity += (acceleration * deltaTimeSeconds); - if (ABS(velocity.x) > MAX_VELOCITY) { - velocity.x = SIGN(velocity.x) * MAX_VELOCITY; - } - if (ABS(velocity.y) > MAX_VELOCITY) { - velocity.y = SIGN(velocity.y) * MAX_VELOCITY; + Vector2 force; + 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; + force += i.force * impulseDtSeconds; + + + i.timeAppliedSeconds = nextTimeAppliedSeconds; } + Vector2 acceleration = force / mass; + velocity += (acceleration * impulseDtSeconds); position += (velocity * deltaTimeSeconds); - force = Vector2 { 0.f, 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--; + } + } } }; @@ -106,6 +140,7 @@ struct Rectangle { struct Circle { OrthographicShape shape; Rigidbody body; + Vector2 force; float32 radius = 5.f; @@ -204,7 +239,9 @@ void update(float32 deltaTimeSeconds, void* userData) { if (isPointInRectangle(pointer.body.position, rectangle)) { if (!isIntersectingPointer) { isIntersectingPointer = true; - rectangle.body.force += pointer.body.force; + Impulse i; + i.force = pointer.force; + rectangle.body.applyImpulse(i); } } else if (isIntersectingPointer) { isIntersectingPointer = false; @@ -263,8 +300,8 @@ EM_BOOL onMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void return true; } - pointer.body.force.x = static_cast<float32>(mouseEvent->movementX) * 1000.f; - pointer.body.force.y = static_cast<float32>(-mouseEvent->movementY) * 1000.f; + pointer.force.x = static_cast<float32>(mouseEvent->movementX) * 2000.f; + pointer.force.y = static_cast<float32>(-mouseEvent->movementY) * 2000.f; pointer.body.position.x = static_cast<float32>(mouseEvent->targetX); pointer.body.position.y = static_cast<float32>(600.f - mouseEvent->targetY); diff --git a/2d/rigidbody/rigidbody_1/snippet1.cpp b/2d/rigidbody/rigidbody_1/snippet1.cpp index 77a81b7..dd07254 100644 --- a/2d/rigidbody/rigidbody_1/snippet1.cpp +++ b/2d/rigidbody/rigidbody_1/snippet1.cpp @@ -1,7 +1,6 @@ struct Rigidbody { Vector2 force = { 0, 0 }; - Vector2 acceleration = { 0, 0 }; Vector2 velocity = { 0, 0 }; Vector2 position = { 0, 0 }; float32 mass = 1.f; diff --git a/2d/rigidbody/rigidbody_1/snippet2.cpp b/2d/rigidbody/rigidbody_1/snippet2.cpp index 8ad468c..1288209 100644 --- a/2d/rigidbody/rigidbody_1/snippet2.cpp +++ b/2d/rigidbody/rigidbody_1/snippet2.cpp @@ -6,14 +6,6 @@ struct Rigidbody { Vector2 position = { 0, 0 }; float32 mass = 1.f; - void applyForce(Vector2 f) { - force += f; - } - - void applyGravity(float32 deltaTimeSeconds) { - velocity += (Vector2 { 0.f, -50.f } * deltaTimeSeconds); - } - void update(float32 deltaTimeSeconds) { applyGravity(deltaTimeSeconds); @@ -22,4 +14,12 @@ struct Rigidbody { position += (velocity * deltaTimeSeconds); force = Vector2 { 0.f, 0.f }; } + + void applyGravity(float32 deltaTimeSeconds) { + velocity += (Vector2 { 0.f, -9.8.f } * deltaTimeSeconds); + } + + void applyForce(Vector2 f) { + force += f; + } }; diff --git a/2d/rigidbody/rigidbody_1/snippet3.cpp b/2d/rigidbody/rigidbody_1/snippet3.cpp new file mode 100644 index 0000000..a43c884 --- /dev/null +++ b/2d/rigidbody/rigidbody_1/snippet3.cpp @@ -0,0 +1,66 @@ +struct Impulse { + Vector2 force = { 0, 0 }; + float32 timeOfApplicationSeconds = 0.25f; + float32 timeAppliedSeconds = 0.f; + bool isDead = false; +}; + +const int32 NUM_IMPULSES = 4; + +struct Rigidbody { + int32 numImpulses = 0; + Impulse activeImpulses[NUM_IMPULSES]; + Vector2 velocity = { 0, 0 }; + Vector2 position = { 0, 0 }; + float32 mass = 1.f; + + void update(float32 deltaTimeSeconds) { + applyGravity(deltaTimeSeconds); + + // Add up all of the forces acting at this moment + Vector2 force; + for (int32 idx = 0; idx < numImpulses; idx++) { + Impulse& i = activeImpulses[idx]; + + float32 nextTimeAppliedSeconds = i.timeAppliedSeconds + deltaTimeSeconds; + if (nextTimeAppliedSeconds >= i.timeOfApplicationSeconds) { + nextTimeAppliedSeconds = i.timeOfApplicationSeconds; + i.isDead = true; + } + + float32 impulseDtSeconds = nextTimeAppliedSeconds - i.timeAppliedSeconds; + force += i.force * impulseDtSeconds; + i.timeAppliedSeconds = nextTimeAppliedSeconds; + } + + Vector2 acceleration = force / mass; + velocity += (acceleration * impulseDtSeconds); + position += (velocity * deltaTimeSeconds); + + // 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--; + } + } + } + + void applyGravity(float32 deltaTimeSeconds) { + velocity += (Vector2 { 0.f, -9.8f } * deltaTimeSeconds); + } + + void applyImpulse(Impulse i) { + if (numImpulses > NUM_IMPULSES) { + printf("Unable to apply impulse. Buffer full.\n"); + return; + } + + activeImpulses[numImpulses] = i; + numImpulses++; + } +}; |