grid-apps-cmms/src/mesh/api.js

255 lines
5.8 KiB
JavaScript
Raw Normal View History

/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
// dep: ext.three
// dep: ext.three-bgu
gapp.load(bind, "mesh.api", [
"moto.license", // dep: moto.license
"moto.client", // dep: moto.client
"moto.broker", // dep: moto.broker
"moto.space", // dep: moto.space
"mesh.tool", // dep: mesh.tool
"add.array", // dep: add.array
]);
function bind() {
broker = gapp.broker;
// publish messages with results of function call
// selection.move = broker.wrap('selection.move', selection.move);
// selection.rotate = broker.wrap('selection.rotate', selection.rotate);
// selection.update = broker.wrap('selection.update', selection.update);
}
let mesh = self.mesh = self.mesh || {};
if (mesh.api) return;
let space = moto.Space;
2021-12-30 22:59:46 -05:00
let groups = [];
2021-12-31 14:12:42 -05:00
let selected = [];
let broker;
2021-12-31 14:12:42 -05:00
let selection = {
// @returns {MeshObject[]}
2021-12-31 14:12:42 -05:00
list() {
return selected.slice();
2021-12-31 14:12:42 -05:00
},
// @param group {MeshObject[]}
2021-12-31 14:12:42 -05:00
set(objects) {
selected = objects;
this.update();
2021-12-31 14:12:42 -05:00
},
// @param group {MeshObject}
2021-12-31 14:12:42 -05:00
add(object) {
selected.addOnce(object);
this.update();
2021-12-31 14:12:42 -05:00
},
toggle(object) {
selected.remove(object) || selected.addOnce(object);
this.update();
},
// @param group {MeshObject}
2021-12-31 14:12:42 -05:00
remove(object) {
selected.remove(object);
this.update();
2021-12-31 14:12:42 -05:00
},
clear() {
selected = [];
this.update();
},
update() {
for (let group of groups) {
group.material(mesh.material.unselected);
group.showBounds(true);
}
for (let object of selected) {
object.material(mesh.material.selected);
object.showBounds(true);
}
return selection;
2021-12-31 14:12:42 -05:00
},
move(dx = 0, dy = 0, dz = 0) {
for (let s of selected) {
s.move(dx, dy, dz);
2021-12-30 22:59:46 -05:00
}
2021-12-31 14:12:42 -05:00
return selection;
2021-12-30 22:59:46 -05:00
},
2021-12-31 14:12:42 -05:00
rotate(dx = 0, dy = 0, dz = 0) {
for (let s of selected) {
2021-12-31 16:12:37 -05:00
s.rotate(dx, dy, dz);
2021-12-31 14:12:42 -05:00
}
return selection;
},
2022-01-01 10:44:06 -05:00
qrotate(q) {
for (let s of selected) {
s.qrotate(q);
}
return selection;
},
2021-12-31 14:12:42 -05:00
scale(dx = 0, dy = 0, dz = 0) {
for (let s of selected) {
let { x, y, z } = s.scale();
s.scale(x + dx, y + dy, z + dz);
}
return selection;
},
floor() {
for (let s of selected) {
s.floor(...arguments);
}
return selection;
},
centerXY() {
for (let s of selected) {
2021-12-31 16:59:38 -05:00
s.centerXY(...arguments);
2021-12-31 14:12:42 -05:00
}
return selection;
},
home() {
return selection.centerXY().floor();
2021-12-31 16:59:38 -05:00
},
focus() {
api.focus(selected);
},
bounds() {
return util.bounds(selected.map(s => s.object()));
2021-12-31 14:12:42 -05:00
}
};
let group = {
// @returns {MeshGroup[]}
list() {
return groups.slice();
},
// @param group {MeshModel[]}
new: (models) => {
return group.add(new mesh.group(models));
},
// @param group {MeshGroup}
add: (group) => {
groups.addOnce(group);
space.world.add(group.group);
space.update();
selection.set([group]);
return group;
},
// @param group {MeshGroup}
remove: (group) => {
groups.remove(group);
space.world.remove(group.group);
space.update();
}
};
let api = mesh.api = {
clear: () => {
for (let group of group.list()) {
group.remove(group);
}
},
2021-12-31 16:59:38 -05:00
// @param object {THREE.Object3D | THREE.Object3D[]}
focus: (object) => {
let { center } = util.bounds(object);
2021-12-31 17:20:41 -05:00
// when no valid objects supplied, set origin
2021-12-31 16:59:38 -05:00
if (isNaN(center.x * center.y * center.z)) {
2021-12-31 17:20:41 -05:00
center = { x: 0, y: 0, z: 0 };
2021-12-31 16:59:38 -05:00
}
2021-12-31 17:20:41 -05:00
// sets "home" views (front, back, home, reset)
space.platform.setCenter(center.x, center.y, center.z);
// sets camera focus
2021-12-31 16:59:38 -05:00
space.view.setFocus(new THREE.Vector3(
center.x, center.z, center.y
));
},
2021-12-31 14:12:42 -05:00
selection,
group,
2021-12-30 22:59:46 -05:00
model: {
2021-12-31 00:35:45 -05:00
// @returns {MeshModel[]}
2021-12-30 22:59:46 -05:00
list() {
return groups.map(g => g.models).flat();
},
2021-12-31 00:35:45 -05:00
// @param group {MeshModel}
2021-12-30 22:59:46 -05:00
remove: (model) => {
model.group.remove(model);
}
},
objects: () => {
return group.list().map(o => o.models).flat().map(o => o.object());
}
};
2021-12-31 00:35:45 -05:00
let util = mesh.util = {
// @param object {THREE.Object3D | THREE.Object3D[] | MeshObject | MeshObject[]}
2021-12-31 00:35:45 -05:00
// @returns bounds modified for moto.Space
bounds: (object) => {
2021-12-31 16:59:38 -05:00
let box = new THREE.Box3();
if (Array.isArray(object)) {
for (let o of object) {
2022-01-01 10:44:06 -05:00
box.expandByObject(
2021-12-31 16:59:38 -05:00
o instanceof mesh.object ? o.object() : o
2022-01-01 10:44:06 -05:00
);
// box.union(new THREE.Box3().setFromObject(
// o instanceof mesh.object ? o.object() : o
// ));
2021-12-31 16:59:38 -05:00
}
} else if (object) {
box.setFromObject(
object instanceof mesh.object ? object.object() : object);
} else {
return box;
}
2021-12-31 00:35:45 -05:00
let bnd = {
min: {
x: box.min.x,
y: box.min.z,
z: box.min.y
},
max: {
x: box.max.x,
y: box.max.z,
z: box.max.y
}
};
bnd.size = {
x: bnd.max.x - bnd.min.x,
y: bnd.max.y - bnd.min.y,
z: bnd.max.z - bnd.min.z
};
bnd.center = {
x: (bnd.max.x + bnd.min.x) / 2,
y: -(bnd.max.y + bnd.min.y) / 2,
2021-12-31 00:35:45 -05:00
z: (bnd.max.z + bnd.min.z) / 2
};
return bnd;
}
};
})();