mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 10:37:34 +00:00
first attempt of implmenting asm style box2d engine
This commit is contained in:
parent
ebf167107a
commit
cca3a258ba
12 changed files with 12255 additions and 10876 deletions
|
|
@ -57,13 +57,13 @@ function(Parent, Nc, Parser, Settings) {
|
||||||
this.player.doll.updatePositionState(update);
|
this.player.doll.updatePositionState(update);
|
||||||
} else {
|
} else {
|
||||||
// HARD UPDATE FOR SELF
|
// HARD UPDATE FOR SELF
|
||||||
console.log(this.player.user.options.nickname + ' is cheating.')
|
console.log(this.player.user.options.nickname + ' is cheating. difference:', difference);
|
||||||
|
|
||||||
var body = this.player.doll.body;
|
var body = this.player.doll.body;
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
p: body.GetPosition(),
|
p: body.GetPosition().Copy(),
|
||||||
lv: body.GetLinearVelocity()
|
lv: body.GetLinearVelocity().Copy()
|
||||||
};
|
};
|
||||||
|
|
||||||
Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + this.player.id, 'positionStateReset', options);
|
Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + this.player.id, 'positionStateReset', options);
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,9 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N
|
||||||
}
|
}
|
||||||
|
|
||||||
GameController.prototype.onLevelLoaded = function() {
|
GameController.prototype.onLevelLoaded = function() {
|
||||||
|
console.log("onLevelLoaded updateWorld pre")
|
||||||
this.updateWorld();
|
this.updateWorld();
|
||||||
|
console.log("onLevelLoaded updateWorld post")
|
||||||
};
|
};
|
||||||
|
|
||||||
GameController.prototype.onUserJoined = function (user) {
|
GameController.prototype.onUserJoined = function (user) {
|
||||||
|
|
@ -115,20 +117,22 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N
|
||||||
getSleeping = getSleeping || false;
|
getSleeping = getSleeping || false;
|
||||||
|
|
||||||
var update = {};
|
var update = {};
|
||||||
|
|
||||||
var body = this.physicsEngine.world.GetBodyList();
|
var body = this.physicsEngine.world.GetBodyList();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
if((getSleeping || body.IsAwake()) && body.GetType() === Box2D.Dynamics.b2Body.b2_dynamicBody) {
|
if((getSleeping || body.IsAwake()) && body.GetType() === Box2D.Dynamics.b2Body.b2_dynamicBody) {
|
||||||
var userData = body.GetUserData();
|
var userData = body.GetUserData();
|
||||||
|
|
||||||
|
|
||||||
if (userData instanceof GameObject) {
|
if (userData instanceof GameObject) {
|
||||||
var gameObject = userData;
|
var gameObject = userData;
|
||||||
|
|
||||||
update[gameObject.uid] = {
|
update[gameObject.uid] = {
|
||||||
p: body.GetPosition(),
|
p: body.GetPosition().Copy(),
|
||||||
a: body.GetAngle(),
|
a: body.GetAngle(),
|
||||||
lv: body.GetLinearVelocity(),
|
lv: body.GetLinearVelocity().Copy(),
|
||||||
av: body.GetAngularVelocity()
|
av: body.GetAngularVelocity().Copy()
|
||||||
};
|
};
|
||||||
|
|
||||||
if(gameObject instanceof Doll) {
|
if(gameObject instanceof Doll) {
|
||||||
|
|
@ -138,6 +142,12 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Settings.USE_ASM) {
|
||||||
|
if(body.GetNext() == body) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} while (body = body.GetNext());
|
} while (body = body.GetNext());
|
||||||
|
|
||||||
return update;
|
return update;
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,12 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Settings.USE_ASM) {
|
||||||
|
if(body.GetNext() == body) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} while (body = body.GetNext());
|
} while (body = body.GetNext());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,12 @@ define(function() {
|
||||||
CANVAS_DOM_ID: 'canvasContainer',
|
CANVAS_DOM_ID: 'canvasContainer',
|
||||||
IS_BROWSER_ENVIRONMENT: typeof window !== 'undefined',
|
IS_BROWSER_ENVIRONMENT: typeof window !== 'undefined',
|
||||||
USE_WEBGL: true,
|
USE_WEBGL: true,
|
||||||
|
USE_ASM: true,
|
||||||
|
|
||||||
// NETWORKING
|
// NETWORKING
|
||||||
NETWORK_UPDATE_INTERVAL: 70,
|
NETWORK_UPDATE_INTERVAL: 70,
|
||||||
CHANNEL_DESTRUCTION_TIME: 30,
|
CHANNEL_DESTRUCTION_TIME: 30,
|
||||||
NETWORK_LOG_INCOMING: false,
|
NETWORK_LOG_INCOMING: true,
|
||||||
NETWORK_LOG_OUTGOING: false,
|
NETWORK_LOG_OUTGOING: false,
|
||||||
NETWORK_LOG_FILTER: ['ping', 'pong', 'worldUpdate', 'lookAt'],
|
NETWORK_LOG_FILTER: ['ping', 'pong', 'worldUpdate', 'lookAt'],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@ function (Parent, Box2D, Settings, Exception, Nc) {
|
||||||
|
|
||||||
var bodyDef = new Box2D.Dynamics.b2BodyDef();
|
var bodyDef = new Box2D.Dynamics.b2BodyDef();
|
||||||
bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody;
|
bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody;
|
||||||
bodyDef.position.x = (this.options.x * Settings.TILE_SIZE + Settings.TILE_SIZE / 2) / Settings.RATIO;
|
|
||||||
bodyDef.position.y = (this.options.y * Settings.TILE_SIZE + Settings.TILE_SIZE / 2) / Settings.RATIO;
|
var x = (this.options.x * Settings.TILE_SIZE + Settings.TILE_SIZE / 2) / Settings.RATIO;
|
||||||
|
var y = (this.options.y * Settings.TILE_SIZE + Settings.TILE_SIZE / 2) / Settings.RATIO;
|
||||||
|
|
||||||
|
bodyDef.position = new Box2D.Common.Math.b2Vec2(x, y);
|
||||||
bodyDef.angle = (this.options.r || 0) * 90 * Math.PI / 180;
|
bodyDef.angle = (this.options.r || 0) * 90 * Math.PI / 180;
|
||||||
|
|
||||||
return bodyDef;
|
return bodyDef;
|
||||||
|
|
@ -31,8 +34,14 @@ function (Parent, Box2D, Settings, Exception, Nc) {
|
||||||
|
|
||||||
Tile.prototype.createPhysicTile = function (tile) {
|
Tile.prototype.createPhysicTile = function (tile) {
|
||||||
var vertices = this.createVertices(tile);
|
var vertices = this.createVertices(tile);
|
||||||
var tileShape = new Box2D.Collision.Shapes.b2PolygonShape();
|
|
||||||
|
var tileShape;
|
||||||
|
if(Settings.USE_ASM) {
|
||||||
|
tileShape = Box2D.createPolygonShape(vertices);
|
||||||
|
} else {
|
||||||
|
tileShape = new Box2D.Collision.Shapes.b2PolygonShape();
|
||||||
tileShape.SetAsArray(vertices, vertices.length);
|
tileShape.SetAsArray(vertices, vertices.length);
|
||||||
|
}
|
||||||
|
|
||||||
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
|
var fixtureDef = new Box2D.Dynamics.b2FixtureDef();
|
||||||
fixtureDef.shape = tileShape;
|
fixtureDef.shape = tileShape;
|
||||||
|
|
|
||||||
10952
app/Lib/Vendor/Box2D.js
vendored
10952
app/Lib/Vendor/Box2D.js
vendored
File diff suppressed because it is too large
Load diff
10866
app/Lib/Vendor/Box2D/Box2D.js
vendored
Executable file
10866
app/Lib/Vendor/Box2D/Box2D.js
vendored
Executable file
File diff suppressed because it is too large
Load diff
537
app/Lib/Vendor/Box2D/asmBox2d.js
vendored
Normal file
537
app/Lib/Vendor/Box2D/asmBox2d.js
vendored
Normal file
File diff suppressed because one or more lines are too long
142
app/Lib/Vendor/Box2D/embox2d-html5canvas-debugDraw.js
vendored
Normal file
142
app/Lib/Vendor/Box2D/embox2d-html5canvas-debugDraw.js
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
|
||||||
|
function drawAxes(ctx) {
|
||||||
|
ctx.strokeStyle = 'rgb(192,0,0)';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, 0);
|
||||||
|
ctx.lineTo(1, 0);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.strokeStyle = 'rgb(0,192,0)';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(0, 0);
|
||||||
|
ctx.lineTo(0, 1);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setColorFromDebugDrawCallback(color) {
|
||||||
|
var col = Box2D.wrapPointer(color, b2Color);
|
||||||
|
var red = (col.get_r() * 255)|0;
|
||||||
|
var green = (col.get_g() * 255)|0;
|
||||||
|
var blue = (col.get_b() * 255)|0;
|
||||||
|
var colStr = red+","+green+","+blue;
|
||||||
|
context.fillStyle = "rgba("+colStr+",0.5)";
|
||||||
|
context.strokeStyle = "rgb("+colStr+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawSegment(vert1, vert2) {
|
||||||
|
var vert1V = Box2D.wrapPointer(vert1, b2Vec2);
|
||||||
|
var vert2V = Box2D.wrapPointer(vert2, b2Vec2);
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(vert1V.get_x(),vert1V.get_y());
|
||||||
|
context.lineTo(vert2V.get_x(),vert2V.get_y());
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawPolygon(vertices, vertexCount, fill) {
|
||||||
|
context.beginPath();
|
||||||
|
for(tmpI=0;tmpI<vertexCount;tmpI++) {
|
||||||
|
var vert = Box2D.wrapPointer(vertices+(tmpI*8), b2Vec2);
|
||||||
|
if ( tmpI == 0 )
|
||||||
|
context.moveTo(vert.get_x(),vert.get_y());
|
||||||
|
else
|
||||||
|
context.lineTo(vert.get_x(),vert.get_y());
|
||||||
|
}
|
||||||
|
context.closePath();
|
||||||
|
if (fill)
|
||||||
|
context.fill();
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawCircle(center, radius, axis, fill) {
|
||||||
|
var centerV = Box2D.wrapPointer(center, b2Vec2);
|
||||||
|
var axisV = Box2D.wrapPointer(axis, b2Vec2);
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.arc(centerV.get_x(),centerV.get_y(), radius, 0, 2 * Math.PI, false);
|
||||||
|
if (fill)
|
||||||
|
context.fill();
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
if (fill) {
|
||||||
|
//render axis marker
|
||||||
|
var vert2V = copyVec2(centerV);
|
||||||
|
vert2V.op_add( scaledVec2(axisV, radius) );
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(centerV.get_x(),centerV.get_y());
|
||||||
|
context.lineTo(vert2V.get_x(),vert2V.get_y());
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawTransform(transform) {
|
||||||
|
var trans = Box2D.wrapPointer(transform,b2Transform);
|
||||||
|
var pos = trans.get_p();
|
||||||
|
var rot = trans.get_q();
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
context.translate(pos.get_x(), pos.get_y());
|
||||||
|
context.scale(0.5,0.5);
|
||||||
|
context.rotate(rot.GetAngle());
|
||||||
|
context.lineWidth *= 2;
|
||||||
|
drawAxes(context);
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCanvasDebugDraw() {
|
||||||
|
var debugDraw = new Box2D.b2Draw();
|
||||||
|
|
||||||
|
Box2D.customizeVTable(debugDraw, [{
|
||||||
|
original: Box2D.b2Draw.prototype.DrawSegment,
|
||||||
|
replacement:
|
||||||
|
function(ths, vert1, vert2, color) {
|
||||||
|
setColorFromDebugDrawCallback(color);
|
||||||
|
drawSegment(vert1, vert2);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
Box2D.customizeVTable(debugDraw, [{
|
||||||
|
original: Box2D.b2Draw.prototype.DrawPolygon,
|
||||||
|
replacement:
|
||||||
|
function(ths, vertices, vertexCount, color) {
|
||||||
|
setColorFromDebugDrawCallback(color);
|
||||||
|
drawPolygon(vertices, vertexCount, false);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
Box2D.customizeVTable(debugDraw, [{
|
||||||
|
original: Box2D.b2Draw.prototype.DrawSolidPolygon,
|
||||||
|
replacement:
|
||||||
|
function(ths, vertices, vertexCount, color) {
|
||||||
|
setColorFromDebugDrawCallback(color);
|
||||||
|
drawPolygon(vertices, vertexCount, true);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
Box2D.customizeVTable(debugDraw, [{
|
||||||
|
original: Box2D.b2Draw.prototype.DrawCircle,
|
||||||
|
replacement:
|
||||||
|
function(ths, center, radius, color) {
|
||||||
|
setColorFromDebugDrawCallback(color);
|
||||||
|
var dummyAxis = b2Vec2(0,0);
|
||||||
|
drawCircle(center, radius, dummyAxis, false);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
Box2D.customizeVTable(debugDraw, [{
|
||||||
|
original: Box2D.b2Draw.prototype.DrawSolidCircle,
|
||||||
|
replacement:
|
||||||
|
function(ths, center, radius, axis, color) {
|
||||||
|
setColorFromDebugDrawCallback(color);
|
||||||
|
drawCircle(center, radius, axis, true);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
Box2D.customizeVTable(debugDraw, [{
|
||||||
|
original: Box2D.b2Draw.prototype.DrawTransform,
|
||||||
|
replacement:
|
||||||
|
function(ths, transform) {
|
||||||
|
drawTransform(transform);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return debugDraw;
|
||||||
|
}
|
||||||
415
app/Lib/Vendor/Box2D/embox2d-html5canvas-testbed.js
vendored
Normal file
415
app/Lib/Vendor/Box2D/embox2d-html5canvas-testbed.js
vendored
Normal file
|
|
@ -0,0 +1,415 @@
|
||||||
|
|
||||||
|
var PTM = 32;
|
||||||
|
|
||||||
|
var world = null;
|
||||||
|
var mouseJointGroundBody;
|
||||||
|
var canvas;
|
||||||
|
var context;
|
||||||
|
var myDebugDraw;
|
||||||
|
var myQueryCallback;
|
||||||
|
var mouseJoint = null;
|
||||||
|
var run = true;
|
||||||
|
var frameTime60 = 0;
|
||||||
|
var statusUpdateCounter = 0;
|
||||||
|
var showStats = false;
|
||||||
|
var mouseDown = false;
|
||||||
|
var shiftDown = false;
|
||||||
|
var mousePosPixel = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
var prevMousePosPixel = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
var mousePosWorld = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
var canvasOffset = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
var viewCenterPixel = {
|
||||||
|
x:320,
|
||||||
|
y:240
|
||||||
|
};
|
||||||
|
var currentTest = null;
|
||||||
|
|
||||||
|
function myRound(val,places) {
|
||||||
|
var c = 1;
|
||||||
|
for (var i = 0; i < places; i++)
|
||||||
|
c *= 10;
|
||||||
|
return Math.round(val*c)/c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorldPointFromPixelPoint(pixelPoint) {
|
||||||
|
return {
|
||||||
|
x: (pixelPoint.x - canvasOffset.x)/PTM,
|
||||||
|
y: (pixelPoint.y - (canvas.height - canvasOffset.y))/PTM
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMousePos(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
mousePosPixel = {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: canvas.height - (evt.clientY - rect.top)
|
||||||
|
};
|
||||||
|
mousePosWorld = getWorldPointFromPixelPoint(mousePosPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setViewCenterWorld(b2vecpos, instantaneous) {
|
||||||
|
var currentViewCenterWorld = getWorldPointFromPixelPoint( viewCenterPixel );
|
||||||
|
var toMoveX = b2vecpos.get_x() - currentViewCenterWorld.x;
|
||||||
|
var toMoveY = b2vecpos.get_y() - currentViewCenterWorld.y;
|
||||||
|
var fraction = instantaneous ? 1 : 0.25;
|
||||||
|
canvasOffset.x -= myRound(fraction * toMoveX * PTM, 0);
|
||||||
|
canvasOffset.y += myRound(fraction * toMoveY * PTM, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseMove(canvas, evt) {
|
||||||
|
prevMousePosPixel = mousePosPixel;
|
||||||
|
updateMousePos(canvas, evt);
|
||||||
|
updateStats();
|
||||||
|
if ( shiftDown ) {
|
||||||
|
canvasOffset.x += (mousePosPixel.x - prevMousePosPixel.x);
|
||||||
|
canvasOffset.y -= (mousePosPixel.y - prevMousePosPixel.y);
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
else if ( mouseDown && mouseJoint != null ) {
|
||||||
|
mouseJoint.SetTarget( new b2Vec2(mousePosWorld.x, mousePosWorld.y) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startMouseJoint() {
|
||||||
|
|
||||||
|
if ( mouseJoint != null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Make a small box.
|
||||||
|
var aabb = new b2AABB();
|
||||||
|
var d = 0.001;
|
||||||
|
aabb.set_lowerBound(new b2Vec2(mousePosWorld.x - d, mousePosWorld.y - d));
|
||||||
|
aabb.set_upperBound(new b2Vec2(mousePosWorld.x + d, mousePosWorld.y + d));
|
||||||
|
|
||||||
|
// Query the world for overlapping shapes.
|
||||||
|
myQueryCallback.m_fixture = null;
|
||||||
|
myQueryCallback.m_point = new b2Vec2(mousePosWorld.x, mousePosWorld.y);
|
||||||
|
world.QueryAABB(myQueryCallback, aabb);
|
||||||
|
|
||||||
|
if (myQueryCallback.m_fixture)
|
||||||
|
{
|
||||||
|
var body = myQueryCallback.m_fixture.GetBody();
|
||||||
|
var md = new b2MouseJointDef();
|
||||||
|
md.set_bodyA(mouseJointGroundBody);
|
||||||
|
md.set_bodyB(body);
|
||||||
|
md.set_target( new b2Vec2(mousePosWorld.x, mousePosWorld.y) );
|
||||||
|
md.set_maxForce( 1000 * body.GetMass() );
|
||||||
|
md.set_collideConnected(true);
|
||||||
|
|
||||||
|
mouseJoint = Box2D.castObject( world.CreateJoint(md), b2MouseJoint );
|
||||||
|
body.SetAwake(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseDown(canvas, evt) {
|
||||||
|
updateMousePos(canvas, evt);
|
||||||
|
if ( !mouseDown )
|
||||||
|
startMouseJoint();
|
||||||
|
mouseDown = true;
|
||||||
|
updateStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseUp(canvas, evt) {
|
||||||
|
mouseDown = false;
|
||||||
|
updateMousePos(canvas, evt);
|
||||||
|
updateStats();
|
||||||
|
if ( mouseJoint != null ) {
|
||||||
|
world.DestroyJoint(mouseJoint);
|
||||||
|
mouseJoint = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseOut(canvas, evt) {
|
||||||
|
onMouseUp(canvas,evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyDown(canvas, evt) {
|
||||||
|
//console.log(evt.keyCode);
|
||||||
|
if ( evt.keyCode == 80 ) {//p
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 82 ) {//r
|
||||||
|
resetScene();
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 83 ) {//s
|
||||||
|
step();
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 88 ) {//x
|
||||||
|
zoomIn();
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 90 ) {//z
|
||||||
|
zoomOut();
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 37 ) {//left
|
||||||
|
canvasOffset.x += 32;
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 39 ) {//right
|
||||||
|
canvasOffset.x -= 32;
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 38 ) {//up
|
||||||
|
canvasOffset.y += 32;
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 40 ) {//down
|
||||||
|
canvasOffset.y -= 32;
|
||||||
|
}
|
||||||
|
else if ( evt.keyCode == 16 ) {//shift
|
||||||
|
shiftDown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currentTest && currentTest.onKeyDown )
|
||||||
|
currentTest.onKeyDown(canvas, evt);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyUp(canvas, evt) {
|
||||||
|
if ( evt.keyCode == 16 ) {//shift
|
||||||
|
shiftDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( currentTest && currentTest.onKeyUp )
|
||||||
|
currentTest.onKeyUp(canvas, evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoomIn() {
|
||||||
|
var currentViewCenterWorld = getWorldPointFromPixelPoint( viewCenterPixel );
|
||||||
|
PTM *= 1.1;
|
||||||
|
var newViewCenterWorld = getWorldPointFromPixelPoint( viewCenterPixel );
|
||||||
|
canvasOffset.x += (newViewCenterWorld.x-currentViewCenterWorld.x) * PTM;
|
||||||
|
canvasOffset.y -= (newViewCenterWorld.y-currentViewCenterWorld.y) * PTM;
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoomOut() {
|
||||||
|
var currentViewCenterWorld = getWorldPointFromPixelPoint( viewCenterPixel );
|
||||||
|
PTM /= 1.1;
|
||||||
|
var newViewCenterWorld = getWorldPointFromPixelPoint( viewCenterPixel );
|
||||||
|
canvasOffset.x += (newViewCenterWorld.x-currentViewCenterWorld.x) * PTM;
|
||||||
|
canvasOffset.y -= (newViewCenterWorld.y-currentViewCenterWorld.y) * PTM;
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDebugDrawCheckboxesFromWorld() {
|
||||||
|
var flags = myDebugDraw.GetFlags();
|
||||||
|
document.getElementById('drawShapesCheck').checked = (( flags & e_shapeBit ) != 0);
|
||||||
|
document.getElementById('drawJointsCheck').checked = (( flags & e_jointBit ) != 0);
|
||||||
|
document.getElementById('drawAABBsCheck').checked = (( flags & e_aabbBit ) != 0);
|
||||||
|
//document.getElementById('drawPairsCheck').checked = (( flags & e_pairBit ) != 0);
|
||||||
|
document.getElementById('drawTransformsCheck').checked = (( flags & e_centerOfMassBit ) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateWorldFromDebugDrawCheckboxes() {
|
||||||
|
var flags = 0;
|
||||||
|
if ( document.getElementById('drawShapesCheck').checked )
|
||||||
|
flags |= e_shapeBit;
|
||||||
|
if ( document.getElementById('drawJointsCheck').checked )
|
||||||
|
flags |= e_jointBit;
|
||||||
|
if ( document.getElementById('drawAABBsCheck').checked )
|
||||||
|
flags |= e_aabbBit;
|
||||||
|
/*if ( document.getElementById('drawPairsCheck').checked )
|
||||||
|
flags |= e_pairBit;*/
|
||||||
|
if ( document.getElementById('drawTransformsCheck').checked )
|
||||||
|
flags |= e_centerOfMassBit;
|
||||||
|
myDebugDraw.SetFlags( flags );
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateContinuousRefreshStatus() {
|
||||||
|
showStats = ( document.getElementById('showStatsCheck').checked );
|
||||||
|
if ( !showStats ) {
|
||||||
|
var fbSpan = document.getElementById('feedbackSpan');
|
||||||
|
fbSpan.innerHTML = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
updateStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
|
||||||
|
canvas = document.getElementById("canvas");
|
||||||
|
context = canvas.getContext( '2d' );
|
||||||
|
|
||||||
|
canvasOffset.x = canvas.width/2;
|
||||||
|
canvasOffset.y = canvas.height/2;
|
||||||
|
|
||||||
|
canvas.addEventListener('mousemove', function(evt) {
|
||||||
|
onMouseMove(canvas,evt);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
canvas.addEventListener('mousedown', function(evt) {
|
||||||
|
onMouseDown(canvas,evt);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
canvas.addEventListener('mouseup', function(evt) {
|
||||||
|
onMouseUp(canvas,evt);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
canvas.addEventListener('mouseout', function(evt) {
|
||||||
|
onMouseOut(canvas,evt);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
canvas.addEventListener('keydown', function(evt) {
|
||||||
|
onKeyDown(canvas,evt);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
canvas.addEventListener('keyup', function(evt) {
|
||||||
|
onKeyUp(canvas,evt);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
myDebugDraw = getCanvasDebugDraw();
|
||||||
|
myDebugDraw.SetFlags(e_shapeBit);
|
||||||
|
|
||||||
|
myQueryCallback = new b2QueryCallback();
|
||||||
|
|
||||||
|
Box2D.customizeVTable(myQueryCallback, [{
|
||||||
|
original: Box2D.b2QueryCallback.prototype.ReportFixture,
|
||||||
|
replacement:
|
||||||
|
function(thsPtr, fixturePtr) {
|
||||||
|
var ths = Box2D.wrapPointer( thsPtr, b2QueryCallback );
|
||||||
|
var fixture = Box2D.wrapPointer( fixturePtr, b2Fixture );
|
||||||
|
if ( fixture.GetBody().GetType() != Box2D.b2_dynamicBody ) //mouse cannot drag static bodies around
|
||||||
|
return true;
|
||||||
|
if ( ! fixture.TestPoint( ths.m_point ) )
|
||||||
|
return true;
|
||||||
|
ths.m_fixture = fixture;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeTest() {
|
||||||
|
resetScene();
|
||||||
|
if ( currentTest && currentTest.setNiceViewCenter )
|
||||||
|
currentTest.setNiceViewCenter();
|
||||||
|
updateDebugDrawCheckboxesFromWorld();
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWorld() {
|
||||||
|
|
||||||
|
if ( world != null )
|
||||||
|
Box2D.destroy(world);
|
||||||
|
|
||||||
|
world = new b2World( new b2Vec2(0.0, -10.0) );
|
||||||
|
world.SetDebugDraw(myDebugDraw);
|
||||||
|
|
||||||
|
mouseJointGroundBody = world.CreateBody( new b2BodyDef() );
|
||||||
|
|
||||||
|
var e = document.getElementById("testSelection");
|
||||||
|
var v = e.options[e.selectedIndex].value;
|
||||||
|
|
||||||
|
eval( "currentTest = new "+v+"();" );
|
||||||
|
|
||||||
|
currentTest.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetScene() {
|
||||||
|
createWorld();
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function step(timestamp) {
|
||||||
|
|
||||||
|
if ( currentTest && currentTest.step )
|
||||||
|
currentTest.step();
|
||||||
|
|
||||||
|
if ( ! showStats ) {
|
||||||
|
world.Step(1/60, 3, 2);
|
||||||
|
draw();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var current = Date.now();
|
||||||
|
world.Step(1/60, 3, 2);
|
||||||
|
var frametime = (Date.now() - current);
|
||||||
|
frameTime60 = frameTime60 * (59/60) + frametime * (1/60);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
statusUpdateCounter++;
|
||||||
|
if ( statusUpdateCounter > 20 ) {
|
||||||
|
updateStats();
|
||||||
|
statusUpdateCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
|
||||||
|
//black background
|
||||||
|
context.fillStyle = 'rgb(0,0,0)';
|
||||||
|
context.fillRect( 0, 0, canvas.width, canvas.height );
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
context.translate(canvasOffset.x, canvasOffset.y);
|
||||||
|
context.scale(1,-1);
|
||||||
|
context.scale(PTM,PTM);
|
||||||
|
context.lineWidth /= PTM;
|
||||||
|
|
||||||
|
drawAxes(context);
|
||||||
|
|
||||||
|
context.fillStyle = 'rgb(255,255,0)';
|
||||||
|
world.DrawDebugData();
|
||||||
|
|
||||||
|
if ( mouseJoint != null ) {
|
||||||
|
//mouse joint is not drawn with regular joints in debug draw
|
||||||
|
var p1 = mouseJoint.GetAnchorB();
|
||||||
|
var p2 = mouseJoint.GetTarget();
|
||||||
|
context.strokeStyle = 'rgb(204,204,204)';
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(p1.get_x(),p1.get_y());
|
||||||
|
context.lineTo(p2.get_x(),p2.get_y());
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStats() {
|
||||||
|
if ( ! showStats )
|
||||||
|
return;
|
||||||
|
var currentViewCenterWorld = getWorldPointFromPixelPoint( viewCenterPixel );
|
||||||
|
var fbSpan = document.getElementById('feedbackSpan');
|
||||||
|
fbSpan.innerHTML =
|
||||||
|
"Status: "+(run?'running':'paused') +
|
||||||
|
"<br>Physics step time (average of last 60 steps): "+myRound(frameTime60,2)+"ms" +
|
||||||
|
//"<br>Mouse down: "+mouseDown +
|
||||||
|
"<br>PTM: "+myRound(PTM,2) +
|
||||||
|
"<br>View center: "+myRound(currentViewCenterWorld.x,3)+", "+myRound(currentViewCenterWorld.y,3) +
|
||||||
|
//"<br>Canvas offset: "+myRound(canvasOffset.x,0)+", "+myRound(canvasOffset.y,0) +
|
||||||
|
"<br>Mouse pos (pixel): "+mousePosPixel.x+", "+mousePosPixel.y +
|
||||||
|
"<br>Mouse pos (world): "+myRound(mousePosWorld.x,3)+", "+myRound(mousePosWorld.y,3);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestAnimFrame = (function(){
|
||||||
|
return window.requestAnimationFrame ||
|
||||||
|
window.webkitRequestAnimationFrame ||
|
||||||
|
window.mozRequestAnimationFrame ||
|
||||||
|
window.oRequestAnimationFrame ||
|
||||||
|
window.msRequestAnimationFrame ||
|
||||||
|
function( callback ){
|
||||||
|
window.setTimeout(callback, 1000 / 60);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
if ( run )
|
||||||
|
requestAnimFrame( animate );
|
||||||
|
step();
|
||||||
|
}
|
||||||
|
|
||||||
|
function pause() {
|
||||||
|
run = !run;
|
||||||
|
if (run)
|
||||||
|
animate();
|
||||||
|
updateStats();
|
||||||
|
}
|
||||||
106
app/Lib/Vendor/Box2D/helpers.js
vendored
Normal file
106
app/Lib/Vendor/Box2D/helpers.js
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
define([
|
||||||
|
"Lib/Vendor/Box2D/asmBox2d"
|
||||||
|
],
|
||||||
|
|
||||||
|
function () {
|
||||||
|
|
||||||
|
//Having to type 'Box2D.' in front of everything makes porting
|
||||||
|
//existing C++ code a pain in the butt. This function can be used
|
||||||
|
//to make everything in the Box2D namespace available without
|
||||||
|
//needing to do that.
|
||||||
|
var using = function (ns, pattern) {
|
||||||
|
if (pattern == undefined) {
|
||||||
|
// import all
|
||||||
|
for (var name in ns) {
|
||||||
|
this[name] = ns[name];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof(pattern) == 'string') {
|
||||||
|
pattern = new RegExp(pattern);
|
||||||
|
}
|
||||||
|
// import only stuff matching given pattern
|
||||||
|
for (var name in ns) {
|
||||||
|
if (name.match(pattern)) {
|
||||||
|
this[name] = ns[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var e_shapeBit = 0x0001;
|
||||||
|
var e_jointBit = 0x0002;
|
||||||
|
var e_aabbBit = 0x0004;
|
||||||
|
var e_pairBit = 0x0008;
|
||||||
|
var e_centerOfMassBit = 0x0010;
|
||||||
|
|
||||||
|
|
||||||
|
//to replace original C++ operator =
|
||||||
|
function copyVec2(vec) {
|
||||||
|
return new b2Vec2(vec.get_x(), vec.get_y());
|
||||||
|
}
|
||||||
|
|
||||||
|
//to replace original C++ operator * (float)
|
||||||
|
function scaleVec2(vec, scale) {
|
||||||
|
vec.set_x( scale * vec.get_x() );
|
||||||
|
vec.set_y( scale * vec.get_y() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//to replace original C++ operator *= (float)
|
||||||
|
function scaledVec2(vec, scale) {
|
||||||
|
return new b2Vec2(scale * vec.get_x(), scale * vec.get_y());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// http://stackoverflow.com/questions/12792486/emscripten-bindings-how-to-create-an-accessible-c-c-array-from-javascript
|
||||||
|
function createChainShape(vertices, closedLoop) {
|
||||||
|
var shape = new b2ChainShape();
|
||||||
|
var buffer = Box2D.allocate(vertices.length * 8, 'float', Box2D.ALLOC_STACK);
|
||||||
|
var offset = 0;
|
||||||
|
for (var i=0;i<vertices.length;i++) {
|
||||||
|
Box2D.setValue(buffer+(offset), vertices[i].get_x(), 'float'); // x
|
||||||
|
Box2D.setValue(buffer+(offset+4), vertices[i].get_y(), 'float'); // y
|
||||||
|
offset += 8;
|
||||||
|
}
|
||||||
|
var ptr_wrapped = Box2D.wrapPointer(buffer, Box2D.b2Vec2);
|
||||||
|
if ( closedLoop )
|
||||||
|
shape.CreateLoop(ptr_wrapped, vertices.length);
|
||||||
|
else
|
||||||
|
shape.CreateChain(ptr_wrapped, vertices.length);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPolygonShape(vertices) {
|
||||||
|
var shape = new b2PolygonShape();
|
||||||
|
var buffer = Box2D.allocate(vertices.length * 8, 'float', Box2D.ALLOC_STACK);
|
||||||
|
var offset = 0;
|
||||||
|
for (var i=0;i<vertices.length;i++) {
|
||||||
|
Box2D.setValue(buffer+(offset), vertices[i].get_x(), 'float'); // x
|
||||||
|
Box2D.setValue(buffer+(offset+4), vertices[i].get_y(), 'float'); // y
|
||||||
|
offset += 8;
|
||||||
|
}
|
||||||
|
var ptr_wrapped = Box2D.wrapPointer(buffer, Box2D.b2Vec2);
|
||||||
|
shape.Set(ptr_wrapped, vertices.length);
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRandomPolygonShape(radius) {
|
||||||
|
var numVerts = 3.5 + Math.random() * 5;
|
||||||
|
numVerts = numVerts | 0;
|
||||||
|
var verts = [];
|
||||||
|
for (var i = 0; i < numVerts; i++) {
|
||||||
|
var angle = i / numVerts * 360.0 * 0.0174532925199432957;
|
||||||
|
verts.push( new b2Vec2( radius * Math.sin(angle), radius * -Math.cos(angle) ) );
|
||||||
|
}
|
||||||
|
return createPolygonShape(verts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
createPolygonShape: createPolygonShape,
|
||||||
|
createChainShape: createChainShape,
|
||||||
|
createRandomPolygonShape: createRandomPolygonShape,
|
||||||
|
scaleVec2: scaleVec2,
|
||||||
|
scaledVec2: scaledVec2,
|
||||||
|
copyVec2: copyVec2,
|
||||||
|
using: using
|
||||||
|
};
|
||||||
|
});
|
||||||
5
app/Lib/Vendor/Box2D/test.js
vendored
Normal file
5
app/Lib/Vendor/Box2D/test.js
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
function test() {
|
||||||
|
console.log('my test')
|
||||||
|
}
|
||||||
|
|
||||||
|
var test2 = 'test2';
|
||||||
Loading…
Add table
Add a link
Reference in a new issue