|
| 1 | +/** |
| 2 | + * @author Joachim Grill <joachim@codeandweb.com> |
| 3 | + * @copyright 2018 CodeAndWeb GmbH |
| 4 | + * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} |
| 5 | + */ |
| 6 | + |
| 7 | +var Bodies = require('./lib/factory/Bodies'); |
| 8 | +var Body = require('./lib/body/Body'); |
| 9 | +var GetFastValue = require('../../utils/object/GetFastValue'); |
| 10 | +var Common = require('./lib/core/Common'); |
| 11 | +var Vertices = require('./lib/geometry/Vertices'); |
| 12 | +var Bounds = require('./lib/geometry/Bounds'); |
| 13 | +var Vector = require('./lib/geometry/Vector'); |
| 14 | + |
| 15 | + |
| 16 | +var PhysicsEditorLoader = { |
| 17 | + |
| 18 | + loadBody: function (x, y, w, h, config) |
| 19 | + { |
| 20 | + const fixtureConfigs = GetFastValue(config, 'fixtures', []); |
| 21 | + const fixtures = []; |
| 22 | + for (let fixtureConfig of fixtureConfigs) |
| 23 | + { |
| 24 | + const f = this.loadFixture(fixtureConfig); |
| 25 | + fixtures.push(...f); |
| 26 | + } |
| 27 | + |
| 28 | + var matterConfig = Common.extend({}, false, config); |
| 29 | + delete matterConfig.fixtures; |
| 30 | + delete matterConfig.type; |
| 31 | + |
| 32 | + const body = Body.create(matterConfig); |
| 33 | + Body.setParts(body, fixtures); |
| 34 | + body.render.sprite.xOffset = body.position.x / w; |
| 35 | + body.render.sprite.yOffset = body.position.y / h; |
| 36 | + Body.setPosition(body, { x: x, y: y }); |
| 37 | + |
| 38 | + return body; |
| 39 | + }, |
| 40 | + |
| 41 | + |
| 42 | + loadFixture: function (fixtureConfig) |
| 43 | + { |
| 44 | + var matterConfig = Common.extend({}, false, fixtureConfig); |
| 45 | + delete matterConfig.circle; |
| 46 | + delete matterConfig.vertices; |
| 47 | + |
| 48 | + let fixtures; |
| 49 | + if (fixtureConfig.circle) |
| 50 | + { |
| 51 | + const x = GetFastValue(fixtureConfig.circle, 'x'); |
| 52 | + const y = GetFastValue(fixtureConfig.circle, 'y'); |
| 53 | + const r = GetFastValue(fixtureConfig.circle, 'radius'); |
| 54 | + fixtures = [ Bodies.circle(x, y, r, matterConfig) ]; |
| 55 | + } |
| 56 | + else if (fixtureConfig.vertices) |
| 57 | + { |
| 58 | + fixtures = this.loadVertices(fixtureConfig.vertices, matterConfig); |
| 59 | + } |
| 60 | + return fixtures; |
| 61 | + }, |
| 62 | + |
| 63 | + |
| 64 | + loadVertices: function (vertexSets, options) |
| 65 | + { |
| 66 | + var i, j, k, v, z; |
| 67 | + var parts = []; |
| 68 | + |
| 69 | + options = options || {}; |
| 70 | + |
| 71 | + for (v = 0; v < vertexSets.length; v += 1) { |
| 72 | + parts.push(Body.create(Common.extend({ |
| 73 | + position: Vertices.centre(vertexSets[v]), |
| 74 | + vertices: vertexSets[v] |
| 75 | + }, options))); |
| 76 | + } |
| 77 | + |
| 78 | + // flag coincident part edges |
| 79 | + var coincident_max_dist = 5; |
| 80 | + |
| 81 | + for (i = 0; i < parts.length; i++) { |
| 82 | + var partA = parts[i]; |
| 83 | + |
| 84 | + for (j = i + 1; j < parts.length; j++) { |
| 85 | + var partB = parts[j]; |
| 86 | + |
| 87 | + if (Bounds.overlaps(partA.bounds, partB.bounds)) { |
| 88 | + var pav = partA.vertices, |
| 89 | + pbv = partB.vertices; |
| 90 | + |
| 91 | + // iterate vertices of both parts |
| 92 | + for (k = 0; k < partA.vertices.length; k++) { |
| 93 | + for (z = 0; z < partB.vertices.length; z++) { |
| 94 | + // find distances between the vertices |
| 95 | + var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])), |
| 96 | + db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length])); |
| 97 | + |
| 98 | + // if both vertices are very close, consider the edge concident (internal) |
| 99 | + if (da < coincident_max_dist && db < coincident_max_dist) { |
| 100 | + pav[k].isInternal = true; |
| 101 | + pbv[z].isInternal = true; |
| 102 | + } |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + } |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + return parts; |
| 111 | + } |
| 112 | + |
| 113 | +}; |
| 114 | + |
| 115 | +module.exports = PhysicsEditorLoader; |
0 commit comments