diff --git a/src/add/array.js b/src/add/array.js index f0632d02..66b14d38 100644 --- a/src/add/array.js +++ b/src/add/array.js @@ -173,6 +173,24 @@ return this.filter(v => isNaN(v)).length > 0; }; + // wrap a function and unroll the first parameter into + // successive function calls if it is an array + Array.handle = function(fn) { + return function() { + let args = [...arguments]; + let val = args.shift(); + if (Array.isArray(val)) { + let rv = []; + for (let v of val.slice()) { + rv.push(fn(v, ...args)); + } + return rv; + } else { + return fn(val, ...args); + } + } + }; + for (let i in AP) { Object.defineProperty(Array.prototype, i, { value: AP[i], diff --git a/src/main/mesh.js b/src/main/mesh.js index 2b446998..6d09c0e8 100644 --- a/src/main/mesh.js +++ b/src/main/mesh.js @@ -85,8 +85,7 @@ broker.subscribe('space_init', data => { // add object loader broker.subscribe('space_load', data => { for (let od of data) { - let obj = new mesh.object(od); - moto.Space.world.add(obj.mesh); + mesh.api.models.add(new mesh.model(od)); } }); @@ -107,7 +106,8 @@ gapp.finalize("main.mesh", [ "moto.client", // dep: moto.client "moto.broker", // dep: moto.broker "moto.space", // dep: moto.space - "mesh.object", // dep: mesh.object + "mesh.api", // dep: mesh.api + "mesh.model", // dep: mesh.model "load.file", // dep: load.file ]); diff --git a/src/mesh/api.js b/src/mesh/api.js new file mode 100644 index 00000000..76aac982 --- /dev/null +++ b/src/mesh/api.js @@ -0,0 +1,42 @@ +/** Copyright Stewart Allen -- All Rights Reserved */ + +"use strict"; + +(function() { + +// dep: ext.three +// dep: ext.three-bgu +gapp.register("mesh.api", [ + "moto.license", // dep: moto.license + "moto.client", // dep: moto.client + "moto.space", // dep: moto.space + "mesh.tool", // dep: mesh.tool + "add.array", // dep: add.array +]); + +let mesh = self.mesh = self.mesh || {}; +if (mesh.api) return; + +let space = moto.Space; +let models = []; + +let api = mesh.api = { + + models: { + all: models, + + add: model => { + if (!models.contains(model)) { + space.model.add(model.mesh); + models.push(model); + } + }, + + remove: Array.handle(model => { + space.model.remove(model.mesh); + models.remove(model); + }) + } +}; + +})(); diff --git a/src/mesh/object.js b/src/mesh/model.js similarity index 89% rename from src/mesh/object.js rename to src/mesh/model.js index 999d9f76..86458ff3 100644 --- a/src/mesh/object.js +++ b/src/mesh/model.js @@ -4,14 +4,15 @@ (function() { -gapp.register("mesh.object", [ +gapp.register("mesh.model", [ "add.three", // dep: add.three "moto.license", // dep: moto.license ]); let mesh = self.mesh = self.mesh || {}; -if (mesh.object) return; +if (mesh.model) return; +/** default materials **/ mesh.material = { solid: new THREE.MeshPhongMaterial({ transparent: true, @@ -22,7 +23,8 @@ mesh.material = { }) }; -mesh.object = class MeshObject { +/** 3D model rendered on plaform **/ +mesh.model = class MeshModel { constructor(data) { let { file, mesh } = data; diff --git a/src/mesh/tool.js b/src/mesh/tool.js index 12930787..eba6f59a 100644 --- a/src/mesh/tool.js +++ b/src/mesh/tool.js @@ -8,8 +8,9 @@ gapp.register("mesh.tool"); let mesh = self.mesh = self.mesh || {}; -if (mesh.object) return; +if (mesh.tool) return; +/** tool for identiying defects and healing them **/ mesh.tool = class MeshTool { constructor(params = {}) { this.precision = Math.pow(10, params.precision || 6); diff --git a/src/moto/space.js b/src/moto/space.js index 83059137..4a2d58e7 100644 --- a/src/moto/space.js +++ b/src/moto/space.js @@ -954,6 +954,19 @@ active: updateLastAction }, + // wraps WORLD add/remove with immediate refresh + model: { + add: mesh => { + WORLD.add(mesh); + refresh(); + }, + + remove: (mesh) => { + WORLD.remove(mesh); + refresh(); + } + }, + world: WORLD, platform: {