From 7b4dedf0ce66c405d6a4c4006862350053c71127 Mon Sep 17 00:00:00 2001 From: mattkae Date: Sat, 29 Jan 2022 10:44:32 -0500 Subject: Doing undamped simulation correctly --- 2d/softbody/softbody_1/undamped.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to '2d/softbody/softbody_1/undamped.cpp') diff --git a/2d/softbody/softbody_1/undamped.cpp b/2d/softbody/softbody_1/undamped.cpp index b041a6f..68e0636 100644 --- a/2d/softbody/softbody_1/undamped.cpp +++ b/2d/softbody/softbody_1/undamped.cpp @@ -36,13 +36,11 @@ namespace Undamped { // -- Spring initial variables float32 k = 4; // Spring Constant, in N / m - float32 initialDisplacement = 3.f; - float32 initialVelocity = 0.f; // -- Spring runtime variables - float32 angularVelocity = 0.f; - float32 displacement = 0.f; - float32 timeElapsed = 0.f; + float32 force = 0.f; + float32 velocity = 0.f; + float32 position = 0.f; void load(Renderer2d* renderer, SpringWeight* inWieight, float32 length, float32 inInitialDisplacement, float32 inK, float32 loopRadius); void update(float32 dtSeconds); @@ -106,6 +104,7 @@ namespace Undamped { void SpringWeight::load(Renderer2d* renderer, float32 inMass, Vector4 startColor, Vector4 endColor) { mass = inMass; radius = mass * 16.f; + if (radius > 42) radius = 42.f; const int32 numSegments = 96; const float32 radiansPerSegment = (2.f * PI) / static_cast(numSegments); const int32 numVertices = numSegments * 3; @@ -149,14 +148,12 @@ namespace Undamped { shape.unload(); } - void Spring::load(Renderer2d* renderer, SpringWeight* inWeight, float32 length, float32 inInitialDisplacement, float32 inK, float32 loopRadius) { + void Spring::load(Renderer2d* renderer, SpringWeight* inWeight, float32 length, float32 initialDisplacement, float32 inK, float32 loopRadius) { weight = inWeight; - initialDisplacement = inInitialDisplacement; - displacement = 0; + position = initialDisplacement; k = inK; - - angularVelocity = sqrtf(k / weight->mass); - timeElapsed = 0.f; + force = -k * initialDisplacement; + velocity = sqrtf(k / weight->mass); const int32 verticesPerSegment = 6; numSegments = 256; @@ -170,12 +167,19 @@ namespace Undamped { const float32 offset = 0.25f; int32 vidx = 0; + float32 dx = position; for (int pidx = 0; pidx < numSegments; pidx++) { float32 y1 = lengthIncrement * pidx; float32 x1 = loopWidth * sinf(frequency * y1 + offset); float32 y2 = y1 + lengthIncrement; float32 x2 = loopWidth * sinf(frequency * y2 + offset); + + float32 y1Offset = dx * (1.f - pidx / static_cast(numSegments)); + float32 y2Offset = dx * (1.f - (pidx + 1) / static_cast(numSegments)); + + y1 += y1Offset; + y2 += y2Offset; vertices[vidx++].position = Vector2(x1, y1); vertices[vidx++].position = Vector2(x1, y2); @@ -188,15 +192,16 @@ namespace Undamped { shape.load(vertices, numVertices, renderer, GL_DYNAMIC_DRAW); shape.model = Mat4x4().translateByVec2(Vector2(400, 300)); - weight->shape.model = shape.model.translateByVec2(Vector2(0, -weight->radius)); + weight->shape.model = shape.model.translateByVec2(Vector2(0, -weight->radius + dx)); } void Spring::update(float32 dtSeconds) { - timeElapsed += dtSeconds; - float32 lastDisplacement = displacement; - displacement = initialDisplacement * cosf(angularVelocity * timeElapsed - initialVelocity); - float32 dx = displacement - lastDisplacement; + float32 lastPosition = position; + force = -k * position; + velocity = velocity + (force * dtSeconds) / weight->mass; + position = position + velocity * dtSeconds; + float32 dx = position - lastPosition; int32 vidx = 0; for (int pidx = 0; pidx < numSegments; pidx++) { float32 y1Offset = dx * (1.f - pidx / static_cast(numSegments)); -- cgit v1.2.1