mirror of
https://github.com/liabru/matter-js.git
synced 2024-12-25 13:39:06 -05:00
composites now support removals (implemented isModified flag)
This commit is contained in:
parent
4514f2d598
commit
b253683cb5
5 changed files with 187 additions and 35 deletions
|
@ -11,6 +11,8 @@ var Composite = {};
|
|||
|
||||
(function() {
|
||||
|
||||
var _nextId = 0;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* @method create
|
||||
|
@ -19,12 +21,49 @@ var Composite = {};
|
|||
*/
|
||||
Composite.create = function(options) {
|
||||
return Common.extend({
|
||||
id: Composite.nextId(),
|
||||
parent: null,
|
||||
isModified: false,
|
||||
bodies: [],
|
||||
constraints: [],
|
||||
composites: []
|
||||
}, 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
|
||||
* @method addComposite
|
||||
|
@ -34,6 +73,8 @@ var Composite = {};
|
|||
*/
|
||||
Composite.addComposite = function(compositeA, compositeB) {
|
||||
compositeA.composites.push(compositeB);
|
||||
compositeB.parent = compositeA;
|
||||
Composite.setModified(compositeA, true, true, false);
|
||||
return compositeA;
|
||||
};
|
||||
|
||||
|
@ -46,6 +87,44 @@ var Composite = {};
|
|||
*/
|
||||
Composite.addBody = function(composite, 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;
|
||||
};
|
||||
|
||||
|
@ -58,6 +137,71 @@ var Composite = {};
|
|||
*/
|
||||
Composite.addConstraint = function(composite, 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;
|
||||
};
|
||||
|
||||
|
@ -91,23 +235,4 @@ var Composite = {};
|
|||
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;
|
||||
};
|
||||
|
||||
})();
|
|
@ -48,7 +48,7 @@ var Grid = {};
|
|||
for (i = 0; i < bodies.length; i++) {
|
||||
var body = bodies[i];
|
||||
|
||||
if (body.isSleeping)
|
||||
if (body.isSleeping && !forceUpdate)
|
||||
continue;
|
||||
|
||||
// don't update out of world bodies
|
||||
|
|
|
@ -167,6 +167,10 @@ var Engine = {};
|
|||
*/
|
||||
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
|
||||
Engine.update(engine, delta, correction);
|
||||
|
||||
|
@ -234,18 +238,24 @@ var Engine = {};
|
|||
broadphasePairs = [],
|
||||
i;
|
||||
|
||||
// get lists of all bodies and constraints, no matter what composites they are in
|
||||
var allBodies = Composite.allBodies(world),
|
||||
allConstraints = Composite.allConstraints(world);
|
||||
|
||||
// reset metrics logging
|
||||
Metrics.reset(engine.metrics);
|
||||
|
||||
// if sleeping enabled, call the sleeping controller
|
||||
if (engine.enableSleeping)
|
||||
Sleeping.update(allBodies);
|
||||
|
||||
// applies gravity to all bodies
|
||||
Body.applyGravityAll(allBodies, world.gravity);
|
||||
|
||||
// update the mouse constraint
|
||||
MouseConstraint.update(engine.mouseConstraint, allBodies, engine.input);
|
||||
|
||||
// update all body position and rotation by integration
|
||||
Body.updateAll(allBodies, delta * engine.timeScale, correction, world.bounds);
|
||||
|
||||
// update all constraints
|
||||
|
@ -255,16 +265,24 @@ var Engine = {};
|
|||
|
||||
// broadphase pass: find potential collision pairs
|
||||
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;
|
||||
} else {
|
||||
|
||||
// if no broadphase set, we just pass all bodies
|
||||
broadphasePairs = allBodies;
|
||||
}
|
||||
|
||||
// narrowphase pass: find actual collisions, then create or update collision pairs
|
||||
var collisions = broadphase.detector(broadphasePairs, engine);
|
||||
|
||||
// update pairs
|
||||
// update collision pairs
|
||||
var pairs = engine.pairs,
|
||||
timestamp = engine.timing.timestamp;
|
||||
Pairs.update(pairs, collisions, timestamp);
|
||||
|
@ -286,11 +304,16 @@ var Engine = {};
|
|||
}
|
||||
Resolver.postSolvePosition(allBodies);
|
||||
|
||||
// update metrics log
|
||||
Metrics.update(engine.metrics, engine);
|
||||
|
||||
// clear force buffers
|
||||
Body.resetForcesAll(allBodies);
|
||||
|
||||
// clear all composite modified flags
|
||||
if (world.isModified)
|
||||
Composite.setModified(world, false, false, true);
|
||||
|
||||
return engine;
|
||||
};
|
||||
|
||||
|
@ -315,14 +338,6 @@ var Engine = {};
|
|||
Sleeping.set(body, false);
|
||||
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);
|
||||
|
||||
var broadphase = engine.broadphase[engine.broadphase.current];
|
||||
|
||||
if (broadphase.controller === Grid)
|
||||
Grid.clear(broadphase.instance);
|
||||
|
||||
if (broadphase.controller) {
|
||||
var bodies = Composite.allBodies(world);
|
||||
broadphase.controller.clear(broadphase.instance);
|
||||
broadphase.controller.update(broadphase.instance, bodies, engine, true);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -132,7 +132,12 @@ var Gui = {};
|
|||
|
||||
var physics = datGui.addFolder('Engine');
|
||||
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, 'velocityIterations', 1, 10).step(1);
|
||||
physics.add(engine, 'positionIterations', 1, 10).step(1);
|
||||
|
|
|
@ -61,6 +61,16 @@ var 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
|
||||
* @method setBackground
|
||||
|
|
Loading…
Reference in a new issue