Skip to content

Commit 0d90a17

Browse files
committed
optimised SAT._findSupports
1 parent efede6e commit 0d90a17

1 file changed

Lines changed: 36 additions & 39 deletions

File tree

src/collision/SAT.js

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ var Vector = require('../geometry/Vector');
120120
collision.penetration.y = collision.normal.y * collision.depth;
121121

122122
// find support points, there is always either exactly one or two
123-
var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal),
123+
var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal, 1),
124124
supports = [];
125125

126126
// find the supports from bodyB that are inside bodyA
@@ -132,8 +132,8 @@ var Vector = require('../geometry/Vector');
132132

133133
// find the supports from bodyA that are inside bodyB
134134
if (supports.length < 2) {
135-
var verticesA = SAT._findSupports(bodyB, bodyA, Vector.neg(collision.normal));
136-
135+
var verticesA = SAT._findSupports(bodyB, bodyA, collision.normal, -1);
136+
137137
if (Vertices.contains(bodyB.vertices, verticesA[0]))
138138
supports.push(verticesA[0]);
139139

@@ -183,7 +183,7 @@ var Vector = require('../geometry/Vector');
183183
result.overlap = overlap;
184184
result.axis = axis;
185185
result.axisNumber = i;
186-
}
186+
}
187187
}
188188

189189
return result;
@@ -214,57 +214,54 @@ var Vector = require('../geometry/Vector');
214214
projection.min = min;
215215
projection.max = max;
216216
};
217-
217+
218218
/**
219219
* Finds supporting vertices given two bodies along a given direction using hill-climbing.
220220
* @method _findSupports
221221
* @private
222-
* @param {} bodyA
223-
* @param {} bodyB
224-
* @param {} normal
222+
* @param {body} bodyA
223+
* @param {body} bodyB
224+
* @param {vector} normal
225+
* @param {number} direction
225226
* @return [vector]
226227
*/
227-
SAT._findSupports = function(bodyA, bodyB, normal) {
228-
var nearestDistance = Number.MAX_VALUE,
229-
vertexToBody = Vector._temp[0],
230-
vertices = bodyB.vertices,
231-
bodyAPosition = bodyA.position,
232-
distance,
233-
vertex,
228+
SAT._findSupports = function(bodyA, bodyB, normal, direction) {
229+
var vertices = bodyB.vertices,
230+
verticesLength = vertices.length,
231+
bodyAPositionX = bodyA.position.x,
232+
bodyAPositionY = bodyA.position.y,
233+
normalX = normal.x * direction,
234+
normalY = normal.y * direction,
235+
nearestDistance = Infinity,
234236
vertexA,
235-
vertexB;
237+
vertexB,
238+
vertexC,
239+
distance,
240+
j;
236241

237-
// find closest vertex on bodyB
238-
for (var i = 0; i < vertices.length; i++) {
239-
vertex = vertices[i];
240-
vertexToBody.x = vertex.x - bodyAPosition.x;
241-
vertexToBody.y = vertex.y - bodyAPosition.y;
242-
distance = -Vector.dot(normal, vertexToBody);
242+
// find deepest vertex relative to the axis
243+
for (j = 0; j < verticesLength; j += 1) {
244+
vertexB = vertices[j];
245+
distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y);
243246

247+
// convex hill-climbing
244248
if (distance < nearestDistance) {
245249
nearestDistance = distance;
246-
vertexA = vertex;
250+
vertexA = vertexB;
247251
}
248252
}
249253

250-
// find next closest vertex using the two connected to it
251-
var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
252-
vertex = vertices[prevIndex];
253-
vertexToBody.x = vertex.x - bodyAPosition.x;
254-
vertexToBody.y = vertex.y - bodyAPosition.y;
255-
nearestDistance = -Vector.dot(normal, vertexToBody);
256-
vertexB = vertex;
257-
258-
var nextIndex = (vertexA.index + 1) % vertices.length;
259-
vertex = vertices[nextIndex];
260-
vertexToBody.x = vertex.x - bodyAPosition.x;
261-
vertexToBody.y = vertex.y - bodyAPosition.y;
262-
distance = -Vector.dot(normal, vertexToBody);
263-
if (distance < nearestDistance) {
264-
vertexB = vertex;
254+
// measure next vertex
255+
vertexC = vertices[(verticesLength + vertexA.index - 1) % verticesLength];
256+
nearestDistance = normalX * (bodyAPositionX - vertexC.x) + normalY * (bodyAPositionY - vertexC.y);
257+
258+
// compare with previous vertex
259+
vertexB = vertices[(vertexA.index + 1) % verticesLength];
260+
if (normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y) < nearestDistance) {
261+
return [vertexA, vertexB];
265262
}
266263

267-
return [vertexA, vertexB];
264+
return [vertexA, vertexC];
268265
};
269266

270267
})();

0 commit comments

Comments
 (0)