summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattkae <mattkae@protonmail.com>2022-02-06 16:36:56 -0500
committermattkae <mattkae@protonmail.com>2022-02-06 16:36:56 -0500
commite965ed809e91079496f5b2d711ceb3e5e7b99f3d (patch)
tree18eab7d47e3d0a3582be3ddd6b7e9125ec10b42e
parent2d5ade4d7f323e5b4cb5ed27af8dbe04cbcb4ad0 (diff)
Working softbody simulation
-rwxr-xr-x2d/softbody/softbody_1/dist/output.wasmbin58758 -> 58771 bytes
-rw-r--r--2d/softbody/softbody_2/SpringRectangle.h244
-rw-r--r--2d/softbody/softbody_2/dist/output.js118
-rwxr-xr-x2d/softbody/softbody_2/dist/output.wasmbin43836 -> 45315 bytes
-rw-r--r--shared_cpp/Renderer2d.cpp3
-rw-r--r--shared_cpp/Renderer2d.h1
6 files changed, 156 insertions, 210 deletions
diff --git a/2d/softbody/softbody_1/dist/output.wasm b/2d/softbody/softbody_1/dist/output.wasm
index 8f7c621..a66202f 100755
--- a/2d/softbody/softbody_1/dist/output.wasm
+++ b/2d/softbody/softbody_1/dist/output.wasm
Binary files differ
diff --git a/2d/softbody/softbody_2/SpringRectangle.h b/2d/softbody/softbody_2/SpringRectangle.h
index e2cdf60..2965efa 100644
--- a/2d/softbody/softbody_2/SpringRectangle.h
+++ b/2d/softbody/softbody_2/SpringRectangle.h
@@ -7,51 +7,47 @@ struct PointMassUpdateData {
Vector2 restingPosition; // Position is in world coordinates
Vector2 currentPosition; // Position is in world coordinates
Vector2 velocity;
+ Vector2 acceleration;
Vector2 force;
bool isHovered = false;
PointMassUpdateData* neighbors[4];
};
-EM_BOOL onMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
-EM_BOOL onMouseDown(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
-EM_BOOL onMouseUp(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
-
struct SoftbodyRectangle {
// User defined
float32 width = 200;
float32 height = 200;
- int32 springDensity = 10;
- float32 k = 3.f; // in N /m
- float32 c = 3.f;
- float32 jointMassKg = 1.f;
+ int32 springDensity = 16;
+ float32 k = 10000000.f; // in N /m
+ float32 c = 9000.f;
+ float32 jointMassKg = 10.f;
+ float32 floorPosition = 0;
// Calculated before runtime
Vector2 springDimensions;
// Runtime data
- float32 totalTimeSeconds = 0.f;
PointMassUpdateData* updateData = NULL;
- bool hasLastPositionChanged = false;
- Vector2 lastMousePosition;
- PointMassUpdateData* draggedVertex = NULL;
// Render data
Mesh2d mesh;
Mesh2d pointsMesh;
+ Mesh2d floorMesh;
Vertex2d* vertices = NULL;
Vertex2d* pointsVertices = NULL;
void load(Renderer2d* renderer) {
- Vector2 position = Vector2(800 / 2 - width / 2, 600 / 2 - height / 2);
+ auto defaultPosition = Vector2(800 / 2 - width / 2, 400);
springDimensions = Vector2(width / springDensity, height / springDensity);
int32 numVertices = springDensity * springDensity; // Each subdivision is a square.
int32 numIndices = 6 * ((springDensity - 1) * (springDensity - 1));
vertices = new Vertex2d[numVertices];
updateData = new PointMassUpdateData[numVertices];
+ pointsVertices = new Vertex2d[numVertices];
auto indices = new GLuint[numIndices];
- // Load a square with the desired density
+ // -- Load a square with the desired density
int32 vIdx = 0;
int32 iIdx = 0;
float32 inverseDensity = 1.f / springDensity;
@@ -59,24 +55,26 @@ struct SoftbodyRectangle {
for (int32 y = 0; y < springDensity; y++) { // Rows
for (int32 x = 0; x < springDensity; x++) { // Columns
Vector2 vpos = Vector2(x * inverseDensity - halfInv, y * inverseDensity- halfInv);
- vpos.x = vpos.x * width + position.x;
- vpos.y = vpos.y * height + position.y;
+ vpos.x = vpos.x * width + defaultPosition.x;
+ vpos.y = vpos.y * height + defaultPosition.y;
vertices[vIdx] = { vpos, Vector4(1, 0, 0, 1) };
updateData[vIdx].index = vIdx;
- updateData[vIdx].restingPosition = vpos;
+ updateData[vIdx].restingPosition = vpos;
updateData[vIdx].currentPosition = vpos;
updateData[vIdx].force = Vector2(0, 0);
updateData[vIdx].velocity = Vector2(0, 0);
+ updateData[vIdx].acceleration = Vector2(0, 0);
- if (x != 0) updateData[vIdx].neighbors[0] = &updateData[vIdx - 1]; // Left
+ if (x != springDensity - 1) updateData[vIdx].neighbors[0] = &updateData[vIdx + 1]; // Right
else updateData[vIdx].neighbors[0] = NULL;
- if (x != springDensity - 1) updateData[vIdx].neighbors[1] = &updateData[vIdx + 1]; // Right
+ if (y != springDensity - 1) updateData[vIdx].neighbors[1] = &updateData[vIdx + springDensity]; // Bottom
else updateData[vIdx].neighbors[1] = NULL;
- if (y != 0) updateData[vIdx].neighbors[2] = &updateData[vIdx - springDensity]; // Top
+ if (x != 0) updateData[vIdx].neighbors[2] = &updateData[vIdx - 1]; // Left
else updateData[vIdx].neighbors[2] = NULL;
- if (y != springDensity - 1) updateData[vIdx].neighbors[3] = &updateData[vIdx + springDensity]; // Bottom
+ if (y != 0) updateData[vIdx].neighbors[3] = &updateData[vIdx - springDensity]; // Top
else updateData[vIdx].neighbors[3] = NULL;
+
if (y != springDensity - 1 && x != springDensity - 1) {
indices[iIdx++] = vIdx;
@@ -87,132 +85,129 @@ struct SoftbodyRectangle {
indices[iIdx++] = vIdx + 1;
}
+ pointsVertices[vIdx].position = vpos;
+ pointsVertices[vIdx].color = Vector4(0, 0, 0, 1);
+
vIdx++;
}
}
mesh.load(vertices, numVertices, indices, numIndices, renderer, GL_DYNAMIC_DRAW);
-
- pointsVertices = new Vertex2d[numVertices];
- for (int32 v = 0; v < numVertices; v++) {
- pointsVertices[v].position = vertices[v].position;
- pointsVertices[v].color = Vector4(0, 0, 0, 1);
- }
pointsMesh.load(pointsVertices, numVertices, renderer, GL_DYNAMIC_DRAW);
-
delete [] indices;
- // Setup callbacks
- emscripten_set_mousemove_callback("#gl_canvas", this, false, onMouseMove);
- emscripten_set_mousedown_callback("#gl_canvas", this, false, onMouseDown);
- emscripten_set_mouseup_callback("#gl_canvas", this, false, onMouseUp);
+ // -- Load the floor line;
+ Vector2 floorDimensions = Vector2(renderer->context->width, 8);
+ floorPosition = 100.f;
+ Vector4 floorColor = Vector4(0.5, 0.5, 0.5, 1);
+ Vertex2d floorVertices[6];
+ floorVertices[0] = { Vector4(0, floorPosition, 0, 1), floorColor };
+ floorVertices[1] = { Vector4(floorDimensions.x, floorPosition, 0, 1), floorColor };
+ floorVertices[2] = { Vector4(0, floorPosition - floorDimensions.y, 0, 1), floorColor };
+ floorVertices[3] = { Vector4(0, floorPosition - floorDimensions.y, 0, 1), floorColor };
+ floorVertices[4] = { Vector4(floorDimensions.x, floorPosition - floorDimensions.y, 0, 1), floorColor };
+ floorVertices[5] = { Vector4(floorDimensions.x, floorPosition, 0, 1), floorColor };
+ floorMesh.load(floorVertices, 6, renderer);
}
Vector2 getForceBetweenPointMasses(PointMassUpdateData* first, PointMassUpdateData* second) {
auto relativeVelocity = second->velocity - first->velocity;
- auto restLength = (first->restingPosition - second->restingPosition).length();
+ auto restLength = (second->restingPosition - first->restingPosition).length();
auto relativePosition = second->currentPosition - first->currentPosition;
auto currentLength = relativePosition.length();
auto positionDir = relativePosition.normalize();
- auto dotProduct = positionDir.dot(relativeVelocity);
+ auto velDotProduct = positionDir.dot(relativeVelocity);
+ auto accelDotProduct = positionDir.dot(second->acceleration - first->acceleration);
float32 springForce = k * (currentLength - restLength);
- float32 dampingForce = c * dotProduct;
- float32 totalForce = springForce + dampingForce;
-
+ float32 dampingForce = c * velDotProduct;
+ float32 accelerationForce = jointMassKg * accelDotProduct;
+ float32 totalForce = accelerationForce + springForce + dampingForce;
+
return positionDir * totalForce;
}
void update(float32 dtSeconds) {
- totalTimeSeconds += dtSeconds;
-
- for (int32 v = 0; v < pointsMesh.numVertices; v++) {
+ for (int32 v = 0; v < pointsMesh.numVertices; v++) {
auto pointMass = &updateData[v];
- if (draggedVertex != NULL) {
- if (pointMass == draggedVertex && hasLastPositionChanged) {
- hasLastPositionChanged = false;
- Vector2 displacement = lastMousePosition - pointMass->restingPosition;
-
- // We need to limit the new position based off of the triangle
- if (displacement.x > springDimensions.x) {
- displacement.x = springDimensions.x;
- }
- else if (displacement.x < -springDimensions.x) {
- displacement.x = -springDimensions.x;
- }
-
- if (displacement.y > springDimensions.y) {
- displacement.y = springDimensions.y;
- }
- else if (displacement.y < -springDimensions.y) {
- displacement.y = -springDimensions.y;
- }
-
- pointMass->currentPosition = pointMass->restingPosition + displacement;
- vertices[v].position = pointMass->currentPosition;
- pointsVertices[v].position = pointMass->currentPosition;
- }
- }
- else {
- // Add the forces from it's neighbors
- for (int32 n = 0; n < 4; n++) {
- auto neighbor = pointMass->neighbors[n];
- if (neighbor == NULL) continue;
+ // -- Add the forces from it's neighbors. Note that we only do the first two
+ // neighbors, which are the right and bottom neighbors.
+ for (int32 n = 0; n < 2; n++) {
+ auto neighbor = pointMass->neighbors[n];
+ if (neighbor == NULL) continue;
- pointMass->force += getForceBetweenPointMasses(pointMass, neighbor);
- }
-
- pointMass->velocity = pointMass->velocity + (pointMass->force / jointMassKg) * dtSeconds;
- pointMass->currentPosition = pointMass->currentPosition + (pointMass->velocity * dtSeconds);
-
- const float32 COLLISION_DISTANCE = 4.f;
- for (int32 n = 0; n < pointsMesh.numVertices; n++) {
- if (n == v) continue;
- auto neighbor = &updateData[n];
-
- if ((neighbor->currentPosition - pointMass->currentPosition).length() < COLLISION_DISTANCE) {
- auto positionNormal = (neighbor->currentPosition - pointMass->currentPosition).normalize();
- pointMass->currentPosition = neighbor->currentPosition - positionNormal * COLLISION_DISTANCE;
- float32 dotProduct = pointMass->velocity.dot(positionNormal);
- pointMass->velocity = pointMass->velocity - positionNormal * (2 * dotProduct);
- }
- }
+ auto forceBetween = getForceBetweenPointMasses(pointMass, neighbor);
+ pointMass->force = pointMass->force + forceBetween;
+ neighbor->force = neighbor->force- forceBetween;
+ }
+ }
- vertices[v].position = pointMass->currentPosition;
- pointsVertices[v].position = pointMass->currentPosition;
-
- // Hovering highlights behavior
- if (hasLastPositionChanged) {
- if ((pointMass->currentPosition - lastMousePosition).length() < 10.f) {
- pointsVertices[v].color = Vector4(1, 1, 0, 1);
- pointMass->isHovered = true;
-
- for (int32 n = 0; n < 4; n++) {
- if (pointMass->neighbors[n])
- pointsVertices[pointMass->neighbors[n]->index].color = Vector4(0, 0, 1, 1);
- }
- }
- else if (pointMass->isHovered) {
- pointsVertices[v].color = Vector4(0, 0, 0, 1);
- for (int32 n = 0; n < 4; n++) {
- if (pointMass->neighbors[n] && !pointMass->neighbors[n]->isHovered)
- pointsVertices[pointMass->neighbors[n]->index].color = Vector4(0, 0, 0, 1);
- }
- pointMass->isHovered = false;
- }
+ // -- Update the local position of each vertex.
+ for (int32 v = 0; v < pointsMesh.numVertices; v++) {
+ auto pointMass = &updateData[v];
+ auto prevPos = pointMass->currentPosition;
+
+ // -- Gravity
+ Vector2 g = Vector2(0, -9.8 * jointMassKg) * dtSeconds;
+
+ // -- Euler integration to find the current velocity and position
+ pointMass->acceleration = (pointMass->force / jointMassKg) * dtSeconds;
+ pointMass->velocity = pointMass->velocity + pointMass->acceleration * dtSeconds + g;
+ pointMass->restingPosition = pointMass->restingPosition + g * dtSeconds;
+ pointMass->currentPosition = pointMass->currentPosition + (pointMass->velocity * dtSeconds);
+
+ pointMass->force = Vector2(0, 0); // Reset the force for the next update
+
+ particleFloorCollision(pointMass, prevPos, dtSeconds);
+
+ // -- Collision detection
+ const float32 COLLISION_DISTANCE = 0.3f;
+ for (int32 n = 0; n < 4; n++) {
+ auto neighbor = pointMass->neighbors[n];
+ if (neighbor == NULL) continue;
+
+ if ((neighbor->currentPosition - pointMass->currentPosition).length() < COLLISION_DISTANCE) {
+ auto positionNormal = (neighbor->currentPosition - pointMass->currentPosition).normalize();
+ pointMass->currentPosition = neighbor->currentPosition - positionNormal * COLLISION_DISTANCE;
+ float32 dotProduct = pointMass->velocity.dot(positionNormal);
+ pointMass->velocity = pointMass->velocity - positionNormal * (2 * dotProduct);
}
}
+
+ vertices[v].position = pointMass->currentPosition;
+ pointsVertices[v].position = pointMass->currentPosition;
}
- if (hasLastPositionChanged) hasLastPositionChanged = false;
+ // -- Update vertices
mesh.updateVertices(vertices);
pointsMesh.updateVertices(pointsVertices);
}
+ void particleFloorCollision(PointMassUpdateData* ud, Vector2 prevPos, float32 dtSeconds) {
+ // We assume that the floor is always horizontal for this simulation
+ auto dotProduct = ud->velocity.dot(Vector2(0, 1));
+ if (dotProduct >= 0) {
+ return; // Not moving in the same direction
+ }
+
+ if (ud->currentPosition.y - floorPosition < 0.1f) {
+ // Find the point in the simulation at which we began intersecting, and then reflect.
+ Vector2 newPosition;
+ do {
+ dtSeconds = dtSeconds - 0.02f;
+ newPosition = prevPos + ud->velocity * dtSeconds;
+ } while (newPosition.y < floorPosition);
+
+ ud->currentPosition = newPosition;
+ ud->velocity = (ud->velocity - Vector2(0, 1) * (2 * dotProduct)) * 0.5f;
+ }
+ }
+
void render(Renderer2d* renderer) {
mesh.render(renderer);
pointsMesh.render(renderer, GL_POINTS);
+ floorMesh.render(renderer);
}
void unload() {
@@ -222,30 +217,3 @@ struct SoftbodyRectangle {
delete [] pointsVertices;
}
};
-
-EM_BOOL onMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
- SoftbodyRectangle* rectangle = (SoftbodyRectangle*)userData;
- rectangle->hasLastPositionChanged = true;
- rectangle->lastMousePosition = Vector2(static_cast<float32>(mouseEvent->targetX), static_cast<float32>(600 - mouseEvent->targetY));
- return true;
-}
-
-EM_BOOL onMouseDown(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
- SoftbodyRectangle* rectangle = (SoftbodyRectangle*)userData;
-
- for (int32 v = 0; v < rectangle->pointsMesh.numVertices; v++) {
- auto pointMass = &rectangle->updateData[v];
- if (pointMass->isHovered) {
- rectangle->draggedVertex = pointMass;
- break;
- }
- }
-
- return true;
-}
-
-EM_BOOL onMouseUp(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) {
- SoftbodyRectangle* rectangle = (SoftbodyRectangle*)userData;
- rectangle->draggedVertex = NULL;
- return true;
-}
diff --git a/2d/softbody/softbody_2/dist/output.js b/2d/softbody/softbody_2/dist/output.js
index 51df416..4f59242 100644
--- a/2d/softbody/softbody_2/dist/output.js
+++ b/2d/softbody/softbody_2/dist/output.js
@@ -15,6 +15,9 @@
// can continue to use Module afterwards as well.
var Module = typeof Module !== 'undefined' ? Module : {};
+// See https://caniuse.com/mdn-javascript_builtins_object_assign
+var objAssign = Object.assign;
+
// --pre-jses are emitted after the Module integration code, so that they can
// refer to Module (if they choose; they can also define Module)
// {{PRE_JSES}}
@@ -24,17 +27,11 @@ var Module = typeof Module !== 'undefined' ? Module : {};
// we collect those properties and reapply _after_ we configure
// the current environment's defaults to avoid having to be so
// defensive during initialization.
-var moduleOverrides = {};
-var key;
-for (key in Module) {
- if (Module.hasOwnProperty(key)) {
- moduleOverrides[key] = Module[key];
- }
-}
+var moduleOverrides = objAssign({}, Module);
var arguments_ = [];
var thisProgram = './this.program';
-var quit_ = function(status, toThrow) {
+var quit_ = (status, toThrow) => {
throw toThrow;
};
@@ -77,15 +74,16 @@ var read_,
// this may no longer be needed under node.
function logExceptionOnExit(e) {
if (e instanceof ExitStatus) return;
- var toLog = e;
+ let toLog = e;
if (e && typeof e === 'object' && e.stack) {
toLog = [e, e.stack];
}
err('exiting due to exception: ' + toLog);
}
-var nodeFS;
+var fs;
var nodePath;
+var requireNodeFS;
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?)');
@@ -98,11 +96,20 @@ if (ENVIRONMENT_IS_NODE) {
// include: node_shell_read.js
+requireNodeFS = function() {
+ // Use nodePath as the indicator for these not being initialized,
+ // since in some environments a global fs may have already been
+ // created.
+ if (!nodePath) {
+ fs = require('fs');
+ nodePath = require('path');
+ }
+}
+
read_ = function shell_read(filename, binary) {
- if (!nodeFS) nodeFS = require('fs');
- if (!nodePath) nodePath = require('path');
+ requireNodeFS();
filename = nodePath['normalize'](filename);
- return nodeFS['readFileSync'](filename, binary ? null : 'utf8');
+ return fs.readFileSync(filename, binary ? null : 'utf8');
};
readBinary = function readBinary(filename) {
@@ -115,10 +122,9 @@ readBinary = function readBinary(filename) {
};
readAsync = function readAsync(filename, onload, onerror) {
- if (!nodeFS) nodeFS = require('fs');
- if (!nodePath) nodePath = require('path');
+ requireNodeFS();
filename = nodePath['normalize'](filename);
- nodeFS['readFile'](filename, function(err, data) {
+ fs.readFile(filename, function(err, data) {
if (err) onerror(err);
else onload(data.buffer);
});
@@ -149,7 +155,7 @@ readAsync = function readAsync(filename, onload, onerror) {
// See https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode
process['on']('unhandledRejection', function(reason) { throw reason; });
- quit_ = function(status, toThrow) {
+ quit_ = (status, toThrow) => {
if (keepRuntimeAlive()) {
process['exitCode'] = status;
throw toThrow;
@@ -172,7 +178,7 @@ if (ENVIRONMENT_IS_SHELL) {
}
readBinary = function readBinary(f) {
- var data;
+ let data;
if (typeof readbuffer === 'function') {
return new Uint8Array(readbuffer(f));
}
@@ -182,7 +188,7 @@ if (ENVIRONMENT_IS_SHELL) {
};
readAsync = function readAsync(f, onload, onerror) {
- setTimeout(function() { onload(readBinary(f)); }, 0);
+ setTimeout(() => onload(readBinary(f)), 0);
};
if (typeof scriptArgs != 'undefined') {
@@ -192,7 +198,7 @@ if (ENVIRONMENT_IS_SHELL) {
}
if (typeof quit === 'function') {
- quit_ = function(status, toThrow) {
+ quit_ = (status, toThrow) => {
logExceptionOnExit(toThrow);
quit(status);
};
@@ -233,7 +239,6 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
// Differentiate the Web Worker from the Node Worker case, as reading must
// be done differently.
{
-
// include: web_or_worker_shell_read.js
@@ -272,7 +277,7 @@ if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
// end include: web_or_worker_shell_read.js
}
- setWindowTitle = function(title) { document.title = title };
+ setWindowTitle = (title) => document.title = title;
} else
{
throw new Error('environment detection error');
@@ -282,11 +287,7 @@ var out = Module['print'] || console.log.bind(console);
var err = Module['printErr'] || console.warn.bind(console);
// Merge back in the overrides
-for (key in moduleOverrides) {
- if (moduleOverrides.hasOwnProperty(key)) {
- Module[key] = moduleOverrides[key];
- }
-}
+objAssign(Module, moduleOverrides);
// Free the object hierarchy contained in the overrides, this lets the GC
// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
moduleOverrides = null;
@@ -396,10 +397,10 @@ function getNativeTypeSize(type) {
case 'float': return 4;
case 'double': return 8;
default: {
- if (type[type.length-1] === '*') {
+ if (type[type.length - 1] === '*') {
return POINTER_SIZE;
} else if (type[0] === 'i') {
- var bits = Number(type.substr(1));
+ const bits = Number(type.substr(1));
assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type);
return bits / 8;
} else {
@@ -694,7 +695,7 @@ var EXITSTATUS;
/** @type {function(*, string=)} */
function assert(condition, text) {
if (!condition) {
- abort('Assertion failed: ' + text);
+ abort('Assertion failed' + (text ? ': ' + text : ''));
}
}
@@ -2095,21 +2096,6 @@ var ASM_CONSTS = {
return 0;
}
- function _emscripten_set_mousedown_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
- registerMouseEventCallback(target, userData, useCapture, callbackfunc, 5, "mousedown", targetThread);
- return 0;
- }
-
- function _emscripten_set_mousemove_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
- registerMouseEventCallback(target, userData, useCapture, callbackfunc, 8, "mousemove", targetThread);
- return 0;
- }
-
- function _emscripten_set_mouseup_callback_on_thread(target, userData, useCapture, callbackfunc, targetThread) {
- registerMouseEventCallback(target, userData, useCapture, callbackfunc, 6, "mouseup", targetThread);
- return 0;
- }
-
function __webgl_enable_ANGLE_instanced_arrays(ctx) {
// Extension available in WebGL 1 from Firefox 26 and Google Chrome 30 onwards. Core feature in WebGL 2.
var ext = ctx.getExtension('ANGLE_instanced_arrays');
@@ -2449,20 +2435,6 @@ 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);
@@ -2484,6 +2456,10 @@ var ASM_CONSTS = {
}
+ function _emscripten_webgl_make_context_current(contextHandle) {
+ var success = GL.makeContextCurrent(contextHandle);
+ return success ? 0 : -5;
+ }
var SYSCALLS = {mappings:{},buffers:[null,[],[]],printChar:function(stream, curr) {
var buffer = SYSCALLS.buffers[stream];
@@ -3074,9 +3050,6 @@ var asmLibraryArg = {
"emscripten_resize_heap": _emscripten_resize_heap,
"emscripten_set_canvas_element_size": _emscripten_set_canvas_element_size,
"emscripten_set_click_callback_on_thread": _emscripten_set_click_callback_on_thread,
- "emscripten_set_mousedown_callback_on_thread": _emscripten_set_mousedown_callback_on_thread,
- "emscripten_set_mousemove_callback_on_thread": _emscripten_set_mousemove_callback_on_thread,
- "emscripten_set_mouseup_callback_on_thread": _emscripten_set_mouseup_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,
@@ -3134,15 +3107,6 @@ var ___errno_location = Module["___errno_location"] = createExportWrapper("__err
var _fflush = Module["_fflush"] = createExportWrapper("fflush");
/** @type {function(...*):?} */
-var stackSave = Module["stackSave"] = createExportWrapper("stackSave");
-
-/** @type {function(...*):?} */
-var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore");
-
-/** @type {function(...*):?} */
-var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc");
-
-/** @type {function(...*):?} */
var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() {
return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments);
};
@@ -3158,6 +3122,15 @@ var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function()
};
/** @type {function(...*):?} */
+var stackSave = Module["stackSave"] = createExportWrapper("stackSave");
+
+/** @type {function(...*):?} */
+var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore");
+
+/** @type {function(...*):?} */
+var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc");
+
+/** @type {function(...*):?} */
var _malloc = Module["_malloc"] = createExportWrapper("malloc");
/** @type {function(...*):?} */
@@ -3242,7 +3215,10 @@ if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] =
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, "convertFrameToPC")) Module["convertFrameToPC"] = function() { abort("'convertFrameToPC' 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, "saveInUnwindCache")) Module["saveInUnwindCache"] = function() { abort("'saveInUnwindCache' was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)") };
+if (!Object.getOwnPropertyDescriptor(Module, "convertPCtoSourceLocation")) Module["convertPCtoSourceLocation"] = function() { abort("'convertPCtoSourceLocation' 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)") };
diff --git a/2d/softbody/softbody_2/dist/output.wasm b/2d/softbody/softbody_2/dist/output.wasm
index 85d82ce..8710d1a 100755
--- a/2d/softbody/softbody_2/dist/output.wasm
+++ b/2d/softbody/softbody_2/dist/output.wasm
Binary files differ
diff --git a/shared_cpp/Renderer2d.cpp b/shared_cpp/Renderer2d.cpp
index e1892e5..70e6714 100644
--- a/shared_cpp/Renderer2d.cpp
+++ b/shared_cpp/Renderer2d.cpp
@@ -21,7 +21,8 @@ const char* orthographicFragment =
" gl_FragColor = VertexColor; \n"
"}";
-void Renderer2d::load(WebglContext* context) {
+void Renderer2d::load(WebglContext* inContext) {
+ context = inContext;
printf("Compiling orthographic shader...\n");
shader = loadShader(orthographicVertex, orthographicFragment);
diff --git a/shared_cpp/Renderer2d.h b/shared_cpp/Renderer2d.h
index 3ecb410..bada0ea 100644
--- a/shared_cpp/Renderer2d.h
+++ b/shared_cpp/Renderer2d.h
@@ -10,6 +10,7 @@ struct WebglContext;
struct Renderer2d {
Mat4x4 projection;
uint32 shader;
+ WebglContext* context;
struct {
int32 position;