0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-12-26 13:49:01 -05:00

improved collision detection for compounds

This commit is contained in:
liabru 2015-02-10 23:40:05 +00:00
parent 5ab2bf30f0
commit 84d9f591aa
3 changed files with 34 additions and 20 deletions

View file

@ -28,8 +28,10 @@ var SAT = {};
if (prevCol) { if (prevCol) {
// estimate total motion // estimate total motion
var motion = bodyA.speed * bodyA.speed + bodyA.angularSpeed * bodyA.angularSpeed var parentA = bodyA.parent,
+ bodyB.speed * bodyB.speed + bodyB.angularSpeed * bodyB.angularSpeed; 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 // we may be able to (partially) reuse collision result
// but only safe if collision was resting // but only safe if collision was resting
@ -113,7 +115,7 @@ var SAT = {};
if (Vertices.contains(bodyA.vertices, verticesB[0])) if (Vertices.contains(bodyA.vertices, verticesB[0]))
supports.push(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]); supports.push(verticesB[1]);
// find the supports from bodyA that are inside bodyB // find the supports from bodyA that are inside bodyB
@ -123,12 +125,12 @@ var SAT = {};
if (Vertices.contains(bodyB.vertices, verticesA[0])) if (Vertices.contains(bodyB.vertices, verticesA[0]))
supports.push(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]); supports.push(verticesA[1]);
} }
// account for the edge case of overlapping but no vertex containment // account for the edge case of overlapping but no vertex containment
if (supports.length < 2) if (supports.length < 1)
supports = [verticesB[0]]; supports = [verticesB[0]];
collision.supports = supports; collision.supports = supports;
@ -220,8 +222,8 @@ var SAT = {};
bodyAPosition = bodyA.position, bodyAPosition = bodyA.position,
distance, distance,
vertex, vertex,
vertexA = vertices[0], vertexA,
vertexB = vertices[1]; vertexB;
// find closest vertex on bodyB // find closest vertex on bodyB
for (var i = 0; i < vertices.length; i++) { for (var i = 0; i < vertices.length; i++) {
@ -244,6 +246,8 @@ var SAT = {};
nearestDistance = -Vector.dot(normal, vertexToBody); nearestDistance = -Vector.dot(normal, vertexToBody);
vertexB = vertex; 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; var nextIndex = (vertexA.index + 1) % vertices.length;
vertex = vertices[nextIndex]; vertex = vertices[nextIndex];
vertexToBody.x = vertex.x - bodyAPosition.x; vertexToBody.x = vertex.x - bodyAPosition.x;
@ -252,6 +256,10 @@ var SAT = {};
if (distance < nearestDistance) { if (distance < nearestDistance) {
vertexB = vertex; vertexB = vertex;
} }
}
if (!vertexB)
return [vertexA];
return [vertexA, vertexB]; return [vertexA, vertexB];
}; };

View file

@ -19,6 +19,11 @@ var Axes = {};
// find the unique axes, using edge normal gradients // find the unique axes, using edge normal gradients
for (var i = 0; i < vertices.length; i++) { for (var i = 0; i < vertices.length; i++) {
// skip internal edges
if (vertices[i].isInternal) {
continue;
}
var j = (i + 1) % vertices.length, var j = (i + 1) % vertices.length,
normal = Vector.normalise({ normal = Vector.normalise({
x: vertices[j].y - vertices[i].y, x: vertices[j].y - vertices[i].y,

View file

@ -35,12 +35,13 @@ var Vertices = {};
for (var i = 0; i < points.length; i++) { for (var i = 0; i < points.length; i++) {
var point = points[i], var point = points[i],
vertex = {}; vertex = {
x: point.x,
vertex.x = point.x; y: point.y,
vertex.y = point.y; index: i,
vertex.index = i; body: body,
vertex.body = body; isInternal: false
};
vertices.push(vertex); vertices.push(vertex);
} }