diff --git a/build/dragonbones/dragonbones.js b/build/dragonbones/dragonbones.js index 5d346b9c..9e023398 100644 --- a/build/dragonbones/dragonbones.js +++ b/build/dragonbones/dragonbones.js @@ -1,5 +1,5 @@ /** - * Hilo 1.1.4 for dragonbones + * Hilo 1.1.9 for dragonbones * Copyright 2016 alibaba.com * Licensed under the MIT License */ diff --git a/build/dragonbones/dragonbones.min.js b/build/dragonbones/dragonbones.min.js index c8bc587d..9c673bad 100644 --- a/build/dragonbones/dragonbones.min.js +++ b/build/dragonbones/dragonbones.min.js @@ -1,5 +1,5 @@ /** - * Hilo 1.1.4 for dragonbones + * Hilo 1.1.9 for dragonbones * Copyright 2016 alibaba.com * Licensed under the MIT License */ diff --git a/build/physics/physics.js b/build/physics/physics.js index 254c31cc..aace76e2 100644 --- a/build/physics/physics.js +++ b/build/physics/physics.js @@ -1,21 +1,21 @@ /** - * Hilo 1.1.4 for physics + * Hilo 1.1.9 for physics * Copyright 2016 alibaba.com * Licensed under the MIT License */ (function(){ /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,7 +30,7 @@ Object.create = Object.create || function(o) { F.prototype = o; return new F(); }; - + //var VERSION = CP_VERSION_MAJOR + "." + CP_VERSION_MINOR + "." + CP_VERSION_RELEASE; var cp; @@ -46,7 +46,6 @@ if(typeof exports === 'undefined'){ var assert = function(value, message) { - return if (!value) { throw new Error('Assertion failed: ' + message); } @@ -54,7 +53,6 @@ var assert = function(value, message) var assertSoft = function(value, message) { - return if(!value && console && console.warn) { console.warn("ASSERTION FAILED: " + message); if(console.trace) { @@ -107,7 +105,7 @@ var deleteObjFromList = function(arr, obj) if(arr[i] === obj){ arr[i] = arr[arr.length - 1]; arr.length--; - + return; } } @@ -162,11 +160,11 @@ cp.momentForPoly = function(m, verts, offset) var a = vcross2(v2x, v2y, v1x, v1y); var b = vdot2(v1x, v1y, v1x, v1y) + vdot2(v1x, v1y, v2x, v2y) + vdot2(v2x, v2y, v2x, v2y); - + sum1 += a*b; sum2 += a; } - + return (m*sum1)/(6*sum2); }; @@ -176,7 +174,7 @@ cp.areaForPoly = function(verts) for(var i=0, len=verts.length; i> 1; for(var i=1; i> 1; //if(first) (*first) = start; var resultCount = QHullReduce(tolerance, result, 2, count - 2, a, b, a, 1) + 1; @@ -388,17 +386,17 @@ var lerpconst = function(f1, f2, d) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -630,7 +628,7 @@ var vnear = cp.v.near = function(v1, v2, dist) var vslerp = cp.v.slerp = function(v1, v2, t) { var omega = Math.acos(vdot(v1, v2)); - + if(omega) { var denom = 1/Math.sin(omega); return vadd(vmult(v1, Math.sin((1 - t)*omega)*denom), vmult(v2, Math.sin(t*omega)*denom)); @@ -665,17 +663,17 @@ var vstr = cp.v.str = function(v) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -796,25 +794,25 @@ var bbWrapVect = function(bb, v) var ix = Math.abs(bb.r - bb.l); var modx = (v.x - bb.l) % ix; var x = (modx > 0) ? modx : modx + ix; - + var iy = Math.abs(bb.t - bb.b); var mody = (v.y - bb.b) % iy; var y = (mody > 0) ? mody : mody + iy; - + return new Vect(x + bb.l, y + bb.b); }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -823,7 +821,7 @@ var bbWrapVect = function(bb, v) * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + /// Segment query info struct. /* These are created using literals where needed. typedef struct cpSegmentQueryInfo { @@ -862,21 +860,21 @@ var Shape = cp.Shape = function(body) { /// Sensor flag. /// Sensor shapes call collision callbacks but don't produce collisions. this.sensor = false; - + /// Coefficient of restitution. (elasticity) this.e = 0; /// Coefficient of friction. this.u = 0; /// Surface velocity used when solving for friction. this.surface_v = vzero; - + /// Collision type of this shape used when picking collision handlers. this.collision_type = 0; /// Group of this shape. Shapes in the same group don't collide. this.group = 0; // Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero. this.layers = CP_ALL_LAYERS; - + this.space = null; // Copy the collision code from the prototype into the actual object. This makes collision @@ -990,7 +988,7 @@ var CircleShape = cp.CircleShape = function(body, radius, offset) { this.c = this.tc = offset; this.r = radius; - + this.type = 'circle'; Shape.call(this, body); @@ -1016,10 +1014,10 @@ CircleShape.prototype.cacheData = function(p, rot) var delta = vsub(p, this.tc); var distsq = vlengthsq(delta); var r = this.r; - + if(distsq < r*r){ var info = new PointQueryExtendedInfo(this); - + var dist = Math.sqrt(distsq); info.d = r - dist; info.n = vmult(delta, 1/dist); @@ -1033,7 +1031,7 @@ CircleShape.prototype.nearestPointQuery = function(p) var deltay = p.y - this.tc.y; var d = vlength2(deltax, deltay); var r = this.r; - + var nearestp = new Vect(this.tc.x + deltax * r/d, this.tc.y + deltay * r/d); return new NearestPointQueryInfo(this, nearestp, d - r); }; @@ -1043,13 +1041,13 @@ var circleSegmentQuery = function(shape, center, r, a, b, info) // offset the line to be relative to the circle a = vsub(a, center); b = vsub(b, center); - + var qa = vdot(a, a) - 2*vdot(a, b) + vdot(b, b); var qb = -2*vdot(a, a) + 2*vdot(a, b); var qc = vdot(a, a) - r*r; - + var det = qb*qb - 4*qa*qc; - + if(det >= 0) { var t = (-qb - Math.sqrt(det))/(2*qa); @@ -1086,12 +1084,12 @@ var SegmentShape = cp.SegmentShape = function(body, a, b, r) this.n = vperp(vnormalize(vsub(b, a))); this.ta = this.tb = this.tn = null; - + this.r = r; - + this.a_tangent = vzero; this.b_tangent = vzero; - + this.type = 'segment'; Shape.call(this, body); }; @@ -1103,9 +1101,9 @@ SegmentShape.prototype.cacheData = function(p, rot) this.ta = vadd(p, vrotate(this.a, rot)); this.tb = vadd(p, vrotate(this.b, rot)); this.tn = vrotate(this.n, rot); - + var l,r,b,t; - + if(this.ta.x < this.tb.x){ l = this.ta.x; r = this.tb.x; @@ -1113,7 +1111,7 @@ SegmentShape.prototype.cacheData = function(p, rot) l = this.tb.x; r = this.ta.x; } - + if(this.ta.y < this.tb.y){ b = this.ta.y; t = this.tb.y; @@ -1121,7 +1119,7 @@ SegmentShape.prototype.cacheData = function(p, rot) b = this.tb.y; t = this.ta.y; } - + var rad = this.r; this.bb_l = l - rad; @@ -1133,12 +1131,12 @@ SegmentShape.prototype.cacheData = function(p, rot) SegmentShape.prototype.nearestPointQuery = function(p) { var closest = closestPointOnSegment(p, this.ta, this.tb); - + var deltax = p.x - closest.x; var deltay = p.y - closest.y; var d = vlength2(deltax, deltay); var r = this.r; - + var nearestp = (d ? vadd(closest, vmult(new Vect(deltax, deltay), r/d)) : closest); return new NearestPointQueryInfo(this, nearestp, d - r); }; @@ -1148,26 +1146,26 @@ SegmentShape.prototype.segmentQuery = function(a, b) var n = this.tn; var d = vdot(vsub(this.ta, a), n); var r = this.r; - + var flipped_n = (d > 0 ? vneg(n) : n); var n_offset = vsub(vmult(flipped_n, r), a); - + var seg_a = vadd(this.ta, n_offset); var seg_b = vadd(this.tb, n_offset); var delta = vsub(b, a); - + if(vcross(delta, seg_a)*vcross(delta, seg_b) <= 0){ var d_offset = d + (d > 0 ? -r : r); var ad = -d_offset; var bd = vdot(delta, n) - d_offset; - + if(ad*bd < 0){ return new SegmentQueryInfo(this, ad/(ad - bd), flipped_n); } } else if(r !== 0){ var info1 = circleSegmentQuery(this, this.ta, this.r, a, b); var info2 = circleSegmentQuery(this, this.tb, this.r, a, b); - + if (info1){ return info2 && info2.t < info1.t ? info2 : info1; } else { @@ -1203,17 +1201,17 @@ CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius); */ /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -1222,7 +1220,7 @@ CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius); * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + /// Check that a set of vertexes is convex and has a clockwise winding. var polyValidate = function(verts) { @@ -1234,13 +1232,13 @@ var polyValidate = function(verts) var by = verts[(i+3)%len]; var cx = verts[(i+4)%len]; var cy = verts[(i+5)%len]; - + //if(vcross(vsub(b, a), vsub(c, b)) > 0){ if(vcross2(bx - ax, by - ay, cx - bx, cy - by) > 0){ return false; } } - + return true; }; @@ -1274,7 +1272,7 @@ PolyShape.prototype.setVerts = function(verts, offset) // Fail if the user attempts to pass a concave poly, or a bad winding. assert(polyValidate(verts), "Polygon is concave or has a reversed winding. Consider using cpConvexHull()"); - + var len = verts.length; var numVerts = len >> 1; @@ -1284,7 +1282,7 @@ PolyShape.prototype.setVerts = function(verts, offset) this.tVerts = new Array(len); this.planes = new Array(numVerts); this.tPlanes = new Array(numVerts); - + for(var i=0; i (' + vx + ',' + vy + ')'); - + dst[i] = vx; dst[i+1] = vy; @@ -1362,7 +1360,7 @@ PolyShape.prototype.transformAxes = function(p, rot) { var src = this.planes; var dst = this.tPlanes; - + for(var i=0; i 0) outside = true; - + var v1x = verts[i*2]; var v1y = verts[i*2 + 1]; var closest = closestPointOnSegment2(p.x, p.y, v0x, v0y, v1x, v1y); - + var dist = vdist(p, closest); if(dist < minDist){ minDist = dist; closestPoint = closest; } - + v0x = v1x; v0y = v1y; } - + return new NearestPointQueryInfo(this, closestPoint, (outside ? minDist : -minDist)); }; @@ -1413,16 +1411,16 @@ PolyShape.prototype.segmentQuery = function(a, b) var verts = this.tVerts; var numVerts = axes.length; var len = numVerts * 2; - + for(var i=0; i an) continue; - + var bn = vdot(b, n); var t = (axes[i].d - an)/(bn - an); if(t < 0 || 1 < t) continue; - + var point = vlerp(a, b, t); var dt = -vcross(n, point); var dtMin = -vcross2(n.x, n.y, verts[i*2], verts[i*2+1]); @@ -1441,38 +1439,38 @@ PolyShape.prototype.valueOnAxis = function(n, d) { var verts = this.tVerts; var m = vdot2(n.x, n.y, verts[0], verts[1]); - + for(var i=2; i 0) return false; } - + return true; }; PolyShape.prototype.containsVertPartial = function(vx, vy, n) { var planes = this.tPlanes; - + for(var i=0; i 0) return false; } - + return true; }; @@ -1945,31 +1943,31 @@ var SpatialIndex = cp.SpatialIndex = function(staticIndex) } }; -// Collide the objects in an index against the objects in a staticIndex using the query callback function. +// Collide the objects in a dynamic index against the objects in a static index using the query callback function. SpatialIndex.prototype.collideStatic = function(staticIndex, func) { if(staticIndex.count > 0){ - var query = staticIndex.query; - - this.each(function(obj) { - query(obj, new BB(obj.bb_l, obj.bb_b, obj.bb_r, obj.bb_t), func); + this.each(function(obj1) { + staticIndex.query(new BB(obj1.bb_l, obj1.bb_b, obj1.bb_r, obj1.bb_t), function (obj2) { + func(obj1, obj2); + }); }); } }; /* Copyright (c) 2009 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -1984,7 +1982,7 @@ SpatialIndex.prototype.collideStatic = function(staticIndex, func) var BBTree = cp.BBTree = function(staticIndex) { SpatialIndex.call(this, staticIndex); - + this.velocityFunc = null; // This is a hash from object ID -> object for the objects stored in the BBTree. @@ -1993,11 +1991,11 @@ var BBTree = cp.BBTree = function(staticIndex) this.count = 0; this.root = null; - + // A linked list containing an object pool of tree nodes and pairs. this.pooledNodes = null; this.pooledPairs = null; - + this.stamp = 0; }; @@ -2013,7 +2011,7 @@ var Node = function(tree, a, b) this.bb_r = max(a.bb_r, b.bb_r); this.bb_t = max(a.bb_t, b.bb_t); this.parent = null; - + this.setA(a); this.setB(b); }; @@ -2053,7 +2051,7 @@ BBTree.prototype.getBB = function(obj, dest) var coef = 0.1; var x = (obj.bb_r - obj.bb_l)*coef; var y = (obj.bb_t - obj.bb_b)*coef; - + var v = vmult(velocityFunc(obj), 0.1); dest.bb_l = obj.bb_l + min(-x, v.x); @@ -2133,7 +2131,7 @@ var unlinkThread = function(prev, leaf, next) if(next){ if(next.leafA === leaf) next.prevA = prev; else next.prevB = prev; } - + if(prev){ if(prev.leafA === leaf) prev.nextA = next; else prev.nextB = next; } else { @@ -2147,7 +2145,7 @@ Leaf.prototype.clearPairs = function(tree) next; this.pairs = null; - + while(pair){ if(pair.leafA === this){ next = pair.nextA; @@ -2170,7 +2168,7 @@ var pairInsert = function(a, b, tree) if(nextA){ if(nextA.leafA === a) nextA.prevA = pair; else nextA.prevB = pair; } - + if(nextB){ if(nextB.leafA === b) nextB.prevA = pair; else nextB.prevB = pair; } @@ -2212,7 +2210,7 @@ Node.prototype.otherChild = function(child) Node.prototype.replaceChild = function(child, value, tree) { assertSoft(child == this.A || child == this.B, "Node is not a child of parent."); - + if(this.A == child){ this.A.recycle(tree); this.setA(value); @@ -2220,7 +2218,7 @@ Node.prototype.replaceChild = function(child, value, tree) this.B.recycle(tree); this.setB(value); } - + for(var node=this; node; node = node.parent){ //node.bb = bbMerge(node.A.bb, node.B.bb); var a = node.A; @@ -2263,18 +2261,18 @@ var subtreeInsert = function(subtree, leaf, tree) } else { var cost_a = subtree.B.bbArea() + bbTreeMergedArea(subtree.A, leaf); var cost_b = subtree.A.bbArea() + bbTreeMergedArea(subtree.B, leaf); - + if(cost_a === cost_b){ cost_a = bbProximity(subtree.A, leaf); cost_b = bbProximity(subtree.B, leaf); - } + } if(cost_b < cost_a){ subtree.setB(subtreeInsert(subtree.B, leaf, tree)); } else { subtree.setA(subtreeInsert(subtree.A, leaf, tree)); } - + // subtree.bb = bbMerge(subtree.bb, leaf.bb); subtree.bb_l = min(subtree.bb_l, leaf.bb_l); subtree.bb_b = min(subtree.bb_b, leaf.bb_b); @@ -2311,20 +2309,20 @@ var nodeSegmentQuery = function(node, a, b) var tx2 = (node.bb_r == a.x ? Infinity : (node.bb_r - a.x)*idx); var txmin = min(tx1, tx2); var txmax = max(tx1, tx2); - + var idy = 1/(b.y - a.y); var ty1 = (node.bb_b == a.y ? -Infinity : (node.bb_b - a.y)*idy); var ty2 = (node.bb_t == a.y ? Infinity : (node.bb_t - a.y)*idy); var tymin = min(ty1, ty2); var tymax = max(ty1, ty2); - + if(tymin <= txmax && txmin <= tymax){ var min_ = max(txmin, tymin); var max_ = min(txmax, tymax); - + if(0.0 <= max_ && min_ <= 1.0) return max(min_, 0.0); } - + return Infinity; }; @@ -2335,7 +2333,7 @@ var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) } else { var t_a = nodeSegmentQuery(subtree.A, a, b); var t_b = nodeSegmentQuery(subtree.B, a, b); - + if(t_a < t_b){ if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func)); if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func)); @@ -2343,7 +2341,7 @@ var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func)); if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func)); } - + return t_exit; } }; @@ -2414,7 +2412,7 @@ Leaf.prototype.markSubtree = function(tree, staticRoot, func) { if(this.stamp == tree.getStamp()){ if(staticRoot) staticRoot.markLeafQuery(this, false, tree, func); - + for(var node = this; node.parent; node = node.parent){ if(node == node.parent.A){ node.parent.B.markLeafQuery(this, true, tree, func); @@ -2456,16 +2454,16 @@ Leaf.prototype.update = function(tree) //if(!bbContainsBB(this.bb, bb)){ if(!this.containsObj(obj)){ tree.getBB(this.obj, this); - + root = subtreeRemove(root, this, tree); tree.root = subtreeInsert(root, this, tree); - + this.clearPairs(tree); this.stamp = tree.getStamp(); - + return true; } - + return false; }; @@ -2492,7 +2490,7 @@ BBTree.prototype.insert = function(obj, hashid) this.leaves[hashid] = leaf; this.root = subtreeInsert(this.root, leaf, this); this.count++; - + leaf.stamp = this.getStamp(); leaf.addPairs(this); this.incrementStamp(); @@ -2521,7 +2519,7 @@ var voidQueryFunc = function(obj1, obj2){}; BBTree.prototype.reindexQuery = function(func) { if(!this.root) return; - + // LeafUpdate() may modify this.root. Don't cache it. var hashid, leaves = this.leaves; @@ -2529,13 +2527,13 @@ BBTree.prototype.reindexQuery = function(func) { leaves[hashid].update(this); } - + var staticIndex = this.staticIndex; var staticRoot = staticIndex && staticIndex.root; - + this.root.markSubtree(this, staticRoot, func); if(staticIndex && !staticRoot) this.collideStatic(this, staticIndex, func); - + this.incrementStamp(); }; @@ -2602,7 +2600,7 @@ var partitionNodes = function(tree, nodes, offset, count) } else if(count == 2) { return tree.makeNode(nodes[offset], nodes[offset + 1]); } - + // Find the AABB for these nodes //var bb = nodes[offset].bb; var node = nodes[offset]; @@ -2620,10 +2618,10 @@ var partitionNodes = function(tree, nodes, offset, count) bb_r = max(bb_r, node.bb_r); bb_t = max(bb_t, node.bb_t); } - + // Split it on it's longest axis var splitWidth = (bb_r - bb_l > bb_t - bb_b); - + // Sort the bounds and use the median as the splitting point var bounds = new Array(count*2); if(splitWidth){ @@ -2637,7 +2635,7 @@ var partitionNodes = function(tree, nodes, offset, count) bounds[2*i + 1] = nodes[i].bb_t; } } - + bounds.sort(function(a, b) { // This might run faster if the function was moved out into the global scope. return a - b; @@ -2650,7 +2648,7 @@ var partitionNodes = function(tree, nodes, offset, count) var b_l = bb_l, b_b = bb_b, b_r = bb_r, b_t = bb_t; if(splitWidth) a_r = b_l = split; else a_t = b_b = split; - + // Partition the nodes var right = end; for(var left=offset; left < right;){ @@ -2664,13 +2662,13 @@ var partitionNodes = function(tree, nodes, offset, count) left++; } } - + if(right == count){ var node = null; for(var i=offset; iprev = prev; if(next.body_a === body){ @@ -3032,15 +3030,15 @@ Arbiter.prototype.unthread = function() //{ // cpFloat fsum = 0; // cpVect vsum = vzero; -// +// // for(int i=0; i= mindist*mindist) return; - + var dist = Math.sqrt(distsq); // Allocate and initialize the contact. @@ -3276,15 +3274,15 @@ var circle2segment = function(circleShape, segmentShape) var seg_a = segmentShape.ta; var seg_b = segmentShape.tb; var center = circleShape.tc; - + var seg_delta = vsub(seg_b, seg_a); var closest_t = clamp01(vdot(seg_delta, vsub(center, seg_a))/vlengthsq(seg_delta)); var closest = vadd(seg_a, vmult(seg_delta, closest_t)); - + var contact = circle2circleQuery(center, closest, circleShape.r, segmentShape.r); if(contact){ var n = contact.n; - + // Reject endcap collisions if tangents are provided. return ( (closest_t === 0 && vdot(n, segmentShape.a_tangent) < 0) || @@ -3308,7 +3306,7 @@ var findMSA = function(poly, planes) var min_index = 0; var min = poly.valueOnAxis(planes[0].n, planes[0].d); if(min > 0) return -1; - + for(var i=1; i 0) { @@ -3318,7 +3316,7 @@ var findMSA = function(poly, planes) min_index = i; } } - + last_MSA_min = min; return min_index; }; @@ -3338,7 +3336,7 @@ var findVertsFallback = function(poly1, poly2, n, dist) arr.push(new Contact(new Vect(vx, vy), n, dist, hashPair(poly1.hashid, i))); } } - + var verts2 = poly2.tVerts; for(var i=0; i>1))); } } - + var verts2 = poly2.tVerts; for(var i=0; i>1))); } } - + return (arr.length ? arr : findVertsFallback(poly1, poly2, n, dist)); }; @@ -3383,11 +3381,11 @@ var poly2poly = function(poly1, poly2) var mini1 = findMSA(poly2, poly1.tPlanes); if(mini1 == -1) return NONE; var min1 = last_MSA_min; - + var mini2 = findMSA(poly1, poly2.tPlanes); if(mini2 == -1) return NONE; var min2 = last_MSA_min; - + // There is overlap, find the penetrating verts if(min1 > min2) return findVerts(poly1, poly2, poly1.tPlanes[mini1].n, min1); @@ -3404,12 +3402,12 @@ var segValueOnAxis = function(seg, n, d) }; // Identify vertexes that have penetrated the segment. -var findPointsBehindSeg = function(arr, seg, poly, pDist, coef) +var findPointsBehindSeg = function(arr, seg, poly, pDist, coef) { var dta = vcross(seg.tn, seg.ta); var dtb = vcross(seg.tn, seg.tb); var n = vmult(seg.tn, coef); - + var verts = poly.tVerts; for(var i=0; i 0 || minNorm > 0) return NONE; - + var mini = 0; var poly_min = segValueOnAxis(seg, planes[0].n, planes[0].d); if(poly_min > 0) return NONE; @@ -3449,34 +3447,34 @@ var seg2poly = function(seg, poly) mini = i; } } - + var poly_n = vneg(planes[mini].n); - + var va = vadd(seg.ta, vmult(poly_n, seg.r)); var vb = vadd(seg.tb, vmult(poly_n, seg.r)); if(poly.containsVert(va.x, va.y)) arr.push(new Contact(va, poly_n, poly_min, hashPair(seg.hashid, 0))); if(poly.containsVert(vb.x, vb.y)) arr.push(new Contact(vb, poly_n, poly_min, hashPair(seg.hashid, 1))); - + // Floating point precision problems here. // This will have to do for now. // poly_min -= cp_collision_slop; // TODO is this needed anymore? - + if(minNorm >= poly_min || minNeg >= poly_min) { if(minNorm > minNeg) findPointsBehindSeg(arr, seg, poly, minNorm, 1); else findPointsBehindSeg(arr, seg, poly, minNeg, -1); } - + // If no other collision points are found, try colliding endpoints. if(arr.length === 0){ var mini2 = mini * 2; var verts = poly.tVerts; var poly_a = new Vect(verts[mini2], verts[mini2+1]); - + var con; if((con = circle2circleQuery(seg.ta, poly_a, seg.r, 0, arr))) return [con]; if((con = circle2circleQuery(seg.tb, poly_a, seg.r, 0, arr))) return [con]; @@ -3497,7 +3495,7 @@ var seg2poly = function(seg, poly) var circle2poly = function(circ, poly) { var planes = poly.tPlanes; - + var mini = 0; var min = vdot(planes[0].n, circ.tc) - planes[0].d - circ.r; for(var i=0; i 0, "You created a 0 length pin joint. A pivot joint will be much more stable."); this.r1 = this.r2 = null; @@ -5251,21 +5249,21 @@ PinJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); var dist = vlength(delta); this.n = vmult(delta, 1/(dist ? dist : Infinity)); - + // calculate mass normal this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*(dist - this.dist)/dt, -maxBias, maxBias); - + // compute max impulse this.jnMax = this.maxForce * dt; }; @@ -5284,13 +5282,13 @@ PinJoint.prototype.applyImpulse = function() // compute relative velocity var vrn = normal_relative_velocity(a, b, this.r1, this.r2, n); - + // compute normal impulse var jn = (this.bias - vrn)*this.nMass; var jnOld = this.jnAcc; this.jnAcc = clamp(jnOld + jn, -this.jnMax, this.jnMax); jn = this.jnAcc - jnOld; - + // apply impulse apply_impulses(a, b, this.r1, this.r2, n.x*jn, n.y*jn); }; @@ -5301,17 +5299,17 @@ PinJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5324,7 +5322,7 @@ PinJoint.prototype.getImpulse = function() var SlideJoint = cp.SlideJoint = function(a, b, anchr1, anchr2, min, max) { Constraint.call(this, a, b); - + this.anchr1 = anchr1; this.anchr2 = anchr2; this.min = min; @@ -5332,7 +5330,7 @@ var SlideJoint = cp.SlideJoint = function(a, b, anchr1, anchr2, min, max) this.r1 = this.r2 = this.n = null; this.nMass = 0; - + this.jnAcc = this.jnMax = 0; this.bias = 0; }; @@ -5343,10 +5341,10 @@ SlideJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); var dist = vlength(delta); var pdist = 0; @@ -5360,14 +5358,14 @@ SlideJoint.prototype.preStep = function(dt) this.n = vzero; this.jnAcc = 0; } - + // calculate mass normal this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - + // compute max impulse this.jnMax = this.maxForce * dt; }; @@ -5384,21 +5382,21 @@ SlideJoint.prototype.applyImpulse = function() var a = this.a; var b = this.b; - + var n = this.n; var r1 = this.r1; var r2 = this.r2; - + // compute relative velocity var vr = relative_velocity(a, b, r1, r2); var vrn = vdot(vr, n); - + // compute normal impulse var jn = (this.bias - vrn)*this.nMass; var jnOld = this.jnAcc; this.jnAcc = clamp(jnOld + jn, -this.jnMax, 0); jn = this.jnAcc - jnOld; - + // apply impulse apply_impulses(a, b, this.r1, this.r2, n.x * jn, n.y * jn); }; @@ -5409,17 +5407,17 @@ SlideJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5433,7 +5431,7 @@ SlideJoint.prototype.getImpulse = function() var PivotJoint = cp.PivotJoint = function(a, b, anchr1, anchr2) { Constraint.call(this, a, b); - + if(typeof anchr2 === 'undefined') { var pivot = anchr1; @@ -5445,7 +5443,7 @@ var PivotJoint = cp.PivotJoint = function(a, b, anchr1, anchr2) this.anchr2 = anchr2; this.r1 = this.r2 = vzero; - + this.k1 = new Vect(0,0); this.k2 = new Vect(0,0); this.jAcc = vzero; @@ -5460,16 +5458,16 @@ PivotJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + // Calculate mass tensor. Result is stored into this.k1 & this.k2. k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); - + // compute max impulse this.jMaxLen = this.maxForce * dt; - + // calculate bias velocity var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias); @@ -5484,18 +5482,18 @@ PivotJoint.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + var r1 = this.r1; var r2 = this.r2; - + // compute relative velocity var vr = relative_velocity(a, b, r1, r2); - + // compute normal impulse var j = mult_k(vsub(this.bias, vr), this.k1, this.k2); var jOld = this.jAcc; this.jAcc = vclamp(vadd(this.jAcc, j), this.jMaxLen); - + // apply impulse apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y); }; @@ -5506,17 +5504,17 @@ PivotJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5529,12 +5527,12 @@ PivotJoint.prototype.getImpulse = function() var GrooveJoint = cp.GrooveJoint = function(a, b, groove_a, groove_b, anchr2) { Constraint.call(this, a, b); - + this.grv_a = groove_a; this.grv_b = groove_b; this.grv_n = vperp(vnormalize(vsub(groove_b, groove_a))); this.anchr2 = anchr2; - + this.grv_tn = null; this.clamp = 0; this.r1 = this.r2 = null; @@ -5553,7 +5551,7 @@ GrooveJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + // calculate endpoints in worldspace var ta = a.local2World(this.grv_a); var tb = a.local2World(this.grv_b); @@ -5561,10 +5559,10 @@ GrooveJoint.prototype.preStep = function(dt) // calculate axis var n = vrotate(this.grv_n, a.rot); var d = vdot(ta, n); - + this.grv_tn = n; this.r2 = vrotate(this.anchr2, b.rot); - + // calculate tangential distance along the axis of r2 var td = vcross(vadd(b.p, this.r2), n); // calculate clamping factor and r2 @@ -5578,13 +5576,13 @@ GrooveJoint.prototype.preStep = function(dt) this.clamp = 0; this.r1 = vsub(vadd(vmult(vperp(n), -td), vmult(n, d)), a.p); } - + // Calculate mass tensor - k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); - + k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); + // compute max impulse this.jMaxLen = this.maxForce * dt; - + // calculate bias velocity var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias); @@ -5605,17 +5603,17 @@ GrooveJoint.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + var r1 = this.r1; var r2 = this.r2; - + // compute impulse var vr = relative_velocity(a, b, r1, r2); var j = mult_k(vsub(this.bias, vr), this.k1, this.k2); var jOld = this.jAcc; this.jAcc = this.grooveConstrain(vadd(jOld, j)); - + // apply impulse apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y); }; @@ -5629,7 +5627,7 @@ GrooveJoint.prototype.setGrooveA = function(value) { this.grv_a = value; this.grv_n = vperp(vnormalize(vsub(this.grv_b, value))); - + this.activateBodies(); }; @@ -5637,22 +5635,22 @@ GrooveJoint.prototype.setGrooveB = function(value) { this.grv_b = value; this.grv_n = vperp(vnormalize(vsub(value, this.grv_a))); - + this.activateBodies(); }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5669,10 +5667,10 @@ var defaultSpringForce = function(spring, dist){ var DampedSpring = cp.DampedSpring = function(a, b, anchr1, anchr2, restLength, stiffness, damping) { Constraint.call(this, a, b); - + this.anchr1 = anchr1; this.anchr2 = anchr2; - + this.restLength = restLength; this.stiffness = stiffness; this.damping = damping; @@ -5691,18 +5689,18 @@ DampedSpring.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); var dist = vlength(delta); this.n = vmult(delta, 1/(dist ? dist : Infinity)); - + var k = k_scalar(a, b, this.r1, this.r2, this.n); assertSoft(k !== 0, "Unsolvable this."); this.nMass = 1/k; - + this.target_vrn = 0; this.v_coef = 1 - Math.exp(-this.damping*dt*k); @@ -5717,18 +5715,18 @@ DampedSpring.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + var n = this.n; var r1 = this.r1; var r2 = this.r2; // compute relative velocity var vrn = normal_relative_velocity(a, b, r1, r2, n); - + // compute velocity loss from drag var v_damp = (this.target_vrn - vrn)*this.v_coef; this.target_vrn = vrn + v_damp; - + v_damp *= this.nMass; apply_impulses(a, b, this.r1, this.r2, this.n.x * v_damp, this.n.y * v_damp); }; @@ -5739,17 +5737,17 @@ DampedSpring.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5766,7 +5764,7 @@ var defaultSpringTorque = function(spring, relativeAngle){ var DampedRotarySpring = cp.DampedRotarySpring = function(a, b, restAngle, stiffness, damping) { Constraint.call(this, a, b); - + this.restAngle = restAngle; this.stiffness = stiffness; this.damping = damping; @@ -5783,7 +5781,7 @@ DampedRotarySpring.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + var moment = a.i_inv + b.i_inv; assertSoft(moment !== 0, "Unsolvable spring."); this.iSum = 1/moment; @@ -5803,15 +5801,15 @@ DampedRotarySpring.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + // compute relative velocity var wrn = a.w - b.w;//normal_relative_velocity(a, b, r1, r2, n) - this.target_vrn; - + // compute velocity loss from drag // not 100% certain spring is derived correctly, though it makes sense var w_damp = (this.target_wrn - wrn)*this.w_coef; this.target_wrn = wrn + w_damp; - + //apply_impulses(a, b, this.r1, this.r2, vmult(this.n, v_damp*this.nMass)); var j_damp = w_damp*this.iSum; a.w += j_damp*a.i_inv; @@ -5821,17 +5819,17 @@ DampedRotarySpring.prototype.applyImpulse = function() // DampedRotarySpring.prototype.getImpulse = function(){ return 0; }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5844,7 +5842,7 @@ DampedRotarySpring.prototype.applyImpulse = function() var RotaryLimitJoint = cp.RotaryLimitJoint = function(a, b, min, max) { Constraint.call(this, a, b); - + this.min = min; this.max = max; @@ -5859,7 +5857,7 @@ RotaryLimitJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + var dist = b.a - a.a; var pdist = 0; if(dist > this.max) { @@ -5867,14 +5865,14 @@ RotaryLimitJoint.prototype.preStep = function(dt) } else if(dist < this.min) { pdist = this.min - dist; } - + // calculate moment of inertia coefficient. this.iSum = 1/(1/a.i + 1/b.i); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - + // compute max impulse this.jMax = this.maxForce * dt; @@ -5886,7 +5884,7 @@ RotaryLimitJoint.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -5898,11 +5896,11 @@ RotaryLimitJoint.prototype.applyImpulse = function() var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w - a.w; - - // compute normal impulse + + // compute normal impulse var j = -(this.bias + wr)*this.iSum; var jOld = this.jAcc; if(this.bias < 0){ @@ -5911,7 +5909,7 @@ RotaryLimitJoint.prototype.applyImpulse = function() this.jAcc = clamp(jOld + j, -this.jMax, 0); } j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -5923,17 +5921,17 @@ RotaryLimitJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5950,10 +5948,10 @@ var RatchetJoint = cp.RatchetJoint = function(a, b, phase, ratchet) this.angle = 0; this.phase = phase; this.ratchet = ratchet; - + // STATIC_BODY_CHECK this.angle = (b ? b.a : 0) - (a ? a.a : 0); - + this.iSum = this.bias = this.jAcc = this.jMax = 0; }; @@ -5963,28 +5961,28 @@ RatchetJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + var angle = this.angle; var phase = this.phase; var ratchet = this.ratchet; - + var delta = b.a - a.a; var diff = angle - delta; var pdist = 0; - + if(diff*ratchet > 0){ pdist = diff; } else { this.angle = Math.floor((delta - phase)/ratchet)*ratchet + phase; } - + // calculate moment of inertia coefficient. this.iSum = 1/(a.i_inv + b.i_inv); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - + // compute max impulse this.jMax = this.maxForce * dt; @@ -5996,7 +5994,7 @@ RatchetJoint.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -6008,17 +6006,17 @@ RatchetJoint.prototype.applyImpulse = function() var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w - a.w; var ratchet = this.ratchet; - - // compute normal impulse + + // compute normal impulse var j = -(this.bias + wr)*this.iSum; var jOld = this.jAcc; this.jAcc = clamp((jOld + j)*ratchet, 0, this.jMax*Math.abs(ratchet))/ratchet; j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -6030,17 +6028,17 @@ RatchetJoint.prototype.getImpulse = function(joint) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -6053,11 +6051,11 @@ RatchetJoint.prototype.getImpulse = function(joint) var GearJoint = cp.GearJoint = function(a, b, phase, ratio) { Constraint.call(this, a, b); - + this.phase = phase; this.ratio = ratio; this.ratio_inv = 1/ratio; - + this.jAcc = 0; this.iSum = this.bias = this.jMax = 0; @@ -6069,14 +6067,14 @@ GearJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + // calculate moment of inertia coefficient. this.iSum = 1/(a.i_inv*this.ratio_inv + this.ratio*b.i_inv); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*(b.a*this.ratio - a.a - this.phase)/dt, -maxBias, maxBias); - + // compute max impulse this.jMax = this.maxForce * dt; }; @@ -6085,7 +6083,7 @@ GearJoint.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv*this.ratio_inv; b.w += j*b.i_inv; @@ -6095,22 +6093,22 @@ GearJoint.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w*this.ratio - a.w; - - // compute normal impulse + + // compute normal impulse var j = (this.bias - wr)*this.iSum; var jOld = this.jAcc; this.jAcc = clamp(jOld + j, -this.jMax, this.jMax); j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv*this.ratio_inv; b.w += j*b.i_inv; }; -GearJoint.prototype.getImpulse = function() +GearJoint.prototype.getImpulse = function() { return Math.abs(this.jAcc); }; @@ -6123,17 +6121,17 @@ GearJoint.prototype.setRatio = function(value) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -6146,9 +6144,9 @@ GearJoint.prototype.setRatio = function(value) var SimpleMotor = cp.SimpleMotor = function(a, b, rate) { Constraint.call(this, a, b); - + this.rate = rate; - + this.jAcc = 0; this.iSum = this.jMax = 0; @@ -6160,7 +6158,7 @@ SimpleMotor.prototype.preStep = function(dt) { // calculate moment of inertia coefficient. this.iSum = 1/(this.a.i_inv + this.b.i_inv); - + // compute max impulse this.jMax = this.maxForce * dt; }; @@ -6169,7 +6167,7 @@ SimpleMotor.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -6179,16 +6177,16 @@ SimpleMotor.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w - a.w + this.rate; - - // compute normal impulse + + // compute normal impulse var j = -wr*this.iSum; var jOld = this.jAcc; this.jAcc = clamp(jOld + j, -this.jMax, this.jMax); j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv; b.w += j*b.i_inv; diff --git a/build/physics/physics.min.js b/build/physics/physics.min.js index f5e29b93..22e0c373 100644 --- a/build/physics/physics.min.js +++ b/build/physics/physics.min.js @@ -1,8 +1,8 @@ /** - * Hilo 1.1.4 for physics + * Hilo 1.1.9 for physics * Copyright 2016 alibaba.com * Licensed under the MIT License */ -!function(){Object.create=Object.create||function(t){function i(){}return i.prototype=t,new i};var t;"undefined"==typeof exports?(t={},"object"==typeof window&&(window.cp=t)):t=exports;var i,e,s=function(t,i){},n=function(t,i){},r=function(t,i){return ti?t:i};"object"==typeof window&&window.navigator.userAgent.indexOf("Firefox")>-1?(i=Math.min,e=Math.max):(i=r,e=o);var a=function(t,i){return t>1,h=1;hs||c==s&&p>n)&&(s=c,n=p,o=h)}return[r,o]},u=function(t,i,e){var s=t[2*i];t[2*i]=t[2*e],t[2*e]=s,s=t[2*i+1],t[2*i+1]=t[2*e+1],t[2*e+1]=s},y=function(t,i,e,s,n,r){if(0===e)return 0;for(var o=0,a=i,h=A(n,s),c=r*m(h),p=i,l=i+e-1;p<=l;){var y=new f(t[2*p],t[2*p+1]),b=C(h,A(y,s));b>c?(b>o&&(o=b,a=p),p++):(u(t,p,l),l--)}return a!=i&&u(t,i,a),p-i},b=function(t,i,e,s,n,r,o,a){if(s<0)return 0;if(0==s)return i[2*a]=r.x,i[2*a+1]=r.y,1;var h=y(i,e,s,n,r,t),c=new f(i[2*e],i[2*e+1]),p=b(t,i,e+1,h-1,n,c,r,a),l=a+p++;i[2*l]=r.x,i[2*l+1]=r.y;var u=y(i,e+h,s-h,r,o,t),d=new f(i[2*(e+h)],i[2*(e+h)+1]);return p+b(t,i,e+h+1,u-1,r,d,o,a+p)};t.convexHull=function(t,i,e){if(i)for(var s=0;s>1,y=b(e,i,2,p-2,h,c,h,1)+1;return i.length=2*y,n(tt(i),"Internal error: cpConvexHull() and cpPolyValidate() did not agree.Please report this error with as much info as you can."),i};var d=function(t,s,n){return i(e(t,s),n)},v=function(t){return e(0,i(t,1))},f=t.Vect=function(t,i){this.x=t,this.y=i};t.v=function(t,i){return new f(t,i)};var _=t.vzero=new f(0,0),x=t.v.dot=function(t,i){return t.x*i.x+t.y*i.y},g=function(t,i,e,s){return t*e+i*s},m=t.v.len=function(t){return Math.sqrt(x(t,t))},w=t.v.len2=function(t,i){return Math.sqrt(t*t+i*i)},S=(t.v.eql=function(t,i){return t.x===i.x&&t.y===i.y},t.v.add=function(t,i){return new f(t.x+i.x,t.y+i.y)});f.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this};var A=t.v.sub=function(t,i){return new f(t.x-i.x,t.y-i.y)};f.prototype.sub=function(t){return this.x-=t.x,this.y-=t.y,this};var B=t.v.neg=function(t){return new f((-t.x),(-t.y))};f.prototype.neg=function(){return this.x=-this.x,this.y=-this.y,this};var j=t.v.mult=function(t,i){return new f(t.x*i,t.y*i)};f.prototype.mult=function(t){return this.x*=t,this.y*=t,this};var C=t.v.cross=function(t,i){return t.x*i.y-t.y*i.x},k=function(t,i,e,s){return t*s-i*e},M=t.v.perp=function(t){return new f((-t.y),t.x)},P=(t.v.pvrperp=function(t){return new f(t.y,(-t.x))},t.v.project=function(t,i){return j(i,x(t,i)/T(i))});f.prototype.project=function(t){return this.mult(x(this,t)/T(t)),this};var I=t.v.rotate=function(t,i){return new f(t.x*i.x-t.y*i.y,t.x*i.y+t.y*i.x)};f.prototype.rotate=function(t){return this.x=this.x*t.x-this.y*t.y,this.y=this.x*t.y+this.y*t.x,this};var L=t.v.unrotate=function(t,i){return new f(t.x*i.x+t.y*i.y,t.y*i.x-t.x*i.y)},T=t.v.lengthsq=function(t){return x(t,t)},V=t.v.lengthsq2=function(t,i){return t*t+i*i},R=t.v.lerp=function(t,i,e){return S(j(t,1-e),j(i,e))},F=t.v.normalize=function(t){return j(t,1/m(t))},N=t.v.normalize_safe=function(t){return 0===t.x&&0===t.y?_:F(t)},E=t.v.clamp=function(t,i){return x(t,t)>i*i?j(F(t),i):t},Q=(t.v.lerpconst=function(t,i,e){return S(t,E(A(i,t),e))},t.v.dist=function(t,i){return m(A(t,i))}),H=t.v.distsq=function(t,i){return T(A(t,i))},O=(t.v.near=function(t,i,e){return H(t,i)=0){var p=(-a-Math.sqrt(c))/(2*o);if(0<=p&&p<=1)return new X(t,p,F(R(s,n,p)))}};K.prototype.segmentQuery=function(t,i){return Z(this,this.tc,this.r,t,i)};var $=t.SegmentShape=function(t,i,e,s){this.a=i,this.b=e,this.n=M(F(A(e,i))),this.ta=this.tb=this.tn=null,this.r=s,this.a_tangent=_,this.b_tangent=_,this.type="segment",U.call(this,t)};$.prototype=Object.create(U.prototype),$.prototype.cacheData=function(t,i){this.ta=S(t,I(this.a,i)),this.tb=S(t,I(this.b,i)),this.tn=I(this.n,i);var e,s,n,r;this.ta.x0?B(e):e,o=A(j(r,n),t),a=S(this.ta,o),h=S(this.tb,o),c=A(i,t);if(C(c,a)*C(c,h)<=0){var p=s+(s>0?-n:n),l=-p,u=x(c,e)-p;if(l*u<0)return new X(this,l/(l-u),r)}else if(0!==n){var y=Z(this,this.ta,this.r,t,i),b=Z(this,this.tb,this.r,t,i);return y?b&&b.t0)return!1}return!0},it=t.PolyShape=function(t,i,e){this.setVerts(i,e),this.type="poly",U.call(this,t)};it.prototype=Object.create(U.prototype);var et=function(t,i){this.n=t,this.d=i};et.prototype.compare=function(t){return x(this.n,t)-this.d},it.prototype.setVerts=function(t,i){s(t.length>=4,"Polygons require some verts"),s("number"==typeof t[0],"Polygon verticies should be specified in a flattened list (eg [x1,y1,x2,y2,x3,y3,...])"),s(tt(t),"Polygon is concave or has a reversed winding. Consider using cpConvexHull()");var e=t.length,n=e>>1;this.verts=new Array(e),this.tVerts=new Array(e),this.planes=new Array(n),this.tPlanes=new Array(n);for(var r=0;r>1]=new et(p,g(p.x,p.y,o,a)),this.tPlanes[r>>1]=new et(new f(0,0),0)}};var st=(t.BoxShape=function(t,i,e){var s=i/2,n=e/2;return st(t,new W((-s),(-n),s,n))},t.BoxShape2=function(t,i){var e=[i.l,i.b,i.l,i.t,i.r,i.t,i.r,i.b];return new it(t,e,_)});it.prototype.transformVerts=function(t,s){for(var n=this.verts,r=this.tVerts,o=1/0,a=-(1/0),h=1/0,c=-(1/0),p=0;p0&&(a=!0);var c=e[2*h],l=e[2*h+1],u=p(t.x,t.y,s,n,c,l),y=Q(t,u);yh)){var c=x(i,a),p=(e[o].d-h)/(c-h);if(!(p<0||10)return!1}return!0},it.prototype.containsVertPartial=function(t,i,e){for(var s=this.tPlanes,n=0;n0)return!1}}return!0},it.prototype.getNumVerts=function(){return this.verts.length/2},it.prototype.getVert=function(t){return new f(this.verts[2*t],this.verts[2*t+1])};var nt=t.Body=function(t,i){this.p=new f(0,0),this.vx=this.vy=0,this.f=new f(0,0),this.w=0,this.t=0,this.v_limit=1/0,this.w_limit=1/0,this.v_biasx=this.v_biasy=0,this.w_bias=0,this.space=null,this.shapeList=[],this.arbiterList=null,this.constraintList=null,this.nodeRoot=null,this.nodeNext=null,this.nodeIdleTime=0,this.setMass(t),this.setMoment(i),this.rot=new f(0,0),this.setAngle(0)};if("undefined"!=typeof DEBUG&&DEBUG){var rt=function(t,i){s(t.x==t.x&&t.y==t.y,i)},ot=function(t,i){s(Math.abs(t.x)!==1/0&&Math.abs(t.y)!==1/0,i)},at=function(t,i){rt(t,i),ot(t,i)};nt.prototype.sanityCheck=function(){s(this.m===this.m&&this.m_inv===this.m_inv,"Body's mass is invalid."),s(this.i===this.i&&this.i_inv===this.i_inv,"Body's moment is invalid."),at(this.p,"Body's position is invalid."),at(this.f,"Body's force is invalid."),s(this.vx===this.vx&&Math.abs(this.vx)!==1/0,"Body's velocity is invalid."),s(this.vy===this.vy&&Math.abs(this.vy)!==1/0,"Body's velocity is invalid."),s(this.a===this.a&&Math.abs(this.a)!==1/0,"Body's angle is invalid."),s(this.w===this.w&&Math.abs(this.w)!==1/0,"Body's angular velocity is invalid."),s(this.t===this.t&&Math.abs(this.t)!==1/0,"Body's torque is invalid."),at(this.rot,"Body's rotation vector is invalid."),s(this.v_limit===this.v_limit,"Body's velocity limit is invalid."),s(this.w_limit===this.w_limit,"Body's angular velocity limit is invalid.")}}else nt.prototype.sanityCheck=function(){};nt.prototype.getPos=function(){return this.p},nt.prototype.getVel=function(){return new f(this.vx,this.vy)},nt.prototype.getAngVel=function(){return this.w},nt.prototype.isSleeping=function(){return null!==this.nodeRoot},nt.prototype.isStatic=function(){return this.nodeIdleTime===1/0},nt.prototype.isRogue=function(){return null===this.space},nt.prototype.setMass=function(t){s(t>0,"Mass must be positive and non-zero."),this.activate(),this.m=t,this.m_inv=1/t},nt.prototype.setMoment=function(t){s(t>0,"Moment of Inertia must be positive and non-zero."),this.activate(),this.i=t,this.i_inv=1/t},nt.prototype.addShape=function(t){this.shapeList.push(t)},nt.prototype.removeShape=function(t){h(this.shapeList,t)};var ht=function(t,i,e){return t===e?t.next(i):(t.a===i?t.next_a=ht(t.next_a,i,e):t.next_b=ht(t.next_b,i,e),t)};nt.prototype.removeConstraint=function(t){this.constraintList=ht(this.constraintList,this,t)},nt.prototype.setPos=function(i){this.activate(),this.sanityCheck(),i===_&&(i=t.v(0,0)),this.p=i},nt.prototype.setVel=function(t){this.activate(),this.vx=t.x,this.vy=t.y},nt.prototype.setAngVel=function(t){this.activate(),this.w=t},nt.prototype.setAngleInternal=function(t){s(!isNaN(t),"Internal Error: Attempting to set body's angle to NaN"),this.a=t,this.rot.x=Math.cos(t),this.rot.y=Math.sin(t)},nt.prototype.setAngle=function(t){this.activate(),this.sanityCheck(),this.setAngleInternal(t)},nt.prototype.velocity_func=function(t,i,e){var s=this.vx*i+(t.x+this.f.x*this.m_inv)*e,n=this.vy*i+(t.y+this.f.y*this.m_inv)*e,r=this.v_limit,o=s*s+n*n,a=o>r*r?r/Math.sqrt(o):1;this.vx=s*a,this.vy=n*a;var h=this.w_limit;this.w=d(this.w*i+this.t*this.i_inv*e,-h,h),this.sanityCheck()},nt.prototype.position_func=function(t){this.p.x+=(this.vx+this.v_biasx)*t,this.p.y+=(this.vy+this.v_biasy)*t,this.setAngleInternal(this.a+(this.w+this.w_bias)*t),this.v_biasx=this.v_biasy=0,this.w_bias=0,this.sanityCheck()},nt.prototype.resetForces=function(){this.activate(),this.f=new f(0,0),this.t=0},nt.prototype.applyForce=function(t,i){this.activate(),this.f=S(this.f,t),this.t+=C(i,t)},nt.prototype.applyImpulse=function(t,i){this.activate(),pi(this,t.x,t.y,i)},nt.prototype.getVelAtPoint=function(t){return S(new f(this.vx,this.vy),j(M(t),this.w))},nt.prototype.getVelAtWorldPoint=function(t){return this.getVelAtPoint(A(t,this.p))},nt.prototype.getVelAtLocalPoint=function(t){return this.getVelAtPoint(I(t,this.rot))},nt.prototype.eachShape=function(t){for(var i=0,e=this.shapeList.length;i0){var e=t.query;this.each(function(t){e(t,new W(t.bb_l,t.bb_b,t.bb_r,t.bb_t),i)})}};var pt=t.BBTree=function(t){ct.call(this,t),this.velocityFunc=null,this.leaves={},this.count=0,this.root=null,this.pooledNodes=null,this.pooledPairs=null,this.stamp=0};pt.prototype=Object.create(ct.prototype);var lt=0,ut=function(t,s,n){this.obj=null,this.bb_l=i(s.bb_l,n.bb_l),this.bb_b=i(s.bb_b,n.bb_b),this.bb_r=e(s.bb_r,n.bb_r),this.bb_t=e(s.bb_t,n.bb_t),this.parent=null,this.setA(s),this.setB(n)};pt.prototype.makeNode=function(t,i){var e=this.pooledNodes;return e?(this.pooledNodes=e.parent,e.constructor(this,t,i),e):(lt++,new ut(this,t,i))};var yt=0,bt=function(t,i){this.obj=i,t.getBB(i,this),this.parent=null,this.stamp=1,this.pairs=null,yt++};pt.prototype.getBB=function(t,s){var n=this.velocityFunc;if(n){var r=.1,o=(t.bb_r-t.bb_l)*r,a=(t.bb_t-t.bb_b)*r,h=j(n(t),.1);s.bb_l=t.bb_l+i(-o,h.x),s.bb_b=t.bb_b+i(-a,h.y),s.bb_r=t.bb_r+e(o,h.x),s.bb_t=t.bb_t+e(a,h.y)}else s.bb_l=t.bb_l,s.bb_b=t.bb_b,s.bb_r=t.bb_r,s.bb_t=t.bb_t},pt.prototype.getStamp=function(){var t=this.dynamicIndex;return t&&t.stamp?t.stamp:this.stamp},pt.prototype.incrementStamp=function(){this.dynamicIndex&&this.dynamicIndex.stamp?this.dynamicIndex.stamp++:this.stamp++};var dt=0,vt=function(t,i,e,s){this.prevA=null,this.leafA=t,this.nextA=i,this.prevB=null,this.leafB=e,this.nextB=s};pt.prototype.makePair=function(t,i,e,s){var n=this.pooledPairs;return n?(this.pooledPairs=n.prevA,n.prevA=null,n.leafA=t,n.nextA=i,n.prevB=null,n.leafB=e,n.nextB=s,n):(dt++,new vt(t,i,e,s))},vt.prototype.recycle=function(t){this.prevA=t.pooledPairs,t.pooledPairs=this};var ft=function(t,i,e){e&&(e.leafA===i?e.prevA=t:e.prevB=t),t?t.leafA===i?t.nextA=e:t.nextB=e:i.pairs=e};bt.prototype.clearPairs=function(t){var i,e=this.pairs;for(this.pairs=null;e;)e.leafA===this?(i=e.nextA,ft(e.prevB,e.leafB,e.nextB)):(i=e.nextB,ft(e.prevA,e.leafA,e.nextA)),e.recycle(t),e=i};var _t=function(t,i,e){var s=t.pairs,n=i.pairs,r=e.makePair(t,s,i,n);t.pairs=i.pairs=r,s&&(s.leafA===t?s.prevA=r:s.prevB=r),n&&(n.leafA===i?n.prevA=r:n.prevB=r)};ut.prototype.recycle=function(t){this.parent=t.pooledNodes,t.pooledNodes=this},bt.prototype.recycle=function(t){},ut.prototype.setA=function(t){this.A=t,t.parent=this},ut.prototype.setB=function(t){this.B=t,t.parent=this},bt.prototype.isLeaf=!0,ut.prototype.isLeaf=!1,ut.prototype.otherChild=function(t){return this.A==t?this.B:this.A},ut.prototype.replaceChild=function(t,s,r){n(t==this.A||t==this.B,"Node is not a child of parent."),this.A==t?(this.A.recycle(r),this.setA(s)):(this.B.recycle(r),this.setB(s));for(var o=this;o;o=o.parent){var a=o.A,h=o.B;o.bb_l=i(a.bb_l,h.bb_l),o.bb_b=i(a.bb_b,h.bb_b),o.bb_r=e(a.bb_r,h.bb_r),o.bb_t=e(a.bb_t,h.bb_t)}},ut.prototype.bbArea=bt.prototype.bbArea=function(){return(this.bb_r-this.bb_l)*(this.bb_t-this.bb_b)};var xt=function(t,s){return(e(t.bb_r,s.bb_r)-i(t.bb_l,s.bb_l))*(e(t.bb_t,s.bb_t)-i(t.bb_b,s.bb_b))},gt=function(t,i){return Math.abs(t.bb_l+t.bb_r-i.bb_l-i.bb_r)+Math.abs(t.bb_b+t.bb_t-i.bb_b-i.bb_t)},mt=function(t,s,n){if(null==t)return s;if(t.isLeaf)return n.makeNode(s,t);var r=t.B.bbArea()+xt(t.A,s),o=t.A.bbArea()+xt(t.B,s);return r===o&&(r=gt(t.A,s),o=gt(t.B,s)),o=t.bb_r&&this.bb_b<=t.bb_b&&this.bb_t>=t.bb_t},bt.prototype.update=function(t){var i=t.root,e=this.obj;return!this.containsObj(e)&&(t.getBB(this.obj,this),i=Bt(i,this,t),t.root=mt(i,this,t),this.clearPairs(t),this.stamp=t.getStamp(),!0)},bt.prototype.addPairs=function(t){var i=t.dynamicIndex;if(i){var e=i.root;e&&e.markLeafQuery(this,!0,i,null)}else{var s=t.staticIndex.root;this.markSubtree(t,s,null)}},pt.prototype.insert=function(t,i){var e=new bt(this,t);this.leaves[i]=e,this.root=mt(this.root,e,this),this.count++,e.stamp=this.getStamp(),e.addPairs(this),this.incrementStamp()},pt.prototype.remove=function(t,i){var e=this.leaves[i];delete this.leaves[i],this.root=Bt(this.root,e,this),this.count--,e.clearPairs(this),e.recycle(this)},pt.prototype.contains=function(t,i){return null!=this.leaves[i]};var Ct=function(t,i){};pt.prototype.reindexQuery=function(t){if(this.root){var i,e=this.leaves;for(i in e)e[i].update(this);var s=this.staticIndex,n=s&&s.root;this.root.markSubtree(this,n,t),s&&!n&&this.collideStatic(this,s,t),this.incrementStamp()}},pt.prototype.reindex=function(){this.reindexQuery(Ct)},pt.prototype.reindexObject=function(t,i){var e=this.leaves[i];e&&(e.update(this)&&e.addPairs(this),this.incrementStamp())},pt.prototype.pointQuery=function(t,i){this.query(new W(t.x,t.y,t.x,t.y),i)},pt.prototype.segmentQuery=function(t,i,e,s){this.root&&At(this.root,t,i,e,s)},pt.prototype.query=function(t,i){this.root&&wt(this.root,t,i)},pt.prototype.count=function(){return this.count},pt.prototype.each=function(t){var i;for(i in this.leaves)t(this.leaves[i].obj)};var kt=function(t,s,n,r,o){return(e(t.bb_r,r)-i(t.bb_l,s))*(e(t.bb_t,o)-i(t.bb_b,n))},Mt=function(t,s,n,r){if(1==r)return s[n];if(2==r)return t.makeNode(s[n],s[n+1]);for(var o=s[n],a=o.bb_l,h=o.bb_b,c=o.bb_r,p=o.bb_t,l=n+r,u=n+1;up-h,b=new Array(2*r);if(y)for(var u=n;u=n*n)){var a=Math.sqrt(o);return new Et(S(t,j(r,.5+(e-.5*n)/(a?a:1/0))),a?j(r,1/a):new f(1,0),a-n,0)}},Ot=function(t,i){var e=Ht(t.tc,i.tc,t.r,i.r);return e?[e]:Qt},qt=function(t,i){var e=i.ta,s=i.tb,n=t.tc,r=A(s,e),o=v(x(r,A(n,e))/T(r)),a=S(e,j(r,o)),h=Ht(n,a,t.r,i.r);if(h){var c=h.n;return 0===o&&x(c,i.a_tangent)<0||1===o&&x(c,i.b_tangent)<0?Qt:[h]}return Qt},Wt=0,Dt=function(t,i){var e=0,s=t.valueOnAxis(i[0].n,i[0].d);if(s>0)return-1;for(var n=1;n0)return-1;r>s&&(s=r,e=n)}return Wt=s,e},Gt=function(t,i,e,s){for(var n=[],r=t.tVerts,o=0;o>1)))}for(var p=i.tVerts,o=0;o>1)))}return n.length?n:Gt(t,i,e,s)},Yt=function(t,i){var e=Dt(i,t.tPlanes);if(e==-1)return Qt;var s=Wt,n=Dt(t,i.tPlanes);if(n==-1)return Qt;var r=Wt;return s>r?Jt(t,i,t.tPlanes[e].n,s):Jt(t,i,B(i.tPlanes[n].n),r)},Ut=function(t,e,s){var n=x(e,t.ta)-t.r,r=x(e,t.tb)-t.r;return i(n,r)-s},zt=function(t,i,e,s,n){for(var r=C(i.tn,i.ta),o=C(i.tn,i.tb),h=j(i.tn,n),c=e.tVerts,p=0;p=y&&y>=o&&t.push(new Et(new f(l,u),h,s,a(e.hashid,p)))}}},Xt=function(t,i){var e=[],s=i.tPlanes,n=s.length,r=x(t.tn,t.ta),o=i.valueOnAxis(t.tn,r)-t.r,h=i.valueOnAxis(B(t.tn),-r)-t.r;if(h>0||o>0)return Qt;var c=0,p=Ut(t,s[0].n,s[0].d);if(p>0)return Qt;for(var l=0;l0)return Qt;u>p&&(p=u,c=l)}var y=B(s[c].n),b=S(t.ta,j(y,t.r)),d=S(t.tb,j(y,t.r));if(i.containsVert(b.x,b.y)&&e.push(new Et(b,y,p,a(t.hashid,0))),i.containsVert(d.x,d.y)&&e.push(new Et(d,y,p,a(t.hashid,1))),(o>=p||h>=p)&&(o>h?zt(e,t,i,o,1):zt(e,t,i,h,-1)),0===e.length){var v,_=2*c,g=i.tVerts,m=new f(g[_],g[_+1]);if(v=Ht(t.ta,m,t.r,0,e))return[v];if(v=Ht(t.tb,m,t.r,0,e))return[v];var w=2*n,A=new f(g[(_+2)%w],g[(_+3)%w]);if(v=Ht(t.ta,A,t.r,0,e))return[v];if(v=Ht(t.tb,A,t.r,0,e))return[v]}return e},Kt=function(t,i){for(var e=i.tPlanes,s=0,n=x(e[0].n,t.tc)-e[0].d-t.r,r=0;r0)return Qt;o>n&&(n=o,s=r)}var a=e[s].n,h=i.tVerts,c=h.length,p=s<<1,l=h[p],u=h[p+1],y=h[(p+2)%c],b=h[(p+3)%c],d=k(a.x,a.y,l,u),v=k(a.x,a.y,y,b),_=C(a,t.tc);if(_h?0:r.nodeIdleTime+t}for(var c=this.arbiters,s=0,p=c.length;s=0,"Internal Error: Space lock underflow."),0===this.locked&&t){for(var i=this.rousedBodies,e=0;ee.collisionCode){var o=i;i=e,e=o}var h=Zt(i,e);if(0!==h.length){var c=a(i.hashid,e.hashid),p=s.cachedArbiters[c];p||(p=s.cachedArbiters[c]=new Lt(i,e)),p.update(h,n,i,e),"first coll"!=p.state||n.begin(p,s)||p.ignore(),"ignore"!==p.state&&n.preSolve(p,s)&&!r?s.arbiters.push(p):(p.contacts=null,"ignore"!==p.state&&(p.state="normal")),p.stamp=s.stamp}}}}},ti.prototype.arbiterSetFilter=function(t){var i=this.stamp-t.stamp,e=t.body_a,s=t.body_b;return!(!e.isStatic()&&!e.isSleeping()||!s.isStatic()&&!s.isSleeping())||(i>=1&&"cached"!=t.state&&(t.callSeparate(this),t.state="cached"),!(i>=this.collisionPersistence)||(t.contacts=null,!1))};var ai=function(t){var i=t.body;t.update(i.p,i.rot)};ti.prototype.step=function(t){if(0!==t){s(0===_.x&&0===_.y,"vzero is invalid"),this.stamp++;var i=this.curr_dt;this.curr_dt=t;var e,n,r,o=this.bodies,a=this.constraints,h=this.arbiters;for(e=0;e0,"You created a 0 length pin joint. A pivot joint will be much more stable."),this.r1=this.r2=null,this.n=null,this.nMass=0,this.jnAcc=this.jnMax=0,this.bias=0};xi.prototype=Object.create(_i.prototype),xi.prototype.preStep=function(t){var i=this.a,e=this.b;this.r1=I(this.anchr1,i.rot),this.r2=I(this.anchr2,e.rot);var s=A(S(e.p,this.r2),S(i.p,this.r1)),n=m(s);this.n=j(s,1/(n?n:1/0)),this.nMass=1/bi(i,e,this.r1,this.r2,this.n);var r=this.maxBias;this.bias=d(-fi(this.errorBias,t)*(n-this.dist)/t,-r,r),this.jnMax=this.maxForce*t},xi.prototype.applyCachedImpulse=function(t){var i=j(this.n,this.jnAcc*t);li(this.a,this.b,this.r1,this.r2,i.x,i.y)},xi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=this.n,s=ci(t,i,this.r1,this.r2,e),n=(this.bias-s)*this.nMass,r=this.jnAcc;this.jnAcc=d(r+n,-this.jnMax,this.jnMax),n=this.jnAcc-r,li(t,i,this.r1,this.r2,e.x*n,e.y*n)},xi.prototype.getImpulse=function(){return Math.abs(this.jnAcc)};var gi=t.SlideJoint=function(t,i,e,s,n,r){_i.call(this,t,i),this.anchr1=e,this.anchr2=s,this.min=n,this.max=r,this.r1=this.r2=this.n=null,this.nMass=0,this.jnAcc=this.jnMax=0,this.bias=0};gi.prototype=Object.create(_i.prototype),gi.prototype.preStep=function(t){var i=this.a,e=this.b;this.r1=I(this.anchr1,i.rot),this.r2=I(this.anchr2,e.rot);var s=A(S(e.p,this.r2),S(i.p,this.r1)),n=m(s),r=0;n>this.max?(r=n-this.max,this.n=N(s)):n=C(n,r)?(this.clamp=-1,this.r1=A(n,i.p)):(this.clamp=0,this.r1=A(S(j(M(r),-a),j(r,o)),i.p)),di(i,e,this.r1,this.r2,this.k1,this.k2),this.jMaxLen=this.maxForce*t;var h=A(S(e.p,this.r2),S(i.p,this.r1));this.bias=E(j(h,-fi(this.errorBias,t)/t),this.maxBias)},wi.prototype.applyCachedImpulse=function(t){li(this.a,this.b,this.r1,this.r2,this.jAcc.x*t,this.jAcc.y*t)},wi.prototype.grooveConstrain=function(t){var i=this.grv_tn,e=this.clamp*C(t,i)>0?t:P(t,i);return E(e,this.jMaxLen)},wi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=this.r1,s=this.r2,n=hi(t,i,e,s),r=vi(A(this.bias,n),this.k1,this.k2),o=this.jAcc;this.jAcc=this.grooveConstrain(S(o,r)),li(t,i,this.r1,this.r2,this.jAcc.x-o.x,this.jAcc.y-o.y)},wi.prototype.getImpulse=function(){return m(this.jAcc)},wi.prototype.setGrooveA=function(t){this.grv_a=t,this.grv_n=M(F(A(this.grv_b,t))),this.activateBodies()},wi.prototype.setGrooveB=function(t){this.grv_b=t,this.grv_n=M(F(A(t,this.grv_a))),this.activateBodies()};var Si=function(t,i){return(t.restLength-i)*t.stiffness},Ai=t.DampedSpring=function(t,i,e,s,n,r,o){_i.call(this,t,i),this.anchr1=e,this.anchr2=s,this.restLength=n,this.stiffness=r,this.damping=o,this.springForceFunc=Si,this.target_vrn=this.v_coef=0,this.r1=this.r2=null,this.nMass=0,this.n=null};Ai.prototype=Object.create(_i.prototype),Ai.prototype.preStep=function(t){var i=this.a,e=this.b;this.r1=I(this.anchr1,i.rot),this.r2=I(this.anchr2,e.rot);var s=A(S(e.p,this.r2),S(i.p,this.r1)),r=m(s);this.n=j(s,1/(r?r:1/0));var o=bi(i,e,this.r1,this.r2,this.n);n(0!==o,"Unsolvable this."),this.nMass=1/o,this.target_vrn=0,this.v_coef=1-Math.exp(-this.damping*t*o);var a=this.springForceFunc(this,r);li(i,e,this.r1,this.r2,this.n.x*a*t,this.n.y*a*t)},Ai.prototype.applyCachedImpulse=function(t){},Ai.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=this.n,s=this.r1,n=this.r2,r=ci(t,i,s,n,e),o=(this.target_vrn-r)*this.v_coef;this.target_vrn=r+o,o*=this.nMass,li(t,i,this.r1,this.r2,this.n.x*o,this.n.y*o)},Ai.prototype.getImpulse=function(){return 0};var Bi=function(t,i){return(i-t.restAngle)*t.stiffness},ji=t.DampedRotarySpring=function(t,i,e,s,n){_i.call(this,t,i),this.restAngle=e,this.stiffness=s,this.damping=n,this.springTorqueFunc=Bi,this.target_wrn=0,this.w_coef=0,this.iSum=0};ji.prototype=Object.create(_i.prototype),ji.prototype.preStep=function(t){var i=this.a,e=this.b,s=i.i_inv+e.i_inv;n(0!==s,"Unsolvable spring."),this.iSum=1/s,this.w_coef=1-Math.exp(-this.damping*t*s),this.target_wrn=0;var r=this.springTorqueFunc(this,i.a-e.a)*t;i.w-=r*i.i_inv,e.w+=r*e.i_inv},ji.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=t.w-i.w,s=(this.target_wrn-e)*this.w_coef;this.target_wrn=e+s;var n=s*this.iSum;t.w+=n*t.i_inv,i.w-=n*i.i_inv};var Ci=t.RotaryLimitJoint=function(t,i,e,s){_i.call(this,t,i),this.min=e,this.max=s,this.jAcc=0,this.iSum=this.bias=this.jMax=0};Ci.prototype=Object.create(_i.prototype),Ci.prototype.preStep=function(t){var i=this.a,e=this.b,s=e.a-i.a,n=0;s>this.max?n=this.max-s:s0?h=a:this.angle=Math.floor((o-n)/r)*r+n,this.iSum=1/(i.i_inv+e.i_inv);var c=this.maxBias;this.bias=d(-fi(this.errorBias,t)*h/t,-c,c),this.jMax=this.maxForce*t,this.bias||(this.jAcc=0)},ki.prototype.applyCachedImpulse=function(t){var i=this.a,e=this.b,s=this.jAcc*t;i.w-=s*i.i_inv,e.w+=s*e.i_inv},ki.prototype.applyImpulse=function(){if(this.bias){var t=this.a,i=this.b,e=i.w-t.w,s=this.ratchet,n=-(this.bias+e)*this.iSum,r=this.jAcc;this.jAcc=d((r+n)*s,0,this.jMax*Math.abs(s))/s,n=this.jAcc-r,t.w-=n*t.i_inv,i.w+=n*i.i_inv}},ki.prototype.getImpulse=function(t){return Math.abs(t.jAcc)};var Mi=t.GearJoint=function(t,i,e,s){_i.call(this,t,i),this.phase=e,this.ratio=s,this.ratio_inv=1/s,this.jAcc=0,this.iSum=this.bias=this.jMax=0};Mi.prototype=Object.create(_i.prototype),Mi.prototype.preStep=function(t){var i=this.a,e=this.b;this.iSum=1/(i.i_inv*this.ratio_inv+this.ratio*e.i_inv);var s=this.maxBias;this.bias=d(-fi(this.errorBias,t)*(e.a*this.ratio-i.a-this.phase)/t,-s,s),this.jMax=this.maxForce*t},Mi.prototype.applyCachedImpulse=function(t){var i=this.a,e=this.b,s=this.jAcc*t;i.w-=s*i.i_inv*this.ratio_inv,e.w+=s*e.i_inv},Mi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=i.w*this.ratio-t.w,s=(this.bias-e)*this.iSum,n=this.jAcc;this.jAcc=d(n+s,-this.jMax,this.jMax),s=this.jAcc-n,t.w-=s*t.i_inv*this.ratio_inv,i.w+=s*i.i_inv},Mi.prototype.getImpulse=function(){return Math.abs(this.jAcc)},Mi.prototype.setRatio=function(t){this.ratio=t,this.ratio_inv=1/t,this.activateBodies()};var Pi=t.SimpleMotor=function(t,i,e){_i.call(this,t,i),this.rate=e,this.jAcc=0,this.iSum=this.jMax=0};Pi.prototype=Object.create(_i.prototype),Pi.prototype.preStep=function(t){this.iSum=1/(this.a.i_inv+this.b.i_inv),this.jMax=this.maxForce*t},Pi.prototype.applyCachedImpulse=function(t){var i=this.a,e=this.b,s=this.jAcc*t;i.w-=s*i.i_inv,e.w+=s*e.i_inv},Pi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=i.w-t.w+this.rate,s=-e*this.iSum,n=this.jAcc;this.jAcc=d(n+s,-this.jMax,this.jMax),s=this.jAcc-n,t.w-=s*t.i_inv,i.w+=s*i.i_inv},Pi.prototype.getImpulse=function(){return Math.abs(this.jAcc)}}(),function(){var t=Hilo.Class,i=Hilo.EventMixin,e=Hilo.View,s=Math.PI/180,n=1/s,r={space:null,body:null,shape:null,applyImpulse:function(t,i){i=i||{x:0,y:0},this.body.applyImpulse(cp.v(t.x,t.y),cp.v(i.x,i.y))},applyForce:function(t,i){i=i||{x:0,y:0},this.body.applyForce(cp.v(t.x,t.y),cp.v(i.x,i.y))},setPosition:function(t,i){this.body.setPos(new cp.Vect(t,i)),this.body.isStaticBody&&(this.space.needReindexStatic=!0)},setRotation:function(t){this.body.setAngle(t*s),this.body.isStaticBody&&(this.space.needReindexStatic=!0)},render:function(t,i){this._physicsRender(),this._viewRender.call(this,t,i)},_physicsRender:function(){this.x=this.body.p.x,this.y=this.body.p.y,this.rotation=this.body.a*n}},o=t.create({Mixes:i,Statics:{SHAPE_RECT:"rect",SHAPE_CIRCLE:"circle",SHAPE_POLYGEN:"polygen"},constructor:function(t,i){this._init(t,i)},_init:function(t,i){var e=new cp.Space;if(e.iterations=20,e.gravity=new cp.Vect(t.x,t.y),e.collisionSlop=.5,e.sleepTimeThreshold=.5,i)for(var s in i)e[s]=i[s];this.space=e,this.staticBody=e.staticBody,this._deleteBodies=[]},tick:function(t){var i=this.space;t=t>32?16:t,i.needReindexStatic&&(i.reindexStatic(),i.needReindexStatic=!1),i.step(.001*t);for(var e=this._deleteBodies.length-1;e>=0;e--){for(var s=this._deleteBodies[e],n=s.shapeList,r=n.length-1;r>=0;r--)i.removeShape(n[r]);i.removeBody(s)}},bindView:function(i,e){i.body&&this.unbindView(i);var n,a,e=e||{},h=e.mass||1,c=e.type||o.SHAPE_RECT,p=void 0===e.group?0:e.group,l=void 0===e.layers?-1:e.layers,u=i.width*i.scaleX,y=i.height*i.scaleY;switch(c!==o.SHAPE_POLYGEN||i.boundsArea||e.boundsArea||(c=o.SHAPE_RECT),c){case o.SHAPE_RECT:u=e.width||u,y=e.height||y,n=e.isStatic?this._createStaticBody():new cp.Body(h,cp.momentForBox(h,u,y)),a=new cp.BoxShape(n,u,y);break;case o.SHAPE_CIRCLE:radius=e.radius||.5*u,n=e.isStatic?this._createStaticBody():new cp.Body(h,cp.momentForCircle(h,0,radius,new cp.Vect(0,0))),a=new cp.CircleShape(n,radius,new cp.Vect(0,0));break;case o.SHAPE_POLYGEN:var b=e.boundsArea||i.boundsArea;verts=[],b.forEach(function(t){verts.push(t.x),verts.push(t.y)}),i.boundsArea=b,n=e.isStatic?this._createStaticBody():new cp.Body(h,cp.momentForPoly(h,verts,new cp.Vect(0,0))),a=new cp.PolyShape(n,verts,new cp.Vect(0,0))}n.setAngle(i.rotation*s),n.setPos(new cp.Vect(i.x,i.y)),a.setElasticity(e.restitution||.4),a.setFriction(e.friction||1),a.setCollisionType(e.collisionType||1),a.layers=l,a.group=p,i._viewRender=i.render,t.mix(i,r),i.body=n,i.shape=a,i.space=this.space,n.view=i,i.pivotX=.5*i.width,i.pivotY=.5*i.height,e.isStatic?this.space.addShape(a):(this.space.addBody(n),this.space.addShape(a)),i._physicsRender()},addConstraint:function(t){return this.space.addConstraint(t)},removeConstraint:function(t){return this.space.removeConstraint(t)},unbindView:function(t,i){var e=t.body;e&&(t.body=null,e.view=null,this._deleteBodies.indexOf(e)<0&&this._deleteBodies.push(e));for(var s in r)t[s]=null;t._viewRender&&(t.render=t._viewRender),i&&t.removeFromParent()},addCollisionListener:function(t,i,e){var s=e.begin||function(t){return!0},n=e.preSolve||function(t){return!0},r=e.postSolve||function(t){},o=e.separate||function(t){};this.space.addCollisionHandler(t,i,s,n,r,o)},createBounds:function(t,i){this._createBound({x:0,y:i},{x:t,y:i},1),this._createBound({x:0,y:0},{x:0,y:i},1),this._createBound({x:t,y:0},{x:t,y:i},1)},_createBound:function(t,i,e){var s=this.space.addShape(new cp.SegmentShape(this.staticBody,cp.v(t.x,t.y),cp.v(i.x,i.y),e));s.setElasticity(1),s.setFriction(1)},_createStaticBody:function(){var t=new cp.Body(1/0,1/0);return t.nodeIdleTime=1/0,t.isStaticBody=!0,t}}),a=t.create({Extends:e,constructor:function(t){t=t||{},this.id=this.id||t.id||Hilo.getUid("PhysicsDebugView"),this.showShapes=!0,this.showConstraints=!0,a.superclass.constructor.call(this,t),this.space=t.world.space,this.pointerEnabled=!1,this.pointerChildren=!1,this.initDebugDraw()},render:function(t,i){var e=t.canvas,s=t.context;e.getContext&&s&&(this.showShapes&&this.space.eachShape(function(t){t.hideDebugView||(s.fillStyle=t.style(),t.draw(s))}),this.showConstraints&&this.space.eachConstraint(function(t){!t.hideDebugView&&t.draw&&t.draw(s)}))},initDebugDraw:function(){if(!this._isInit){this._isInit=!0;var t=cp.v,i=function(t,i,e,s){t.beginPath(),t.arc(i.x,i.y,e,0,2*Math.PI,!1),void 0===s&&(s=!0),s&&t.fill(),t.stroke()},e=function(t,i,e){t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(e.x,e.y),t.stroke()},s=[t(0,0),t(.2,0),t(.25,.5),t(.3,-1),t(.35,1),t(.4,-1),t(.45,1),t(.5,-1),t(.55,1),t(.6,-1),t(.65,1),t(.7,-1),t(.75,.5),t(.8,0),t(1,0)],n=function(i,e,n,r){null==r&&(r=6),i.beginPath(),i.moveTo(e.x,e.y);for(var o=t.sub(n,e),a=t.len(o),h=t.mult(o,1/a),c=1;cthis.space.sleepTimeThreshold?"rgb(170,170,170)":o[this.hashid%o.length])}}}});Hilo.Physics=o,Hilo.PhysicsDebugView=a}(); \ No newline at end of file +!function(){Object.create=Object.create||function(t){function i(){}return i.prototype=t,new i};var t;"undefined"==typeof exports?(t={},"object"==typeof window&&(window.cp=t)):t=exports;var i,e,s=function(t,i){if(!t)throw new Error("Assertion failed: "+i)},n=function(t,i){!t&&console&&console.warn&&(console.warn("ASSERTION FAILED: "+i),console.trace&&console.trace())},r=function(t,i){return ti?t:i};"object"==typeof window&&window.navigator.userAgent.indexOf("Firefox")>-1?(i=Math.min,e=Math.max):(i=r,e=o);var a=function(t,i){return t>1,h=1;hs||c==s&&p>n)&&(s=c,n=p,o=h)}return[r,o]},u=function(t,i,e){var s=t[2*i];t[2*i]=t[2*e],t[2*e]=s,s=t[2*i+1],t[2*i+1]=t[2*e+1],t[2*e+1]=s},y=function(t,i,e,s,n,r){if(0===e)return 0;for(var o=0,a=i,h=A(n,s),c=r*m(h),p=i,l=i+e-1;p<=l;){var y=new f(t[2*p],t[2*p+1]),b=C(h,A(y,s));b>c?(b>o&&(o=b,a=p),p++):(u(t,p,l),l--)}return a!=i&&u(t,i,a),p-i},b=function(t,i,e,s,n,r,o,a){if(s<0)return 0;if(0==s)return i[2*a]=r.x,i[2*a+1]=r.y,1;var h=y(i,e,s,n,r,t),c=new f(i[2*e],i[2*e+1]),p=b(t,i,e+1,h-1,n,c,r,a),l=a+p++;i[2*l]=r.x,i[2*l+1]=r.y;var u=y(i,e+h,s-h,r,o,t),d=new f(i[2*(e+h)],i[2*(e+h)+1]);return p+b(t,i,e+h+1,u-1,r,d,o,a+p)};t.convexHull=function(t,i,e){if(i)for(var s=0;s>1,y=b(e,i,2,p-2,h,c,h,1)+1;return i.length=2*y,n(tt(i),"Internal error: cpConvexHull() and cpPolyValidate() did not agree.Please report this error with as much info as you can."),i};var d=function(t,s,n){return i(e(t,s),n)},v=function(t){return e(0,i(t,1))},f=t.Vect=function(t,i){this.x=t,this.y=i};t.v=function(t,i){return new f(t,i)};var _=t.vzero=new f(0,0),x=t.v.dot=function(t,i){return t.x*i.x+t.y*i.y},g=function(t,i,e,s){return t*e+i*s},m=t.v.len=function(t){return Math.sqrt(x(t,t))},w=t.v.len2=function(t,i){return Math.sqrt(t*t+i*i)},S=(t.v.eql=function(t,i){return t.x===i.x&&t.y===i.y},t.v.add=function(t,i){return new f(t.x+i.x,t.y+i.y)});f.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this};var A=t.v.sub=function(t,i){return new f(t.x-i.x,t.y-i.y)};f.prototype.sub=function(t){return this.x-=t.x,this.y-=t.y,this};var B=t.v.neg=function(t){return new f((-t.x),(-t.y))};f.prototype.neg=function(){return this.x=-this.x,this.y=-this.y,this};var j=t.v.mult=function(t,i){return new f(t.x*i,t.y*i)};f.prototype.mult=function(t){return this.x*=t,this.y*=t,this};var C=t.v.cross=function(t,i){return t.x*i.y-t.y*i.x},k=function(t,i,e,s){return t*s-i*e},M=t.v.perp=function(t){return new f((-t.y),t.x)},P=(t.v.pvrperp=function(t){return new f(t.y,(-t.x))},t.v.project=function(t,i){return j(i,x(t,i)/T(i))});f.prototype.project=function(t){return this.mult(x(this,t)/T(t)),this};var I=t.v.rotate=function(t,i){return new f(t.x*i.x-t.y*i.y,t.x*i.y+t.y*i.x)};f.prototype.rotate=function(t){return this.x=this.x*t.x-this.y*t.y,this.y=this.x*t.y+this.y*t.x,this};var L=t.v.unrotate=function(t,i){return new f(t.x*i.x+t.y*i.y,t.y*i.x-t.x*i.y)},T=t.v.lengthsq=function(t){return x(t,t)},R=t.v.lengthsq2=function(t,i){return t*t+i*i},V=t.v.lerp=function(t,i,e){return S(j(t,1-e),j(i,e))},F=t.v.normalize=function(t){return j(t,1/m(t))},N=t.v.normalize_safe=function(t){return 0===t.x&&0===t.y?_:F(t)},E=t.v.clamp=function(t,i){return x(t,t)>i*i?j(F(t),i):t},Q=(t.v.lerpconst=function(t,i,e){return S(t,E(A(i,t),e))},t.v.dist=function(t,i){return m(A(t,i))}),H=t.v.distsq=function(t,i){return T(A(t,i))},O=(t.v.near=function(t,i,e){return H(t,i)=0){var p=(-a-Math.sqrt(c))/(2*o);if(0<=p&&p<=1)return new X(t,p,F(V(s,n,p)))}};K.prototype.segmentQuery=function(t,i){return Z(this,this.tc,this.r,t,i)};var $=t.SegmentShape=function(t,i,e,s){this.a=i,this.b=e,this.n=M(F(A(e,i))),this.ta=this.tb=this.tn=null,this.r=s,this.a_tangent=_,this.b_tangent=_,this.type="segment",U.call(this,t)};$.prototype=Object.create(U.prototype),$.prototype.cacheData=function(t,i){this.ta=S(t,I(this.a,i)),this.tb=S(t,I(this.b,i)),this.tn=I(this.n,i);var e,s,n,r;this.ta.x0?B(e):e,o=A(j(r,n),t),a=S(this.ta,o),h=S(this.tb,o),c=A(i,t);if(C(c,a)*C(c,h)<=0){var p=s+(s>0?-n:n),l=-p,u=x(c,e)-p;if(l*u<0)return new X(this,l/(l-u),r)}else if(0!==n){var y=Z(this,this.ta,this.r,t,i),b=Z(this,this.tb,this.r,t,i);return y?b&&b.t0)return!1}return!0},it=t.PolyShape=function(t,i,e){this.setVerts(i,e),this.type="poly",U.call(this,t)};it.prototype=Object.create(U.prototype);var et=function(t,i){this.n=t,this.d=i};et.prototype.compare=function(t){return x(this.n,t)-this.d},it.prototype.setVerts=function(t,i){s(t.length>=4,"Polygons require some verts"),s("number"==typeof t[0],"Polygon verticies should be specified in a flattened list (eg [x1,y1,x2,y2,x3,y3,...])"),s(tt(t),"Polygon is concave or has a reversed winding. Consider using cpConvexHull()");var e=t.length,n=e>>1;this.verts=new Array(e),this.tVerts=new Array(e),this.planes=new Array(n),this.tPlanes=new Array(n);for(var r=0;r>1]=new et(p,g(p.x,p.y,o,a)),this.tPlanes[r>>1]=new et(new f(0,0),0)}};var st=(t.BoxShape=function(t,i,e){var s=i/2,n=e/2;return st(t,new D((-s),(-n),s,n))},t.BoxShape2=function(t,i){var e=[i.l,i.b,i.l,i.t,i.r,i.t,i.r,i.b];return new it(t,e,_)});it.prototype.transformVerts=function(t,s){for(var n=this.verts,r=this.tVerts,o=1/0,a=-(1/0),h=1/0,c=-(1/0),p=0;p0&&(a=!0);var c=e[2*h],l=e[2*h+1],u=p(t.x,t.y,s,n,c,l),y=Q(t,u);yh)){var c=x(i,a),p=(e[o].d-h)/(c-h);if(!(p<0||10)return!1}return!0},it.prototype.containsVertPartial=function(t,i,e){for(var s=this.tPlanes,n=0;n0)return!1}}return!0},it.prototype.getNumVerts=function(){return this.verts.length/2},it.prototype.getVert=function(t){return new f(this.verts[2*t],this.verts[2*t+1])};var nt=t.Body=function(t,i){this.p=new f(0,0),this.vx=this.vy=0,this.f=new f(0,0),this.w=0,this.t=0,this.v_limit=1/0,this.w_limit=1/0,this.v_biasx=this.v_biasy=0,this.w_bias=0,this.space=null,this.shapeList=[],this.arbiterList=null,this.constraintList=null,this.nodeRoot=null,this.nodeNext=null,this.nodeIdleTime=0,this.setMass(t),this.setMoment(i),this.rot=new f(0,0),this.setAngle(0)};if("undefined"!=typeof DEBUG&&DEBUG){var rt=function(t,i){s(t.x==t.x&&t.y==t.y,i)},ot=function(t,i){s(Math.abs(t.x)!==1/0&&Math.abs(t.y)!==1/0,i)},at=function(t,i){rt(t,i),ot(t,i)};nt.prototype.sanityCheck=function(){s(this.m===this.m&&this.m_inv===this.m_inv,"Body's mass is invalid."),s(this.i===this.i&&this.i_inv===this.i_inv,"Body's moment is invalid."),at(this.p,"Body's position is invalid."),at(this.f,"Body's force is invalid."),s(this.vx===this.vx&&Math.abs(this.vx)!==1/0,"Body's velocity is invalid."),s(this.vy===this.vy&&Math.abs(this.vy)!==1/0,"Body's velocity is invalid."),s(this.a===this.a&&Math.abs(this.a)!==1/0,"Body's angle is invalid."),s(this.w===this.w&&Math.abs(this.w)!==1/0,"Body's angular velocity is invalid."),s(this.t===this.t&&Math.abs(this.t)!==1/0,"Body's torque is invalid."),at(this.rot,"Body's rotation vector is invalid."),s(this.v_limit===this.v_limit,"Body's velocity limit is invalid."),s(this.w_limit===this.w_limit,"Body's angular velocity limit is invalid.")}}else nt.prototype.sanityCheck=function(){};nt.prototype.getPos=function(){return this.p},nt.prototype.getVel=function(){return new f(this.vx,this.vy)},nt.prototype.getAngVel=function(){return this.w},nt.prototype.isSleeping=function(){return null!==this.nodeRoot},nt.prototype.isStatic=function(){return this.nodeIdleTime===1/0},nt.prototype.isRogue=function(){return null===this.space},nt.prototype.setMass=function(t){s(t>0,"Mass must be positive and non-zero."),this.activate(),this.m=t,this.m_inv=1/t},nt.prototype.setMoment=function(t){s(t>0,"Moment of Inertia must be positive and non-zero."),this.activate(),this.i=t,this.i_inv=1/t},nt.prototype.addShape=function(t){this.shapeList.push(t)},nt.prototype.removeShape=function(t){h(this.shapeList,t)};var ht=function(t,i,e){return t===e?t.next(i):(t.a===i?t.next_a=ht(t.next_a,i,e):t.next_b=ht(t.next_b,i,e),t)};nt.prototype.removeConstraint=function(t){this.constraintList=ht(this.constraintList,this,t)},nt.prototype.setPos=function(i){this.activate(),this.sanityCheck(),i===_&&(i=t.v(0,0)),this.p=i},nt.prototype.setVel=function(t){this.activate(),this.vx=t.x,this.vy=t.y},nt.prototype.setAngVel=function(t){this.activate(),this.w=t},nt.prototype.setAngleInternal=function(t){s(!isNaN(t),"Internal Error: Attempting to set body's angle to NaN"),this.a=t,this.rot.x=Math.cos(t),this.rot.y=Math.sin(t)},nt.prototype.setAngle=function(t){this.activate(),this.sanityCheck(),this.setAngleInternal(t)},nt.prototype.velocity_func=function(t,i,e){var s=this.vx*i+(t.x+this.f.x*this.m_inv)*e,n=this.vy*i+(t.y+this.f.y*this.m_inv)*e,r=this.v_limit,o=s*s+n*n,a=o>r*r?r/Math.sqrt(o):1;this.vx=s*a,this.vy=n*a;var h=this.w_limit;this.w=d(this.w*i+this.t*this.i_inv*e,-h,h),this.sanityCheck()},nt.prototype.position_func=function(t){this.p.x+=(this.vx+this.v_biasx)*t,this.p.y+=(this.vy+this.v_biasy)*t,this.setAngleInternal(this.a+(this.w+this.w_bias)*t),this.v_biasx=this.v_biasy=0,this.w_bias=0,this.sanityCheck()},nt.prototype.resetForces=function(){this.activate(),this.f=new f(0,0),this.t=0},nt.prototype.applyForce=function(t,i){this.activate(),this.f=S(this.f,t),this.t+=C(i,t)},nt.prototype.applyImpulse=function(t,i){this.activate(),pi(this,t.x,t.y,i)},nt.prototype.getVelAtPoint=function(t){return S(new f(this.vx,this.vy),j(M(t),this.w))},nt.prototype.getVelAtWorldPoint=function(t){return this.getVelAtPoint(A(t,this.p))},nt.prototype.getVelAtLocalPoint=function(t){return this.getVelAtPoint(I(t,this.rot))},nt.prototype.eachShape=function(t){for(var i=0,e=this.shapeList.length;i0&&this.each(function(e){t.query(new D(e.bb_l,e.bb_b,e.bb_r,e.bb_t),function(t){i(e,t)})})};var pt=t.BBTree=function(t){ct.call(this,t),this.velocityFunc=null,this.leaves={},this.count=0,this.root=null,this.pooledNodes=null,this.pooledPairs=null,this.stamp=0};pt.prototype=Object.create(ct.prototype);var lt=0,ut=function(t,s,n){this.obj=null,this.bb_l=i(s.bb_l,n.bb_l),this.bb_b=i(s.bb_b,n.bb_b),this.bb_r=e(s.bb_r,n.bb_r),this.bb_t=e(s.bb_t,n.bb_t),this.parent=null,this.setA(s),this.setB(n)};pt.prototype.makeNode=function(t,i){var e=this.pooledNodes;return e?(this.pooledNodes=e.parent,e.constructor(this,t,i),e):(lt++,new ut(this,t,i))};var yt=0,bt=function(t,i){this.obj=i,t.getBB(i,this),this.parent=null,this.stamp=1,this.pairs=null,yt++};pt.prototype.getBB=function(t,s){var n=this.velocityFunc;if(n){var r=.1,o=(t.bb_r-t.bb_l)*r,a=(t.bb_t-t.bb_b)*r,h=j(n(t),.1);s.bb_l=t.bb_l+i(-o,h.x),s.bb_b=t.bb_b+i(-a,h.y),s.bb_r=t.bb_r+e(o,h.x),s.bb_t=t.bb_t+e(a,h.y)}else s.bb_l=t.bb_l,s.bb_b=t.bb_b,s.bb_r=t.bb_r,s.bb_t=t.bb_t},pt.prototype.getStamp=function(){var t=this.dynamicIndex;return t&&t.stamp?t.stamp:this.stamp},pt.prototype.incrementStamp=function(){this.dynamicIndex&&this.dynamicIndex.stamp?this.dynamicIndex.stamp++:this.stamp++};var dt=0,vt=function(t,i,e,s){this.prevA=null,this.leafA=t,this.nextA=i,this.prevB=null,this.leafB=e,this.nextB=s};pt.prototype.makePair=function(t,i,e,s){var n=this.pooledPairs;return n?(this.pooledPairs=n.prevA,n.prevA=null,n.leafA=t,n.nextA=i,n.prevB=null,n.leafB=e,n.nextB=s,n):(dt++,new vt(t,i,e,s))},vt.prototype.recycle=function(t){this.prevA=t.pooledPairs,t.pooledPairs=this};var ft=function(t,i,e){e&&(e.leafA===i?e.prevA=t:e.prevB=t),t?t.leafA===i?t.nextA=e:t.nextB=e:i.pairs=e};bt.prototype.clearPairs=function(t){var i,e=this.pairs;for(this.pairs=null;e;)e.leafA===this?(i=e.nextA,ft(e.prevB,e.leafB,e.nextB)):(i=e.nextB,ft(e.prevA,e.leafA,e.nextA)),e.recycle(t),e=i};var _t=function(t,i,e){var s=t.pairs,n=i.pairs,r=e.makePair(t,s,i,n);t.pairs=i.pairs=r,s&&(s.leafA===t?s.prevA=r:s.prevB=r),n&&(n.leafA===i?n.prevA=r:n.prevB=r)};ut.prototype.recycle=function(t){this.parent=t.pooledNodes,t.pooledNodes=this},bt.prototype.recycle=function(t){},ut.prototype.setA=function(t){this.A=t,t.parent=this},ut.prototype.setB=function(t){this.B=t,t.parent=this},bt.prototype.isLeaf=!0,ut.prototype.isLeaf=!1,ut.prototype.otherChild=function(t){return this.A==t?this.B:this.A},ut.prototype.replaceChild=function(t,s,r){n(t==this.A||t==this.B,"Node is not a child of parent."),this.A==t?(this.A.recycle(r),this.setA(s)):(this.B.recycle(r),this.setB(s));for(var o=this;o;o=o.parent){var a=o.A,h=o.B;o.bb_l=i(a.bb_l,h.bb_l),o.bb_b=i(a.bb_b,h.bb_b),o.bb_r=e(a.bb_r,h.bb_r),o.bb_t=e(a.bb_t,h.bb_t)}},ut.prototype.bbArea=bt.prototype.bbArea=function(){return(this.bb_r-this.bb_l)*(this.bb_t-this.bb_b)};var xt=function(t,s){return(e(t.bb_r,s.bb_r)-i(t.bb_l,s.bb_l))*(e(t.bb_t,s.bb_t)-i(t.bb_b,s.bb_b))},gt=function(t,i){return Math.abs(t.bb_l+t.bb_r-i.bb_l-i.bb_r)+Math.abs(t.bb_b+t.bb_t-i.bb_b-i.bb_t)},mt=function(t,s,n){if(null==t)return s;if(t.isLeaf)return n.makeNode(s,t);var r=t.B.bbArea()+xt(t.A,s),o=t.A.bbArea()+xt(t.B,s);return r===o&&(r=gt(t.A,s),o=gt(t.B,s)),o=t.bb_r&&this.bb_b<=t.bb_b&&this.bb_t>=t.bb_t},bt.prototype.update=function(t){var i=t.root,e=this.obj;return!this.containsObj(e)&&(t.getBB(this.obj,this),i=Bt(i,this,t),t.root=mt(i,this,t),this.clearPairs(t),this.stamp=t.getStamp(),!0)},bt.prototype.addPairs=function(t){var i=t.dynamicIndex;if(i){var e=i.root;e&&e.markLeafQuery(this,!0,i,null)}else{var s=t.staticIndex.root;this.markSubtree(t,s,null)}},pt.prototype.insert=function(t,i){var e=new bt(this,t);this.leaves[i]=e,this.root=mt(this.root,e,this),this.count++,e.stamp=this.getStamp(),e.addPairs(this),this.incrementStamp()},pt.prototype.remove=function(t,i){var e=this.leaves[i];delete this.leaves[i],this.root=Bt(this.root,e,this),this.count--,e.clearPairs(this),e.recycle(this)},pt.prototype.contains=function(t,i){return null!=this.leaves[i]};var Ct=function(t,i){};pt.prototype.reindexQuery=function(t){if(this.root){var i,e=this.leaves;for(i in e)e[i].update(this);var s=this.staticIndex,n=s&&s.root;this.root.markSubtree(this,n,t),s&&!n&&this.collideStatic(this,s,t),this.incrementStamp()}},pt.prototype.reindex=function(){this.reindexQuery(Ct)},pt.prototype.reindexObject=function(t,i){var e=this.leaves[i];e&&(e.update(this)&&e.addPairs(this),this.incrementStamp())},pt.prototype.pointQuery=function(t,i){this.query(new D(t.x,t.y,t.x,t.y),i)},pt.prototype.segmentQuery=function(t,i,e,s){this.root&&At(this.root,t,i,e,s)},pt.prototype.query=function(t,i){this.root&&wt(this.root,t,i)},pt.prototype.count=function(){return this.count},pt.prototype.each=function(t){var i;for(i in this.leaves)t(this.leaves[i].obj)};var kt=function(t,s,n,r,o){return(e(t.bb_r,r)-i(t.bb_l,s))*(e(t.bb_t,o)-i(t.bb_b,n))},Mt=function(t,s,n,r){if(1==r)return s[n];if(2==r)return t.makeNode(s[n],s[n+1]);for(var o=s[n],a=o.bb_l,h=o.bb_b,c=o.bb_r,p=o.bb_t,l=n+r,u=n+1;up-h,b=new Array(2*r);if(y)for(var u=n;u=n*n)){var a=Math.sqrt(o);return new Et(S(t,j(r,.5+(e-.5*n)/(a?a:1/0))),a?j(r,1/a):new f(1,0),a-n,0)}},Ot=function(t,i){var e=Ht(t.tc,i.tc,t.r,i.r);return e?[e]:Qt},qt=function(t,i){var e=i.ta,s=i.tb,n=t.tc,r=A(s,e),o=v(x(r,A(n,e))/T(r)),a=S(e,j(r,o)),h=Ht(n,a,t.r,i.r);if(h){var c=h.n;return 0===o&&x(c,i.a_tangent)<0||1===o&&x(c,i.b_tangent)<0?Qt:[h]}return Qt},Dt=0,Wt=function(t,i){var e=0,s=t.valueOnAxis(i[0].n,i[0].d);if(s>0)return-1;for(var n=1;n0)return-1;r>s&&(s=r,e=n)}return Dt=s,e},Gt=function(t,i,e,s){for(var n=[],r=t.tVerts,o=0;o>1)))}for(var p=i.tVerts,o=0;o>1)))}return n.length?n:Gt(t,i,e,s)},Yt=function(t,i){var e=Wt(i,t.tPlanes);if(e==-1)return Qt;var s=Dt,n=Wt(t,i.tPlanes);if(n==-1)return Qt;var r=Dt;return s>r?Jt(t,i,t.tPlanes[e].n,s):Jt(t,i,B(i.tPlanes[n].n),r)},Ut=function(t,e,s){var n=x(e,t.ta)-t.r,r=x(e,t.tb)-t.r;return i(n,r)-s},zt=function(t,i,e,s,n){for(var r=C(i.tn,i.ta),o=C(i.tn,i.tb),h=j(i.tn,n),c=e.tVerts,p=0;p=y&&y>=o&&t.push(new Et(new f(l,u),h,s,a(e.hashid,p)))}}},Xt=function(t,i){var e=[],s=i.tPlanes,n=s.length,r=x(t.tn,t.ta),o=i.valueOnAxis(t.tn,r)-t.r,h=i.valueOnAxis(B(t.tn),-r)-t.r;if(h>0||o>0)return Qt;var c=0,p=Ut(t,s[0].n,s[0].d);if(p>0)return Qt;for(var l=0;l0)return Qt;u>p&&(p=u,c=l)}var y=B(s[c].n),b=S(t.ta,j(y,t.r)),d=S(t.tb,j(y,t.r));if(i.containsVert(b.x,b.y)&&e.push(new Et(b,y,p,a(t.hashid,0))),i.containsVert(d.x,d.y)&&e.push(new Et(d,y,p,a(t.hashid,1))),(o>=p||h>=p)&&(o>h?zt(e,t,i,o,1):zt(e,t,i,h,-1)),0===e.length){var v,_=2*c,g=i.tVerts,m=new f(g[_],g[_+1]);if(v=Ht(t.ta,m,t.r,0,e))return[v];if(v=Ht(t.tb,m,t.r,0,e))return[v];var w=2*n,A=new f(g[(_+2)%w],g[(_+3)%w]);if(v=Ht(t.ta,A,t.r,0,e))return[v];if(v=Ht(t.tb,A,t.r,0,e))return[v]}return e},Kt=function(t,i){for(var e=i.tPlanes,s=0,n=x(e[0].n,t.tc)-e[0].d-t.r,r=0;r0)return Qt;o>n&&(n=o,s=r)}var a=e[s].n,h=i.tVerts,c=h.length,p=s<<1,l=h[p],u=h[p+1],y=h[(p+2)%c],b=h[(p+3)%c],d=k(a.x,a.y,l,u),v=k(a.x,a.y,y,b),_=C(a,t.tc);if(_h?0:r.nodeIdleTime+t}for(var c=this.arbiters,s=0,p=c.length;s=0,"Internal Error: Space lock underflow."),0===this.locked&&t){for(var i=this.rousedBodies,e=0;ee.collisionCode){var o=i;i=e,e=o}var h=Zt(i,e);if(0!==h.length){var c=a(i.hashid,e.hashid),p=s.cachedArbiters[c];p||(p=s.cachedArbiters[c]=new Lt(i,e)),p.update(h,n,i,e),"first coll"!=p.state||n.begin(p,s)||p.ignore(),"ignore"!==p.state&&n.preSolve(p,s)&&!r?s.arbiters.push(p):(p.contacts=null,"ignore"!==p.state&&(p.state="normal")),p.stamp=s.stamp}}}}},ti.prototype.arbiterSetFilter=function(t){var i=this.stamp-t.stamp,e=t.body_a,s=t.body_b;return!(!e.isStatic()&&!e.isSleeping()||!s.isStatic()&&!s.isSleeping())||(i>=1&&"cached"!=t.state&&(t.callSeparate(this),t.state="cached"),!(i>=this.collisionPersistence)||(t.contacts=null,!1))};var ai=function(t){var i=t.body;t.update(i.p,i.rot)};ti.prototype.step=function(t){if(0!==t){s(0===_.x&&0===_.y,"vzero is invalid"),this.stamp++;var i=this.curr_dt;this.curr_dt=t;var e,n,r,o=this.bodies,a=this.constraints,h=this.arbiters;for(e=0;e0,"You created a 0 length pin joint. A pivot joint will be much more stable."),this.r1=this.r2=null,this.n=null,this.nMass=0,this.jnAcc=this.jnMax=0,this.bias=0};xi.prototype=Object.create(_i.prototype),xi.prototype.preStep=function(t){var i=this.a,e=this.b;this.r1=I(this.anchr1,i.rot),this.r2=I(this.anchr2,e.rot);var s=A(S(e.p,this.r2),S(i.p,this.r1)),n=m(s);this.n=j(s,1/(n?n:1/0)),this.nMass=1/bi(i,e,this.r1,this.r2,this.n);var r=this.maxBias;this.bias=d(-fi(this.errorBias,t)*(n-this.dist)/t,-r,r),this.jnMax=this.maxForce*t},xi.prototype.applyCachedImpulse=function(t){var i=j(this.n,this.jnAcc*t);li(this.a,this.b,this.r1,this.r2,i.x,i.y)},xi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=this.n,s=ci(t,i,this.r1,this.r2,e),n=(this.bias-s)*this.nMass,r=this.jnAcc;this.jnAcc=d(r+n,-this.jnMax,this.jnMax),n=this.jnAcc-r,li(t,i,this.r1,this.r2,e.x*n,e.y*n)},xi.prototype.getImpulse=function(){return Math.abs(this.jnAcc)};var gi=t.SlideJoint=function(t,i,e,s,n,r){_i.call(this,t,i),this.anchr1=e,this.anchr2=s,this.min=n,this.max=r,this.r1=this.r2=this.n=null,this.nMass=0,this.jnAcc=this.jnMax=0,this.bias=0};gi.prototype=Object.create(_i.prototype),gi.prototype.preStep=function(t){var i=this.a,e=this.b;this.r1=I(this.anchr1,i.rot),this.r2=I(this.anchr2,e.rot);var s=A(S(e.p,this.r2),S(i.p,this.r1)),n=m(s),r=0;n>this.max?(r=n-this.max,this.n=N(s)):n=C(n,r)?(this.clamp=-1,this.r1=A(n,i.p)):(this.clamp=0,this.r1=A(S(j(M(r),-a),j(r,o)),i.p)),di(i,e,this.r1,this.r2,this.k1,this.k2),this.jMaxLen=this.maxForce*t;var h=A(S(e.p,this.r2),S(i.p,this.r1));this.bias=E(j(h,-fi(this.errorBias,t)/t),this.maxBias)},wi.prototype.applyCachedImpulse=function(t){li(this.a,this.b,this.r1,this.r2,this.jAcc.x*t,this.jAcc.y*t)},wi.prototype.grooveConstrain=function(t){var i=this.grv_tn,e=this.clamp*C(t,i)>0?t:P(t,i);return E(e,this.jMaxLen)},wi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=this.r1,s=this.r2,n=hi(t,i,e,s),r=vi(A(this.bias,n),this.k1,this.k2),o=this.jAcc;this.jAcc=this.grooveConstrain(S(o,r)),li(t,i,this.r1,this.r2,this.jAcc.x-o.x,this.jAcc.y-o.y)},wi.prototype.getImpulse=function(){return m(this.jAcc)},wi.prototype.setGrooveA=function(t){this.grv_a=t,this.grv_n=M(F(A(this.grv_b,t))),this.activateBodies()},wi.prototype.setGrooveB=function(t){this.grv_b=t,this.grv_n=M(F(A(t,this.grv_a))),this.activateBodies()};var Si=function(t,i){return(t.restLength-i)*t.stiffness},Ai=t.DampedSpring=function(t,i,e,s,n,r,o){_i.call(this,t,i),this.anchr1=e,this.anchr2=s,this.restLength=n,this.stiffness=r,this.damping=o,this.springForceFunc=Si,this.target_vrn=this.v_coef=0,this.r1=this.r2=null,this.nMass=0,this.n=null};Ai.prototype=Object.create(_i.prototype),Ai.prototype.preStep=function(t){var i=this.a,e=this.b;this.r1=I(this.anchr1,i.rot),this.r2=I(this.anchr2,e.rot);var s=A(S(e.p,this.r2),S(i.p,this.r1)),r=m(s);this.n=j(s,1/(r?r:1/0));var o=bi(i,e,this.r1,this.r2,this.n);n(0!==o,"Unsolvable this."),this.nMass=1/o,this.target_vrn=0,this.v_coef=1-Math.exp(-this.damping*t*o);var a=this.springForceFunc(this,r);li(i,e,this.r1,this.r2,this.n.x*a*t,this.n.y*a*t)},Ai.prototype.applyCachedImpulse=function(t){},Ai.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=this.n,s=this.r1,n=this.r2,r=ci(t,i,s,n,e),o=(this.target_vrn-r)*this.v_coef;this.target_vrn=r+o,o*=this.nMass,li(t,i,this.r1,this.r2,this.n.x*o,this.n.y*o)},Ai.prototype.getImpulse=function(){return 0};var Bi=function(t,i){return(i-t.restAngle)*t.stiffness},ji=t.DampedRotarySpring=function(t,i,e,s,n){_i.call(this,t,i),this.restAngle=e,this.stiffness=s,this.damping=n,this.springTorqueFunc=Bi,this.target_wrn=0,this.w_coef=0,this.iSum=0};ji.prototype=Object.create(_i.prototype),ji.prototype.preStep=function(t){var i=this.a,e=this.b,s=i.i_inv+e.i_inv;n(0!==s,"Unsolvable spring."),this.iSum=1/s,this.w_coef=1-Math.exp(-this.damping*t*s),this.target_wrn=0;var r=this.springTorqueFunc(this,i.a-e.a)*t;i.w-=r*i.i_inv,e.w+=r*e.i_inv},ji.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=t.w-i.w,s=(this.target_wrn-e)*this.w_coef;this.target_wrn=e+s;var n=s*this.iSum;t.w+=n*t.i_inv,i.w-=n*i.i_inv};var Ci=t.RotaryLimitJoint=function(t,i,e,s){_i.call(this,t,i),this.min=e,this.max=s,this.jAcc=0,this.iSum=this.bias=this.jMax=0};Ci.prototype=Object.create(_i.prototype),Ci.prototype.preStep=function(t){var i=this.a,e=this.b,s=e.a-i.a,n=0;s>this.max?n=this.max-s:s0?h=a:this.angle=Math.floor((o-n)/r)*r+n,this.iSum=1/(i.i_inv+e.i_inv);var c=this.maxBias;this.bias=d(-fi(this.errorBias,t)*h/t,-c,c),this.jMax=this.maxForce*t,this.bias||(this.jAcc=0)},ki.prototype.applyCachedImpulse=function(t){var i=this.a,e=this.b,s=this.jAcc*t;i.w-=s*i.i_inv,e.w+=s*e.i_inv},ki.prototype.applyImpulse=function(){if(this.bias){var t=this.a,i=this.b,e=i.w-t.w,s=this.ratchet,n=-(this.bias+e)*this.iSum,r=this.jAcc;this.jAcc=d((r+n)*s,0,this.jMax*Math.abs(s))/s,n=this.jAcc-r,t.w-=n*t.i_inv,i.w+=n*i.i_inv}},ki.prototype.getImpulse=function(t){return Math.abs(t.jAcc)};var Mi=t.GearJoint=function(t,i,e,s){_i.call(this,t,i),this.phase=e,this.ratio=s,this.ratio_inv=1/s,this.jAcc=0,this.iSum=this.bias=this.jMax=0};Mi.prototype=Object.create(_i.prototype),Mi.prototype.preStep=function(t){var i=this.a,e=this.b;this.iSum=1/(i.i_inv*this.ratio_inv+this.ratio*e.i_inv);var s=this.maxBias;this.bias=d(-fi(this.errorBias,t)*(e.a*this.ratio-i.a-this.phase)/t,-s,s),this.jMax=this.maxForce*t},Mi.prototype.applyCachedImpulse=function(t){var i=this.a,e=this.b,s=this.jAcc*t;i.w-=s*i.i_inv*this.ratio_inv,e.w+=s*e.i_inv},Mi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=i.w*this.ratio-t.w,s=(this.bias-e)*this.iSum,n=this.jAcc;this.jAcc=d(n+s,-this.jMax,this.jMax),s=this.jAcc-n,t.w-=s*t.i_inv*this.ratio_inv,i.w+=s*i.i_inv},Mi.prototype.getImpulse=function(){return Math.abs(this.jAcc)},Mi.prototype.setRatio=function(t){this.ratio=t,this.ratio_inv=1/t,this.activateBodies()};var Pi=t.SimpleMotor=function(t,i,e){_i.call(this,t,i),this.rate=e,this.jAcc=0,this.iSum=this.jMax=0};Pi.prototype=Object.create(_i.prototype),Pi.prototype.preStep=function(t){this.iSum=1/(this.a.i_inv+this.b.i_inv),this.jMax=this.maxForce*t},Pi.prototype.applyCachedImpulse=function(t){var i=this.a,e=this.b,s=this.jAcc*t;i.w-=s*i.i_inv,e.w+=s*e.i_inv},Pi.prototype.applyImpulse=function(){var t=this.a,i=this.b,e=i.w-t.w+this.rate,s=-e*this.iSum,n=this.jAcc;this.jAcc=d(n+s,-this.jMax,this.jMax),s=this.jAcc-n,t.w-=s*t.i_inv,i.w+=s*i.i_inv},Pi.prototype.getImpulse=function(){return Math.abs(this.jAcc)}}(),function(){var t=Hilo.Class,i=Hilo.EventMixin,e=Hilo.View,s=Math.PI/180,n=1/s,r={space:null,body:null,shape:null,applyImpulse:function(t,i){i=i||{x:0,y:0},this.body.applyImpulse(cp.v(t.x,t.y),cp.v(i.x,i.y))},applyForce:function(t,i){i=i||{x:0,y:0},this.body.applyForce(cp.v(t.x,t.y),cp.v(i.x,i.y))},setPosition:function(t,i){this.body.setPos(new cp.Vect(t,i)),this.body.isStaticBody&&(this.space.needReindexStatic=!0)},setRotation:function(t){this.body.setAngle(t*s),this.body.isStaticBody&&(this.space.needReindexStatic=!0)},render:function(t,i){this._physicsRender(),this._viewRender.call(this,t,i)},_physicsRender:function(){this.x=this.body.p.x,this.y=this.body.p.y,this.rotation=this.body.a*n}},o=t.create({Mixes:i,Statics:{SHAPE_RECT:"rect",SHAPE_CIRCLE:"circle",SHAPE_POLYGEN:"polygen"},constructor:function(t,i){this._init(t,i)},_init:function(t,i){var e=new cp.Space;if(e.iterations=20,e.gravity=new cp.Vect(t.x,t.y),e.collisionSlop=.5,e.sleepTimeThreshold=.5,i)for(var s in i)e[s]=i[s];this.space=e,this.staticBody=e.staticBody,this._deleteBodies=[]},tick:function(t){var i=this.space;t=t>32?16:t,i.needReindexStatic&&(i.reindexStatic(),i.needReindexStatic=!1),i.step(.001*t);for(var e=this._deleteBodies.length-1;e>=0;e--){for(var s=this._deleteBodies[e],n=s.shapeList,r=n.length-1;r>=0;r--)i.removeShape(n[r]);i.removeBody(s)}},bindView:function(i,e){i.body&&this.unbindView(i);var n,a,e=e||{},h=e.mass||1,c=e.type||o.SHAPE_RECT,p=void 0===e.group?0:e.group,l=void 0===e.layers?-1:e.layers,u=i.width*i.scaleX,y=i.height*i.scaleY;switch(c!==o.SHAPE_POLYGEN||i.boundsArea||e.boundsArea||(c=o.SHAPE_RECT),c){case o.SHAPE_RECT:u=e.width||u,y=e.height||y,n=e.isStatic?this._createStaticBody():new cp.Body(h,cp.momentForBox(h,u,y)),a=new cp.BoxShape(n,u,y);break;case o.SHAPE_CIRCLE:radius=e.radius||.5*u,n=e.isStatic?this._createStaticBody():new cp.Body(h,cp.momentForCircle(h,0,radius,new cp.Vect(0,0))),a=new cp.CircleShape(n,radius,new cp.Vect(0,0));break;case o.SHAPE_POLYGEN:var b=e.boundsArea||i.boundsArea;verts=[],b.forEach(function(t){verts.push(t.x),verts.push(t.y)}),i.boundsArea=b,n=e.isStatic?this._createStaticBody():new cp.Body(h,cp.momentForPoly(h,verts,new cp.Vect(0,0))),a=new cp.PolyShape(n,verts,new cp.Vect(0,0))}n.setAngle(i.rotation*s),n.setPos(new cp.Vect(i.x,i.y)),a.setElasticity(e.restitution||.4),a.setFriction(e.friction||1),a.setCollisionType(e.collisionType||1),a.layers=l,a.group=p,i._viewRender=i.render,t.mix(i,r),i.body=n,i.shape=a,i.space=this.space,n.view=i,i.pivotX=.5*i.width,i.pivotY=.5*i.height,e.isStatic?this.space.addShape(a):(this.space.addBody(n),this.space.addShape(a)),i._physicsRender()},addConstraint:function(t){return this.space.addConstraint(t)},removeConstraint:function(t){return this.space.removeConstraint(t)},unbindView:function(t,i){var e=t.body;e&&(t.body=null,e.view=null,this._deleteBodies.indexOf(e)<0&&this._deleteBodies.push(e));for(var s in r)t[s]=null;t._viewRender&&(t.render=t._viewRender),i&&t.removeFromParent()},addCollisionListener:function(t,i,e){var s=e.begin||function(t){return!0},n=e.preSolve||function(t){return!0},r=e.postSolve||function(t){},o=e.separate||function(t){};this.space.addCollisionHandler(t,i,s,n,r,o)},createBounds:function(t,i){this._createBound({x:0,y:i},{x:t,y:i},1),this._createBound({x:0,y:0},{x:0,y:i},1),this._createBound({x:t,y:0},{x:t,y:i},1)},_createBound:function(t,i,e){var s=this.space.addShape(new cp.SegmentShape(this.staticBody,cp.v(t.x,t.y),cp.v(i.x,i.y),e));s.setElasticity(1),s.setFriction(1)},_createStaticBody:function(){var t=new cp.Body(1/0,1/0);return t.nodeIdleTime=1/0,t.isStaticBody=!0,t}}),a=t.create({Extends:e,constructor:function(t){t=t||{},this.id=this.id||t.id||Hilo.getUid("PhysicsDebugView"),this.showShapes=!0,this.showConstraints=!0,a.superclass.constructor.call(this,t),this.space=t.world.space,this.pointerEnabled=!1,this.pointerChildren=!1,this.initDebugDraw()},render:function(t,i){var e=t.canvas,s=t.context;e.getContext&&s&&(this.showShapes&&this.space.eachShape(function(t){t.hideDebugView||(s.fillStyle=t.style(),t.draw(s))}),this.showConstraints&&this.space.eachConstraint(function(t){!t.hideDebugView&&t.draw&&t.draw(s)}))},initDebugDraw:function(){if(!this._isInit){this._isInit=!0;var t=cp.v,i=function(t,i,e,s){t.beginPath(),t.arc(i.x,i.y,e,0,2*Math.PI,!1),void 0===s&&(s=!0),s&&t.fill(),t.stroke()},e=function(t,i,e){t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(e.x,e.y),t.stroke()},s=[t(0,0),t(.2,0),t(.25,.5),t(.3,-1),t(.35,1),t(.4,-1),t(.45,1),t(.5,-1),t(.55,1),t(.6,-1),t(.65,1),t(.7,-1),t(.75,.5),t(.8,0),t(1,0)],n=function(i,e,n,r){ +null==r&&(r=6),i.beginPath(),i.moveTo(e.x,e.y);for(var o=t.sub(n,e),a=t.len(o),h=t.mult(o,1/a),c=1;cthis.space.sleepTimeThreshold?"rgb(170,170,170)":o[this.hashid%o.length])}}}});Hilo.Physics=o,Hilo.PhysicsDebugView=a}(); \ No newline at end of file diff --git a/src/extensions/physics/chipmunk.js b/src/extensions/physics/chipmunk.js index c4818dc9..85f951f4 100644 --- a/src/extensions/physics/chipmunk.js +++ b/src/extensions/physics/chipmunk.js @@ -1,16 +1,16 @@ (function(){ /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,7 +25,7 @@ Object.create = Object.create || function(o) { F.prototype = o; return new F(); }; - + //var VERSION = CP_VERSION_MAJOR + "." + CP_VERSION_MINOR + "." + CP_VERSION_RELEASE; var cp; @@ -41,7 +41,6 @@ if(typeof exports === 'undefined'){ var assert = function(value, message) { - return if (!value) { throw new Error('Assertion failed: ' + message); } @@ -49,7 +48,6 @@ var assert = function(value, message) var assertSoft = function(value, message) { - return if(!value && console && console.warn) { console.warn("ASSERTION FAILED: " + message); if(console.trace) { @@ -102,7 +100,7 @@ var deleteObjFromList = function(arr, obj) if(arr[i] === obj){ arr[i] = arr[arr.length - 1]; arr.length--; - + return; } } @@ -157,11 +155,11 @@ cp.momentForPoly = function(m, verts, offset) var a = vcross2(v2x, v2y, v1x, v1y); var b = vdot2(v1x, v1y, v1x, v1y) + vdot2(v1x, v1y, v2x, v2y) + vdot2(v2x, v2y, v2x, v2y); - + sum1 += a*b; sum2 += a; } - + return (m*sum1)/(6*sum2); }; @@ -171,7 +169,7 @@ cp.areaForPoly = function(verts) for(var i=0, len=verts.length; i> 1; for(var i=1; i> 1; //if(first) (*first) = start; var resultCount = QHullReduce(tolerance, result, 2, count - 2, a, b, a, 1) + 1; @@ -383,17 +381,17 @@ var lerpconst = function(f1, f2, d) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -625,7 +623,7 @@ var vnear = cp.v.near = function(v1, v2, dist) var vslerp = cp.v.slerp = function(v1, v2, t) { var omega = Math.acos(vdot(v1, v2)); - + if(omega) { var denom = 1/Math.sin(omega); return vadd(vmult(v1, Math.sin((1 - t)*omega)*denom), vmult(v2, Math.sin(t*omega)*denom)); @@ -660,17 +658,17 @@ var vstr = cp.v.str = function(v) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -791,25 +789,25 @@ var bbWrapVect = function(bb, v) var ix = Math.abs(bb.r - bb.l); var modx = (v.x - bb.l) % ix; var x = (modx > 0) ? modx : modx + ix; - + var iy = Math.abs(bb.t - bb.b); var mody = (v.y - bb.b) % iy; var y = (mody > 0) ? mody : mody + iy; - + return new Vect(x + bb.l, y + bb.b); }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -818,7 +816,7 @@ var bbWrapVect = function(bb, v) * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + /// Segment query info struct. /* These are created using literals where needed. typedef struct cpSegmentQueryInfo { @@ -857,21 +855,21 @@ var Shape = cp.Shape = function(body) { /// Sensor flag. /// Sensor shapes call collision callbacks but don't produce collisions. this.sensor = false; - + /// Coefficient of restitution. (elasticity) this.e = 0; /// Coefficient of friction. this.u = 0; /// Surface velocity used when solving for friction. this.surface_v = vzero; - + /// Collision type of this shape used when picking collision handlers. this.collision_type = 0; /// Group of this shape. Shapes in the same group don't collide. this.group = 0; // Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero. this.layers = CP_ALL_LAYERS; - + this.space = null; // Copy the collision code from the prototype into the actual object. This makes collision @@ -985,7 +983,7 @@ var CircleShape = cp.CircleShape = function(body, radius, offset) { this.c = this.tc = offset; this.r = radius; - + this.type = 'circle'; Shape.call(this, body); @@ -1011,10 +1009,10 @@ CircleShape.prototype.cacheData = function(p, rot) var delta = vsub(p, this.tc); var distsq = vlengthsq(delta); var r = this.r; - + if(distsq < r*r){ var info = new PointQueryExtendedInfo(this); - + var dist = Math.sqrt(distsq); info.d = r - dist; info.n = vmult(delta, 1/dist); @@ -1028,7 +1026,7 @@ CircleShape.prototype.nearestPointQuery = function(p) var deltay = p.y - this.tc.y; var d = vlength2(deltax, deltay); var r = this.r; - + var nearestp = new Vect(this.tc.x + deltax * r/d, this.tc.y + deltay * r/d); return new NearestPointQueryInfo(this, nearestp, d - r); }; @@ -1038,13 +1036,13 @@ var circleSegmentQuery = function(shape, center, r, a, b, info) // offset the line to be relative to the circle a = vsub(a, center); b = vsub(b, center); - + var qa = vdot(a, a) - 2*vdot(a, b) + vdot(b, b); var qb = -2*vdot(a, a) + 2*vdot(a, b); var qc = vdot(a, a) - r*r; - + var det = qb*qb - 4*qa*qc; - + if(det >= 0) { var t = (-qb - Math.sqrt(det))/(2*qa); @@ -1081,12 +1079,12 @@ var SegmentShape = cp.SegmentShape = function(body, a, b, r) this.n = vperp(vnormalize(vsub(b, a))); this.ta = this.tb = this.tn = null; - + this.r = r; - + this.a_tangent = vzero; this.b_tangent = vzero; - + this.type = 'segment'; Shape.call(this, body); }; @@ -1098,9 +1096,9 @@ SegmentShape.prototype.cacheData = function(p, rot) this.ta = vadd(p, vrotate(this.a, rot)); this.tb = vadd(p, vrotate(this.b, rot)); this.tn = vrotate(this.n, rot); - + var l,r,b,t; - + if(this.ta.x < this.tb.x){ l = this.ta.x; r = this.tb.x; @@ -1108,7 +1106,7 @@ SegmentShape.prototype.cacheData = function(p, rot) l = this.tb.x; r = this.ta.x; } - + if(this.ta.y < this.tb.y){ b = this.ta.y; t = this.tb.y; @@ -1116,7 +1114,7 @@ SegmentShape.prototype.cacheData = function(p, rot) b = this.tb.y; t = this.ta.y; } - + var rad = this.r; this.bb_l = l - rad; @@ -1128,12 +1126,12 @@ SegmentShape.prototype.cacheData = function(p, rot) SegmentShape.prototype.nearestPointQuery = function(p) { var closest = closestPointOnSegment(p, this.ta, this.tb); - + var deltax = p.x - closest.x; var deltay = p.y - closest.y; var d = vlength2(deltax, deltay); var r = this.r; - + var nearestp = (d ? vadd(closest, vmult(new Vect(deltax, deltay), r/d)) : closest); return new NearestPointQueryInfo(this, nearestp, d - r); }; @@ -1143,26 +1141,26 @@ SegmentShape.prototype.segmentQuery = function(a, b) var n = this.tn; var d = vdot(vsub(this.ta, a), n); var r = this.r; - + var flipped_n = (d > 0 ? vneg(n) : n); var n_offset = vsub(vmult(flipped_n, r), a); - + var seg_a = vadd(this.ta, n_offset); var seg_b = vadd(this.tb, n_offset); var delta = vsub(b, a); - + if(vcross(delta, seg_a)*vcross(delta, seg_b) <= 0){ var d_offset = d + (d > 0 ? -r : r); var ad = -d_offset; var bd = vdot(delta, n) - d_offset; - + if(ad*bd < 0){ return new SegmentQueryInfo(this, ad/(ad - bd), flipped_n); } } else if(r !== 0){ var info1 = circleSegmentQuery(this, this.ta, this.r, a, b); var info2 = circleSegmentQuery(this, this.tb, this.r, a, b); - + if (info1){ return info2 && info2.t < info1.t ? info2 : info1; } else { @@ -1198,17 +1196,17 @@ CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius); */ /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -1217,7 +1215,7 @@ CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius); * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + /// Check that a set of vertexes is convex and has a clockwise winding. var polyValidate = function(verts) { @@ -1229,13 +1227,13 @@ var polyValidate = function(verts) var by = verts[(i+3)%len]; var cx = verts[(i+4)%len]; var cy = verts[(i+5)%len]; - + //if(vcross(vsub(b, a), vsub(c, b)) > 0){ if(vcross2(bx - ax, by - ay, cx - bx, cy - by) > 0){ return false; } } - + return true; }; @@ -1269,7 +1267,7 @@ PolyShape.prototype.setVerts = function(verts, offset) // Fail if the user attempts to pass a concave poly, or a bad winding. assert(polyValidate(verts), "Polygon is concave or has a reversed winding. Consider using cpConvexHull()"); - + var len = verts.length; var numVerts = len >> 1; @@ -1279,7 +1277,7 @@ PolyShape.prototype.setVerts = function(verts, offset) this.tVerts = new Array(len); this.planes = new Array(numVerts); this.tPlanes = new Array(numVerts); - + for(var i=0; i (' + vx + ',' + vy + ')'); - + dst[i] = vx; dst[i+1] = vy; @@ -1357,7 +1355,7 @@ PolyShape.prototype.transformAxes = function(p, rot) { var src = this.planes; var dst = this.tPlanes; - + for(var i=0; i 0) outside = true; - + var v1x = verts[i*2]; var v1y = verts[i*2 + 1]; var closest = closestPointOnSegment2(p.x, p.y, v0x, v0y, v1x, v1y); - + var dist = vdist(p, closest); if(dist < minDist){ minDist = dist; closestPoint = closest; } - + v0x = v1x; v0y = v1y; } - + return new NearestPointQueryInfo(this, closestPoint, (outside ? minDist : -minDist)); }; @@ -1408,16 +1406,16 @@ PolyShape.prototype.segmentQuery = function(a, b) var verts = this.tVerts; var numVerts = axes.length; var len = numVerts * 2; - + for(var i=0; i an) continue; - + var bn = vdot(b, n); var t = (axes[i].d - an)/(bn - an); if(t < 0 || 1 < t) continue; - + var point = vlerp(a, b, t); var dt = -vcross(n, point); var dtMin = -vcross2(n.x, n.y, verts[i*2], verts[i*2+1]); @@ -1436,38 +1434,38 @@ PolyShape.prototype.valueOnAxis = function(n, d) { var verts = this.tVerts; var m = vdot2(n.x, n.y, verts[0], verts[1]); - + for(var i=2; i 0) return false; } - + return true; }; PolyShape.prototype.containsVertPartial = function(vx, vy, n) { var planes = this.tPlanes; - + for(var i=0; i 0) return false; } - + return true; }; @@ -1940,31 +1938,31 @@ var SpatialIndex = cp.SpatialIndex = function(staticIndex) } }; -// Collide the objects in an index against the objects in a staticIndex using the query callback function. +// Collide the objects in a dynamic index against the objects in a static index using the query callback function. SpatialIndex.prototype.collideStatic = function(staticIndex, func) { if(staticIndex.count > 0){ - var query = staticIndex.query; - - this.each(function(obj) { - query(obj, new BB(obj.bb_l, obj.bb_b, obj.bb_r, obj.bb_t), func); + this.each(function(obj1) { + staticIndex.query(new BB(obj1.bb_l, obj1.bb_b, obj1.bb_r, obj1.bb_t), function (obj2) { + func(obj1, obj2); + }); }); } }; /* Copyright (c) 2009 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -1979,7 +1977,7 @@ SpatialIndex.prototype.collideStatic = function(staticIndex, func) var BBTree = cp.BBTree = function(staticIndex) { SpatialIndex.call(this, staticIndex); - + this.velocityFunc = null; // This is a hash from object ID -> object for the objects stored in the BBTree. @@ -1988,11 +1986,11 @@ var BBTree = cp.BBTree = function(staticIndex) this.count = 0; this.root = null; - + // A linked list containing an object pool of tree nodes and pairs. this.pooledNodes = null; this.pooledPairs = null; - + this.stamp = 0; }; @@ -2008,7 +2006,7 @@ var Node = function(tree, a, b) this.bb_r = max(a.bb_r, b.bb_r); this.bb_t = max(a.bb_t, b.bb_t); this.parent = null; - + this.setA(a); this.setB(b); }; @@ -2048,7 +2046,7 @@ BBTree.prototype.getBB = function(obj, dest) var coef = 0.1; var x = (obj.bb_r - obj.bb_l)*coef; var y = (obj.bb_t - obj.bb_b)*coef; - + var v = vmult(velocityFunc(obj), 0.1); dest.bb_l = obj.bb_l + min(-x, v.x); @@ -2128,7 +2126,7 @@ var unlinkThread = function(prev, leaf, next) if(next){ if(next.leafA === leaf) next.prevA = prev; else next.prevB = prev; } - + if(prev){ if(prev.leafA === leaf) prev.nextA = next; else prev.nextB = next; } else { @@ -2142,7 +2140,7 @@ Leaf.prototype.clearPairs = function(tree) next; this.pairs = null; - + while(pair){ if(pair.leafA === this){ next = pair.nextA; @@ -2165,7 +2163,7 @@ var pairInsert = function(a, b, tree) if(nextA){ if(nextA.leafA === a) nextA.prevA = pair; else nextA.prevB = pair; } - + if(nextB){ if(nextB.leafA === b) nextB.prevA = pair; else nextB.prevB = pair; } @@ -2207,7 +2205,7 @@ Node.prototype.otherChild = function(child) Node.prototype.replaceChild = function(child, value, tree) { assertSoft(child == this.A || child == this.B, "Node is not a child of parent."); - + if(this.A == child){ this.A.recycle(tree); this.setA(value); @@ -2215,7 +2213,7 @@ Node.prototype.replaceChild = function(child, value, tree) this.B.recycle(tree); this.setB(value); } - + for(var node=this; node; node = node.parent){ //node.bb = bbMerge(node.A.bb, node.B.bb); var a = node.A; @@ -2258,18 +2256,18 @@ var subtreeInsert = function(subtree, leaf, tree) } else { var cost_a = subtree.B.bbArea() + bbTreeMergedArea(subtree.A, leaf); var cost_b = subtree.A.bbArea() + bbTreeMergedArea(subtree.B, leaf); - + if(cost_a === cost_b){ cost_a = bbProximity(subtree.A, leaf); cost_b = bbProximity(subtree.B, leaf); - } + } if(cost_b < cost_a){ subtree.setB(subtreeInsert(subtree.B, leaf, tree)); } else { subtree.setA(subtreeInsert(subtree.A, leaf, tree)); } - + // subtree.bb = bbMerge(subtree.bb, leaf.bb); subtree.bb_l = min(subtree.bb_l, leaf.bb_l); subtree.bb_b = min(subtree.bb_b, leaf.bb_b); @@ -2306,20 +2304,20 @@ var nodeSegmentQuery = function(node, a, b) var tx2 = (node.bb_r == a.x ? Infinity : (node.bb_r - a.x)*idx); var txmin = min(tx1, tx2); var txmax = max(tx1, tx2); - + var idy = 1/(b.y - a.y); var ty1 = (node.bb_b == a.y ? -Infinity : (node.bb_b - a.y)*idy); var ty2 = (node.bb_t == a.y ? Infinity : (node.bb_t - a.y)*idy); var tymin = min(ty1, ty2); var tymax = max(ty1, ty2); - + if(tymin <= txmax && txmin <= tymax){ var min_ = max(txmin, tymin); var max_ = min(txmax, tymax); - + if(0.0 <= max_ && min_ <= 1.0) return max(min_, 0.0); } - + return Infinity; }; @@ -2330,7 +2328,7 @@ var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) } else { var t_a = nodeSegmentQuery(subtree.A, a, b); var t_b = nodeSegmentQuery(subtree.B, a, b); - + if(t_a < t_b){ if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func)); if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func)); @@ -2338,7 +2336,7 @@ var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func)); if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func)); } - + return t_exit; } }; @@ -2409,7 +2407,7 @@ Leaf.prototype.markSubtree = function(tree, staticRoot, func) { if(this.stamp == tree.getStamp()){ if(staticRoot) staticRoot.markLeafQuery(this, false, tree, func); - + for(var node = this; node.parent; node = node.parent){ if(node == node.parent.A){ node.parent.B.markLeafQuery(this, true, tree, func); @@ -2451,16 +2449,16 @@ Leaf.prototype.update = function(tree) //if(!bbContainsBB(this.bb, bb)){ if(!this.containsObj(obj)){ tree.getBB(this.obj, this); - + root = subtreeRemove(root, this, tree); tree.root = subtreeInsert(root, this, tree); - + this.clearPairs(tree); this.stamp = tree.getStamp(); - + return true; } - + return false; }; @@ -2487,7 +2485,7 @@ BBTree.prototype.insert = function(obj, hashid) this.leaves[hashid] = leaf; this.root = subtreeInsert(this.root, leaf, this); this.count++; - + leaf.stamp = this.getStamp(); leaf.addPairs(this); this.incrementStamp(); @@ -2516,7 +2514,7 @@ var voidQueryFunc = function(obj1, obj2){}; BBTree.prototype.reindexQuery = function(func) { if(!this.root) return; - + // LeafUpdate() may modify this.root. Don't cache it. var hashid, leaves = this.leaves; @@ -2524,13 +2522,13 @@ BBTree.prototype.reindexQuery = function(func) { leaves[hashid].update(this); } - + var staticIndex = this.staticIndex; var staticRoot = staticIndex && staticIndex.root; - + this.root.markSubtree(this, staticRoot, func); if(staticIndex && !staticRoot) this.collideStatic(this, staticIndex, func); - + this.incrementStamp(); }; @@ -2597,7 +2595,7 @@ var partitionNodes = function(tree, nodes, offset, count) } else if(count == 2) { return tree.makeNode(nodes[offset], nodes[offset + 1]); } - + // Find the AABB for these nodes //var bb = nodes[offset].bb; var node = nodes[offset]; @@ -2615,10 +2613,10 @@ var partitionNodes = function(tree, nodes, offset, count) bb_r = max(bb_r, node.bb_r); bb_t = max(bb_t, node.bb_t); } - + // Split it on it's longest axis var splitWidth = (bb_r - bb_l > bb_t - bb_b); - + // Sort the bounds and use the median as the splitting point var bounds = new Array(count*2); if(splitWidth){ @@ -2632,7 +2630,7 @@ var partitionNodes = function(tree, nodes, offset, count) bounds[2*i + 1] = nodes[i].bb_t; } } - + bounds.sort(function(a, b) { // This might run faster if the function was moved out into the global scope. return a - b; @@ -2645,7 +2643,7 @@ var partitionNodes = function(tree, nodes, offset, count) var b_l = bb_l, b_b = bb_b, b_r = bb_r, b_t = bb_t; if(splitWidth) a_r = b_l = split; else a_t = b_b = split; - + // Partition the nodes var right = end; for(var left=offset; left < right;){ @@ -2659,13 +2657,13 @@ var partitionNodes = function(tree, nodes, offset, count) left++; } } - + if(right == count){ var node = null; for(var i=offset; iprev = prev; if(next.body_a === body){ @@ -3027,15 +3025,15 @@ Arbiter.prototype.unthread = function() //{ // cpFloat fsum = 0; // cpVect vsum = vzero; -// +// // for(int i=0; i= mindist*mindist) return; - + var dist = Math.sqrt(distsq); // Allocate and initialize the contact. @@ -3271,15 +3269,15 @@ var circle2segment = function(circleShape, segmentShape) var seg_a = segmentShape.ta; var seg_b = segmentShape.tb; var center = circleShape.tc; - + var seg_delta = vsub(seg_b, seg_a); var closest_t = clamp01(vdot(seg_delta, vsub(center, seg_a))/vlengthsq(seg_delta)); var closest = vadd(seg_a, vmult(seg_delta, closest_t)); - + var contact = circle2circleQuery(center, closest, circleShape.r, segmentShape.r); if(contact){ var n = contact.n; - + // Reject endcap collisions if tangents are provided. return ( (closest_t === 0 && vdot(n, segmentShape.a_tangent) < 0) || @@ -3303,7 +3301,7 @@ var findMSA = function(poly, planes) var min_index = 0; var min = poly.valueOnAxis(planes[0].n, planes[0].d); if(min > 0) return -1; - + for(var i=1; i 0) { @@ -3313,7 +3311,7 @@ var findMSA = function(poly, planes) min_index = i; } } - + last_MSA_min = min; return min_index; }; @@ -3333,7 +3331,7 @@ var findVertsFallback = function(poly1, poly2, n, dist) arr.push(new Contact(new Vect(vx, vy), n, dist, hashPair(poly1.hashid, i))); } } - + var verts2 = poly2.tVerts; for(var i=0; i>1))); } } - + var verts2 = poly2.tVerts; for(var i=0; i>1))); } } - + return (arr.length ? arr : findVertsFallback(poly1, poly2, n, dist)); }; @@ -3378,11 +3376,11 @@ var poly2poly = function(poly1, poly2) var mini1 = findMSA(poly2, poly1.tPlanes); if(mini1 == -1) return NONE; var min1 = last_MSA_min; - + var mini2 = findMSA(poly1, poly2.tPlanes); if(mini2 == -1) return NONE; var min2 = last_MSA_min; - + // There is overlap, find the penetrating verts if(min1 > min2) return findVerts(poly1, poly2, poly1.tPlanes[mini1].n, min1); @@ -3399,12 +3397,12 @@ var segValueOnAxis = function(seg, n, d) }; // Identify vertexes that have penetrated the segment. -var findPointsBehindSeg = function(arr, seg, poly, pDist, coef) +var findPointsBehindSeg = function(arr, seg, poly, pDist, coef) { var dta = vcross(seg.tn, seg.ta); var dtb = vcross(seg.tn, seg.tb); var n = vmult(seg.tn, coef); - + var verts = poly.tVerts; for(var i=0; i 0 || minNorm > 0) return NONE; - + var mini = 0; var poly_min = segValueOnAxis(seg, planes[0].n, planes[0].d); if(poly_min > 0) return NONE; @@ -3444,34 +3442,34 @@ var seg2poly = function(seg, poly) mini = i; } } - + var poly_n = vneg(planes[mini].n); - + var va = vadd(seg.ta, vmult(poly_n, seg.r)); var vb = vadd(seg.tb, vmult(poly_n, seg.r)); if(poly.containsVert(va.x, va.y)) arr.push(new Contact(va, poly_n, poly_min, hashPair(seg.hashid, 0))); if(poly.containsVert(vb.x, vb.y)) arr.push(new Contact(vb, poly_n, poly_min, hashPair(seg.hashid, 1))); - + // Floating point precision problems here. // This will have to do for now. // poly_min -= cp_collision_slop; // TODO is this needed anymore? - + if(minNorm >= poly_min || minNeg >= poly_min) { if(minNorm > minNeg) findPointsBehindSeg(arr, seg, poly, minNorm, 1); else findPointsBehindSeg(arr, seg, poly, minNeg, -1); } - + // If no other collision points are found, try colliding endpoints. if(arr.length === 0){ var mini2 = mini * 2; var verts = poly.tVerts; var poly_a = new Vect(verts[mini2], verts[mini2+1]); - + var con; if((con = circle2circleQuery(seg.ta, poly_a, seg.r, 0, arr))) return [con]; if((con = circle2circleQuery(seg.tb, poly_a, seg.r, 0, arr))) return [con]; @@ -3492,7 +3490,7 @@ var seg2poly = function(seg, poly) var circle2poly = function(circ, poly) { var planes = poly.tPlanes; - + var mini = 0; var min = vdot(planes[0].n, circ.tc) - planes[0].d - circ.r; for(var i=0; i 0, "You created a 0 length pin joint. A pivot joint will be much more stable."); this.r1 = this.r2 = null; @@ -5246,21 +5244,21 @@ PinJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); var dist = vlength(delta); this.n = vmult(delta, 1/(dist ? dist : Infinity)); - + // calculate mass normal this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*(dist - this.dist)/dt, -maxBias, maxBias); - + // compute max impulse this.jnMax = this.maxForce * dt; }; @@ -5279,13 +5277,13 @@ PinJoint.prototype.applyImpulse = function() // compute relative velocity var vrn = normal_relative_velocity(a, b, this.r1, this.r2, n); - + // compute normal impulse var jn = (this.bias - vrn)*this.nMass; var jnOld = this.jnAcc; this.jnAcc = clamp(jnOld + jn, -this.jnMax, this.jnMax); jn = this.jnAcc - jnOld; - + // apply impulse apply_impulses(a, b, this.r1, this.r2, n.x*jn, n.y*jn); }; @@ -5296,17 +5294,17 @@ PinJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5319,7 +5317,7 @@ PinJoint.prototype.getImpulse = function() var SlideJoint = cp.SlideJoint = function(a, b, anchr1, anchr2, min, max) { Constraint.call(this, a, b); - + this.anchr1 = anchr1; this.anchr2 = anchr2; this.min = min; @@ -5327,7 +5325,7 @@ var SlideJoint = cp.SlideJoint = function(a, b, anchr1, anchr2, min, max) this.r1 = this.r2 = this.n = null; this.nMass = 0; - + this.jnAcc = this.jnMax = 0; this.bias = 0; }; @@ -5338,10 +5336,10 @@ SlideJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); var dist = vlength(delta); var pdist = 0; @@ -5355,14 +5353,14 @@ SlideJoint.prototype.preStep = function(dt) this.n = vzero; this.jnAcc = 0; } - + // calculate mass normal this.nMass = 1/k_scalar(a, b, this.r1, this.r2, this.n); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - + // compute max impulse this.jnMax = this.maxForce * dt; }; @@ -5379,21 +5377,21 @@ SlideJoint.prototype.applyImpulse = function() var a = this.a; var b = this.b; - + var n = this.n; var r1 = this.r1; var r2 = this.r2; - + // compute relative velocity var vr = relative_velocity(a, b, r1, r2); var vrn = vdot(vr, n); - + // compute normal impulse var jn = (this.bias - vrn)*this.nMass; var jnOld = this.jnAcc; this.jnAcc = clamp(jnOld + jn, -this.jnMax, 0); jn = this.jnAcc - jnOld; - + // apply impulse apply_impulses(a, b, this.r1, this.r2, n.x * jn, n.y * jn); }; @@ -5404,17 +5402,17 @@ SlideJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5428,7 +5426,7 @@ SlideJoint.prototype.getImpulse = function() var PivotJoint = cp.PivotJoint = function(a, b, anchr1, anchr2) { Constraint.call(this, a, b); - + if(typeof anchr2 === 'undefined') { var pivot = anchr1; @@ -5440,7 +5438,7 @@ var PivotJoint = cp.PivotJoint = function(a, b, anchr1, anchr2) this.anchr2 = anchr2; this.r1 = this.r2 = vzero; - + this.k1 = new Vect(0,0); this.k2 = new Vect(0,0); this.jAcc = vzero; @@ -5455,16 +5453,16 @@ PivotJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + // Calculate mass tensor. Result is stored into this.k1 & this.k2. k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); - + // compute max impulse this.jMaxLen = this.maxForce * dt; - + // calculate bias velocity var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias); @@ -5479,18 +5477,18 @@ PivotJoint.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + var r1 = this.r1; var r2 = this.r2; - + // compute relative velocity var vr = relative_velocity(a, b, r1, r2); - + // compute normal impulse var j = mult_k(vsub(this.bias, vr), this.k1, this.k2); var jOld = this.jAcc; this.jAcc = vclamp(vadd(this.jAcc, j), this.jMaxLen); - + // apply impulse apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y); }; @@ -5501,17 +5499,17 @@ PivotJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5524,12 +5522,12 @@ PivotJoint.prototype.getImpulse = function() var GrooveJoint = cp.GrooveJoint = function(a, b, groove_a, groove_b, anchr2) { Constraint.call(this, a, b); - + this.grv_a = groove_a; this.grv_b = groove_b; this.grv_n = vperp(vnormalize(vsub(groove_b, groove_a))); this.anchr2 = anchr2; - + this.grv_tn = null; this.clamp = 0; this.r1 = this.r2 = null; @@ -5548,7 +5546,7 @@ GrooveJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + // calculate endpoints in worldspace var ta = a.local2World(this.grv_a); var tb = a.local2World(this.grv_b); @@ -5556,10 +5554,10 @@ GrooveJoint.prototype.preStep = function(dt) // calculate axis var n = vrotate(this.grv_n, a.rot); var d = vdot(ta, n); - + this.grv_tn = n; this.r2 = vrotate(this.anchr2, b.rot); - + // calculate tangential distance along the axis of r2 var td = vcross(vadd(b.p, this.r2), n); // calculate clamping factor and r2 @@ -5573,13 +5571,13 @@ GrooveJoint.prototype.preStep = function(dt) this.clamp = 0; this.r1 = vsub(vadd(vmult(vperp(n), -td), vmult(n, d)), a.p); } - + // Calculate mass tensor - k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); - + k_tensor(a, b, this.r1, this.r2, this.k1, this.k2); + // compute max impulse this.jMaxLen = this.maxForce * dt; - + // calculate bias velocity var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); this.bias = vclamp(vmult(delta, -bias_coef(this.errorBias, dt)/dt), this.maxBias); @@ -5600,17 +5598,17 @@ GrooveJoint.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + var r1 = this.r1; var r2 = this.r2; - + // compute impulse var vr = relative_velocity(a, b, r1, r2); var j = mult_k(vsub(this.bias, vr), this.k1, this.k2); var jOld = this.jAcc; this.jAcc = this.grooveConstrain(vadd(jOld, j)); - + // apply impulse apply_impulses(a, b, this.r1, this.r2, this.jAcc.x - jOld.x, this.jAcc.y - jOld.y); }; @@ -5624,7 +5622,7 @@ GrooveJoint.prototype.setGrooveA = function(value) { this.grv_a = value; this.grv_n = vperp(vnormalize(vsub(this.grv_b, value))); - + this.activateBodies(); }; @@ -5632,22 +5630,22 @@ GrooveJoint.prototype.setGrooveB = function(value) { this.grv_b = value; this.grv_n = vperp(vnormalize(vsub(value, this.grv_a))); - + this.activateBodies(); }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5664,10 +5662,10 @@ var defaultSpringForce = function(spring, dist){ var DampedSpring = cp.DampedSpring = function(a, b, anchr1, anchr2, restLength, stiffness, damping) { Constraint.call(this, a, b); - + this.anchr1 = anchr1; this.anchr2 = anchr2; - + this.restLength = restLength; this.stiffness = stiffness; this.damping = damping; @@ -5686,18 +5684,18 @@ DampedSpring.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + this.r1 = vrotate(this.anchr1, a.rot); this.r2 = vrotate(this.anchr2, b.rot); - + var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1)); var dist = vlength(delta); this.n = vmult(delta, 1/(dist ? dist : Infinity)); - + var k = k_scalar(a, b, this.r1, this.r2, this.n); assertSoft(k !== 0, "Unsolvable this."); this.nMass = 1/k; - + this.target_vrn = 0; this.v_coef = 1 - Math.exp(-this.damping*dt*k); @@ -5712,18 +5710,18 @@ DampedSpring.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + var n = this.n; var r1 = this.r1; var r2 = this.r2; // compute relative velocity var vrn = normal_relative_velocity(a, b, r1, r2, n); - + // compute velocity loss from drag var v_damp = (this.target_vrn - vrn)*this.v_coef; this.target_vrn = vrn + v_damp; - + v_damp *= this.nMass; apply_impulses(a, b, this.r1, this.r2, this.n.x * v_damp, this.n.y * v_damp); }; @@ -5734,17 +5732,17 @@ DampedSpring.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5761,7 +5759,7 @@ var defaultSpringTorque = function(spring, relativeAngle){ var DampedRotarySpring = cp.DampedRotarySpring = function(a, b, restAngle, stiffness, damping) { Constraint.call(this, a, b); - + this.restAngle = restAngle; this.stiffness = stiffness; this.damping = damping; @@ -5778,7 +5776,7 @@ DampedRotarySpring.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + var moment = a.i_inv + b.i_inv; assertSoft(moment !== 0, "Unsolvable spring."); this.iSum = 1/moment; @@ -5798,15 +5796,15 @@ DampedRotarySpring.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + // compute relative velocity var wrn = a.w - b.w;//normal_relative_velocity(a, b, r1, r2, n) - this.target_vrn; - + // compute velocity loss from drag // not 100% certain spring is derived correctly, though it makes sense var w_damp = (this.target_wrn - wrn)*this.w_coef; this.target_wrn = wrn + w_damp; - + //apply_impulses(a, b, this.r1, this.r2, vmult(this.n, v_damp*this.nMass)); var j_damp = w_damp*this.iSum; a.w += j_damp*a.i_inv; @@ -5816,17 +5814,17 @@ DampedRotarySpring.prototype.applyImpulse = function() // DampedRotarySpring.prototype.getImpulse = function(){ return 0; }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5839,7 +5837,7 @@ DampedRotarySpring.prototype.applyImpulse = function() var RotaryLimitJoint = cp.RotaryLimitJoint = function(a, b, min, max) { Constraint.call(this, a, b); - + this.min = min; this.max = max; @@ -5854,7 +5852,7 @@ RotaryLimitJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + var dist = b.a - a.a; var pdist = 0; if(dist > this.max) { @@ -5862,14 +5860,14 @@ RotaryLimitJoint.prototype.preStep = function(dt) } else if(dist < this.min) { pdist = this.min - dist; } - + // calculate moment of inertia coefficient. this.iSum = 1/(1/a.i + 1/b.i); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - + // compute max impulse this.jMax = this.maxForce * dt; @@ -5881,7 +5879,7 @@ RotaryLimitJoint.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -5893,11 +5891,11 @@ RotaryLimitJoint.prototype.applyImpulse = function() var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w - a.w; - - // compute normal impulse + + // compute normal impulse var j = -(this.bias + wr)*this.iSum; var jOld = this.jAcc; if(this.bias < 0){ @@ -5906,7 +5904,7 @@ RotaryLimitJoint.prototype.applyImpulse = function() this.jAcc = clamp(jOld + j, -this.jMax, 0); } j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -5918,17 +5916,17 @@ RotaryLimitJoint.prototype.getImpulse = function() }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -5945,10 +5943,10 @@ var RatchetJoint = cp.RatchetJoint = function(a, b, phase, ratchet) this.angle = 0; this.phase = phase; this.ratchet = ratchet; - + // STATIC_BODY_CHECK this.angle = (b ? b.a : 0) - (a ? a.a : 0); - + this.iSum = this.bias = this.jAcc = this.jMax = 0; }; @@ -5958,28 +5956,28 @@ RatchetJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + var angle = this.angle; var phase = this.phase; var ratchet = this.ratchet; - + var delta = b.a - a.a; var diff = angle - delta; var pdist = 0; - + if(diff*ratchet > 0){ pdist = diff; } else { this.angle = Math.floor((delta - phase)/ratchet)*ratchet + phase; } - + // calculate moment of inertia coefficient. this.iSum = 1/(a.i_inv + b.i_inv); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*pdist/dt, -maxBias, maxBias); - + // compute max impulse this.jMax = this.maxForce * dt; @@ -5991,7 +5989,7 @@ RatchetJoint.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -6003,17 +6001,17 @@ RatchetJoint.prototype.applyImpulse = function() var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w - a.w; var ratchet = this.ratchet; - - // compute normal impulse + + // compute normal impulse var j = -(this.bias + wr)*this.iSum; var jOld = this.jAcc; this.jAcc = clamp((jOld + j)*ratchet, 0, this.jMax*Math.abs(ratchet))/ratchet; j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -6025,17 +6023,17 @@ RatchetJoint.prototype.getImpulse = function(joint) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -6048,11 +6046,11 @@ RatchetJoint.prototype.getImpulse = function(joint) var GearJoint = cp.GearJoint = function(a, b, phase, ratio) { Constraint.call(this, a, b); - + this.phase = phase; this.ratio = ratio; this.ratio_inv = 1/ratio; - + this.jAcc = 0; this.iSum = this.bias = this.jMax = 0; @@ -6064,14 +6062,14 @@ GearJoint.prototype.preStep = function(dt) { var a = this.a; var b = this.b; - + // calculate moment of inertia coefficient. this.iSum = 1/(a.i_inv*this.ratio_inv + this.ratio*b.i_inv); - + // calculate bias velocity var maxBias = this.maxBias; this.bias = clamp(-bias_coef(this.errorBias, dt)*(b.a*this.ratio - a.a - this.phase)/dt, -maxBias, maxBias); - + // compute max impulse this.jMax = this.maxForce * dt; }; @@ -6080,7 +6078,7 @@ GearJoint.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv*this.ratio_inv; b.w += j*b.i_inv; @@ -6090,22 +6088,22 @@ GearJoint.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w*this.ratio - a.w; - - // compute normal impulse + + // compute normal impulse var j = (this.bias - wr)*this.iSum; var jOld = this.jAcc; this.jAcc = clamp(jOld + j, -this.jMax, this.jMax); j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv*this.ratio_inv; b.w += j*b.i_inv; }; -GearJoint.prototype.getImpulse = function() +GearJoint.prototype.getImpulse = function() { return Math.abs(this.jAcc); }; @@ -6118,17 +6116,17 @@ GearJoint.prototype.setRatio = function(value) }; /* Copyright (c) 2007 Scott Lembcke - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -6141,9 +6139,9 @@ GearJoint.prototype.setRatio = function(value) var SimpleMotor = cp.SimpleMotor = function(a, b, rate) { Constraint.call(this, a, b); - + this.rate = rate; - + this.jAcc = 0; this.iSum = this.jMax = 0; @@ -6155,7 +6153,7 @@ SimpleMotor.prototype.preStep = function(dt) { // calculate moment of inertia coefficient. this.iSum = 1/(this.a.i_inv + this.b.i_inv); - + // compute max impulse this.jMax = this.maxForce * dt; }; @@ -6164,7 +6162,7 @@ SimpleMotor.prototype.applyCachedImpulse = function(dt_coef) { var a = this.a; var b = this.b; - + var j = this.jAcc*dt_coef; a.w -= j*a.i_inv; b.w += j*b.i_inv; @@ -6174,16 +6172,16 @@ SimpleMotor.prototype.applyImpulse = function() { var a = this.a; var b = this.b; - + // compute relative rotational velocity var wr = b.w - a.w + this.rate; - - // compute normal impulse + + // compute normal impulse var j = -wr*this.iSum; var jOld = this.jAcc; this.jAcc = clamp(jOld + j, -this.jMax, this.jMax); j = this.jAcc - jOld; - + // apply impulse a.w -= j*a.i_inv; b.w += j*b.i_inv;