From 17d56155b47b469c3a459ada71a1fe5461ed46f4 Mon Sep 17 00:00:00 2001 From: Jeremy Apthorp Date: Mon, 2 Jan 2012 13:50:17 +1100 Subject: [PATCH 1/2] Fix obvious inconsistencies in SegmentQuery, but it's still broken. --- cp.js | 24 ++++++++++++------------ cp.min.js | 4 ++-- lib/cpBB.js | 6 +++--- lib/cpBBTree.js | 16 ++++++++-------- lib/cpSpaceQuery.js | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cp.js b/cp.js index 0bd268d..edc0239 100644 --- a/cp.js +++ b/cp.js @@ -605,10 +605,10 @@ var bbSegmentQuery = function(bb, a, b) var tymax = max(ty1, ty2); if(tymin <= txmax && txmin <= tymax){ - var min = max(txmin, tymin); - var max = min(txmax, tymax); + var min_ = max(txmin, tymin); + var max_ = min(txmax, tymax); - if(0.0 <= max && min <= 1.0) return max(min, 0.0); + if(0.0 <= max_ && min_ <= 1.0) return max(min_, 0.0); } return Infinity; @@ -2120,10 +2120,10 @@ var bbTreeSegmentQuery = function(node, a, b) var tymax = max(ty1, ty2); if(tymin <= txmax && txmin <= tymax){ - var min = max(txmin, tymin); - var max = min(txmax, tymax); + var min_ = max(txmin, tymin); + var max_ = min(txmax, tymax); - if(0.0 <= max && min <= 1.0) return max(min, 0.0); + if(0.0 <= max_ && min_ <= 1.0) return max(min_, 0.0); } return Infinity; @@ -2138,11 +2138,11 @@ var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) var t_b = bbTreeSegmentQuery(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, data)); - if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func, data)); + 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)); } else { - if(t_b < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.B, a, b, t_exit, func, data)); - if(t_a < t_exit) t_exit = min(t_exit, subtreeSegmentQuery(subtree.A, a, b, t_exit, func, data)); + 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; @@ -2367,7 +2367,7 @@ BBTree.prototype.pointQuery = function(point, func) BBTree.prototype.segmentQuery = function(a, b, t_exit, func) { - if(this.root) subtreeSegmentQuery(this, a, b, t_exit, func); + if(this.root) subtreeSegmentQuery(this.root, a, b, t_exit, func); }; BBTree.prototype.query = function(bb, func) @@ -4227,7 +4227,7 @@ Space.prototype.segmentQuery = function(start, end, layers, group, func) /// Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns null if no shapes were hit. Space.prototype.segmentQueryFirst = function(start, end, layers, group) { - var out = null; + var out = new SegmentQueryInfo(null, 1, vzero); var helper = function(shape){ var info; diff --git a/cp.min.js b/cp.min.js index 47161b9..f3014db 100644 --- a/cp.min.js +++ b/cp.min.js @@ -1,2 +1,2 @@ -(function(){Object.create=Object.create||function(a){function b(){}return b.prototype=a,new b};if(typeof a=="undefined")var a={};typeof window=="object"&&(window.cp=a);var b=function(a,b){if(!a)throw new Error("Assertion failed: "+b)},c=function(a,b){!a&&console&&console.warn&&console.warn("ASSERTION FAILED: "+b)},d=function(a,b){return a+" "+b},e=function(a,b){return ab?a:b},g,h;typeof window=="object"&&window.navigator.userAgent.indexOf("Firefox")>-1?(g=Math.min,h=Math.max):(g=e,h=f);var i=function(a,b){for(var c=0;cb*b?I(S(a),b):a},V=a.v.lerpconst=function(a,b,c){return F(a,U(G(b,a),c))},W=a.v.dist=function(a,b){return D(G(a,b))},X=a.v.distsq=function(a,b){return Q(G(a,b))},Y=a.v.near=function(a,b,c){return X(a,b)=b.r&&a.b<=b.b&&a.t>=b.t},bi=function(a,b){return a.l<=b.x&&a.r>=b.x&&a.b<=b.y&&a.t>=b.y},bj=function(a,b,c,d,e){return a<=e.x&&c>=e.x&&b<=e.y&&d>=e.y},bk=function(a,b){return new bd(g(a.l,b.l),g(a.b,b.b),h(a.r,b.r),h(a.t,b.t))},bl=function(a,b){return new bd(g(a.l,b.x),g(a.b,b.y),h(a.r,b.x),h(a.t,b.y))},bm=function(a){return(a.r-a.l)*(a.t-a.b)},bn=function(a,b){return(h(a.r,b.r)-g(a.l,b.l))*(h(a.t,b.t)-g(a.b,b.b))},bo=function(a,b,c,d,e){return(h(a.r,d)-g(a.l,b))*(h(a.t,e)-g(a.b,c))},bp=function(a,b,c){var d=1/(c.x-b.x),e=a.l==b.x?-Infinity:(a.l-b.x)*d,f=a.r==b.x?Infinity:(a.r-b.x)*d,g=n(e,f),h=o(e,f),i=1/(c.y-b.y),j=a.b==b.y?-Infinity:(a.b-b.y)*i,k=a.t==b.y?Infinity:(a.t-b.y)*i,l=n(j,k),m=o(j,k);if(l<=h&&g<=m){var n=o(g,l),o=n(h,m);if(0<=o&&n<=1)return o(n,0)}return Infinity},bq=function(a,b,c){return bp(a,b,c)!=Infinity},br=function(a,b){var c=g(h(a.l,b.x),a.r),d=g(h(a.b,b.y),a.t);return new z(c,d)},bs=function(a,b){var c=Math.abs(a.r-a.l),d=(b.x-a.l)%c,e=d>0?d:d+c,f=Math.abs(a.t-a.b),g=(b.y-a.b)%f,h=g>0?g:g+f;return new z(e+a.l,h+a.b)},bt=0,bu=0,bv=-1;a.resetShapeIdCounter=function(){bt=0};var bw=a.Shape=function(a){this.body=a,this.bb_l=this.bb_b=this.bb_r=this.bb_t=0,this.hashid=bt++,this.sensor=!1,this.e=0,this.u=0,this.surface_v=A,this.collision_type=0,this.group=0,this.layers=bv,this.space=null,this.collisionCode=this.collisionCode};bw.prototype.setElasticity=function(a){this.e=a},bw.prototype.setFriction=function(a){this.body.activate(),this.u=a},bw.prototype.setLayers=function(a){this.body.activate(),this.layers=a},bw.prototype.active=function(){return this.prev||this.body.shapeList.length>0&&this.body.shapeList[0]===this},bw.prototype.setBody=function(a){b(!this.active(),"You cannot change the body on an active shape. You must remove the shape, then "),this.body=a},bw.prototype.cacheBB=function(){return this.update(this.body.p,this.body.rot)},bw.prototype.update=function(a,c){b(!isNaN(c.x),"Rotation is NaN"),b(!isNaN(a.x),"Position is NaN"),this.cacheData(a,c)};var bx=function(a){this.shape=a,this.d=Infinity,this.n=A},by=function(a,b,c){this.shape=a,this.t=b,this.n=c},bz=a.CircleShape=function(a,b,c){this.c=this.tc=c,this.r=b,this.type="circle",bw.call(this,a)};bz.prototype=Object.create(bw.prototype),bz.prototype.cacheData=function(a,b){var c=this.tc=O(this.c,b).add(a),d=this.r;this.bb_l=c.x-d,this.bb_b=c.y-d,this.bb_r=c.x+d,this.bb_t=c.y+d},bz.prototype.pointQuery=function(a){var b=G(a,this.tc),c=Q(b),d=this.r;if(c=0){var k=(-h-Math.sqrt(j))/(2*g);if(0<=k&&k<=1)return new by(a,k,S(R(d,e,k)))}};bz.prototype.segmentQuery=function(a,b){return bA(this,this.tc,this.r,a,b)};var bB=a.SegmentShape=function(a,b,c,d){this.a=b,this.b=c,this.n=L(S(G(c,b))),this.ta=this.tb=this.tn=null,this.r=d,this.a_tangent=A,this.b_tangent=A,this.type="segment",bw.call(this,a)};bB.prototype=Object.create(bw.prototype),bB.prototype.cacheData=function(a,b){this.ta=F(a,O(this.a,b)),this.tb=F(a,O(this.b,b)),this.tn=O(this.n,b);var c,d,e,f;this.ta.x0?H(c):c,g=G(I(f,e),a),h=F(this.ta,g),i=F(this.tb,g),j=G(b,a);if(J(j,h)*J(j,i)<=0){var k=d+(d>0?-e:e),l=-k,m=B(j,c)-k;if(l*m<0)return{shape:this,t:l/(l-m),n:f}}else if(e!=0){var n=bA(this,this.ta,this.r,a,b),o=bA(this,this.tb,this.r,a,b);return n?o&&o.t0)return!1}return!0},bD=a.PolyShape=function(a,c,d){b(c.length>=4,"Polygons require some verts"),b(typeof c[0]=="number","Polygon verticies should be specified in a flattened list"),b(bC(c),"Polygon is concave or has a reversed winding."),this.setVerts(c,d),this.type="poly",bw.call(this,a)};bD.prototype=Object.create(bw.prototype);var bE=function(a,b){this.n=a,this.d=b};bD.prototype.setVerts=function(a,b){var c=a.length,d=c>>1;this.verts=new Array(c),this.tVerts=new Array(c),this.axes=new Array(d),this.tAxes=new Array(d);for(var e=0;e>1]=new bE(j,C(j.x,j.y,f,g)),this.tAxes[e>>1]=new bE(new z(0,0),0)}};var bF=a.BoxShape=function(a,b,c){var d=b/2,e=c/2;return bG(a,new bd(-d,-e,d,e))},bG=a.BoxShape2=function(a,b){var c=[b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b];return new bD(a,c,A)};bD.prototype.transformVerts=function(a,b){var c=this.verts,d=this.tVerts,e=Infinity,f=-Infinity,i=Infinity,j=-Infinity;for(var k=0;ki)continue;var j=B(b,h),k=(c[g].d-i)/(j-i);if(k<0||10)return!1}return!0},bD.prototype.containsVertPartial=function(a,b,c){var d=this.tAxes;for(var e=0;e0)return!1}return!0};var bH=a.Body=function(a,b){bH.prototype.velocity_func=bH.prototype.updateVelocity,bH.prototype.position_func=bH.prototype.updatePosition,this.p=new z(0,0),this.vx=this.vy=0,this.f=new z(0,0),this.w=0,this.t=0,this.v_limit=Infinity,this.w_limit=Infinity,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(a),this.setMoment(b),this.rot=new z(0,0),this.setAngle(0)},bI=function(){return body=new bH(Infinity,Infinity),body.nodeIdleTime=Infinity,body};if(typeof DEBUG!="undefined"&&DEBUG){var bJ=function(a,c){b(a.x==a.x&&a.y==a.y,c)},bK=function(a,c){b(Math.abs(a.x)!==Infinity&&Math.abs(a.y)!==Infinity,c)},bL=function(a,b){bJ(a,b),bK(a,b)};bH.prototype.sanityCheck=function(){b(this.m===this.m&&this.m_inv===this.m_inv,"Body's mass is invalid."),b(this.i===this.i&&this.i_inv===this.i_inv,"Body's moment is invalid."),bL(this.p,"Body's position is invalid."),bL(this.f,"Body's force is invalid."),b(this.vx===this.vx&&Math.abs(this.vx)!==Infinity,"Body's velocity is invalid."),b(this.vy===this.vy&&Math.abs(this.vy)!==Infinity,"Body's velocity is invalid."),b(this.a===this.a&&Math.abs(this.a)!==Infinity,"Body's angle is invalid."),b(this.w===this.w&&Math.abs(this.w)!==Infinity,"Body's angular velocity is invalid."),b(this.t===this.t&&Math.abs(this.t)!==Infinity,"Body's torque is invalid."),bL(this.rot,"Internal error: Body's rotation vector is invalid."),b(this.v_limit===this.v_limit,"Body's velocity limit is invalid."),b(this.w_limit===this.w_limit,"Body's angular velocity limit is invalid.")}}else bH.prototype.sanityCheck=function(){};bH.prototype.isSleeping=function(){return this.nodeRoot!==null},bH.prototype.isStatic=function(){return this.nodeIdleTime===Infinity},bH.prototype.isRogue=function(){return this.space===null},bH.prototype.setMass=function(a){b(a>0,"Mass must be positive and non-zero."),this.activate(),this.m=a,this.m_inv=1/a},bH.prototype.setMoment=function(a){b(a>0,"Moment of Inertia must be positive and non-zero."),this.activate(),this.i=a,this.i_inv=1/a},bH.prototype.addShape=function(a){this.shapeList.push(a)},bH.prototype.removeShape=function(a){i(this.shapeList,a)};var bM=function(a,b,c){return a==c?a.next(b):(a.a===b?a.next_a=bM(a.next_a,b,c):a.next_b=bM(a.next_b,b,c),a)};bH.prototype.removeConstraint=function(a){this.constraintList=bM(this.constraintList,this,a)},bH.prototype.setPos=function(a){this.activate(),this.sanityCheck(),this.p=a},bH.prototype.setVelocity=function(a){this.activate(),this.vx=a.x,this.vy=a.y},bH.prototype.setAngleInternal=function(a){b(!isNaN(a),"Internal Error: Attempting to set body's angle to NaN"),this.a=a,this.rot.x=Math.cos(a),this.rot.y=Math.sin(a)},bH.prototype.setAngle=function(a){this.activate(),this.sanityCheck(),this.setAngleInternal(a)},bH.prototype.updateVelocity=function(a,b,c){var d=this.vx*b+(a.x+this.f.x*this.m_inv)*c,e=this.vy*b+(a.y+this.f.y*this.m_inv)*c,f=this.v_limit,g=d*d+e*e,h=g>f*f?f/Math.sqrt(len):1;this.vx=d*h,this.vy=e*h;var i=this.w_limit;this.w=t(this.w*b+this.t*this.i_inv*c,-i,i),this.sanityCheck()},bH.prototype.updatePosition=function(a){this.p.x+=(this.vx+this.v_biasx)*a,this.p.y+=(this.vy+this.v_biasy)*a,this.setAngleInternal(this.a+(this.w+this.w_bias)*a),this.v_biasx=this.v_biasy=0,this.w_bias=0,this.sanityCheck()},bH.prototype.resetForces=function(){this.activate(),this.f=new z(0,0),this.t=0},bH.prototype.applyForce=function(a,b){this.activate(),this.f=F(this.f,a),this.t+=J(b,a)},bH.prototype.applyImpulse=function(a,b){this.activate(),cR(this,a.x,a.y,b)},bH.prototype.getVelAtPoint=function(a){return F(new z(this.vx,this.vy),I(L(a),body.w))},bH.prototype.getVelAtWorldPoint=function(a){return this.getVelAtPoint(G(a,body.p))},bH.prototype.getVelAtLocalPoint=function(a){return this.getVelAtPoint(O(a,body.rot))},bH.prototype.eachShape=function(a){for(var b=0,c=this.shapeList.length;b0){var c=a.query;this.each(function(a){c(a,new bd(a.bb_l,a.bb_b,a.bb_r,a.bb_t),b)})}};var bO=a.BBTree=function(a){bN.call(this,a),this.velocityFunc=null,this.leaves={},this.count=0,this.root=null,this.stamp=0};bO.prototype=Object.create(bN.prototype);var bP=0,bQ=function(a,b,c){this.obj=null,this.bb_l=g(b.bb_l,c.bb_l),this.bb_b=g(b.bb_b,c.bb_b),this.bb_r=h(b.bb_r,c.bb_r),this.bb_t=h(b.bb_t,c.bb_t),this.parent=null,this.setA(b),this.setB(c),bP++},bR=0,bS=function(a,b){this.obj=b,a.getBB(b,this),this.parent=null,this.stamp=1,this.pairs=null,bR++};bO.prototype.getBB=function(a,b){var c=this.velocityFunc;if(c){var d=.1,e=(a.bb_r-a.bb_l)*d,f=(a.bb_t-a.bb_b)*d,i=I(c(a),.1);b.bb_l=a.bb_l+g(-e,i.x),b.bb_b=a.bb_b+g(-f,i.y),b.bb_r=a.bb_r+h(e,i.x),b.bb_t=a.bb_t+h(f,i.y)}else b.bb_l=a.bb_l,b.bb_b=a.bb_b,b.bb_r=a.bb_r,b.bb_t=a.bb_t},bO.prototype.getStamp=function(){var a=this.dynamicIndex;return a&&a.stamp?a.stamp:this.stamp},bO.prototype.incrementStamp=function(){this.dynamicIndex&&this.dynamicIndex.stamp?this.dynamicIndex.stamp++:this.stamp++};var bT=function(a,b){this.a=a,this.b=b},bU=function(a,b){this.prev=null,this.next=b,this.leaf=a};bU.prototype.unlink=function(){var a=this.next,b=this.prev;a&&(a.a.leaf==this.leaf?a.a.prev=b:a.b.prev=b),b?b.a.leaf==this.leaf?b.a.next=a:b.b.next=a:this.leaf.pairs=a},bS.prototype.clearPairs=function(a){var b=this.pairs,c;this.pairs=null;while(b)b.a.leaf==this?(c=b.a.next,b.b.unlink(),b=c):(c=b.b.next,b.a.unlink(),b=c)};var bV=function(a,b,c){var d=a.pairs,e=b.pairs,f=new bT(new bU(a,d),new bU(b,e));a.pairs=b.pairs=f,d&&(d.a.leaf==a?d.a.prev=f:d.b.prev=f),e&&(e.a.leaf==b?e.a.prev=f:e.b.prev=f)};bQ.prototype.setA=function(a){this.A=a,a.parent=this},bQ.prototype.setB=function(a){this.B=a,a.parent=this},bS.prototype.isLeaf=!0,bQ.prototype.isLeaf=!1,bQ.prototype.otherChild=function(a){return this.A==a?this.B:this.A},bQ.prototype.replaceChild=function(a,b,d){c(a==this.A||a==this.B,"Node is not a child of parent."),this.A==a?this.setA(b):this.setB(b);for(var e=this;e;e=e.parent){var f=e.A,i=e.B;e.bb_l=g(f.bb_l,i.bb_l),e.bb_b=g(f.bb_b,i.bb_b),e.bb_r=h(f.bb_r,i.bb_r),e.bb_t=h(f.bb_t,i.bb_t)}},bQ.prototype.bbArea=bS.prototype.bbArea=function(){return(this.bb_r-this.bb_l)*(this.bb_t-this.bb_b)};var bW=function(a,b){return(h(a.bb_r,b.bb_r)-g(a.bb_l,b.bb_l))*(h(a.bb_t,b.bb_t)-g(a.bb_b,b.bb_b))},bX=function(a,b){return Math.abs(a.bb_l+a.bb_r-b.bb_l-b.bb_r)+Math.abs(a.bb_b+b.bb_t-b.bb_b-b.bb_t)},bY=function(a,b,c){if(a==null)return b;if(a.isLeaf)return new bQ(c,b,a);var d=a.B.bbArea()+bW(a.A,b),e=a.A.bbArea()+bW(a.B,b);return d===e&&(d=bX(a.A,b),e=bX(a.B,b)),e=a.bb_r&&this.bb_b<=a.bb_b&&this.bb_t>=a.bb_t},bS.prototype.update=function(a){var b=a.root,c=this.obj;return this.containsObj(c)?!1:(a.getBB(this.obj,this),b=ca(b,this,a),a.root=bY(b,this,a),this.clearPairs(a),this.stamp=a.getStamp(),!0)},bS.prototype.addPairs=function(a){var b=a.dynamicIndex;if(b){var c=b.root;c&&cc(c,this,!0,b,null)}else{var d=a.staticIndex.root;cd(this,a,d,null)}},bO.prototype.insert=function(a,b){var c=new bS(this,a);this.leaves[b]=c,this.root=bY(this.root,c,this),this.count++,c.stamp=this.getStamp(),c.addPairs(this),this.incrementStamp()},bO.prototype.remove=function(a,b){var c=this.leaves[b];delete this.leaves[b],this.root=ca(this.root,c,this),this.count--,c.clearPairs(this)},bO.prototype.contains=function(a,b){return this.leaves[b]!=null};var cf=function(a,b){};bO.prototype.reindexQuery=function(a){if(!this.root)return;var b,c=this.leaves;for(b in c)c[b].update(this);var d=this.staticIndex,e=d&&d.root;ce(this.root,this,e,a),d&&!e&&this.collideStatic(this,d,a),this.incrementStamp()},bO.prototype.reindex=function(){this.reindexQuery(cf)},bO.prototype.reindexObject=function(a,b){var c=this.leaves[b];c&&(c.update(this)&&c.addPairs(this),this.incrementStamp())},bO.prototype.pointQuery=function(a,b){this.root&&bZ(this.root,new bd(a.x,a.y,a.x,a.y),b)},bO.prototype.segmentQuery=function(a,b,c,d){this.root&&b_(this,a,b,c,d)},bO.prototype.query=function(a,b){this.root&&bZ(this.root,a,b)},bO.prototype.count=function(){return this.count},bO.prototype.each=function(a){var b;for(b in this.leaves)a(this.leaves[b].obj)};var cg=function(a,b,c,d,e){return(h(a.bb_r,d)-g(a.bb_l,b))*(h(a.bb_t,e)-g(a.bb_b,c))},ch=function(a,b,c,d){if(d==1)return b[c];if(d==2)return new bQ(a,b[c],b[c+1]);var e=b[c],f=e.bb_l,i=e.bb_b,j=e.bb_r,k=e.bb_t,l=c+d;for(var m=c+1;mk-i,o=new Array(d*2);if(n)for(var m=c;m=e*e)return;var h=Math.sqrt(g);return new cr(F(a,I(f,.5+(c-.5*e)/(h?h:Infinity))),h?I(f,1/h):new z(1,0),h-e,0)},cu=function(a,b){var c=ct(a.tc,b.tc,a.r,b.r);return c?[c]:cs},cv=function(a,b){var c=b.ta,d=b.tb,e=a.tc,f=G(d,c),g=u(B(f,G(e,c))/Q(f)),h=F(c,I(f,g)),i=ct(e,h,a.r,b.r);if(i){var j=i.n;return g===0&&B(j,b.a_tangent)<0||g===1&&B(j,b.b_tangent)<0?cs:[i]}return cs},cw=0,cx=function(a,b){var c=0,d=a.valueOnAxis(b[0].n,b[0].d);if(d>0)return-1;for(var e=1;e0)return-1;f>d&&(d=f,c=e)}return cw=d,c},cy=function(a,b,c,e){var f=[],g=a.tVerts;for(var h=0;h>1)))}var k=b.tVerts;for(var h=0;h>1)))}return f.length?f:cy(a,b,c,e)},cA=function(a,b){var c=cx(b,a.tAxes);if(c==-1)return cs;var d=cw,e=cx(a,b.tAxes);if(e==-1)return cs;var f=cw;return d>f?cz(a,b,a.tAxes[c].n,d):cz(a,b,H(b.tAxes[e].n),f)},cB=function(a,b,c){var d=B(b,a.ta)-a.r,e=B(b,a.tb)-a.r;return g(d,e)-c},cC=function(a,b,c,e,f){var g=J(b.tn,b.ta),h=J(b.tn,b.tb),i=I(b.tn,f),j=c.tVerts;for(var k=0;k=n&&n>=h&&a.push(new cr(new z(l,m),i,e,d(c.hashid,k)))}}},cD=function(a,b){var c=[],e=b.tAxes,f=e.length,g=B(a.tn,a.ta),h=b.valueOnAxis(a.tn,g)-a.r,i=b.valueOnAxis(H(a.tn),-g)-a.r;if(i>0||h>0)return cs;var j=0,k=cB(a,e[0].n,e[0].d);if(k>0)return cs;for(var l=0;l0)return cs;m>k&&(k=m,j=l)}var n=H(e[j].n),o=F(a.ta,I(n,a.r)),p=F(a.tb,I(n,a.r));b.containsVert(o.x,o.y)&&c.push(new cr(o,n,k,d(a.hashid,0))),b.containsVert(p.x,p.y)&&c.push(new cr(p,n,k,d(a.hashid,1)));if(h>=k||i>=k)h>i?cC(c,a,b,h,1):cC(c,a,b,i,-1);if(c.length===0){var q=j*2,r=b.tVerts,s=new z(r[q],r[q+1]),t;if(t=ct(a.ta,s,a.r,0,c))return[t];if(t=ct(a.tb,s,a.r,0,c))return[t];var u=f*2,v=new z(r[(q+2)%u],r[(q+3)%u]);if(t=ct(a.ta,v,a.r,0,c))return[t];if(t=ct(a.tb,v,a.r,0,c))return[t]}return c},cE=function(a,b){var c=b.tAxes,d=0,e=B(c[0].n,a.tc)-c[0].d-a.r;for(var f=0;f0)return cs;g>e&&(e=g,d=f)}var h=c[d].n,i=b.tVerts,j=i.length,k=d<<1,l=i[k],m=i[k+1],n=i[(k+2)%j],o=i[(k+3)%j],p=K(h.x,h.y,l,m),q=K(h.x,h.y,n,o),r=J(h,a.tc);if(rh?0:g.nodeIdleTime+a,c(g.nodeNext===null,"Internal Error: Dangling next pointer detected in contact graph."),c(g.nodeRoot===null,"Internal Error: Dangling root pointer detected in contact graph.")}var i=this.arbiters;for(var f=0,j=i.length;f=0,"Internal Error: Space lock underflow.");if(!this.locked&&a){var c=this.rousedBodies;for(var d=0;dc.collisionCode){var h=b;b=c,c=h}var i=cF(b,c);if(i.length===0)return;var j=d(b.hashid,c.hashid),k=e.cachedArbiters[j];k||(k=e.cachedArbiters[j]=new cl(b,c)),k.update(i,f,b,c),k.state=="first coll"&&!f.begin(k,e)&&k.ignore(),k.state!=="ignore"&&f.preSolve(k,e)&&!g?e.arbiters.push(k):(k.contacts=null,k.state!=="ignore"&&(k.state="normal")),k.stamp=e.stamp}},cH.prototype.arbiterSetFilter=function(a){var b=this.stamp-a.stamp,c=a.body_a,d=a.body_b;return(c.isStatic()||c.isSleeping())&&(d.isStatic()||d.isSleeping())?!0:(b>=1&&a.state!="cached"&&(a.callSeparate(this),a.state="cached"),b>=this.collisionPersistence?(a.contacts=null,!1):!0)};var cO=function(a){var b=a.body;a.update(b.p,b.rot)};cH.prototype.step=function(a){if(a===0)return;b(A.x===0&&A.y===0,"vzero is invalid"),this.stamp++;var c=this.curr_dt;this.curr_dt=a;var d=this.bodies,e=this.constraints,f=this.arbiters;for(var g=0;gb?a:b},g,h;typeof window=="object"&&window.navigator.userAgent.indexOf("Firefox")>-1?(g=Math.min,h=Math.max):(g=e,h=f);var i=function(a,b){for(var c=0;cb*b?I(S(a),b):a},V=a.v.lerpconst=function(a,b,c){return F(a,U(G(b,a),c))},W=a.v.dist=function(a,b){return D(G(a,b))},X=a.v.distsq=function(a,b){return Q(G(a,b))},Y=a.v.near=function(a,b,c){return X(a,b)=b.r&&a.b<=b.b&&a.t>=b.t},bi=function(a,b){return a.l<=b.x&&a.r>=b.x&&a.b<=b.y&&a.t>=b.y},bj=function(a,b,c,d,e){return a<=e.x&&c>=e.x&&b<=e.y&&d>=e.y},bk=function(a,b){return new bd(g(a.l,b.l),g(a.b,b.b),h(a.r,b.r),h(a.t,b.t))},bl=function(a,b){return new bd(g(a.l,b.x),g(a.b,b.y),h(a.r,b.x),h(a.t,b.y))},bm=function(a){return(a.r-a.l)*(a.t-a.b)},bn=function(a,b){return(h(a.r,b.r)-g(a.l,b.l))*(h(a.t,b.t)-g(a.b,b.b))},bo=function(a,b,c,d,e){return(h(a.r,d)-g(a.l,b))*(h(a.t,e)-g(a.b,c))},bp=function(a,b,c){var d=1/(c.x-b.x),e=a.l==b.x?-Infinity:(a.l-b.x)*d,f=a.r==b.x?Infinity:(a.r-b.x)*d,i=g(e,f),j=h(e,f),k=1/(c.y-b.y),l=a.b==b.y?-Infinity:(a.b-b.y)*k,m=a.t==b.y?Infinity:(a.t-b.y)*k,n=g(l,m),o=h(l,m);if(n<=j&&i<=o){var p=h(i,n),q=g(j,o);if(0<=q&&p<=1)return h(p,0)}return Infinity},bq=function(a,b,c){return bp(a,b,c)!=Infinity},br=function(a,b){var c=g(h(a.l,b.x),a.r),d=g(h(a.b,b.y),a.t);return new z(c,d)},bs=function(a,b){var c=Math.abs(a.r-a.l),d=(b.x-a.l)%c,e=d>0?d:d+c,f=Math.abs(a.t-a.b),g=(b.y-a.b)%f,h=g>0?g:g+f;return new z(e+a.l,h+a.b)},bt=0,bu=0,bv=-1;a.resetShapeIdCounter=function(){bt=0};var bw=a.Shape=function(a){this.body=a,this.bb_l=this.bb_b=this.bb_r=this.bb_t=0,this.hashid=bt++,this.sensor=!1,this.e=0,this.u=0,this.surface_v=A,this.collision_type=0,this.group=0,this.layers=bv,this.space=null,this.collisionCode=this.collisionCode};bw.prototype.setElasticity=function(a){this.e=a},bw.prototype.setFriction=function(a){this.body.activate(),this.u=a},bw.prototype.setLayers=function(a){this.body.activate(),this.layers=a},bw.prototype.active=function(){return this.prev||this.body.shapeList.length>0&&this.body.shapeList[0]===this},bw.prototype.setBody=function(a){b(!this.active(),"You cannot change the body on an active shape. You must remove the shape, then "),this.body=a},bw.prototype.cacheBB=function(){return this.update(this.body.p,this.body.rot)},bw.prototype.update=function(a,c){b(!isNaN(c.x),"Rotation is NaN"),b(!isNaN(a.x),"Position is NaN"),this.cacheData(a,c)};var bx=function(a){this.shape=a,this.d=Infinity,this.n=A},by=function(a,b,c){this.shape=a,this.t=b,this.n=c},bz=a.CircleShape=function(a,b,c){this.c=this.tc=c,this.r=b,this.type="circle",bw.call(this,a)};bz.prototype=Object.create(bw.prototype),bz.prototype.cacheData=function(a,b){var c=this.tc=O(this.c,b).add(a),d=this.r;this.bb_l=c.x-d,this.bb_b=c.y-d,this.bb_r=c.x+d,this.bb_t=c.y+d},bz.prototype.pointQuery=function(a){var b=G(a,this.tc),c=Q(b),d=this.r;if(c=0){var k=(-h-Math.sqrt(j))/(2*g);if(0<=k&&k<=1)return new by(a,k,S(R(d,e,k)))}};bz.prototype.segmentQuery=function(a,b){return bA(this,this.tc,this.r,a,b)};var bB=a.SegmentShape=function(a,b,c,d){this.a=b,this.b=c,this.n=L(S(G(c,b))),this.ta=this.tb=this.tn=null,this.r=d,this.a_tangent=A,this.b_tangent=A,this.type="segment",bw.call(this,a)};bB.prototype=Object.create(bw.prototype),bB.prototype.cacheData=function(a,b){this.ta=F(a,O(this.a,b)),this.tb=F(a,O(this.b,b)),this.tn=O(this.n,b);var c,d,e,f;this.ta.x0?H(c):c,g=G(I(f,e),a),h=F(this.ta,g),i=F(this.tb,g),j=G(b,a);if(J(j,h)*J(j,i)<=0){var k=d+(d>0?-e:e),l=-k,m=B(j,c)-k;if(l*m<0)return{shape:this,t:l/(l-m),n:f}}else if(e!=0){var n=bA(this,this.ta,this.r,a,b),o=bA(this,this.tb,this.r,a,b);return n?o&&o.t0)return!1}return!0},bD=a.PolyShape=function(a,c,d){b(c.length>=4,"Polygons require some verts"),b(typeof c[0]=="number","Polygon verticies should be specified in a flattened list"),b(bC(c),"Polygon is concave or has a reversed winding."),this.setVerts(c,d),this.type="poly",bw.call(this,a)};bD.prototype=Object.create(bw.prototype);var bE=function(a,b){this.n=a,this.d=b};bD.prototype.setVerts=function(a,b){var c=a.length,d=c>>1;this.verts=new Array(c),this.tVerts=new Array(c),this.axes=new Array(d),this.tAxes=new Array(d);for(var e=0;e>1]=new bE(j,C(j.x,j.y,f,g)),this.tAxes[e>>1]=new bE(new z(0,0),0)}};var bF=a.BoxShape=function(a,b,c){var d=b/2,e=c/2;return bG(a,new bd(-d,-e,d,e))},bG=a.BoxShape2=function(a,b){var c=[b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b];return new bD(a,c,A)};bD.prototype.transformVerts=function(a,b){var c=this.verts,d=this.tVerts,e=Infinity,f=-Infinity,i=Infinity,j=-Infinity;for(var k=0;ki)continue;var j=B(b,h),k=(c[g].d-i)/(j-i);if(k<0||10)return!1}return!0},bD.prototype.containsVertPartial=function(a,b,c){var d=this.tAxes;for(var e=0;e0)return!1}return!0};var bH=a.Body=function(a,b){bH.prototype.velocity_func=bH.prototype.updateVelocity,bH.prototype.position_func=bH.prototype.updatePosition,this.p=new z(0,0),this.vx=this.vy=0,this.f=new z(0,0),this.w=0,this.t=0,this.v_limit=Infinity,this.w_limit=Infinity,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(a),this.setMoment(b),this.rot=new z(0,0),this.setAngle(0)},bI=function(){return body=new bH(Infinity,Infinity),body.nodeIdleTime=Infinity,body};if(typeof DEBUG!="undefined"&&DEBUG){var bJ=function(a,c){b(a.x==a.x&&a.y==a.y,c)},bK=function(a,c){b(Math.abs(a.x)!==Infinity&&Math.abs(a.y)!==Infinity,c)},bL=function(a,b){bJ(a,b),bK(a,b)};bH.prototype.sanityCheck=function(){b(this.m===this.m&&this.m_inv===this.m_inv,"Body's mass is invalid."),b(this.i===this.i&&this.i_inv===this.i_inv,"Body's moment is invalid."),bL(this.p,"Body's position is invalid."),bL(this.f,"Body's force is invalid."),b(this.vx===this.vx&&Math.abs(this.vx)!==Infinity,"Body's velocity is invalid."),b(this.vy===this.vy&&Math.abs(this.vy)!==Infinity,"Body's velocity is invalid."),b(this.a===this.a&&Math.abs(this.a)!==Infinity,"Body's angle is invalid."),b(this.w===this.w&&Math.abs(this.w)!==Infinity,"Body's angular velocity is invalid."),b(this.t===this.t&&Math.abs(this.t)!==Infinity,"Body's torque is invalid."),bL(this.rot,"Internal error: Body's rotation vector is invalid."),b(this.v_limit===this.v_limit,"Body's velocity limit is invalid."),b(this.w_limit===this.w_limit,"Body's angular velocity limit is invalid.")}}else bH.prototype.sanityCheck=function(){};bH.prototype.isSleeping=function(){return this.nodeRoot!==null},bH.prototype.isStatic=function(){return this.nodeIdleTime===Infinity},bH.prototype.isRogue=function(){return this.space===null},bH.prototype.setMass=function(a){b(a>0,"Mass must be positive and non-zero."),this.activate(),this.m=a,this.m_inv=1/a},bH.prototype.setMoment=function(a){b(a>0,"Moment of Inertia must be positive and non-zero."),this.activate(),this.i=a,this.i_inv=1/a},bH.prototype.addShape=function(a){this.shapeList.push(a)},bH.prototype.removeShape=function(a){i(this.shapeList,a)};var bM=function(a,b,c){return a==c?a.next(b):(a.a===b?a.next_a=bM(a.next_a,b,c):a.next_b=bM(a.next_b,b,c),a)};bH.prototype.removeConstraint=function(a){this.constraintList=bM(this.constraintList,this,a)},bH.prototype.setPos=function(a){this.activate(),this.sanityCheck(),this.p=a},bH.prototype.setVelocity=function(a){this.activate(),this.vx=a.x,this.vy=a.y},bH.prototype.setAngleInternal=function(a){b(!isNaN(a),"Internal Error: Attempting to set body's angle to NaN"),this.a=a,this.rot.x=Math.cos(a),this.rot.y=Math.sin(a)},bH.prototype.setAngle=function(a){this.activate(),this.sanityCheck(),this.setAngleInternal(a)},bH.prototype.updateVelocity=function(a,b,c){var d=this.vx*b+(a.x+this.f.x*this.m_inv)*c,e=this.vy*b+(a.y+this.f.y*this.m_inv)*c,f=this.v_limit,g=d*d+e*e,h=g>f*f?f/Math.sqrt(len):1;this.vx=d*h,this.vy=e*h;var i=this.w_limit;this.w=t(this.w*b+this.t*this.i_inv*c,-i,i),this.sanityCheck()},bH.prototype.updatePosition=function(a){this.p.x+=(this.vx+this.v_biasx)*a,this.p.y+=(this.vy+this.v_biasy)*a,this.setAngleInternal(this.a+(this.w+this.w_bias)*a),this.v_biasx=this.v_biasy=0,this.w_bias=0,this.sanityCheck()},bH.prototype.resetForces=function(){this.activate(),this.f=new z(0,0),this.t=0},bH.prototype.applyForce=function(a,b){this.activate(),this.f=F(this.f,a),this.t+=J(b,a)},bH.prototype.applyImpulse=function(a,b){this.activate(),cR(this,a.x,a.y,b)},bH.prototype.getVelAtPoint=function(a){return F(new z(this.vx,this.vy),I(L(a),body.w))},bH.prototype.getVelAtWorldPoint=function(a){return this.getVelAtPoint(G(a,body.p))},bH.prototype.getVelAtLocalPoint=function(a){return this.getVelAtPoint(O(a,body.rot))},bH.prototype.eachShape=function(a){for(var b=0,c=this.shapeList.length;b0){var c=a.query;this.each(function(a){c(a,new bd(a.bb_l,a.bb_b,a.bb_r,a.bb_t),b)})}};var bO=a.BBTree=function(a){bN.call(this,a),this.velocityFunc=null,this.leaves={},this.count=0,this.root=null,this.stamp=0};bO.prototype=Object.create(bN.prototype);var bP=0,bQ=function(a,b,c){this.obj=null,this.bb_l=g(b.bb_l,c.bb_l),this.bb_b=g(b.bb_b,c.bb_b),this.bb_r=h(b.bb_r,c.bb_r),this.bb_t=h(b.bb_t,c.bb_t),this.parent=null,this.setA(b),this.setB(c),bP++},bR=0,bS=function(a,b){this.obj=b,a.getBB(b,this),this.parent=null,this.stamp=1,this.pairs=null,bR++};bO.prototype.getBB=function(a,b){var c=this.velocityFunc;if(c){var d=.1,e=(a.bb_r-a.bb_l)*d,f=(a.bb_t-a.bb_b)*d,i=I(c(a),.1);b.bb_l=a.bb_l+g(-e,i.x),b.bb_b=a.bb_b+g(-f,i.y),b.bb_r=a.bb_r+h(e,i.x),b.bb_t=a.bb_t+h(f,i.y)}else b.bb_l=a.bb_l,b.bb_b=a.bb_b,b.bb_r=a.bb_r,b.bb_t=a.bb_t},bO.prototype.getStamp=function(){var a=this.dynamicIndex;return a&&a.stamp?a.stamp:this.stamp},bO.prototype.incrementStamp=function(){this.dynamicIndex&&this.dynamicIndex.stamp?this.dynamicIndex.stamp++:this.stamp++};var bT=function(a,b){this.a=a,this.b=b},bU=function(a,b){this.prev=null,this.next=b,this.leaf=a};bU.prototype.unlink=function(){var a=this.next,b=this.prev;a&&(a.a.leaf==this.leaf?a.a.prev=b:a.b.prev=b),b?b.a.leaf==this.leaf?b.a.next=a:b.b.next=a:this.leaf.pairs=a},bS.prototype.clearPairs=function(a){var b=this.pairs,c;this.pairs=null;while(b)b.a.leaf==this?(c=b.a.next,b.b.unlink(),b=c):(c=b.b.next,b.a.unlink(),b=c)};var bV=function(a,b,c){var d=a.pairs,e=b.pairs,f=new bT(new bU(a,d),new bU(b,e));a.pairs=b.pairs=f,d&&(d.a.leaf==a?d.a.prev=f:d.b.prev=f),e&&(e.a.leaf==b?e.a.prev=f:e.b.prev=f)};bQ.prototype.setA=function(a){this.A=a,a.parent=this},bQ.prototype.setB=function(a){this.B=a,a.parent=this},bS.prototype.isLeaf=!0,bQ.prototype.isLeaf=!1,bQ.prototype.otherChild=function(a){return this.A==a?this.B:this.A},bQ.prototype.replaceChild=function(a,b,d){c(a==this.A||a==this.B,"Node is not a child of parent."),this.A==a?this.setA(b):this.setB(b);for(var e=this;e;e=e.parent){var f=e.A,i=e.B;e.bb_l=g(f.bb_l,i.bb_l),e.bb_b=g(f.bb_b,i.bb_b),e.bb_r=h(f.bb_r,i.bb_r),e.bb_t=h(f.bb_t,i.bb_t)}},bQ.prototype.bbArea=bS.prototype.bbArea=function(){return(this.bb_r-this.bb_l)*(this.bb_t-this.bb_b)};var bW=function(a,b){return(h(a.bb_r,b.bb_r)-g(a.bb_l,b.bb_l))*(h(a.bb_t,b.bb_t)-g(a.bb_b,b.bb_b))},bX=function(a,b){return Math.abs(a.bb_l+a.bb_r-b.bb_l-b.bb_r)+Math.abs(a.bb_b+b.bb_t-b.bb_b-b.bb_t)},bY=function(a,b,c){if(a==null)return b;if(a.isLeaf)return new bQ(c,b,a);var d=a.B.bbArea()+bW(a.A,b),e=a.A.bbArea()+bW(a.B,b);return d===e&&(d=bX(a.A,b),e=bX(a.B,b)),e=a.bb_r&&this.bb_b<=a.bb_b&&this.bb_t>=a.bb_t},bS.prototype.update=function(a){var b=a.root,c=this.obj;return this.containsObj(c)?!1:(a.getBB(this.obj,this),b=ca(b,this,a),a.root=bY(b,this,a),this.clearPairs(a),this.stamp=a.getStamp(),!0)},bS.prototype.addPairs=function(a){var b=a.dynamicIndex;if(b){var c=b.root;c&&cc(c,this,!0,b,null)}else{var d=a.staticIndex.root;cd(this,a,d,null)}},bO.prototype.insert=function(a,b){var c=new bS(this,a);this.leaves[b]=c,this.root=bY(this.root,c,this),this.count++,c.stamp=this.getStamp(),c.addPairs(this),this.incrementStamp()},bO.prototype.remove=function(a,b){var c=this.leaves[b];delete this.leaves[b],this.root=ca(this.root,c,this),this.count--,c.clearPairs(this)},bO.prototype.contains=function(a,b){return this.leaves[b]!=null};var cf=function(a,b){};bO.prototype.reindexQuery=function(a){if(!this.root)return;var b,c=this.leaves;for(b in c)c[b].update(this);var d=this.staticIndex,e=d&&d.root;ce(this.root,this,e,a),d&&!e&&this.collideStatic(this,d,a),this.incrementStamp()},bO.prototype.reindex=function(){this.reindexQuery(cf)},bO.prototype.reindexObject=function(a,b){var c=this.leaves[b];c&&(c.update(this)&&c.addPairs(this),this.incrementStamp())},bO.prototype.pointQuery=function(a,b){this.root&&bZ(this.root,new bd(a.x,a.y,a.x,a.y),b)},bO.prototype.segmentQuery=function(a,b,c,d){this.root&&b_(this.root,a,b,c,d)},bO.prototype.query=function(a,b){this.root&&bZ(this.root,a,b)},bO.prototype.count=function(){return this.count},bO.prototype.each=function(a){var b;for(b in this.leaves)a(this.leaves[b].obj)};var cg=function(a,b,c,d,e){return(h(a.bb_r,d)-g(a.bb_l,b))*(h(a.bb_t,e)-g(a.bb_b,c))},ch=function(a,b,c,d){if(d==1)return b[c];if(d==2)return new bQ(a,b[c],b[c+1]);var e=b[c],f=e.bb_l,i=e.bb_b,j=e.bb_r,k=e.bb_t,l=c+d;for(var m=c+1;mk-i,o=new Array(d*2);if(n)for(var m=c;m=e*e)return;var h=Math.sqrt(g);return new cr(F(a,I(f,.5+(c-.5*e)/(h?h:Infinity))),h?I(f,1/h):new z(1,0),h-e,0)},cu=function(a,b){var c=ct(a.tc,b.tc,a.r,b.r);return c?[c]:cs},cv=function(a,b){var c=b.ta,d=b.tb,e=a.tc,f=G(d,c),g=u(B(f,G(e,c))/Q(f)),h=F(c,I(f,g)),i=ct(e,h,a.r,b.r);if(i){var j=i.n;return g===0&&B(j,b.a_tangent)<0||g===1&&B(j,b.b_tangent)<0?cs:[i]}return cs},cw=0,cx=function(a,b){var c=0,d=a.valueOnAxis(b[0].n,b[0].d);if(d>0)return-1;for(var e=1;e0)return-1;f>d&&(d=f,c=e)}return cw=d,c},cy=function(a,b,c,e){var f=[],g=a.tVerts;for(var h=0;h>1)))}var k=b.tVerts;for(var h=0;h>1)))}return f.length?f:cy(a,b,c,e)},cA=function(a,b){var c=cx(b,a.tAxes);if(c==-1)return cs;var d=cw,e=cx(a,b.tAxes);if(e==-1)return cs;var f=cw;return d>f?cz(a,b,a.tAxes[c].n,d):cz(a,b,H(b.tAxes[e].n),f)},cB=function(a,b,c){var d=B(b,a.ta)-a.r,e=B(b,a.tb)-a.r;return g(d,e)-c},cC=function(a,b,c,e,f){var g=J(b.tn,b.ta),h=J(b.tn,b.tb),i=I(b.tn,f),j=c.tVerts;for(var k=0;k=n&&n>=h&&a.push(new cr(new z(l,m),i,e,d(c.hashid,k)))}}},cD=function(a,b){var c=[],e=b.tAxes,f=e.length,g=B(a.tn,a.ta),h=b.valueOnAxis(a.tn,g)-a.r,i=b.valueOnAxis(H(a.tn),-g)-a.r;if(i>0||h>0)return cs;var j=0,k=cB(a,e[0].n,e[0].d);if(k>0)return cs;for(var l=0;l0)return cs;m>k&&(k=m,j=l)}var n=H(e[j].n),o=F(a.ta,I(n,a.r)),p=F(a.tb,I(n,a.r));b.containsVert(o.x,o.y)&&c.push(new cr(o,n,k,d(a.hashid,0))),b.containsVert(p.x,p.y)&&c.push(new cr(p,n,k,d(a.hashid,1)));if(h>=k||i>=k)h>i?cC(c,a,b,h,1):cC(c,a,b,i,-1);if(c.length===0){var q=j*2,r=b.tVerts,s=new z(r[q],r[q+1]),t;if(t=ct(a.ta,s,a.r,0,c))return[t];if(t=ct(a.tb,s,a.r,0,c))return[t];var u=f*2,v=new z(r[(q+2)%u],r[(q+3)%u]);if(t=ct(a.ta,v,a.r,0,c))return[t];if(t=ct(a.tb,v,a.r,0,c))return[t]}return c},cE=function(a,b){var c=b.tAxes,d=0,e=B(c[0].n,a.tc)-c[0].d-a.r;for(var f=0;f0)return cs;g>e&&(e=g,d=f)}var h=c[d].n,i=b.tVerts,j=i.length,k=d<<1,l=i[k],m=i[k+1],n=i[(k+2)%j],o=i[(k+3)%j],p=K(h.x,h.y,l,m),q=K(h.x,h.y,n,o),r=J(h,a.tc);if(rh?0:g.nodeIdleTime+a,c(g.nodeNext===null,"Internal Error: Dangling next pointer detected in contact graph."),c(g.nodeRoot===null,"Internal Error: Dangling root pointer detected in contact graph.")}var i=this.arbiters;for(var f=0,j=i.length;f=0,"Internal Error: Space lock underflow.");if(!this.locked&&a){var c=this.rousedBodies;for(var d=0;dc.collisionCode){var h=b;b=c,c=h}var i=cF(b,c);if(i.length===0)return;var j=d(b.hashid,c.hashid),k=e.cachedArbiters[j];k||(k=e.cachedArbiters[j]=new cl(b,c)),k.update(i,f,b,c),k.state=="first coll"&&!f.begin(k,e)&&k.ignore(),k.state!=="ignore"&&f.preSolve(k,e)&&!g?e.arbiters.push(k):(k.contacts=null,k.state!=="ignore"&&(k.state="normal")),k.stamp=e.stamp}},cH.prototype.arbiterSetFilter=function(a){var b=this.stamp-a.stamp,c=a.body_a,d=a.body_b;return(c.isStatic()||c.isSleeping())&&(d.isStatic()||d.isSleeping())?!0:(b>=1&&a.state!="cached"&&(a.callSeparate(this),a.state="cached"),b>=this.collisionPersistence?(a.contacts=null,!1):!0)};var cO=function(a){var b=a.body;a.update(b.p,b.rot)};cH.prototype.step=function(a){if(a===0)return;b(A.x===0&&A.y===0,"vzero is invalid"),this.stamp++;var c=this.curr_dt;this.curr_dt=a;var d=this.bodies,e=this.constraints,f=this.arbiters;for(var g=0;g Date: Mon, 2 Jan 2012 15:38:17 +1100 Subject: [PATCH 2/2] Fix segment-poly query. --- cp.js | 43 +++++++++---------------------------------- cp.min.js | 4 ++-- lib/cpBB.js | 8 ++++---- lib/cpBBTree.js | 29 ++--------------------------- lib/cpPolyShape.js | 6 +++--- 5 files changed, 20 insertions(+), 70 deletions(-) diff --git a/cp.js b/cp.js index edc0239..9ab603b 100644 --- a/cp.js +++ b/cp.js @@ -593,14 +593,14 @@ var bbMergedArea2 = function(bb, l, b, r, t) var bbSegmentQuery = function(bb, a, b) { var idx = 1/(b.x - a.x); - var tx1 = (bb.l == a.x ? -Infinity : (bb.l - a.x)*idx); - var tx2 = (bb.r == a.x ? Infinity : (bb.r - a.x)*idx); + var tx1 = (bb.bb_l == a.x ? -Infinity : (bb.bb_l - a.x)*idx); + var tx2 = (bb.bb_r == a.x ? Infinity : (bb.bb_r - a.x)*idx); var txmin = min(tx1, tx2); var txmax = max(tx1, tx2); var idy = 1/(b.y - a.y); - var ty1 = (bb.b == a.y ? -Infinity : (bb.b - a.y)*idy); - var ty2 = (bb.t == a.y ? Infinity : (bb.t - a.y)*idy); + var ty1 = (bb.bb_b == a.y ? -Infinity : (bb.bb_b - a.y)*idy); + var ty2 = (bb.bb_t == a.y ? Infinity : (bb.bb_t - a.y)*idy); var tymin = min(ty1, ty2); var tymax = max(ty1, ty2); @@ -1226,9 +1226,9 @@ PolyShape.prototype.segmentQuery = function(a, b) var point = vlerp(a, b, t); var dt = -vcross(n, point); - var dtMin = -vcross2(n.x, n.y, verts[i], verts[i+1]); - var dtMax = -vcross2(n.x, n.y, verts[(i+2)%len], verts[(i+3)%len]); - + var dtMin = -vcross2(n.x, n.y, verts[i*2], verts[i*2+1]); + var dtMax = -vcross2(n.x, n.y, verts[(i*2+2)%len], verts[(i*2+3)%len]); + if(dtMin <= dt && dt <= dtMax){ // josephg: In the original C code, this function keeps // looping through axes after finding a match. I *think* @@ -2104,38 +2104,13 @@ var subtreeQuery = function(subtree, bb, func) } }; -/// Returns the fraction along the segment query the cpBB is hit. Returns Infinity if it doesn't hit. -var bbTreeSegmentQuery = function(node, a, b) -{ - var idx = 1/(b.x - a.x); - var tx1 = (node.bb_l == a.x ? -Infinity : (node.bb_l - a.x)*idx); - 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; -}; - var subtreeSegmentQuery = function(subtree, a, b, t_exit, func) { if(subtree.isLeaf){ return func(subtree.obj); } else { - var t_a = bbTreeSegmentQuery(subtree.A, a, b); - var t_b = bbTreeSegmentQuery(subtree.B, a, b); + var t_a = bbSegmentQuery(subtree.A, a, b); + var t_b = bbSegmentQuery(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)); diff --git a/cp.min.js b/cp.min.js index f3014db..e517c3b 100644 --- a/cp.min.js +++ b/cp.min.js @@ -1,2 +1,2 @@ -(function(){Object.create=Object.create||function(a){function b(){}return b.prototype=a,new b};if(typeof a=="undefined")var a={};typeof window=="object"&&(window.cp=a);var b=function(a,b){if(!a)throw new Error("Assertion failed: "+b)},c=function(a,b){!a&&console&&console.warn&&console.warn("ASSERTION FAILED: "+b)},d=function(a,b){return a+" "+b},e=function(a,b){return ab?a:b},g,h;typeof window=="object"&&window.navigator.userAgent.indexOf("Firefox")>-1?(g=Math.min,h=Math.max):(g=e,h=f);var i=function(a,b){for(var c=0;cb*b?I(S(a),b):a},V=a.v.lerpconst=function(a,b,c){return F(a,U(G(b,a),c))},W=a.v.dist=function(a,b){return D(G(a,b))},X=a.v.distsq=function(a,b){return Q(G(a,b))},Y=a.v.near=function(a,b,c){return X(a,b)=b.r&&a.b<=b.b&&a.t>=b.t},bi=function(a,b){return a.l<=b.x&&a.r>=b.x&&a.b<=b.y&&a.t>=b.y},bj=function(a,b,c,d,e){return a<=e.x&&c>=e.x&&b<=e.y&&d>=e.y},bk=function(a,b){return new bd(g(a.l,b.l),g(a.b,b.b),h(a.r,b.r),h(a.t,b.t))},bl=function(a,b){return new bd(g(a.l,b.x),g(a.b,b.y),h(a.r,b.x),h(a.t,b.y))},bm=function(a){return(a.r-a.l)*(a.t-a.b)},bn=function(a,b){return(h(a.r,b.r)-g(a.l,b.l))*(h(a.t,b.t)-g(a.b,b.b))},bo=function(a,b,c,d,e){return(h(a.r,d)-g(a.l,b))*(h(a.t,e)-g(a.b,c))},bp=function(a,b,c){var d=1/(c.x-b.x),e=a.l==b.x?-Infinity:(a.l-b.x)*d,f=a.r==b.x?Infinity:(a.r-b.x)*d,i=g(e,f),j=h(e,f),k=1/(c.y-b.y),l=a.b==b.y?-Infinity:(a.b-b.y)*k,m=a.t==b.y?Infinity:(a.t-b.y)*k,n=g(l,m),o=h(l,m);if(n<=j&&i<=o){var p=h(i,n),q=g(j,o);if(0<=q&&p<=1)return h(p,0)}return Infinity},bq=function(a,b,c){return bp(a,b,c)!=Infinity},br=function(a,b){var c=g(h(a.l,b.x),a.r),d=g(h(a.b,b.y),a.t);return new z(c,d)},bs=function(a,b){var c=Math.abs(a.r-a.l),d=(b.x-a.l)%c,e=d>0?d:d+c,f=Math.abs(a.t-a.b),g=(b.y-a.b)%f,h=g>0?g:g+f;return new z(e+a.l,h+a.b)},bt=0,bu=0,bv=-1;a.resetShapeIdCounter=function(){bt=0};var bw=a.Shape=function(a){this.body=a,this.bb_l=this.bb_b=this.bb_r=this.bb_t=0,this.hashid=bt++,this.sensor=!1,this.e=0,this.u=0,this.surface_v=A,this.collision_type=0,this.group=0,this.layers=bv,this.space=null,this.collisionCode=this.collisionCode};bw.prototype.setElasticity=function(a){this.e=a},bw.prototype.setFriction=function(a){this.body.activate(),this.u=a},bw.prototype.setLayers=function(a){this.body.activate(),this.layers=a},bw.prototype.active=function(){return this.prev||this.body.shapeList.length>0&&this.body.shapeList[0]===this},bw.prototype.setBody=function(a){b(!this.active(),"You cannot change the body on an active shape. You must remove the shape, then "),this.body=a},bw.prototype.cacheBB=function(){return this.update(this.body.p,this.body.rot)},bw.prototype.update=function(a,c){b(!isNaN(c.x),"Rotation is NaN"),b(!isNaN(a.x),"Position is NaN"),this.cacheData(a,c)};var bx=function(a){this.shape=a,this.d=Infinity,this.n=A},by=function(a,b,c){this.shape=a,this.t=b,this.n=c},bz=a.CircleShape=function(a,b,c){this.c=this.tc=c,this.r=b,this.type="circle",bw.call(this,a)};bz.prototype=Object.create(bw.prototype),bz.prototype.cacheData=function(a,b){var c=this.tc=O(this.c,b).add(a),d=this.r;this.bb_l=c.x-d,this.bb_b=c.y-d,this.bb_r=c.x+d,this.bb_t=c.y+d},bz.prototype.pointQuery=function(a){var b=G(a,this.tc),c=Q(b),d=this.r;if(c=0){var k=(-h-Math.sqrt(j))/(2*g);if(0<=k&&k<=1)return new by(a,k,S(R(d,e,k)))}};bz.prototype.segmentQuery=function(a,b){return bA(this,this.tc,this.r,a,b)};var bB=a.SegmentShape=function(a,b,c,d){this.a=b,this.b=c,this.n=L(S(G(c,b))),this.ta=this.tb=this.tn=null,this.r=d,this.a_tangent=A,this.b_tangent=A,this.type="segment",bw.call(this,a)};bB.prototype=Object.create(bw.prototype),bB.prototype.cacheData=function(a,b){this.ta=F(a,O(this.a,b)),this.tb=F(a,O(this.b,b)),this.tn=O(this.n,b);var c,d,e,f;this.ta.x0?H(c):c,g=G(I(f,e),a),h=F(this.ta,g),i=F(this.tb,g),j=G(b,a);if(J(j,h)*J(j,i)<=0){var k=d+(d>0?-e:e),l=-k,m=B(j,c)-k;if(l*m<0)return{shape:this,t:l/(l-m),n:f}}else if(e!=0){var n=bA(this,this.ta,this.r,a,b),o=bA(this,this.tb,this.r,a,b);return n?o&&o.t0)return!1}return!0},bD=a.PolyShape=function(a,c,d){b(c.length>=4,"Polygons require some verts"),b(typeof c[0]=="number","Polygon verticies should be specified in a flattened list"),b(bC(c),"Polygon is concave or has a reversed winding."),this.setVerts(c,d),this.type="poly",bw.call(this,a)};bD.prototype=Object.create(bw.prototype);var bE=function(a,b){this.n=a,this.d=b};bD.prototype.setVerts=function(a,b){var c=a.length,d=c>>1;this.verts=new Array(c),this.tVerts=new Array(c),this.axes=new Array(d),this.tAxes=new Array(d);for(var e=0;e>1]=new bE(j,C(j.x,j.y,f,g)),this.tAxes[e>>1]=new bE(new z(0,0),0)}};var bF=a.BoxShape=function(a,b,c){var d=b/2,e=c/2;return bG(a,new bd(-d,-e,d,e))},bG=a.BoxShape2=function(a,b){var c=[b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b];return new bD(a,c,A)};bD.prototype.transformVerts=function(a,b){var c=this.verts,d=this.tVerts,e=Infinity,f=-Infinity,i=Infinity,j=-Infinity;for(var k=0;ki)continue;var j=B(b,h),k=(c[g].d-i)/(j-i);if(k<0||10)return!1}return!0},bD.prototype.containsVertPartial=function(a,b,c){var d=this.tAxes;for(var e=0;e0)return!1}return!0};var bH=a.Body=function(a,b){bH.prototype.velocity_func=bH.prototype.updateVelocity,bH.prototype.position_func=bH.prototype.updatePosition,this.p=new z(0,0),this.vx=this.vy=0,this.f=new z(0,0),this.w=0,this.t=0,this.v_limit=Infinity,this.w_limit=Infinity,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(a),this.setMoment(b),this.rot=new z(0,0),this.setAngle(0)},bI=function(){return body=new bH(Infinity,Infinity),body.nodeIdleTime=Infinity,body};if(typeof DEBUG!="undefined"&&DEBUG){var bJ=function(a,c){b(a.x==a.x&&a.y==a.y,c)},bK=function(a,c){b(Math.abs(a.x)!==Infinity&&Math.abs(a.y)!==Infinity,c)},bL=function(a,b){bJ(a,b),bK(a,b)};bH.prototype.sanityCheck=function(){b(this.m===this.m&&this.m_inv===this.m_inv,"Body's mass is invalid."),b(this.i===this.i&&this.i_inv===this.i_inv,"Body's moment is invalid."),bL(this.p,"Body's position is invalid."),bL(this.f,"Body's force is invalid."),b(this.vx===this.vx&&Math.abs(this.vx)!==Infinity,"Body's velocity is invalid."),b(this.vy===this.vy&&Math.abs(this.vy)!==Infinity,"Body's velocity is invalid."),b(this.a===this.a&&Math.abs(this.a)!==Infinity,"Body's angle is invalid."),b(this.w===this.w&&Math.abs(this.w)!==Infinity,"Body's angular velocity is invalid."),b(this.t===this.t&&Math.abs(this.t)!==Infinity,"Body's torque is invalid."),bL(this.rot,"Internal error: Body's rotation vector is invalid."),b(this.v_limit===this.v_limit,"Body's velocity limit is invalid."),b(this.w_limit===this.w_limit,"Body's angular velocity limit is invalid.")}}else bH.prototype.sanityCheck=function(){};bH.prototype.isSleeping=function(){return this.nodeRoot!==null},bH.prototype.isStatic=function(){return this.nodeIdleTime===Infinity},bH.prototype.isRogue=function(){return this.space===null},bH.prototype.setMass=function(a){b(a>0,"Mass must be positive and non-zero."),this.activate(),this.m=a,this.m_inv=1/a},bH.prototype.setMoment=function(a){b(a>0,"Moment of Inertia must be positive and non-zero."),this.activate(),this.i=a,this.i_inv=1/a},bH.prototype.addShape=function(a){this.shapeList.push(a)},bH.prototype.removeShape=function(a){i(this.shapeList,a)};var bM=function(a,b,c){return a==c?a.next(b):(a.a===b?a.next_a=bM(a.next_a,b,c):a.next_b=bM(a.next_b,b,c),a)};bH.prototype.removeConstraint=function(a){this.constraintList=bM(this.constraintList,this,a)},bH.prototype.setPos=function(a){this.activate(),this.sanityCheck(),this.p=a},bH.prototype.setVelocity=function(a){this.activate(),this.vx=a.x,this.vy=a.y},bH.prototype.setAngleInternal=function(a){b(!isNaN(a),"Internal Error: Attempting to set body's angle to NaN"),this.a=a,this.rot.x=Math.cos(a),this.rot.y=Math.sin(a)},bH.prototype.setAngle=function(a){this.activate(),this.sanityCheck(),this.setAngleInternal(a)},bH.prototype.updateVelocity=function(a,b,c){var d=this.vx*b+(a.x+this.f.x*this.m_inv)*c,e=this.vy*b+(a.y+this.f.y*this.m_inv)*c,f=this.v_limit,g=d*d+e*e,h=g>f*f?f/Math.sqrt(len):1;this.vx=d*h,this.vy=e*h;var i=this.w_limit;this.w=t(this.w*b+this.t*this.i_inv*c,-i,i),this.sanityCheck()},bH.prototype.updatePosition=function(a){this.p.x+=(this.vx+this.v_biasx)*a,this.p.y+=(this.vy+this.v_biasy)*a,this.setAngleInternal(this.a+(this.w+this.w_bias)*a),this.v_biasx=this.v_biasy=0,this.w_bias=0,this.sanityCheck()},bH.prototype.resetForces=function(){this.activate(),this.f=new z(0,0),this.t=0},bH.prototype.applyForce=function(a,b){this.activate(),this.f=F(this.f,a),this.t+=J(b,a)},bH.prototype.applyImpulse=function(a,b){this.activate(),cR(this,a.x,a.y,b)},bH.prototype.getVelAtPoint=function(a){return F(new z(this.vx,this.vy),I(L(a),body.w))},bH.prototype.getVelAtWorldPoint=function(a){return this.getVelAtPoint(G(a,body.p))},bH.prototype.getVelAtLocalPoint=function(a){return this.getVelAtPoint(O(a,body.rot))},bH.prototype.eachShape=function(a){for(var b=0,c=this.shapeList.length;b0){var c=a.query;this.each(function(a){c(a,new bd(a.bb_l,a.bb_b,a.bb_r,a.bb_t),b)})}};var bO=a.BBTree=function(a){bN.call(this,a),this.velocityFunc=null,this.leaves={},this.count=0,this.root=null,this.stamp=0};bO.prototype=Object.create(bN.prototype);var bP=0,bQ=function(a,b,c){this.obj=null,this.bb_l=g(b.bb_l,c.bb_l),this.bb_b=g(b.bb_b,c.bb_b),this.bb_r=h(b.bb_r,c.bb_r),this.bb_t=h(b.bb_t,c.bb_t),this.parent=null,this.setA(b),this.setB(c),bP++},bR=0,bS=function(a,b){this.obj=b,a.getBB(b,this),this.parent=null,this.stamp=1,this.pairs=null,bR++};bO.prototype.getBB=function(a,b){var c=this.velocityFunc;if(c){var d=.1,e=(a.bb_r-a.bb_l)*d,f=(a.bb_t-a.bb_b)*d,i=I(c(a),.1);b.bb_l=a.bb_l+g(-e,i.x),b.bb_b=a.bb_b+g(-f,i.y),b.bb_r=a.bb_r+h(e,i.x),b.bb_t=a.bb_t+h(f,i.y)}else b.bb_l=a.bb_l,b.bb_b=a.bb_b,b.bb_r=a.bb_r,b.bb_t=a.bb_t},bO.prototype.getStamp=function(){var a=this.dynamicIndex;return a&&a.stamp?a.stamp:this.stamp},bO.prototype.incrementStamp=function(){this.dynamicIndex&&this.dynamicIndex.stamp?this.dynamicIndex.stamp++:this.stamp++};var bT=function(a,b){this.a=a,this.b=b},bU=function(a,b){this.prev=null,this.next=b,this.leaf=a};bU.prototype.unlink=function(){var a=this.next,b=this.prev;a&&(a.a.leaf==this.leaf?a.a.prev=b:a.b.prev=b),b?b.a.leaf==this.leaf?b.a.next=a:b.b.next=a:this.leaf.pairs=a},bS.prototype.clearPairs=function(a){var b=this.pairs,c;this.pairs=null;while(b)b.a.leaf==this?(c=b.a.next,b.b.unlink(),b=c):(c=b.b.next,b.a.unlink(),b=c)};var bV=function(a,b,c){var d=a.pairs,e=b.pairs,f=new bT(new bU(a,d),new bU(b,e));a.pairs=b.pairs=f,d&&(d.a.leaf==a?d.a.prev=f:d.b.prev=f),e&&(e.a.leaf==b?e.a.prev=f:e.b.prev=f)};bQ.prototype.setA=function(a){this.A=a,a.parent=this},bQ.prototype.setB=function(a){this.B=a,a.parent=this},bS.prototype.isLeaf=!0,bQ.prototype.isLeaf=!1,bQ.prototype.otherChild=function(a){return this.A==a?this.B:this.A},bQ.prototype.replaceChild=function(a,b,d){c(a==this.A||a==this.B,"Node is not a child of parent."),this.A==a?this.setA(b):this.setB(b);for(var e=this;e;e=e.parent){var f=e.A,i=e.B;e.bb_l=g(f.bb_l,i.bb_l),e.bb_b=g(f.bb_b,i.bb_b),e.bb_r=h(f.bb_r,i.bb_r),e.bb_t=h(f.bb_t,i.bb_t)}},bQ.prototype.bbArea=bS.prototype.bbArea=function(){return(this.bb_r-this.bb_l)*(this.bb_t-this.bb_b)};var bW=function(a,b){return(h(a.bb_r,b.bb_r)-g(a.bb_l,b.bb_l))*(h(a.bb_t,b.bb_t)-g(a.bb_b,b.bb_b))},bX=function(a,b){return Math.abs(a.bb_l+a.bb_r-b.bb_l-b.bb_r)+Math.abs(a.bb_b+b.bb_t-b.bb_b-b.bb_t)},bY=function(a,b,c){if(a==null)return b;if(a.isLeaf)return new bQ(c,b,a);var d=a.B.bbArea()+bW(a.A,b),e=a.A.bbArea()+bW(a.B,b);return d===e&&(d=bX(a.A,b),e=bX(a.B,b)),e=a.bb_r&&this.bb_b<=a.bb_b&&this.bb_t>=a.bb_t},bS.prototype.update=function(a){var b=a.root,c=this.obj;return this.containsObj(c)?!1:(a.getBB(this.obj,this),b=ca(b,this,a),a.root=bY(b,this,a),this.clearPairs(a),this.stamp=a.getStamp(),!0)},bS.prototype.addPairs=function(a){var b=a.dynamicIndex;if(b){var c=b.root;c&&cc(c,this,!0,b,null)}else{var d=a.staticIndex.root;cd(this,a,d,null)}},bO.prototype.insert=function(a,b){var c=new bS(this,a);this.leaves[b]=c,this.root=bY(this.root,c,this),this.count++,c.stamp=this.getStamp(),c.addPairs(this),this.incrementStamp()},bO.prototype.remove=function(a,b){var c=this.leaves[b];delete this.leaves[b],this.root=ca(this.root,c,this),this.count--,c.clearPairs(this)},bO.prototype.contains=function(a,b){return this.leaves[b]!=null};var cf=function(a,b){};bO.prototype.reindexQuery=function(a){if(!this.root)return;var b,c=this.leaves;for(b in c)c[b].update(this);var d=this.staticIndex,e=d&&d.root;ce(this.root,this,e,a),d&&!e&&this.collideStatic(this,d,a),this.incrementStamp()},bO.prototype.reindex=function(){this.reindexQuery(cf)},bO.prototype.reindexObject=function(a,b){var c=this.leaves[b];c&&(c.update(this)&&c.addPairs(this),this.incrementStamp())},bO.prototype.pointQuery=function(a,b){this.root&&bZ(this.root,new bd(a.x,a.y,a.x,a.y),b)},bO.prototype.segmentQuery=function(a,b,c,d){this.root&&b_(this.root,a,b,c,d)},bO.prototype.query=function(a,b){this.root&&bZ(this.root,a,b)},bO.prototype.count=function(){return this.count},bO.prototype.each=function(a){var b;for(b in this.leaves)a(this.leaves[b].obj)};var cg=function(a,b,c,d,e){return(h(a.bb_r,d)-g(a.bb_l,b))*(h(a.bb_t,e)-g(a.bb_b,c))},ch=function(a,b,c,d){if(d==1)return b[c];if(d==2)return new bQ(a,b[c],b[c+1]);var e=b[c],f=e.bb_l,i=e.bb_b,j=e.bb_r,k=e.bb_t,l=c+d;for(var m=c+1;mk-i,o=new Array(d*2);if(n)for(var m=c;m=e*e)return;var h=Math.sqrt(g);return new cr(F(a,I(f,.5+(c-.5*e)/(h?h:Infinity))),h?I(f,1/h):new z(1,0),h-e,0)},cu=function(a,b){var c=ct(a.tc,b.tc,a.r,b.r);return c?[c]:cs},cv=function(a,b){var c=b.ta,d=b.tb,e=a.tc,f=G(d,c),g=u(B(f,G(e,c))/Q(f)),h=F(c,I(f,g)),i=ct(e,h,a.r,b.r);if(i){var j=i.n;return g===0&&B(j,b.a_tangent)<0||g===1&&B(j,b.b_tangent)<0?cs:[i]}return cs},cw=0,cx=function(a,b){var c=0,d=a.valueOnAxis(b[0].n,b[0].d);if(d>0)return-1;for(var e=1;e0)return-1;f>d&&(d=f,c=e)}return cw=d,c},cy=function(a,b,c,e){var f=[],g=a.tVerts;for(var h=0;h>1)))}var k=b.tVerts;for(var h=0;h>1)))}return f.length?f:cy(a,b,c,e)},cA=function(a,b){var c=cx(b,a.tAxes);if(c==-1)return cs;var d=cw,e=cx(a,b.tAxes);if(e==-1)return cs;var f=cw;return d>f?cz(a,b,a.tAxes[c].n,d):cz(a,b,H(b.tAxes[e].n),f)},cB=function(a,b,c){var d=B(b,a.ta)-a.r,e=B(b,a.tb)-a.r;return g(d,e)-c},cC=function(a,b,c,e,f){var g=J(b.tn,b.ta),h=J(b.tn,b.tb),i=I(b.tn,f),j=c.tVerts;for(var k=0;k=n&&n>=h&&a.push(new cr(new z(l,m),i,e,d(c.hashid,k)))}}},cD=function(a,b){var c=[],e=b.tAxes,f=e.length,g=B(a.tn,a.ta),h=b.valueOnAxis(a.tn,g)-a.r,i=b.valueOnAxis(H(a.tn),-g)-a.r;if(i>0||h>0)return cs;var j=0,k=cB(a,e[0].n,e[0].d);if(k>0)return cs;for(var l=0;l0)return cs;m>k&&(k=m,j=l)}var n=H(e[j].n),o=F(a.ta,I(n,a.r)),p=F(a.tb,I(n,a.r));b.containsVert(o.x,o.y)&&c.push(new cr(o,n,k,d(a.hashid,0))),b.containsVert(p.x,p.y)&&c.push(new cr(p,n,k,d(a.hashid,1)));if(h>=k||i>=k)h>i?cC(c,a,b,h,1):cC(c,a,b,i,-1);if(c.length===0){var q=j*2,r=b.tVerts,s=new z(r[q],r[q+1]),t;if(t=ct(a.ta,s,a.r,0,c))return[t];if(t=ct(a.tb,s,a.r,0,c))return[t];var u=f*2,v=new z(r[(q+2)%u],r[(q+3)%u]);if(t=ct(a.ta,v,a.r,0,c))return[t];if(t=ct(a.tb,v,a.r,0,c))return[t]}return c},cE=function(a,b){var c=b.tAxes,d=0,e=B(c[0].n,a.tc)-c[0].d-a.r;for(var f=0;f0)return cs;g>e&&(e=g,d=f)}var h=c[d].n,i=b.tVerts,j=i.length,k=d<<1,l=i[k],m=i[k+1],n=i[(k+2)%j],o=i[(k+3)%j],p=K(h.x,h.y,l,m),q=K(h.x,h.y,n,o),r=J(h,a.tc);if(rh?0:g.nodeIdleTime+a,c(g.nodeNext===null,"Internal Error: Dangling next pointer detected in contact graph."),c(g.nodeRoot===null,"Internal Error: Dangling root pointer detected in contact graph.")}var i=this.arbiters;for(var f=0,j=i.length;f=0,"Internal Error: Space lock underflow.");if(!this.locked&&a){var c=this.rousedBodies;for(var d=0;dc.collisionCode){var h=b;b=c,c=h}var i=cF(b,c);if(i.length===0)return;var j=d(b.hashid,c.hashid),k=e.cachedArbiters[j];k||(k=e.cachedArbiters[j]=new cl(b,c)),k.update(i,f,b,c),k.state=="first coll"&&!f.begin(k,e)&&k.ignore(),k.state!=="ignore"&&f.preSolve(k,e)&&!g?e.arbiters.push(k):(k.contacts=null,k.state!=="ignore"&&(k.state="normal")),k.stamp=e.stamp}},cH.prototype.arbiterSetFilter=function(a){var b=this.stamp-a.stamp,c=a.body_a,d=a.body_b;return(c.isStatic()||c.isSleeping())&&(d.isStatic()||d.isSleeping())?!0:(b>=1&&a.state!="cached"&&(a.callSeparate(this),a.state="cached"),b>=this.collisionPersistence?(a.contacts=null,!1):!0)};var cO=function(a){var b=a.body;a.update(b.p,b.rot)};cH.prototype.step=function(a){if(a===0)return;b(A.x===0&&A.y===0,"vzero is invalid"),this.stamp++;var c=this.curr_dt;this.curr_dt=a;var d=this.bodies,e=this.constraints,f=this.arbiters;for(var g=0;gb?a:b},g,h;typeof window=="object"&&window.navigator.userAgent.indexOf("Firefox")>-1?(g=Math.min,h=Math.max):(g=e,h=f);var i=function(a,b){for(var c=0;cb*b?I(S(a),b):a},V=a.v.lerpconst=function(a,b,c){return F(a,U(G(b,a),c))},W=a.v.dist=function(a,b){return D(G(a,b))},X=a.v.distsq=function(a,b){return Q(G(a,b))},Y=a.v.near=function(a,b,c){return X(a,b)=b.r&&a.b<=b.b&&a.t>=b.t},bi=function(a,b){return a.l<=b.x&&a.r>=b.x&&a.b<=b.y&&a.t>=b.y},bj=function(a,b,c,d,e){return a<=e.x&&c>=e.x&&b<=e.y&&d>=e.y},bk=function(a,b){return new bd(g(a.l,b.l),g(a.b,b.b),h(a.r,b.r),h(a.t,b.t))},bl=function(a,b){return new bd(g(a.l,b.x),g(a.b,b.y),h(a.r,b.x),h(a.t,b.y))},bm=function(a){return(a.r-a.l)*(a.t-a.b)},bn=function(a,b){return(h(a.r,b.r)-g(a.l,b.l))*(h(a.t,b.t)-g(a.b,b.b))},bo=function(a,b,c,d,e){return(h(a.r,d)-g(a.l,b))*(h(a.t,e)-g(a.b,c))},bp=function(a,b,c){var d=1/(c.x-b.x),e=a.bb_l==b.x?-Infinity:(a.bb_l-b.x)*d,f=a.bb_r==b.x?Infinity:(a.bb_r-b.x)*d,i=g(e,f),j=h(e,f),k=1/(c.y-b.y),l=a.bb_b==b.y?-Infinity:(a.bb_b-b.y)*k,m=a.bb_t==b.y?Infinity:(a.bb_t-b.y)*k,n=g(l,m),o=h(l,m);if(n<=j&&i<=o){var p=h(i,n),q=g(j,o);if(0<=q&&p<=1)return h(p,0)}return Infinity},bq=function(a,b,c){return bp(a,b,c)!=Infinity},br=function(a,b){var c=g(h(a.l,b.x),a.r),d=g(h(a.b,b.y),a.t);return new z(c,d)},bs=function(a,b){var c=Math.abs(a.r-a.l),d=(b.x-a.l)%c,e=d>0?d:d+c,f=Math.abs(a.t-a.b),g=(b.y-a.b)%f,h=g>0?g:g+f;return new z(e+a.l,h+a.b)},bt=0,bu=0,bv=-1;a.resetShapeIdCounter=function(){bt=0};var bw=a.Shape=function(a){this.body=a,this.bb_l=this.bb_b=this.bb_r=this.bb_t=0,this.hashid=bt++,this.sensor=!1,this.e=0,this.u=0,this.surface_v=A,this.collision_type=0,this.group=0,this.layers=bv,this.space=null,this.collisionCode=this.collisionCode};bw.prototype.setElasticity=function(a){this.e=a},bw.prototype.setFriction=function(a){this.body.activate(),this.u=a},bw.prototype.setLayers=function(a){this.body.activate(),this.layers=a},bw.prototype.active=function(){return this.prev||this.body.shapeList.length>0&&this.body.shapeList[0]===this},bw.prototype.setBody=function(a){b(!this.active(),"You cannot change the body on an active shape. You must remove the shape, then "),this.body=a},bw.prototype.cacheBB=function(){return this.update(this.body.p,this.body.rot)},bw.prototype.update=function(a,c){b(!isNaN(c.x),"Rotation is NaN"),b(!isNaN(a.x),"Position is NaN"),this.cacheData(a,c)};var bx=function(a){this.shape=a,this.d=Infinity,this.n=A},by=function(a,b,c){this.shape=a,this.t=b,this.n=c},bz=a.CircleShape=function(a,b,c){this.c=this.tc=c,this.r=b,this.type="circle",bw.call(this,a)};bz.prototype=Object.create(bw.prototype),bz.prototype.cacheData=function(a,b){var c=this.tc=O(this.c,b).add(a),d=this.r;this.bb_l=c.x-d,this.bb_b=c.y-d,this.bb_r=c.x+d,this.bb_t=c.y+d},bz.prototype.pointQuery=function(a){var b=G(a,this.tc),c=Q(b),d=this.r;if(c=0){var k=(-h-Math.sqrt(j))/(2*g);if(0<=k&&k<=1)return new by(a,k,S(R(d,e,k)))}};bz.prototype.segmentQuery=function(a,b){return bA(this,this.tc,this.r,a,b)};var bB=a.SegmentShape=function(a,b,c,d){this.a=b,this.b=c,this.n=L(S(G(c,b))),this.ta=this.tb=this.tn=null,this.r=d,this.a_tangent=A,this.b_tangent=A,this.type="segment",bw.call(this,a)};bB.prototype=Object.create(bw.prototype),bB.prototype.cacheData=function(a,b){this.ta=F(a,O(this.a,b)),this.tb=F(a,O(this.b,b)),this.tn=O(this.n,b);var c,d,e,f;this.ta.x0?H(c):c,g=G(I(f,e),a),h=F(this.ta,g),i=F(this.tb,g),j=G(b,a);if(J(j,h)*J(j,i)<=0){var k=d+(d>0?-e:e),l=-k,m=B(j,c)-k;if(l*m<0)return{shape:this,t:l/(l-m),n:f}}else if(e!=0){var n=bA(this,this.ta,this.r,a,b),o=bA(this,this.tb,this.r,a,b);return n?o&&o.t0)return!1}return!0},bD=a.PolyShape=function(a,c,d){b(c.length>=4,"Polygons require some verts"),b(typeof c[0]=="number","Polygon verticies should be specified in a flattened list"),b(bC(c),"Polygon is concave or has a reversed winding."),this.setVerts(c,d),this.type="poly",bw.call(this,a)};bD.prototype=Object.create(bw.prototype);var bE=function(a,b){this.n=a,this.d=b};bD.prototype.setVerts=function(a,b){var c=a.length,d=c>>1;this.verts=new Array(c),this.tVerts=new Array(c),this.axes=new Array(d),this.tAxes=new Array(d);for(var e=0;e>1]=new bE(j,C(j.x,j.y,f,g)),this.tAxes[e>>1]=new bE(new z(0,0),0)}};var bF=a.BoxShape=function(a,b,c){var d=b/2,e=c/2;return bG(a,new bd(-d,-e,d,e))},bG=a.BoxShape2=function(a,b){var c=[b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b];return new bD(a,c,A)};bD.prototype.transformVerts=function(a,b){var c=this.verts,d=this.tVerts,e=Infinity,f=-Infinity,i=Infinity,j=-Infinity;for(var k=0;ki)continue;var j=B(b,h),k=(c[g].d-i)/(j-i);if(k<0||10)return!1}return!0},bD.prototype.containsVertPartial=function(a,b,c){var d=this.tAxes;for(var e=0;e0)return!1}return!0};var bH=a.Body=function(a,b){bH.prototype.velocity_func=bH.prototype.updateVelocity,bH.prototype.position_func=bH.prototype.updatePosition,this.p=new z(0,0),this.vx=this.vy=0,this.f=new z(0,0),this.w=0,this.t=0,this.v_limit=Infinity,this.w_limit=Infinity,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(a),this.setMoment(b),this.rot=new z(0,0),this.setAngle(0)},bI=function(){return body=new bH(Infinity,Infinity),body.nodeIdleTime=Infinity,body};if(typeof DEBUG!="undefined"&&DEBUG){var bJ=function(a,c){b(a.x==a.x&&a.y==a.y,c)},bK=function(a,c){b(Math.abs(a.x)!==Infinity&&Math.abs(a.y)!==Infinity,c)},bL=function(a,b){bJ(a,b),bK(a,b)};bH.prototype.sanityCheck=function(){b(this.m===this.m&&this.m_inv===this.m_inv,"Body's mass is invalid."),b(this.i===this.i&&this.i_inv===this.i_inv,"Body's moment is invalid."),bL(this.p,"Body's position is invalid."),bL(this.f,"Body's force is invalid."),b(this.vx===this.vx&&Math.abs(this.vx)!==Infinity,"Body's velocity is invalid."),b(this.vy===this.vy&&Math.abs(this.vy)!==Infinity,"Body's velocity is invalid."),b(this.a===this.a&&Math.abs(this.a)!==Infinity,"Body's angle is invalid."),b(this.w===this.w&&Math.abs(this.w)!==Infinity,"Body's angular velocity is invalid."),b(this.t===this.t&&Math.abs(this.t)!==Infinity,"Body's torque is invalid."),bL(this.rot,"Internal error: Body's rotation vector is invalid."),b(this.v_limit===this.v_limit,"Body's velocity limit is invalid."),b(this.w_limit===this.w_limit,"Body's angular velocity limit is invalid.")}}else bH.prototype.sanityCheck=function(){};bH.prototype.isSleeping=function(){return this.nodeRoot!==null},bH.prototype.isStatic=function(){return this.nodeIdleTime===Infinity},bH.prototype.isRogue=function(){return this.space===null},bH.prototype.setMass=function(a){b(a>0,"Mass must be positive and non-zero."),this.activate(),this.m=a,this.m_inv=1/a},bH.prototype.setMoment=function(a){b(a>0,"Moment of Inertia must be positive and non-zero."),this.activate(),this.i=a,this.i_inv=1/a},bH.prototype.addShape=function(a){this.shapeList.push(a)},bH.prototype.removeShape=function(a){i(this.shapeList,a)};var bM=function(a,b,c){return a==c?a.next(b):(a.a===b?a.next_a=bM(a.next_a,b,c):a.next_b=bM(a.next_b,b,c),a)};bH.prototype.removeConstraint=function(a){this.constraintList=bM(this.constraintList,this,a)},bH.prototype.setPos=function(a){this.activate(),this.sanityCheck(),this.p=a},bH.prototype.setVelocity=function(a){this.activate(),this.vx=a.x,this.vy=a.y},bH.prototype.setAngleInternal=function(a){b(!isNaN(a),"Internal Error: Attempting to set body's angle to NaN"),this.a=a,this.rot.x=Math.cos(a),this.rot.y=Math.sin(a)},bH.prototype.setAngle=function(a){this.activate(),this.sanityCheck(),this.setAngleInternal(a)},bH.prototype.updateVelocity=function(a,b,c){var d=this.vx*b+(a.x+this.f.x*this.m_inv)*c,e=this.vy*b+(a.y+this.f.y*this.m_inv)*c,f=this.v_limit,g=d*d+e*e,h=g>f*f?f/Math.sqrt(len):1;this.vx=d*h,this.vy=e*h;var i=this.w_limit;this.w=t(this.w*b+this.t*this.i_inv*c,-i,i),this.sanityCheck()},bH.prototype.updatePosition=function(a){this.p.x+=(this.vx+this.v_biasx)*a,this.p.y+=(this.vy+this.v_biasy)*a,this.setAngleInternal(this.a+(this.w+this.w_bias)*a),this.v_biasx=this.v_biasy=0,this.w_bias=0,this.sanityCheck()},bH.prototype.resetForces=function(){this.activate(),this.f=new z(0,0),this.t=0},bH.prototype.applyForce=function(a,b){this.activate(),this.f=F(this.f,a),this.t+=J(b,a)},bH.prototype.applyImpulse=function(a,b){this.activate(),cQ(this,a.x,a.y,b)},bH.prototype.getVelAtPoint=function(a){return F(new z(this.vx,this.vy),I(L(a),body.w))},bH.prototype.getVelAtWorldPoint=function(a){return this.getVelAtPoint(G(a,body.p))},bH.prototype.getVelAtLocalPoint=function(a){return this.getVelAtPoint(O(a,body.rot))},bH.prototype.eachShape=function(a){for(var b=0,c=this.shapeList.length;b0){var c=a.query;this.each(function(a){c(a,new bd(a.bb_l,a.bb_b,a.bb_r,a.bb_t),b)})}};var bO=a.BBTree=function(a){bN.call(this,a),this.velocityFunc=null,this.leaves={},this.count=0,this.root=null,this.stamp=0};bO.prototype=Object.create(bN.prototype);var bP=0,bQ=function(a,b,c){this.obj=null,this.bb_l=g(b.bb_l,c.bb_l),this.bb_b=g(b.bb_b,c.bb_b),this.bb_r=h(b.bb_r,c.bb_r),this.bb_t=h(b.bb_t,c.bb_t),this.parent=null,this.setA(b),this.setB(c),bP++},bR=0,bS=function(a,b){this.obj=b,a.getBB(b,this),this.parent=null,this.stamp=1,this.pairs=null,bR++};bO.prototype.getBB=function(a,b){var c=this.velocityFunc;if(c){var d=.1,e=(a.bb_r-a.bb_l)*d,f=(a.bb_t-a.bb_b)*d,i=I(c(a),.1);b.bb_l=a.bb_l+g(-e,i.x),b.bb_b=a.bb_b+g(-f,i.y),b.bb_r=a.bb_r+h(e,i.x),b.bb_t=a.bb_t+h(f,i.y)}else b.bb_l=a.bb_l,b.bb_b=a.bb_b,b.bb_r=a.bb_r,b.bb_t=a.bb_t},bO.prototype.getStamp=function(){var a=this.dynamicIndex;return a&&a.stamp?a.stamp:this.stamp},bO.prototype.incrementStamp=function(){this.dynamicIndex&&this.dynamicIndex.stamp?this.dynamicIndex.stamp++:this.stamp++};var bT=function(a,b){this.a=a,this.b=b},bU=function(a,b){this.prev=null,this.next=b,this.leaf=a};bU.prototype.unlink=function(){var a=this.next,b=this.prev;a&&(a.a.leaf==this.leaf?a.a.prev=b:a.b.prev=b),b?b.a.leaf==this.leaf?b.a.next=a:b.b.next=a:this.leaf.pairs=a},bS.prototype.clearPairs=function(a){var b=this.pairs,c;this.pairs=null;while(b)b.a.leaf==this?(c=b.a.next,b.b.unlink(),b=c):(c=b.b.next,b.a.unlink(),b=c)};var bV=function(a,b,c){var d=a.pairs,e=b.pairs,f=new bT(new bU(a,d),new bU(b,e));a.pairs=b.pairs=f,d&&(d.a.leaf==a?d.a.prev=f:d.b.prev=f),e&&(e.a.leaf==b?e.a.prev=f:e.b.prev=f)};bQ.prototype.setA=function(a){this.A=a,a.parent=this},bQ.prototype.setB=function(a){this.B=a,a.parent=this},bS.prototype.isLeaf=!0,bQ.prototype.isLeaf=!1,bQ.prototype.otherChild=function(a){return this.A==a?this.B:this.A},bQ.prototype.replaceChild=function(a,b,d){c(a==this.A||a==this.B,"Node is not a child of parent."),this.A==a?this.setA(b):this.setB(b);for(var e=this;e;e=e.parent){var f=e.A,i=e.B;e.bb_l=g(f.bb_l,i.bb_l),e.bb_b=g(f.bb_b,i.bb_b),e.bb_r=h(f.bb_r,i.bb_r),e.bb_t=h(f.bb_t,i.bb_t)}},bQ.prototype.bbArea=bS.prototype.bbArea=function(){return(this.bb_r-this.bb_l)*(this.bb_t-this.bb_b)};var bW=function(a,b){return(h(a.bb_r,b.bb_r)-g(a.bb_l,b.bb_l))*(h(a.bb_t,b.bb_t)-g(a.bb_b,b.bb_b))},bX=function(a,b){return Math.abs(a.bb_l+a.bb_r-b.bb_l-b.bb_r)+Math.abs(a.bb_b+b.bb_t-b.bb_b-b.bb_t)},bY=function(a,b,c){if(a==null)return b;if(a.isLeaf)return new bQ(c,b,a);var d=a.B.bbArea()+bW(a.A,b),e=a.A.bbArea()+bW(a.B,b);return d===e&&(d=bX(a.A,b),e=bX(a.B,b)),e=a.bb_r&&this.bb_b<=a.bb_b&&this.bb_t>=a.bb_t},bS.prototype.update=function(a){var b=a.root,c=this.obj;return this.containsObj(c)?!1:(a.getBB(this.obj,this),b=b_(b,this,a),a.root=bY(b,this,a),this.clearPairs(a),this.stamp=a.getStamp(),!0)},bS.prototype.addPairs=function(a){var b=a.dynamicIndex;if(b){var c=b.root;c&&cb(c,this,!0,b,null)}else{var d=a.staticIndex.root;cc(this,a,d,null)}},bO.prototype.insert=function(a,b){var c=new bS(this,a);this.leaves[b]=c,this.root=bY(this.root,c,this),this.count++,c.stamp=this.getStamp(),c.addPairs(this),this.incrementStamp()},bO.prototype.remove=function(a,b){var c=this.leaves[b];delete this.leaves[b],this.root=b_(this.root,c,this),this.count--,c.clearPairs(this)},bO.prototype.contains=function(a,b){return this.leaves[b]!=null};var ce=function(a,b){};bO.prototype.reindexQuery=function(a){if(!this.root)return;var b,c=this.leaves;for(b in c)c[b].update(this);var d=this.staticIndex,e=d&&d.root;cd(this.root,this,e,a),d&&!e&&this.collideStatic(this,d,a),this.incrementStamp()},bO.prototype.reindex=function(){this.reindexQuery(ce)},bO.prototype.reindexObject=function(a,b){var c=this.leaves[b];c&&(c.update(this)&&c.addPairs(this),this.incrementStamp())},bO.prototype.pointQuery=function(a,b){this.root&&bZ(this.root,new bd(a.x,a.y,a.x,a.y),b)},bO.prototype.segmentQuery=function(a,b,c,d){this.root&&b$(this.root,a,b,c,d)},bO.prototype.query=function(a,b){this.root&&bZ(this.root,a,b)},bO.prototype.count=function(){return this.count},bO.prototype.each=function(a){var b;for(b in this.leaves)a(this.leaves[b].obj)};var cf=function(a,b,c,d,e){return(h(a.bb_r,d)-g(a.bb_l,b))*(h(a.bb_t,e)-g(a.bb_b,c))},cg=function(a,b,c,d){if(d==1)return b[c];if(d==2)return new bQ(a,b[c],b[c+1]);var e=b[c],f=e.bb_l,i=e.bb_b,j=e.bb_r,k=e.bb_t,l=c+d;for(var m=c+1;mk-i,o=new Array(d*2);if(n)for(var m=c;m=e*e)return;var h=Math.sqrt(g);return new cq(F(a,I(f,.5+(c-.5*e)/(h?h:Infinity))),h?I(f,1/h):new z(1,0),h-e,0)},ct=function(a,b){var c=cs(a.tc,b.tc,a.r,b.r);return c?[c]:cr},cu=function(a,b){var c=b.ta,d=b.tb,e=a.tc,f=G(d,c),g=u(B(f,G(e,c))/Q(f)),h=F(c,I(f,g)),i=cs(e,h,a.r,b.r);if(i){var j=i.n;return g===0&&B(j,b.a_tangent)<0||g===1&&B(j,b.b_tangent)<0?cr:[i]}return cr},cv=0,cw=function(a,b){var c=0,d=a.valueOnAxis(b[0].n,b[0].d);if(d>0)return-1;for(var e=1;e0)return-1;f>d&&(d=f,c=e)}return cv=d,c},cx=function(a,b,c,e){var f=[],g=a.tVerts;for(var h=0;h>1)))}var k=b.tVerts;for(var h=0;h>1)))}return f.length?f:cx(a,b,c,e)},cz=function(a,b){var c=cw(b,a.tAxes);if(c==-1)return cr;var d=cv,e=cw(a,b.tAxes);if(e==-1)return cr;var f=cv;return d>f?cy(a,b,a.tAxes[c].n,d):cy(a,b,H(b.tAxes[e].n),f)},cA=function(a,b,c){var d=B(b,a.ta)-a.r,e=B(b,a.tb)-a.r;return g(d,e)-c},cB=function(a,b,c,e,f){var g=J(b.tn,b.ta),h=J(b.tn,b.tb),i=I(b.tn,f),j=c.tVerts;for(var k=0;k=n&&n>=h&&a.push(new cq(new z(l,m),i,e,d(c.hashid,k)))}}},cC=function(a,b){var c=[],e=b.tAxes,f=e.length,g=B(a.tn,a.ta),h=b.valueOnAxis(a.tn,g)-a.r,i=b.valueOnAxis(H(a.tn),-g)-a.r;if(i>0||h>0)return cr;var j=0,k=cA(a,e[0].n,e[0].d);if(k>0)return cr;for(var l=0;l0)return cr;m>k&&(k=m,j=l)}var n=H(e[j].n),o=F(a.ta,I(n,a.r)),p=F(a.tb,I(n,a.r));b.containsVert(o.x,o.y)&&c.push(new cq(o,n,k,d(a.hashid,0))),b.containsVert(p.x,p.y)&&c.push(new cq(p,n,k,d(a.hashid,1)));if(h>=k||i>=k)h>i?cB(c,a,b,h,1):cB(c,a,b,i,-1);if(c.length===0){var q=j*2,r=b.tVerts,s=new z(r[q],r[q+1]),t;if(t=cs(a.ta,s,a.r,0,c))return[t];if(t=cs(a.tb,s,a.r,0,c))return[t];var u=f*2,v=new z(r[(q+2)%u],r[(q+3)%u]);if(t=cs(a.ta,v,a.r,0,c))return[t];if(t=cs(a.tb,v,a.r,0,c))return[t]}return c},cD=function(a,b){var c=b.tAxes,d=0,e=B(c[0].n,a.tc)-c[0].d-a.r;for(var f=0;f0)return cr;g>e&&(e=g,d=f)}var h=c[d].n,i=b.tVerts,j=i.length,k=d<<1,l=i[k],m=i[k+1],n=i[(k+2)%j],o=i[(k+3)%j],p=K(h.x,h.y,l,m),q=K(h.x,h.y,n,o),r=J(h,a.tc);if(rh?0:g.nodeIdleTime+a,c(g.nodeNext===null,"Internal Error: Dangling next pointer detected in contact graph."),c(g.nodeRoot===null,"Internal Error: Dangling root pointer detected in contact graph.")}var i=this.arbiters;for(var f=0,j=i.length;f=0,"Internal Error: Space lock underflow.");if(!this.locked&&a){var c=this.rousedBodies;for(var d=0;dc.collisionCode){var h=b;b=c,c=h}var i=cE(b,c);if(i.length===0)return;var j=d(b.hashid,c.hashid),k=e.cachedArbiters[j];k||(k=e.cachedArbiters[j]=new ck(b,c)),k.update(i,f,b,c),k.state=="first coll"&&!f.begin(k,e)&&k.ignore(),k.state!=="ignore"&&f.preSolve(k,e)&&!g?e.arbiters.push(k):(k.contacts=null,k.state!=="ignore"&&(k.state="normal")),k.stamp=e.stamp}},cG.prototype.arbiterSetFilter=function(a){var b=this.stamp-a.stamp,c=a.body_a,d=a.body_b;return(c.isStatic()||c.isSleeping())&&(d.isStatic()||d.isSleeping())?!0:(b>=1&&a.state!="cached"&&(a.callSeparate(this),a.state="cached"),b>=this.collisionPersistence?(a.contacts=null,!1):!0)};var cN=function(a){var b=a.body;a.update(b.p,b.rot)};cG.prototype.step=function(a){if(a===0)return;b(A.x===0&&A.y===0,"vzero is invalid"),this.stamp++;var c=this.curr_dt;this.curr_dt=a;var d=this.bodies,e=this.constraints,f=this.arbiters;for(var g=0;g