Skip to content

Commit

Permalink
implemented compound bodies, added Body.setParts
Browse files Browse the repository at this point in the history
  • Loading branch information
liabru committed Feb 1, 2015
1 parent b7bf5d6 commit f554d6c
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 22 deletions.
84 changes: 80 additions & 4 deletions src/body/Body.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ var Body = {};
vertices: body.vertices,
isStatic: body.isStatic,
isSleeping: body.isSleeping,
parent: body.parent || body,
parts: body.parts || [body]
});

Expand Down Expand Up @@ -194,6 +195,9 @@ var Body = {};
case 'angularVelocity':
Body.setAngularVelocity(body, value);
break;
case 'parts':
Body.setParts(body, value);
break;
default:
body[property] = value;

Expand Down Expand Up @@ -298,6 +302,78 @@ var Body = {};
Bounds.update(body.bounds, body.vertices, body.velocity);
};

/**
* Sets the parts of the `body` and updates mass, inertia and centroid.
* Each part will have its parent set to `body`.
* By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.`
* Note that this method will ensure that the first part in `body.parts` will always be the `body`.
* @method setParts
* @param {body} body
* @param [body] parts
* @param {bool} [autoHull=true]
*/
Body.setParts = function(body, parts, autoHull) {
autoHull = typeof autoHull !== 'undefined' ? autoHull : true;

// ensure the body is always at index 0
var index = Common.indexOf(parts, body);
if (index > -1) {
parts.splice(index, 1);
}

parts.unshift(body);
body.parts = parts;

if (parts.length === 1)
return;

var i;

// find the convex hull of all parts to set on the parent body
if (autoHull) {
var vertices = [];
for (i = 1; i < parts.length; i++) {
vertices = vertices.concat(parts[i].vertices);
}

Vertices.clockwiseSort(vertices);

var hull = Vertices.hull(vertices),
hullCentre = Vertices.centre(hull);

Body.setVertices(body, hull);
Body.setPosition(body, hullCentre);
}

// find the combined properties of all parts to set on the parent body
var mass = 0,
area = 0,
inertia = 0,
centroid = { x: 0, y: 0 };

for (i = 1; i < parts.length; i++) {
var part = parts[i];
part.parent = body;
mass += part.mass;
area += part.area;
inertia += part.inertia;
Vector.add(centroid, part.position, centroid);
}

centroid = Vector.div(centroid, parts.length - 1);

body.area = area;
body.parent = body;
body.position.x = centroid.x;
body.position.y = centroid.y;
body.positionPrev.x = centroid.x;
body.positionPrev.y = centroid.y;

Body.setMass(body, mass);
Body.setInertia(body, inertia);
Body.setPosition(body, centroid);
};

/**
* Sets the position of the body instantly. Velocity, angle, force etc. are unchanged.
* @method setPosition
Expand All @@ -314,8 +390,6 @@ var Body = {};

Vertices.translate(body.vertices, delta);
Bounds.update(body.bounds, body.vertices, body.velocity);

//Common.each(body.children, Body.setPosition, position);
};

/**
Expand All @@ -333,8 +407,6 @@ var Body = {};
Vertices.rotate(body.vertices, delta, body.position);
Axes.rotate(body.axes, delta);
Bounds.update(body.bounds, body.vertices, body.velocity);

//Common.each(body.children, Body.setAngle, angle);
};

/**
Expand Down Expand Up @@ -452,6 +524,10 @@ var Body = {};
Axes.rotate(part.axes, body.angularVelocity);
}
Bounds.update(part.bounds, body.vertices, body.velocity);
if (i > 0) {
part.position.x += body.velocity.x;
part.position.y += body.velocity.y;
}
}
};

Expand Down
17 changes: 8 additions & 9 deletions src/collision/Detector.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,15 @@ var Detector = {};

// mid phase
if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
/*for (var j = 1; j < bodyA.parts.length; j++) {
for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
var partA = bodyA.parts[j];

for (var k = 1; k < bodyB.parts.length; k++) {
for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) {
var partB = bodyB.parts[k];

if (Bounds.overlaps(partA.bounds, partB.bounds)) {*/

if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
// find a previous collision we could reuse
var pairId = Pair.id(bodyA, bodyB),
var pairId = Pair.id(partA, partB),
pair = pairsTable[pairId],
previousCollision;

Expand All @@ -61,7 +60,7 @@ var Detector = {};
}

// narrow phase
var collision = SAT.collides(bodyA, bodyB, previousCollision);
var collision = SAT.collides(partA, partB, previousCollision);

// @if DEBUG
metrics.narrowphaseTests += 1;
Expand All @@ -75,9 +74,9 @@ var Detector = {};
metrics.narrowDetections += 1;
// @endif
}
//}
//}
//}
}
}
}
}
}

Expand Down
20 changes: 12 additions & 8 deletions src/collision/Resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ var Resolver = {};
continue;

collision = pair.collision;
bodyA = collision.bodyA;
bodyB = collision.bodyB;
bodyA = collision.parentA;
bodyB = collision.parentB;
vertex = collision.supports[0];
vertexCorrected = collision.supportCorrected;
normal = collision.normal;
Expand All @@ -61,8 +61,8 @@ var Resolver = {};
continue;

collision = pair.collision;
bodyA = collision.bodyA;
bodyB = collision.bodyB;
bodyA = collision.parentA;
bodyB = collision.parentB;
normal = collision.normal;
positionImpulse = ((pair.separation * _positionDampen) - pair.slop) * timeScale;

Expand Down Expand Up @@ -102,6 +102,10 @@ var Resolver = {};
var part = body.parts[j];
Vertices.translate(part.vertices, body.positionImpulse);
Bounds.update(part.bounds, body.vertices, body.velocity);
if (j > 0) {
part.position.x += body.positionImpulse.x;
part.position.y += body.positionImpulse.y;
}
}

// dampen accumulator to warm the next step
Expand Down Expand Up @@ -142,8 +146,8 @@ var Resolver = {};

contacts = pair.activeContacts;
collision = pair.collision;
bodyA = collision.bodyA;
bodyB = collision.bodyB;
bodyA = collision.parentA;
bodyB = collision.parentB;
normal = collision.normal;
tangent = collision.tangent;

Expand Down Expand Up @@ -197,8 +201,8 @@ var Resolver = {};
continue;

var collision = pair.collision,
bodyA = collision.bodyA,
bodyB = collision.bodyB,
bodyA = collision.parentA,
bodyB = collision.parentB,
normal = collision.normal,
tangent = collision.tangent,
contacts = pair.activeContacts,
Expand Down
2 changes: 2 additions & 0 deletions src/collision/SAT.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ var SAT = {};
collision.collided = true;
collision.normal = minOverlap.axis;
collision.depth = minOverlap.overlap;
collision.parentA = collision.bodyA.parent;
collision.parentB = collision.bodyB.parent;

bodyA = collision.bodyA;
bodyB = collision.bodyB;
Expand Down
5 changes: 5 additions & 0 deletions src/constraint/Constraint.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ var Constraint = {};
}

Bounds.update(part.bounds, body.vertices);

if (j > 0) {
part.position.x += impulse.x;
part.position.y += impulse.y;
}
}

impulse.x = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/geometry/Vertices.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ var Vertices = {};
});

return vertices;
}
};

/**
* Returns the convex hull of the input vertices as a new array of points.
Expand Down

0 comments on commit f554d6c

Please sign in to comment.