Skip to content

Commit

Permalink
improved collision detection for compounds
Browse files Browse the repository at this point in the history
  • Loading branch information
liabru committed Feb 10, 2015
1 parent 5ab2bf3 commit 84d9f59
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 20 deletions.
36 changes: 22 additions & 14 deletions src/collision/SAT.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ var SAT = {};

if (prevCol) {
// estimate total motion
var motion = bodyA.speed * bodyA.speed + bodyA.angularSpeed * bodyA.angularSpeed
+ bodyB.speed * bodyB.speed + bodyB.angularSpeed * bodyB.angularSpeed;
var parentA = bodyA.parent,
parentB = bodyB.parent,
motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
+ parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;

// we may be able to (partially) reuse collision result
// but only safe if collision was resting
Expand Down Expand Up @@ -113,7 +115,7 @@ var SAT = {};
if (Vertices.contains(bodyA.vertices, verticesB[0]))
supports.push(verticesB[0]);

if (Vertices.contains(bodyA.vertices, verticesB[1]))
if (verticesB[1] && Vertices.contains(bodyA.vertices, verticesB[1]))
supports.push(verticesB[1]);

// find the supports from bodyA that are inside bodyB
Expand All @@ -123,12 +125,12 @@ var SAT = {};
if (Vertices.contains(bodyB.vertices, verticesA[0]))
supports.push(verticesA[0]);

if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
if (verticesA[1] && supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
supports.push(verticesA[1]);
}

// account for the edge case of overlapping but no vertex containment
if (supports.length < 2)
if (supports.length < 1)
supports = [verticesB[0]];

collision.supports = supports;
Expand Down Expand Up @@ -220,8 +222,8 @@ var SAT = {};
bodyAPosition = bodyA.position,
distance,
vertex,
vertexA = vertices[0],
vertexB = vertices[1];
vertexA,
vertexB;

// find closest vertex on bodyB
for (var i = 0; i < vertices.length; i++) {
Expand All @@ -244,15 +246,21 @@ var SAT = {};
nearestDistance = -Vector.dot(normal, vertexToBody);
vertexB = vertex;

var nextIndex = (vertexA.index + 1) % vertices.length;
vertex = vertices[nextIndex];
vertexToBody.x = vertex.x - bodyAPosition.x;
vertexToBody.y = vertex.y - bodyAPosition.y;
distance = -Vector.dot(normal, vertexToBody);
if (distance < nearestDistance) {
vertexB = vertex;
// if the closest vertex is internal, we can't use the next connected vertex
if (!vertexA.isInternal) {
var nextIndex = (vertexA.index + 1) % vertices.length;
vertex = vertices[nextIndex];
vertexToBody.x = vertex.x - bodyAPosition.x;
vertexToBody.y = vertex.y - bodyAPosition.y;
distance = -Vector.dot(normal, vertexToBody);
if (distance < nearestDistance) {
vertexB = vertex;
}
}

if (!vertexB)
return [vertexA];

return [vertexA, vertexB];
};

Expand Down
5 changes: 5 additions & 0 deletions src/geometry/Axes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ var Axes = {};

// find the unique axes, using edge normal gradients
for (var i = 0; i < vertices.length; i++) {
// skip internal edges
if (vertices[i].isInternal) {
continue;
}

var j = (i + 1) % vertices.length,
normal = Vector.normalise({
x: vertices[j].y - vertices[i].y,
Expand Down
13 changes: 7 additions & 6 deletions src/geometry/Vertices.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ var Vertices = {};

for (var i = 0; i < points.length; i++) {
var point = points[i],
vertex = {};

vertex.x = point.x;
vertex.y = point.y;
vertex.index = i;
vertex.body = body;
vertex = {
x: point.x,
y: point.y,
index: i,
body: body,
isInternal: false
};

vertices.push(vertex);
}
Expand Down

0 comments on commit 84d9f59

Please sign in to comment.