Last active
December 16, 2015 03:29
-
-
Save jlongster/5369811 to your computer and use it in GitHub Desktop.
large LLJS example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern clear, fillRect, renderLine, print; | |
struct Vec2d { | |
function void Vec2d(float x, float y) { | |
this->x = x; | |
this->y = y; | |
} | |
float x; | |
float y; | |
} | |
struct Point { | |
function void Point(float x, float y, | |
float sizeX, float sizeY, | |
float mass, | |
int pinned) { | |
this->pos.x = x; | |
this->pos.y = y; | |
this->lastPos = this->pos; | |
this->size.x = sizeX; | |
this->size.y = sizeY; | |
this->mass = mass; | |
this->acc.x = 0; | |
this->acc.y = 0; | |
this->pinned = pinned; | |
} | |
Vec2d pos; | |
Vec2d lastPos; | |
Vec2d size; | |
float mass; | |
Vec2d acc; | |
int pinned; | |
} | |
struct Link { | |
function void Link(Point *p1, Point *p2, | |
float distRest, float stiffness, float tearness) { | |
this->p1 = p1; | |
this->p2 = p2; | |
this->distRest = distRest; | |
this->stiffness = stiffness; | |
this->tearness = tearness; | |
} | |
Point *p1; | |
Point *p2; | |
float distRest; | |
float stiffness; | |
float tearness; | |
} | |
let int clothW = 10; | |
let int clothH = 10; | |
let int numPoints = 100; | |
let int numLinks = 2; | |
let Point points[100]; | |
let int gravity = 500; | |
let int leftOverTime = 0; | |
function int min(int a, int b) { | |
if(a < b) { | |
return a; | |
} | |
return b; | |
} | |
function void update(int dt) { | |
let int steps = min((dt + leftOverTime) / 16, 5); | |
leftOverTime = dt - steps * 16; | |
for(let int i = 0; i<steps; i = i + 1) { | |
updateStep(float(16.0) / float(1000.0)); | |
} | |
} | |
function void updateStep(float dt) { | |
for(let int z=0; z<3; z = z + 1) { | |
for(let int i=0; i<numPoints; i = i + 1) { | |
solveConstraints(&points[i]); | |
} | |
} | |
for(let int i=0; i<numPoints; i = i + 1) { | |
updatePoint(&points[i], dt); | |
} | |
} | |
function void render() { | |
clear(); | |
for(let int j=0; j<numPoints; j = j + 1) { | |
fillRect(points[j].pos.x, | |
points[j].pos.y, | |
points[j].size.x, | |
points[j].size.y); | |
} | |
} | |
function void solveConstraints(Point *p) { | |
} | |
function void updatePoint(Point *p, float dt) { | |
let float dtSeq = dt * dt; | |
applyForce(p, 0, p->mass * gravity); | |
let float x = p->pos.x; | |
let float y = p->pos.y; | |
let float lx = p->lastPos.x; | |
let float ly = p->lastPos.y; | |
p->lastPos = p->pos; | |
let Vec2d vel((x - lx) * .99, (y - ly) * .99); | |
p->pos.x = x + vel.x + p->acc.x * dtSeq; | |
p->pos.y = y + vel.y + p->acc.y * dtSeq; | |
p->acc.x = 0; | |
p->acc.y = 0; | |
} | |
function void applyForce(Point *p, float x, float y) { | |
p->acc.x = p->acc.x + x / p->mass; | |
p->acc.y = p->acc.y + y / p->mass; | |
} | |
function void main(int width) { | |
let float restingDistance = 6; | |
let int minWidth = width / 2 - int((clothW * restingDistance) / 2); | |
let int minHeight = 25; | |
for(let int y=0; y<clothH; y = y + 1) { | |
for(let int x=0; x<clothW; x = x + 1) { | |
let Point p( | |
minWidth + x * restingDistance, | |
minHeight + y * restingDistance, | |
3, 3, | |
1, y == 0 | |
); | |
points[y*clothW + x] = p; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
if(!Math.imul) { | |
Math.imul = function(x, y) { return x * y; }; | |
} | |
var MB = 1024 * 1024; | |
var SIZE = 256 * MB; | |
var STACK_SIZE = 2 * MB; | |
var HEAP_SIZE = SIZE - STACK_SIZE; | |
var buffer = new ArrayBuffer(SIZE); | |
var asm = (function (global, env, buffer) { | |
"use asm"; | |
var stackSize = env.STACK_SIZE|0; | |
var heapSize = env.HEAP_SIZE|0; | |
var totalSize = env.TOTAL_SIZE|0; | |
var clear = env.clear; | |
var fillRect = env.fillRect; | |
var renderLine = env.renderLine; | |
var print = env.print; | |
var U1 = new global.Uint8Array(buffer); | |
var I1 = new global.Int8Array(buffer); | |
var U2 = new global.Uint16Array(buffer); | |
var I2 = new global.Int16Array(buffer); | |
var U4 = new global.Uint32Array(buffer); | |
var I4 = new global.Int32Array(buffer); | |
var F4 = new global.Float32Array(buffer); | |
var F8 = new global.Float64Array(buffer); | |
var acos = global.Math.acos; | |
var asin = global.Math.asin; | |
var atan = global.Math.atan; | |
var cos = global.Math.cos; | |
var sin = global.Math.sin; | |
var tan = global.Math.tan; | |
var ceil = global.Math.ceil; | |
var floor = global.Math.floor; | |
var exp = global.Math.exp; | |
var log = global.Math.log; | |
var sqrt = global.Math.sqrt; | |
var abs = global.Math.abs; | |
var atan2 = global.Math.atan2; | |
var pow = global.Math.pow; | |
var imul = global.Math.imul; | |
var globalSP = 4464; | |
var clothW = 10; | |
var clothH = 10; | |
var numPoints = 100; | |
var numLinks = 2; | |
var gravity = 500; | |
var leftOverTime = 0; | |
function Vec2d$Vec2d(thisPtr, x, y) { | |
thisPtr = thisPtr | 0; | |
x = +x; | |
y = +y; | |
var $SP = 0; | |
F4[(thisPtr) >> 2] = x; | |
F4[((thisPtr) + 4 | 0) >> 2] = y; | |
} | |
function Point$Point(thisPtr, x, y, sizeX, sizeY, mass, pinned) { | |
thisPtr = thisPtr | 0; | |
x = +x; | |
y = +y; | |
sizeX = +sizeX; | |
sizeY = +sizeY; | |
mass = +mass; | |
pinned = pinned | 0; | |
var $SP = 0; | |
F4[((thisPtr)) >> 2] = x; | |
F4[(((thisPtr)) + 4 | 0) >> 2] = y; | |
memcpy((thisPtr) + 8 | 0, (thisPtr) | 0, 8); | |
F4[((thisPtr) + 16 | 0) >> 2] = sizeX; | |
F4[(((thisPtr) + 16 | 0) + 4 | 0) >> 2] = sizeY; | |
F4[((thisPtr) + 24 | 0) >> 2] = mass; | |
F4[((thisPtr) + 32 | 0) >> 2] = +0; | |
F4[(((thisPtr) + 32 | 0) + 4 | 0) >> 2] = +0; | |
I4[((thisPtr) + 40 | 0) >> 2] = pinned; | |
} | |
function Link$Link(thisPtr, p1, p2, distRest, stiffness, tearness) { | |
thisPtr = thisPtr | 0; | |
p1 = p1 | 0; | |
p2 = p2 | 0; | |
distRest = +distRest; | |
stiffness = +stiffness; | |
tearness = +tearness; | |
var $SP = 0; | |
U4[(thisPtr) >> 2] = p1 | 0; | |
U4[((thisPtr) + 4 | 0) >> 2] = p2 | 0; | |
F4[((thisPtr) + 8 | 0) >> 2] = distRest; | |
F4[((thisPtr) + 12 | 0) >> 2] = stiffness; | |
F4[((thisPtr) + 16 | 0) >> 2] = tearness; | |
} | |
function min(a, b) { | |
a = a | 0; | |
b = b | 0; | |
var $SP = 0; | |
if ((a | 0) < (b | 0)) { | |
return a | 0; | |
} | |
return b | 0; | |
} | |
function update(dt) { | |
dt = dt | 0; | |
var steps = 0, i = 0, $SP = 0; | |
steps = min(((dt | 0 | 0) + (leftOverTime | 0 | 0) | 0 | 0 | 0 | 0) / 16 | 0 | 0, 5); | |
leftOverTime = (dt | 0) - (imul(steps, 16) | 0) | 0; | |
for (i = 0; (i | 0) < (steps | 0); i = (i | 0) + 1 | 0) { | |
updateStep(+(+(+16) / +(+1000))); | |
} | |
} | |
function updateStep(dt) { | |
dt = +dt; | |
var z = 0, i = 0, i$1 = 0, $SP = 0; | |
for (z = 0; (z | 0) < 3; z = (z | 0) + 1 | 0) { | |
for (i = 0; (i | 0) < (numPoints | 0); i = (i | 0) + 1 | 0) { | |
solveConstraints((((totalSize - globalSP | 0) + 64 | 0) + i * 44) | 0); | |
} | |
} | |
for (i$1 = 0; (i$1 | 0) < (numPoints | 0); i$1 = (i$1 | 0) + 1 | 0) { | |
updatePoint((((totalSize - globalSP | 0) + 64 | 0) + i$1 * 44) | 0, dt); | |
} | |
} | |
function render() { | |
var j = 0, $SP = 0; | |
clear(); | |
for (j = 0; (j | 0) < (numPoints | 0); j = (j | 0) + 1 | 0) { | |
fillRect(+F4[(((((totalSize - globalSP | 0) + 64 | 0) + j * 44))) >> 2], +F4[((((((totalSize - globalSP | 0) + 64 | 0) + j * 44))) + 4 | 0) >> 2], +F4[(((((totalSize - globalSP | 0) + 64 | 0) + j * 44)) + 16 | 0) >> 2], +F4[((((((totalSize - globalSP | 0) + 64 | 0) + j * 44)) + 16 | 0) + 4 | 0) >> 2]); | |
} | |
} | |
function solveConstraints(p) { | |
p = p | 0; | |
var $SP = 0; | |
} | |
function updatePoint(p, dt) { | |
p = p | 0; | |
dt = +dt; | |
var dtSeq = 0.0, x = 0.0, y = 0.0, lx = 0.0, ly = 0.0, vel = 0, $SP = 0; | |
U4[1] = (U4[1] | 0) - 8; | |
$SP = U4[1] | 0; | |
dtSeq = +(+dt * +dt); | |
applyForce(p | 0, +0, +(+(+F4[((p) + 24 | 0) >> 2]) * +(gravity | 0))); | |
x = +F4[((p)) >> 2]; | |
y = +F4[(((p)) + 4 | 0) >> 2]; | |
lx = +F4[((p) + 8 | 0) >> 2]; | |
ly = +F4[(((p) + 8 | 0) + 4 | 0) >> 2]; | |
memcpy((p) + 8 | 0, (p) | 0, 8); | |
(Vec2d$Vec2d(($SP) | 0 | 0, +((+x - +lx) * 0.99), +((+y - +ly) * 0.99)), F4[($SP) >> 2]); | |
F4[((p)) >> 2] = +(+x + +(+F4[(($SP)) >> 2]) + +(+F4[((p) + 32 | 0) >> 2]) * +dtSeq); | |
F4[(((p)) + 4 | 0) >> 2] = +(+y + +(+F4[((($SP)) + 4 | 0) >> 2]) + +(+F4[(((p) + 32 | 0) + 4 | 0) >> 2]) * +dtSeq); | |
F4[((p) + 32 | 0) >> 2] = +0; | |
F4[(((p) + 32 | 0) + 4 | 0) >> 2] = +0; | |
U4[1] = (U4[1] | 0) + 8; | |
return 0.0; | |
} | |
function applyForce(p, x, y) { | |
p = p | 0; | |
x = +x; | |
y = +y; | |
var $SP = 0; | |
F4[((p) + 32 | 0) >> 2] = +(+(+F4[((p) + 32 | 0) >> 2]) + +x / +(+F4[((p) + 24 | 0) >> 2])); | |
F4[(((p) + 32 | 0) + 4 | 0) >> 2] = +(+(+F4[(((p) + 32 | 0) + 4 | 0) >> 2]) + +y / +(+F4[((p) + 24 | 0) >> 2])); | |
} | |
function main(width) { | |
width = width | 0; | |
var restingDistance = 0.0, minWidth = 0, minHeight = 0, y = 0, x = 0, p = 0, $SP = 0; | |
U4[1] = totalSize - 4464; | |
U4[0] = 4; | |
U4[1] = (U4[1] | 0) - 48; | |
$SP = U4[1] | 0; | |
restingDistance = +6.0; | |
minWidth = ((width | 0 | 0) / 2 | 0 | 0 | 0 | 0) - (~~(+(clothW | 0) * +restingDistance / +2) | 0 | 0) | 0 | 0; | |
minHeight = 25; | |
for (y = 0; (y | 0) < (clothH | 0); y = (y | 0) + 1 | 0) { | |
for (x = 0; (x | 0) < (clothW | 0); x = (x | 0) + 1 | 0) { | |
(Point$Point(($SP) | 0 | 0, +(+(minWidth | 0) + +(x | 0) * +restingDistance), +(+(minHeight | 0) + +(y | 0) * +restingDistance), +3, +3, +1, (y | 0 | 0) == 0), F4[($SP) >> 2]); | |
memcpy((((totalSize - globalSP | 0) + 64 | 0) + ((imul(y | 0, clothW | 0) | 0 | 0 | 0) + (x | 0 | 0 | 0) | 0 | 0 | 0) * 44) | 0, ($SP) | 0, 44); | |
} | |
} | |
U4[1] = (U4[1] | 0) + 48; | |
return 0.0; | |
} | |
function memcpy(dest, src, num) { | |
dest = dest|0; src = src|0; num = num|0; | |
var ret = 0; | |
ret = dest|0; | |
if ((dest&3) == (src&3)) { | |
while (dest & 3) { | |
if ((num|0) == 0) return ret|0; | |
U1[(dest)]=U1[(src)]; | |
dest = (dest+1)|0; | |
src = (src+1)|0; | |
num = (num-1)|0; | |
} | |
while ((num|0) >= 4) { | |
U4[((dest)>>2)]=U4[((src)>>2)]; | |
dest = (dest+4)|0; | |
src = (src+4)|0; | |
num = (num-4)|0; | |
} | |
} | |
while ((num|0) > 0) { | |
U1[(dest)]=U1[(src)]; | |
dest = (dest+1)|0; | |
src = (src+1)|0; | |
num = (num-1)|0; | |
} | |
return ret|0; | |
} | |
function memset(ptr, value, num) { | |
ptr = ptr|0; value = value|0; num = num|0; | |
var stop = 0, value4 = 0, stop4 = 0, unaligned = 0; | |
stop = (ptr + num)|0; | |
if ((num|0) >= 20) { | |
// This is unaligned, but quite large, so work hard to get to aligned settings | |
value = value & 0xff; | |
unaligned = ptr & 3; | |
value4 = value | (value << 8) | (value << 16) | (value << 24); | |
stop4 = stop & ~3; | |
if (unaligned) { | |
unaligned = (ptr + 4 - unaligned)|0; | |
while ((ptr|0) < (unaligned|0)) { // no need to check for stop, since we have large num | |
U1[(ptr)]=value; | |
ptr = (ptr+1)|0; | |
} | |
} | |
while ((ptr|0) < (stop4|0)) { | |
U4[((ptr)>>2)]=value4; | |
ptr = (ptr+4)|0; | |
} | |
} | |
while ((ptr|0) < (stop|0)) { | |
U1[(ptr)]=value; | |
ptr = (ptr+1)|0; | |
} | |
} | |
return { update: update, | |
render: render, | |
main: main }; | |
})({ Uint8Array: Uint8Array, | |
Int8Array: Int8Array, | |
Uint16Array: Uint16Array, | |
Int16Array: Int16Array, | |
Uint32Array: Uint32Array, | |
Int32Array: Int32Array, | |
Float32Array: Float32Array, | |
Float64Array: Float64Array, | |
Math: Math }, | |
{ clear: clear, | |
fillRect: fillRect, | |
renderLine: renderLine, | |
print: print, | |
HEAP_SIZE: HEAP_SIZE, | |
STACK_SIZE: STACK_SIZE, | |
TOTAL_SIZE: SIZE }, | |
buffer); | |
function assertEqual(val1, val2) { | |
var err = true; | |
var msg; | |
if(val1 | 0 !== val1) { | |
if(Math.abs(val1 - val2) < .00000001) { | |
err = false; | |
} | |
else { | |
msg = 'eps'; | |
} | |
} | |
else if(val1 === val2) { | |
err = false; | |
} | |
if(err) { | |
throw new Error(val1 + ' does not equal ' + val2); | |
} | |
} | |
function _print(/* arg1, arg2, ..., argN */) { | |
var func = ((typeof console !== 'undefined' && console.log) || print); | |
func.apply(null, arguments); | |
} | |
var _time; | |
function start() { | |
_time = Date.now(); | |
} | |
function end() { | |
return Date.now() - _time; | |
} | |
window.verlet = asm; | |
})(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment