Skip to content

Instantly share code, notes, and snippets.

@einaros
Created October 10, 2010 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save einaros/619421 to your computer and use it in GitHub Desktop.
Save einaros/619421 to your computer and use it in GitHub Desktop.
(function () {
function getBodyAtXY(world, x, y, includeStatic) {
var pos = new b2Vec2();
pos.Set(x, y);
var aabb = new b2AABB();
aabb.lowerBound.Set(x - 0.001, y - 0.001);
aabb.upperBound.Set(x + 0.001, y + 0.001);
var maxShapes = 10;
var shapes = [];
var count = world.Query(aabb, shapes, maxShapes);
for (var i = 0; i < count; ++i) {
if (shapes[i].GetBody().IsStatic() == false || includeStatic) {
var tShape = shapes[i];
var inside = tShape.TestPoint(tShape.GetBody().GetXForm(), pos);
if (inside) {
return tShape.GetBody();
}
}
}
return null;
}
function makeMouseClickHandler(world) {
return function mouseClickHandler(e) {
e.preventDefault();
var x = e.pageX;
var y = e.pageY;
var mouseJoint = null;
var body = getBodyAtXY(world, x, y, false);
if (body) {
var md = new b2MouseJointDef();
md.body1 = world.GetGroundBody();
md.body2 = body;
md.target.Set(x, y);
md.maxForce = 10000.0 * body.GetMass();
md.timeStep = 1.0 / 20.0;
mouseJoint = world.CreateJoint(md);
body.WakeUp();
$(window).bind("mousemove.drag", function (e) {
e.preventDefault();
var p2 = new b2Vec2(e.pageX, e.pageY);
mouseJoint.SetTarget(p2);
}).bind("mouseup.drag", function (e) {
e.preventDefault();
world.DestroyJoint(mouseJoint);
mouseJoint = null;
$(window).unbind(".drag");
});
}
}
}
function makeVideoTile(world, video, sourceX, sourceY, w, h, x, y) {
var bodyDef = new b2BodyDef();
bodyDef.position.Set(x, y);
var body = world.CreateBody(bodyDef);
var shapeDef = new b2PolygonDef();
body.w = w;
body.h = h;
shapeDef.SetAsBox(body.w / 2, body.h / 2);
shapeDef.restitution = 1.0;
shapeDef.density = 1.0;
shapeDef.friction = 10.0;
body.CreateShape(shapeDef);
body.SetMassFromShapes();
return {
render: function (g) {
var t = body.m_xf;
g.save();
g.translate(t.position.x, t.position.y);
g.rotate(body.GetAngle());
g.translate(-(w / 2), -(h / 2));
g.drawImage(video, sourceX, sourceY, w, h, 0, 0, w, h);
g.restore();
},
body: body
};
}
function makeGroundElement(world, x, y, w, h) {
var bodyDef = new b2BodyDef();
bodyDef.position.Set(x, y);
var body = world.CreateBody(bodyDef);
var groundShapeDef = new b2PolygonDef();
groundShapeDef.restitution = 0.0;
groundShapeDef.friction = 10.0;
groundShapeDef.density = 1.0;
body.w = w;
body.h = h;
groundShapeDef.SetAsBox(body.w / 2, body.h / 2);
body.CreateShape(groundShapeDef);
body.SynchronizeShapes();
}
function setup(video) {
var theCanvas = $(document.createElement("canvas")).css({
position: "absolute",
top: 0,
left: 0
}).attr("width", $(window).width()).attr("height", $(window).height());
$("body").append(theCanvas);
var ctx = theCanvas[0].getContext("2d");
var width = $(window).width();
var height = $(window).height();
var c_width = width;
var c_height = height;
var worldAABB = new b2AABB();
worldAABB.lowerBound.Set(-100000.0, -100000.0);
worldAABB.upperBound.Set(100000.0, 100000.0);
var gravity = new b2Vec2(0, 0);
var world = new b2World(worldAABB, gravity, true);
var bodyElements = [];
theCanvas.mousedown(makeMouseClickHandler(world));
// Build walls around the window
makeGroundElement(world, c_width / 2, -2.5, c_width, 5);
makeGroundElement(world, c_width / 2, c_height + 2.5, c_width, 5);
makeGroundElement(world, -2.5, c_height / 2, 5, c_height);
makeGroundElement(world, c_width + 2.5, c_height / 2, 5, c_height);
// Rip the video element into pieces
var offsetX = width - video.videoWidth;
var offsetY = height - video.videoHeight;
var piecesH = 10;
var piecesW = 10;
var dy = video.videoHeight / piecesH;
var dx = video.videoWidth / piecesW;
for (var y = 0; y < piecesH; ++y) {
for (var x = 0; x < piecesW; ++x) {
bodyElements.push(
makeVideoTile(world, video, x * dx, y * dy, dx, dy, offsetX + x * dx, offsetY + y * dy));
}
}
// Render loop
setInterval(function () {
world.Step(1.0 / 20.0, 10);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
for (var i = 0; i < bodyElements.length; ++i) {
bodyElements[i].render(ctx);
}
}, 33);
}
$(function () {
$("video:first").bind("play", function () {
setup($("video")[0]);
});
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment