diff options
author | Matthew Kosarek <mattkae@protonmail.com> | 2021-11-14 14:38:06 -0500 |
---|---|---|
committer | Matthew Kosarek <mattkae@protonmail.com> | 2021-11-14 14:38:06 -0500 |
commit | fd3c1e74e7ebe9125b98dba311efcbe73e89859e (patch) | |
tree | 0adb39252bb0e86a45a456971b5253edd7237014 | |
parent | 5c613a10364f30bd6add25f7950433f0c482c3ca (diff) |
(mkosarek) Working on undamped and damped
-rw-r--r-- | 2d/_collisions/polygon_polygon.html | 2 | ||||
-rw-r--r-- | 2d/_collisions/rectangle_rectangle.html | 2 | ||||
-rw-r--r-- | 2d/rigidbody/rigidbody_1.html | 2 | ||||
-rw-r--r-- | 2d/rigidbody/rigidbody_2.html | 2 | ||||
-rw-r--r-- | 2d/rigidbody/rigidbody_3.html | 2 | ||||
-rw-r--r-- | 2d/softbody/softbody_1.html | 103 | ||||
-rw-r--r-- | 2d/softbody/softbody_1.html.content | 92 | ||||
-rwxr-xr-x | 2d/softbody/softbody_1/build.sh | 2 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/damped.cpp | 255 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/damped.h | 8 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/dist/output.js | 944 | ||||
-rwxr-xr-x | 2d/softbody/softbody_1/dist/output.wasm | bin | 44089 -> 55671 bytes | |||
-rw-r--r-- | 2d/softbody/softbody_1/main.cpp | 219 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/undamped.cpp | 227 | ||||
-rw-r--r-- | 2d/softbody/softbody_1/undamped.h | 8 | ||||
-rw-r--r-- | 3d/rigidbody.html | 2 | ||||
-rw-r--r-- | index.css | 11 | ||||
-rw-r--r-- | index.html | 2 | ||||
-rw-r--r-- | roadmap.html | 2 | ||||
-rw-r--r-- | shared_cpp/WebglContext.h | 7 | ||||
-rw-r--r-- | shared_cpp/mathlib.h | 1 |
21 files changed, 1135 insertions, 758 deletions
diff --git a/2d/_collisions/polygon_polygon.html b/2d/_collisions/polygon_polygon.html index 75dbcfd..d384bc7 100644 --- a/2d/_collisions/polygon_polygon.html +++ b/2d/_collisions/polygon_polygon.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/2d/_collisions/rectangle_rectangle.html b/2d/_collisions/rectangle_rectangle.html index 75c2e62..11376b7 100644 --- a/2d/_collisions/rectangle_rectangle.html +++ b/2d/_collisions/rectangle_rectangle.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/2d/rigidbody/rigidbody_1.html b/2d/rigidbody/rigidbody_1.html index 153e443..239bf52 100644 --- a/2d/rigidbody/rigidbody_1.html +++ b/2d/rigidbody/rigidbody_1.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/2d/rigidbody/rigidbody_2.html b/2d/rigidbody/rigidbody_2.html index f24666c..64429b5 100644 --- a/2d/rigidbody/rigidbody_2.html +++ b/2d/rigidbody/rigidbody_2.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/2d/rigidbody/rigidbody_3.html b/2d/rigidbody/rigidbody_3.html index ed07bbb..f35a151 100644 --- a/2d/rigidbody/rigidbody_3.html +++ b/2d/rigidbody/rigidbody_3.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/2d/softbody/softbody_1.html b/2d/softbody/softbody_1.html index b505f1b..f103545 100644 --- a/2d/softbody/softbody_1.html +++ b/2d/softbody/softbody_1.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> @@ -54,40 +54,111 @@ <script src="./softbody_1/dist/output.js"></script> <script> window.onload = function() { - var lPlayElement = document.getElementById('gl_canvas_play'), - lStopElement = document.getElementById('gl_canvas_stop'); - lPlayElement.addEventListener('click', function() { - lPlayElement.style.display = 'none'; - lStopElement.style.display = 'block'; - }); - lStopElement.addEventListener('click', function() { - lStopElement.style.display = 'none'; - lPlayElement.style.display = 'block'; - }); + function addButtonListener(pPlay, pStop, pDisableElementList) { + var lPlayElement = document.getElementById(pPlay), + lStopElement = document.getElementById(pStop); + lPlayElement.addEventListener('click', function() { + lPlayElement.style.display = 'none'; + lStopElement.style.display = 'block'; + + pDisableElementList.forEach(function(element) { + element.disabled = true; + }); + }); + lStopElement.addEventListener('click', function() { + lStopElement.style.display = 'none'; + lPlayElement.style.display = 'block'; + + pDisableElementList.forEach(function(element) { + element.disabled = false; + }); + }); + } + + addButtonListener('gl_canvas_play_undamped', 'gl_canvas_stop_undamped', [ + document.getElementById('undamped_spring_length'), + document.getElementById('undamped_start_position') + ]); + addButtonListener('gl_canvas_play_damped', 'gl_canvas_stop_damped', [ + + ]); } </script> <article> - <h1>Softbody</h1> + <h1>Springs</h1> + <section> + <p> + It is time to investigate what it means to have a deformation in our physics system. By deformation, I mean that the + vertices of our shapes are no longer fixed to one point within the model. We will begin with what I believe + by investigating the most common of all deformations: a weight attached to a spring in two dimensions. + </p> + </section> <section> <h2></h2> </section> <section> <h2> - Live Example + Undamped Springs + </h2> + <p> + <span class='widget_container'> + <label for='undamped_spring_length'>Spring Length (m)</label> + <input type='range' id='undamped_spring_length'/> + </span> + + <span class='widget_container'> + <label for='undamped_start_position'>Start Displacement (m)</label> + <input type='range' id='undamped_start_position'/> + </span> + + </p> + <div class="opengl_canvas_container"> + <canvas id="gl_canvas_undamped" width="800" height="600"></canvas> + <button id="gl_canvas_play_undamped" class="play_button"> + Play + </button> + <button id="gl_canvas_stop_undamped" class="stop_button"> + Stop + </button> + </div> + </section> + + <section> + <h2> + Damped Springs </h2> <p> + </p> <div class="opengl_canvas_container"> - <canvas id="gl_canvas" width="800" height="600"></canvas> - <button id="gl_canvas_play" class="play_button"> + <canvas id="gl_canvas_damped" width="800" height="600"></canvas> + <button id="gl_canvas_play_damped" class="play_button"> Play </button> - <button id="gl_canvas_stop" class="stop_button"> + <button id="gl_canvas_stop_damped" class="stop_button"> Stop </button> </div> </section> + + <footer id='references'> + <h2>References</h2> + <ul> + <li> + <a href='https://www.youtube.com/watch?v=Z52emur7Rko'>Wonderful Undamped Resource</a> + </li> + <li> + <a href='https://www.youtube.com/watch?v=CTd1uVq5-l8'>Wonderful Damped Resource</a> + </li> + <li> + <a href='http://ambrsoft.com/CalcPhysics/Spring/SpringData.htm'>List of Equations for Spring Motion</a> + </li> + <li> + <a href='https://www.ryanjuckett.com/damped-springs/'>Ryan Juckett's Explanation of Damped Springs</a> + </li> + </ul> + </footer> </article> </main> </body> diff --git a/2d/softbody/softbody_1.html.content b/2d/softbody/softbody_1.html.content index 92be361..9e48383 100644 --- a/2d/softbody/softbody_1.html.content +++ b/2d/softbody/softbody_1.html.content @@ -1,16 +1,34 @@ <script src="./softbody_1/dist/output.js"></script> <script> window.onload = function() { - var lPlayElement = document.getElementById('gl_canvas_play'), - lStopElement = document.getElementById('gl_canvas_stop'); - lPlayElement.addEventListener('click', function() { - lPlayElement.style.display = 'none'; - lStopElement.style.display = 'block'; - }); - lStopElement.addEventListener('click', function() { - lStopElement.style.display = 'none'; - lPlayElement.style.display = 'block'; - }); + function addButtonListener(pPlay, pStop, pDisableElementList) { + var lPlayElement = document.getElementById(pPlay), + lStopElement = document.getElementById(pStop); + lPlayElement.addEventListener('click', function() { + lPlayElement.style.display = 'none'; + lStopElement.style.display = 'block'; + + pDisableElementList.forEach(function(element) { + element.disabled = true; + }); + }); + lStopElement.addEventListener('click', function() { + lStopElement.style.display = 'none'; + lPlayElement.style.display = 'block'; + + pDisableElementList.forEach(function(element) { + element.disabled = false; + }); + }); + } + + addButtonListener('gl_canvas_play_undamped', 'gl_canvas_stop_undamped', [ + document.getElementById('undamped_spring_length'), + document.getElementById('undamped_start_position') + ]); + addButtonListener('gl_canvas_play_damped', 'gl_canvas_stop_damped', [ + + ]); } </script> @@ -28,18 +46,64 @@ </section> <section> <h2> - Live Example + Undamped Springs </h2> <p> + <span class='widget_container'> + <label for='undamped_spring_length'>Spring Length (m)</label> + <input type='range' id='undamped_spring_length'/> + </span> + + <span class='widget_container'> + <label for='undamped_start_position'>Start Displacement (m)</label> + <input type='range' id='undamped_start_position'/> + </span> + </p> <div class="opengl_canvas_container"> - <canvas id="gl_canvas" width="800" height="600"></canvas> - <button id="gl_canvas_play" class="play_button"> + <canvas id="gl_canvas_undamped" width="800" height="600"></canvas> + <button id="gl_canvas_play_undamped" class="play_button"> Play </button> - <button id="gl_canvas_stop" class="stop_button"> + <button id="gl_canvas_stop_undamped" class="stop_button"> Stop </button> </div> </section> + + <section> + <h2> + Damped Springs + </h2> + <p> + + </p> + <div class="opengl_canvas_container"> + <canvas id="gl_canvas_damped" width="800" height="600"></canvas> + <button id="gl_canvas_play_damped" class="play_button"> + Play + </button> + <button id="gl_canvas_stop_damped" class="stop_button"> + Stop + </button> + </div> + </section> + + <footer id='references'> + <h2>References</h2> + <ul> + <li> + <a href='https://www.youtube.com/watch?v=Z52emur7Rko'>Wonderful Undamped Resource</a> + </li> + <li> + <a href='https://www.youtube.com/watch?v=CTd1uVq5-l8'>Wonderful Damped Resource</a> + </li> + <li> + <a href='http://ambrsoft.com/CalcPhysics/Spring/SpringData.htm'>List of Equations for Spring Motion</a> + </li> + <li> + <a href='https://www.ryanjuckett.com/damped-springs/'>Ryan Juckett's Explanation of Damped Springs</a> + </li> + </ul> + </footer> </article> diff --git a/2d/softbody/softbody_1/build.sh b/2d/softbody/softbody_1/build.sh index 892dddd..f1c15de 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 $filepaths -s ALLOW_MEMORY_GROWTH=1 -s USE_WEBGL2=1 -s FULL_ES3=1 -s WASM=1 -s NO_EXIT_RUNTIME=1
\ No newline at end of file +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 diff --git a/2d/softbody/softbody_1/damped.cpp b/2d/softbody/softbody_1/damped.cpp new file mode 100644 index 0000000..010963b --- /dev/null +++ b/2d/softbody/softbody_1/damped.cpp @@ -0,0 +1,255 @@ +#include "undamped.h" +#include "../../../shared_cpp/Renderer2d.h" +#include "../../../shared_cpp/types.h" +#include "../../../shared_cpp/WebglContext.h" +#include "../../../shared_cpp/mathlib.h" +#include "../../../shared_cpp/MainLoop.h" +#include <cstdio> +#include <cmath> +#include <emscripten/html5.h> +#include <unistd.h> +#include <pthread.h> +#include <cmath> +#include <cfloat> + +namespace Damped { + struct DampedSpringWeight { + Mesh2d shape; + float32 radius; + float32 mass = 1.f; + + void load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor); + void update(float32 dtSeconds); + void render(Renderer2d* renderer); + void unload(); + }; + + struct DampedSpring { + DampedSpringWeight* weight; + + Mesh2d shape; + + Vertex2d* vertices = NULL; + int32 numSegments = 0; + int32 numVertices = 0; + + // Initialization variables + float32 k = 4; // DampedSpring Constant, in N / m (Hooke's Law) + float32 c = 1.f; // Viscous damping coefficient (Damping force) + float32 R = 2.f; + float32 gamma = 6.2; + + // Constants calculated at load time + float32 discriminant = 0.f; + float32 omega1 = 0.f; + + // Update variables + float32 displacement = 0.f; + float32 timeElapsed = 0.f; + + + void load(Renderer2d* renderer, DampedSpringWeight* inWieight, float32 length, float32 loopRadius); + void update(float32 dtSeconds); + void render(Renderer2d* renderer); + void unload(); + }; + + WebglContext* context; + Renderer2d renderer; + MainLoop mainLoop; + DampedSpringWeight weight; + DampedSpring spring; + + EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); + EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); + void load(); + void update(float32 deltaTimeSeconds, void* userData); + void unload(); + + void init(WebglContext* inContext) { + context = inContext; + emscripten_set_click_callback("#gl_canvas_play_damped", NULL, false, onPlayClicked); + emscripten_set_click_callback("#gl_canvas_stop_damped", NULL, false, onStopClicked); + } + + void load() { + context->init("#gl_canvas_damped"); + + 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, 16.f); + + mainLoop.run(update); + } + + void update(float32 deltaTimeSeconds, void* userData) { + // -- Update + spring.update(deltaTimeSeconds); + weight.update(deltaTimeSeconds); + + // -- Render + renderer.render(); + weight.render(&renderer); + spring.render(&renderer); + } + + void unload() { + mainLoop.stop(); + renderer.unload(); + weight.unload(); + spring.unload(); + context->destroy(); + } + + void DampedSpringWeight::load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor) { + radius = inRadius; + const int32 numSegments = 96; + const float32 radiansPerSegment = (2.f * PI) / static_cast<float>(numSegments); + const int32 numVertices = numSegments * 3; + + float32 t = 0.f; + float32 tIncrement = 1.f / (numSegments / 2.f); + startColor = startColor.toNormalizedColor(); + endColor = endColor.toNormalizedColor(); + + Vertex2d vertices[numVertices]; + for (int idx = 0; idx < numSegments; idx++) { + int vIdx = idx * 3; + + Vector4 color = lerp(startColor, endColor, t); + if (idx >= numSegments / 2) { + t -= tIncrement; + } else { + t += tIncrement; + } + + vertices[vIdx].color = color; + vertices[vIdx].position = Vector2 { radius * cosf(radiansPerSegment * idx), radius * sinf(radiansPerSegment * idx) }; + vertices[vIdx + 1].color = color; + vertices[vIdx + 1].position = Vector2 { 0.f, 0.f }; + vertices[vIdx + 2].color = color; + vertices[vIdx + 2].position = Vector2 { radius * cosf(radiansPerSegment * (idx + 1)), radius * sinf(radiansPerSegment * (idx + 1)) }; + } + + shape.load(vertices, numVertices, renderer); + } + + void DampedSpringWeight::update(float32 dtSeconds) { + + } + + void DampedSpringWeight::render(Renderer2d* renderer) { + shape.render(renderer); + } + + void DampedSpringWeight::unload() { + shape.unload(); + } + + const float32 epsilon = 0.0001f; + + void DampedSpring::load(Renderer2d* renderer, DampedSpringWeight* inWeight, float32 length, float32 loopRadius) { + weight = inWeight; + discriminant = c * c - (4 * weight->mass * k); + + if (discriminant < epsilon && discriminant > -epsilon) { // Real repeated root: Overdamped motion + + } + else if (discriminant > 0) { // Two real roots: Critically damped motion + + } + else { // Complex pair (less than zero): Underdamped motion + omega1 = sqrtf(-discriminant) / (2.f * weight->mass); // Get the real part of the number + } + + timeElapsed = 0.f; + + const int32 verticesPerSegment = 6; + numSegments = 256; + numVertices = numSegments * verticesPerSegment; + vertices = new Vertex2d[numVertices]; + + float32 lengthIncrement = length / static_cast<float32>(numSegments); + + const float32 frequency = 0.25f; + const float32 loopWidth = 20.f; + const float32 offset = 0.25f; + + int32 vidx = 0; + 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); + + vertices[vidx++].position = Vector2(x1, y1); + vertices[vidx++].position = Vector2(x1, y2); + vertices[vidx++].position = Vector2(x2, y1); + vertices[vidx++].position = Vector2(x2, y1); + vertices[vidx++].position = Vector2(x1, y2); + vertices[vidx++].position = Vector2(x2, y2); + } + + 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)); + } + + void DampedSpring::update(float32 dtSeconds) { + timeElapsed += dtSeconds; + + if (discriminant < epsilon && discriminant > -epsilon) { // Real repeated root: Overdamped motion + + } + else if (discriminant > 0) { // Two real roots: Critically damped motion + + } + else { // Complex pair (less than zero): Underdamped motion + float32 exponent = (-c / (2 * weight->mass)) * timeElapsed; + displacement = R * pow(E, exponent) * (cosf(omega1 * timeElapsed - gamma)); + } + + 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)); + vertices[vidx++].position.y += y1Offset; + vertices[vidx++].position.y += y2Offset; + vertices[vidx++].position.y += y1Offset; + vertices[vidx++].position.y += y1Offset; + vertices[vidx++].position.y += y2Offset; + vertices[vidx++].position.y += y2Offset; + } + + weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, displacement)); + } + + void DampedSpring::render(Renderer2d* renderer) { + glBindBuffer(GL_ARRAY_BUFFER, shape.vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2d), &vertices[0]); + + shape.render(renderer); + } + + void DampedSpring::unload() { + shape.unload(); + delete[] vertices; + } + + + EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { + printf("Play clicked\n"); + + load(); + return true; + } + + EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { + printf("Stop clicked\n"); + unload(); + return true; + } +} diff --git a/2d/softbody/softbody_1/damped.h b/2d/softbody/softbody_1/damped.h new file mode 100644 index 0000000..f36e8dd --- /dev/null +++ b/2d/softbody/softbody_1/damped.h @@ -0,0 +1,8 @@ +#pragma once + +struct WebglContext; + +namespace Damped { + void init(WebglContext* inContext); +} + diff --git a/2d/softbody/softbody_1/dist/output.js b/2d/softbody/softbody_1/dist/output.js index 914e5e2..24241bf 100644 --- a/2d/softbody/softbody_1/dist/output.js +++ b/2d/softbody/softbody_1/dist/output.js @@ -41,13 +41,16 @@ var quit_ = function(status, toThrow) { // Determine the runtime environment we are in. You can customize this by // setting the ENVIRONMENT setting at compile time (see settings.js). -// Attempt to auto-detect the environment -var ENVIRONMENT_IS_WEB = typeof window === 'object'; -var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; +var ENVIRONMENT_IS_WEB = false; +var ENVIRONMENT_IS_WORKER = false; +var ENVIRONMENT_IS_NODE = false; +var ENVIRONMENT_IS_SHELL = false; +ENVIRONMENT_IS_WEB = typeof window === 'object'; +ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; // N.b. Electron.js environment is simultaneously a NODE-environment, but // also a web environment. -var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string'; -var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; +ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string'; +ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; if (Module['ENVIRONMENT']) { throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)'); @@ -72,7 +75,6 @@ var nodeFS; var nodePath; if (ENVIRONMENT_IS_NODE) { - if (!(typeof process === 'object' && typeof require === 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); if (ENVIRONMENT_IS_WORKER) { scriptDirectory = require('path').dirname(scriptDirectory) + '/'; } else { @@ -98,16 +100,6 @@ readBinary = function readBinary(filename) { return ret; }; -readAsync = function readAsync(filename, onload, onerror) { - if (!nodeFS) nodeFS = require('fs'); - if (!nodePath) nodePath = require('path'); - filename = nodePath['normalize'](filename); - nodeFS['readFile'](filename, function(err, data) { - if (err) onerror(err); - else onload(data.buffer); - }); -}; - // end include: node_shell_read.js if (process['argv'].length > 1) { thisProgram = process['argv'][1].replace(/\\/g, '/'); @@ -128,11 +120,7 @@ readAsync = function readAsync(filename, onload, onerror) { process['on']('unhandledRejection', abort); - quit_ = function(status, toThrow) { - if (keepRuntimeAlive()) { - process['exitCode'] = status; - throw toThrow; - } + quit_ = function(status) { process['exit'](status); }; @@ -141,8 +129,6 @@ readAsync = function readAsync(filename, onload, onerror) { } else if (ENVIRONMENT_IS_SHELL) { - if ((typeof process === 'object' && typeof require === 'function') || typeof window === 'object' || typeof importScripts === 'function') throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); - if (typeof read != 'undefined') { read_ = function shell_read(f) { return read(f); @@ -159,10 +145,6 @@ if (ENVIRONMENT_IS_SHELL) { return data; }; - readAsync = function readAsync(f, onload, onerror) { - setTimeout(function() { onload(readBinary(f)); }, 0); - }; - if (typeof scriptArgs != 'undefined') { arguments_ = scriptArgs; } else if (typeof arguments != 'undefined') { @@ -203,8 +185,6 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { scriptDirectory = ''; } - if (!(typeof window === 'object' || typeof importScripts === 'function')) throw new Error('not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)'); - // Differentiate the Web Worker from the Node Worker case, as reading must // be done differently. { @@ -354,15 +334,17 @@ var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; -function alignMemory() { abort('`alignMemory` is now a library function and not included by default; add it to your library.js __deps or to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE on the command line'); } - -assert(!ENVIRONMENT_IS_SHELL, "shell environment detected but not enabled at build time. Add 'shell' to `-s ENVIRONMENT` to enable."); var STACK_ALIGN = 16; +function alignMemory(size, factor) { + if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default + return Math.ceil(size / factor) * factor; +} + function getNativeTypeSize(type) { switch (type) { case 'i1': case 'i8': return 1; @@ -560,6 +542,10 @@ function addFunction(func, sig) { // end include: runtime_debug.js +function makeBigInt(low, high, unsigned) { + return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0)); +} + var tempRet0 = 0; var setTempRet0 = function(value) { @@ -570,6 +556,10 @@ var getTempRet0 = function() { return tempRet0; }; +function getCompilerSetting(name) { + throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work'; +} + // === Preamble library stuff === @@ -729,12 +719,9 @@ function ccall(ident, returnType, argTypes, args, opts) { } } var ret = func.apply(null, cArgs); - function onDone(ret) { - if (stack !== 0) stackRestore(stack); - return convertReturnValue(ret); - } - ret = onDone(ret); + ret = convertReturnValue(ret); + if (stack !== 0) stackRestore(stack); return ret; } @@ -1273,6 +1260,10 @@ function checkStackCookie() { if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian! (Run with -s SUPPORT_BIG_ENDIAN=1 to bypass)'; })(); +function abortFnPtrError(ptr, sig) { + abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). Build with ASSERTIONS=2 for more info."); +} + // end include: runtime_assertions.js var __ATPRERUN__ = []; // functions called before the runtime is initialized var __ATINIT__ = []; // functions called during startup @@ -1282,11 +1273,6 @@ var __ATPOSTRUN__ = []; // functions called after the main() is called var runtimeInitialized = false; var runtimeExited = false; -var runtimeKeepaliveCounter = 0; - -function keepRuntimeAlive() { - return noExitRuntime || runtimeKeepaliveCounter > 0; -} function preRun() { @@ -1509,18 +1495,25 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile; // include: URIUtils.js +function hasPrefix(str, prefix) { + return String.prototype.startsWith ? + str.startsWith(prefix) : + str.indexOf(prefix) === 0; +} + // Prefix of data URIs emitted by SINGLE_FILE and related options. var dataURIPrefix = 'data:application/octet-stream;base64,'; // Indicates whether filename is a base64 data URI. function isDataURI(filename) { - // Prefix of data URIs emitted by SINGLE_FILE and related options. - return filename.startsWith(dataURIPrefix); + return hasPrefix(filename, dataURIPrefix); } +var fileURIPrefix = "file://"; + // Indicates whether filename is delivered via file protocol (as opposed to http/https) function isFileURI(filename) { - return filename.startsWith('file://'); + return hasPrefix(filename, fileURIPrefix); } // end include: URIUtils.js @@ -1540,11 +1533,10 @@ function createExportWrapper(name, fixedasm) { }; } -var wasmBinaryFile; - wasmBinaryFile = 'output.wasm'; - if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile); - } +var wasmBinaryFile = 'output.wasm'; +if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); +} function getBinary(file) { try { @@ -1590,7 +1582,7 @@ function getBinaryPromise() { } } } - + // Otherwise, getBinary should be able to get it synchronously return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); } @@ -1630,26 +1622,24 @@ function createWasm() { // we can't run yet (except in a pthread, where we have a custom sync instantiator) addRunDependency('wasm-instantiate'); - // Prefer streaming instantiation if available. // Async compilation can be confusing when an error on the page overwrites Module // (for example, if the order of elements is wrong, and the one defining Module is // later), so we save Module and check it later. var trueModule = Module; - function receiveInstantiationResult(result) { - // 'result' is a ResultObject object which has both the module and instance. + function receiveInstantiatedSource(output) { + // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance. // receiveInstance() will swap in the exports (to Module.asm) so they can be called assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); trueModule = null; // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line. // When the regression is fixed, can restore the above USE_PTHREADS-enabled path. - receiveInstance(result['instance']); + receiveInstance(output['instance']); } function instantiateArrayBuffer(receiver) { return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info); - }).then(function (instance) { - return instance; + var result = WebAssembly.instantiate(binary, info); + return result; }).then(receiver, function(reason) { err('failed to asynchronously prepare wasm: ' + reason); @@ -1661,6 +1651,7 @@ function createWasm() { }); } + // Prefer streaming instantiation if available. function instantiateAsync() { if (!wasmBinary && typeof WebAssembly.instantiateStreaming === 'function' && @@ -1670,19 +1661,16 @@ function createWasm() { typeof fetch === 'function') { return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) { var result = WebAssembly.instantiateStreaming(response, info); - - return result.then( - receiveInstantiationResult, - function(reason) { + return result.then(receiveInstantiatedSource, function(reason) { // We expect the most common failure cause to be a bad MIME type for the binary, // in which case falling back to ArrayBuffer instantiation should work. err('wasm streaming compile failed: ' + reason); err('falling back to ArrayBuffer instantiation'); - return instantiateArrayBuffer(receiveInstantiationResult); + return instantiateArrayBuffer(receiveInstantiatedSource); }); }); } else { - return instantiateArrayBuffer(receiveInstantiationResult); + return instantiateArrayBuffer(receiveInstantiatedSource); } } @@ -1770,6 +1758,11 @@ var ASM_CONSTS = { return error.stack.toString(); } + var runtimeKeepaliveCounter=0; + function keepRuntimeAlive() { + return noExitRuntime || runtimeKeepaliveCounter > 0; + } + function stackTrace() { var js = jsStackTrace(); if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); @@ -1800,14 +1793,13 @@ var ASM_CONSTS = { updateGlobalBufferAndViews(wasmMemory.buffer); return 1 /*success*/; } catch(e) { - err('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e); + console.error('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e); } // implicit 0 return to save code size (caller will cast "undefined" into 0 // anyhow) } function _emscripten_resize_heap(requestedSize) { var oldSize = HEAPU8.length; - requestedSize = requestedSize >>> 0; // With pthreads, races can happen (another thread might increase the size in between), so return a failure, and let the caller retry. assert(requestedSize > oldSize); @@ -1821,7 +1813,7 @@ var ASM_CONSTS = { // 4. If we were unable to allocate as much memory, it may be due to over-eager decision to excessively reserve due to (3) above. // Hence if an allocation fails, cut down on the amount of excess growth, in an attempt to succeed to perform a smaller allocation. - // A limit is set for how much we can grow. We should not exceed that + // A limit was set for how much we can grow. We should not exceed that // (the wasm binary specifies it, so if we tried, we'd fail anyhow). // In CAN_ADDRESS_2GB mode, stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate full 4GB Wasm memories, the size will wrap // back to 0 bytes in Wasm side for any code that deals with heap sizes, which would require special casing all heap size related code to treat @@ -1851,7 +1843,7 @@ var ASM_CONSTS = { return false; } - var JSEvents = {inEventHandler:0,removeAllEventListeners:function() { + var JSEvents={inEventHandler:0,removeAllEventListeners:function() { for (var i = JSEvents.eventHandlers.length-1; i >= 0; --i) { JSEvents._removeHandler(i); } @@ -1964,7 +1956,7 @@ var ASM_CONSTS = { return cString > 2 ? UTF8ToString(cString) : cString; } - var specialHTMLTargets = [0, typeof document !== 'undefined' ? document : 0, typeof window !== 'undefined' ? window : 0]; + var specialHTMLTargets=[0, typeof document !== 'undefined' ? document : 0, typeof window !== 'undefined' ? window : 0]; function findEventTarget(target) { target = maybeCStringToJsString(target); var domElement = specialHTMLTargets[target] || (typeof document !== 'undefined' ? document.querySelector(target) : undefined); @@ -1984,32 +1976,31 @@ var ASM_CONSTS = { } function fillMouseEventData(eventStruct, e, target) { assert(eventStruct % 4 == 0); - HEAPF64[((eventStruct)>>3)] = e.timeStamp; var idx = eventStruct >> 2; - HEAP32[idx + 2] = e.screenX; - HEAP32[idx + 3] = e.screenY; - HEAP32[idx + 4] = e.clientX; - HEAP32[idx + 5] = e.clientY; - HEAP32[idx + 6] = e.ctrlKey; - HEAP32[idx + 7] = e.shiftKey; - HEAP32[idx + 8] = e.altKey; - HEAP32[idx + 9] = e.metaKey; - HEAP16[idx*2 + 20] = e.button; - HEAP16[idx*2 + 21] = e.buttons; - - HEAP32[idx + 11] = e["movementX"] + HEAP32[idx + 0] = e.screenX; + HEAP32[idx + 1] = e.screenY; + HEAP32[idx + 2] = e.clientX; + HEAP32[idx + 3] = e.clientY; + HEAP32[idx + 4] = e.ctrlKey; + HEAP32[idx + 5] = e.shiftKey; + HEAP32[idx + 6] = e.altKey; + HEAP32[idx + 7] = e.metaKey; + HEAP16[idx*2 + 16] = e.button; + HEAP16[idx*2 + 17] = e.buttons; + + HEAP32[idx + 9] = e["movementX"] ; - HEAP32[idx + 12] = e["movementY"] + HEAP32[idx + 10] = e["movementY"] ; var rect = getBoundingClientRect(target); - HEAP32[idx + 13] = e.clientX - rect.left; - HEAP32[idx + 14] = e.clientY - rect.top; + HEAP32[idx + 11] = e.clientX - rect.left; + HEAP32[idx + 12] = e.clientY - rect.top; } function registerMouseEventCallback(target, userData, useCapture, callbackfunc, eventTypeId, eventTypeString, targetThread) { - if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 72 ); + if (!JSEvents.mouseEvent) JSEvents.mouseEvent = _malloc( 64 ); target = findEventTarget(target); var mouseEventHandlerFunc = function(ev) { @@ -2082,7 +2073,7 @@ var ASM_CONSTS = { // Closure is expected to be allowed to minify the '.multiDrawWebgl' property, so not accessing it quoted. return !!(ctx.multiDrawWebgl = ctx.getExtension('WEBGL_multi_draw')); } - var GL = {counter:1,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},queries:[],samplers:[],transformFeedbacks:[],syncs:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode) { + var GL={counter:1,buffers:[],mappedBuffers:{},programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},timerQueriesEXT:[],queries:[],samplers:[],transformFeedbacks:[],syncs:[],byteSizeByTypeRoot:5120,byteSizeByType:[1,1,2,2,4,4,4,2,3,4,8],programInfos:{},stringCache:{},stringiCache:{},unpackAlignment:4,recordError:function recordError(errorCode) { if (!GL.lastError) { GL.lastError = errorCode; } @@ -2306,35 +2297,64 @@ var ASM_CONSTS = { __webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx); __webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx); - // On WebGL 2, EXT_disjoint_timer_query is replaced with an alternative - // that's based on core APIs, and exposes only the queryCounterEXT() - // entrypoint. - if (context.version >= 2) { - GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query_webgl2"); - } - - // However, Firefox exposes the WebGL 1 version on WebGL 2 as well and - // thus we look for the WebGL 1 version again if the WebGL 2 version - // isn't present. https://bugzilla.mozilla.org/show_bug.cgi?id=1328882 - if (context.version < 2 || !GLctx.disjointTimerQueryExt) - { - GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); - } - + GLctx.disjointTimerQueryExt = GLctx.getExtension("EXT_disjoint_timer_query"); __webgl_enable_WEBGL_multi_draw(GLctx); // .getSupportedExtensions() can return null if context is lost, so coerce to empty array. var exts = GLctx.getSupportedExtensions() || []; exts.forEach(function(ext) { // WEBGL_lose_context, WEBGL_debug_renderer_info and WEBGL_debug_shaders are not enabled by default. - if (!ext.includes('lose_context') && !ext.includes('debug')) { + if (ext.indexOf('lose_context') < 0 && ext.indexOf('debug') < 0) { // Call .getExtension() to enable that extension permanently. GLctx.getExtension(ext); } }); + },populateUniformTable:function(program) { + var p = GL.programs[program]; + var ptable = GL.programInfos[program] = { + uniforms: {}, + maxUniformLength: 0, // This is eagerly computed below, since we already enumerate all uniforms anyway. + maxAttributeLength: -1, // This is lazily computed and cached, computed when/if first asked, "-1" meaning not computed yet. + maxUniformBlockNameLength: -1 // Lazily computed as well + }; + + var utable = ptable.uniforms; + // A program's uniform table maps the string name of an uniform to an integer location of that uniform. + // The global GL.uniforms map maps integer locations to WebGLUniformLocations. + var numUniforms = GLctx.getProgramParameter(p, 0x8B86/*GL_ACTIVE_UNIFORMS*/); + for (var i = 0; i < numUniforms; ++i) { + var u = GLctx.getActiveUniform(p, i); + + var name = u.name; + ptable.maxUniformLength = Math.max(ptable.maxUniformLength, name.length+1); + + // If we are dealing with an array, e.g. vec4 foo[3], strip off the array index part to canonicalize that "foo", "foo[]", + // and "foo[0]" will mean the same. Loop below will populate foo[1] and foo[2]. + if (name.slice(-1) == ']') { + name = name.slice(0, name.lastIndexOf('[')); + } + + // Optimize memory usage slightly: If we have an array of uniforms, e.g. 'vec3 colors[3];', then + // only store the string 'colors' in utable, and 'colors[0]', 'colors[1]' and 'colors[2]' will be parsed as 'colors'+i. + // Note that for the GL.uniforms table, we still need to fetch the all WebGLUniformLocations for all the indices. + var loc = GLctx.getUniformLocation(p, name); + if (loc) { + var id = GL.getNewId(GL.uniforms); + utable[name] = [u.size, id]; + GL.uniforms[id] = loc; + + for (var j = 1; j < u.size; ++j) { + var n = name + '['+j+']'; + loc = GLctx.getUniformLocation(p, n); + id = GL.getNewId(GL.uniforms); + + GL.uniforms[id] = loc; + } + } + } }}; - var __emscripten_webgl_power_preferences = ['default', 'low-power', 'high-performance']; + var __emscripten_webgl_power_preferences=['default', 'low-power', 'high-performance']; function _emscripten_webgl_do_create_context(target, attributes) { assert(attributes); var a = attributes >> 2; @@ -2375,6 +2395,25 @@ var ASM_CONSTS = { return _emscripten_webgl_do_create_context(a0,a1); } + function _emscripten_webgl_do_get_current_context() { + return GL.currentContext ? GL.currentContext.handle : 0; + } + function _emscripten_webgl_get_current_context( + ) { + return _emscripten_webgl_do_get_current_context(); + } + Module["_emscripten_webgl_get_current_context"] = _emscripten_webgl_get_current_context; + + function _emscripten_webgl_make_context_current(contextHandle) { + var success = GL.makeContextCurrent(contextHandle); + return success ? 0 : -5; + } + Module["_emscripten_webgl_make_context_current"] = _emscripten_webgl_make_context_current; + function _emscripten_webgl_destroy_context(contextHandle) { + if (GL.currentContext == contextHandle) GL.currentContext = 0; + GL.deleteContext(contextHandle); + } + function _emscripten_webgl_init_context_attributes(attributes) { assert(attributes); var a = attributes >> 2; @@ -2391,10 +2430,6 @@ var ASM_CONSTS = { } - function _emscripten_webgl_make_context_current(contextHandle) { - var success = GL.makeContextCurrent(contextHandle); - return success ? 0 : -5; - } function flush_NO_FILESYSTEM() { // flush anything remaining in the buffers during shutdown @@ -2404,7 +2439,7 @@ var ASM_CONSTS = { if (buffers[2].length) SYSCALLS.printChar(2, 10); } - var SYSCALLS = {mappings:{},buffers:[null,[],[]],printChar:function(stream, curr) { + var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream, curr) { var buffer = SYSCALLS.buffers[stream]; assert(buffer); if (curr === 0 || curr === 10) { @@ -2442,7 +2477,8 @@ var ASM_CONSTS = { } function _glAttachShader(program, shader) { - GLctx.attachShader(GL.programs[program], GL.shaders[shader]); + GLctx.attachShader(GL.programs[program], + GL.shaders[shader]); } function _glBindBuffer(target, buffer) { @@ -2510,11 +2546,7 @@ var ASM_CONSTS = { function _glCreateProgram() { var id = GL.getNewId(GL.programs); var program = GLctx.createProgram(); - // Store additional information needed for each shader program: program.name = id; - // Lazy cache results of glGetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH/GL_ACTIVE_ATTRIBUTE_MAX_LENGTH/GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) - program.maxUniformLength = program.maxAttributeLength = program.maxUniformBlockNameLength = 0; - program.uniformIdCounter = 1; GL.programs[id] = program; return id; } @@ -2522,7 +2554,6 @@ var ASM_CONSTS = { function _glCreateShader(shaderType) { var id = GL.getNewId(GL.shaders); GL.shaders[id] = GLctx.createShader(shaderType); - return id; } @@ -2556,6 +2587,7 @@ var ASM_CONSTS = { GLctx.deleteProgram(program); program.name = 0; GL.programs[id] = null; + GL.programInfos[id] = null; } function _glDeleteShader(id) { @@ -2648,35 +2680,42 @@ var ASM_CONSTS = { return; } - program = GL.programs[program]; + var ptable = GL.programInfos[program]; + if (!ptable) { + GL.recordError(0x502 /* GL_INVALID_OPERATION */); + return; + } if (pname == 0x8B84) { // GL_INFO_LOG_LENGTH - var log = GLctx.getProgramInfoLog(program); + var log = GLctx.getProgramInfoLog(GL.programs[program]); if (log === null) log = '(unknown error)'; HEAP32[((p)>>2)] = log.length + 1; } else if (pname == 0x8B87 /* GL_ACTIVE_UNIFORM_MAX_LENGTH */) { - if (!program.maxUniformLength) { - for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) { - program.maxUniformLength = Math.max(program.maxUniformLength, GLctx.getActiveUniform(program, i).name.length+1); - } - } - HEAP32[((p)>>2)] = program.maxUniformLength; + HEAP32[((p)>>2)] = ptable.maxUniformLength; } else if (pname == 0x8B8A /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */) { - if (!program.maxAttributeLength) { - for (var i = 0; i < GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/); ++i) { - program.maxAttributeLength = Math.max(program.maxAttributeLength, GLctx.getActiveAttrib(program, i).name.length+1); + if (ptable.maxAttributeLength == -1) { + program = GL.programs[program]; + var numAttribs = GLctx.getProgramParameter(program, 0x8B89/*GL_ACTIVE_ATTRIBUTES*/); + ptable.maxAttributeLength = 0; // Spec says if there are no active attribs, 0 must be returned. + for (var i = 0; i < numAttribs; ++i) { + var activeAttrib = GLctx.getActiveAttrib(program, i); + ptable.maxAttributeLength = Math.max(ptable.maxAttributeLength, activeAttrib.name.length+1); } } - HEAP32[((p)>>2)] = program.maxAttributeLength; + HEAP32[((p)>>2)] = ptable.maxAttributeLength; } else if (pname == 0x8A35 /* GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */) { - if (!program.maxUniformBlockNameLength) { - for (var i = 0; i < GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/); ++i) { - program.maxUniformBlockNameLength = Math.max(program.maxUniformBlockNameLength, GLctx.getActiveUniformBlockName(program, i).length+1); + if (ptable.maxUniformBlockNameLength == -1) { + program = GL.programs[program]; + var numBlocks = GLctx.getProgramParameter(program, 0x8A36/*GL_ACTIVE_UNIFORM_BLOCKS*/); + ptable.maxUniformBlockNameLength = 0; + for (var i = 0; i < numBlocks; ++i) { + var activeBlockName = GLctx.getActiveUniformBlockName(program, i); + ptable.maxUniformBlockNameLength = Math.max(ptable.maxUniformBlockNameLength, activeBlockName.length+1); } } - HEAP32[((p)>>2)] = program.maxUniformBlockNameLength; + HEAP32[((p)>>2)] = ptable.maxUniformBlockNameLength; } else { - HEAP32[((p)>>2)] = GLctx.getProgramParameter(program, pname); + HEAP32[((p)>>2)] = GLctx.getProgramParameter(GL.programs[program], pname); } } @@ -2718,100 +2757,28 @@ var ASM_CONSTS = { function jstoi_q(str) { return parseInt(str); } - - /** @noinline */ - function webglGetLeftBracePos(name) { - return name.slice(-1) == ']' && name.lastIndexOf('['); - } - function webglPrepareUniformLocationsBeforeFirstUse(program) { - var uniformLocsById = program.uniformLocsById, // Maps GLuint -> WebGLUniformLocation - uniformSizeAndIdsByName = program.uniformSizeAndIdsByName, // Maps name -> [uniform array length, GLuint] - i, j; - - // On the first time invocation of glGetUniformLocation on this shader program: - // initialize cache data structures and discover which uniforms are arrays. - if (!uniformLocsById) { - // maps GLint integer locations to WebGLUniformLocations - program.uniformLocsById = uniformLocsById = {}; - // maps integer locations back to uniform name strings, so that we can lazily fetch uniform array locations - program.uniformArrayNamesById = {}; - - for (i = 0; i < GLctx.getProgramParameter(program, 0x8B86/*GL_ACTIVE_UNIFORMS*/); ++i) { - var u = GLctx.getActiveUniform(program, i); - var nm = u.name; - var sz = u.size; - var lb = webglGetLeftBracePos(nm); - var arrayName = lb > 0 ? nm.slice(0, lb) : nm; - - // Assign a new location. - var id = program.uniformIdCounter; - program.uniformIdCounter += sz; - // Eagerly get the location of the uniformArray[0] base element. - // The remaining indices >0 will be left for lazy evaluation to - // improve performance. Those may never be needed to fetch, if the - // application fills arrays always in full starting from the first - // element of the array. - uniformSizeAndIdsByName[arrayName] = [sz, id]; - - // Store placeholder integers in place that highlight that these - // >0 index locations are array indices pending population. - for(j = 0; j < sz; ++j) { - uniformLocsById[id] = j; - program.uniformArrayNamesById[id++] = arrayName; - } - } - } - } function _glGetUniformLocation(program, name) { - name = UTF8ToString(name); - if (program = GL.programs[program]) { - webglPrepareUniformLocationsBeforeFirstUse(program); - var uniformLocsById = program.uniformLocsById; // Maps GLuint -> WebGLUniformLocation - var arrayIndex = 0; - var uniformBaseName = name; - - // Invariant: when populating integer IDs for uniform locations, we must maintain the precondition that - // arrays reside in contiguous addresses, i.e. for a 'vec4 colors[10];', colors[4] must be at location colors[0]+4. - // However, user might call glGetUniformLocation(program, "colors") for an array, so we cannot discover based on the user - // input arguments whether the uniform we are dealing with is an array. The only way to discover which uniforms are arrays - // is to enumerate over all the active uniforms in the program. - var leftBrace = webglGetLeftBracePos(name); - - // If user passed an array accessor "[index]", parse the array index off the accessor. - if (leftBrace > 0) { - arrayIndex = jstoi_q(name.slice(leftBrace + 1)) >>> 0; // "index]", coerce parseInt(']') with >>>0 to treat "foo[]" as "foo[0]" and foo[-1] as unsigned out-of-bounds. - uniformBaseName = name.slice(0, leftBrace); - } - - // Have we cached the location of this uniform before? - var sizeAndId = program.uniformSizeAndIdsByName[uniformBaseName]; // A pair [array length, GLint of the uniform location] - - // If an uniform with this name exists, and if its index is within the array limits (if it's even an array), - // query the WebGLlocation, or return an existing cached location. - if (sizeAndId && arrayIndex < sizeAndId[0]) { - arrayIndex += sizeAndId[1]; // Add the base location of the uniform to the array index offset. - if ((uniformLocsById[arrayIndex] = uniformLocsById[arrayIndex] || GLctx.getUniformLocation(program, name))) { - return arrayIndex; - } - } + var arrayIndex = 0; + // If user passed an array accessor "[index]", parse the array index off the accessor. + if (name[name.length - 1] == ']') { + var leftBrace = name.lastIndexOf('['); + arrayIndex = name[leftBrace+1] != ']' ? jstoi_q(name.slice(leftBrace + 1)) : 0; // "index]", parseInt will ignore the ']' at the end; but treat "foo[]" as "foo[0]" + name = name.slice(0, leftBrace); } - else { - // N.b. we are currently unable to distinguish between GL program IDs that never existed vs GL program IDs that have been deleted, - // so report GL_INVALID_VALUE in both cases. - GL.recordError(0x501 /* GL_INVALID_VALUE */); + + var uniformInfo = GL.programInfos[program] && GL.programInfos[program].uniforms[name]; // returns pair [ dimension_of_uniform_array, uniform_location ] + if (uniformInfo && arrayIndex >= 0 && arrayIndex < uniformInfo[0]) { // Check if user asked for an out-of-bounds element, i.e. for 'vec4 colors[3];' user could ask for 'colors[10]' which should return -1. + return uniformInfo[1] + arrayIndex; + } else { + return -1; } - return -1; } function _glLinkProgram(program) { - program = GL.programs[program]; - GLctx.linkProgram(program); - // Invalidate earlier computed uniform->ID mappings, those have now become stale - program.uniformLocsById = 0; // Mark as null-like so that glGetUniformLocation() knows to populate this again. - program.uniformSizeAndIdsByName = {}; - + GLctx.linkProgram(GL.programs[program]); + GL.populateUniformTable(program); } function _glShaderSource(shader, count, string, length) { @@ -2820,30 +2787,11 @@ var ASM_CONSTS = { GLctx.shaderSource(GL.shaders[shader], source); } - function webglGetUniformLocation(location) { - var p = GLctx.currentProgram; - - if (p) { - var webglLoc = p.uniformLocsById[location]; - // p.uniformLocsById[location] stores either an integer, or a WebGLUniformLocation. - - // If an integer, we have not yet bound the location, so do it now. The integer value specifies the array index - // we should bind to. - if (typeof webglLoc === 'number') { - p.uniformLocsById[location] = webglLoc = GLctx.getUniformLocation(p, p.uniformArrayNamesById[location] + (webglLoc > 0 ? '[' + webglLoc + ']' : '')); - } - // Else an already cached WebGLUniformLocation, return it. - return webglLoc; - } else { - GL.recordError(0x502/*GL_INVALID_OPERATION*/); - } - } - - var miniTempWebGLFloatBuffers = []; + var miniTempWebGLFloatBuffers=[]; function _glUniformMatrix4fv(location, count, transpose, value) { if (GL.currentContext.version >= 2) { // WebGL 2 provides new garbage-free entry points to call to WebGL. Use those always when possible. - GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, HEAPF32, value>>2, count*16); + GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, HEAPF32, value>>2, count*16); return; } @@ -2876,15 +2824,11 @@ var ASM_CONSTS = { { var view = HEAPF32.subarray((value)>>2, (value+count*64)>>2); } - GLctx.uniformMatrix4fv(webglGetUniformLocation(location), !!transpose, view); + GLctx.uniformMatrix4fv(GL.uniforms[location], !!transpose, view); } function _glUseProgram(program) { - program = GL.programs[program]; - GLctx.useProgram(program); - // Record the currently active program so that we can access the uniform - // mapping table of that program. - GLctx.currentProgram = program; + GLctx.useProgram(GL.programs[program]); } function _glVertexAttribPointer(index, size, type, normalized, stride, ptr) { @@ -2905,8 +2849,8 @@ var ASM_CONSTS = { GLctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); } - function _setTempRet0(val) { - setTempRet0(val); + function _setTempRet0($i) { + setTempRet0(($i) | 0); } var GLctx;; var miniTempWebGLFloatBuffersStorage = new Float32Array(288); @@ -2951,6 +2895,7 @@ var asmLibraryArg = { "emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size, "emscripten_set_click_callback_on_thread": _emscripten_set_click_callback_on_thread, "emscripten_webgl_create_context": _emscripten_webgl_create_context, + "emscripten_webgl_destroy_context": _emscripten_webgl_destroy_context, "emscripten_webgl_init_context_attributes": _emscripten_webgl_init_context_attributes, "emscripten_webgl_make_context_current": _emscripten_webgl_make_context_current, "fd_write": _fd_write, @@ -3041,237 +2986,230 @@ var dynCall_jiji = Module["dynCall_jiji"] = createExportWrapper("dynCall_jiji"); // === Auto-generated postamble setup entry stuff === -if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ccall")) Module["ccall"] = function() { abort("'ccall' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "cwrap")) Module["cwrap"] = function() { abort("'cwrap' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "keepRuntimeAlive")) Module["keepRuntimeAlive"] = function() { abort("'keepRuntimeAlive' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "zeroMemory")) Module["zeroMemory"] = function() { abort("'zeroMemory' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setFileTime")) Module["setFileTime"] = function() { abort("'setFileTime' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetPton4")) Module["inetPton4"] = function() { abort("'inetPton4' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetNtop4")) Module["inetNtop4"] = function() { abort("'inetNtop4' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetPton6")) Module["inetPton6"] = function() { abort("'inetPton6' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetNtop6")) Module["inetNtop6"] = function() { abort("'inetNtop6' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readSockaddr")) Module["readSockaddr"] = function() { abort("'readSockaddr' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeSockaddr")) Module["writeSockaddr"] = function() { abort("'writeSockaddr' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getHostByName")) Module["getHostByName"] = function() { abort("'getHostByName' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getRandomDevice")) Module["getRandomDevice"] = function() { abort("'getRandomDevice' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "traverseStack")) Module["traverseStack"] = function() { abort("'traverseStack' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "withBuiltinMalloc")) Module["withBuiltinMalloc"] = function() { abort("'withBuiltinMalloc' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgsArray")) Module["readAsmConstArgsArray"] = function() { abort("'readAsmConstArgsArray' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "mainThreadEM_ASM")) Module["mainThreadEM_ASM"] = function() { abort("'mainThreadEM_ASM' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getExecutableName")) Module["getExecutableName"] = function() { abort("'getExecutableName' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "listenOnce")) Module["listenOnce"] = function() { abort("'listenOnce' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "autoResumeAudioContext")) Module["autoResumeAudioContext"] = function() { abort("'autoResumeAudioContext' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCallLegacy")) Module["dynCallLegacy"] = function() { abort("'dynCallLegacy' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getDynCaller")) Module["getDynCaller"] = function() { abort("'getDynCaller' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "callRuntimeCallbacks")) Module["callRuntimeCallbacks"] = function() { abort("'callRuntimeCallbacks' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "handleException")) Module["handleException"] = function() { abort("'handleException' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runtimeKeepalivePush")) Module["runtimeKeepalivePush"] = function() { abort("'runtimeKeepalivePush' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runtimeKeepalivePop")) Module["runtimeKeepalivePop"] = function() { abort("'runtimeKeepalivePop' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "callUserCallback")) Module["callUserCallback"] = function() { abort("'callUserCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "maybeExit")) Module["maybeExit"] = function() { abort("'maybeExit' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "safeSetTimeout")) Module["safeSetTimeout"] = function() { abort("'safeSetTimeout' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "asmjsMangle")) Module["asmjsMangle"] = function() { abort("'asmjsMangle' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "asyncLoad")) Module["asyncLoad"] = function() { abort("'asyncLoad' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "alignMemory")) Module["alignMemory"] = function() { abort("'alignMemory' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "mmapAlloc")) Module["mmapAlloc"] = function() { abort("'mmapAlloc' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "unSign")) Module["unSign"] = function() { abort("'unSign' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "reSign")) Module["reSign"] = function() { abort("'reSign' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getSocketFromFD")) Module["getSocketFromFD"] = function() { abort("'getSocketFromFD' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getSocketAddress")) Module["getSocketAddress"] = function() { abort("'getSocketAddress' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerKeyEventCallback")) Module["registerKeyEventCallback"] = function() { abort("'registerKeyEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "maybeCStringToJsString")) Module["maybeCStringToJsString"] = function() { abort("'maybeCStringToJsString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "findEventTarget")) Module["findEventTarget"] = function() { abort("'findEventTarget' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "findCanvasEventTarget")) Module["findCanvasEventTarget"] = function() { abort("'findCanvasEventTarget' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getBoundingClientRect")) Module["getBoundingClientRect"] = function() { abort("'getBoundingClientRect' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillMouseEventData")) Module["fillMouseEventData"] = function() { abort("'fillMouseEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerMouseEventCallback")) Module["registerMouseEventCallback"] = function() { abort("'registerMouseEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerWheelEventCallback")) Module["registerWheelEventCallback"] = function() { abort("'registerWheelEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerUiEventCallback")) Module["registerUiEventCallback"] = function() { abort("'registerUiEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFocusEventCallback")) Module["registerFocusEventCallback"] = function() { abort("'registerFocusEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceOrientationEventData")) Module["fillDeviceOrientationEventData"] = function() { abort("'fillDeviceOrientationEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceOrientationEventCallback")) Module["registerDeviceOrientationEventCallback"] = function() { abort("'registerDeviceOrientationEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceMotionEventData")) Module["fillDeviceMotionEventData"] = function() { abort("'fillDeviceMotionEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceMotionEventCallback")) Module["registerDeviceMotionEventCallback"] = function() { abort("'registerDeviceMotionEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "screenOrientation")) Module["screenOrientation"] = function() { abort("'screenOrientation' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillOrientationChangeEventData")) Module["fillOrientationChangeEventData"] = function() { abort("'fillOrientationChangeEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerOrientationChangeEventCallback")) Module["registerOrientationChangeEventCallback"] = function() { abort("'registerOrientationChangeEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillFullscreenChangeEventData")) Module["fillFullscreenChangeEventData"] = function() { abort("'fillFullscreenChangeEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFullscreenChangeEventCallback")) Module["registerFullscreenChangeEventCallback"] = function() { abort("'registerFullscreenChangeEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerRestoreOldStyle")) Module["registerRestoreOldStyle"] = function() { abort("'registerRestoreOldStyle' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "hideEverythingExceptGivenElement")) Module["hideEverythingExceptGivenElement"] = function() { abort("'hideEverythingExceptGivenElement' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "restoreHiddenElements")) Module["restoreHiddenElements"] = function() { abort("'restoreHiddenElements' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setLetterbox")) Module["setLetterbox"] = function() { abort("'setLetterbox' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "currentFullscreenStrategy")) Module["currentFullscreenStrategy"] = function() { abort("'currentFullscreenStrategy' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "restoreOldWindowedStyle")) Module["restoreOldWindowedStyle"] = function() { abort("'restoreOldWindowedStyle' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "softFullscreenResizeWebGLRenderTarget")) Module["softFullscreenResizeWebGLRenderTarget"] = function() { abort("'softFullscreenResizeWebGLRenderTarget' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "doRequestFullscreen")) Module["doRequestFullscreen"] = function() { abort("'doRequestFullscreen' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillPointerlockChangeEventData")) Module["fillPointerlockChangeEventData"] = function() { abort("'fillPointerlockChangeEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockChangeEventCallback")) Module["registerPointerlockChangeEventCallback"] = function() { abort("'registerPointerlockChangeEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockErrorEventCallback")) Module["registerPointerlockErrorEventCallback"] = function() { abort("'registerPointerlockErrorEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "requestPointerLock")) Module["requestPointerLock"] = function() { abort("'requestPointerLock' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillVisibilityChangeEventData")) Module["fillVisibilityChangeEventData"] = function() { abort("'fillVisibilityChangeEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerVisibilityChangeEventCallback")) Module["registerVisibilityChangeEventCallback"] = function() { abort("'registerVisibilityChangeEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerTouchEventCallback")) Module["registerTouchEventCallback"] = function() { abort("'registerTouchEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillGamepadEventData")) Module["fillGamepadEventData"] = function() { abort("'fillGamepadEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerGamepadEventCallback")) Module["registerGamepadEventCallback"] = function() { abort("'registerGamepadEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerBeforeUnloadEventCallback")) Module["registerBeforeUnloadEventCallback"] = function() { abort("'registerBeforeUnloadEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillBatteryEventData")) Module["fillBatteryEventData"] = function() { abort("'fillBatteryEventData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "battery")) Module["battery"] = function() { abort("'battery' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerBatteryEventCallback")) Module["registerBatteryEventCallback"] = function() { abort("'registerBatteryEventCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setCanvasElementSize")) Module["setCanvasElementSize"] = function() { abort("'setCanvasElementSize' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getCanvasElementSize")) Module["getCanvasElementSize"] = function() { abort("'getCanvasElementSize' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "polyfillSetImmediate")) Module["polyfillSetImmediate"] = function() { abort("'polyfillSetImmediate' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "flush_NO_FILESYSTEM")) Module["flush_NO_FILESYSTEM"] = function() { abort("'flush_NO_FILESYSTEM' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "uncaughtExceptionCount")) Module["uncaughtExceptionCount"] = function() { abort("'uncaughtExceptionCount' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exceptionLast")) Module["exceptionLast"] = function() { abort("'exceptionLast' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exceptionCaught")) Module["exceptionCaught"] = function() { abort("'exceptionCaught' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfo")) Module["ExceptionInfo"] = function() { abort("'ExceptionInfo' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "CatchInfo")) Module["CatchInfo"] = function() { abort("'CatchInfo' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exception_addRef")) Module["exception_addRef"] = function() { abort("'exception_addRef' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exception_decRef")) Module["exception_decRef"] = function() { abort("'exception_decRef' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "funcWrappers")) Module["funcWrappers"] = function() { abort("'funcWrappers' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setMainLoop")) Module["setMainLoop"] = function() { abort("'setMainLoop' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "wget")) Module["wget"] = function() { abort("'wget' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "_setNetworkCallback")) Module["_setNetworkCallback"] = function() { abort("'_setNetworkCallback' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "tempFixedLengthArray")) Module["tempFixedLengthArray"] = function() { abort("'tempFixedLengthArray' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "miniTempWebGLFloatBuffers")) Module["miniTempWebGLFloatBuffers"] = function() { abort("'miniTempWebGLFloatBuffers' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "heapObjectForWebGLType")) Module["heapObjectForWebGLType"] = function() { abort("'heapObjectForWebGLType' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "heapAccessShiftForWebGLHeap")) Module["heapAccessShiftForWebGLHeap"] = function() { abort("'heapAccessShiftForWebGLHeap' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "computeUnpackAlignedImageSize")) Module["computeUnpackAlignedImageSize"] = function() { abort("'computeUnpackAlignedImageSize' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "webglGetUniformLocation")) Module["webglGetUniformLocation"] = function() { abort("'webglGetUniformLocation' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "webglPrepareUniformLocationsBeforeFirstUse")) Module["webglPrepareUniformLocationsBeforeFirstUse"] = function() { abort("'webglPrepareUniformLocationsBeforeFirstUse' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "webglGetLeftBracePos")) Module["webglGetLeftBracePos"] = function() { abort("'webglGetLeftBracePos' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetBufferBinding")) Module["emscriptenWebGLGetBufferBinding"] = function() { abort("'emscriptenWebGLGetBufferBinding' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLValidateMapBufferTarget")) Module["emscriptenWebGLValidateMapBufferTarget"] = function() { abort("'emscriptenWebGLValidateMapBufferTarget' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeGLArray")) Module["writeGLArray"] = function() { abort("'writeGLArray' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetIndexed")) Module["emscriptenWebGLGetIndexed"] = function() { abort("'emscriptenWebGLGetIndexed' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +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)") }; +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)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setFileTime")) Module["setFileTime"] = function() { abort("'setFileTime' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetPton4")) Module["inetPton4"] = function() { abort("'inetPton4' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetNtop4")) Module["inetNtop4"] = function() { abort("'inetNtop4' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetPton6")) Module["inetPton6"] = function() { abort("'inetPton6' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetNtop6")) Module["inetNtop6"] = function() { abort("'inetNtop6' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readSockaddr")) Module["readSockaddr"] = function() { abort("'readSockaddr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeSockaddr")) Module["writeSockaddr"] = function() { abort("'writeSockaddr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getHostByName")) Module["getHostByName"] = function() { abort("'getHostByName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getRandomDevice")) Module["getRandomDevice"] = function() { abort("'getRandomDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "traverseStack")) Module["traverseStack"] = function() { abort("'traverseStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "withBuiltinMalloc")) Module["withBuiltinMalloc"] = function() { abort("'withBuiltinMalloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgsArray")) Module["readAsmConstArgsArray"] = function() { abort("'readAsmConstArgsArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "mainThreadEM_ASM")) Module["mainThreadEM_ASM"] = function() { abort("'mainThreadEM_ASM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getExecutableName")) Module["getExecutableName"] = function() { abort("'getExecutableName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "listenOnce")) Module["listenOnce"] = function() { abort("'listenOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "autoResumeAudioContext")) Module["autoResumeAudioContext"] = function() { abort("'autoResumeAudioContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCallLegacy")) Module["dynCallLegacy"] = function() { abort("'dynCallLegacy' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getDynCaller")) Module["getDynCaller"] = function() { abort("'getDynCaller' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "callRuntimeCallbacks")) Module["callRuntimeCallbacks"] = function() { abort("'callRuntimeCallbacks' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runtimeKeepaliveCounter")) Module["runtimeKeepaliveCounter"] = function() { abort("'runtimeKeepaliveCounter' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "keepRuntimeAlive")) Module["keepRuntimeAlive"] = function() { abort("'keepRuntimeAlive' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runtimeKeepalivePush")) Module["runtimeKeepalivePush"] = function() { abort("'runtimeKeepalivePush' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runtimeKeepalivePop")) Module["runtimeKeepalivePop"] = function() { abort("'runtimeKeepalivePop' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "callUserCallback")) Module["callUserCallback"] = function() { abort("'callUserCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "maybeExit")) Module["maybeExit"] = function() { abort("'maybeExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "unSign")) Module["unSign"] = function() { abort("'unSign' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "reSign")) Module["reSign"] = function() { abort("'reSign' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getSocketFromFD")) Module["getSocketFromFD"] = function() { abort("'getSocketFromFD' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getSocketAddress")) Module["getSocketAddress"] = function() { abort("'getSocketAddress' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerKeyEventCallback")) Module["registerKeyEventCallback"] = function() { abort("'registerKeyEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "maybeCStringToJsString")) Module["maybeCStringToJsString"] = function() { abort("'maybeCStringToJsString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "findEventTarget")) Module["findEventTarget"] = function() { abort("'findEventTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "findCanvasEventTarget")) Module["findCanvasEventTarget"] = function() { abort("'findCanvasEventTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getBoundingClientRect")) Module["getBoundingClientRect"] = function() { abort("'getBoundingClientRect' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillMouseEventData")) Module["fillMouseEventData"] = function() { abort("'fillMouseEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerMouseEventCallback")) Module["registerMouseEventCallback"] = function() { abort("'registerMouseEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerWheelEventCallback")) Module["registerWheelEventCallback"] = function() { abort("'registerWheelEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerUiEventCallback")) Module["registerUiEventCallback"] = function() { abort("'registerUiEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFocusEventCallback")) Module["registerFocusEventCallback"] = function() { abort("'registerFocusEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceOrientationEventData")) Module["fillDeviceOrientationEventData"] = function() { abort("'fillDeviceOrientationEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceOrientationEventCallback")) Module["registerDeviceOrientationEventCallback"] = function() { abort("'registerDeviceOrientationEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceMotionEventData")) Module["fillDeviceMotionEventData"] = function() { abort("'fillDeviceMotionEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceMotionEventCallback")) Module["registerDeviceMotionEventCallback"] = function() { abort("'registerDeviceMotionEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "screenOrientation")) Module["screenOrientation"] = function() { abort("'screenOrientation' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillOrientationChangeEventData")) Module["fillOrientationChangeEventData"] = function() { abort("'fillOrientationChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerOrientationChangeEventCallback")) Module["registerOrientationChangeEventCallback"] = function() { abort("'registerOrientationChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillFullscreenChangeEventData")) Module["fillFullscreenChangeEventData"] = function() { abort("'fillFullscreenChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFullscreenChangeEventCallback")) Module["registerFullscreenChangeEventCallback"] = function() { abort("'registerFullscreenChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerRestoreOldStyle")) Module["registerRestoreOldStyle"] = function() { abort("'registerRestoreOldStyle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "hideEverythingExceptGivenElement")) Module["hideEverythingExceptGivenElement"] = function() { abort("'hideEverythingExceptGivenElement' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "restoreHiddenElements")) Module["restoreHiddenElements"] = function() { abort("'restoreHiddenElements' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setLetterbox")) Module["setLetterbox"] = function() { abort("'setLetterbox' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "currentFullscreenStrategy")) Module["currentFullscreenStrategy"] = function() { abort("'currentFullscreenStrategy' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "restoreOldWindowedStyle")) Module["restoreOldWindowedStyle"] = function() { abort("'restoreOldWindowedStyle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "softFullscreenResizeWebGLRenderTarget")) Module["softFullscreenResizeWebGLRenderTarget"] = function() { abort("'softFullscreenResizeWebGLRenderTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "doRequestFullscreen")) Module["doRequestFullscreen"] = function() { abort("'doRequestFullscreen' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillPointerlockChangeEventData")) Module["fillPointerlockChangeEventData"] = function() { abort("'fillPointerlockChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockChangeEventCallback")) Module["registerPointerlockChangeEventCallback"] = function() { abort("'registerPointerlockChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockErrorEventCallback")) Module["registerPointerlockErrorEventCallback"] = function() { abort("'registerPointerlockErrorEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "requestPointerLock")) Module["requestPointerLock"] = function() { abort("'requestPointerLock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillVisibilityChangeEventData")) Module["fillVisibilityChangeEventData"] = function() { abort("'fillVisibilityChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerVisibilityChangeEventCallback")) Module["registerVisibilityChangeEventCallback"] = function() { abort("'registerVisibilityChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerTouchEventCallback")) Module["registerTouchEventCallback"] = function() { abort("'registerTouchEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillGamepadEventData")) Module["fillGamepadEventData"] = function() { abort("'fillGamepadEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerGamepadEventCallback")) Module["registerGamepadEventCallback"] = function() { abort("'registerGamepadEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerBeforeUnloadEventCallback")) Module["registerBeforeUnloadEventCallback"] = function() { abort("'registerBeforeUnloadEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillBatteryEventData")) Module["fillBatteryEventData"] = function() { abort("'fillBatteryEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "battery")) Module["battery"] = function() { abort("'battery' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerBatteryEventCallback")) Module["registerBatteryEventCallback"] = function() { abort("'registerBatteryEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setCanvasElementSize")) Module["setCanvasElementSize"] = function() { abort("'setCanvasElementSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getCanvasElementSize")) Module["getCanvasElementSize"] = function() { abort("'getCanvasElementSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "polyfillSetImmediate")) Module["polyfillSetImmediate"] = function() { abort("'polyfillSetImmediate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "flush_NO_FILESYSTEM")) Module["flush_NO_FILESYSTEM"] = function() { abort("'flush_NO_FILESYSTEM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "uncaughtExceptionCount")) Module["uncaughtExceptionCount"] = function() { abort("'uncaughtExceptionCount' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exceptionLast")) Module["exceptionLast"] = function() { abort("'exceptionLast' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exceptionCaught")) Module["exceptionCaught"] = function() { abort("'exceptionCaught' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfoAttrs")) Module["ExceptionInfoAttrs"] = function() { abort("'ExceptionInfoAttrs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfo")) Module["ExceptionInfo"] = function() { abort("'ExceptionInfo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "CatchInfo")) Module["CatchInfo"] = function() { abort("'CatchInfo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exception_addRef")) Module["exception_addRef"] = function() { abort("'exception_addRef' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exception_decRef")) Module["exception_decRef"] = function() { abort("'exception_decRef' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "funcWrappers")) Module["funcWrappers"] = function() { abort("'funcWrappers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setMainLoop")) Module["setMainLoop"] = function() { abort("'setMainLoop' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "mmapAlloc")) Module["mmapAlloc"] = function() { abort("'mmapAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "_setNetworkCallback")) Module["_setNetworkCallback"] = function() { abort("'_setNetworkCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "tempFixedLengthArray")) Module["tempFixedLengthArray"] = function() { abort("'tempFixedLengthArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "miniTempWebGLFloatBuffers")) Module["miniTempWebGLFloatBuffers"] = function() { abort("'miniTempWebGLFloatBuffers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "heapObjectForWebGLType")) Module["heapObjectForWebGLType"] = function() { abort("'heapObjectForWebGLType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "heapAccessShiftForWebGLHeap")) Module["heapAccessShiftForWebGLHeap"] = function() { abort("'heapAccessShiftForWebGLHeap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "computeUnpackAlignedImageSize")) Module["computeUnpackAlignedImageSize"] = function() { abort("'computeUnpackAlignedImageSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetBufferBinding")) Module["emscriptenWebGLGetBufferBinding"] = function() { abort("'emscriptenWebGLGetBufferBinding' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLValidateMapBufferTarget")) Module["emscriptenWebGLValidateMapBufferTarget"] = function() { abort("'emscriptenWebGLValidateMapBufferTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeGLArray")) Module["writeGLArray"] = function() { abort("'writeGLArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetIndexed")) Module["emscriptenWebGLGetIndexed"] = function() { abort("'emscriptenWebGLGetIndexed' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; Module["writeStackCookie"] = writeStackCookie; Module["checkStackCookie"] = checkStackCookie; -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); var calledRun; @@ -3315,25 +3253,25 @@ function callMain(args) { // In PROXY_TO_PTHREAD builds, we should never exit the runtime below, as // execution is asynchronously handed off to a pthread. - // if we're not running an evented main loop, it's time to exit - exit(ret, /* implicit = */ true); - } - catch (e) { - // Certain exception types we do not treat as errors since they are used for - // internal control flow. - // 1. ExitStatus, which is thrown by exit() - // 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others - // that wish to return to JS event loop. - if (e instanceof ExitStatus || e == 'unwind') { + // if we're not running an evented main loop, it's time to exit + exit(ret, /* implicit = */ true); + } + catch(e) { + if (e instanceof ExitStatus) { + // exit() throws this once it's done to make sure execution + // has been stopped completely return; + } else if (e == 'unwind') { + // running an evented main loop, don't immediately exit + return; + } else { + var toLog = e; + if (e && typeof e === 'object' && e.stack) { + toLog = [e, e.stack]; + } + err('exception thrown: ' + toLog); + quit_(1, e); } - // Anything else is an unexpected exception and we treat it as hard error. - var toLog = e; - if (e && typeof e === 'object' && e.stack) { - toLog = [e, e.stack]; - } - err('exception thrown: ' + toLog); - quit_(1, e); } finally { calledMain = true; @@ -3438,6 +3376,14 @@ function exit(status, implicit) { checkUnflushedContent(); + // if this is just main exit-ing implicitly, and the status is 0, then we + // don't need to do anything here and can just leave. if the status is + // non-zero, though, then we need to report it. + // (we may have warned about this earlier, if a situation justifies doing so) + if (implicit && keepRuntimeAlive() && status === 0) { + return; + } + if (keepRuntimeAlive()) { // if exit() was called, we may warn the user if the runtime isn't actually being shut down if (!implicit) { @@ -3445,19 +3391,15 @@ function exit(status, implicit) { err(msg); } } else { + exitRuntime(); - } - procExit(status); -} + if (Module['onExit']) Module['onExit'](status); -function procExit(code) { - EXITSTATUS = code; - if (!keepRuntimeAlive()) { - if (Module['onExit']) Module['onExit'](code); ABORT = true; } - quit_(code, new ExitStatus(code)); + + quit_(status, new ExitStatus(status)); } if (Module['preInit']) { diff --git a/2d/softbody/softbody_1/dist/output.wasm b/2d/softbody/softbody_1/dist/output.wasm Binary files differindex a0646b3..9c47c47 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 0b04426..33a2c77 100644 --- a/2d/softbody/softbody_1/main.cpp +++ b/2d/softbody/softbody_1/main.cpp @@ -1,228 +1,17 @@ -#include "../../../shared_cpp/Renderer2d.h" -#include "../../../shared_cpp/types.h" +#include "undamped.h" +#include "damped.h" #include "../../../shared_cpp/WebglContext.h" -#include "../../../shared_cpp/mathlib.h" -#include "../../../shared_cpp/MainLoop.h" -#include <cstdio> -#include <cmath> -#include <emscripten/html5.h> -#include <unistd.h> -#include <pthread.h> -#include <cmath> -#include <cfloat> - -struct MassSpringVertex { - -}; - -struct MassSpringBody { - -}; - -struct SpringWeight { - Mesh2d shape; - float32 radius; - float32 mass = 2.f; - - void load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor); - void update(float32 dtSeconds); - void render(Renderer2d* renderer); - void unload(); -}; - -struct Spring { - SpringWeight* weight; - - Mesh2d shape; - - Vertex2d* vertices = NULL; - int32 numSegments = 0; - int32 numVertices = 0; - float32 k = 5; // Spring Constant, in N / m - float32 angularVelocity = 0.f; // To be calculated - float32 displacement = 0.f; - float32 timeElapsed = 0.f; - - void load(Renderer2d* renderer, SpringWeight* inWieight, float32 length, float32 loopRadius); - void update(float32 dtSeconds); - void render(Renderer2d* renderer); - void unload(); -}; - -EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); -EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); - -void load(); -void update(float32 time, void* userData); -void unload(); WebglContext context; -Renderer2d renderer; -MainLoop mainLoop; -SpringWeight weight; -Spring spring; int main() { - context.init("#gl_canvas"); - emscripten_set_click_callback("#gl_canvas_play", NULL, false, onPlayClicked); - emscripten_set_click_callback("#gl_canvas_stop", NULL, false, onStopClicked); + Damped::init(&context); + Undamped::init(&context); return 0; } -void load() { - 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, 100.f, 16.f); - - mainLoop.run(update); -} - -void update(float32 deltaTimeSeconds, void* userData) { - // -- Update - spring.update(deltaTimeSeconds); - weight.update(deltaTimeSeconds); - - // -- Render - renderer.render(); - weight.render(&renderer); - spring.render(&renderer); -} - -void unload() { - mainLoop.stop(); - renderer.unload(); - weight.unload(); - spring.unload(); -} // // Interactions with DOM handled below // -EM_BOOL onPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { - printf("Play clicked\n"); - - load(); - return true; -} - -EM_BOOL onStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { - printf("Stop clicked\n"); - unload(); - return true; -} - - -void SpringWeight::load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor) { - radius = inRadius; - const int32 numSegments = 96; - const float32 radiansPerSegment = (2.f * PI) / static_cast<float>(numSegments); - const int32 numVertices = numSegments * 3; - - float32 t = 0.f; - float32 tIncrement = 1.f / (numSegments / 2.f); - startColor = startColor.toNormalizedColor(); - endColor = endColor.toNormalizedColor(); - Vertex2d vertices[numVertices]; - for (int idx = 0; idx < numSegments; idx++) { - int vIdx = idx * 3; - - Vector4 color = lerp(startColor, endColor, t); - if (idx >= numSegments / 2) { - t -= tIncrement; - } else { - t += tIncrement; - } - - vertices[vIdx].color = color; - vertices[vIdx].position = Vector2 { radius * cosf(radiansPerSegment * idx), radius * sinf(radiansPerSegment * idx) }; - vertices[vIdx + 1].color = color; - vertices[vIdx + 1].position = Vector2 { 0.f, 0.f }; - vertices[vIdx + 2].color = color; - vertices[vIdx + 2].position = Vector2 { radius * cosf(radiansPerSegment * (idx + 1)), radius * sinf(radiansPerSegment * (idx + 1)) }; - } - - shape.load(vertices, numVertices, renderer); -} - -void SpringWeight::update(float32 dtSeconds) { - -} - -void SpringWeight::render(Renderer2d* renderer) { - shape.render(renderer); -} - -void SpringWeight::unload() { - shape.unload(); -} - -void Spring::load(Renderer2d* renderer, SpringWeight* inWeight, float32 length, float32 loopRadius) { - weight = inWeight; - angularVelocity = sqrtf(k / weight->mass); - timeElapsed = 0.f; - - const int32 verticesPerSegment = 6; - numSegments = 256; - numVertices = numSegments * verticesPerSegment; - vertices = new Vertex2d[numVertices]; - - float32 lengthIncrement = length / static_cast<float32>(numSegments); - - const float32 frequency = 0.25f; - const float32 loopWidth = 20.f; - const float32 offset = 0.25f; - - int32 vidx = 0; - 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); - - vertices[vidx++].position = Vector2(x1, y1); - vertices[vidx++].position = Vector2(x1, y2); - vertices[vidx++].position = Vector2(x2, y1); - vertices[vidx++].position = Vector2(x2, y1); - vertices[vidx++].position = Vector2(x1, y2); - vertices[vidx++].position = Vector2(x2, y2); - } - - 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)); -} - -void Spring::update(float32 dtSeconds) { - timeElapsed += dtSeconds; - displacement = 2 * cosf(angularVelocity * timeElapsed); - - 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)); - vertices[vidx++].position.y += y1Offset; - vertices[vidx++].position.y += y2Offset; - vertices[vidx++].position.y += y1Offset; - vertices[vidx++].position.y += y1Offset; - vertices[vidx++].position.y += y2Offset; - vertices[vidx++].position.y += y2Offset; - } - - weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, displacement)); -} - -void Spring::render(Renderer2d* renderer) { - glBindBuffer(GL_ARRAY_BUFFER, shape.vbo); - glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2d), &vertices[0]); - - shape.render(renderer); -} - -void Spring::unload() { - shape.unload(); - delete[] vertices; -} diff --git a/2d/softbody/softbody_1/undamped.cpp b/2d/softbody/softbody_1/undamped.cpp new file mode 100644 index 0000000..ec53f50 --- /dev/null +++ b/2d/softbody/softbody_1/undamped.cpp @@ -0,0 +1,227 @@ +#include "undamped.h" +#include "../../../shared_cpp/Renderer2d.h" +#include "../../../shared_cpp/types.h" +#include "../../../shared_cpp/WebglContext.h" +#include "../../../shared_cpp/mathlib.h" +#include "../../../shared_cpp/MainLoop.h" +#include <cstdio> +#include <cmath> +#include <emscripten/html5.h> +#include <unistd.h> +#include <pthread.h> +#include <cmath> +#include <cfloat> + +namespace Undamped { + + struct SpringWeight { + Mesh2d shape; + float32 radius; + float32 mass = 2.f; + + void load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor); + void update(float32 dtSeconds); + void render(Renderer2d* renderer); + void unload(); + }; + + struct Spring { + SpringWeight* weight; + + Mesh2d shape; + + Vertex2d* vertices = NULL; + int32 numSegments = 0; + int32 numVertices = 0; + float32 k = 4; // Spring Constant, in N / m + float32 initialDisplacement = 3.f; + float32 initialVelocity = 0.f; + float32 angularVelocity = 0.f; // To be calculated + float32 displacement = 0.f; + float32 timeElapsed = 0.f; + + void load(Renderer2d* renderer, SpringWeight* inWieight, float32 length, float32 loopRadius); + void update(float32 dtSeconds); + void render(Renderer2d* renderer); + void unload(); + }; + + WebglContext* context; + Renderer2d renderer; + MainLoop mainLoop; + SpringWeight weight; + Spring spring; + + EM_BOOL onUndampedPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); + EM_BOOL onUndampedStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData); + void load(); + void update(float32 deltaTimeSeconds, void* userData); + void unload(); + + void init(WebglContext* inContext) { + context = inContext; + emscripten_set_click_callback("#gl_canvas_play_undamped", NULL, false, onUndampedPlayClicked); + emscripten_set_click_callback("#gl_canvas_stop_undamped", NULL, false, onUndampedStopClicked); + } + + void load() { + context->init("#gl_canvas_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); + + mainLoop.run(update); + } + + void update(float32 deltaTimeSeconds, void* userData) { + // -- Update + spring.update(deltaTimeSeconds); + weight.update(deltaTimeSeconds); + + // -- Render + renderer.render(); + weight.render(&renderer); + spring.render(&renderer); + } + + void unload() { + mainLoop.stop(); + renderer.unload(); + weight.unload(); + spring.unload(); + + context->destroy(); + } + + + void SpringWeight::load(Renderer2d* renderer, float32 inRadius, Vector4 startColor, Vector4 endColor) { + radius = inRadius; + const int32 numSegments = 96; + const float32 radiansPerSegment = (2.f * PI) / static_cast<float>(numSegments); + const int32 numVertices = numSegments * 3; + + float32 t = 0.f; + float32 tIncrement = 1.f / (numSegments / 2.f); + startColor = startColor.toNormalizedColor(); + endColor = endColor.toNormalizedColor(); + + Vertex2d vertices[numVertices]; + for (int idx = 0; idx < numSegments; idx++) { + int vIdx = idx * 3; + + Vector4 color = lerp(startColor, endColor, t); + if (idx >= numSegments / 2) { + t -= tIncrement; + } else { + t += tIncrement; + } + + vertices[vIdx].color = color; + vertices[vIdx].position = Vector2 { radius * cosf(radiansPerSegment * idx), radius * sinf(radiansPerSegment * idx) }; + vertices[vIdx + 1].color = color; + vertices[vIdx + 1].position = Vector2 { 0.f, 0.f }; + vertices[vIdx + 2].color = color; + vertices[vIdx + 2].position = Vector2 { radius * cosf(radiansPerSegment * (idx + 1)), radius * sinf(radiansPerSegment * (idx + 1)) }; + } + + shape.load(vertices, numVertices, renderer); + } + + void SpringWeight::update(float32 dtSeconds) { + + } + + void SpringWeight::render(Renderer2d* renderer) { + shape.render(renderer); + } + + void SpringWeight::unload() { + shape.unload(); + } + + void Spring::load(Renderer2d* renderer, SpringWeight* inWeight, float32 length, float32 loopRadius) { + weight = inWeight; + angularVelocity = sqrtf(k / weight->mass); + timeElapsed = 0.f; + + const int32 verticesPerSegment = 6; + numSegments = 256; + numVertices = numSegments * verticesPerSegment; + vertices = new Vertex2d[numVertices]; + + float32 lengthIncrement = length / static_cast<float32>(numSegments); + + const float32 frequency = 0.25f; + const float32 loopWidth = 20.f; + const float32 offset = 0.25f; + + int32 vidx = 0; + 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); + + vertices[vidx++].position = Vector2(x1, y1); + vertices[vidx++].position = Vector2(x1, y2); + vertices[vidx++].position = Vector2(x2, y1); + vertices[vidx++].position = Vector2(x2, y1); + vertices[vidx++].position = Vector2(x1, y2); + vertices[vidx++].position = Vector2(x2, y2); + } + + 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)); + } + + void Spring::update(float32 dtSeconds) { + timeElapsed += dtSeconds; + displacement = initialDisplacement * cosf(angularVelocity * timeElapsed - initialVelocity); + + 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)); + vertices[vidx++].position.y += y1Offset; + vertices[vidx++].position.y += y2Offset; + vertices[vidx++].position.y += y1Offset; + vertices[vidx++].position.y += y1Offset; + vertices[vidx++].position.y += y2Offset; + vertices[vidx++].position.y += y2Offset; + } + + weight->shape.model = weight->shape.model.translateByVec2(Vector2(0, displacement)); + } + + void Spring::render(Renderer2d* renderer) { + glBindBuffer(GL_ARRAY_BUFFER, shape.vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices * sizeof(Vertex2d), &vertices[0]); + + shape.render(renderer); + } + + void Spring::unload() { + shape.unload(); + delete[] vertices; + } + + + EM_BOOL onUndampedPlayClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { + printf("Play clicked\n"); + + load(); + return true; + } + + EM_BOOL onUndampedStopClicked(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData) { + printf("Stop clicked\n"); + unload(); + return true; + } + +} diff --git a/2d/softbody/softbody_1/undamped.h b/2d/softbody/softbody_1/undamped.h new file mode 100644 index 0000000..a87e446 --- /dev/null +++ b/2d/softbody/softbody_1/undamped.h @@ -0,0 +1,8 @@ +#pragma once + +struct WebglContext; + +namespace Undamped { + void init(WebglContext* inContext); +} + diff --git a/3d/rigidbody.html b/3d/rigidbody.html index e5b0270..a0c868d 100644 --- a/3d/rigidbody.html +++ b/3d/rigidbody.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> @@ -261,6 +261,8 @@ WebGL container border: 1px solid #b0a565; width: 800px; height: 600px; + + background-color: rgb(51, 76.5, 76.5); } .opengl_canvas_container .stop_button { @@ -278,4 +280,11 @@ WebGL container cursor: pointer; } - +/*********************************** +Input Styling +************************************/ +.widget_container { + display: flex; + flex-direction: row; + align-items: center; +} @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/roadmap.html b/roadmap.html index cf3a4e6..375b2b0 100644 --- a/roadmap.html +++ b/roadmap.html @@ -27,7 +27,7 @@ <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> <li><label>Softbody</label></li> - <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Softbody</a></li> + <li><a title="/2d/softbody/softbody_1.html" href="/2d/softbody/softbody_1.html">Springs</a></li> </ul> </li> <li> diff --git a/shared_cpp/WebglContext.h b/shared_cpp/WebglContext.h index 8064b04..3b6f517 100644 --- a/shared_cpp/WebglContext.h +++ b/shared_cpp/WebglContext.h @@ -6,11 +6,13 @@ #include <EGL/egl.h> struct WebglContext { - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = 0; int width = 800; int height = 600; void init(const char* query, int inWidth = 800, int inHeight = 600) { + if (context != 0) destroy(); + width = inWidth; height = inHeight; emscripten_set_canvas_element_size( query, width, height); @@ -35,5 +37,6 @@ struct WebglContext { void destroy() { emscripten_webgl_destroy_context(context); + context = 0; } -};
\ No newline at end of file +}; diff --git a/shared_cpp/mathlib.h b/shared_cpp/mathlib.h index 0a39195..fd21ae2 100644 --- a/shared_cpp/mathlib.h +++ b/shared_cpp/mathlib.h @@ -18,6 +18,7 @@ #define ABS(x) (x < 0 ? -x : x) #define SIGN(x) (x < 0 ? -1 : 1) #define PI 3.141592653589793238463 +#define E 2.71828182845904523536 #define DEG_TO_RAD(x) (x * (PI / 180.f)) #define RAD_TO_DEG(x) (x * (180.f / PI)) |