Created
October 10, 2010 18:02
-
-
Save einaros/619421 to your computer and use it in GitHub Desktop.
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 () { | |
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