├── LICENSE.txt ├── README.md ├── blank.svg ├── demos ├── compound.js ├── crank.js ├── demo_base.js ├── demos.js ├── draw_world.js ├── drop.js ├── pendulum.js ├── stack.js └── top.js ├── images └── yarada.jpg ├── index.html ├── js └── box2d │ ├── collision │ ├── ClipVertex.js │ ├── Features.js │ ├── b2AABB.js │ ├── b2Bound.js │ ├── b2BoundValues.js │ ├── b2BroadPhase.js │ ├── b2BufferedPair.js │ ├── b2Collision.js │ ├── b2ContactID.js │ ├── b2ContactPoint.js │ ├── b2Distance.js │ ├── b2Manifold.js │ ├── b2OBB.js │ ├── b2Pair.js │ ├── b2PairCallback.js │ ├── b2PairManager.js │ ├── b2Proxy.js │ └── shapes │ │ ├── b2BoxDef.js │ │ ├── b2CircleDef.js │ │ ├── b2CircleShape.js │ │ ├── b2MassData.js │ │ ├── b2PolyDef.js │ │ ├── b2PolyShape.js │ │ ├── b2Shape.js │ │ └── b2ShapeDef.js │ ├── common │ ├── b2Settings.js │ └── math │ │ ├── b2Mat22.js │ │ ├── b2Math.js │ │ └── b2Vec2.js │ └── dynamics │ ├── b2Body.js │ ├── b2BodyDef.js │ ├── b2CollisionFilter.js │ ├── b2ContactManager.js │ ├── b2Island.js │ ├── b2TimeStep.js │ ├── b2World.js │ ├── b2WorldListener.js │ ├── contacts │ ├── b2CircleContact.js │ ├── b2Conservative.js │ ├── b2Contact.js │ ├── b2ContactConstraint.js │ ├── b2ContactConstraintPoint.js │ ├── b2ContactNode.js │ ├── b2ContactRegister.js │ ├── b2ContactSolver.js │ ├── b2NullContact.js │ ├── b2PolyAndCircleContact.js │ └── b2PolyContact.js │ └── joints │ ├── b2DistanceJoint.js │ ├── b2DistanceJointDef.js │ ├── b2GearJoint.js │ ├── b2GearJointDef.js │ ├── b2Jacobian.js │ ├── b2Joint.js │ ├── b2JointDef.js │ ├── b2JointNode.js │ ├── b2MouseJoint.js │ ├── b2MouseJointDef.js │ ├── b2PrismaticJoint.js │ ├── b2PrismaticJointDef.js │ ├── b2PulleyJoint.js │ ├── b2PulleyJointDef.js │ ├── b2RevoluteJoint.js │ ├── b2RevoluteJointDef.js │ ├── b2SpringJoint.js │ └── b2SpringJointDef.js ├── lib ├── box2d.js └── jquery.svg.min.js ├── old_index.html └── style └── box2d.css /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The zlib/libpng License 2 | 3 | Copyright (c) 2008 ANDO Yasushi 4 | 5 | This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 8 | 9 | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 10 | 11 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 12 | 13 | 3. This notice may not be removed or altered from any source distribution. 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Screenshot](http://lavadip.com/experiments/box2d_thumb.png) 2 | 3 | ## [Demo](http://lavadip.com/experiments/box2d_demo/) 4 | 5 | ## About this fork 6 | 7 | The original box2d-js library is hosted on [sourceforge](http://box2d-js.sourceforge.net/). It seems to be currently unmaintained and uses the HTML5 Canvas element for display. 8 | 9 | This fork has the following changes over the original: 10 | 11 | #### New features 12 | * Spring Joint (simple version, suitable for simulation of soft bodies) 13 | 14 | #### Code Optimisations 15 | * Removed dependency on prototype.js 16 | * Simple optimisations to core library 17 | * Avoid frequent instantiations of b2Vec2 18 | 19 | ## Features in the demo 20 | 21 | * Use of SVGs instead of Canvas 22 | * Using jquery and jquery.svg 23 | * only create a shape for the first time, then use transformations 24 | * if static or sleeping then don't redraw 25 | 26 | * throttling of step size and inter-frame delays, to achieve a target FPS. 27 | * a new demo scene called `drop` to show off spring-joints. 28 | -------------------------------------------------------------------------------- /blank.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /demos/compound.js: -------------------------------------------------------------------------------- 1 | demos.compound = {}; 2 | demos.compound.createCompoundBall = function(world, x, y) { 3 | var ballSd1 = new b2CircleDef(); 4 | ballSd1.density = 1.0; 5 | ballSd1.radius = 20; 6 | ballSd1.restitution = 0.2; 7 | ballSd1.localPosition.Set(-20, 0); 8 | var ballSd2 = new b2CircleDef(); 9 | ballSd2.density = 1.0; 10 | ballSd2.radius = 20; 11 | ballSd2.restitution = 0.2; 12 | ballSd2.localPosition.Set(20, 0); 13 | var ballBd = new b2BodyDef(); 14 | ballBd.AddShape(ballSd1); 15 | ballBd.AddShape(ballSd2); 16 | ballBd.position.Set(x, y); 17 | return world.CreateBody(ballBd); 18 | } 19 | 20 | demos.compound.createCompoundPoly = function(world, x, y) { 21 | var points = [[-30, 0], [30, 0], [0, 15]]; 22 | var polySd1 = new b2PolyDef(); 23 | polySd1.vertexCount = points.length; 24 | for (var i = 0; i < points.length; i++) { 25 | polySd1.vertices[i].Set(points[i][0], points[i][1]); 26 | } 27 | polySd1.localRotation = 0.3524 * Math.PI; 28 | var R1 = new b2Mat22(polySd1.localRotation); 29 | polySd1.localPosition = b2Math.b2MulMV(R1, new b2Vec2(30, 0)); 30 | polySd1.density = 1.0; 31 | var polySd2 = new b2PolyDef(); 32 | polySd2.vertexCount = points.length; 33 | for (var i = 0; i < points.length; i++) { 34 | polySd2.vertices[i].Set(points[i][0], points[i][1]); 35 | } 36 | polySd2.localRotation = -0.3524 * Math.PI; 37 | var R2 = new b2Mat22(polySd2.localRotation); 38 | polySd2.localPosition = b2Math.b2MulMV(R2, new b2Vec2(-30, 0)); 39 | var polyBd = new b2BodyDef(); 40 | polyBd.AddShape(polySd1); 41 | polyBd.AddShape(polySd2); 42 | polyBd.position.Set(x,y); 43 | return world.CreateBody(polyBd) 44 | } 45 | 46 | demos.compound.initWorld = function(world) { 47 | var i; 48 | for (i = 1; i <= 8; i++) { 49 | demos.compound.createCompoundPoly(world, 150 + 3 * Math.random(), 40 * i); 50 | } 51 | for (i = 1; i <= 8; i++) { 52 | demos.compound.createCompoundBall(world, 350 + 3 * Math.random(), 45 * i); 53 | } 54 | } 55 | demos.InitWorlds.push(demos.compound.initWorld); 56 | 57 | 58 | -------------------------------------------------------------------------------- /demos/crank.js: -------------------------------------------------------------------------------- 1 | demos.crank = {}; 2 | demos.crank.initWorld = function(world) { 3 | var ground = world.m_groundBody; 4 | 5 | // Define crank. 6 | var sd = new b2BoxDef(); 7 | sd.extents.Set(5, 25); 8 | sd.density = 1.0; 9 | 10 | var bd = new b2BodyDef(); 11 | bd.AddShape(sd); 12 | 13 | var rjd = new b2RevoluteJointDef(); 14 | 15 | var prevBody = ground; 16 | 17 | bd.position.Set(600/2, 300); 18 | var body = world.CreateBody(bd); 19 | 20 | rjd.anchorPoint.Set(600/2, 325); 21 | rjd.body1 = prevBody; 22 | rjd.body2 = body; 23 | rjd.motorSpeed = -1.0 * Math.PI; 24 | rjd.motorTorque = 500000000.0; 25 | rjd.enableMotor = true; 26 | world.CreateJoint(rjd); 27 | 28 | prevBody = body; 29 | 30 | // Define follower. 31 | sd.extents.Set(5, 45); 32 | bd.position.Set(600/2, 230); 33 | body = world.CreateBody(bd); 34 | 35 | rjd.anchorPoint.Set(600/2, 275); 36 | rjd.body1 = prevBody; 37 | rjd.body2 = body; 38 | rjd.enableMotor = false; 39 | world.CreateJoint(rjd); 40 | 41 | prevBody = body; 42 | 43 | // Define piston 44 | sd.extents.Set(20, 20); 45 | bd.position.Set(600/2, 185); 46 | body = world.CreateBody(bd); 47 | 48 | rjd.anchorPoint.Set(600/2, 185); 49 | rjd.body1 = prevBody; 50 | rjd.body2 = body; 51 | world.CreateJoint(rjd); 52 | 53 | var pjd = new b2PrismaticJointDef(); 54 | pjd.anchorPoint.Set(600/2, 185); 55 | pjd.body1 = ground; 56 | pjd.body2 = body; 57 | pjd.axis.Set(0.0, 1.0); 58 | pjd.motorSpeed = 0.0; // joint friction 59 | pjd.motorForce = 100000.0; 60 | pjd.enableMotor = true; 61 | 62 | world.CreateJoint(pjd); 63 | 64 | // Create a payload 65 | sd.density = 2.0; 66 | bd.position.Set(600/2, 50); 67 | world.CreateBody(bd); 68 | } 69 | demos.InitWorlds.push(demos.crank.initWorld); 70 | -------------------------------------------------------------------------------- /demos/demo_base.js: -------------------------------------------------------------------------------- 1 | function createWorld() { 2 | var worldAABB = new b2AABB(); 3 | worldAABB.minVertex.Set(-1000, -1000); 4 | worldAABB.maxVertex.Set(1000, 1000); 5 | var gravity = new b2Vec2(0, 300); 6 | var doSleep = true; 7 | var world = new b2World(worldAABB, gravity, doSleep); 8 | createGround(world); 9 | createBox(world, 0, 225, 10, 250); 10 | createBox(world, 600, 225, 10, 250); 11 | return world; 12 | } 13 | 14 | function createGround(world) { 15 | var groundSd = new b2BoxDef(); 16 | groundSd.extents.Set(1200, 50); 17 | groundSd.restitution = 0.5; 18 | groundSd.friction = 0.3; 19 | var groundBd = new b2BodyDef(); 20 | groundBd.AddShape(groundSd); 21 | groundBd.position.Set(-600, 440); 22 | return world.CreateBody(groundBd) 23 | } 24 | 25 | function createBall(world, x, y) { 26 | var ballSd = new b2CircleDef(); 27 | ballSd.density = 1.0; 28 | ballSd.radius = 20; 29 | ballSd.restitution = 0.6; 30 | ballSd.friction = 0.4; 31 | var ballBd = new b2BodyDef(); 32 | ballBd.AddShape(ballSd); 33 | ballBd.position.Set(x,y); 34 | return world.CreateBody(ballBd); 35 | } 36 | 37 | function createBox(world, x, y, width, height, fixed) { 38 | if (typeof(fixed) == 'undefined') fixed = true; 39 | var boxSd = new b2BoxDef(); 40 | boxSd.restitution = 0.6; 41 | boxSd.friction = .3; 42 | if (!fixed) boxSd.density = 1.0; 43 | boxSd.extents.Set(width, height); 44 | var boxBd = new b2BodyDef(); 45 | boxBd.AddShape(boxSd); 46 | boxBd.position.Set(x,y); 47 | return world.CreateBody(boxBd) 48 | } 49 | 50 | var demos = {}; 51 | demos.InitWorlds = []; 52 | -------------------------------------------------------------------------------- /demos/demos.js: -------------------------------------------------------------------------------- 1 | var initId = 0; 2 | var world = createWorld(); 3 | var ctx = null; 4 | var currBuffer = 0; 5 | 6 | var canvasWidth; 7 | var canvasHeight; 8 | var canvasTop; 9 | var canvasLeft; 10 | 11 | function setupWorld(did) { 12 | if (!did) did = 0; 13 | world = createWorld(); 14 | initId += did; 15 | initId %= demos.InitWorlds.length; 16 | if (initId < 0) initId = demos.InitWorlds.length + initId; 17 | demos.InitWorlds[initId](world); 18 | } 19 | function setupNextWorld() { setupWorld(1); } 20 | function setupPrevWorld() { setupWorld(-1); } 21 | 22 | var frames = 0; 23 | var lastTime = (new Date()).getTime(); 24 | var lastFrameTime = (new Date()).getTime(); 25 | var stepSize = 1; 26 | var delayAvg = 0; 27 | var maxStepSize = 40; 28 | var missedFrames = 11; 29 | var targetFPS = 30; 30 | var timeStep = 1.0/targetFPS; 31 | var lastDelay = timeStep * 1000; 32 | function step() { 33 | 34 | world.Step(timeStep, Math.round(stepSize)); 35 | 36 | if ((delayAvg > 0) || (missedFrames > 5)) { 37 | drawWorld(world, ctx); 38 | missedFrames = 0; 39 | frames += 1; 40 | if ((targetFPS < 30) && (delayAvg > 10)) { 41 | targetFPS++; 42 | timeStep = 1/targetFPS; 43 | } 44 | } else { 45 | missedFrames += 1; 46 | if (missedFrames > 3) { 47 | targetFPS--; 48 | targetFPS = (targetFPS < 25) ? 25 : targetFPS; 49 | timeStep = 1/targetFPS; 50 | } 51 | } 52 | 53 | // double buffered svg : switch the buffers here 54 | // ctx.svg.change(ctx.buffers[currBuffer], {'visiblity': 'visible'}); 55 | // currBuffer++; 56 | // currBuffer %= 2; 57 | // ctx.svg.change(ctx.buffers[currBuffer], {'visiblity': 'hidden'}); 58 | 59 | 60 | var currTime = (new Date()).getTime(); 61 | if ((currTime - lastTime) >= 1000) { 62 | jQuery('#fpsText').text(world.m_bodyCount + " bodies. " + frames); 63 | jQuery('#stepSize').text(stepSize.toFixed(1)); 64 | 65 | lastTime = currTime; 66 | 67 | if (frames > (targetFPS + 2)) { 68 | stepSize+=0.1; 69 | stepSize = (stepSize > maxStepSize) ? maxStepSize : stepSize; 70 | } else if (frames < (targetFPS - 2)) { 71 | if ((targetFPS - frames) > 5) { 72 | stepSize-=2; 73 | } else { 74 | stepSize-=0.1; 75 | } 76 | stepSize = (stepSize < 1) ? 1 : stepSize; 77 | } 78 | 79 | jQuery('#delayVal').text((delayAvg / frames).toFixed(1)); 80 | frames = 0; 81 | delayAvg = 0.001; 82 | } 83 | var delay = (stepSize * timeStep * 1000) - (currTime - lastFrameTime); 84 | delay = (delay + lastDelay) / 2; 85 | lastDelay = delay; 86 | 87 | delayAvg += delay; 88 | lastFrameTime = currTime; 89 | 90 | setTimeout(step, (delay > 0) ? delay : 0); 91 | } 92 | 93 | /* 94 | function initBuffers(svgContext) { 95 | ctx.buffers[0] = svgContext.group('buffer1'); 96 | // ctx.buffers[1] = svgContext.group('buffer2', {'visibility':'hidden'}); 97 | } 98 | */ 99 | 100 | function disableSelection(target) { 101 | if (typeof target.onselectstart!="undefined") //IE route 102 | target.onselectstart=function(){return false}; 103 | 104 | else if (typeof target.style.MozUserSelect!="undefined") //Firefox route 105 | target.style.MozUserSelect="none"; 106 | 107 | else //All other route (ie: Opera) 108 | target.onmousedown=function(){return false}; 109 | } 110 | 111 | function handleResize() { 112 | var canvasElm = jQuery('#canvas'); 113 | canvasWidth = parseInt(canvasElm.width); 114 | canvasHeight = parseInt(canvasElm.height); 115 | canvasTop = parseInt(canvasElm.offset().top); 116 | canvasLeft = parseInt(canvasElm.offset().left); 117 | } 118 | 119 | jQuery(window).load(function() { 120 | setupWorld(); 121 | 122 | var canvasElm = jQuery('#canvas'); 123 | handleResize(); 124 | jQuery(window).resize(handleResize); 125 | disableSelection(canvasElm.get(0)); 126 | 127 | // the first call initialises the svg 128 | // the second call fetches the handle 129 | if (jQuery.browser.msie) { 130 | jQuery('#message').html('
If this message doesn\'t go off, your browser (Internet explorer) doesn\'t support SVG.
Try installing the Adobe SVG Viewer'); 131 | } 132 | canvasElm.svg({'onLoad':function() { 133 | ctx = canvasElm.svg('get'); 134 | if (jQuery.browser.msie) { 135 | jQuery('#message').empty(); 136 | } 137 | 138 | // ctx = {'svg':svgContext, 'buffers' : []}; 139 | // initBuffers(svgContext); 140 | 141 | function clickPoint(event) { 142 | return { 143 | x: event.pageX || (event.clientX + 144 | (document.documentElement.scrollLeft || document.body.scrollLeft)), 145 | y: event.pageY || (event.clientY + 146 | (document.documentElement.scrollTop || document.body.scrollTop)) 147 | }; 148 | }; 149 | 150 | jQuery('#canvas').click(function(e) { 151 | var position = clickPoint(e); 152 | if (Math.random() < 0.5) 153 | demos.top.createBall(world, position.x - canvasLeft, position.y - canvasTop); 154 | else 155 | createBox(world, position.x - canvasLeft, position.y - canvasTop, 10, 10, false); 156 | 157 | e.stopPropagation(); 158 | return false; 159 | }).dblclick(function(e) {e.stopPropagation();}); 160 | 161 | jQuery(window).keypress(function(e) { 162 | if (e.altKey || e.ctrlKey) { 163 | return 164 | } 165 | missedFrames = 11; 166 | ctx.clear(); 167 | // initBuffers(svgContext); 168 | setupPrevWorld(); 169 | return false; 170 | }); 171 | 172 | step(); 173 | }}); 174 | }); 175 | -------------------------------------------------------------------------------- /demos/draw_world.js: -------------------------------------------------------------------------------- 1 | function drawWorld(world, context) { 2 | context.root().suspendRedraw(10000); 3 | for (var j = world.m_jointList; j; j = j.m_next) { 4 | drawJoint(j, context); 5 | } 6 | for (var b = world.m_bodyList; b; b = b.m_next) { 7 | for (var s = b.GetShapeList(); s != null; s = s.GetNext()) { 8 | drawShape(s, context, b); 9 | } 10 | } 11 | context.root().unsuspendRedrawAll(); 12 | } 13 | 14 | var uniqueJointId = 0; 15 | 16 | function drawJoint(joint, context) { 17 | var b1 = joint.m_body1; 18 | var b2 = joint.m_body2; 19 | 20 | switch (joint.m_type) { 21 | case b2Joint.e_distanceJoint: 22 | var p1 = joint.GetAnchor1(); 23 | var p2 = joint.GetAnchor2(); 24 | if (joint.sprite) { 25 | context.change(context.getElementById(joint.spriteId), {'x1':p1.x,'y1':p1.y,'x2':p2.x, 'y2':p2.y}); 26 | } else { 27 | joint.sprite = context.group(); 28 | joint.spriteId = 'joint'+(uniqueJointId++); 29 | context.line(joint.sprite, p1.x, p1.y, p2.x, p2.y, {stroke:'#9f9', fillOpacity:'0', id:joint.spriteId}); 30 | } 31 | break; 32 | 33 | case b2Joint.e_springJoint: 34 | /* 35 | if (joint.sprite) { 36 | if (joint.m_length > 2) { 37 | context.change(joint.sprite, {'visiblity':'visible'}); 38 | context.change(context.getElementById(joint.spriteId), {'x1':p1.x,'y1':p1.y,'x2':p2.x, 'y2':p2.y}); 39 | } else { 40 | context.change(joint.sprite, {'visiblity':'hidden'}); 41 | } 42 | } else { 43 | joint.sprite = context.group(); 44 | joint.spriteId = 'joint'+(uniqueJointId++); 45 | context.line(joint.sprite, p1.x, p1.y, p2.x, p2.y, {stroke:'#9f9', fillOpacity:'0', id:joint.spriteId}); 46 | } 47 | break; 48 | */ 49 | case b2Joint.e_pulleyJoint: 50 | // TODO 51 | break; 52 | 53 | default: 54 | if (joint.sprite) { 55 | if (b1 == world.m_groundBody) { 56 | var p1 = joint.GetAnchor1(); 57 | var x2 = b2.m_position; 58 | context.change(context.getElementById(joint.spriteId), {'x1':p1.x,'y1':p1.y,'x2':x2.x, 'y2':x2.y}); 59 | } 60 | } else { 61 | var x1 = b1.m_position; 62 | var x2 = b2.m_position; 63 | var p1 = joint.GetAnchor1(); 64 | joint.sprite = context.group(); 65 | if (b1 == world.m_groundBody) { 66 | joint.spriteId = 'joint'+(uniqueJointId++); 67 | context.line(joint.sprite, p1.x, p1.y, x2.x, x2.y, {stroke:'#f99', 'id':joint.spriteId}); 68 | } else if (b2 == world.m_groundBody) { 69 | context.line(joint.sprite, p1.x, p1.y, x1.x, x1.y, {stroke:'blue'}); 70 | } else { 71 | var p2 = joint.GetAnchor2(); 72 | context.line(joint.sprite, x1.x, x1.y, p1.x, p1.y, {strokeWidth:'2px',stroke:'#9bb', fillOpacity:'0'}); 73 | context.line(joint.sprite, p1.x, p1.y, x2.x, x2.y, {strokeWidth:'2px',stroke:'#9bb', fillOpacity:'0'}); 74 | context.line(joint.sprite, x2.x, x2.y, p2.x, p2.y, {strokeWidth:'2px',stroke:'#9bb', fillOpacity:'0'}); 75 | } 76 | } 77 | break; 78 | } 79 | } 80 | 81 | function setBallHoverIn() { 82 | this.setAttribute("class", 'ball ballHovering'); 83 | } 84 | 85 | function setBallHoverOut() { 86 | this.setAttribute("class", 'ball'); 87 | } 88 | 89 | function setPolyHoverIn() { 90 | this.setAttribute("class", 'poly polyHovering'); 91 | } 92 | 93 | function setPolyHoverOut() { 94 | this.setAttribute("class", 'poly'); 95 | } 96 | 97 | function drawShape(shape, context, parentBody, currBuffer, buffers) { 98 | var pos = shape.m_position; 99 | var angle = parentBody.GetRotation(); 100 | switch (shape.m_type) { 101 | case b2Shape.e_circleShape: 102 | { 103 | if (shape.sprite) { 104 | if (!(parentBody.IsSleeping() || parentBody.IsStatic())) { 105 | var ax = shape.m_R.col1; 106 | angle *= 180/Math.PI; 107 | context.change(shape.sprite, {'transform':'rotate('+angle+','+pos.x+','+pos.y+'),translate('+pos.x+','+pos.y+')'}); 108 | } 109 | } else { 110 | var r = shape.m_radius; 111 | var ax = shape.m_R.col1; 112 | shape.sprite = context.group(); 113 | var circleObj = context.circle(shape.sprite, 0, 0, shape.m_radius, {strokeWidth:'1px',stroke:'#f99', 'class':'ball'}); 114 | context.line(shape.sprite, 0, 0, r * ax.x, r *ax.y, {stroke:'#a99', fillOpacity:'0'}); 115 | context.change(shape.sprite, {'transform':'translate('+pos.x+','+pos.y+')'}); 116 | jQuery(circleObj).hover(setBallHoverIn, setBallHoverOut); 117 | // jQuery(shape.sprite).hover(function() {console.log("hovering on " + pos.x + ',' + pos.y)}); 118 | } 119 | } 120 | break; 121 | case b2Shape.e_polyShape: 122 | { 123 | if (shape.sprite) { 124 | if (!(parentBody.IsSleeping() || parentBody.IsStatic())) { 125 | angle *= 180/Math.PI; // convert to degrees from radians 126 | context.change(shape.sprite, {'transform':'rotate('+angle+','+pos.x+','+pos.y+'),translate('+pos.x+','+pos.y+')'}); 127 | } 128 | } else { 129 | 130 | function adjust(x, y) { 131 | var cos = Math.cos(angle); 132 | var sin = Math.sin(angle); 133 | return [x*cos - y*sin, x*sin + y*cos]; 134 | } 135 | 136 | var tV = shape.m_vertices[0]; 137 | var xy = adjust(tV.x,tV.y); 138 | var pathStr = 'M'+xy[0]+' '+xy[1] + ' '; 139 | for (var i = 1; i < shape.m_vertexCount; i++) { 140 | var v = shape.m_vertices[i]; 141 | var xyInner = adjust(v.x,v.y); 142 | pathStr += 'L'+xyInner[0]+' '+xyInner[1]+' '; 143 | } 144 | pathStr += 'L'+xy[0]+' '+xy[1]+' '; 145 | shape.sprite = context.group(); 146 | var pathObj = context.path(shape.sprite, pathStr, {stroke:'#696', 'class':'poly'}); 147 | angle *= 180/Math.PI; // convert to degrees from radians 148 | context.change(shape.sprite, {'transform':'rotate('+angle+'),translate('+pos.x+','+pos.y+')'}); 149 | jQuery(pathObj).hover(setPolyHoverIn, setPolyHoverOut); 150 | } 151 | } 152 | break; 153 | } 154 | } 155 | 156 | -------------------------------------------------------------------------------- /demos/drop.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2010 HRJ http://lavadip.com 2 | * */ 3 | 4 | demos.drop = {}; 5 | 6 | // Idea from http://cowboyprogramming.com/2007/01/05/blob-physics/ 7 | 8 | demos.drop.createParticle = function (world, x, y, radius) { 9 | var ballSd = new b2CircleDef(); 10 | ballSd.density = 1.0; 11 | ballSd.radius = radius; 12 | ballSd.restitution = 0.6; 13 | ballSd.friction = 0.1; 14 | var ballBd = new b2BodyDef(); 15 | ballBd.AddShape(ballSd); 16 | ballBd.position.Set(x,y); 17 | return world.CreateBody(ballBd); 18 | }; 19 | 20 | demos.drop.initWorld = function(world) { 21 | 22 | /* 23 | var body1 = createBox(world, 40, 30, 5, 5, false); 24 | var body2 = createBox(world, 80, 10, 5, 5, false); 25 | */ 26 | var body1 = demos.drop.createParticle(world, 90,30, 10); 27 | var body2 = demos.drop.createParticle(world, 130,40, 10); 28 | 29 | 30 | var spring = new b2DistanceJointDef(body1, body2, 10); 31 | 32 | spring.body1 = body1; 33 | spring.body2 = body2; 34 | spring.anchorPoint1 = new b2Vec2(90,30); 35 | spring.anchorPoint2 = new b2Vec2(130,40); 36 | world.CreateJoint(spring); 37 | 38 | createDrop(320, 50, 12, 3); 39 | // createDrop(400, 100, 16, 4); 40 | 41 | function createDrop(centerx, centery, segments, radius) { 42 | var centralBody = demos.drop.createParticle(world, centerx, centery, radius); 43 | 44 | var innerBodies = []; 45 | var outerBodies = []; 46 | var R1 = 2*radius*segments / Math.PI; 47 | var R2 = R1 + radius*4; 48 | 49 | for (var i = segments; i--;) { 50 | var angle = 2*Math.PI/segments * i; 51 | var x = Math.sin(angle); 52 | var y = Math.cos(angle); 53 | 54 | innerBodies[i] = demos.drop.createParticle(world, centerx + x*R1, centery + y*R1, radius); 55 | var spring = new b2SpringJointDef(centralBody, innerBodies[i], 60); 56 | 57 | spring.anchorPoint1 = centralBody.m_position; 58 | spring.anchorPoint2 = innerBodies[i].m_position; 59 | world.CreateJoint(spring); 60 | 61 | outerBodies[i] = demos.drop.createParticle(world, centerx + x*R2, centery + y*R2, radius); 62 | var spring = new b2SpringJointDef(centralBody, innerBodies[i], 60); 63 | 64 | spring.anchorPoint1 = centralBody.m_position; 65 | spring.anchorPoint2 = outerBodies[i].m_position; 66 | world.CreateJoint(spring); 67 | } 68 | 69 | for (var i = segments; i--;) { 70 | var next = (i + 1) % segments; 71 | 72 | var spring = new b2SpringJointDef(outerBodies[i], outerBodies[next], 60); 73 | spring.anchorPoint1 = outerBodies[i].m_position; 74 | spring.anchorPoint2 = outerBodies[next].m_position; 75 | world.CreateJoint(spring); 76 | 77 | var spring = new b2SpringJointDef(innerBodies[i], innerBodies[next], 30); 78 | spring.anchorPoint1 = innerBodies[i].m_position; 79 | spring.anchorPoint2 = innerBodies[next].m_position; 80 | world.CreateJoint(spring); 81 | 82 | var spring = new b2SpringJointDef(innerBodies[i], outerBodies[i], 30); 83 | spring.anchorPoint1 = innerBodies[i].m_position; 84 | spring.anchorPoint2 = outerBodies[i].m_position; 85 | world.CreateJoint(spring); 86 | 87 | var spring = new b2SpringJointDef(innerBodies[i], outerBodies[next], 30); 88 | spring.anchorPoint1 = innerBodies[i].m_position; 89 | spring.anchorPoint2 = outerBodies[next].m_position; 90 | world.CreateJoint(spring); 91 | } 92 | } 93 | 94 | // create some obstructions 95 | demos.top.createPoly(world, 50, 250, [[0, 0], [150, 40], [0, 40]], true); 96 | demos.top.createPoly(world, 370, 150, [[0, 0], [0, 30],[-200, 30]], true); 97 | demos.top.createPoly(world, 300, 330, [[0, 0], [0, 20], [-100, 20]], true); 98 | 99 | }; 100 | 101 | demos.InitWorlds.push(demos.drop.initWorld); 102 | -------------------------------------------------------------------------------- /demos/pendulum.js: -------------------------------------------------------------------------------- 1 | demos.pendulum = {}; 2 | demos.pendulum.initWorld = function(world) { 3 | var i; 4 | var ground = world.GetGroundBody(); 5 | var jointDef = new b2RevoluteJointDef(); 6 | var L = 170; 7 | var spacing = 40; 8 | for (i = 0; i < 4; i++) { 9 | jointDef.anchorPoint.Set(250 + spacing * i, 0); 10 | jointDef.body1 = ground; 11 | jointDef.body2 = createBall(world, 250 + spacing * i, L); 12 | world.CreateJoint(jointDef); 13 | } 14 | jointDef.anchorPoint.Set(250 - spacing, 0); 15 | jointDef.body1 = ground; 16 | jointDef.body2 = createBall(world, 250 - spacing - L, 0); 17 | world.CreateJoint(jointDef); 18 | } 19 | demos.InitWorlds.push(demos.pendulum.initWorld); 20 | 21 | 22 | -------------------------------------------------------------------------------- /demos/stack.js: -------------------------------------------------------------------------------- 1 | demos.stack = {}; 2 | demos.stack.initWorld = function(world) { 3 | var sd = new b2BoxDef(); 4 | var bd = new b2BodyDef(); 5 | bd.AddShape(sd); 6 | sd.density = 1.0; 7 | sd.friction = .5; 8 | var size = 15; 9 | sd.extents.Set(size, size); 10 | 11 | var i; 12 | for (i = 0; i < 8; i++) { 13 | bd.position.Set(600/2-150, (250-i*(size + 1)*2)); 14 | world.CreateBody(bd); 15 | bd.position.Set(600/2, (250-i*(size + 1)*2)); 16 | world.CreateBody(bd); 17 | bd.position.Set(600/2+150+Math.random()*2-i, (250-i*(size + 1)*2)); 18 | world.CreateBody(bd); 19 | } 20 | } 21 | demos.InitWorlds.push(demos.stack.initWorld); 22 | 23 | 24 | -------------------------------------------------------------------------------- /demos/top.js: -------------------------------------------------------------------------------- 1 | demos.top = {}; 2 | demos.top.createBall = function(world, x, y, rad, fixed) { 3 | var ballSd = new b2CircleDef(); 4 | if (!fixed) ballSd.density = 1.0; 5 | ballSd.radius = rad || 10; 6 | ballSd.restitution = 0.2; 7 | var ballBd = new b2BodyDef(); 8 | ballBd.AddShape(ballSd); 9 | ballBd.position.Set(x,y); 10 | return world.CreateBody(ballBd); 11 | }; 12 | demos.top.createPoly = function(world, x, y, points, fixed) { 13 | var polySd = new b2PolyDef(); 14 | if (!fixed) polySd.density = 1.0; 15 | polySd.vertexCount = points.length; 16 | for (var i = 0; i < points.length; i++) { 17 | polySd.vertices[i].Set(points[i][0], points[i][1]); 18 | } 19 | var polyBd = new b2BodyDef(); 20 | polyBd.AddShape(polySd); 21 | polyBd.position.Set(x,y); 22 | return world.CreateBody(polyBd) 23 | }; 24 | demos.top.initWorld = function(world) { 25 | demos.top.createBall(world, 450, 150, 50, true); 26 | for (var i = 8; i--;) { 27 | demos.top.createBall(world, 60*i + 20, 10, 6, false); 28 | } 29 | demos.top.createPoly(world, 100, 100, [[0, 0], [10, 30], [-10, 30]], true); 30 | demos.top.createPoly(world, 150, 150, [[0, 0], [10, 30], [-10, 30]], true); 31 | var pendulum = createBox(world, 150, 100, 20, 20, false); 32 | var jointDef = new b2RevoluteJointDef(); 33 | jointDef.body1 = pendulum; 34 | jointDef.body2 = world.GetGroundBody(); 35 | jointDef.anchorPoint = pendulum.GetCenterPosition(); 36 | world.CreateJoint(jointDef); 37 | 38 | var seesaw = demos.top.createPoly(world, 300, 200, [[0, 0], [100, 30], [-100, 30]]); 39 | jointDef.body1 = seesaw; 40 | jointDef.anchorPoint = seesaw.GetCenterPosition(); 41 | world.CreateJoint(jointDef); 42 | }; 43 | demos.InitWorlds.push(demos.top.initWorld); 44 | 45 | 46 | -------------------------------------------------------------------------------- /images/yarada.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hrj/box2d-js/cc56fac37a6c7c44e6044220c5a9a3900449b25a/images/yarada.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Box2DJS - Physics Engine for JavaScript 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |

FPS Step size delay(ms)

40 |

Box2D JS demo

41 |
42 |

43 | Left-click to spawn an object. 44 |

45 |

46 | Press any key to view the next example. 47 |

48 |
49 |

More info and source on GitHub.

50 |

51 | 52 | 53 |

54 |
55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /js/box2d/collision/ClipVertex.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var ClipVertex = function() { 24 | // initialize instance variables for references 25 | this.v = new b2Vec2(); 26 | this.id = new b2ContactID(); 27 | }; 28 | 29 | ClipVertex.prototype = { 30 | v: new b2Vec2(), 31 | id: new b2ContactID(), 32 | }; 33 | 34 | 35 | -------------------------------------------------------------------------------- /js/box2d/collision/Features.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | // We use contact ids to facilitate warm starting. 21 | var Features = function() {}; 22 | 23 | Features.prototype = 24 | { 25 | // 26 | set_referenceFace: function(value){ 27 | this._referenceFace = value; 28 | this._m_id._key = (this._m_id._key & 0xffffff00) | (this._referenceFace & 0x000000ff) 29 | }, 30 | get_referenceFace: function(){ 31 | return this._referenceFace; 32 | }, 33 | _referenceFace: 0, 34 | // 35 | set_incidentEdge: function(value){ 36 | this._incidentEdge = value; 37 | this._m_id._key = (this._m_id._key & 0xffff00ff) | ((this._incidentEdge << 8) & 0x0000ff00) 38 | }, 39 | get_incidentEdge: function(){ 40 | return this._incidentEdge; 41 | }, 42 | _incidentEdge: 0, 43 | // 44 | set_incidentVertex: function(value){ 45 | this._incidentVertex = value; 46 | this._m_id._key = (this._m_id._key & 0xff00ffff) | ((this._incidentVertex << 16) & 0x00ff0000) 47 | }, 48 | get_incidentVertex: function(){ 49 | return this._incidentVertex; 50 | }, 51 | _incidentVertex: 0, 52 | // 53 | set_flip: function(value){ 54 | this._flip = value; 55 | this._m_id._key = (this._m_id._key & 0x00ffffff) | ((this._flip << 24) & 0xff000000) 56 | }, 57 | get_flip: function(){ 58 | return this._flip; 59 | }, 60 | _flip: 0, 61 | _m_id: null, 62 | }; 63 | -------------------------------------------------------------------------------- /js/box2d/collision/b2AABB.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | // A manifold for two touching convex shapes. 22 | var b2AABB = function() { 23 | // initialize instance variables for references 24 | this.minVertex = new b2Vec2(); 25 | this.maxVertex = new b2Vec2(); 26 | }; 27 | 28 | b2AABB.prototype = 29 | { 30 | IsValid: function(){ 31 | //var d = b2Math.SubtractVV(this.maxVertex, this.minVertex); 32 | var dX = this.maxVertex.x; 33 | var dY = this.maxVertex.y; 34 | dX = this.maxVertex.x; 35 | dY = this.maxVertex.y; 36 | dX -= this.minVertex.x; 37 | dY -= this.minVertex.y; 38 | var valid = dX >= 0.0 && dY >= 0.0; 39 | valid = valid && this.minVertex.IsValid() && this.maxVertex.IsValid(); 40 | return valid; 41 | }, 42 | 43 | minVertex: new b2Vec2(), 44 | maxVertex: new b2Vec2() 45 | }; 46 | -------------------------------------------------------------------------------- /js/box2d/collision/b2Bound.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2Bound = function() {}; 22 | b2Bound.prototype = { 23 | IsLower: function(){ return (this.value & 1) == 0; }, 24 | IsUpper: function(){ return (this.value & 1) == 1; }, 25 | Swap: function(b){ 26 | var tempValue = this.value; 27 | var tempProxyId = this.proxyId; 28 | var tempStabbingCount = this.stabbingCount; 29 | 30 | this.value = b.value; 31 | this.proxyId = b.proxyId; 32 | this.stabbingCount = b.stabbingCount; 33 | 34 | b.value = tempValue; 35 | b.proxyId = tempProxyId; 36 | b.stabbingCount = tempStabbingCount; 37 | }, 38 | 39 | value: 0, 40 | proxyId: 0, 41 | stabbingCount: 0 42 | }; 43 | -------------------------------------------------------------------------------- /js/box2d/collision/b2BoundValues.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2BoundValues = function() { 22 | // initialize instance variables for references 23 | this.lowerValues = [0,0]; 24 | this.upperValues = [0,0]; 25 | }; 26 | b2BoundValues.prototype = { 27 | lowerValues: [0,0], 28 | upperValues: [0,0] 29 | } 30 | -------------------------------------------------------------------------------- /js/box2d/collision/b2BufferedPair.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2BufferedPair = function() {}; 22 | b2BufferedPair.prototype = { 23 | proxyId1: 0, 24 | proxyId2: 0 25 | }; 26 | -------------------------------------------------------------------------------- /js/box2d/collision/b2ContactID.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | // We use contact ids to facilitate warm starting. 22 | var b2ContactID = function(){ 23 | // initialize instance variables for references 24 | this.features = new Features(); 25 | this.features._m_id = this; 26 | }; 27 | 28 | b2ContactID.prototype = 29 | { 30 | Set: function(id){ 31 | this.set_key(id._key); 32 | }, 33 | Copy: function(){ 34 | var id = new b2ContactID(); 35 | id.set_key(this._key); 36 | return id; 37 | }, 38 | get_key: function(){ 39 | return this._key; 40 | }, 41 | set_key: function(value) { 42 | this._key = value; 43 | this.features._referenceFace = this._key & 0x000000ff; 44 | this.features._incidentEdge = ((this._key & 0x0000ff00) >> 8) & 0x000000ff; 45 | this.features._incidentVertex = ((this._key & 0x00ff0000) >> 16) & 0x000000ff; 46 | this.features._flip = ((this._key & 0xff000000) >> 24) & 0x000000ff; 47 | }, 48 | features: null, 49 | _key: 0 50 | }; 51 | -------------------------------------------------------------------------------- /js/box2d/collision/b2ContactPoint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | // We use contact ids to facilitate warm starting. 20 | var b2ContactPoint = function() { 21 | // initialize instance variables for references 22 | this.position = new b2Vec2(); 23 | this.id = new b2ContactID(); 24 | }; 25 | 26 | b2ContactPoint.prototype = { 27 | position: new b2Vec2(), 28 | separation: null, 29 | normalImpulse: null, 30 | tangentImpulse: null, 31 | id: new b2ContactID(), 32 | }; 33 | -------------------------------------------------------------------------------- /js/box2d/collision/b2Distance.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2Distance = function() {}; 22 | 23 | b2Distance.prototype = 24 | { 25 | 26 | // GJK using Voronoi regions (Christer Ericson) and region selection 27 | // optimizations (Casey Muratori). 28 | 29 | // The origin is either in the region of points[1] or in the edge region. The origin is 30 | // not in region of points[0] because that is the old point. 31 | 32 | // Possible regions: 33 | // - points[2] 34 | // - edge points[0]-points[2] 35 | // - edge points[1]-points[2] 36 | // - inside the triangle 37 | ProcessTwo : function(p1Out, p2Out, p1s, p2s, points) { 38 | // If in point[1] region 39 | //b2Vec2 r = -points[1]; 40 | var rX = -points[1].x; 41 | var rY = -points[1].y; 42 | //b2Vec2 d = points[1] - points[0]; 43 | var dX = points[0].x - points[1].x; 44 | var dY = points[0].y - points[1].y; 45 | //float32 length = d.Normalize(); 46 | var length = Math.sqrt(dX*dX + dY*dY); 47 | dX /= length; 48 | dY /= length; 49 | 50 | //float32 lambda = b2Dot(r, d); 51 | var lambda = rX * dX + rY * dY; 52 | if (lambda <= 0.0 || length < Number.MIN_VALUE) 53 | { 54 | // The simplex is reduced to a point. 55 | //*p1Out = p1s[1]; 56 | p1Out.SetV(p1s[1]); 57 | //*p2Out = p2s[1]; 58 | p2Out.SetV(p2s[1]); 59 | //p1s[0] = p1s[1]; 60 | p1s[0].SetV(p1s[1]); 61 | //p2s[0] = p2s[1]; 62 | p2s[0].SetV(p2s[1]); 63 | points[0].SetV(points[1]); 64 | return 1; 65 | } 66 | 67 | // Else in edge region 68 | lambda /= length; 69 | //*p1Out = p1s[1] + lambda * (p1s[0] - p1s[1]); 70 | p1Out.x = p1s[1].x + lambda * (p1s[0].x - p1s[1].x); 71 | p1Out.y = p1s[1].y + lambda * (p1s[0].y - p1s[1].y); 72 | //*p2Out = p2s[1] + lambda * (p2s[0] - p2s[1]); 73 | p2Out.x = p2s[1].x + lambda * (p2s[0].x - p2s[1].x); 74 | p2Out.y = p2s[1].y + lambda * (p2s[0].y - p2s[1].y); 75 | return 2; 76 | }, 77 | ProcessThree : function(p1Out, p2Out, p1s, p2s, points) { 78 | //b2Vec2 a = points[0]; 79 | var aX = points[0].x; 80 | var aY = points[0].y; 81 | //b2Vec2 b = points[1]; 82 | var bX = points[1].x; 83 | var bY = points[1].y; 84 | //b2Vec2 c = points[2]; 85 | var cX = points[2].x; 86 | var cY = points[2].y; 87 | 88 | //b2Vec2 ab = b - a; 89 | var abX = bX - aX; 90 | var abY = bY - aY; 91 | //b2Vec2 ac = c - a; 92 | var acX = cX - aX; 93 | var acY = cY - aY; 94 | //b2Vec2 bc = c - b; 95 | var bcX = cX - bX; 96 | var bcY = cY - bY; 97 | 98 | //float32 sn = -b2Dot(a, ab), sd = b2Dot(b, ab); 99 | var sn = -(aX * abX + aY * abY); 100 | var sd = (bX * abX + bY * abY); 101 | //float32 tn = -b2Dot(a, ac), td = b2Dot(c, ac); 102 | var tn = -(aX * acX + aY * acY); 103 | var td = (cX * acX + cY * acY); 104 | //float32 un = -b2Dot(b, bc), ud = b2Dot(c, bc); 105 | var un = -(bX * bcX + bY * bcY); 106 | var ud = (cX * bcX + cY * bcY); 107 | 108 | // In vertex c region? 109 | if (td <= 0.0 && ud <= 0.0) 110 | { 111 | // Single point 112 | //*p1Out = p1s[2]; 113 | p1Out.SetV(p1s[2]); 114 | //*p2Out = p2s[2]; 115 | p2Out.SetV(p2s[2]); 116 | //p1s[0] = p1s[2]; 117 | p1s[0].SetV(p1s[2]); 118 | //p2s[0] = p2s[2]; 119 | p2s[0].SetV(p2s[2]); 120 | points[0].SetV(points[2]); 121 | return 1; 122 | } 123 | 124 | // Should not be in vertex a or b region. 125 | //b2Settings.b2Assert(sn > 0.0 || tn > 0.0); 126 | //b2Settings.b2Assert(sd > 0.0 || un > 0.0); 127 | 128 | //float32 n = b2Cross(ab, ac); 129 | var n = abX * acY - abY * acX; 130 | 131 | // Should not be in edge ab region. 132 | //float32 vc = n * b2Cross(a, b); 133 | var vc = n * (aX * bY - aY * bX); 134 | //b2Settings.b2Assert(vc > 0.0 || sn > 0.0 || sd > 0.0); 135 | 136 | // In edge bc region? 137 | //float32 va = n * b2Cross(b, c); 138 | var va = n * (bX * cY - bY * cX); 139 | if (va <= 0.0 && un >= 0.0 && ud >= 0.0) 140 | { 141 | //b2Settings.b2Assert(un + ud > 0.0); 142 | 143 | //float32 lambda = un / (un + ud); 144 | var lambda = un / (un + ud); 145 | //*p1Out = p1s[1] + lambda * (p1s[2] - p1s[1]); 146 | p1Out.x = p1s[1].x + lambda * (p1s[2].x - p1s[1].x); 147 | p1Out.y = p1s[1].y + lambda * (p1s[2].y - p1s[1].y); 148 | //*p2Out = p2s[1] + lambda * (p2s[2] - p2s[1]); 149 | p2Out.x = p2s[1].x + lambda * (p2s[2].x - p2s[1].x); 150 | p2Out.y = p2s[1].y + lambda * (p2s[2].y - p2s[1].y); 151 | //p1s[0] = p1s[2]; 152 | p1s[0].SetV(p1s[2]); 153 | //p2s[0] = p2s[2]; 154 | p2s[0].SetV(p2s[2]); 155 | //points[0] = points[2]; 156 | points[0].SetV(points[2]); 157 | return 2; 158 | } 159 | 160 | // In edge ac region? 161 | //float32 vb = n * b2Cross(c, a); 162 | var vb = n * (cX * aY - cY * aX); 163 | if (vb <= 0.0 && tn >= 0.0 && td >= 0.0) 164 | { 165 | //b2Settings.b2Assert(tn + td > 0.0); 166 | 167 | //float32 lambda = tn / (tn + td); 168 | var lambda = tn / (tn + td); 169 | //*p1Out = p1s[0] + lambda * (p1s[2] - p1s[0]); 170 | p1Out.x = p1s[0].x + lambda * (p1s[2].x - p1s[0].x); 171 | p1Out.y = p1s[0].y + lambda * (p1s[2].y - p1s[0].y); 172 | //*p2Out = p2s[0] + lambda * (p2s[2] - p2s[0]); 173 | p2Out.x = p2s[0].x + lambda * (p2s[2].x - p2s[0].x); 174 | p2Out.y = p2s[0].y + lambda * (p2s[2].y - p2s[0].y); 175 | //p1s[1] = p1s[2]; 176 | p1s[1].SetV(p1s[2]); 177 | //p2s[1] = p2s[2]; 178 | p2s[1].SetV(p2s[2]); 179 | //points[1] = points[2]; 180 | points[1].SetV(points[2]); 181 | return 2; 182 | } 183 | 184 | // Inside the triangle, compute barycentric coordinates 185 | //float32 denom = va + vb + vc; 186 | var denom = va + vb + vc; 187 | //b2Settings.b2Assert(denom > 0.0); 188 | denom = 1.0 / denom; 189 | //float32 u = va * denom; 190 | var u = va * denom; 191 | //float32 v = vb * denom; 192 | var v = vb * denom; 193 | //float32 w = 1.0f - u - v; 194 | var w = 1.0 - u - v; 195 | //*p1Out = u * p1s[0] + v * p1s[1] + w * p1s[2]; 196 | p1Out.x = u * p1s[0].x + v * p1s[1].x + w * p1s[2].x; 197 | p1Out.y = u * p1s[0].y + v * p1s[1].y + w * p1s[2].y; 198 | //*p2Out = u * p2s[0] + v * p2s[1] + w * p2s[2]; 199 | p2Out.x = u * p2s[0].x + v * p2s[1].x + w * p2s[2].x; 200 | p2Out.y = u * p2s[0].y + v * p2s[1].y + w * p2s[2].y; 201 | return 3; 202 | }, 203 | InPoinsts : function(w, points, pointCount) { 204 | for (var i = pointCount; i--;) 205 | { 206 | if (w.x == points[i].x && w.y == points[i].y) 207 | { 208 | return true; 209 | } 210 | } 211 | 212 | return false; 213 | }, 214 | Distance : function(p1Out, p2Out, shape1, shape2) { 215 | //b2Vec2 p1s[3], p2s[3]; 216 | var p1s = new Array(3); 217 | var p2s = new Array(3); 218 | //b2Vec2 points[3]; 219 | var points = new Array(3); 220 | //int32 pointCount = 0; 221 | var pointCount = 0; 222 | 223 | //*p1Out = shape1->m_position; 224 | p1Out.SetV(shape1.m_position); 225 | //*p2Out = shape2->m_position; 226 | p2Out.SetV(shape2.m_position); 227 | 228 | var vSqr = 0.0; 229 | var maxIterations = 20; 230 | for (var iter = 0; iter < maxIterations; ++iter) 231 | { 232 | //b2Vec2 v = *p2Out - *p1Out; 233 | var vX = p2Out.x - p1Out.x; 234 | var vY = p2Out.y - p1Out.y; 235 | //b2Vec2 w1 = shape1->Support(v); 236 | var w1 = shape1.Support(vX, vY); 237 | //b2Vec2 w2 = shape2->Support(-v); 238 | var w2 = shape2.Support(-vX, -vY); 239 | //float32 vSqr = b2Dot(v, v); 240 | vSqr = (vX*vX + vY*vY); 241 | //b2Vec2 w = w2 - w1; 242 | var wX = w2.x - w1.x; 243 | var wY = w2.y - w1.y; 244 | //float32 vw = b2Dot(v, w); 245 | var vw = (vX*wX + vY*wY); 246 | //if (vSqr - b2Dot(v, w) <= 0.01f * vSqr) 247 | if (vSqr - b2Dot(vX * wX + vY * wY) <= 0.01 * vSqr) 248 | { 249 | if (pointCount == 0) 250 | { 251 | //*p1Out = w1; 252 | p1Out.SetV(w1); 253 | //*p2Out = w2; 254 | p2Out.SetV(w2); 255 | } 256 | b2Distance.g_GJK_Iterations = iter; 257 | return Math.sqrt(vSqr); 258 | } 259 | 260 | switch (pointCount) 261 | { 262 | case 0: 263 | //p1s[0] = w1; 264 | p1s[0].SetV(w1); 265 | //p2s[0] = w2; 266 | p2s[0].SetV(w2); 267 | points[0] = w; 268 | //*p1Out = p1s[0]; 269 | p1Out.SetV(p1s[0]); 270 | //*p2Out = p2s[0]; 271 | p2Out.SetV(p2s[0]); 272 | ++pointCount; 273 | break; 274 | 275 | case 1: 276 | //p1s[1] = w1; 277 | p1s[1].SetV(w1); 278 | //p2s[1] = w2; 279 | p2s[1].SetV(w2); 280 | //points[1] = w; 281 | points[1].x = wX; 282 | points[1].y = wY; 283 | pointCount = b2Distance.ProcessTwo(p1Out, p2Out, p1s, p2s, points); 284 | break; 285 | 286 | case 2: 287 | //p1s[2] = w1; 288 | p1s[2].SetV(w1); 289 | //p2s[2] = w2; 290 | p2s[2].SetV(w2); 291 | //points[2] = w; 292 | points[2].x = wX; 293 | points[2].y = wY; 294 | pointCount = b2Distance.ProcessThree(p1Out, p2Out, p1s, p2s, points); 295 | break; 296 | } 297 | 298 | // If we have three points, then the origin is in the corresponding triangle. 299 | if (pointCount == 3) 300 | { 301 | b2Distance.g_GJK_Iterations = iter; 302 | return 0.0; 303 | } 304 | 305 | //float32 maxSqr = -FLT_MAX; 306 | var maxSqr = -Number.MAX_VALUE; 307 | for (var i = pointCount; i--;) 308 | { 309 | //maxSqr = b2Math.b2Max(maxSqr, b2Dot(points[i], points[i])); 310 | maxSqr = b2Math.b2Max(maxSqr, (points[i].x*points[i].x + points[i].y*points[i].y)); 311 | } 312 | 313 | if (pointCount == 3 || vSqr <= 100.0 * Number.MIN_VALUE * maxSqr) 314 | { 315 | b2Distance.g_GJK_Iterations = iter; 316 | return Math.sqrt(vSqr); 317 | } 318 | } 319 | 320 | b2Distance.g_GJK_Iterations = maxIterations; 321 | return Math.sqrt(vSqr); 322 | } 323 | }; 324 | 325 | 326 | b2Distance.g_GJK_Iterations = 0; 327 | -------------------------------------------------------------------------------- /js/box2d/collision/b2Manifold.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | // A manifold for two touching convex shapes. 22 | var b2Manifold = function(){ 23 | this.points = new Array(b2Settings.b2_maxManifoldPoints); 24 | for (var i = b2Settings.b2_maxManifoldPoints; i--;){ 25 | this.points[i] = new b2ContactPoint(); 26 | } 27 | this.normal = new b2Vec2(); 28 | }; 29 | 30 | b2Manifold.prototype = { 31 | points: null, 32 | normal: null, 33 | pointCount: 0 34 | }; 35 | -------------------------------------------------------------------------------- /js/box2d/collision/b2OBB.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | // A manifold for two touching convex shapes. 22 | var b2OBB = function() { 23 | // initialize instance variables for references 24 | this.R = new b2Mat22(); 25 | this.center = new b2Vec2(); 26 | this.extents = new b2Vec2(); 27 | }; 28 | 29 | b2OBB.prototype = { 30 | R: new b2Mat22(), 31 | center: new b2Vec2(), 32 | extents: new b2Vec2(), 33 | }; 34 | -------------------------------------------------------------------------------- /js/box2d/collision/b2Pair.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | // The pair manager is used by the broad-phase to quickly add/remove/find pairs 20 | // of overlapping proxies. It is based closely on code provided by Pierre Terdiman. 21 | // http: 22 | 23 | 24 | 25 | 26 | 27 | var b2Pair = function() {}; 28 | 29 | b2Pair.prototype = 30 | { 31 | SetBuffered: function() { this.status |= b2Pair.e_pairBuffered; }, 32 | ClearBuffered: function() { this.status &= ~b2Pair.e_pairBuffered; }, 33 | IsBuffered: function(){ return (this.status & b2Pair.e_pairBuffered) == b2Pair.e_pairBuffered; }, 34 | 35 | SetRemoved: function() { this.status |= b2Pair.e_pairRemoved; }, 36 | ClearRemoved: function() { this.status &= ~b2Pair.e_pairRemoved; }, 37 | IsRemoved: function(){ return (this.status & b2Pair.e_pairRemoved) == b2Pair.e_pairRemoved; }, 38 | 39 | SetFinal: function() { this.status |= b2Pair.e_pairFinal; }, 40 | IsFinal: function(){ return (this.status & b2Pair.e_pairFinal) == b2Pair.e_pairFinal; }, 41 | 42 | userData: null, 43 | proxyId1: 0, 44 | proxyId2: 0, 45 | next: 0, 46 | status: 0 47 | }; 48 | 49 | b2Pair.b2_nullPair = b2Settings.USHRT_MAX; 50 | b2Pair.b2_nullProxy = b2Settings.USHRT_MAX; 51 | b2Pair.b2_tableCapacity = b2Settings.b2_maxPairs; 52 | b2Pair.b2_tableMask = b2Pair.b2_tableCapacity - 1; 53 | b2Pair.e_pairBuffered = 0x0001; 54 | b2Pair.e_pairRemoved = 0x0002; 55 | b2Pair.e_pairFinal = 0x0004; 56 | -------------------------------------------------------------------------------- /js/box2d/collision/b2PairCallback.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2PairCallback = function() {}; 22 | 23 | b2PairCallback.prototype = 24 | { 25 | //virtual ~b2PairCallback() {} 26 | 27 | // This returns the new pair user data. 28 | PairAdded: function(proxyUserData1, proxyUserData2){return null}, 29 | 30 | // This should free the pair's user data. In extreme circumstances, it is possible 31 | // this will be called with null pairUserData because the pair never existed. 32 | PairRemoved: function(proxyUserData1, proxyUserData2, pairUserData){}, 33 | }; 34 | 35 | 36 | -------------------------------------------------------------------------------- /js/box2d/collision/b2Proxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2Proxy = function() { 20 | // initialize instance variables for references 21 | this.lowerBounds = [/*uint*/(0), /*uint*/(0)]; 22 | this.upperBounds = [/*uint*/(0), /*uint*/(0)]; 23 | }; 24 | 25 | b2Proxy.prototype = { 26 | GetNext: function(){ return this.lowerBounds[0]; }, 27 | SetNext: function(next) { this.lowerBounds[0] = next /*& 0x0000ffff*/; }, 28 | 29 | IsValid: function(){ return this.overlapCount != b2BroadPhase.b2_invalid; }, 30 | 31 | lowerBounds: [/*uint*/(0), /*uint*/(0)], 32 | upperBounds: [/*uint*/(0), /*uint*/(0)], 33 | overlapCount: 0, 34 | timeStamp: 0, 35 | 36 | userData: null, 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2BoxDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2BoxDef = function() { 20 | // The constructor for b2ShapeDef 21 | this.type = b2Shape.e_unknownShape; 22 | this.userData = null; 23 | this.localPosition = new b2Vec2(0.0, 0.0); 24 | this.localRotation = 0.0; 25 | this.friction = 0.2; 26 | this.restitution = 0.0; 27 | this.density = 0.0; 28 | this.categoryBits = 0x0001; 29 | this.maskBits = 0xFFFF; 30 | this.groupIndex = 0; 31 | 32 | this.type = b2Shape.e_boxShape; 33 | this.extents = new b2Vec2(1.0, 1.0); 34 | }; 35 | 36 | Object.extend(b2BoxDef.prototype, b2ShapeDef.prototype); 37 | Object.extend(b2BoxDef.prototype, { 38 | extents: null 39 | }); 40 | 41 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2CircleDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2CircleDef = function() { 21 | // The constructor for b2ShapeDef 22 | this.type = b2Shape.e_unknownShape; 23 | this.userData = null; 24 | this.localPosition = new b2Vec2(0.0, 0.0); 25 | this.localRotation = 0.0; 26 | this.friction = 0.2; 27 | this.restitution = 0.0; 28 | this.density = 0.0; 29 | this.categoryBits = 0x0001; 30 | this.maskBits = 0xFFFF; 31 | this.groupIndex = 0; 32 | // 33 | 34 | this.type = b2Shape.e_circleShape; 35 | this.radius = 1.0; 36 | }; 37 | 38 | Object.extend(b2CircleDef.prototype, b2ShapeDef.prototype); 39 | Object.extend(b2CircleDef.prototype, { 40 | radius: null 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2CircleShape.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2CircleShape = function(def, body, localCenter) { 20 | // initialize instance variables for references 21 | this.m_R = new b2Mat22(); 22 | this.m_position = new b2Vec2(); 23 | // 24 | 25 | // The constructor for b2Shape 26 | this.m_userData = def.userData; 27 | 28 | this.m_friction = def.friction; 29 | this.m_restitution = def.restitution; 30 | this.m_body = body; 31 | 32 | this.m_proxyId = b2Pair.b2_nullProxy; 33 | 34 | this.m_maxRadius = 0.0; 35 | 36 | this.m_categoryBits = def.categoryBits; 37 | this.m_maskBits = def.maskBits; 38 | this.m_groupIndex = def.groupIndex; 39 | // 40 | 41 | // initialize instance variables for references 42 | this.m_localPosition = new b2Vec2(); 43 | // 44 | 45 | //super(def, body); 46 | 47 | //b2Settings.b2Assert(def.type == b2Shape.e_circleShape); 48 | var circle = def; 49 | 50 | //this.m_localPosition = def.localPosition - localCenter; 51 | this.m_localPosition.Set(def.localPosition.x - localCenter.x, def.localPosition.y - localCenter.y); 52 | this.m_type = b2Shape.e_circleShape; 53 | this.m_radius = circle.radius; 54 | 55 | this.m_R.SetM(this.m_body.m_R); 56 | //b2Vec2 r = b2Mul(this.m_body->this.m_R, this.m_localPosition); 57 | var rX = this.m_R.col1.x * this.m_localPosition.x + this.m_R.col2.x * this.m_localPosition.y; 58 | var rY = this.m_R.col1.y * this.m_localPosition.x + this.m_R.col2.y * this.m_localPosition.y; 59 | //this.m_position = this.m_body->this.m_position + r; 60 | this.m_position.x = this.m_body.m_position.x + rX; 61 | this.m_position.y = this.m_body.m_position.y + rY; 62 | //this.m_maxRadius = r.Length() + this.m_radius; 63 | this.m_maxRadius = Math.sqrt(rX*rX+rY*rY) + this.m_radius; 64 | 65 | var aabb = new b2AABB(); 66 | aabb.minVertex.Set(this.m_position.x - this.m_radius, this.m_position.y - this.m_radius); 67 | aabb.maxVertex.Set(this.m_position.x + this.m_radius, this.m_position.y + this.m_radius); 68 | 69 | var broadPhase = this.m_body.m_world.m_broadPhase; 70 | if (broadPhase.InRange(aabb)) 71 | { 72 | this.m_proxyId = broadPhase.CreateProxy(aabb, this); 73 | } 74 | else 75 | { 76 | this.m_proxyId = b2Pair.b2_nullProxy; 77 | } 78 | 79 | if (this.m_proxyId == b2Pair.b2_nullProxy) 80 | { 81 | this.m_body.Freeze(); 82 | } 83 | }; 84 | 85 | Object.extend(b2CircleShape.prototype, b2Shape.prototype); 86 | Object.extend(b2CircleShape.prototype, { 87 | TestPoint: function(p){ 88 | //var d = b2Math.SubtractVV(p, this.m_position); 89 | var d = new b2Vec2(); 90 | d.SetV(p); 91 | d.Subtract(this.m_position); 92 | return b2Math.b2Dot(d, d) <= this.m_radius * this.m_radius; 93 | }, 94 | 95 | //--------------- Internals Below ------------------- 96 | 97 | 98 | Synchronize: function(position1, R1, position2, R2){ 99 | this.m_R.SetM(R2); 100 | //this.m_position = position2 + b2Mul(R2, this.m_localPosition); 101 | this.m_position.x = (R2.col1.x * this.m_localPosition.x + R2.col2.x * this.m_localPosition.y) + position2.x; 102 | this.m_position.y = (R2.col1.y * this.m_localPosition.x + R2.col2.y * this.m_localPosition.y) + position2.y; 103 | 104 | if (this.m_proxyId == b2Pair.b2_nullProxy) 105 | { 106 | return; 107 | } 108 | 109 | // Compute an AABB that covers the swept shape (may miss some rotation effect). 110 | //b2Vec2 p1 = position1 + b2Mul(R1, this.m_localPosition); 111 | var p1X = position1.x + (R1.col1.x * this.m_localPosition.x + R1.col2.x * this.m_localPosition.y); 112 | var p1Y = position1.y + (R1.col1.y * this.m_localPosition.x + R1.col2.y * this.m_localPosition.y); 113 | //b2Vec2 lower = b2Min(p1, this.m_position); 114 | var lowerX = Math.min(p1X, this.m_position.x); 115 | var lowerY = Math.min(p1Y, this.m_position.y); 116 | //b2Vec2 upper = b2Max(p1, this.m_position); 117 | var upperX = Math.max(p1X, this.m_position.x); 118 | var upperY = Math.max(p1Y, this.m_position.y); 119 | 120 | var aabb = new b2AABB(); 121 | aabb.minVertex.Set(lowerX - this.m_radius, lowerY - this.m_radius); 122 | aabb.maxVertex.Set(upperX + this.m_radius, upperY + this.m_radius); 123 | 124 | var broadPhase = this.m_body.m_world.m_broadPhase; 125 | if (broadPhase.InRange(aabb)) 126 | { 127 | broadPhase.MoveProxy(this.m_proxyId, aabb); 128 | } 129 | else 130 | { 131 | this.m_body.Freeze(); 132 | } 133 | }, 134 | 135 | QuickSync: function(position, R){ 136 | this.m_R.SetM(R); 137 | //this.m_position = position + b2Mul(R, this.m_localPosition); 138 | this.m_position.x = (R.col1.x * this.m_localPosition.x + R.col2.x * this.m_localPosition.y) + position.x; 139 | this.m_position.y = (R.col1.y * this.m_localPosition.x + R.col2.y * this.m_localPosition.y) + position.y; 140 | }, 141 | 142 | 143 | ResetProxy: function(broadPhase) 144 | { 145 | if (this.m_proxyId == b2Pair.b2_nullProxy) 146 | { 147 | return; 148 | } 149 | 150 | var proxy = broadPhase.GetProxy(this.m_proxyId); 151 | 152 | broadPhase.DestroyProxy(this.m_proxyId); 153 | proxy = null; 154 | 155 | var aabb = new b2AABB(); 156 | aabb.minVertex.Set(this.m_position.x - this.m_radius, this.m_position.y - this.m_radius); 157 | aabb.maxVertex.Set(this.m_position.x + this.m_radius, this.m_position.y + this.m_radius); 158 | 159 | if (broadPhase.InRange(aabb)) 160 | { 161 | this.m_proxyId = broadPhase.CreateProxy(aabb, this); 162 | } 163 | else 164 | { 165 | this.m_proxyId = b2Pair.b2_nullProxy; 166 | } 167 | 168 | if (this.m_proxyId == b2Pair.b2_nullProxy) 169 | { 170 | this.m_body.Freeze(); 171 | } 172 | }, 173 | 174 | 175 | Support: function(dX, dY, out) 176 | { 177 | //b2Vec2 u = d; 178 | //u.Normalize(); 179 | var len = Math.sqrt(dX*dX + dY*dY); 180 | dX /= len; 181 | dY /= len; 182 | //return this.m_position + this.m_radius * u; 183 | out.Set( this.m_position.x + this.m_radius*dX, 184 | this.m_position.y + this.m_radius*dY); 185 | }, 186 | 187 | 188 | // Local position in parent body 189 | m_localPosition: new b2Vec2(), 190 | m_radius: null 191 | }); 192 | 193 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2MassData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2MassData = function() { 21 | // initialize instance variables for references 22 | this.center = new b2Vec2(0,0); 23 | }; 24 | 25 | b2MassData.prototype = 26 | { 27 | mass: 0.0, 28 | center: new b2Vec2(0,0), 29 | I: 0.0, 30 | 31 | }; 32 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2PolyDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | var b2PolyDef = function() { 26 | // The constructor for b2ShapeDef 27 | this.type = b2Shape.e_unknownShape; 28 | this.userData = null; 29 | this.localPosition = new b2Vec2(0.0, 0.0); 30 | this.localRotation = 0.0; 31 | this.friction = 0.2; 32 | this.restitution = 0.0; 33 | this.density = 0.0; 34 | this.categoryBits = 0x0001; 35 | this.maskBits = 0xFFFF; 36 | this.groupIndex = 0; 37 | // 38 | 39 | // initialize instance variables for references 40 | this.vertices = new Array(b2Settings.b2_maxPolyVertices); 41 | // 42 | 43 | this.type = b2Shape.e_polyShape; 44 | this.vertexCount = 0; 45 | 46 | for (var i = b2Settings.b2_maxPolyVertices; i--;){ 47 | this.vertices[i] = new b2Vec2(); 48 | } 49 | }; 50 | 51 | Object.extend(b2PolyDef.prototype, b2ShapeDef.prototype); 52 | Object.extend(b2PolyDef.prototype, { 53 | vertices: new Array(b2Settings.b2_maxPolyVertices), 54 | vertexCount: 0 55 | }); 56 | 57 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2Shape.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | // Shapes are created automatically when a body is created. 20 | // Client code does not normally interact with shapes. 21 | var b2Shape = function(def, body) { 22 | // initialize instance variables for references 23 | this.m_R = new b2Mat22(); 24 | this.m_position = new b2Vec2(); 25 | // 26 | 27 | this.m_userData = def.userData; 28 | 29 | this.m_friction = def.friction; 30 | this.m_restitution = def.restitution; 31 | this.m_body = body; 32 | 33 | this.m_proxyId = b2Pair.b2_nullProxy; 34 | 35 | this.m_maxRadius = 0.0; 36 | 37 | this.m_categoryBits = def.categoryBits; 38 | this.m_maskBits = def.maskBits; 39 | this.m_groupIndex = def.groupIndex; 40 | }; 41 | 42 | b2Shape.prototype = { 43 | TestPoint: function(p){return false}, 44 | 45 | GetUserData: function(){return this.m_userData;}, 46 | 47 | GetType: function(){ 48 | return this.m_type; 49 | }, 50 | 51 | // Get the parent body of this shape. 52 | GetBody: function(){ 53 | return this.m_body; 54 | }, 55 | 56 | GetPosition: function(){ 57 | return this.m_position; 58 | }, 59 | GetRotationMatrix: function(){ 60 | return this.m_R; 61 | }, 62 | 63 | // Remove and then add proxy from the broad-phase. 64 | // This is used to refresh the collision filters. 65 | ResetProxy: function(broadPhase){}, 66 | 67 | // Get the next shape in the parent body's shape list. 68 | GetNext: function(){ 69 | return this.m_next; 70 | }, 71 | 72 | //--------------- Internals Below ------------------- 73 | 74 | 75 | 76 | 77 | // Internal use only. Do not call. 78 | //b2Shape::~b2Shape() 79 | //{ 80 | // this.m_body->m_world->m_broadPhase->this.DestroyProxy(this.m_proxyId); 81 | //} 82 | 83 | 84 | DestroyProxy: function() 85 | { 86 | if (this.m_proxyId != b2Pair.b2_nullProxy) 87 | { 88 | this.m_body.m_world.m_broadPhase.DestroyProxy(this.m_proxyId); 89 | this.m_proxyId = b2Pair.b2_nullProxy; 90 | } 91 | }, 92 | 93 | 94 | // Internal use only. Do not call. 95 | Synchronize: function(position1, R1, position2, R2){}, 96 | QuickSync: function(position, R){}, 97 | Support: function(dX, dY, out){}, 98 | GetMaxRadius: function(){ 99 | return this.m_maxRadius; 100 | }, 101 | 102 | m_next: null, 103 | 104 | m_R: new b2Mat22(), 105 | m_position: new b2Vec2(), 106 | 107 | m_type: 0, 108 | 109 | m_userData: null, 110 | 111 | m_body: null, 112 | 113 | m_friction: null, 114 | m_restitution: null, 115 | 116 | m_maxRadius: null, 117 | 118 | m_proxyId: 0, 119 | m_categoryBits: 0, 120 | m_maskBits: 0, 121 | m_groupIndex: 0 122 | }; 123 | 124 | 125 | b2Shape.Create = function(def, body, center) { 126 | switch (def.type) 127 | { 128 | case b2Shape.e_circleShape: 129 | { 130 | //void* mem = body->m_world->m_blockAllocator.Allocate(sizeof(b2CircleShape)); 131 | return new b2CircleShape(def, body, center); 132 | } 133 | 134 | case b2Shape.e_boxShape: 135 | case b2Shape.e_polyShape: 136 | { 137 | //void* mem = body->m_world->m_blockAllocator.Allocate(sizeof(b2PolyShape)); 138 | return new b2PolyShape(def, body, center); 139 | } 140 | } 141 | 142 | //b2Settings.b2Assert(false); 143 | return null; 144 | }; 145 | b2Shape.Destroy = function(shape) { 146 | /*b2BlockAllocator& allocator = shape->m_body->m_world->m_blockAllocator; 147 | 148 | switch (shape.m_type) 149 | { 150 | case b2Shape.e_circleShape: 151 | shape->~b2Shape(); 152 | allocator.Free(shape, sizeof(b2CircleShape)); 153 | break; 154 | 155 | case b2Shape.e_polyShape: 156 | shape->~b2Shape(); 157 | allocator.Free(shape, sizeof(b2PolyShape)); 158 | break; 159 | 160 | default: 161 | b2Assert(false); 162 | } 163 | 164 | shape = NULL;*/ 165 | 166 | // FROM DESTRUCTOR 167 | if (shape.m_proxyId != b2Pair.b2_nullProxy) 168 | shape.m_body.m_world.m_broadPhase.DestroyProxy(shape.m_proxyId); 169 | }; 170 | b2Shape.e_unknownShape = -1; 171 | b2Shape.e_circleShape = 0; 172 | b2Shape.e_boxShape = 1; 173 | b2Shape.e_polyShape = 2; 174 | b2Shape.e_meshShape = 3; 175 | b2Shape.e_shapeTypeCount = 4; 176 | b2Shape.PolyMass = function(massData, vs, count, rho) { 177 | //b2Settings.b2Assert(count >= 3); 178 | 179 | //var center = new b2Vec2(0.0, 0.0); 180 | var center = new b2Vec2(); 181 | center.SetZero(); 182 | 183 | var area = 0.0; 184 | var I = 0.0; 185 | 186 | // pRef is the reference point for forming triangles. 187 | // It's location doesn't change the result (except for rounding error). 188 | var pRef = new b2Vec2(0.0, 0.0); 189 | 190 | var inv3 = 1.0 / 3.0; 191 | 192 | for (var i = count; i--;) 193 | { 194 | // Triangle vertices. 195 | var p1 = pRef; 196 | var p2 = vs[i]; 197 | var p3 = i + 1 < count ? vs[i+1] : vs[0]; 198 | 199 | var e1 = b2Math.SubtractVV(p2, p1); 200 | var e2 = b2Math.SubtractVV(p3, p1); 201 | 202 | var D = b2Math.b2CrossVV(e1, e2); 203 | 204 | var triangleArea = 0.5 * D; 205 | area += triangleArea; 206 | 207 | // Area weighted centroid 208 | // center += triangleArea * inv3 * (p1 + p2 + p3); 209 | var tVec = new b2Vec2(); 210 | tVec.SetV(p1); 211 | tVec.Add(p2); 212 | tVec.Add(p3); 213 | tVec.Multiply(inv3*triangleArea); 214 | center.Add(tVec); 215 | 216 | var px = p1.x; 217 | var py = p1.y; 218 | var ex1 = e1.x; 219 | var ey1 = e1.y; 220 | var ex2 = e2.x; 221 | var ey2 = e2.y; 222 | 223 | var intx2 = inv3 * (0.25 * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5*px*px; 224 | var inty2 = inv3 * (0.25 * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5*py*py; 225 | 226 | I += D * (intx2 + inty2); 227 | } 228 | 229 | // Total mass 230 | massData.mass = rho * area; 231 | 232 | // Center of mass 233 | //b2Settings.b2Assert(area > Number.MIN_VALUE); 234 | center.Multiply( 1.0 / area ); 235 | massData.center = center; 236 | 237 | // Inertia tensor relative to the center. 238 | I = rho * (I - area * b2Math.b2Dot(center, center)); 239 | massData.I = I; 240 | }; 241 | b2Shape.PolyCentroid = function(vs, count, out) { 242 | //b2Settings.b2Assert(count >= 3); 243 | 244 | //b2Vec2 c; c.Set(0.0f, 0.0f); 245 | var cX = 0.0; 246 | var cY = 0.0; 247 | //float32 area = 0.0f; 248 | var area = 0.0; 249 | 250 | // pRef is the reference point for forming triangles. 251 | // It's location doesn't change the result (except for rounding error). 252 | //b2Vec2 pRef(0.0f, 0.0f); 253 | var pRefX = 0.0; 254 | var pRefY = 0.0; 255 | /* 256 | // This code would put the reference point inside the polygon. 257 | for (var i = 0; i < count; ++i) 258 | { 259 | //pRef += vs[i]; 260 | pRef.x += vs[i].x; 261 | pRef.y += vs[i].y; 262 | } 263 | pRef.x *= 1.0 / count; 264 | pRef.y *= 1.0 / count; 265 | */ 266 | 267 | //const float32 inv3 = 1.0f / 3.0f; 268 | var inv3 = 1.0 / 3.0; 269 | 270 | for (var i = count; i--;) 271 | { 272 | // Triangle vertices. 273 | //b2Vec2 p1 = pRef; 274 | var p1X = pRefX; 275 | var p1Y = pRefY; 276 | //b2Vec2 p2 = vs[i]; 277 | var p2X = vs[i].x; 278 | var p2Y = vs[i].y; 279 | //b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0]; 280 | var p3X = i + 1 < count ? vs[i+1].x : vs[0].x; 281 | var p3Y = i + 1 < count ? vs[i+1].y : vs[0].y; 282 | 283 | //b2Vec2 e1 = p2 - p1; 284 | var e1X = p2X - p1X; 285 | var e1Y = p2Y - p1Y; 286 | //b2Vec2 e2 = p3 - p1; 287 | var e2X = p3X - p1X; 288 | var e2Y = p3Y - p1Y; 289 | 290 | //float32 D = b2Cross(e1, e2); 291 | var D = (e1X * e2Y - e1Y * e2X); 292 | 293 | //float32 triangleArea = 0.5f * D; 294 | var triangleArea = 0.5 * D; 295 | area += triangleArea; 296 | 297 | // Area weighted centroid 298 | //c += triangleArea * inv3 * (p1 + p2 + p3); 299 | cX += triangleArea * inv3 * (p1X + p2X + p3X); 300 | cY += triangleArea * inv3 * (p1Y + p2Y + p3Y); 301 | } 302 | 303 | // Centroid 304 | //b2Settings.b2Assert(area > Number.MIN_VALUE); 305 | cX *= 1.0 / area; 306 | cY *= 1.0 / area; 307 | 308 | // Replace return with 'out' vector 309 | //return c; 310 | out.Set(cX, cY); 311 | }; 312 | -------------------------------------------------------------------------------- /js/box2d/collision/shapes/b2ShapeDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2ShapeDef = function() { 20 | this.type = b2Shape.e_unknownShape; 21 | this.userData = null; 22 | this.localPosition = new b2Vec2(0.0, 0.0); 23 | this.localRotation = 0.0; 24 | this.friction = 0.2; 25 | this.restitution = 0.0; 26 | this.density = 0.0; 27 | this.categoryBits = 0x0001; 28 | this.maskBits = 0xFFFF; 29 | this.groupIndex = 0; 30 | }; 31 | 32 | b2ShapeDef.prototype = { 33 | //virtual ~b2ShapeDef() {} 34 | 35 | ComputeMass: function(massData) 36 | { 37 | 38 | massData.center = new b2Vec2(0.0, 0.0) 39 | 40 | if (this.density == 0.0) 41 | { 42 | massData.mass = 0.0; 43 | massData.center.Set(0.0, 0.0); 44 | massData.I = 0.0; 45 | }; 46 | 47 | switch (this.type) 48 | { 49 | case b2Shape.e_circleShape: 50 | { 51 | var circle = this; 52 | massData.mass = this.density * b2Settings.b2_pi * circle.radius * circle.radius; 53 | massData.center.Set(0.0, 0.0); 54 | massData.I = 0.5 * (massData.mass) * circle.radius * circle.radius; 55 | } 56 | break; 57 | 58 | case b2Shape.e_boxShape: 59 | { 60 | var box = this; 61 | massData.mass = 4.0 * this.density * box.extents.x * box.extents.y; 62 | massData.center.Set(0.0, 0.0); 63 | massData.I = massData.mass / 3.0 * b2Math.b2Dot(box.extents, box.extents); 64 | } 65 | break; 66 | 67 | case b2Shape.e_polyShape: 68 | { 69 | var poly = this; 70 | b2Shape.PolyMass(massData, poly.vertices, poly.vertexCount, this.density); 71 | } 72 | break; 73 | 74 | default: 75 | massData.mass = 0.0; 76 | massData.center.Set(0.0, 0.0); 77 | massData.I = 0.0; 78 | break; 79 | } 80 | }, 81 | 82 | type: 0, 83 | userData: null, 84 | localPosition: null, 85 | localRotation: null, 86 | friction: null, 87 | restitution: null, 88 | density: null, 89 | 90 | // The collision category bits. Normally you would just set one bit. 91 | categoryBits: 0, 92 | 93 | // The collision mask bits. This states the categories that this 94 | // shape would accept for collision. 95 | maskBits: 0, 96 | 97 | // Collision groups allow a certain group of objects to never collide (negative) 98 | // or always collide (positive). Zero means no collision group. Non-zero group 99 | // filtering always wins against the mask bits. 100 | groupIndex: 0 101 | }; 102 | -------------------------------------------------------------------------------- /js/box2d/common/b2Settings.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | /* 24 | var b2Settings = Class.create(); 25 | b2Settings.prototype = { 26 | 27 | 28 | 29 | 30 | // Define your unit system here. The default system is 31 | // meters-kilograms-seconds. For the tuning to work well, 32 | // your dynamic objects should be bigger than a pebble and smaller 33 | // than a house. 34 | //static public const b2Settings.b2_lengthUnitsPerMeter = 1.0; 35 | 36 | // Use this for pixels: 37 | 38 | // Global tuning constants based on MKS units. 39 | 40 | // Collision 41 | 42 | // Dynamics 43 | 44 | // Sleep 45 | 46 | // assert 47 | 48 | initialize: function() {} 49 | }; 50 | */ 51 | var b2Settings = {}; 52 | 53 | b2Settings.USHRT_MAX = 0x0000ffff; 54 | b2Settings.b2_pi = Math.PI; 55 | b2Settings.b2_massUnitsPerKilogram = 1.0; 56 | b2Settings.b2_timeUnitsPerSecond = 1.0; 57 | b2Settings.b2_lengthUnitsPerMeter = 200.0; 58 | b2Settings.b2_maxManifoldPoints = 2; 59 | b2Settings.b2_maxShapesPerBody = 64; 60 | b2Settings.b2_maxPolyVertices = 8; 61 | b2Settings.b2_maxProxies = 1024; 62 | b2Settings.b2_maxPairs = 8 * b2Settings.b2_maxProxies; 63 | b2Settings.b2_linearSlop = 0.005 * b2Settings.b2_lengthUnitsPerMeter; 64 | b2Settings.b2_angularSlop = 2.0 / 180.0 * b2Settings.b2_pi; 65 | b2Settings.b2_velocityThreshold = 1.0 * b2Settings.b2_lengthUnitsPerMeter / b2Settings.b2_timeUnitsPerSecond; 66 | b2Settings.b2_maxLinearCorrection = 0.2 * b2Settings.b2_lengthUnitsPerMeter; 67 | b2Settings.b2_maxAngularCorrection = 8.0 / 180.0 * b2Settings.b2_pi; 68 | b2Settings.b2_contactBaumgarte = 0.2; 69 | b2Settings.b2_timeToSleep = 0.5 * b2Settings.b2_timeUnitsPerSecond; 70 | b2Settings.b2_linearSleepTolerance = 0.01 * b2Settings.b2_lengthUnitsPerMeter / b2Settings.b2_timeUnitsPerSecond; 71 | b2Settings.b2_angularSleepTolerance = 2.0 / 180.0 / b2Settings.b2_timeUnitsPerSecond; 72 | /* 73 | b2Settings.b2Assert = function(a) 74 | { 75 | if (!a){ 76 | var nullVec; 77 | nullVec.x++; 78 | } 79 | }; 80 | */ 81 | -------------------------------------------------------------------------------- /js/box2d/common/math/b2Mat22.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2Mat22 = function(angle, c1, c2) { 24 | if (angle==null) angle = 0; 25 | // initialize instance variables for references 26 | this.col1 = new b2Vec2(); 27 | this.col2 = new b2Vec2(); 28 | // 29 | 30 | if (c1!=null && c2!=null){ 31 | this.col1.SetV(c1); 32 | this.col2.SetV(c2); 33 | } 34 | else{ 35 | var c = Math.cos(angle); 36 | var s = Math.sin(angle); 37 | this.col1.x = c; this.col2.x = -s; 38 | this.col1.y = s; this.col2.y = c; 39 | } 40 | } 41 | 42 | b2Mat22.prototype = 43 | { 44 | Set: function(angle) 45 | { 46 | var c = Math.cos(angle); 47 | var s = Math.sin(angle); 48 | this.col1.x = c; this.col2.x = -s; 49 | this.col1.y = s; this.col2.y = c; 50 | }, 51 | 52 | SetVV: function(c1, c2) 53 | { 54 | this.col1.SetV(c1); 55 | this.col2.SetV(c2); 56 | }, 57 | 58 | Copy: function(){ 59 | return new b2Mat22(0, this.col1, this.col2); 60 | }, 61 | 62 | SetM: function(m) 63 | { 64 | this.col1.SetV(m.col1); 65 | this.col2.SetV(m.col2); 66 | }, 67 | 68 | AddM: function(m) 69 | { 70 | this.col1.x += m.col1.x; 71 | this.col1.y += m.col1.y; 72 | this.col2.x += m.col2.x; 73 | this.col2.y += m.col2.y; 74 | }, 75 | 76 | SetIdentity: function() 77 | { 78 | this.col1.x = 1.0; this.col2.x = 0.0; 79 | this.col1.y = 0.0; this.col2.y = 1.0; 80 | }, 81 | 82 | SetZero: function() 83 | { 84 | this.col1.x = 0.0; this.col2.x = 0.0; 85 | this.col1.y = 0.0; this.col2.y = 0.0; 86 | }, 87 | 88 | Invert: function(out) 89 | { 90 | var a = this.col1.x; 91 | var b = this.col2.x; 92 | var c = this.col1.y; 93 | var d = this.col2.y; 94 | //var B = new b2Mat22(); 95 | var det = a * d - b * c; 96 | //b2Settings.b2Assert(det != 0.0); 97 | det = 1.0 / det; 98 | out.col1.x = det * d; out.col2.x = -det * b; 99 | out.col1.y = -det * c; out.col2.y = det * a; 100 | return out; 101 | }, 102 | 103 | // this.Solve A * x = b 104 | Solve: function(out, bX, bY) 105 | { 106 | //float32 a11 = this.col1.x, a12 = this.col2.x, a21 = this.col1.y, a22 = this.col2.y; 107 | var a11 = this.col1.x; 108 | var a12 = this.col2.x; 109 | var a21 = this.col1.y; 110 | var a22 = this.col2.y; 111 | //float32 det = a11 * a22 - a12 * a21; 112 | var det = a11 * a22 - a12 * a21; 113 | //b2Settings.b2Assert(det != 0.0); 114 | det = 1.0 / det; 115 | out.x = det * (a22 * bX - a12 * bY); 116 | out.y = det * (a11 * bY - a21 * bX); 117 | 118 | return out; 119 | }, 120 | 121 | Abs: function() 122 | { 123 | this.col1.Abs(); 124 | this.col2.Abs(); 125 | }, 126 | 127 | col1: new b2Vec2(), 128 | col2: new b2Vec2() 129 | }; 130 | -------------------------------------------------------------------------------- /js/box2d/common/math/b2Math.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2Math = {}; 22 | b2Math.b2IsValid = function(x) 23 | { 24 | return isFinite(x); 25 | }; 26 | b2Math.b2Dot = function(a, b) 27 | { 28 | return a.x * b.x + a.y * b.y; 29 | }; 30 | b2Math.b2CrossVV = function(a, b) 31 | { 32 | return a.x * b.y - a.y * b.x; 33 | }; 34 | b2Math.b2CrossVF = function(a, s) 35 | { 36 | var v = new b2Vec2(s * a.y, -s * a.x); 37 | return v; 38 | }; 39 | b2Math.b2CrossFV = function(s, a) 40 | { 41 | var v = new b2Vec2(-s * a.y, s * a.x); 42 | return v; 43 | }; 44 | b2Math.b2MulMV = function(A, v) 45 | { 46 | var u = new b2Vec2(A.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.y * v.y); 47 | return u; 48 | }; 49 | b2Math.b2MulTMV = function(A, v) 50 | { 51 | var u = new b2Vec2(b2Math.b2Dot(v, A.col1), b2Math.b2Dot(v, A.col2)); 52 | return u; 53 | }; 54 | b2Math.AddVV = function(a, b) 55 | { 56 | var v = new b2Vec2(a.x + b.x, a.y + b.y); 57 | return v; 58 | }; 59 | b2Math.SubtractVV = function(a, b) 60 | { 61 | var v = new b2Vec2(a.x - b.x, a.y - b.y); 62 | return v; 63 | }; 64 | b2Math.MulFV = function(s, a) 65 | { 66 | var v = new b2Vec2(s * a.x, s * a.y); 67 | return v; 68 | }; 69 | b2Math.AddMM = function(A, B) 70 | { 71 | var C = new b2Mat22(0, b2Math.AddVV(A.col1, B.col1), b2Math.AddVV(A.col2, B.col2)); 72 | return C; 73 | }; 74 | b2Math.b2MulMM = function(A, B) 75 | { 76 | var C = new b2Mat22(0, b2Math.b2MulMV(A, B.col1), b2Math.b2MulMV(A, B.col2)); 77 | return C; 78 | }; 79 | b2Math.b2MulTMM = function(A, B) 80 | { 81 | var c1 = new b2Vec2(b2Math.b2Dot(A.col1, B.col1), b2Math.b2Dot(A.col2, B.col1)); 82 | var c2 = new b2Vec2(b2Math.b2Dot(A.col1, B.col2), b2Math.b2Dot(A.col2, B.col2)); 83 | var C = new b2Mat22(0, c1, c2); 84 | return C; 85 | }; 86 | b2Math.b2Abs = function(a) 87 | { 88 | return a > 0.0 ? a : -a; 89 | }; 90 | b2Math.b2AbsV = function(a) 91 | { 92 | var b = new b2Vec2(b2Math.b2Abs(a.x), b2Math.b2Abs(a.y)); 93 | return b; 94 | }; 95 | b2Math.b2AbsM = function(A) 96 | { 97 | var B = new b2Mat22(0, b2Math.b2AbsV(A.col1), b2Math.b2AbsV(A.col2)); 98 | return B; 99 | }; 100 | b2Math.b2Min = function(a, b) 101 | { 102 | return a < b ? a : b; 103 | }; 104 | b2Math.b2MinV = function(a, b) 105 | { 106 | var c = new b2Vec2(b2Math.b2Min(a.x, b.x), b2Math.b2Min(a.y, b.y)); 107 | return c; 108 | }; 109 | b2Math.b2Max = function(a, b) 110 | { 111 | return a > b ? a : b; 112 | }; 113 | b2Math.b2MaxV = function(a, b) 114 | { 115 | var c = new b2Vec2(b2Math.b2Max(a.x, b.x), b2Math.b2Max(a.y, b.y)); 116 | return c; 117 | }; 118 | b2Math.b2Clamp = function(a, low, high) 119 | { 120 | return b2Math.b2Max(low, b2Math.b2Min(a, high)); 121 | }; 122 | b2Math.b2ClampV = function(a, low, high) 123 | { 124 | return b2Math.b2MaxV(low, b2Math.b2MinV(a, high)); 125 | }; 126 | b2Math.b2Swap = function(a, b) 127 | { 128 | var tmp = a[0]; 129 | a[0] = b[0]; 130 | b[0] = tmp; 131 | }; 132 | b2Math.b2Random = function() 133 | { 134 | return Math.random() * 2 - 1; 135 | }; 136 | b2Math.b2NextPowerOfTwo = function(x) 137 | { 138 | x |= (x >> 1) & 0x7FFFFFFF; 139 | x |= (x >> 2) & 0x3FFFFFFF; 140 | x |= (x >> 4) & 0x0FFFFFFF; 141 | x |= (x >> 8) & 0x00FFFFFF; 142 | x |= (x >> 16)& 0x0000FFFF; 143 | return x + 1; 144 | }; 145 | b2Math.b2IsPowerOfTwo = function(x) 146 | { 147 | var result = x > 0 && (x & (x - 1)) == 0; 148 | return result; 149 | }; 150 | b2Math.tempVec2 = new b2Vec2(); 151 | b2Math.tempVec3 = new b2Vec2(); 152 | b2Math.tempVec4 = new b2Vec2(); 153 | b2Math.tempVec5 = new b2Vec2(); 154 | b2Math.tempMat = new b2Mat22(); 155 | -------------------------------------------------------------------------------- /js/box2d/common/math/b2Vec2.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2Vec2 = function (x_,y_) { 21 | this.x=x_; this.y=y_; 22 | }; 23 | 24 | b2Vec2.prototype = { 25 | 26 | SetZero: function() { this.x = 0.0; this.y = 0.0; }, 27 | Set: function(x_, y_) {this.x=x_; this.y=y_;}, 28 | SetV: function(v) {this.x=v.x; this.y=v.y;}, 29 | 30 | Negative: function() { 31 | return new b2Vec2(-this.x, -this.y); 32 | }, 33 | 34 | 35 | Copy: function(){ 36 | return new b2Vec2(this.x,this.y); 37 | }, 38 | 39 | Add: function(v) 40 | { 41 | this.x += v.x; this.y += v.y; 42 | }, 43 | 44 | Subtract: function(v) 45 | { 46 | this.x -= v.x; this.y -= v.y; 47 | }, 48 | 49 | Multiply: function(a) 50 | { 51 | this.x *= a; this.y *= a; 52 | }, 53 | 54 | MulM: function(A) 55 | { 56 | var tX = this.x; 57 | this.x = A.col1.x * tX + A.col2.x * this.y; 58 | this.y = A.col1.y * tX + A.col2.y * this.y; 59 | }, 60 | 61 | MulTM: function(A) 62 | { 63 | var tX = b2Math.b2Dot(this, A.col1); 64 | this.y = b2Math.b2Dot(this, A.col2); 65 | this.x = tX; 66 | }, 67 | 68 | CrossVF: function(s) 69 | { 70 | var tX = this.x; 71 | this.x = s * this.y; 72 | this.y = -s * tX; 73 | }, 74 | 75 | CrossFV: function(s) 76 | { 77 | var tX = this.x; 78 | this.x = -s * this.y; 79 | this.y = s * tX; 80 | }, 81 | 82 | MinV: function(b) 83 | { 84 | this.x = this.x < b.x ? this.x : b.x; 85 | this.y = this.y < b.y ? this.y : b.y; 86 | }, 87 | 88 | MaxV: function(b) 89 | { 90 | this.x = this.x > b.x ? this.x : b.x; 91 | this.y = this.y > b.y ? this.y : b.y; 92 | }, 93 | 94 | Abs: function() 95 | { 96 | this.x = Math.abs(this.x); 97 | this.y = Math.abs(this.y); 98 | }, 99 | 100 | Length: function() 101 | { 102 | return Math.sqrt(this.x * this.x + this.y * this.y); 103 | }, 104 | 105 | Normalize: function() 106 | { 107 | var length = this.Length(); 108 | if (length < Number.MIN_VALUE) 109 | { 110 | return 0.0; 111 | } 112 | var invLength = 1.0 / length; 113 | this.x *= invLength; 114 | this.y *= invLength; 115 | 116 | return length; 117 | }, 118 | 119 | IsValid: function() 120 | { 121 | return b2Math.b2IsValid(this.x) && b2Math.b2IsValid(this.y); 122 | }, 123 | 124 | x: null, 125 | y: null 126 | }; 127 | 128 | -------------------------------------------------------------------------------- /js/box2d/dynamics/b2BodyDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2BodyDef = function() { 20 | // initialize instance variables for references 21 | this.shapes = new Array(); 22 | // 23 | 24 | this.userData = null; 25 | for (var i = b2Settings.b2_maxShapesPerBody; i--;){ 26 | this.shapes[i] = null; 27 | } 28 | this.position = new b2Vec2(0.0, 0.0); 29 | this.rotation = 0.0; 30 | this.linearVelocity = new b2Vec2(0.0, 0.0); 31 | this.angularVelocity = 0.0; 32 | this.linearDamping = 0.0; 33 | this.angularDamping = 0.0; 34 | this.allowSleep = true; 35 | this.isSleeping = false; 36 | this.preventRotation = false; 37 | }; 38 | 39 | b2BodyDef.prototype = { 40 | 41 | userData: null, 42 | shapes: new Array(), 43 | position: null, 44 | rotation: null, 45 | linearVelocity: null, 46 | angularVelocity: null, 47 | linearDamping: null, 48 | angularDamping: null, 49 | allowSleep: null, 50 | isSleeping: null, 51 | preventRotation: null, 52 | 53 | AddShape: function(shape) 54 | { 55 | for (var i = 0; i < b2Settings.b2_maxShapesPerBody; ++i) 56 | { 57 | if (this.shapes[i] == null) 58 | { 59 | this.shapes[i] = shape; 60 | break; 61 | } 62 | } 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /js/box2d/dynamics/b2CollisionFilter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2CollisionFilter = function() {}; 20 | b2CollisionFilter.prototype = { 21 | 22 | // Return true if contact calculations should be performed between these two shapes. 23 | ShouldCollide: function(shape1, shape2){ 24 | if (shape1.m_groupIndex == shape2.m_groupIndex && shape1.m_groupIndex != 0) 25 | { 26 | return shape1.m_groupIndex > 0; 27 | } 28 | 29 | var collide = (shape1.m_maskBits & shape2.m_categoryBits) != 0 && (shape1.m_categoryBits & shape2.m_maskBits) != 0; 30 | return collide; 31 | }, 32 | 33 | }; 34 | 35 | b2CollisionFilter.b2_defaultFilter = new b2CollisionFilter; 36 | -------------------------------------------------------------------------------- /js/box2d/dynamics/b2ContactManager.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2ContactManager = function(){ 24 | // The constructor for b2PairCallback 25 | // 26 | 27 | // initialize instance variables for references 28 | this.m_nullContact = new b2NullContact(); 29 | // 30 | 31 | this.m_world = null; 32 | this.m_destroyImmediate = false; 33 | }; 34 | Object.extend(b2ContactManager.prototype, b2PairCallback.prototype); 35 | Object.extend(b2ContactManager.prototype, { 36 | 37 | // This is a callback from the broadphase when two AABB proxies begin 38 | // to overlap. We create a b2Contact to manage the narrow phase. 39 | PairAdded: function(proxyUserData1, proxyUserData2){ 40 | var shape1 = proxyUserData1; 41 | var shape2 = proxyUserData2; 42 | 43 | var body1 = shape1.m_body; 44 | var body2 = shape2.m_body; 45 | 46 | if (body1.IsStatic() && body2.IsStatic()) 47 | { 48 | return this.m_nullContact; 49 | } 50 | 51 | if (shape1.m_body == shape2.m_body) 52 | { 53 | return this.m_nullContact; 54 | } 55 | 56 | if (body2.IsConnected(body1)) 57 | { 58 | return this.m_nullContact; 59 | } 60 | 61 | if (this.m_world.m_filter != null && this.m_world.m_filter.ShouldCollide(shape1, shape2) == false) 62 | { 63 | return this.m_nullContact; 64 | } 65 | 66 | // Ensure that body2 is dynamic (body1 is static or dynamic). 67 | if (body2.m_invMass == 0.0) 68 | { 69 | var tempShape = shape1; 70 | shape1 = shape2; 71 | shape2 = tempShape; 72 | //b2Math.b2Swap(shape1, shape2); 73 | var tempBody = body1; 74 | body1 = body2; 75 | body2 = tempBody; 76 | //b2Math.b2Swap(body1, body2); 77 | } 78 | 79 | // Call the factory. 80 | var contact = b2Contact.Create(shape1, shape2, this.m_world.m_blockAllocator); 81 | 82 | if (contact == null) 83 | { 84 | return this.m_nullContact; 85 | } 86 | else 87 | { 88 | // Insert into the world. 89 | contact.m_prev = null; 90 | contact.m_next = this.m_world.m_contactList; 91 | if (this.m_world.m_contactList != null) 92 | { 93 | this.m_world.m_contactList.m_prev = contact; 94 | } 95 | this.m_world.m_contactList = contact; 96 | this.m_world.m_contactCount++; 97 | } 98 | 99 | return contact; 100 | }, 101 | 102 | // This is a callback from the broadphase when two AABB proxies cease 103 | // to overlap. We destroy the b2Contact. 104 | PairRemoved: function(proxyUserData1, proxyUserData2, pairUserData){ 105 | 106 | if (pairUserData == null) 107 | { 108 | return; 109 | } 110 | 111 | var c = pairUserData; 112 | if (c != this.m_nullContact) 113 | { 114 | //b2Settings.b2Assert(this.m_world.m_contactCount > 0); 115 | if (this.m_destroyImmediate == true) 116 | { 117 | this.DestroyContact(c); 118 | c = null; 119 | } 120 | else 121 | { 122 | c.m_flags |= b2Contact.e_destroyFlag; 123 | } 124 | } 125 | }, 126 | 127 | DestroyContact: function(c) 128 | { 129 | 130 | //b2Settings.b2Assert(this.m_world.m_contactCount > 0); 131 | 132 | // Remove from the world. 133 | if (c.m_prev) 134 | { 135 | c.m_prev.m_next = c.m_next; 136 | } 137 | 138 | if (c.m_next) 139 | { 140 | c.m_next.m_prev = c.m_prev; 141 | } 142 | 143 | if (c == this.m_world.m_contactList) 144 | { 145 | this.m_world.m_contactList = c.m_next; 146 | } 147 | 148 | // If there are contact points, then disconnect from the island graph. 149 | if (c.GetManifoldCount() > 0) 150 | { 151 | var body1 = c.m_shape1.m_body; 152 | var body2 = c.m_shape2.m_body; 153 | var node1 = c.m_node1; 154 | var node2 = c.m_node2; 155 | 156 | // Wake up touching bodies. 157 | body1.WakeUp(); 158 | body2.WakeUp(); 159 | 160 | // Remove from body 1 161 | if (node1.prev) 162 | { 163 | node1.prev.next = node1.next; 164 | } 165 | 166 | if (node1.next) 167 | { 168 | node1.next.prev = node1.prev; 169 | } 170 | 171 | if (node1 == body1.m_contactList) 172 | { 173 | body1.m_contactList = node1.next; 174 | } 175 | 176 | node1.prev = null; 177 | node1.next = null; 178 | 179 | // Remove from body 2 180 | if (node2.prev) 181 | { 182 | node2.prev.next = node2.next; 183 | } 184 | 185 | if (node2.next) 186 | { 187 | node2.next.prev = node2.prev; 188 | } 189 | 190 | if (node2 == body2.m_contactList) 191 | { 192 | body2.m_contactList = node2.next; 193 | } 194 | 195 | node2.prev = null; 196 | node2.next = null; 197 | } 198 | 199 | // Call the factory. 200 | b2Contact.Destroy(c, this.m_world.m_blockAllocator); 201 | --this.m_world.m_contactCount; 202 | }, 203 | 204 | 205 | // Destroy any contacts marked for deferred destruction. 206 | CleanContactList: function() 207 | { 208 | var c = this.m_world.m_contactList; 209 | while (c != null) 210 | { 211 | var c0 = c; 212 | c = c.m_next; 213 | 214 | if (c0.m_flags & b2Contact.e_destroyFlag) 215 | { 216 | this.DestroyContact(c0); 217 | c0 = null; 218 | } 219 | } 220 | }, 221 | 222 | 223 | // This is the top level collision call for the time step. Here 224 | // all the narrow phase collision is processed for the world 225 | // contact list. 226 | Collide: function() 227 | { 228 | var body1; 229 | var body2; 230 | var node1; 231 | var node2; 232 | 233 | for (var c = this.m_world.m_contactList; c != null; c = c.m_next) 234 | { 235 | if (c.m_shape1.m_body.IsSleeping() && 236 | c.m_shape2.m_body.IsSleeping()) { 237 | continue; 238 | } 239 | 240 | var oldCount = c.GetManifoldCount(); 241 | c.Evaluate(); 242 | 243 | var newCount = c.GetManifoldCount(); 244 | 245 | if (oldCount == 0 && newCount > 0) 246 | { 247 | //b2Settings.b2Assert(c.GetManifolds().pointCount > 0); 248 | 249 | // Connect to island graph. 250 | body1 = c.m_shape1.m_body; 251 | body2 = c.m_shape2.m_body; 252 | node1 = c.m_node1; 253 | node2 = c.m_node2; 254 | 255 | // Connect to body 1 256 | node1.contact = c; 257 | node1.other = body2; 258 | 259 | node1.prev = null; 260 | node1.next = body1.m_contactList; 261 | if (node1.next != null) { 262 | node1.next.prev = c.m_node1; 263 | } 264 | body1.m_contactList = c.m_node1; 265 | 266 | // Connect to body 2 267 | node2.contact = c; 268 | node2.other = body1; 269 | 270 | node2.prev = null; 271 | node2.next = body2.m_contactList; 272 | if (node2.next != null) { 273 | node2.next.prev = node2; 274 | } 275 | body2.m_contactList = node2; 276 | } else if (oldCount > 0 && newCount == 0) { 277 | // Disconnect from island graph. 278 | body1 = c.m_shape1.m_body; 279 | body2 = c.m_shape2.m_body; 280 | node1 = c.m_node1; 281 | node2 = c.m_node2; 282 | 283 | // Remove from body 1 284 | if (node1.prev) { 285 | node1.prev.next = node1.next; 286 | } 287 | 288 | if (node1.next) { 289 | node1.next.prev = node1.prev; 290 | } 291 | 292 | if (node1 == body1.m_contactList) { 293 | body1.m_contactList = node1.next; 294 | } 295 | 296 | node1.prev = null; 297 | node1.next = null; 298 | 299 | // Remove from body 2 300 | if (node2.prev) { 301 | node2.prev.next = node2.next; 302 | } 303 | 304 | if (node2.next) { 305 | node2.next.prev = node2.prev; 306 | } 307 | 308 | if (node2 == body2.m_contactList) { 309 | body2.m_contactList = node2.next; 310 | } 311 | 312 | node2.prev = null; 313 | node2.next = null; 314 | } 315 | } 316 | }, 317 | 318 | m_world: null, 319 | 320 | // This lets us provide broadphase proxy pair user data for 321 | // contacts that shouldn't exist. 322 | m_nullContact: new b2NullContact(), 323 | m_destroyImmediate: null 324 | }); 325 | 326 | -------------------------------------------------------------------------------- /js/box2d/dynamics/b2TimeStep.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | var b2TimeStep = function(){}; 22 | 23 | b2TimeStep.prototype = 24 | { 25 | dt: null, 26 | inv_dt: null, 27 | iterations: 0 28 | }; 29 | -------------------------------------------------------------------------------- /js/box2d/dynamics/b2WorldListener.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2WorldListener = function() {}; 20 | 21 | b2WorldListener.prototype = { 22 | 23 | // If a body is destroyed, then any joints attached to it are also destroyed. 24 | // This prevents memory leaks, but you may unexpectedly be left with an 25 | // orphaned joint pointer. 26 | // Box2D will notify you when a joint is implicitly destroyed. 27 | // It is NOT called if you directly destroy a joint. 28 | // Implement this abstract class and provide it to b2World via 29 | // b2World::SetListener(). 30 | // DO NOT modify the Box2D world inside this callback. 31 | NotifyJointDestroyed: function(joint){}, 32 | 33 | // This is called when a body's shape passes outside of the world boundary. If you 34 | // override this and pass back e_destroyBody, you must nullify your copies of the 35 | // body pointer. 36 | NotifyBoundaryViolated: function(body) 37 | { 38 | //NOT_USED(body); 39 | return b2WorldListener.b2_freezeBody; 40 | }, 41 | 42 | }; 43 | b2WorldListener.b2_freezeBody = 0; 44 | b2WorldListener.b2_destroyBody = 1; 45 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2CircleContact.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2CircleContact = function(s1, s2) { 21 | // The constructor for b2Contact 22 | // initialize instance variables for references 23 | this.m_node1 = new b2ContactNode(); 24 | this.m_node2 = new b2ContactNode(); 25 | // 26 | this.m_flags = 0; 27 | 28 | if (!s1 || !s2){ 29 | this.m_shape1 = null; 30 | this.m_shape2 = null; 31 | return; 32 | } 33 | 34 | this.m_shape1 = s1; 35 | this.m_shape2 = s2; 36 | 37 | this.m_manifoldCount = 0; 38 | 39 | this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction); 40 | this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution); 41 | 42 | this.m_prev = null; 43 | this.m_next = null; 44 | 45 | this.m_node1.contact = null; 46 | this.m_node1.prev = null; 47 | this.m_node1.next = null; 48 | this.m_node1.other = null; 49 | 50 | this.m_node2.contact = null; 51 | this.m_node2.prev = null; 52 | this.m_node2.next = null; 53 | this.m_node2.other = null; 54 | // 55 | 56 | // initialize instance variables for references 57 | this.m_manifold = [new b2Manifold()]; 58 | // 59 | 60 | this.m_manifold[0].pointCount = 0; 61 | this.m_manifold[0].points[0].normalImpulse = 0.0; 62 | this.m_manifold[0].points[0].tangentImpulse = 0.0; 63 | }; 64 | 65 | Object.extend(b2CircleContact.prototype, b2Contact.prototype); 66 | Object.extend(b2CircleContact.prototype, { 67 | Evaluate: function(){ 68 | b2Collision.b2CollideCircle(this.m_manifold[0], this.m_shape1, this.m_shape2, false); 69 | 70 | if (this.m_manifold[0].pointCount > 0) 71 | { 72 | this.m_manifoldCount = 1; 73 | } 74 | else 75 | { 76 | this.m_manifoldCount = 0; 77 | } 78 | }, 79 | 80 | GetManifolds: function() 81 | { 82 | return this.m_manifold; 83 | }, 84 | 85 | m_manifold: [new b2Manifold()] 86 | }); 87 | 88 | b2CircleContact.Create = function(shape1, shape2, allocator){ 89 | return new b2CircleContact(shape1, shape2); 90 | }; 91 | 92 | b2CircleContact.Destroy = function(){ }; 93 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2Conservative.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2Conservative = function() {}; 24 | 25 | // Temp vars 26 | b2Conservative.R1 = new b2Mat22(); 27 | b2Conservative.R2 = new b2Mat22(); 28 | b2Conservative.x1 = new b2Vec2(); 29 | b2Conservative.x2 = new b2Vec2(); 30 | 31 | b2Conservative.Conservative = function(shape1, shape2) { 32 | var body1 = shape1.GetBody(); 33 | var body2 = shape2.GetBody(); 34 | 35 | //b2Vec2 v1 = body1->m_position - body1->m_position0; 36 | var v1X = body1.m_position.x - body1.m_position0.x; 37 | var v1Y = body1.m_position.y - body1.m_position0.y; 38 | //float32 omega1 = body1->m_rotation - body1->m_rotation0; 39 | var omega1 = body1.m_rotation - body1.m_rotation0; 40 | //b2Vec2 v2 = body2->m_position - body2->m_position0; 41 | var v2X = body2.m_position.x - body2.m_position0.x; 42 | var v2Y = body2.m_position.y - body2.m_position0.y; 43 | //float32 omega2 = body2->m_rotation - body2->m_rotation0; 44 | var omega2 = body2.m_rotation - body2.m_rotation0; 45 | 46 | //float32 r1 = shape1->GetMaxRadius(); 47 | var r1 = shape1.GetMaxRadius(); 48 | //float32 r2 = shape2->GetMaxRadius(); 49 | var r2 = shape2.GetMaxRadius(); 50 | 51 | //b2Vec2 p1Start = body1->m_position0; 52 | var p1StartX = body1.m_position0.x; 53 | var p1StartY = body1.m_position0.y; 54 | //float32 a1Start = body1->m_rotation0; 55 | var a1Start = body1.m_rotation0; 56 | 57 | //b2Vec2 p2Start = body2->m_position0; 58 | var p2StartX = body2.m_position0.x; 59 | var p2StartY = body2.m_position0.y; 60 | //float32 a2Start = body2->m_rotation0; 61 | var a2Start = body2.m_rotation0; 62 | 63 | //b2Vec2 p1 = p1Start; 64 | var p1X = p1StartX; 65 | var p1Y = p1StartY; 66 | //float32 a1 = a1Start; 67 | var a1 = a1Start; 68 | //b2Vec2 p2 = p2Start; 69 | var p2X = p2StartX; 70 | var p2Y = p2StartY; 71 | //float32 a2 = a2Start; 72 | var a2 = a2Start; 73 | 74 | //b2Mat22 b2Conservative.R1(a1), b2Conservative.R2(a2); 75 | b2Conservative.R1.Set(a1); 76 | b2Conservative.R2.Set(a2); 77 | 78 | //shape1->QuickSync(p1, b2Conservative.R1); 79 | shape1.QuickSync(p1, b2Conservative.R1); 80 | //shape2->QuickSync(p2, b2Conservative.R2); 81 | shape2.QuickSync(p2, b2Conservative.R2); 82 | 83 | //float32 s1 = 0.0f; 84 | var s1 = 0.0; 85 | //const int32 maxIterations = 10; 86 | var maxIterations = 10; 87 | //b2Vec2 d; 88 | var dX; 89 | var dY; 90 | //float32 invRelativeVelocity = 0.0f; 91 | var invRelativeVelocity = 0.0; 92 | //bool hit = true; 93 | var hit = true; 94 | //b2Vec2 b2Conservative.x1, b2Conservative.x2; moved to static var 95 | for (var iter = 0; iter < maxIterations; ++iter) 96 | { 97 | // Get the accurate distance between shapes. 98 | //float32 distance = b2Distance.Distance(&b2Conservative.x1, &b2Conservative.x2, shape1, shape2); 99 | var distance = b2Distance.Distance(b2Conservative.x1, b2Conservative.x2, shape1, shape2); 100 | if (distance < b2Settings.b2_linearSlop) 101 | { 102 | if (iter == 0) 103 | { 104 | hit = false; 105 | } 106 | else 107 | { 108 | hit = true; 109 | } 110 | break; 111 | } 112 | 113 | if (iter == 0) 114 | { 115 | //b2Vec2 d = b2Conservative.x2 - b2Conservative.x1; 116 | dX = b2Conservative.x2.x - b2Conservative.x1.x; 117 | dY = b2Conservative.x2.y - b2Conservative.x1.y; 118 | //d.Normalize(); 119 | var dLen = Math.sqrt(dX*dX + dY*dY); 120 | //float32 relativeVelocity = b2Dot(d, v1 - v2) + b2Abs(omega1) * r1 + b2Abs(omega2) * r2; 121 | var relativeVelocity = (dX*(v1X-v2X) + dY*(v1Y - v2Y)) + Math.abs(omega1) * r1 + Math.abs(omega2) * r2; 122 | if (Math.abs(relativeVelocity) < Number.MIN_VALUE) 123 | { 124 | hit = false; 125 | break; 126 | } 127 | 128 | invRelativeVelocity = 1.0 / relativeVelocity; 129 | } 130 | 131 | // Get the conservative movement. 132 | //float32 ds = distance * invRelativeVelocity; 133 | var ds = distance * invRelativeVelocity; 134 | //float32 s2 = s1 + ds; 135 | var s2 = s1 + ds; 136 | 137 | if (s2 < 0.0 || 1.0 < s2) 138 | { 139 | hit = false; 140 | break; 141 | } 142 | 143 | if (s2 < (1.0 + 100.0 * Number.MIN_VALUE) * s1) 144 | { 145 | hit = true; 146 | break; 147 | } 148 | 149 | s1 = s2; 150 | 151 | // Move forward conservatively. 152 | //p1 = p1Start + s1 * v1; 153 | p1X = p1StartX + s1 * v1.x; 154 | p1Y = p1StartY + s1 * v1.y; 155 | //a1 = a1Start + s1 * omega1; 156 | a1 = a1Start + s1 * omega1; 157 | //p2 = p2Start + s1 * v2; 158 | p2X = p2StartX + s1 * v2.x; 159 | p2Y = p2StartY + s1 * v2.y; 160 | //a2 = a2Start + s1 * omega2; 161 | a2 = a2Start + s1 * omega2; 162 | 163 | b2Conservative.R1.Set(a1); 164 | b2Conservative.R2.Set(a2); 165 | shape1.QuickSync(p1, b2Conservative.R1); 166 | shape2.QuickSync(p2, b2Conservative.R2); 167 | } 168 | 169 | if (hit) 170 | { 171 | // Hit, move bodies to safe position and re-sync shapes. 172 | //b2Vec2 d = b2Conservative.x2 - b2Conservative.x1; 173 | dX = b2Conservative.x2.x - b2Conservative.x1.x; 174 | dY = b2Conservative.x2.y - b2Conservative.x1.y; 175 | //float32 length = d.Length(); 176 | var length = Math.sqrt(dX*dX + dY*dY); 177 | if (length > FLT_EPSILON) 178 | { 179 | d *= b2_linearSlop / length; 180 | } 181 | 182 | if (body1.IsStatic()) 183 | { 184 | //body1.m_position = p1; 185 | body1.m_position.x = p1X; 186 | body1.m_position.y = p1Y; 187 | } 188 | else 189 | { 190 | //body1.m_position = p1 - d; 191 | body1.m_position.x = p1X - dX; 192 | body1.m_position.y = p1Y - dY; 193 | } 194 | body1.m_rotation = a1; 195 | body1.m_R.Set(a1); 196 | body1.QuickSyncShapes(); 197 | 198 | if (body2.IsStatic()) 199 | { 200 | //body2->m_position = p2; 201 | body2.m_position.x = p2X; 202 | body2.m_position.y = p2Y; 203 | } 204 | else 205 | { 206 | //body2->m_position = p2 + d; 207 | body2.m_position.x = p2X + dX; 208 | body2.m_position.y = p2Y + dY; 209 | } 210 | //body2.m_position = p2 + d; 211 | body2.m_position.x = p2X + dX; 212 | body2.m_position.y = p2Y + dY; 213 | body2.m_rotation = a2; 214 | body2.m_R.Set(a2); 215 | body2.QuickSyncShapes(); 216 | 217 | return true; 218 | } 219 | 220 | // No hit, restore shapes. 221 | shape1.QuickSync(body1.m_position, body1.m_R); 222 | shape2.QuickSync(body2.m_position, body2.m_R); 223 | return false; 224 | }; 225 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2Contact.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2Contact = function(s1, s2) { 20 | // initialize instance variables for references 21 | this.m_node1 = new b2ContactNode(); 22 | this.m_node2 = new b2ContactNode(); 23 | // 24 | 25 | this.m_flags = 0; 26 | 27 | if (!s1 || !s2){ 28 | this.m_shape1 = null; 29 | this.m_shape2 = null; 30 | return; 31 | } 32 | 33 | this.m_shape1 = s1; 34 | this.m_shape2 = s2; 35 | 36 | this.m_manifoldCount = 0; 37 | 38 | this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction); 39 | this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution); 40 | 41 | this.m_prev = null; 42 | this.m_next = null; 43 | 44 | this.m_node1.contact = null; 45 | this.m_node1.prev = null; 46 | this.m_node1.next = null; 47 | this.m_node1.other = null; 48 | 49 | this.m_node2.contact = null; 50 | this.m_node2.prev = null; 51 | this.m_node2.next = null; 52 | this.m_node2.other = null; 53 | }; 54 | 55 | b2Contact.prototype = { 56 | GetManifolds: function(){return null}, 57 | GetManifoldCount: function() 58 | { 59 | return this.m_manifoldCount; 60 | }, 61 | 62 | GetNext: function(){ 63 | return this.m_next; 64 | }, 65 | 66 | GetShape1: function(){ 67 | return this.m_shape1; 68 | }, 69 | 70 | GetShape2: function(){ 71 | return this.m_shape2; 72 | }, 73 | 74 | //--------------- Internals Below ------------------- 75 | 76 | // this.m_flags 77 | // enum 78 | 79 | 80 | //virtual ~b2Contact() {} 81 | 82 | Evaluate: function(){}, 83 | 84 | m_flags: 0, 85 | 86 | // World pool and list pointers. 87 | m_prev: null, 88 | m_next: null, 89 | 90 | // Nodes for connecting bodies. 91 | m_node1: new b2ContactNode(), 92 | m_node2: new b2ContactNode(), 93 | 94 | m_shape1: null, 95 | m_shape2: null, 96 | 97 | m_manifoldCount: 0, 98 | 99 | // Combined friction 100 | m_friction: null, 101 | m_restitution: null 102 | }; 103 | 104 | b2Contact.e_islandFlag = 0x0001; 105 | b2Contact.e_destroyFlag = 0x0002; 106 | b2Contact.AddType = function(createFcn, destroyFcn, type1, type2) 107 | { 108 | //b2Settings.b2Assert(b2Shape.e_unknownShape < type1 && type1 < b2Shape.e_shapeTypeCount); 109 | //b2Settings.b2Assert(b2Shape.e_unknownShape < type2 && type2 < b2Shape.e_shapeTypeCount); 110 | 111 | b2Contact.s_registers[type1][type2].createFcn = createFcn; 112 | b2Contact.s_registers[type1][type2].destroyFcn = destroyFcn; 113 | b2Contact.s_registers[type1][type2].primary = true; 114 | 115 | if (type1 != type2) 116 | { 117 | b2Contact.s_registers[type2][type1].createFcn = createFcn; 118 | b2Contact.s_registers[type2][type1].destroyFcn = destroyFcn; 119 | b2Contact.s_registers[type2][type1].primary = false; 120 | } 121 | }; 122 | b2Contact.InitializeRegisters = function(){ 123 | b2Contact.s_registers = new Array(b2Shape.e_shapeTypeCount); 124 | for (var i = b2Shape.e_shapeTypeCount; i--;){ 125 | b2Contact.s_registers[i] = new Array(b2Shape.e_shapeTypeCount); 126 | for (var j = b2Shape.e_shapeTypeCount; j--;){ 127 | b2Contact.s_registers[i][j] = new b2ContactRegister(); 128 | } 129 | } 130 | 131 | b2Contact.AddType(b2CircleContact.Create, b2CircleContact.Destroy, b2Shape.e_circleShape, b2Shape.e_circleShape); 132 | b2Contact.AddType(b2PolyAndCircleContact.Create, b2PolyAndCircleContact.Destroy, b2Shape.e_polyShape, b2Shape.e_circleShape); 133 | b2Contact.AddType(b2PolyContact.Create, b2PolyContact.Destroy, b2Shape.e_polyShape, b2Shape.e_polyShape); 134 | 135 | }; 136 | b2Contact.Create = function(shape1, shape2, allocator){ 137 | if (b2Contact.s_initialized == false) 138 | { 139 | b2Contact.InitializeRegisters(); 140 | b2Contact.s_initialized = true; 141 | } 142 | 143 | var type1 = shape1.m_type; 144 | var type2 = shape2.m_type; 145 | 146 | //b2Settings.b2Assert(b2Shape.e_unknownShape < type1 && type1 < b2Shape.e_shapeTypeCount); 147 | //b2Settings.b2Assert(b2Shape.e_unknownShape < type2 && type2 < b2Shape.e_shapeTypeCount); 148 | 149 | var createFcn = b2Contact.s_registers[type1][type2].createFcn; 150 | if (createFcn) 151 | { 152 | if (b2Contact.s_registers[type1][type2].primary) 153 | { 154 | return createFcn(shape1, shape2, allocator); 155 | } 156 | else 157 | { 158 | var c = createFcn(shape2, shape1, allocator); 159 | for (var i = 0; i < c.GetManifoldCount(); ++i) 160 | { 161 | var m = c.GetManifolds()[ i ]; 162 | m.normal = m.normal.Negative(); 163 | } 164 | return c; 165 | } 166 | } 167 | else 168 | { 169 | return null; 170 | } 171 | }; 172 | b2Contact.Destroy = function(contact, allocator){ 173 | //b2Settings.b2Assert(b2Contact.s_initialized == true); 174 | 175 | if (contact.GetManifoldCount() > 0) 176 | { 177 | contact.m_shape1.m_body.WakeUp(); 178 | contact.m_shape2.m_body.WakeUp(); 179 | } 180 | 181 | var type1 = contact.m_shape1.m_type; 182 | var type2 = contact.m_shape2.m_type; 183 | 184 | //b2Settings.b2Assert(b2Shape.e_unknownShape < type1 && type1 < b2Shape.e_shapeTypeCount); 185 | //b2Settings.b2Assert(b2Shape.e_unknownShape < type2 && type2 < b2Shape.e_shapeTypeCount); 186 | 187 | var destroyFcn = b2Contact.s_registers[type1][type2].destroyFcn; 188 | destroyFcn(contact, allocator); 189 | }; 190 | b2Contact.s_registers = null; 191 | b2Contact.s_initialized = false; 192 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2ContactConstraint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2ContactConstraint = function(){ 24 | // initialize instance variables for references 25 | this.normal = new b2Vec2(); 26 | // 27 | 28 | this.points = new Array(b2Settings.b2_maxManifoldPoints); 29 | for (var i = b2Settings.b2_maxManifoldPoints; i--;){ 30 | this.points[i] = new b2ContactConstraintPoint(); 31 | } 32 | 33 | }; 34 | 35 | b2ContactConstraint.prototype = { 36 | points: null, 37 | normal: new b2Vec2(), 38 | manifold: null, 39 | body1: null, 40 | body2: null, 41 | friction: null, 42 | restitution: null, 43 | pointCount: 0 44 | }; 45 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2ContactConstraintPoint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2ContactConstraintPoint = function() { 21 | // initialize instance variables for references 22 | this.localAnchor1 = new b2Vec2(); 23 | this.localAnchor2 = new b2Vec2(); 24 | }; 25 | 26 | b2ContactConstraintPoint.prototype = { 27 | localAnchor1: new b2Vec2(), 28 | localAnchor2: new b2Vec2(), 29 | normalImpulse: null, 30 | tangentImpulse: null, 31 | positionImpulse: null, 32 | normalMass: null, 33 | tangentMass: null, 34 | separation: null, 35 | velocityBias: null, 36 | }; 37 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2ContactNode.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2ContactNode = function() {}; 20 | 21 | b2ContactNode.prototype = { 22 | other: null, 23 | contact: null, 24 | prev: null, 25 | next: null, 26 | }; 27 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2ContactRegister.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2ContactRegister = function() {}; 21 | 22 | b2ContactRegister.prototype = { 23 | createFcn: null, 24 | destroyFcn: null, 25 | primary: null, 26 | }; 27 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2NullContact.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | var b2NullContact = function(s1, s2) { 19 | // The constructor for b2Contact 20 | // initialize instance variables for references 21 | this.m_node1 = new b2ContactNode(); 22 | this.m_node2 = new b2ContactNode(); 23 | // 24 | this.m_flags = 0; 25 | 26 | if (!s1 || !s2){ 27 | this.m_shape1 = null; 28 | this.m_shape2 = null; 29 | return; 30 | } 31 | 32 | this.m_shape1 = s1; 33 | this.m_shape2 = s2; 34 | 35 | this.m_manifoldCount = 0; 36 | 37 | this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction); 38 | this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution); 39 | 40 | this.m_prev = null; 41 | this.m_next = null; 42 | 43 | this.m_node1.contact = null; 44 | this.m_node1.prev = null; 45 | this.m_node1.next = null; 46 | this.m_node1.other = null; 47 | 48 | this.m_node2.contact = null; 49 | this.m_node2.prev = null; 50 | this.m_node2.next = null; 51 | this.m_node2.other = null; 52 | // 53 | }; 54 | 55 | Object.extend(b2NullContact.prototype, b2Contact.prototype); 56 | Object.extend(b2NullContact.prototype, { 57 | Evaluate: function() {}, 58 | GetManifolds: function(){ return null; } 59 | }); 60 | 61 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2PolyAndCircleContact.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2PolyAndCircleContact = function(s1, s2) { 24 | // The constructor for b2Contact 25 | // initialize instance variables for references 26 | this.m_node1 = new b2ContactNode(); 27 | this.m_node2 = new b2ContactNode(); 28 | // 29 | this.m_flags = 0; 30 | 31 | if (!s1 || !s2){ 32 | this.m_shape1 = null; 33 | this.m_shape2 = null; 34 | return; 35 | } 36 | 37 | this.m_shape1 = s1; 38 | this.m_shape2 = s2; 39 | 40 | this.m_manifoldCount = 0; 41 | 42 | this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction); 43 | this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution); 44 | 45 | this.m_prev = null; 46 | this.m_next = null; 47 | 48 | this.m_node1.contact = null; 49 | this.m_node1.prev = null; 50 | this.m_node1.next = null; 51 | this.m_node1.other = null; 52 | 53 | this.m_node2.contact = null; 54 | this.m_node2.prev = null; 55 | this.m_node2.next = null; 56 | this.m_node2.other = null; 57 | // 58 | 59 | // initialize instance variables for references 60 | this.m_manifold = [new b2Manifold()]; 61 | // 62 | 63 | //super(shape1, shape2); 64 | 65 | // b2Settings.b2Assert(this.m_shape1.m_type == b2Shape.e_polyShape); 66 | // b2Settings.b2Assert(this.m_shape2.m_type == b2Shape.e_circleShape); 67 | this.m_manifold[0].pointCount = 0; 68 | this.m_manifold[0].points[0].normalImpulse = 0.0; 69 | this.m_manifold[0].points[0].tangentImpulse = 0.0; 70 | }; 71 | 72 | Object.extend(b2PolyAndCircleContact.prototype, b2Contact.prototype); 73 | Object.extend(b2PolyAndCircleContact.prototype, { 74 | 75 | //~b2PolyAndCircleContact() {} 76 | 77 | Evaluate: function(){ 78 | b2Collision.b2CollidePolyAndCircle(this.m_manifold[0], this.m_shape1, this.m_shape2, false); 79 | 80 | if (this.m_manifold[0].pointCount > 0) 81 | { 82 | this.m_manifoldCount = 1; 83 | } 84 | else 85 | { 86 | this.m_manifoldCount = 0; 87 | } 88 | }, 89 | 90 | GetManifolds: function() 91 | { 92 | return this.m_manifold; 93 | }, 94 | 95 | m_manifold: [new b2Manifold()] 96 | }); 97 | 98 | b2PolyAndCircleContact.Create = function(shape1, shape2, allocator){ 99 | return new b2PolyAndCircleContact(shape1, shape2); 100 | }; 101 | 102 | b2PolyAndCircleContact.Destroy = function(contact, allocator){ }; 103 | -------------------------------------------------------------------------------- /js/box2d/dynamics/contacts/b2PolyContact.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2PolyContact = function(s1, s2) { 24 | // The constructor for b2Contact 25 | // initialize instance variables for references 26 | this.m_node1 = new b2ContactNode(); 27 | this.m_node2 = new b2ContactNode(); 28 | // 29 | this.m_flags = 0; 30 | 31 | if (!s1 || !s2){ 32 | this.m_shape1 = null; 33 | this.m_shape2 = null; 34 | return; 35 | } 36 | 37 | this.m_shape1 = s1; 38 | this.m_shape2 = s2; 39 | 40 | this.m_manifoldCount = 0; 41 | 42 | this.m_friction = Math.sqrt(this.m_shape1.m_friction * this.m_shape2.m_friction); 43 | this.m_restitution = b2Math.b2Max(this.m_shape1.m_restitution, this.m_shape2.m_restitution); 44 | 45 | this.m_prev = null; 46 | this.m_next = null; 47 | 48 | this.m_node1.contact = null; 49 | this.m_node1.prev = null; 50 | this.m_node1.next = null; 51 | this.m_node1.other = null; 52 | 53 | this.m_node2.contact = null; 54 | this.m_node2.prev = null; 55 | this.m_node2.next = null; 56 | this.m_node2.other = null; 57 | // 58 | 59 | // initialize instance variables for references 60 | this.m0 = new b2Manifold(); 61 | this.m_manifold = [new b2Manifold()]; 62 | // 63 | 64 | //super(shape1, shape2); 65 | //b2Settings.b2Assert(this.m_shape1.m_type == b2Shape.e_polyShape); 66 | //b2Settings.b2Assert(this.m_shape2.m_type == b2Shape.e_polyShape); 67 | this.m_manifold[0].pointCount = 0; 68 | }; 69 | 70 | Object.extend(b2PolyContact.prototype, b2Contact.prototype); 71 | Object.extend(b2PolyContact.prototype, { 72 | 73 | //~b2PolyContact() {} 74 | 75 | // store temp manifold to reduce calls to new 76 | m0: new b2Manifold(), 77 | 78 | Evaluate: function(){ 79 | var tMani = this.m_manifold[0]; 80 | // replace memcpy 81 | // memcpy(&this.m0, &this.m_manifold, sizeof(b2Manifold)); 82 | //this.m0.points = new Array(tMani.pointCount); 83 | var tPoints = this.m0.points; 84 | 85 | for (var k = tMani.pointCount; k--;){ 86 | var tPoint = tPoints[k]; 87 | var tPoint0 = tMani.points[k]; 88 | //tPoint.separation = tPoint0.separation; 89 | tPoint.normalImpulse = tPoint0.normalImpulse; 90 | tPoint.tangentImpulse = tPoint0.tangentImpulse; 91 | //tPoint.position.SetV( tPoint0.position ); 92 | 93 | tPoint.id = tPoint0.id.Copy(); 94 | 95 | /*this.m0.points[k].id.features = new Features(); 96 | this.m0.points[k].id.features.referenceFace = this.m_manifold[0].points[k].id.features.referenceFace; 97 | this.m0.points[k].id.features.incidentEdge = this.m_manifold[0].points[k].id.features.incidentEdge; 98 | this.m0.points[k].id.features.incidentVertex = this.m_manifold[0].points[k].id.features.incidentVertex; 99 | this.m0.points[k].id.features.flip = this.m_manifold[0].points[k].id.features.flip;*/ 100 | } 101 | //this.m0.normal.SetV( tMani.normal ); 102 | this.m0.pointCount = tMani.pointCount; 103 | 104 | b2Collision.b2CollidePoly(tMani, this.m_shape1, this.m_shape2, false); 105 | 106 | // Match contact ids to facilitate warm starting. 107 | if (tMani.pointCount > 0) 108 | { 109 | var match = [false, false]; 110 | 111 | // Match old contact ids to new contact ids and copy the 112 | // stored impulses to warm start the solver. 113 | for (var i = tMani.pointCount; i--;) 114 | { 115 | var cp = tMani.points[ i ]; 116 | 117 | cp.normalImpulse = 0.0; 118 | cp.tangentImpulse = 0.0; 119 | var idKey = cp.id.key; 120 | 121 | for (var j = this.m0.pointCount; j--;) 122 | { 123 | 124 | if (match[j] == true) 125 | continue; 126 | 127 | var cp0 = this.m0.points[j]; 128 | var id0 = cp0.id; 129 | 130 | if (id0.key == idKey) 131 | { 132 | match[j] = true; 133 | cp.normalImpulse = cp0.normalImpulse; 134 | cp.tangentImpulse = cp0.tangentImpulse; 135 | break; 136 | } 137 | } 138 | } 139 | 140 | this.m_manifoldCount = 1; 141 | } 142 | else 143 | { 144 | this.m_manifoldCount = 0; 145 | } 146 | }, 147 | 148 | GetManifolds: function() 149 | { 150 | return this.m_manifold; 151 | }, 152 | 153 | m_manifold: [new b2Manifold()] 154 | }); 155 | 156 | b2PolyContact.Create = function(shape1, shape2, allocator) { 157 | return new b2PolyContact(shape1, shape2); 158 | }; 159 | 160 | b2PolyContact.Destroy = function(){}; 161 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2DistanceJoint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | // C = norm(p2 - p1) - L 22 | // u = (p2 - p1) / norm(p2 - p1) 23 | // Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1)) 24 | // J = [-u -cross(r1, u) u cross(r2, u)] 25 | // K = J * invM * JT 26 | // = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2 27 | 28 | var b2DistanceJoint = function(def) { 29 | // The constructor for b2Joint 30 | // initialize instance variables for references 31 | this.m_node1 = new b2JointNode(); 32 | this.m_node2 = new b2JointNode(); 33 | // 34 | this.m_type = def.type; 35 | this.m_prev = null; 36 | this.m_next = null; 37 | this.m_body1 = def.body1; 38 | this.m_body2 = def.body2; 39 | this.m_collideConnected = def.collideConnected; 40 | this.m_islandFlag = false; 41 | this.m_userData = def.userData; 42 | // 43 | 44 | // initialize instance variables for references 45 | this.m_localAnchor1 = new b2Vec2(); 46 | this.m_localAnchor2 = new b2Vec2(); 47 | this.m_u = new b2Vec2(); 48 | // 49 | 50 | //super(def); 51 | 52 | var tMat; 53 | var tX; 54 | var tY; 55 | tMat = this.m_body1.m_R; 56 | tX = def.anchorPoint1.x - this.m_body1.m_position.x; 57 | tY = def.anchorPoint1.y - this.m_body1.m_position.y; 58 | this.m_localAnchor1.x = tX*tMat.col1.x + tY*tMat.col1.y; 59 | this.m_localAnchor1.y = tX*tMat.col2.x + tY*tMat.col2.y; 60 | 61 | tMat = this.m_body2.m_R; 62 | tX = def.anchorPoint2.x - this.m_body2.m_position.x; 63 | tY = def.anchorPoint2.y - this.m_body2.m_position.y; 64 | this.m_localAnchor2.x = tX*tMat.col1.x + tY*tMat.col1.y; 65 | this.m_localAnchor2.y = tX*tMat.col2.x + tY*tMat.col2.y; 66 | 67 | //b2Vec2 d = def->anchorPoint2 - def->anchorPoint1; 68 | tX = def.anchorPoint2.x - def.anchorPoint1.x; 69 | tY = def.anchorPoint2.y - def.anchorPoint1.y; 70 | //this.m_length = d.Length(); 71 | this.m_length = Math.sqrt(tX*tX + tY*tY); 72 | this.m_impulse = 0.0; 73 | }; 74 | 75 | Object.extend(b2DistanceJoint.prototype, b2Joint.prototype); 76 | Object.extend(b2DistanceJoint.prototype, 77 | { 78 | //--------------- Internals Below ------------------- 79 | 80 | PrepareVelocitySolver: function(){ 81 | 82 | var tMat; 83 | 84 | // Compute the effective mass matrix. 85 | //b2Vec2 r1 = b2Mul(this.m_body1->m_R, this.m_localAnchor1); 86 | tMat = this.m_body1.m_R; 87 | var r1X = tMat.col1.x * this.m_localAnchor1.x + tMat.col2.x * this.m_localAnchor1.y; 88 | var r1Y = tMat.col1.y * this.m_localAnchor1.x + tMat.col2.y * this.m_localAnchor1.y; 89 | //b2Vec2 r2 = b2Mul(this.m_body2->m_R, this.m_localAnchor2); 90 | tMat = this.m_body2.m_R; 91 | var r2X = tMat.col1.x * this.m_localAnchor2.x + tMat.col2.x * this.m_localAnchor2.y; 92 | var r2Y = tMat.col1.y * this.m_localAnchor2.x + tMat.col2.y * this.m_localAnchor2.y; 93 | //this.m_u = this.m_body2->m_position + r2 - this.m_body1->m_position - r1; 94 | this.m_u.x = this.m_body2.m_position.x + r2X - this.m_body1.m_position.x - r1X; 95 | this.m_u.y = this.m_body2.m_position.y + r2Y - this.m_body1.m_position.y - r1Y; 96 | 97 | // Handle singularity. 98 | //float32 length = this.m_u.Length(); 99 | var length = Math.sqrt(this.m_u.x*this.m_u.x + this.m_u.y*this.m_u.y); 100 | if (length > b2Settings.b2_linearSlop) 101 | { 102 | //this.m_u *= 1.0 / length; 103 | this.m_u.Multiply( 1.0 / length ); 104 | } 105 | else 106 | { 107 | this.m_u.SetZero(); 108 | } 109 | 110 | //float32 cr1u = b2Cross(r1, this.m_u); 111 | var cr1u = (r1X * this.m_u.y - r1Y * this.m_u.x); 112 | //float32 cr2u = b2Cross(r2, this.m_u); 113 | var cr2u = (r2X * this.m_u.y - r2Y * this.m_u.x); 114 | //this.m_mass = this.m_body1->m_invMass + this.m_body1->m_invI * cr1u * cr1u + this.m_body2->m_invMass + this.m_body2->m_invI * cr2u * cr2u; 115 | this.m_mass = this.m_body1.m_invMass + this.m_body1.m_invI * cr1u * cr1u + this.m_body2.m_invMass + this.m_body2.m_invI * cr2u * cr2u; 116 | //b2Settings.b2Assert(this.m_mass > Number.MIN_VALUE); 117 | this.m_mass = 1.0 / this.m_mass; 118 | 119 | if (b2World.s_enableWarmStarting) 120 | { 121 | //b2Vec2 P = this.m_impulse * this.m_u; 122 | var PX = this.m_impulse * this.m_u.x; 123 | var PY = this.m_impulse * this.m_u.y; 124 | //this.m_body1.m_linearVelocity -= this.m_body1.m_invMass * P; 125 | this.m_body1.m_linearVelocity.x -= this.m_body1.m_invMass * PX; 126 | this.m_body1.m_linearVelocity.y -= this.m_body1.m_invMass * PY; 127 | //this.m_body1.m_angularVelocity -= this.m_body1.m_invI * b2Cross(r1, P); 128 | this.m_body1.m_angularVelocity -= this.m_body1.m_invI * (r1X * PY - r1Y * PX); 129 | //this.m_body2.m_linearVelocity += this.m_body2.m_invMass * P; 130 | this.m_body2.m_linearVelocity.x += this.m_body2.m_invMass * PX; 131 | this.m_body2.m_linearVelocity.y += this.m_body2.m_invMass * PY; 132 | //this.m_body2.m_angularVelocity += this.m_body2.m_invI * b2Cross(r2, P); 133 | this.m_body2.m_angularVelocity += this.m_body2.m_invI * (r2X * PY - r2Y * PX); 134 | } 135 | else 136 | { 137 | this.m_impulse = 0.0; 138 | } 139 | 140 | }, 141 | 142 | 143 | 144 | SolveVelocityConstraints: function(step){ 145 | 146 | var tMat; 147 | 148 | tMat = this.m_body1.m_R; 149 | var r1X = tMat.col1.x * this.m_localAnchor1.x + tMat.col2.x * this.m_localAnchor1.y; 150 | var r1Y = tMat.col1.y * this.m_localAnchor1.x + tMat.col2.y * this.m_localAnchor1.y; 151 | tMat = this.m_body2.m_R; 152 | var r2X = tMat.col1.x * this.m_localAnchor2.x + tMat.col2.x * this.m_localAnchor2.y; 153 | var r2Y = tMat.col1.y * this.m_localAnchor2.x + tMat.col2.y * this.m_localAnchor2.y; 154 | 155 | // Cdot = dot(u, v + cross(w, r)) 156 | var v1X = this.m_body1.m_linearVelocity.x + (-this.m_body1.m_angularVelocity * r1Y); 157 | var v1Y = this.m_body1.m_linearVelocity.y + (this.m_body1.m_angularVelocity * r1X); 158 | var v2X = this.m_body2.m_linearVelocity.x + (-this.m_body2.m_angularVelocity * r2Y); 159 | var v2Y = this.m_body2.m_linearVelocity.y + (this.m_body2.m_angularVelocity * r2X); 160 | var Cdot = (this.m_u.x * (v2X - v1X) + this.m_u.y * (v2Y - v1Y)); 161 | var impulse = -this.m_mass * Cdot; 162 | this.m_impulse += impulse; 163 | 164 | var PX = impulse * this.m_u.x; 165 | var PY = impulse * this.m_u.y; 166 | this.m_body1.m_linearVelocity.x -= this.m_body1.m_invMass * PX; 167 | this.m_body1.m_linearVelocity.y -= this.m_body1.m_invMass * PY; 168 | this.m_body1.m_angularVelocity -= this.m_body1.m_invI * (r1X * PY - r1Y * PX); 169 | this.m_body2.m_linearVelocity.x += this.m_body2.m_invMass * PX; 170 | this.m_body2.m_linearVelocity.y += this.m_body2.m_invMass * PY; 171 | this.m_body2.m_angularVelocity += this.m_body2.m_invI * (r2X * PY - r2Y * PX); 172 | }, 173 | 174 | SolvePositionConstraints: function(){ 175 | 176 | var tMat; 177 | 178 | tMat = this.m_body1.m_R; 179 | var r1X = tMat.col1.x * this.m_localAnchor1.x + tMat.col2.x * this.m_localAnchor1.y; 180 | var r1Y = tMat.col1.y * this.m_localAnchor1.x + tMat.col2.y * this.m_localAnchor1.y; 181 | tMat = this.m_body2.m_R; 182 | var r2X = tMat.col1.x * this.m_localAnchor2.x + tMat.col2.x * this.m_localAnchor2.y; 183 | var r2Y = tMat.col1.y * this.m_localAnchor2.x + tMat.col2.y * this.m_localAnchor2.y; 184 | var dX = this.m_body2.m_position.x + r2X - this.m_body1.m_position.x - r1X; 185 | var dY = this.m_body2.m_position.y + r2Y - this.m_body1.m_position.y - r1Y; 186 | 187 | var length = Math.sqrt(dX*dX + dY*dY); 188 | dX /= length; 189 | dY /= length; 190 | var C = length - this.m_length; 191 | C = b2Math.b2Clamp(C, -b2Settings.b2_maxLinearCorrection, b2Settings.b2_maxLinearCorrection); 192 | 193 | var impulse = -this.m_mass * C; 194 | this.m_u.Set(dX, dY); 195 | var PX = impulse * this.m_u.x; 196 | var PY = impulse * this.m_u.y; 197 | 198 | 199 | this.m_body1.m_position.x -= this.m_body1.m_invMass * PX; 200 | this.m_body1.m_position.y -= this.m_body1.m_invMass * PY; 201 | this.m_body1.m_rotation -= this.m_body1.m_invI * (r1X * PY - r1Y * PX); 202 | this.m_body2.m_position.x += this.m_body2.m_invMass * PX; 203 | this.m_body2.m_position.y += this.m_body2.m_invMass * PY; 204 | this.m_body2.m_rotation += this.m_body2.m_invI * (r2X * PY - r2Y * PX); 205 | 206 | this.m_body1.m_R.Set(this.m_body1.m_rotation); 207 | this.m_body2.m_R.Set(this.m_body2.m_rotation); 208 | 209 | return b2Math.b2Abs(C) < b2Settings.b2_linearSlop; 210 | 211 | }, 212 | 213 | GetAnchor1: function(){ 214 | return b2Math.AddVV(this.m_body1.m_position , b2Math.b2MulMV(this.m_body1.m_R, this.m_localAnchor1)); 215 | }, 216 | GetAnchor2: function(){ 217 | return b2Math.AddVV(this.m_body2.m_position , b2Math.b2MulMV(this.m_body2.m_R, this.m_localAnchor2)); 218 | }, 219 | 220 | GetReactionForce: function(invTimeStep) 221 | { 222 | var F = new b2Vec2(); 223 | F.SetV(this.m_u); 224 | F.Multiply(this.m_impulse * invTimeStep); 225 | return F; 226 | }, 227 | 228 | GetReactionTorque: function(invTimeStep) 229 | { 230 | //NOT_USED(invTimeStep); 231 | return 0.0; 232 | }, 233 | 234 | m_localAnchor1: null, 235 | m_localAnchor2: null, 236 | m_u: new b2Vec2(), 237 | m_impulse: null, 238 | m_mass: null, 239 | m_length: null 240 | }); 241 | 242 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2DistanceJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2DistanceJointDef = function() { 21 | // The constructor for b2JointDef 22 | this.type = b2Joint.e_unknownJoint; 23 | this.userData = null; 24 | this.body1 = null; 25 | this.body2 = null; 26 | this.collideConnected = false; 27 | // 28 | 29 | // initialize instance variables for references 30 | this.anchorPoint1 = new b2Vec2(0, 0); 31 | this.anchorPoint2 = new b2Vec2(0, 0); 32 | // 33 | 34 | this.type = b2Joint.e_distanceJoint; 35 | }; 36 | 37 | Object.extend(b2DistanceJointDef.prototype, b2JointDef.prototype); 38 | Object.extend(b2DistanceJointDef.prototype, { 39 | 40 | anchorPoint1: null, 41 | anchorPoint2: null 42 | }); 43 | 44 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2GearJoint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2GearJoint = function(def){ 21 | // The constructor for b2Joint 22 | // initialize instance variables for references 23 | this.m_node1 = new b2JointNode(); 24 | this.m_node2 = new b2JointNode(); 25 | // 26 | this.m_type = def.type; 27 | this.m_prev = null; 28 | this.m_next = null; 29 | this.m_body1 = def.body1; 30 | this.m_body2 = def.body2; 31 | this.m_collideConnected = def.collideConnected; 32 | this.m_islandFlag = false; 33 | this.m_userData = def.userData; 34 | // 35 | 36 | // initialize instance variables for references 37 | this.m_groundAnchor1 = new b2Vec2(); 38 | this.m_groundAnchor2 = new b2Vec2(); 39 | this.m_localAnchor1 = new b2Vec2(); 40 | this.m_localAnchor2 = new b2Vec2(); 41 | this.m_J = new b2Jacobian(); 42 | // 43 | 44 | // parent constructor 45 | //super(def); 46 | 47 | //b2Settings.b2Assert(def.joint1.m_type == b2Joint.e_revoluteJoint || def.joint1.m_type == b2Joint.e_prismaticJoint); 48 | //b2Settings.b2Assert(def.joint2.m_type == b2Joint.e_revoluteJoint || def.joint2.m_type == b2Joint.e_prismaticJoint); 49 | //b2Settings.b2Assert(def.joint1.m_body1.IsStatic()); 50 | //b2Settings.b2Assert(def.joint2.m_body1.IsStatic()); 51 | 52 | this.m_revolute1 = null; 53 | this.m_prismatic1 = null; 54 | this.m_revolute2 = null; 55 | this.m_prismatic2 = null; 56 | 57 | var coordinate1; 58 | var coordinate2; 59 | 60 | this.m_ground1 = def.joint1.m_body1; 61 | this.m_body1 = def.joint1.m_body2; 62 | if (def.joint1.m_type == b2Joint.e_revoluteJoint) 63 | { 64 | this.m_revolute1 = def.joint1; 65 | this.m_groundAnchor1.SetV( this.m_revolute1.m_localAnchor1 ); 66 | this.m_localAnchor1.SetV( this.m_revolute1.m_localAnchor2 ); 67 | coordinate1 = this.m_revolute1.GetJointAngle(); 68 | } 69 | else 70 | { 71 | this.m_prismatic1 = def.joint1; 72 | this.m_groundAnchor1.SetV( this.m_prismatic1.m_localAnchor1 ); 73 | this.m_localAnchor1.SetV( this.m_prismatic1.m_localAnchor2 ); 74 | coordinate1 = this.m_prismatic1.GetJointTranslation(); 75 | } 76 | 77 | this.m_ground2 = def.joint2.m_body1; 78 | this.m_body2 = def.joint2.m_body2; 79 | if (def.joint2.m_type == b2Joint.e_revoluteJoint) 80 | { 81 | this.m_revolute2 = def.joint2; 82 | this.m_groundAnchor2.SetV( this.m_revolute2.m_localAnchor1 ); 83 | this.m_localAnchor2.SetV( this.m_revolute2.m_localAnchor2 ); 84 | coordinate2 = this.m_revolute2.GetJointAngle(); 85 | } 86 | else 87 | { 88 | this.m_prismatic2 = def.joint2; 89 | this.m_groundAnchor2.SetV( this.m_prismatic2.m_localAnchor1 ); 90 | this.m_localAnchor2.SetV( this.m_prismatic2.m_localAnchor2 ); 91 | coordinate2 = this.m_prismatic2.GetJointTranslation(); 92 | } 93 | 94 | this.m_ratio = def.ratio; 95 | 96 | this.m_constant = coordinate1 + this.m_ratio * coordinate2; 97 | 98 | this.m_impulse = 0.0; 99 | 100 | }; 101 | 102 | Object.extend(b2GearJoint.prototype, b2Joint.prototype); 103 | Object.extend(b2GearJoint.prototype, { 104 | GetAnchor1: function(){ 105 | //return this.m_body1.m_position + b2MulMV(this.m_body1.m_R, this.m_localAnchor1); 106 | var tMat = this.m_body1.m_R; 107 | return new b2Vec2( this.m_body1.m_position.x + (tMat.col1.x * this.m_localAnchor1.x + tMat.col2.x * this.m_localAnchor1.y), 108 | this.m_body1.m_position.y + (tMat.col1.y * this.m_localAnchor1.x + tMat.col2.y * this.m_localAnchor1.y)); 109 | }, 110 | GetAnchor2: function(){ 111 | //return this.m_body2->m_position + b2Mul(this.m_body2->m_R, this.m_localAnchor2); 112 | var tMat = this.m_body2.m_R; 113 | return new b2Vec2( this.m_body2.m_position.x + (tMat.col1.x * this.m_localAnchor2.x + tMat.col2.x * this.m_localAnchor2.y), 114 | this.m_body2.m_position.y + (tMat.col1.y * this.m_localAnchor2.x + tMat.col2.y * this.m_localAnchor2.y)); 115 | }, 116 | 117 | GetReactionForce: function(invTimeStep){ 118 | //b2Vec2 F(0.0f, 0.0f); 119 | return new b2Vec2(); 120 | }, 121 | GetReactionTorque: function(invTimeStep){ 122 | return 0.0; 123 | }, 124 | 125 | GetRatio: function(){ 126 | return this.m_ratio; 127 | }, 128 | 129 | //--------------- Internals Below ------------------- 130 | 131 | PrepareVelocitySolver: function(){ 132 | var g1 = this.m_ground1; 133 | var g2 = this.m_ground2; 134 | var b1 = this.m_body1; 135 | var b2 = this.m_body2; 136 | 137 | // temp vars 138 | var ugX; 139 | var ugY; 140 | var rX; 141 | var rY; 142 | var tMat; 143 | var tVec; 144 | var crug; 145 | 146 | var K = 0.0; 147 | this.m_J.SetZero(); 148 | 149 | if (this.m_revolute1) 150 | { 151 | this.m_J.angular1 = -1.0; 152 | K += b1.m_invI; 153 | } 154 | else 155 | { 156 | //b2Vec2 ug = b2MulMV(g1->m_R, this.m_prismatic1->m_localXAxis1); 157 | tMat = g1.m_R; 158 | tVec = this.m_prismatic1.m_localXAxis1; 159 | ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; 160 | ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; 161 | //b2Vec2 r = b2MulMV(b1->m_R, this.m_localAnchor1); 162 | tMat = b1.m_R; 163 | rX = tMat.col1.x * this.m_localAnchor1.x + tMat.col2.x * this.m_localAnchor1.y; 164 | rY = tMat.col1.y * this.m_localAnchor1.x + tMat.col2.y * this.m_localAnchor1.y; 165 | 166 | //var crug = b2Cross(r, ug); 167 | crug = rX * ugY - rY * ugX; 168 | //this.m_J.linear1 = -ug; 169 | this.m_J.linear1.Set(-ugX, -ugY); 170 | this.m_J.angular1 = -crug; 171 | K += b1.m_invMass + b1.m_invI * crug * crug; 172 | } 173 | 174 | if (this.m_revolute2) 175 | { 176 | this.m_J.angular2 = -this.m_ratio; 177 | K += this.m_ratio * this.m_ratio * b2.m_invI; 178 | } 179 | else 180 | { 181 | //b2Vec2 ug = b2Mul(g2->m_R, this.m_prismatic2->m_localXAxis1); 182 | tMat = g2.m_R; 183 | tVec = this.m_prismatic2.m_localXAxis1; 184 | ugX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y; 185 | ugY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y; 186 | //b2Vec2 r = b2Mul(b2->m_R, this.m_localAnchor2); 187 | tMat = b2.m_R; 188 | rX = tMat.col1.x * this.m_localAnchor2.x + tMat.col2.x * this.m_localAnchor2.y; 189 | rY = tMat.col1.y * this.m_localAnchor2.x + tMat.col2.y * this.m_localAnchor2.y; 190 | //float32 crug = b2Cross(r, ug); 191 | crug = rX * ugY - rY * ugX; 192 | //this.m_J.linear2 = -this.m_ratio * ug; 193 | this.m_J.linear2.Set(-this.m_ratio*ugX, -this.m_ratio*ugY); 194 | this.m_J.angular2 = -this.m_ratio * crug; 195 | K += this.m_ratio * this.m_ratio * (b2.m_invMass + b2.m_invI * crug * crug); 196 | } 197 | 198 | // Compute effective mass. 199 | //b2Settings.b2Assert(K > 0.0); 200 | this.m_mass = 1.0 / K; 201 | 202 | // Warm starting. 203 | //b1.m_linearVelocity += b1.m_invMass * this.m_impulse * this.m_J.linear1; 204 | b1.m_linearVelocity.x += b1.m_invMass * this.m_impulse * this.m_J.linear1.x; 205 | b1.m_linearVelocity.y += b1.m_invMass * this.m_impulse * this.m_J.linear1.y; 206 | b1.m_angularVelocity += b1.m_invI * this.m_impulse * this.m_J.angular1; 207 | //b2.m_linearVelocity += b2.m_invMass * this.m_impulse * this.m_J.linear2; 208 | b2.m_linearVelocity.x += b2.m_invMass * this.m_impulse * this.m_J.linear2.x; 209 | b2.m_linearVelocity.y += b2.m_invMass * this.m_impulse * this.m_J.linear2.y; 210 | b2.m_angularVelocity += b2.m_invI * this.m_impulse * this.m_J.angular2; 211 | }, 212 | 213 | 214 | SolveVelocityConstraints: function(step){ 215 | var b1 = this.m_body1; 216 | var b2 = this.m_body2; 217 | 218 | var Cdot = this.m_J.Compute( b1.m_linearVelocity, b1.m_angularVelocity, 219 | b2.m_linearVelocity, b2.m_angularVelocity); 220 | 221 | var impulse = -this.m_mass * Cdot; 222 | this.m_impulse += impulse; 223 | 224 | b1.m_linearVelocity.x += b1.m_invMass * impulse * this.m_J.linear1.x; 225 | b1.m_linearVelocity.y += b1.m_invMass * impulse * this.m_J.linear1.y; 226 | b1.m_angularVelocity += b1.m_invI * impulse * this.m_J.angular1; 227 | b2.m_linearVelocity.x += b2.m_invMass * impulse * this.m_J.linear2.x; 228 | b2.m_linearVelocity.y += b2.m_invMass * impulse * this.m_J.linear2.y; 229 | b2.m_angularVelocity += b2.m_invI * impulse * this.m_J.angular2; 230 | }, 231 | 232 | SolvePositionConstraints: function(){ 233 | var linearError = 0.0; 234 | 235 | var b1 = this.m_body1; 236 | var b2 = this.m_body2; 237 | 238 | var coordinate1; 239 | var coordinate2; 240 | if (this.m_revolute1) 241 | { 242 | coordinate1 = this.m_revolute1.GetJointAngle(); 243 | } 244 | else 245 | { 246 | coordinate1 = this.m_prismatic1.GetJointTranslation(); 247 | } 248 | 249 | if (this.m_revolute2) 250 | { 251 | coordinate2 = this.m_revolute2.GetJointAngle(); 252 | } 253 | else 254 | { 255 | coordinate2 = this.m_prismatic2.GetJointTranslation(); 256 | } 257 | 258 | var C = this.m_constant - (coordinate1 + this.m_ratio * coordinate2); 259 | 260 | var impulse = -this.m_mass * C; 261 | 262 | b1.m_position.x += b1.m_invMass * impulse * this.m_J.linear1.x; 263 | b1.m_position.y += b1.m_invMass * impulse * this.m_J.linear1.y; 264 | b1.m_rotation += b1.m_invI * impulse * this.m_J.angular1; 265 | b2.m_position.x += b2.m_invMass * impulse * this.m_J.linear2.x; 266 | b2.m_position.y += b2.m_invMass * impulse * this.m_J.linear2.y; 267 | b2.m_rotation += b2.m_invI * impulse * this.m_J.angular2; 268 | b1.m_R.Set(b1.m_rotation); 269 | b2.m_R.Set(b2.m_rotation); 270 | 271 | return linearError < b2Settings.b2_linearSlop; 272 | }, 273 | 274 | m_ground1: null, 275 | m_ground2: null, 276 | 277 | // One of these is NULL. 278 | m_revolute1: null, 279 | m_prismatic1: null, 280 | 281 | // One of these is NULL. 282 | m_revolute2: null, 283 | m_prismatic2: null, 284 | 285 | m_groundAnchor1: new b2Vec2(), 286 | m_groundAnchor2: new b2Vec2(), 287 | 288 | m_localAnchor1: new b2Vec2(), 289 | m_localAnchor2: new b2Vec2(), 290 | 291 | m_J: new b2Jacobian(), 292 | 293 | m_constant: null, 294 | m_ratio: null, 295 | 296 | // Effective mass 297 | m_mass: null, 298 | 299 | // Impulse for accumulation/warm starting. 300 | m_impulse: null 301 | }); 302 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2GearJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | 24 | // A gear joint is used to connect two joints together. Either joint 25 | // can be a revolute or prismatic joint. You specify a gear ratio 26 | // to bind the motions together: 27 | // coordinate1 + ratio * coordinate2 = constant 28 | // The ratio can be negative or positive. If one joint is a revolute joint 29 | // and the other joint is a prismatic joint, then the ratio will have units 30 | // of length or units of 1/length. 31 | // 32 | // RESTRICITON: The revolute and prismatic joints must be attached to 33 | // a fixed body (which must be body1 on those joints). 34 | 35 | var b2GearJointDef = function() { 36 | this.type = b2Joint.e_gearJoint; 37 | this.joint1 = null; 38 | this.joint2 = null; 39 | this.ratio = 1.0; 40 | }; 41 | 42 | Object.extend(b2GearJointDef.prototype, b2JointDef.prototype); 43 | Object.extend(b2GearJointDef.prototype, { 44 | joint1: null, 45 | joint2: null, 46 | ratio: null 47 | }); 48 | 49 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2Jacobian.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2Jacobian = function() { 24 | // initialize instance variables for references 25 | this.linear1 = new b2Vec2(); 26 | this.linear2 = new b2Vec2(); 27 | }; 28 | 29 | b2Jacobian.prototype = 30 | { 31 | linear1: new b2Vec2(), 32 | angular1: null, 33 | linear2: new b2Vec2(), 34 | angular2: null, 35 | 36 | SetZero: function(){ 37 | this.linear1.SetZero(); this.angular1 = 0.0; 38 | this.linear2.SetZero(); this.angular2 = 0.0; 39 | }, 40 | Set: function(x1, a1, x2, a2){ 41 | this.linear1.SetV(x1); this.angular1 = a1; 42 | this.linear2.SetV(x2); this.angular2 = a2; 43 | }, 44 | Compute: function(x1, a1, x2, a2){ 45 | 46 | //return b2Math.b2Dot(this.linear1, x1) + this.angular1 * a1 + b2Math.b2Dot(this.linear2, x2) + this.angular2 * a2; 47 | return (this.linear1.x*x1.x + this.linear1.y*x1.y) + this.angular1 * a1 + (this.linear2.x*x2.x + this.linear2.y*x2.y) + this.angular2 * a2; 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2Joint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2Joint = function(def){ 24 | // initialize instance variables for references 25 | this.m_node1 = new b2JointNode(); 26 | this.m_node2 = new b2JointNode(); 27 | // 28 | 29 | this.m_type = def.type; 30 | this.m_prev = null; 31 | this.m_next = null; 32 | this.m_body1 = def.body1; 33 | this.m_body2 = def.body2; 34 | this.m_collideConnected = def.collideConnected; 35 | this.m_islandFlag = false; 36 | this.m_userData = def.userData; 37 | }; 38 | 39 | b2Joint.prototype = 40 | { 41 | GetType: function(){ 42 | return this.m_type; 43 | }, 44 | 45 | GetAnchor1: function(){return null}, 46 | GetAnchor2: function(){return null}, 47 | 48 | GetReactionForce: function(invTimeStep){return null}, 49 | GetReactionTorque: function(invTimeStep){return 0.0}, 50 | 51 | GetBody1: function() 52 | { 53 | return this.m_body1; 54 | }, 55 | 56 | GetBody2: function() 57 | { 58 | return this.m_body2; 59 | }, 60 | 61 | GetNext: function(){ 62 | return this.m_next; 63 | }, 64 | 65 | GetUserData: function(){ 66 | return this.m_userData; 67 | }, 68 | 69 | //--------------- Internals Below ------------------- 70 | 71 | 72 | 73 | //virtual ~b2Joint() {} 74 | 75 | PrepareVelocitySolver: function(){}, 76 | SolveVelocityConstraints: function(step){}, 77 | 78 | // This returns true if the position errors are within tolerance. 79 | PreparePositionSolver: function(){}, 80 | SolvePositionConstraints: function(){return false}, 81 | 82 | m_type: 0, 83 | m_prev: null, 84 | m_next: null, 85 | m_node1: new b2JointNode(), 86 | m_node2: new b2JointNode(), 87 | m_body1: null, 88 | m_body2: null, 89 | 90 | m_islandFlag: null, 91 | m_collideConnected: null, 92 | 93 | m_userData: null 94 | 95 | 96 | // ENUMS 97 | 98 | // enum b2JointType 99 | 100 | // enum b2LimitState 101 | 102 | }; 103 | b2Joint.Create = function(def){ 104 | var joint = null; 105 | 106 | switch (def.type) 107 | { 108 | case b2Joint.e_distanceJoint: 109 | { 110 | //void* mem = allocator->Allocate(sizeof(b2DistanceJoint)); 111 | joint = new b2DistanceJoint(def); 112 | } 113 | break; 114 | 115 | case b2Joint.e_springJoint: 116 | { 117 | joint = new b2SpringJoint(def); 118 | } 119 | break; 120 | 121 | case b2Joint.e_mouseJoint: 122 | { 123 | //void* mem = allocator->Allocate(sizeof(b2MouseJoint)); 124 | joint = new b2MouseJoint(def); 125 | } 126 | break; 127 | 128 | case b2Joint.e_prismaticJoint: 129 | { 130 | //void* mem = allocator->Allocate(sizeof(b2PrismaticJoint)); 131 | joint = new b2PrismaticJoint(def); 132 | } 133 | break; 134 | 135 | case b2Joint.e_revoluteJoint: 136 | { 137 | //void* mem = allocator->Allocate(sizeof(b2RevoluteJoint)); 138 | joint = new b2RevoluteJoint(def); 139 | } 140 | break; 141 | 142 | case b2Joint.e_pulleyJoint: 143 | { 144 | //void* mem = allocator->Allocate(sizeof(b2PulleyJoint)); 145 | joint = new b2PulleyJoint(def); 146 | } 147 | break; 148 | 149 | case b2Joint.e_gearJoint: 150 | { 151 | //void* mem = allocator->Allocate(sizeof(b2GearJoint)); 152 | joint = new b2GearJoint(def); 153 | } 154 | break; 155 | 156 | default: 157 | //b2Settings.b2Assert(false); 158 | break; 159 | } 160 | 161 | return joint; 162 | }; 163 | b2Joint.Destroy = function(joint, allocator){ 164 | /*joint->~b2Joint(); 165 | switch (joint.m_type) 166 | { 167 | case b2Joint.e_distanceJoint: 168 | allocator->Free(joint, sizeof(b2DistanceJoint)); 169 | break; 170 | 171 | case b2Joint.e_mouseJoint: 172 | allocator->Free(joint, sizeof(b2MouseJoint)); 173 | break; 174 | 175 | case b2Joint.e_prismaticJoint: 176 | allocator->Free(joint, sizeof(b2PrismaticJoint)); 177 | break; 178 | 179 | case b2Joint.e_revoluteJoint: 180 | allocator->Free(joint, sizeof(b2RevoluteJoint)); 181 | break; 182 | 183 | case b2Joint.e_pulleyJoint: 184 | allocator->Free(joint, sizeof(b2PulleyJoint)); 185 | break; 186 | 187 | case b2Joint.e_gearJoint: 188 | allocator->Free(joint, sizeof(b2GearJoint)); 189 | break; 190 | 191 | default: 192 | b2Assert(false); 193 | break; 194 | }*/ 195 | }; 196 | b2Joint.e_unknownJoint = 0; 197 | b2Joint.e_revoluteJoint = 1; 198 | b2Joint.e_prismaticJoint = 2; 199 | b2Joint.e_distanceJoint = 3; 200 | b2Joint.e_pulleyJoint = 4; 201 | b2Joint.e_mouseJoint = 5; 202 | b2Joint.e_gearJoint = 6; 203 | b2Joint.e_springJoint = 7; 204 | 205 | b2Joint.e_inactiveLimit = 0; 206 | b2Joint.e_atLowerLimit = 1; 207 | b2Joint.e_atUpperLimit = 2; 208 | b2Joint.e_equalLimits = 3; 209 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2JointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | var b2JointDef = function() { 21 | this.type = b2Joint.e_unknownJoint; 22 | this.userData = null; 23 | this.body1 = null; 24 | this.body2 = null; 25 | this.collideConnected = false; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2JointNode.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2JointNode = function() {}; 24 | 25 | b2JointNode.prototype = 26 | { 27 | other: null, 28 | joint: null, 29 | prev: null, 30 | next: null 31 | } 32 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2MouseJoint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | // p = attached point, m = mouse point 24 | // C = p - m 25 | // Cdot = v 26 | // = v + cross(w, r) 27 | // J = [I r_skew] 28 | // Identity used: 29 | // w k % (rx i + ry j) = w * (-ry i + rx j) 30 | 31 | var b2MouseJoint = function(def){ 32 | // The constructor for b2Joint 33 | // initialize instance variables for references 34 | this.m_node1 = new b2JointNode(); 35 | this.m_node2 = new b2JointNode(); 36 | // 37 | this.m_type = def.type; 38 | this.m_prev = null; 39 | this.m_next = null; 40 | this.m_body1 = def.body1; 41 | this.m_body2 = def.body2; 42 | this.m_collideConnected = def.collideConnected; 43 | this.m_islandFlag = false; 44 | this.m_userData = def.userData; 45 | // 46 | 47 | // initialize instance variables for references 48 | this.K = new b2Mat22(); 49 | this.K1 = new b2Mat22(); 50 | this.K2 = new b2Mat22(); 51 | this.m_localAnchor = new b2Vec2(); 52 | this.m_target = new b2Vec2(); 53 | this.m_impulse = new b2Vec2(); 54 | this.m_ptpMass = new b2Mat22(); 55 | this.m_C = new b2Vec2(); 56 | // 57 | 58 | //super(def); 59 | 60 | this.m_target.SetV(def.target); 61 | //this.m_localAnchor = b2Math.b2MulTMV(this.m_body2.m_R, b2Math.SubtractVV( this.m_target, this.m_body2.m_position ) ); 62 | var tX = this.m_target.x - this.m_body2.m_position.x; 63 | var tY = this.m_target.y - this.m_body2.m_position.y; 64 | this.m_localAnchor.x = (tX * this.m_body2.m_R.col1.x + tY * this.m_body2.m_R.col1.y); 65 | this.m_localAnchor.y = (tX * this.m_body2.m_R.col2.x + tY * this.m_body2.m_R.col2.y); 66 | 67 | this.m_maxForce = def.maxForce; 68 | this.m_impulse.SetZero(); 69 | 70 | var mass = this.m_body2.m_mass; 71 | 72 | // Frequency 73 | var omega = 2.0 * b2Settings.b2_pi * def.frequencyHz; 74 | 75 | // Damping coefficient 76 | var d = 2.0 * mass * def.dampingRatio * omega; 77 | 78 | // Spring stiffness 79 | var k = mass * omega * omega; 80 | 81 | // magic formulas 82 | this.m_gamma = 1.0 / (d + def.timeStep * k); 83 | this.m_beta = def.timeStep * k / (d + def.timeStep * k); 84 | }; 85 | 86 | Object.extend(b2MouseJoint.prototype, b2Joint.prototype); 87 | Object.extend(b2MouseJoint.prototype, { 88 | GetAnchor1: function(){ 89 | return this.m_target; 90 | }, 91 | GetAnchor2: function(){ 92 | var tVec = b2Math.b2MulMV(this.m_body2.m_R, this.m_localAnchor); 93 | tVec.Add(this.m_body2.m_position); 94 | return tVec; 95 | }, 96 | 97 | GetReactionForce: function(invTimeStep) 98 | { 99 | //b2Vec2 F = invTimeStep * this.m_impulse; 100 | var F = new b2Vec2(); 101 | F.SetV(this.m_impulse); 102 | F.Multiply(invTimeStep); 103 | return F; 104 | }, 105 | 106 | GetReactionTorque: function(invTimeStep) 107 | { 108 | //NOT_USED(invTimeStep); 109 | return 0.0; 110 | }, 111 | 112 | SetTarget: function(target){ 113 | this.m_body2.WakeUp(); 114 | this.m_target = target; 115 | }, 116 | 117 | //--------------- Internals Below ------------------- 118 | 119 | // Presolve vars 120 | K: new b2Mat22(), 121 | K1: new b2Mat22(), 122 | K2: new b2Mat22(), 123 | PrepareVelocitySolver: function(){ 124 | var b = this.m_body2; 125 | 126 | var tMat; 127 | 128 | // Compute the effective mass matrix. 129 | //b2Vec2 r = b2Mul(b.m_R, this.m_localAnchor); 130 | tMat = b.m_R; 131 | var rX = tMat.col1.x * this.m_localAnchor.x + tMat.col2.x * this.m_localAnchor.y; 132 | var rY = tMat.col1.y * this.m_localAnchor.x + tMat.col2.y * this.m_localAnchor.y; 133 | 134 | // this.K = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)] 135 | // = [1/m1+1/m2 0 ] + invI1 * [r1.y*r1.y -r1.x*r1.y] + invI2 * [r1.y*r1.y -r1.x*r1.y] 136 | // [ 0 1/m1+1/m2] [-r1.x*r1.y r1.x*r1.x] [-r1.x*r1.y r1.x*r1.x] 137 | var invMass = b.m_invMass; 138 | var invI = b.m_invI; 139 | 140 | //b2Mat22 this.K1; 141 | this.K1.col1.x = invMass; this.K1.col2.x = 0.0; 142 | this.K1.col1.y = 0.0; this.K1.col2.y = invMass; 143 | 144 | //b2Mat22 this.K2; 145 | this.K2.col1.x = invI * rY * rY; this.K2.col2.x = -invI * rX * rY; 146 | this.K2.col1.y = -invI * rX * rY; this.K2.col2.y = invI * rX * rX; 147 | 148 | //b2Mat22 this.K = this.K1 + this.K2; 149 | this.K.SetM(this.K1); 150 | this.K.AddM(this.K2); 151 | this.K.col1.x += this.m_gamma; 152 | this.K.col2.y += this.m_gamma; 153 | 154 | //this.m_ptpMass = this.K.Invert(); 155 | this.K.Invert(this.m_ptpMass); 156 | 157 | //this.m_C = b.m_position + r - this.m_target; 158 | this.m_C.x = b.m_position.x + rX - this.m_target.x; 159 | this.m_C.y = b.m_position.y + rY - this.m_target.y; 160 | 161 | // Cheat with some damping 162 | b.m_angularVelocity *= 0.98; 163 | 164 | // Warm starting. 165 | //b2Vec2 P = this.m_impulse; 166 | var PX = this.m_impulse.x; 167 | var PY = this.m_impulse.y; 168 | //b.m_linearVelocity += invMass * P; 169 | b.m_linearVelocity.x += invMass * PX; 170 | b.m_linearVelocity.y += invMass * PY; 171 | //b.m_angularVelocity += invI * b2Cross(r, P); 172 | b.m_angularVelocity += invI * (rX * PY - rY * PX); 173 | }, 174 | 175 | 176 | SolveVelocityConstraints: function(step){ 177 | var body = this.m_body2; 178 | 179 | var tMat; 180 | 181 | // Compute the effective mass matrix. 182 | //b2Vec2 r = b2Mul(body.m_R, this.m_localAnchor); 183 | tMat = body.m_R; 184 | var rX = tMat.col1.x * this.m_localAnchor.x + tMat.col2.x * this.m_localAnchor.y; 185 | var rY = tMat.col1.y * this.m_localAnchor.x + tMat.col2.y * this.m_localAnchor.y; 186 | 187 | // Cdot = v + cross(w, r) 188 | //b2Vec2 Cdot = body->m_linearVelocity + b2Cross(body->m_angularVelocity, r); 189 | var CdotX = body.m_linearVelocity.x + (-body.m_angularVelocity * rY); 190 | var CdotY = body.m_linearVelocity.y + (body.m_angularVelocity * rX); 191 | //b2Vec2 impulse = -b2Mul(this.m_ptpMass, Cdot + (this.m_beta * step->inv_dt) * this.m_C + this.m_gamma * this.m_impulse); 192 | tMat = this.m_ptpMass; 193 | var tX = CdotX + (this.m_beta * step.inv_dt) * this.m_C.x + this.m_gamma * this.m_impulse.x; 194 | var tY = CdotY + (this.m_beta * step.inv_dt) * this.m_C.y + this.m_gamma * this.m_impulse.y; 195 | var impulseX = -(tMat.col1.x * tX + tMat.col2.x * tY); 196 | var impulseY = -(tMat.col1.y * tX + tMat.col2.y * tY); 197 | 198 | var oldImpulseX = this.m_impulse.x; 199 | var oldImpulseY = this.m_impulse.y; 200 | //this.m_impulse += impulse; 201 | this.m_impulse.x += impulseX; 202 | this.m_impulse.y += impulseY; 203 | var length = this.m_impulse.Length(); 204 | if (length > step.dt * this.m_maxForce) 205 | { 206 | //this.m_impulse *= step.dt * this.m_maxForce / length; 207 | this.m_impulse.Multiply(step.dt * this.m_maxForce / length); 208 | } 209 | //impulse = this.m_impulse - oldImpulse; 210 | impulseX = this.m_impulse.x - oldImpulseX; 211 | impulseY = this.m_impulse.y - oldImpulseY; 212 | 213 | //body.m_linearVelocity += body->m_invMass * impulse; 214 | body.m_linearVelocity.x += body.m_invMass * impulseX; 215 | body.m_linearVelocity.y += body.m_invMass * impulseY; 216 | //body.m_angularVelocity += body->m_invI * b2Cross(r, impulse); 217 | body.m_angularVelocity += body.m_invI * (rX * impulseY - rY * impulseX); 218 | }, 219 | SolvePositionConstraints: function(){ 220 | return true; 221 | }, 222 | 223 | m_localAnchor: new b2Vec2(), 224 | m_target: new b2Vec2(), 225 | m_impulse: new b2Vec2(), 226 | 227 | m_ptpMass: new b2Mat22(), 228 | m_C: new b2Vec2(), 229 | m_maxForce: null, 230 | m_beta: null, 231 | m_gamma: null 232 | }); 233 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2MouseJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2MouseJointDef = function() { 20 | // The constructor for b2JointDef 21 | this.type = b2Joint.e_mouseJoint; 22 | this.userData = null; 23 | this.body1 = null; 24 | this.body2 = null; 25 | this.collideConnected = false; 26 | // 27 | 28 | // initialize instance variables for references 29 | this.target = new b2Vec2(); 30 | // 31 | 32 | this.type = b2Joint.e_mouseJoint; 33 | this.maxForce = 0.0; 34 | this.frequencyHz = 5.0; 35 | this.dampingRatio = 0.7; 36 | this.timeStep = 1.0 / 60.0; 37 | }; 38 | 39 | 40 | Object.extend(b2MouseJointDef.prototype, b2JointDef.prototype); 41 | Object.extend(b2MouseJointDef.prototype, { 42 | 43 | target: new b2Vec2(), 44 | maxForce: null, 45 | frequencyHz: null, 46 | dampingRatio: null, 47 | timeStep: null 48 | }); 49 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2PrismaticJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | var b2PrismaticJointDef = function() { 20 | // The constructor for b2JointDef 21 | this.type = b2Joint.e_unknownJoint; 22 | this.userData = null; 23 | this.body1 = null; 24 | this.body2 = null; 25 | this.collideConnected = false; 26 | // 27 | 28 | this.type = b2Joint.e_prismaticJoint; 29 | this.anchorPoint = new b2Vec2(0.0, 0.0); 30 | this.axis = new b2Vec2(0.0, 0.0); 31 | this.lowerTranslation = 0.0; 32 | this.upperTranslation = 0.0; 33 | this.motorForce = 0.0; 34 | this.motorSpeed = 0.0; 35 | this.enableLimit = false; 36 | this.enableMotor = false; 37 | }; 38 | 39 | 40 | Object.extend(b2PrismaticJointDef.prototype, b2JointDef.prototype); 41 | Object.extend(b2PrismaticJointDef.prototype, { 42 | anchorPoint: null, 43 | axis: null, 44 | lowerTranslation: null, 45 | upperTranslation: null, 46 | motorForce: null, 47 | motorSpeed: null, 48 | enableLimit: null, 49 | enableMotor: null 50 | }); 51 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2PulleyJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | 24 | // The pulley joint is connected to two bodies and two fixed ground points. 25 | // The pulley supports a ratio such that: 26 | // length1 + ratio * length2 = constant 27 | // Yes, the force transmitted is scaled by the ratio. 28 | // The pulley also enforces a maximum length limit on both sides. This is 29 | // useful to prevent one side of the pulley hitting the top. 30 | 31 | var b2PulleyJointDef = function() { 32 | // The constructor for b2JointDef 33 | this.type = b2Joint.e_unknownJoint; 34 | this.userData = null; 35 | this.body1 = null; 36 | this.body2 = null; 37 | this.collideConnected = false; 38 | // 39 | 40 | // initialize instance variables for references 41 | this.groundPoint1 = new b2Vec2(); 42 | this.groundPoint2 = new b2Vec2(); 43 | this.anchorPoint1 = new b2Vec2(); 44 | this.anchorPoint2 = new b2Vec2(); 45 | // 46 | 47 | this.type = b2Joint.e_pulleyJoint; 48 | this.groundPoint1.Set(-1.0, 1.0); 49 | this.groundPoint2.Set(1.0, 1.0); 50 | this.anchorPoint1.Set(-1.0, 0.0); 51 | this.anchorPoint2.Set(1.0, 0.0); 52 | this.maxLength1 = 0.5 * b2PulleyJoint.b2_minPulleyLength; 53 | this.maxLength2 = 0.5 * b2PulleyJoint.b2_minPulleyLength; 54 | this.ratio = 1.0; 55 | this.collideConnected = true; 56 | }; 57 | 58 | Object.extend(b2PulleyJointDef.prototype, b2JointDef.prototype); 59 | Object.extend(b2PulleyJointDef.prototype, { 60 | groundPoint1: new b2Vec2(), 61 | groundPoint2: new b2Vec2(), 62 | anchorPoint1: new b2Vec2(), 63 | anchorPoint2: new b2Vec2(), 64 | maxLength1: null, 65 | maxLength2: null, 66 | ratio: null 67 | }); 68 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2RevoluteJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2007 Erin Catto http: 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | 24 | var b2RevoluteJointDef = function() { 25 | // The constructor for b2JointDef 26 | this.type = b2Joint.e_unknownJoint; 27 | this.userData = null; 28 | this.body1 = null; 29 | this.body2 = null; 30 | this.collideConnected = false; 31 | // 32 | 33 | this.type = b2Joint.e_revoluteJoint; 34 | this.anchorPoint = new b2Vec2(0.0, 0.0); 35 | this.lowerAngle = 0.0; 36 | this.upperAngle = 0.0; 37 | this.motorTorque = 0.0; 38 | this.motorSpeed = 0.0; 39 | this.enableLimit = false; 40 | this.enableMotor = false; 41 | }; 42 | 43 | Object.extend(b2RevoluteJointDef.prototype, b2JointDef.prototype); 44 | Object.extend(b2RevoluteJointDef.prototype, { 45 | anchorPoint: null, 46 | lowerAngle: null, 47 | upperAngle: null, 48 | motorTorque: null, 49 | motorSpeed: null, 50 | enableLimit: null, 51 | enableMotor: null 52 | }); 53 | 54 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2SpringJoint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 HRJ http://lavadip.com 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | // C = norm(p2 - p1) - L 22 | // u = (p2 - p1) / norm(p2 - p1) 23 | // Cdot = dot(u, v2 + cross(w2, r2) - v1 - cross(w1, r1)) 24 | // J = [-u -cross(r1, u) u cross(r2, u)] 25 | // K = J * invM * JT 26 | // = invMass1 + invI1 * cross(r1, u)^2 + invMass2 + invI2 * cross(r2, u)^2 27 | 28 | var b2SpringJoint = function(def) { 29 | // The constructor for b2Joint 30 | // initialize instance variables for references 31 | this.m_node1 = new b2JointNode(); 32 | this.m_node2 = new b2JointNode(); 33 | this.m_type = def.type; 34 | this.m_prev = null; 35 | this.m_next = null; 36 | this.m_body1 = def.body1; 37 | this.m_body2 = def.body2; 38 | this.m_collideConnected = def.collideConnected; 39 | this.m_islandFlag = false; 40 | this.m_userData = def.userData; 41 | this.m_strength = def.strength; 42 | this.m_decay = 1.0; 43 | 44 | this.m_localAnchor1 = new b2Vec2(); 45 | this.m_localAnchor2 = new b2Vec2(); 46 | this.m_worldAnchor1 = new b2Vec2(); 47 | this.m_worldAnchor2 = new b2Vec2(); 48 | this.m_diff = new b2Vec2(); 49 | 50 | var tMat; 51 | var tX; 52 | var tY; 53 | tMat = this.m_body1.m_R; 54 | tX = def.anchorPoint1.x - this.m_body1.m_position.x; 55 | tY = def.anchorPoint1.y - this.m_body1.m_position.y; 56 | this.m_localAnchor1.x = tX*tMat.col1.x + tY*tMat.col1.y; 57 | this.m_localAnchor1.y = tX*tMat.col2.x + tY*tMat.col2.y; 58 | tMat = this.m_body2.m_R; 59 | tX = def.anchorPoint2.x - this.m_body2.m_position.x; 60 | tY = def.anchorPoint2.y - this.m_body2.m_position.y; 61 | this.m_localAnchor2.x = tX*tMat.col1.x + tY*tMat.col1.y; 62 | this.m_localAnchor2.y = tX*tMat.col2.x + tY*tMat.col2.y; 63 | 64 | 65 | tX = def.anchorPoint2.x - def.anchorPoint1.x; 66 | tY = def.anchorPoint2.y - def.anchorPoint1.y; 67 | this.m_length = Math.sqrt(tX*tX + tY*tY); 68 | this.previousLength = this.m_length; 69 | }; 70 | 71 | Object.extend(b2SpringJoint.prototype, b2Joint.prototype); 72 | Object.extend(b2SpringJoint.prototype, 73 | { 74 | //--------------- Internals Below ------------------- 75 | 76 | // Trying to emulate Hooke's law for springs 77 | PrepareVelocitySolver: function(){ 78 | var a1 = this.m_worldAnchor1, 79 | a2 = this.m_worldAnchor2; 80 | a1.SetV(this.m_localAnchor1); 81 | a1.MulM(this.m_body1.m_R); 82 | a1.Add(this.m_body1.m_position); 83 | a2.SetV(this.m_localAnchor2); 84 | a2.MulM(this.m_body2.m_R); 85 | a2.Add(this.m_body2.m_position); 86 | 87 | var diff = this.m_diff; 88 | diff.SetV(a2); 89 | diff.Subtract(a1); 90 | 91 | var diffLength = diff.Length(); 92 | if (diffLength > this.m_length) { 93 | if (diffLength > this.previousLength) { 94 | diff.Multiply(this.m_strength); 95 | decay = 1; 96 | } else { 97 | decay = Math.sqrt(decay); 98 | diff.Multiply(this.m_strength * decay); 99 | } 100 | this.previousLength = diffLength; 101 | if (diff.Length() > 2) { 102 | this.m_body1.ApplyImpulse(diff, a1); 103 | this.m_body2.ApplyImpulse(diff.Negative(), a2); 104 | } 105 | } 106 | }, 107 | 108 | 109 | 110 | SolveVelocityConstraints: function(step){ 111 | 112 | }, 113 | 114 | SolvePositionConstraints: function(){ 115 | 116 | }, 117 | 118 | GetReactionForce: function(invTimeStep) 119 | { 120 | var F = new b2Vec2(0, 0); 121 | return F; 122 | }, 123 | 124 | GetReactionTorque: function(invTimeStep) 125 | { 126 | //NOT_USED(invTimeStep); 127 | return 0.0; 128 | }, 129 | 130 | GetAnchor1 : function() { 131 | return this.m_localAnchor1; 132 | }, 133 | GetAnchor2 : function() { 134 | return this.m_localAnchor2; 135 | }, 136 | 137 | m_localAnchor1: null, 138 | m_localAnchor2: null, 139 | m_worldAnchor1 : null, 140 | m_worldAnchor2 : null, 141 | m_diff : null, 142 | m_length: null, 143 | m_strength: 0 144 | }); 145 | 146 | -------------------------------------------------------------------------------- /js/box2d/dynamics/joints/b2SpringJointDef.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 HRJ http://lavadip.com 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * Permission is granted to anyone to use this software for any purpose, 8 | * including commercial applications, and to alter it and redistribute it 9 | * freely, subject to the following restrictions: 10 | * 1. The origin of this software must not be misrepresented; you must not 11 | * claim that you wrote the original software. If you use this software 12 | * in a product, an acknowledgment in the product documentation would be 13 | * appreciated but is not required. 14 | * 2. Altered source versions must be plainly marked, and must not be 15 | * misrepresented the original software. 16 | * 3. This notice may not be removed or altered from any source distribution. 17 | */ 18 | 19 | 20 | 21 | 22 | 23 | var b2SpringJointDef = function(a_body1, a_body2, a_strength) { 24 | // The constructor for b2JointDef 25 | this.type = b2Joint.e_springJoint; 26 | this.userData = null; 27 | this.body1 = a_body1; 28 | this.body2 = a_body2; 29 | this.collideConnected = true; 30 | // 31 | 32 | // initialize instance variables for references 33 | this.anchorPoint1 = new b2Vec2(); 34 | this.anchorPoint2 = new b2Vec2(); 35 | this.strength = a_strength; 36 | }; 37 | 38 | Object.extend(b2SpringJointDef.prototype, b2JointDef.prototype); 39 | Object.extend(b2SpringJointDef.prototype, 40 | { 41 | initialize: function(a_body1, a_body2, a_strength) 42 | { 43 | // The constructor for b2JointDef 44 | this.type = b2Joint.e_springJoint; 45 | this.userData = null; 46 | this.body1 = a_body1; 47 | this.body2 = a_body2; 48 | this.collideConnected = true; 49 | // 50 | 51 | // initialize instance variables for references 52 | this.anchorPoint1 = new b2Vec2(); 53 | this.anchorPoint2 = new b2Vec2(); 54 | this.strength = a_strength; 55 | }, 56 | 57 | anchorPoint1: null, 58 | anchorPoint2: null, 59 | strength : 0 60 | }); 61 | 62 | -------------------------------------------------------------------------------- /old_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Box2DJS - Physics Engine for JavaScript 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
111 |

FPS Step size delay(ms)

112 |

Box2D JS demo

113 |
114 |

115 | Left-click to spawn an object. 116 |

117 |

118 | Press any key to view the next example. 119 |

120 |

121 | Get the source on GitHub. 122 |

123 | 124 |
125 | 126 | 127 | -------------------------------------------------------------------------------- /style/box2d.css: -------------------------------------------------------------------------------- 1 | body { 2 | background:#aaa; 3 | } 4 | 5 | #canvas { 6 | padding:0; 7 | /*background-color:#333;*/ 8 | background:url('../images/yarada.jpg'); 9 | margin:0 auto; 10 | cursor:crosshair; 11 | } 12 | 13 | #CONTAINER { 14 | margin:0 auto; 15 | text-align:center; 16 | } 17 | 18 | .key { 19 | border-bottom:1px solid #555; 20 | } 21 | 22 | .ball { 23 | fill:#edd; 24 | } 25 | 26 | .ballHovering { 27 | fill:#f99; 28 | } 29 | 30 | .poly { 31 | fill:#afa; 32 | } 33 | 34 | .polyHovering{ 35 | fill:#5f5; 36 | } 37 | --------------------------------------------------------------------------------