Skip to content

Commit f554d6c

Browse files
committed
implemented compound bodies, added Body.setParts
1 parent b7bf5d6 commit f554d6c

File tree

6 files changed

+108
-22
lines changed

6 files changed

+108
-22
lines changed

src/body/Body.js

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ var Body = {};
117117
vertices: body.vertices,
118118
isStatic: body.isStatic,
119119
isSleeping: body.isSleeping,
120+
parent: body.parent || body,
120121
parts: body.parts || [body]
121122
});
122123

@@ -194,6 +195,9 @@ var Body = {};
194195
case 'angularVelocity':
195196
Body.setAngularVelocity(body, value);
196197
break;
198+
case 'parts':
199+
Body.setParts(body, value);
200+
break;
197201
default:
198202
body[property] = value;
199203

@@ -298,6 +302,78 @@ var Body = {};
298302
Bounds.update(body.bounds, body.vertices, body.velocity);
299303
};
300304

305+
/**
306+
* Sets the parts of the `body` and updates mass, inertia and centroid.
307+
* Each part will have its parent set to `body`.
308+
* By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.`
309+
* Note that this method will ensure that the first part in `body.parts` will always be the `body`.
310+
* @method setParts
311+
* @param {body} body
312+
* @param [body] parts
313+
* @param {bool} [autoHull=true]
314+
*/
315+
Body.setParts = function(body, parts, autoHull) {
316+
autoHull = typeof autoHull !== 'undefined' ? autoHull : true;
317+
318+
// ensure the body is always at index 0
319+
var index = Common.indexOf(parts, body);
320+
if (index > -1) {
321+
parts.splice(index, 1);
322+
}
323+
324+
parts.unshift(body);
325+
body.parts = parts;
326+
327+
if (parts.length === 1)
328+
return;
329+
330+
var i;
331+
332+
// find the convex hull of all parts to set on the parent body
333+
if (autoHull) {
334+
var vertices = [];
335+
for (i = 1; i < parts.length; i++) {
336+
vertices = vertices.concat(parts[i].vertices);
337+
}
338+
339+
Vertices.clockwiseSort(vertices);
340+
341+
var hull = Vertices.hull(vertices),
342+
hullCentre = Vertices.centre(hull);
343+
344+
Body.setVertices(body, hull);
345+
Body.setPosition(body, hullCentre);
346+
}
347+
348+
// find the combined properties of all parts to set on the parent body
349+
var mass = 0,
350+
area = 0,
351+
inertia = 0,
352+
centroid = { x: 0, y: 0 };
353+
354+
for (i = 1; i < parts.length; i++) {
355+
var part = parts[i];
356+
part.parent = body;
357+
mass += part.mass;
358+
area += part.area;
359+
inertia += part.inertia;
360+
Vector.add(centroid, part.position, centroid);
361+
}
362+
363+
centroid = Vector.div(centroid, parts.length - 1);
364+
365+
body.area = area;
366+
body.parent = body;
367+
body.position.x = centroid.x;
368+
body.position.y = centroid.y;
369+
body.positionPrev.x = centroid.x;
370+
body.positionPrev.y = centroid.y;
371+
372+
Body.setMass(body, mass);
373+
Body.setInertia(body, inertia);
374+
Body.setPosition(body, centroid);
375+
};
376+
301377
/**
302378
* Sets the position of the body instantly. Velocity, angle, force etc. are unchanged.
303379
* @method setPosition
@@ -314,8 +390,6 @@ var Body = {};
314390

315391
Vertices.translate(body.vertices, delta);
316392
Bounds.update(body.bounds, body.vertices, body.velocity);
317-
318-
//Common.each(body.children, Body.setPosition, position);
319393
};
320394

321395
/**
@@ -333,8 +407,6 @@ var Body = {};
333407
Vertices.rotate(body.vertices, delta, body.position);
334408
Axes.rotate(body.axes, delta);
335409
Bounds.update(body.bounds, body.vertices, body.velocity);
336-
337-
//Common.each(body.children, Body.setAngle, angle);
338410
};
339411

340412
/**
@@ -452,6 +524,10 @@ var Body = {};
452524
Axes.rotate(part.axes, body.angularVelocity);
453525
}
454526
Bounds.update(part.bounds, body.vertices, body.velocity);
527+
if (i > 0) {
528+
part.position.x += body.velocity.x;
529+
part.position.y += body.velocity.y;
530+
}
455531
}
456532
};
457533

src/collision/Detector.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,15 @@ var Detector = {};
4141

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

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

50-
if (Bounds.overlaps(partA.bounds, partB.bounds)) {*/
51-
50+
if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
5251
// find a previous collision we could reuse
53-
var pairId = Pair.id(bodyA, bodyB),
52+
var pairId = Pair.id(partA, partB),
5453
pair = pairsTable[pairId],
5554
previousCollision;
5655

@@ -61,7 +60,7 @@ var Detector = {};
6160
}
6261

6362
// narrow phase
64-
var collision = SAT.collides(bodyA, bodyB, previousCollision);
63+
var collision = SAT.collides(partA, partB, previousCollision);
6564

6665
// @if DEBUG
6766
metrics.narrowphaseTests += 1;
@@ -75,9 +74,9 @@ var Detector = {};
7574
metrics.narrowDetections += 1;
7675
// @endif
7776
}
78-
//}
79-
//}
80-
//}
77+
}
78+
}
79+
}
8180
}
8281
}
8382

src/collision/Resolver.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ var Resolver = {};
4040
continue;
4141

4242
collision = pair.collision;
43-
bodyA = collision.bodyA;
44-
bodyB = collision.bodyB;
43+
bodyA = collision.parentA;
44+
bodyB = collision.parentB;
4545
vertex = collision.supports[0];
4646
vertexCorrected = collision.supportCorrected;
4747
normal = collision.normal;
@@ -61,8 +61,8 @@ var Resolver = {};
6161
continue;
6262

6363
collision = pair.collision;
64-
bodyA = collision.bodyA;
65-
bodyB = collision.bodyB;
64+
bodyA = collision.parentA;
65+
bodyB = collision.parentB;
6666
normal = collision.normal;
6767
positionImpulse = ((pair.separation * _positionDampen) - pair.slop) * timeScale;
6868

@@ -102,6 +102,10 @@ var Resolver = {};
102102
var part = body.parts[j];
103103
Vertices.translate(part.vertices, body.positionImpulse);
104104
Bounds.update(part.bounds, body.vertices, body.velocity);
105+
if (j > 0) {
106+
part.position.x += body.positionImpulse.x;
107+
part.position.y += body.positionImpulse.y;
108+
}
105109
}
106110

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

143147
contacts = pair.activeContacts;
144148
collision = pair.collision;
145-
bodyA = collision.bodyA;
146-
bodyB = collision.bodyB;
149+
bodyA = collision.parentA;
150+
bodyB = collision.parentB;
147151
normal = collision.normal;
148152
tangent = collision.tangent;
149153

@@ -197,8 +201,8 @@ var Resolver = {};
197201
continue;
198202

199203
var collision = pair.collision,
200-
bodyA = collision.bodyA,
201-
bodyB = collision.bodyB,
204+
bodyA = collision.parentA,
205+
bodyB = collision.parentB,
202206
normal = collision.normal,
203207
tangent = collision.tangent,
204208
contacts = pair.activeContacts,

src/collision/SAT.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ var SAT = {};
8787
collision.collided = true;
8888
collision.normal = minOverlap.axis;
8989
collision.depth = minOverlap.overlap;
90+
collision.parentA = collision.bodyA.parent;
91+
collision.parentB = collision.bodyB.parent;
9092

9193
bodyA = collision.bodyA;
9294
bodyB = collision.bodyB;

src/constraint/Constraint.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ var Constraint = {};
260260
}
261261

262262
Bounds.update(part.bounds, body.vertices);
263+
264+
if (j > 0) {
265+
part.position.x += impulse.x;
266+
part.position.y += impulse.y;
267+
}
263268
}
264269

265270
impulse.x = 0;

src/geometry/Vertices.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ var Vertices = {};
337337
});
338338

339339
return vertices;
340-
}
340+
};
341341

342342
/**
343343
* Returns the convex hull of the input vertices as a new array of points.

0 commit comments

Comments
 (0)