summaryrefslogtreecommitdiff
path: root/2d
diff options
context:
space:
mode:
Diffstat (limited to '2d')
-rw-r--r--2d/softbody/softbody_1.html79
-rw-r--r--2d/softbody/softbody_1.html.content79
-rwxr-xr-x2d/softbody/softbody_1/build.sh2
-rw-r--r--2d/softbody/softbody_1/damped.cpp5
-rw-r--r--2d/softbody/softbody_1/damped.h8
-rw-r--r--2d/softbody/softbody_1/dist/output.js14
-rwxr-xr-x2d/softbody/softbody_1/dist/output.wasmbin55671 -> 57098 bytes
-rw-r--r--2d/softbody/softbody_1/main.cpp25
-rw-r--r--2d/softbody/softbody_1/undamped.cpp46
-rw-r--r--2d/softbody/softbody_1/undamped.h10
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
index 9c47c47..33cc2b8 100755
--- a/2d/softbody/softbody_1/dist/output.wasm
+++ b/2d/softbody/softbody_1/dist/output.wasm
Binary files differ
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();
}