diff options
author | Matthew Kosarek <mattkae@protonmail.com> | 2021-11-17 06:58:13 -0500 |
---|---|---|
committer | Matthew Kosarek <mattkae@protonmail.com> | 2021-11-17 06:58:13 -0500 |
commit | a9de99cd643fbb1bb1555fd7206202fb600093e6 (patch) | |
tree | 4200bdcaf045f1a676c8f13825df2fed5ebb6f55 /2d/softbody | |
parent | fd3c1e74e7ebe9125b98dba311efcbe73e89859e (diff) |
(mkosarek) Fixing the displacement displayer
Diffstat (limited to '2d/softbody')
-rw-r--r-- | 2d/softbody/softbody_1.html | 79 | ||||
-rw-r--r-- | 2d/softbody/softbody_1.html.content | 79 | ||||
-rwxr-xr-x | 2d/softbody/softbody_1/build.sh | 2 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/damped.cpp | 5 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/damped.h | 8 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/dist/output.js | 14 | ||||
-rwxr-xr-x | 2d/softbody/softbody_1/dist/output.wasm | bin | 55671 -> 57098 bytes | |||
-rw-r--r-- | 2d/softbody/softbody_1/main.cpp | 25 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/undamped.cpp | 46 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/undamped.h | 10 |
10 files changed, 246 insertions, 22 deletions
diff --git a/2d/softbody/softbody_1.html b/2d/softbody/softbody_1.html index f103545..12ee272 100644 --- a/2d/softbody/softbody_1.html +++ b/2d/softbody/softbody_1.html @@ -54,6 +54,7 @@ <script src="./softbody_1/dist/output.js"></script> <script> window.onload = function() { + // -- Play/Stop Logic function addButtonListener(pPlay, pStop, pDisableElementList) { var lPlayElement = document.getElementById(pPlay), lStopElement = document.getElementById(pStop); @@ -82,6 +83,66 @@ addButtonListener('gl_canvas_play_damped', 'gl_canvas_stop_damped', [ ]); + + // -- Slider logic + var sliderList = document.querySelectorAll('input[type=range]'), + attachListener = function(element) { + var output = element.nextElementSibling; + var updateOutput = function() { + var value = Number(element.value); + output.innerHTML = value; + } + + element.addEventListener('input', updateOutput); + element.addEventListener('change', updateOutput); + updateOutput(); + }; + + for(var i = 0; i < sliderList.length; i++) { + attachListener(sliderList[i]); + } + + // -- Add callbacks for sliders + Module.onRuntimeInitialized = function() { + var Undamped_SetLength = Module.cwrap('Undamped_SetLength', 'void', ['number']), + Undamped_SetDisplacement = Module.cwrap('Undamped_SetDisplacement', 'void', ['number']), + Undamped_SetK = Module.cwrap('Undamped_SetK', 'void', ['number']), + Undamped_SetMass = Module.cwrap('Undamped_SetMass', 'void', ['number']), + lengthSlider = document.getElementById('undamped_spring_length'), + displacementSlider = document.getElementById('undamped_start_position'), + kSlider = document.getElementById('undamped_spring_constant'), + massSlider = document.getElementById('undamped_spring_mass'), + setLength = function(value) { + value = Number(value); + Undamped_SetLength(value); + + var currentDisplacementValue = displacementSlider.value; + var bound = value / 2.0; + displacementSlider.setAttribute('max', bound); + displacementSlider.setAttribute('min', -bound); + + if (currentDisplacementValue < -bound) currentDisplacementValue = -bound; + else if (currentDisplacementValue > bound) currentDisplacementValue = bound; + + var event = new Event('change'); + displacementSlider.value = currentDisplacementValue; + displacementSlider.dispatchEvent(event); + }, + setDisplacement = function(value) { + Undamped_SetDisplacement(value); + }, + setK = function(value) { + Undamped_SetK(value); + }, + setMass = function(mass) { + Undamped_SetMass(mass); + }; + + lengthSlider.addEventListener('change', function(event) { setLength(Number(event.target.value)); }); + displacementSlider.addEventListener('change', function(event) { setDisplacement(Number(event.target.value)); }); + kSlider.addEventListener('change', function(event) { setK(Number(event.target.value)); }); + massSlider.addEventListener('change', function(event) { setMass(Number(event.target.value)); }); + }; } </script> @@ -104,12 +165,26 @@ <p> <span class='widget_container'> <label for='undamped_spring_length'>Spring Length (m)</label> - <input type='range' id='undamped_spring_length'/> + <input type='range' id='undamped_spring_length' min="50" max="300" value="150"/> + <span></span> </span> <span class='widget_container'> <label for='undamped_start_position'>Start Displacement (m)</label> - <input type='range' id='undamped_start_position'/> + <input type='range' id='undamped_start_position' min='-75' max='75' value='0'/> + <span></span> + </span> + + <span class='widget_container'> + <label for='undamped_spring_constant'>Spring Constant (N / m)</label> + <input type='range' id='undamped_spring_constant' min='0.1' max='5.0' value='1.0' step='0.1'/> + <span></span> + </span> + + <span class='widget_container'> + <label for='undamped_spring_mass'>Mass (kg)</label> + <input type='range' id='undamped_spring_mass' min='0.1' max='10.0' value='1.0' step='0.1'/> + <span></span> </span> </p> diff --git a/2d/softbody/softbody_1.html.content b/2d/softbody/softbody_1.html.content index 9e48383..4f66ce3 100644 --- a/2d/softbody/softbody_1.html.content +++ b/2d/softbody/softbody_1.html.content @@ -1,6 +1,7 @@ <script src="./softbody_1/dist/output.js"></script> <script> window.onload = function() { + // -- Play/Stop Logic function addButtonListener(pPlay, pStop, pDisableElementList) { var lPlayElement = document.getElementById(pPlay), lStopElement = document.getElementById(pStop); @@ -29,6 +30,66 @@ addButtonListener('gl_canvas_play_damped', 'gl_canvas_stop_damped', [ ]); + + // -- Slider logic + var sliderList = document.querySelectorAll('input[type=range]'), + attachListener = function(element) { + var output = element.nextElementSibling; + var updateOutput = function() { + var value = Number(element.value); + output.innerHTML = value; + } + + element.addEventListener('input', updateOutput); + element.addEventListener('change', updateOutput); + updateOutput(); + }; + + for(var i = 0; i < sliderList.length; i++) { + attachListener(sliderList[i]); + } + + // -- Add callbacks for sliders + Module.onRuntimeInitialized = function() { + var Undamped_SetLength = Module.cwrap('Undamped_SetLength', 'void', ['number']), + Undamped_SetDisplacement = Module.cwrap('Undamped_SetDisplacement', 'void', ['number']), + Undamped_SetK = Module.cwrap('Undamped_SetK', 'void', ['number']), + Undamped_SetMass = Module.cwrap('Undamped_SetMass', 'void', ['number']), + lengthSlider = document.getElementById('undamped_spring_length'), + displacementSlider = document.getElementById('undamped_start_position'), + kSlider = document.getElementById('undamped_spring_constant'), + massSlider = document.getElementById('undamped_spring_mass'), + setLength = function(value) { + value = Number(value); + Undamped_SetLength(value); + + var currentDisplacementValue = displacementSlider.value; + var bound = value / 2.0; + displacementSlider.setAttribute('max', bound); + displacementSlider.setAttribute('min', -bound); + + if (currentDisplacementValue < -bound) currentDisplacementValue = -bound; + else if (currentDisplacementValue > bound) currentDisplacementValue = bound; + + var event = new Event('change'); + displacementSlider.value = currentDisplacementValue; + displacementSlider.dispatchEvent(event); + }, + setDisplacement = function(value) { + Undamped_SetDisplacement(value); + }, + setK = function(value) { + Undamped_SetK(value); + }, + setMass = function(mass) { + Undamped_SetMass(mass); + }; + + lengthSlider.addEventListener('change', function(event) { setLength(Number(event.target.value)); }); + displacementSlider.addEventListener('change', function(event) { setDisplacement(Number(event.target.value)); }); + kSlider.addEventListener('change', function(event) { setK(Number(event.target.value)); }); + massSlider.addEventListener('change', function(event) { setMass(Number(event.target.value)); }); + }; } </script> @@ -51,12 +112,26 @@ <p> <span class='widget_container'> <label for='undamped_spring_length'>Spring Length (m)</label> - <input type='range' id='undamped_spring_length'/> + <input type='range' id='undamped_spring_length' min="50" max="300" value="150"/> + <span></span> </span> <span class='widget_container'> <label for='undamped_start_position'>Start Displacement (m)</label> - <input type='range' id='undamped_start_position'/> + <input type='range' id='undamped_start_position' min='-75' max='75' value='0'/> + <span></span> + </span> + + <span class='widget_container'> + <label for='undamped_spring_constant'>Spring Constant (N / m)</label> + <input type='range' id='undamped_spring_constant' min='0.1' max='5.0' value='1.0' step='0.1'/> + <span></span> + </span> + + <span class='widget_container'> + <label for='undamped_spring_mass'>Mass (kg)</label> + <input type='range' id='undamped_spring_mass' min='0.1' max='10.0' value='1.0' step='0.1'/> + <span></span> </span> </p> diff --git a/2d/softbody/softbody_1/build.sh b/2d/softbody/softbody_1/build.sh index f1c15de..e1de1bb 100755 --- a/2d/softbody/softbody_1/build.sh +++ b/2d/softbody/softbody_1/build.sh @@ -13,4 +13,4 @@ if [ ! -d ./dist ]; then fi echo "$filepaths" -emcc -o dist/output.js main.cpp undamped.cpp damped.cpp $filepaths -s ALLOW_MEMORY_GROWTH=1 -s USE_WEBGL2=1 -s FULL_ES3=1 -s WASM=1 -s NO_EXIT_RUNTIME=1 +emcc -o dist/output.js main.cpp undamped.cpp damped.cpp $filepaths -s ALLOW_MEMORY_GROWTH=1 -s USE_WEBGL2=1 -s FULL_ES3=1 -s WASM=1 -s NO_EXIT_RUNTIME=1 -s EXPORTED_RUNTIME_METHODS=cwrap diff --git a/2d/softbody/softbody_1/damped.cpp b/2d/softbody/softbody_1/damped.cpp index 010963b..d623c06 100644 --- a/2d/softbody/softbody_1/damped.cpp +++ b/2d/softbody/softbody_1/damped.cpp @@ -1,3 +1,4 @@ +#include "damped.h" #include "undamped.h" #include "../../../shared_cpp/Renderer2d.h" #include "../../../shared_cpp/types.h" @@ -54,6 +55,10 @@ namespace Damped { void unload(); }; + DampedInitVariables initVariables; + void setInitVariables(DampedInitVariables newVariables) { initVariables = newVariables; } + DampedInitVariables getInitVariables() { return initVariables; } + WebglContext* context; Renderer2d renderer; MainLoop mainLoop; diff --git a/2d/softbody/softbody_1/damped.h b/2d/softbody/softbody_1/damped.h index f36e8dd..12bdd2d 100644 --- a/2d/softbody/softbody_1/damped.h +++ b/2d/softbody/softbody_1/damped.h @@ -1,8 +1,16 @@ #pragma once +#include "../../../shared_cpp/types.h" struct WebglContext; namespace Damped { + struct DampedInitVariables { + float32 springLength = 150.f; + float32 initialDisplacement = 10.f; + }; + void init(WebglContext* inContext); + void setInitVariables(DampedInitVariables newVariables); + DampedInitVariables getInitVariables(); } diff --git a/2d/softbody/softbody_1/dist/output.js b/2d/softbody/softbody_1/dist/output.js index 24241bf..2e94e85 100644 --- a/2d/softbody/softbody_1/dist/output.js +++ b/2d/softbody/softbody_1/dist/output.js @@ -2939,6 +2939,18 @@ var asm = createWasm(); var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); /** @type {function(...*):?} */ +var _Undamped_SetLength = Module["_Undamped_SetLength"] = createExportWrapper("Undamped_SetLength"); + +/** @type {function(...*):?} */ +var _Undamped_SetDisplacement = Module["_Undamped_SetDisplacement"] = createExportWrapper("Undamped_SetDisplacement"); + +/** @type {function(...*):?} */ +var _Undamped_SetK = Module["_Undamped_SetK"] = createExportWrapper("Undamped_SetK"); + +/** @type {function(...*):?} */ +var _Undamped_SetMass = Module["_Undamped_SetMass"] = createExportWrapper("Undamped_SetMass"); + +/** @type {function(...*):?} */ var _main = Module["_main"] = createExportWrapper("main"); /** @type {function(...*):?} */ @@ -2989,7 +3001,7 @@ var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji"); if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; if (!Object.getOwnPropertyDescriptor(Module, "ccall")) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "cwrap")) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +Module["cwrap"] = cwrap; if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; diff --git a/2d/softbody/softbody_1/dist/output.wasm b/2d/softbody/softbody_1/dist/output.wasm Binary files differindex 9c47c47..33cc2b8 100755 --- a/2d/softbody/softbody_1/dist/output.wasm +++ b/2d/softbody/softbody_1/dist/output.wasm diff --git a/2d/softbody/softbody_1/main.cpp b/2d/softbody/softbody_1/main.cpp index 33a2c77..f0f46ed 100644 --- a/2d/softbody/softbody_1/main.cpp +++ b/2d/softbody/softbody_1/main.cpp @@ -15,3 +15,28 @@ int main() { // Interactions with DOM handled below // +extern "C" { + EMSCRIPTEN_KEEPALIVE void Undamped_SetLength(float length) { + Undamped::UndampedInitVariables initVariables = Undamped::getInitVariables(); + initVariables.springLength = length; + Undamped::setInitVariables(initVariables); + } + + EMSCRIPTEN_KEEPALIVE void Undamped_SetDisplacement(float displacement) { + Undamped::UndampedInitVariables initVariables = Undamped::getInitVariables(); + initVariables.initialDisplacement = displacement; + Undamped::setInitVariables(initVariables); + } + + EMSCRIPTEN_KEEPALIVE void Undamped_SetK(float k) { + Undamped::UndampedInitVariables initVariables = Undamped::getInitVariables(); + initVariables.k = k; + Undamped::setInitVariables(initVariables); + } + + EMSCRIPTEN_KEEPALIVE void Undamped_SetMass(float mass) { + Undamped::UndampedInitVariables initVariables = Undamped::getInitVariables(); + initVariables.mass = mass; + Undamped::setInitVariables(initVariables); + } +} diff --git a/2d/softbody/softbody_1/undamped.cpp b/2d/softbody/softbody_1/undamped.cpp index ec53f50..a77e2a4 100644 --- a/2d/softbody/softbody_1/undamped.cpp +++ b/2d/softbody/softbody_1/undamped.cpp @@ -16,10 +16,10 @@ namespace Undamped { struct SpringWeight { Mesh2d shape; - float32 radius; - float32 mass = 2.f; + float32 radius = 2.f; + float32 mass = 1.f; - void load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor); + void load(Renderer2d* renderer, float32 inMass, Vector4 startColor, Vector4 endColor); void update(float32 dtSeconds); void render(Renderer2d* renderer); void unload(); @@ -28,24 +28,31 @@ namespace Undamped { struct Spring { SpringWeight* weight; + // -- Rendering Mesh2d shape; - Vertex2d* vertices = NULL; int32 numSegments = 0; int32 numVertices = 0; + + // -- Spring initial variables float32 k = 4; // Spring Constant, in N / m float32 initialDisplacement = 3.f; float32 initialVelocity = 0.f; - float32 angularVelocity = 0.f; // To be calculated + + // -- Spring runtime variables + float32 angularVelocity = 0.f; float32 displacement = 0.f; float32 timeElapsed = 0.f; - void load(Renderer2d* renderer, SpringWeight* inWieight, float32 length, float32 loopRadius); + void load(Renderer2d* renderer, SpringWeight* inWieight, float32 length, float32 inInitialDisplacement, float32 inK, float32 loopRadius); void update(float32 dtSeconds); void render(Renderer2d* renderer); void unload(); }; + UndampedInitVariables initVariables; + void setInitVariables(UndampedInitVariables newVariables) { initVariables = newVariables; } + UndampedInitVariables getInitVariables() { return initVariables; } WebglContext* context; Renderer2d renderer; MainLoop mainLoop; @@ -69,8 +76,8 @@ namespace Undamped { renderer.load(context); - weight.load(&renderer, 32.f, Vector4 { 55.f, 235.f, 35.f, 255.f }, Vector4 { 235.f, 5.f, 235.f, 255.f }); - spring.load(&renderer, &weight, 250.f, 64.f); + weight.load(&renderer, initVariables.mass, Vector4 { 55.f, 235.f, 35.f, 255.f }, Vector4 { 235.f, 5.f, 235.f, 255.f }); + spring.load(&renderer, &weight, initVariables.springLength, initVariables.initialDisplacement, initVariables.k, 64.f); mainLoop.run(update); } @@ -96,8 +103,9 @@ namespace Undamped { } - void SpringWeight::load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor) { - radius = inRadius; + void SpringWeight::load(Renderer2d* renderer, float32 inMass, Vector4 startColor, Vector4 endColor) { + mass = inMass; + radius = mass * 16.f; const int32 numSegments = 96; const float32 radiansPerSegment = (2.f * PI) / static_cast<float>(numSegments); const int32 numVertices = numSegments * 3; @@ -141,11 +149,15 @@ namespace Undamped { shape.unload(); } - void Spring::load(Renderer2d* renderer, SpringWeight* inWeight, float32 length, float32 loopRadius) { + void Spring::load(Renderer2d* renderer, SpringWeight* inWeight, float32 length, float32 inInitialDisplacement, float32 inK, float32 loopRadius) { weight = inWeight; + initialDisplacement = inInitialDisplacement; + displacement = initialDisplacement; + k = inK; + angularVelocity = sqrtf(k / weight->mass); timeElapsed = 0.f; - + const int32 verticesPerSegment = 6; numSegments = 256; numVertices = numSegments * verticesPerSegment; @@ -181,12 +193,14 @@ namespace Undamped { void Spring::update(float32 dtSeconds) { timeElapsed += dtSeconds; + float32 lastDisplacement = displacement; displacement = initialDisplacement * cosf(angularVelocity * timeElapsed - initialVelocity); + float32 dx = displacement - lastDisplacement; int32 vidx = 0; for (int pidx = 0; pidx < numSegments; pidx++) { - float32 y1Offset = displacement * (1.f - pidx / static_cast<float32>(numSegments)); - float32 y2Offset = displacement * (1.f - (pidx + 1) / static_cast<float32>(numSegments)); + float32 y1Offset = dx * (1.f - pidx / static_cast<float32>(numSegments)); + float32 y2Offset = dx * (1.f - (pidx + 1) / static_cast<float32>(numSegments)); vertices[vidx++].position.y += y1Offset; vertices[vidx++].position.y += y2Offset; vertices[vidx++].position.y += y1Offset; @@ -194,8 +208,8 @@ namespace Undamped { vertices[vidx++].position.y += y2Offset; vertices[vidx++].position.y += y2Offset; } - - weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, displacement)); + + weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, dx)); } void Spring::render(Renderer2d* renderer) { diff --git a/2d/softbody/softbody_1/undamped.h b/2d/softbody/softbody_1/undamped.h index a87e446..6fa0afb 100644 --- a/2d/softbody/softbody_1/undamped.h +++ b/2d/softbody/softbody_1/undamped.h @@ -1,8 +1,18 @@ #pragma once +#include "../../../shared_cpp/types.h" struct WebglContext; namespace Undamped { + struct UndampedInitVariables { + float32 springLength = 150.f; + float32 initialDisplacement = 0.f; + float32 k = 1.f; + float32 mass = 1.f; + }; + void init(WebglContext* inContext); + void setInitVariables(UndampedInitVariables newVariables); + UndampedInitVariables getInitVariables(); } |