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

composites now support removals (implemented isModified flag)

This commit is contained in:
liabru 2014-03-24 19:48:23 +00:00
parent 4514f2d598
commit b253683cb5
5 changed files with 187 additions and 35 deletions

View file

@ -11,6 +11,8 @@ var Composite = {};
(function() { (function() {
var _nextId = 0;
/** /**
* Description * Description
* @method create * @method create
@ -19,12 +21,49 @@ var Composite = {};
*/ */
Composite.create = function(options) { Composite.create = function(options) {
return Common.extend({ return Common.extend({
id: Composite.nextId(),
parent: null,
isModified: false,
bodies: [], bodies: [],
constraints: [], constraints: [],
composites: [] composites: []
}, options); }, options);
}; };
/**
* Returns the next unique compositeID
* @method nextId
* @return {Number} Unique compositeID
*/
Composite.nextId = function() {
return _nextId++;
};
/**
* Sets the composite's `isModified` flag.
* If `updateParents` is true, all parents will be set (default: false).
* If `updateChildren` is true, all children will be set (default: false).
* @method setModified
* @param {composite} composite
* @param {boolean} isModified
* @param {boolean} updateParents
* @param {boolean} updateChildren
*/
Composite.setModified = function(composite, isModified, updateParents, updateChildren) {
composite.isModified = isModified;
if (updateParents && composite.parent) {
Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
}
if (updateChildren) {
for(var i = 0; i < composite.composites.length; i++) {
var childComposite = composite.composites[i];
Composite.setModified(childComposite, isModified, updateParents, updateChildren);
}
}
};
/** /**
* Description * Description
* @method addComposite * @method addComposite
@ -34,6 +73,8 @@ var Composite = {};
*/ */
Composite.addComposite = function(compositeA, compositeB) { Composite.addComposite = function(compositeA, compositeB) {
compositeA.composites.push(compositeB); compositeA.composites.push(compositeB);
compositeB.parent = compositeA;
Composite.setModified(compositeA, true, true, false);
return compositeA; return compositeA;
}; };
@ -46,6 +87,44 @@ var Composite = {};
*/ */
Composite.addBody = function(composite, body) { Composite.addBody = function(composite, body) {
composite.bodies.push(body); composite.bodies.push(body);
Composite.setModified(composite, true, true, false);
return composite;
};
/**
* Removes a body from the given composite, and optionally searching its children recursively
* @method removeBody
* @param {composite} composite
* @param {body} body
* @param {boolean} deep
* @return {composite} The original composite with the body removed
*/
Composite.removeBody = function(composite, body, deep) {
var position = composite.bodies.indexOf(body);
if (position !== -1) {
Composite.removeBodyAt(composite, position);
Composite.setModified(composite, true, true, false);
}
if (deep) {
for (var i = 0; i < composite.composites.length; i++){
Composite.removeBody(composite.composites[i], body, true);
}
}
return composite;
};
/**
* Removes a body from the given composite
* @method removeBodyAt
* @param {composite} composite
* @param {number} position
* @return {composite} The original composite with the body removed
*/
Composite.removeBodyAt = function(composite, position) {
composite.bodies.splice(position, 1);
Composite.setModified(composite, true, true, false);
return composite; return composite;
}; };
@ -58,6 +137,71 @@ var Composite = {};
*/ */
Composite.addConstraint = function(composite, constraint) { Composite.addConstraint = function(composite, constraint) {
composite.constraints.push(constraint); composite.constraints.push(constraint);
Composite.setModified(composite, true, true, false);
return composite;
};
/**
* Removes a constraint from the given composite, and optionally searching its children recursively
* @method removeConstraint
* @param {composite} composite
* @param {constraint} constraint
* @param {boolean} deep
* @return {composite} The original composite with the constraint removed
*/
Composite.removeConstraint = function(composite, constraint, deep) {
var position = composite.constraints.indexOf(constraint);
if (position !== -1) {
Composite.removeConstraintAt(composite, position);
}
if (deep) {
for (var i = 0; i < composite.composites.length; i++){
Composite.removeConstraint(composite.composites[i], constraint, true);
}
}
return composite;
};
/**
* Removes a body from the given composite
* @method removeConstraintAt
* @param {composite} composite
* @param {number} position
* @return {composite} The original composite with the constraint removed
*/
Composite.removeConstraintAt = function(composite, position) {
composite.constraints.splice(position, 1);
Composite.setModified(composite, true, true, false);
return composite;
};
/**
* Removes all bodies, constraints and composites from the given composite
* Optionally clearing its children recursively
* @method clear
* @param {world} world
* @param {boolean} keepStatic
* @param {boolean} deep
*/
Composite.clear = function(composite, keepStatic, deep) {
if (deep) {
for (var i = 0; i < composite.composites.length; i++){
Composite.clear(composite.composites[i], keepStatic, true);
}
}
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;
Composite.setModified(composite, true, true, false);
return composite; return composite;
}; };
@ -91,23 +235,4 @@ var Composite = {};
return constraints; 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;
};
})(); })();

View file

@ -48,7 +48,7 @@ var Grid = {};
for (i = 0; i < bodies.length; i++) { for (i = 0; i < bodies.length; i++) {
var body = bodies[i]; var body = bodies[i];
if (body.isSleeping) if (body.isSleeping && !forceUpdate)
continue; continue;
// don't update out of world bodies // don't update out of world bodies

View file

@ -167,6 +167,10 @@ var Engine = {};
*/ */
Events.trigger(engine, 'tick beforeUpdate', event); Events.trigger(engine, 'tick beforeUpdate', event);
// if world has been modified, clear the render scene graph
if (engine.world.isModified)
engine.render.controller.clear(engine.render);
// update // update
Engine.update(engine, delta, correction); Engine.update(engine, delta, correction);
@ -234,18 +238,24 @@ var Engine = {};
broadphasePairs = [], broadphasePairs = [],
i; i;
// get lists of all bodies and constraints, no matter what composites they are in
var allBodies = Composite.allBodies(world), var allBodies = Composite.allBodies(world),
allConstraints = Composite.allConstraints(world); allConstraints = Composite.allConstraints(world);
// reset metrics logging
Metrics.reset(engine.metrics); Metrics.reset(engine.metrics);
// if sleeping enabled, call the sleeping controller
if (engine.enableSleeping) if (engine.enableSleeping)
Sleeping.update(allBodies); Sleeping.update(allBodies);
// applies gravity to all bodies
Body.applyGravityAll(allBodies, world.gravity); Body.applyGravityAll(allBodies, world.gravity);
// update the mouse constraint
MouseConstraint.update(engine.mouseConstraint, allBodies, engine.input); MouseConstraint.update(engine.mouseConstraint, allBodies, engine.input);
// update all body position and rotation by integration
Body.updateAll(allBodies, delta * engine.timeScale, correction, world.bounds); Body.updateAll(allBodies, delta * engine.timeScale, correction, world.bounds);
// update all constraints // update all constraints
@ -255,16 +265,24 @@ var Engine = {};
// broadphase pass: find potential collision pairs // broadphase pass: find potential collision pairs
if (broadphase.controller) { if (broadphase.controller) {
broadphase.controller.update(broadphase.instance, allBodies, engine);
// if world is dirty, we must flush the whole grid
if (world.isModified)
broadphase.controller.clear(broadphase.instance);
// update the grid buckets based on current bodies
broadphase.controller.update(broadphase.instance, allBodies, engine, world.isModified);
broadphasePairs = broadphase.instance.pairsList; broadphasePairs = broadphase.instance.pairsList;
} else { } else {
// if no broadphase set, we just pass all bodies
broadphasePairs = allBodies; broadphasePairs = allBodies;
} }
// narrowphase pass: find actual collisions, then create or update collision pairs // narrowphase pass: find actual collisions, then create or update collision pairs
var collisions = broadphase.detector(broadphasePairs, engine); var collisions = broadphase.detector(broadphasePairs, engine);
// update pairs // update collision pairs
var pairs = engine.pairs, var pairs = engine.pairs,
timestamp = engine.timing.timestamp; timestamp = engine.timing.timestamp;
Pairs.update(pairs, collisions, timestamp); Pairs.update(pairs, collisions, timestamp);
@ -286,11 +304,16 @@ var Engine = {};
} }
Resolver.postSolvePosition(allBodies); Resolver.postSolvePosition(allBodies);
// update metrics log
Metrics.update(engine.metrics, engine); Metrics.update(engine.metrics, engine);
// clear force buffers // clear force buffers
Body.resetForcesAll(allBodies); Body.resetForcesAll(allBodies);
// clear all composite modified flags
if (world.isModified)
Composite.setModified(world, false, false, true);
return engine; return engine;
}; };
@ -315,14 +338,6 @@ var Engine = {};
Sleeping.set(body, false); Sleeping.set(body, false);
body.id = Body.nextId(); body.id = Body.nextId();
} }
var broadphase = engineA.broadphase[engineA.broadphase.current];
if (broadphase.controller === Grid) {
var grid = broadphase.instance;
Grid.clear(grid);
Grid.update(grid, bodies, engineA, true);
}
} }
}; };
@ -339,12 +354,9 @@ var Engine = {};
World.addConstraint(engine.world, engine.mouseConstraint.constraint); World.addConstraint(engine.world, engine.mouseConstraint.constraint);
var broadphase = engine.broadphase[engine.broadphase.current]; var broadphase = engine.broadphase[engine.broadphase.current];
if (broadphase.controller === Grid)
Grid.clear(broadphase.instance);
if (broadphase.controller) { if (broadphase.controller) {
var bodies = Composite.allBodies(world); var bodies = Composite.allBodies(world);
broadphase.controller.clear(broadphase.instance);
broadphase.controller.update(broadphase.instance, bodies, engine, true); broadphase.controller.update(broadphase.instance, bodies, engine, true);
} }
}; };

View file

@ -132,7 +132,12 @@ var Gui = {};
var physics = datGui.addFolder('Engine'); var physics = datGui.addFolder('Engine');
physics.add(engine, 'enableSleeping'); physics.add(engine, 'enableSleeping');
physics.add(engine.broadphase, 'current', ['grid', 'bruteForce']);
physics.add(engine.broadphase, 'current', ['grid', 'bruteForce'])
.onFinishChange(function(value) {
Composite.setModified(engine.world, true, false, false);
});
physics.add(engine, 'timeScale', 0.1, 2).step(0.1); physics.add(engine, 'timeScale', 0.1, 2).step(0.1);
physics.add(engine, 'velocityIterations', 1, 10).step(1); physics.add(engine, 'velocityIterations', 1, 10).step(1);
physics.add(engine, 'positionIterations', 1, 10).step(1); physics.add(engine, 'positionIterations', 1, 10).step(1);

View file

@ -61,6 +61,16 @@ var Render = {};
return render; return render;
}; };
/**
* Clears the renderer. In this implementation, this is a noop.
* @method clear
* @param {RenderPixi} render
*/
Render.clear = function(render) {
// nothing required to clear this renderer implentation
// if a scene graph is required, clear it here (see RenderPixi.js)
};
/** /**
* Sets the background CSS property of the canvas * Sets the background CSS property of the canvas
* @method setBackground * @method setBackground