0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-11-23 09:26:51 -05:00

implemented compound bodies, added Body.setParts

This commit is contained in:
liabru 2015-02-01 00:03:40 +00:00
parent b7bf5d6643
commit f554d6c9a6
6 changed files with 108 additions and 22 deletions

View file

@ -117,6 +117,7 @@ var Body = {};
vertices: body.vertices,
isStatic: body.isStatic,
isSleeping: body.isSleeping,
parent: body.parent || body,
parts: body.parts || [body]
});
@ -194,6 +195,9 @@ var Body = {};
case 'angularVelocity':
Body.setAngularVelocity(body, value);
break;
case 'parts':
Body.setParts(body, value);
break;
default:
body[property] = value;
@ -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
@ -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);
};
/**
@ -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);
};
/**
@ -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;
}
}
};

View file

@ -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;
@ -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;
@ -75,9 +74,9 @@ var Detector = {};
metrics.narrowDetections += 1;
// @endif
}
//}
//}
//}
}
}
}
}
}

View file

@ -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;
@ -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;
@ -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
@ -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;
@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -337,7 +337,7 @@ var Vertices = {};
});
return vertices;
}
};
/**
* Returns the convex hull of the input vertices as a new array of points.