mirror of
https://github.com/liabru/matter-js.git
synced 2024-11-27 09:50:52 -05:00
composites are now an actual tree structure
This commit is contained in:
parent
f4dcb4bb1d
commit
2d52d53bf0
7 changed files with 108 additions and 58 deletions
|
@ -18,26 +18,22 @@ var Composite = {};
|
|||
* @return {composite} A new composite
|
||||
*/
|
||||
Composite.create = function(options) {
|
||||
return Common.extend({ bodies: [], constraints: [], composites: [] }, options);
|
||||
return Common.extend({
|
||||
bodies: [],
|
||||
constraints: [],
|
||||
composites: []
|
||||
}, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @method add
|
||||
* @method addComposite
|
||||
* @param {composite} compositeA
|
||||
* @param {composite} compositeB
|
||||
* @return {composite} The original compositeA with the objects from compositeB added
|
||||
*/
|
||||
Composite.add = function(compositeA, compositeB) {
|
||||
if (compositeA.bodies && compositeB.bodies)
|
||||
compositeA.bodies = compositeA.bodies.concat(compositeB.bodies);
|
||||
|
||||
if (compositeA.constraints && compositeB.constraints)
|
||||
compositeA.constraints = compositeA.constraints.concat(compositeB.constraints);
|
||||
|
||||
if (compositeA.composites && compositeB.composites)
|
||||
compositeA.composites = compositeA.composites.concat(compositeB.composites);
|
||||
|
||||
Composite.addComposite = function(compositeA, compositeB) {
|
||||
compositeA.composites.push(compositeB);
|
||||
return compositeA;
|
||||
};
|
||||
|
||||
|
@ -49,7 +45,6 @@ var Composite = {};
|
|||
* @return {composite} The original composite with the body added
|
||||
*/
|
||||
Composite.addBody = function(composite, body) {
|
||||
composite.bodies = composite.bodies || [];
|
||||
composite.bodies.push(body);
|
||||
return composite;
|
||||
};
|
||||
|
@ -62,9 +57,57 @@ var Composite = {};
|
|||
* @return {composite} The original composite with the constraint added
|
||||
*/
|
||||
Composite.addConstraint = function(composite, constraint) {
|
||||
composite.constraints = composite.constraints || [];
|
||||
composite.constraints.push(constraint);
|
||||
return composite;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all bodies in the given composite, including all bodies in its children, recursively
|
||||
* @method allBodies
|
||||
* @param {composite} composite
|
||||
* @return {body[]} All the bodies
|
||||
*/
|
||||
Composite.allBodies = function(composite) {
|
||||
var bodies = [].concat(composite.bodies);
|
||||
|
||||
for (var i = 0; i < composite.composites.length; i++)
|
||||
bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
|
||||
|
||||
return bodies;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all constraints in the given composite, including all constraints in its children, recursively
|
||||
* @method allConstraints
|
||||
* @param {composite} composite
|
||||
* @return {constraint[]} All the constraints
|
||||
*/
|
||||
Composite.allConstraints = function(composite) {
|
||||
var constraints = [].concat(composite.constraints);
|
||||
|
||||
for (var i = 0; i < composite.composites.length; i++)
|
||||
constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
|
||||
|
||||
return constraints;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes all bodies, constraints and composites from the given composite (non-recursive)
|
||||
* @method clear
|
||||
* @param {world} world
|
||||
* @param {boolean} keepStatic
|
||||
*/
|
||||
Composite.clear = function(composite, keepStatic) {
|
||||
if (keepStatic) {
|
||||
composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; });
|
||||
} else {
|
||||
composite.bodies.length = 0;
|
||||
}
|
||||
|
||||
composite.constraints.length = 0;
|
||||
composite.composites.length = 0;
|
||||
|
||||
return composite;
|
||||
};
|
||||
|
||||
})();
|
|
@ -17,33 +17,29 @@ var World = {};
|
|||
* @return {world} A new world
|
||||
*/
|
||||
World.create = function(options) {
|
||||
var composite = Composite.create();
|
||||
|
||||
var defaults = {
|
||||
gravity: { x: 0, y: 1 },
|
||||
bodies: [],
|
||||
constraints: [],
|
||||
bounds: {
|
||||
min: { x: 0, y: 0 },
|
||||
max: { x: 800, y: 600 }
|
||||
}
|
||||
};
|
||||
|
||||
return Common.extend(defaults, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @method clear
|
||||
* @param {world} world
|
||||
* @param {boolean} keepStatic
|
||||
*/
|
||||
World.clear = function(world, keepStatic) {
|
||||
world.bodies = keepStatic ? world.bodies.filter(function(body) { return body.isStatic; }) : [];
|
||||
world.constraints = [];
|
||||
return Common.extend(composite, defaults, options);
|
||||
};
|
||||
|
||||
// World is a Composite body
|
||||
// see src/module/Outro.js for these aliases:
|
||||
|
||||
/**
|
||||
* An alias for Composite.clear since World is also a Composite (see Outro.js)
|
||||
* @method clear
|
||||
* @param {world} world
|
||||
* @param {boolean} keepStatic
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias for Composite.add since World is also a Composite (see Outro.js)
|
||||
* @method addComposite
|
||||
|
|
|
@ -240,28 +240,31 @@ var Engine = {};
|
|||
broadphasePairs = [],
|
||||
i;
|
||||
|
||||
var allBodies = Composite.allBodies(world),
|
||||
allConstraints = Composite.allConstraints(world);
|
||||
|
||||
Metrics.reset(engine.metrics);
|
||||
|
||||
if (engine.enableSleeping)
|
||||
Sleeping.update(world.bodies);
|
||||
Sleeping.update(allBodies);
|
||||
|
||||
Body.applyGravityAll(world.bodies, world.gravity);
|
||||
Body.applyGravityAll(allBodies, world.gravity);
|
||||
|
||||
MouseConstraint.update(engine.mouseConstraint, world.bodies, engine.input);
|
||||
MouseConstraint.update(engine.mouseConstraint, allBodies, engine.input);
|
||||
|
||||
Body.updateAll(world.bodies, delta * engine.timeScale, correction, world.bounds);
|
||||
Body.updateAll(allBodies, delta * engine.timeScale, correction, world.bounds);
|
||||
|
||||
// update all constraints
|
||||
for (i = 0; i < engine.constraintIterations; i++) {
|
||||
Constraint.updateAll(world.constraints);
|
||||
Constraint.updateAll(allConstraints);
|
||||
}
|
||||
|
||||
// broadphase pass: find potential collision pairs
|
||||
if (broadphase.controller) {
|
||||
broadphase.controller.update(broadphase.instance, world.bodies, engine);
|
||||
broadphase.controller.update(broadphase.instance, allBodies, engine);
|
||||
broadphasePairs = broadphase.instance.pairsList;
|
||||
} else {
|
||||
broadphasePairs = world.bodies;
|
||||
broadphasePairs = allBodies;
|
||||
}
|
||||
|
||||
// narrowphase pass: find actual collisions, then create or update collision pairs
|
||||
|
@ -287,12 +290,12 @@ var Engine = {};
|
|||
for (i = 0; i < engine.positionIterations; i++) {
|
||||
Resolver.solvePosition(pairs.list);
|
||||
}
|
||||
Resolver.postSolvePosition(world.bodies);
|
||||
Resolver.postSolvePosition(allBodies);
|
||||
|
||||
Metrics.update(engine.metrics, engine);
|
||||
|
||||
// clear force buffers
|
||||
Body.resetForcesAll(world.bodies);
|
||||
Body.resetForcesAll(allBodies);
|
||||
|
||||
return engine;
|
||||
};
|
||||
|
@ -311,7 +314,7 @@ var Engine = {};
|
|||
|
||||
Engine.clear(engineA);
|
||||
|
||||
var bodies = engineA.world.bodies;
|
||||
var bodies = Composite.allBodies(engineA.world);
|
||||
|
||||
for (var i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
|
@ -324,7 +327,7 @@ var Engine = {};
|
|||
if (broadphase.controller === Grid) {
|
||||
var grid = broadphase.instance;
|
||||
Grid.clear(grid);
|
||||
Grid.update(grid, engineA.world.bodies, engineA, true);
|
||||
Grid.update(grid, bodies, engineA, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -348,7 +351,8 @@ var Engine = {};
|
|||
Grid.clear(broadphase.instance);
|
||||
|
||||
if (broadphase.controller) {
|
||||
broadphase.controller.update(broadphase.instance, world.bodies, engine, true);
|
||||
var bodies = Composite.allBodies(world);
|
||||
broadphase.controller.update(broadphase.instance, bodies, engine, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -64,14 +64,15 @@ var Metrics = {};
|
|||
Metrics.update = function(metrics, engine) {
|
||||
if (metrics.extended) {
|
||||
var world = engine.world,
|
||||
broadphase = engine.broadphase[engine.broadphase.current];
|
||||
broadphase = engine.broadphase[engine.broadphase.current],
|
||||
bodies = Composite.allBodies(world);
|
||||
|
||||
metrics.collisions = metrics.narrowDetections;
|
||||
metrics.pairs = engine.pairs.list.length;
|
||||
metrics.bodies = world.bodies.length;
|
||||
metrics.bodies = bodies.length;
|
||||
metrics.midEff = (metrics.narrowDetections / (metrics.midphaseTests || 1)).toFixed(2);
|
||||
metrics.narrowEff = (metrics.narrowDetections / (metrics.narrowphaseTests || 1)).toFixed(2);
|
||||
metrics.broadEff = (1 - (metrics.broadphaseTests / (world.bodies.length || 1))).toFixed(2);
|
||||
metrics.broadEff = (1 - (metrics.broadphaseTests / (bodies.length || 1))).toFixed(2);
|
||||
metrics.narrowReuse = (metrics.narrowReuseCount / (metrics.narrowphaseTests || 1)).toFixed(2);
|
||||
//if (broadphase.instance)
|
||||
// metrics.buckets = Common.keys(broadphase.instance.buckets).length;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// aliases
|
||||
|
||||
World.addComposite = Composite.add;
|
||||
World.addComposite = Composite.addComposite;
|
||||
World.addBody = Composite.addBody;
|
||||
World.addConstraint = Composite.addConstraint;
|
||||
World.clear = Composite.clear;
|
||||
|
||||
// exports
|
||||
|
||||
|
|
|
@ -91,6 +91,8 @@ var Render = {};
|
|||
canvas = render.canvas,
|
||||
context = render.context,
|
||||
options = render.options,
|
||||
bodies = Composite.allBodies(world),
|
||||
constraints = Composite.allConstraints(world),
|
||||
i;
|
||||
|
||||
if (options.wireframes) {
|
||||
|
@ -106,35 +108,35 @@ var Render = {};
|
|||
context.globalCompositeOperation = 'source-over';
|
||||
|
||||
/*if (options.showShadows && !options.wireframes)
|
||||
Render.bodyShadows(engine, world.bodies, context);*/
|
||||
Render.bodyShadows(engine, bodies, context);*/
|
||||
|
||||
if (!options.wireframes || (engine.enableSleeping && options.showSleeping)) {
|
||||
// fully featured rendering of bodies
|
||||
Render.bodies(engine, world.bodies, context);
|
||||
Render.bodies(engine, bodies, context);
|
||||
} else {
|
||||
// optimised method for wireframes only
|
||||
Render.bodyWireframes(engine, world.bodies, context);
|
||||
Render.bodyWireframes(engine, bodies, context);
|
||||
}
|
||||
|
||||
if (options.showBounds)
|
||||
Render.bodyBounds(engine, world.bodies, context);
|
||||
Render.bodyBounds(engine, bodies, context);
|
||||
|
||||
if (options.showAxes || options.showAngleIndicator)
|
||||
Render.bodyAxes(engine, world.bodies, context);
|
||||
Render.bodyAxes(engine, bodies, context);
|
||||
|
||||
if (options.showPositions)
|
||||
Render.bodyPositions(engine, world.bodies, context);
|
||||
Render.bodyPositions(engine, bodies, context);
|
||||
|
||||
if (options.showVelocity)
|
||||
Render.bodyVelocity(engine, world.bodies, context);
|
||||
Render.bodyVelocity(engine, bodies, context);
|
||||
|
||||
if (options.showIds)
|
||||
Render.bodyIds(engine, world.bodies, context);
|
||||
Render.bodyIds(engine, bodies, context);
|
||||
|
||||
if (options.showCollisions)
|
||||
Render.collisions(engine, engine.pairs.list, context);
|
||||
|
||||
Render.constraints(world.constraints, context);
|
||||
Render.constraints(constraints, context);
|
||||
|
||||
if (options.showBroadphase && engine.broadphase.current === 'grid')
|
||||
Render.grid(engine, engine.broadphase[engine.broadphase.current].instance, context);
|
||||
|
@ -154,6 +156,7 @@ var Render = {};
|
|||
world = engine.world,
|
||||
render = engine.render,
|
||||
options = render.options,
|
||||
bodies = Composite.allBodies(world),
|
||||
space = " ";
|
||||
|
||||
if (engine.timing.timestamp - (render.debugTimestamp || 0) >= 500) {
|
||||
|
@ -163,7 +166,7 @@ var Render = {};
|
|||
if (engine.metrics.extended) {
|
||||
text += "delta: " + engine.timing.delta.toFixed(3) + space;
|
||||
text += "correction: " + engine.timing.correction.toFixed(3) + space;
|
||||
text += "bodies: " + world.bodies.length + space;
|
||||
text += "bodies: " + bodies.length + space;
|
||||
|
||||
if (engine.broadphase.controller === Grid)
|
||||
text += "buckets: " + engine.metrics.buckets + space;
|
||||
|
|
|
@ -151,6 +151,8 @@ var RenderPixi = {};
|
|||
context = render.context,
|
||||
stage = render.stage,
|
||||
options = render.options,
|
||||
bodies = Composite.allBodies(world),
|
||||
constraints = Composite.allConstraints(world),
|
||||
i;
|
||||
|
||||
if (options.wireframes) {
|
||||
|
@ -159,11 +161,11 @@ var RenderPixi = {};
|
|||
RenderPixi.setBackground(render, options.background);
|
||||
}
|
||||
|
||||
for (i = 0; i < world.bodies.length; i++)
|
||||
RenderPixi.body(engine, world.bodies[i]);
|
||||
for (i = 0; i < bodies.length; i++)
|
||||
RenderPixi.body(engine, bodies[i]);
|
||||
|
||||
for (i = 0; i < world.constraints.length; i++)
|
||||
RenderPixi.constraint(engine, world.constraints[i]);
|
||||
for (i = 0; i < constraints.length; i++)
|
||||
RenderPixi.constraint(engine, constraints[i]);
|
||||
|
||||
context.render(stage);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue