diff --git a/demo/src/index.js b/demo/src/index.js index 6c34c0d..a03cf8b 100644 --- a/demo/src/index.js +++ b/demo/src/index.js @@ -15,7 +15,6 @@ var compare = require('./Compare').compare; var demo = require('./Demo').demo; // browser globals -window.decomp = require('poly-decomp'); window.pathseg = require('pathseg'); window.MatterTools = require('matter-tools'); window.Matter = Matter; diff --git a/examples/concave.js b/examples/concave.js index b7ef410..517b07f 100644 --- a/examples/concave.js +++ b/examples/concave.js @@ -12,6 +12,9 @@ Example.concave = function() { Vertices = Matter.Vertices, Bodies = Matter.Bodies; + // provide concave decomposition support library + Common.setDecomp(require('poly-decomp')); + // create engine var engine = Engine.create(), world = engine.world; @@ -96,7 +99,7 @@ Example.concave = function() { }; Example.concave.title = 'Concave'; -Example.concave.for = '>=0.14.2'; +Example.concave.for = '>0.16.1'; if (typeof module !== 'undefined') { module.exports = Example.concave; diff --git a/examples/raycasting.js b/examples/raycasting.js index a47f4c6..ea9f023 100644 --- a/examples/raycasting.js +++ b/examples/raycasting.js @@ -53,6 +53,9 @@ Example.raycasting = function() { } }); + // for testing raycasting on concave bodies + Common.setDecomp(require('poly-decomp')); + var star = Vertices.fromPath('50 0 63 38 100 38 69 59 82 100 50 75 18 100 31 59 0 38 37 38'), concave = Bodies.fromVertices(200, 200, star); @@ -136,7 +139,7 @@ Example.raycasting = function() { }; Example.raycasting.title = 'Raycasting'; -Example.raycasting.for = '>=0.14.2'; +Example.raycasting.for = '>0.16.1'; if (typeof module !== 'undefined') { module.exports = Example.raycasting; diff --git a/examples/svg.js b/examples/svg.js index 457a57c..186def8 100644 --- a/examples/svg.js +++ b/examples/svg.js @@ -12,6 +12,9 @@ Example.svg = function() { Svg = Matter.Svg, Bodies = Matter.Bodies; + // provide concave decomposition support library + Common.setDecomp(require('poly-decomp')); + // create engine var engine = Engine.create(), world = engine.world; @@ -128,7 +131,7 @@ Example.svg = function() { }; Example.svg.title = 'Concave SVG Paths'; -Example.svg.for = '>=0.14.2'; +Example.svg.for = '>0.16.1'; if (typeof module !== 'undefined') { module.exports = Example.svg; diff --git a/examples/terrain.js b/examples/terrain.js index 8d74b05..e6c6f17 100644 --- a/examples/terrain.js +++ b/examples/terrain.js @@ -13,6 +13,9 @@ Example.terrain = function() { Svg = Matter.Svg, Bodies = Matter.Bodies; + // provide concave decomposition support library + Common.setDecomp(require('poly-decomp')); + // create engine var engine = Engine.create(), world = engine.world; @@ -115,7 +118,7 @@ Example.terrain = function() { }; Example.terrain.title = 'Terrain'; -Example.terrain.for = '>=0.14.2'; +Example.terrain.for = '>0.16.1'; if (typeof module !== 'undefined') { module.exports = Example.terrain; diff --git a/src/core/Common.js b/src/core/Common.js index 015fd77..3c9bfd7 100644 --- a/src/core/Common.js +++ b/src/core/Common.js @@ -14,7 +14,8 @@ module.exports = Common; Common._seed = 0; Common._nowStartTime = +(new Date()); Common._warnedOnce = {}; - + Common._decomp = null; + /** * Extends the object in the first argument using the object in the second argument. * @method extend @@ -565,4 +566,42 @@ module.exports = Common; func )); }; + + /** + * Provide the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module to enable + * concave vertex decomposition support when using `Bodies.fromVertices` e.g. `Common.setDecomp(require('poly-decomp'))`. + * @method setDecomp + * @param {} decomp The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module. + */ + Common.setDecomp = function(decomp) { + Common._decomp = decomp; + }; + + /** + * Returns the [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module provided through `Common.setDecomp`, + * otherwise returns the global `decomp` if set. + * @method getDecomp + * @return {} The [poly-decomp](https://github.com/schteppe/poly-decomp.js) library module if provided. + */ + Common.getDecomp = function() { + // get user provided decomp if set + var decomp = Common._decomp; + + try { + // otherwise from window global + if (!decomp && typeof window !== 'undefined') { + decomp = window.decomp; + } + + // otherwise from node global + if (!decomp && typeof global !== 'undefined') { + decomp = global.decomp; + } + } catch (e) { + // decomp not available + decomp = null; + } + + return decomp; + }; })(); diff --git a/src/factory/Bodies.js b/src/factory/Bodies.js index c91d213..c55e615 100644 --- a/src/factory/Bodies.js +++ b/src/factory/Bodies.js @@ -21,8 +21,6 @@ var Vector = require('../geometry/Vector'); (function() { - Bodies._decompWarned = false; - /** * Creates a new rigid body model with a rectangle hull. * The options parameter is an object that specifies any properties you wish to override the defaults. @@ -178,26 +176,22 @@ var Vector = require('../geometry/Vector'); }; /** - * Creates a body based on set(s) of vertices. + * Utility to create a compound body based on set(s) of vertices. * - * This utility builds on top of `Body.create` to automatically handle concave inputs. - * - * To use this decomposition feature the [poly-decomp](https://github.com/schteppe/poly-decomp.js) - * package should be additionally installed via npm or as a global. + * _Note:_ To optionally enable automatic concave vertices decomposition the [poly-decomp](https://github.com/schteppe/poly-decomp.js) + * package must be first installed and provided see `Common.setDecomp`, otherwise the convex hull of each vertex set will be used. * * The resulting vertices are reorientated about their centre of mass, * and offset such that `body.position` corresponds to this point. * - * If needed the resulting offset may be found by subtracting `body.bounds` from the original input bounds. + * The resulting offset may be found if needed by subtracting `body.bounds` from the original input bounds. * To later move the centre of mass see `Body.setCentre`. * - * Note that decomposition results are not always perfect. - * + * Note that automatic conconcave decomposition results are not always optimal. * For best results, simplify the input vertices as much as possible first. * By default this function applies some addtional simplification to help. * * Some outputs may also require further manual processing afterwards to be robust. - * * In particular some parts may need to be overlapped to avoid collision gaps. * Thin parts and sharp points should be avoided or removed where possible. * @@ -207,16 +201,16 @@ var Vector = require('../geometry/Vector'); * @method fromVertices * @param {number} x * @param {number} y - * @param [[vector]] vertexSets - * @param {object} [options] - * @param {bool} [flagInternal=false] - * @param {number} [removeCollinear=0.01] - * @param {number} [minimumArea=10] - * @param {number} [removeDuplicatePoints=0.01] + * @param {array} vertexSets One or more arrays of vertex points e.g. `[[{ x: 0, y: 0 }...], ...]`. + * @param {object} [options] The body options. + * @param {bool} [flagInternal=false] Optionally marks internal edges with `isInternal`. + * @param {number} [removeCollinear=0.01] Threshold when simplifying vertices along the same edge. + * @param {number} [minimumArea=10] Threshold when removing small parts. + * @param {number} [removeDuplicatePoints=0.01] Threshold when simplifying nearby vertices. * @return {body} */ Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, removeDuplicatePoints) { - var decomp, + var decomp = Common.getDecomp(), canDecomp, body, parts, @@ -229,14 +223,7 @@ var Vector = require('../geometry/Vector'); v, z; - try { - decomp = require('poly-decomp'); - } catch (e) { - // continue without decomp - decomp = null; - } - - // check expected decomp module was resolved + // check decomp is as expected canDecomp = Boolean(decomp && decomp.quickDecomp); options = options || {}; @@ -257,14 +244,10 @@ var Vector = require('../geometry/Vector'); isConvex = Vertices.isConvex(vertices); isConcave = !isConvex; - if (isConcave && !canDecomp && !Bodies._decompWarned) { - Common.warn( - 'Could not resolve the expected \'poly-decomp\' package for concave vertices in \'Bodies.fromVertices\'' + if (isConcave && !canDecomp) { + Common.warnOnce( + 'Bodies.fromVertices: Install the \'poly-decomp\' library and use Common.setDecomp or provide \'decomp\' as a global to decompose concave vertices.' ); - Common.warn( - 'Try \'npm install poly-decomp --save\' or as a global e.g. \'window.decomp\'' - ); - Bodies._decompWarned = true; } if (isConvex || !canDecomp) {