@@ -27,20 +27,47 @@ var Vector = require('../geometry/Vector');
2727 axisNumber : 0
2828 } ;
2929
30+ /**
31+ * Creates a new collision record.
32+ * @private
33+ * @method create
34+ * @param {body } bodyA
35+ * @param {body } bodyB
36+ * @return {collision } A new collision
37+ */
38+ SAT . create = function ( bodyA , bodyB ) {
39+ return {
40+ collided : false ,
41+ bodyA : bodyA ,
42+ bodyB : bodyB ,
43+ parentA : bodyA . parent ,
44+ parentB : bodyB . parent ,
45+ axisBodyA : bodyA ,
46+ axisBodyB : bodyB ,
47+ axisNumber : 0 ,
48+ depth : 0 ,
49+ normal : { x : 0 , y : 0 } ,
50+ tangent : { x : 0 , y : 0 } ,
51+ penetration : { x : 0 , y : 0 } ,
52+ supports : [ ]
53+ } ;
54+ } ;
55+
3056 /**
3157 * Detect collision between two bodies using the Separating Axis Theorem.
3258 * @method collides
3359 * @param {body } bodyA
3460 * @param {body } bodyB
35- * @param {collision } previousCollision
61+ * @param {?collision } previousCollision
62+ * @param {?boolean } [previousPairActive=false]
3663 * @return {collision } collision
3764 */
38- SAT . collides = function ( bodyA , bodyB , previousCollision ) {
65+ SAT . collides = function ( bodyA , bodyB , previousCollision , pairActive ) {
3966 var minOverlap ,
40- collision ,
41- canReusePrevCol = false ;
67+ collision = previousCollision || SAT . create ( bodyA , bodyB ) ,
68+ canReusePrevCol ;
4269
43- if ( previousCollision ) {
70+ if ( pairActive && previousCollision . collided ) {
4471 // estimate total motion
4572 var parentA = bodyA . parent ,
4673 parentB = bodyB . parent ,
@@ -49,24 +76,18 @@ var Vector = require('../geometry/Vector');
4976
5077 // we may be able to (partially) reuse collision result
5178 // but only safe if collision was resting
52- canReusePrevCol = previousCollision && previousCollision . collided && motion < 0.2 ;
53-
54- // reuse collision object
55- collision = previousCollision ;
56- } else {
57- collision = { collided : false , bodyA : bodyA , bodyB : bodyB } ;
79+ canReusePrevCol = motion < 0.2 ;
5880 }
5981
60- if ( previousCollision && canReusePrevCol ) {
82+ if ( canReusePrevCol ) {
6183 // if we can reuse the collision result
6284 // we only need to test the previously found axis
63- var axisBodyA = collision . axisBody ,
64- axisBodyB = axisBodyA === bodyA ? bodyB : bodyA ,
85+ var axisBodyA = previousCollision . axisBodyA ,
86+ axisBodyB = previousCollision . axisBodyB ,
6587 axes = [ axisBodyA . axes [ previousCollision . axisNumber ] ] ;
6688
6789 SAT . _overlapAxes ( _overlapAB , axisBodyA . vertices , axisBodyB . vertices , axes ) ;
68- collision . reused = true ;
69-
90+
7091 if ( _overlapAB . overlap <= 0 ) {
7192 collision . collided = false ;
7293 return collision ;
@@ -92,10 +113,12 @@ var Vector = require('../geometry/Vector');
92113
93114 if ( _overlapAB . overlap < _overlapBA . overlap ) {
94115 minOverlap = _overlapAB ;
95- collision . axisBody = bodyA ;
116+ collision . axisBodyA = bodyA ;
117+ collision . axisBodyB = bodyB ;
96118 } else {
97119 minOverlap = _overlapBA ;
98- collision . axisBody = bodyB ;
120+ collision . axisBodyA = bodyB ;
121+ collision . axisBodyB = bodyA ;
99122 }
100123
101124 // important for reuse later
@@ -112,52 +135,51 @@ var Vector = require('../geometry/Vector');
112135 bodyA = collision . bodyA ;
113136 bodyB = collision . bodyB ;
114137
138+ var normal = collision . normal ,
139+ supports = collision . supports ;
140+
115141 // ensure normal is facing away from bodyA
116142 if ( Vector . dot ( minOverlap . axis , Vector . sub ( bodyB . position , bodyA . position ) ) < 0 ) {
117- collision . normal = {
118- x : minOverlap . axis . x ,
119- y : minOverlap . axis . y
120- } ;
143+ normal . x = minOverlap . axis . x ;
144+ normal . y = minOverlap . axis . y ;
121145 } else {
122- collision . normal = {
123- x : - minOverlap . axis . x ,
124- y : - minOverlap . axis . y
125- } ;
146+ normal . x = - minOverlap . axis . x ;
147+ normal . y = - minOverlap . axis . y ;
126148 }
127149
128- collision . tangent = Vector . perp ( collision . normal ) ;
150+ collision . tangent . x = - normal . y ;
151+ collision . tangent . y = normal . x ;
129152
130- collision . penetration = collision . penetration || { } ;
131- collision . penetration . x = collision . normal . x * collision . depth ;
132- collision . penetration . y = collision . normal . y * collision . depth ;
153+ collision . penetration . x = normal . x * collision . depth ;
154+ collision . penetration . y = normal . y * collision . depth ;
133155
134156 // find support points, there is always either exactly one or two
135- var verticesB = SAT . _findSupports ( bodyA , bodyB , collision . normal , 1 ) ,
136- supports = [ ] ;
157+ var supportsB = SAT . _findSupports ( bodyA , bodyB , collision . normal , 1 ) ;
158+
159+ // clear supports
160+ supports . length = 0 ;
137161
138162 // find the supports from bodyB that are inside bodyA
139- if ( Vertices . contains ( bodyA . vertices , verticesB [ 0 ] ) )
140- supports . push ( verticesB [ 0 ] ) ;
163+ if ( Vertices . contains ( bodyA . vertices , supportsB [ 0 ] ) )
164+ supports . push ( supportsB [ 0 ] ) ;
141165
142- if ( Vertices . contains ( bodyA . vertices , verticesB [ 1 ] ) )
143- supports . push ( verticesB [ 1 ] ) ;
166+ if ( Vertices . contains ( bodyA . vertices , supportsB [ 1 ] ) )
167+ supports . push ( supportsB [ 1 ] ) ;
144168
145169 // find the supports from bodyA that are inside bodyB
146170 if ( supports . length < 2 ) {
147- var verticesA = SAT . _findSupports ( bodyB , bodyA , collision . normal , - 1 ) ;
171+ var supportsA = SAT . _findSupports ( bodyB , bodyA , collision . normal , - 1 ) ;
148172
149- if ( Vertices . contains ( bodyB . vertices , verticesA [ 0 ] ) )
150- supports . push ( verticesA [ 0 ] ) ;
173+ if ( Vertices . contains ( bodyB . vertices , supportsA [ 0 ] ) )
174+ supports . push ( supportsA [ 0 ] ) ;
151175
152- if ( supports . length < 2 && Vertices . contains ( bodyB . vertices , verticesA [ 1 ] ) )
153- supports . push ( verticesA [ 1 ] ) ;
176+ if ( supports . length < 2 && Vertices . contains ( bodyB . vertices , supportsA [ 1 ] ) )
177+ supports . push ( supportsA [ 1 ] ) ;
154178 }
155179
156180 // account for the edge case of overlapping but no vertex containment
157- if ( supports . length < 1 )
158- supports = [ verticesB [ 0 ] ] ;
159-
160- collision . supports = supports ;
181+ if ( supports . length === 0 )
182+ supports . push ( supportsB [ 0 ] ) ;
161183
162184 return collision ;
163185 } ;
@@ -174,22 +196,26 @@ var Vector = require('../geometry/Vector');
174196 SAT . _overlapAxes = function ( result , verticesA , verticesB , axes ) {
175197 var verticesALength = verticesA . length ,
176198 verticesBLength = verticesB . length ,
199+ verticesAX = verticesA [ 0 ] . x ,
200+ verticesAY = verticesA [ 0 ] . y ,
201+ verticesBX = verticesB [ 0 ] . x ,
202+ verticesBY = verticesB [ 0 ] . y ,
177203 axesLength = axes . length ,
178- dot ,
204+ overlapMin = Number . MAX_VALUE ,
205+ overlapAxisNumber = 0 ,
179206 overlap ,
180207 overlapAB ,
181208 overlapBA ,
209+ dot ,
182210 i ,
183211 j ;
184212
185- result . overlap = Number . MAX_VALUE ;
186-
187213 for ( i = 0 ; i < axesLength ; i ++ ) {
188214 var axis = axes [ i ] ,
189215 axisX = axis . x ,
190216 axisY = axis . y ,
191- minA = verticesA [ 0 ] . x * axisX + verticesA [ 0 ] . y * axisY ,
192- minB = verticesB [ 0 ] . x * axisX + verticesB [ 0 ] . y * axisY ,
217+ minA = verticesAX * axisX + verticesAY * axisY ,
218+ minB = verticesBX * axisX + verticesBY * axisY ,
193219 maxA = minA ,
194220 maxB = minB ;
195221
@@ -217,18 +243,20 @@ var Vector = require('../geometry/Vector');
217243 overlapBA = maxB - minA ;
218244 overlap = overlapAB < overlapBA ? overlapAB : overlapBA ;
219245
220- if ( overlap <= 0 ) {
221- result . overlap = overlap ;
222- result . axisNumber = i ;
223- return ;
224- }
246+ if ( overlap < overlapMin ) {
247+ overlapMin = overlap ;
248+ overlapAxisNumber = i ;
225249
226- if ( overlap < result . overlap ) {
227- result . overlap = overlap ;
228- result . axis = axis ;
229- result . axisNumber = i ;
250+ if ( overlap <= 0 ) {
251+ // can not be intersecting
252+ break ;
253+ }
230254 }
231255 }
256+
257+ result . axis = axes [ overlapAxisNumber ] ;
258+ result . axisNumber = overlapAxisNumber ;
259+ result . overlap = overlapMin ;
232260 } ;
233261
234262 /**
0 commit comments