mesh v2 at /v2/mesh
This commit is contained in:
parent
aee9fd6ed7
commit
6566c45f9a
85 changed files with 138198 additions and 1 deletions
170
src2/mesh/group.js
Normal file
170
src2/mesh/group.js
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||
|
||||
import { THREE } from '../ext/three.js';
|
||||
const { Group, Box3 } = THREE;
|
||||
import { license as motoLicense } from '../moto/license.js';
|
||||
import { broker as motoBroker } from '../moto/broker.js';
|
||||
import { client as motoClient } from '../moto/client.js';
|
||||
import { space as motoSpace } from '../moto/space.js';
|
||||
import { object as meshObject } from './object.js';
|
||||
import { api as meshApi } from './api.js';
|
||||
import { model as meshModel } from './model.js';
|
||||
|
||||
const call = motoBroker.send;
|
||||
const worker = motoClient.fn;
|
||||
|
||||
class MeshGroup extends meshObject {
|
||||
// @param group {MeshModel[]}
|
||||
constructor(models = [], id, name) {
|
||||
super(id);
|
||||
this.group3 = new Group();
|
||||
this.models = [];
|
||||
this.name = name;
|
||||
for (let model of models) {
|
||||
this.add(model);
|
||||
}
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "group";
|
||||
}
|
||||
|
||||
get object() {
|
||||
return this.group3;
|
||||
}
|
||||
|
||||
get bounds() {
|
||||
let box3 = new Box3();
|
||||
for (let model of this.models) {
|
||||
box3.union(model.world_bounds);
|
||||
}
|
||||
return box3;
|
||||
}
|
||||
|
||||
// @param model {MeshModel}
|
||||
add(model) {
|
||||
model.group = this;
|
||||
this.models.addOnce(model);
|
||||
this.group3.add(model.mesh);
|
||||
motoSpace.update();
|
||||
call.model_add({model, group:this});
|
||||
worker.group_add({id: this.id, model:model.id});
|
||||
// update data store
|
||||
meshApi.db.space.put(this.id, this.models.map(m => m.id));
|
||||
return this;
|
||||
}
|
||||
|
||||
// @param model {MeshModel}
|
||||
// @param free {boolean} prevent cleanup of model so it can be re-used
|
||||
remove(model, opt = { free: true }) {
|
||||
// remove all models and group
|
||||
if (arguments.length === 0) {
|
||||
for (let m of this.models.slice()) {
|
||||
this.remove(m);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.models.remove(model);
|
||||
this.group3.remove(model.mesh);
|
||||
// create message for listeners
|
||||
call.model_remove({model, group:this});
|
||||
// trigger sync with worker
|
||||
worker.group_remove({id: this.id, model: model.id});
|
||||
// ensure worker cleanup of model
|
||||
if (opt.free) model.remove(true);
|
||||
// auto-remove group when empty
|
||||
if (this.group3.children.length === 0) {
|
||||
meshApi.group.remove(this);
|
||||
// manage lifecycle with worker, mesh app caches, etc
|
||||
this.destroy();
|
||||
} else {
|
||||
// update data store
|
||||
meshApi.db.space.put(this.id, this.models.map(m => m.id));
|
||||
}
|
||||
motoSpace.update();
|
||||
return this;
|
||||
}
|
||||
|
||||
promote() {
|
||||
let { dim, mid } = this.bounds;
|
||||
let { x, y, z } = dim;
|
||||
let max = Math.max(x, y, z);
|
||||
if (max < 2) {
|
||||
meshApi.log.emit(`auto-scaling import from ${max.round(5)}`);
|
||||
this.scale(1000, 1000, 1000);
|
||||
}
|
||||
let { center, floor } = meshApi.prefs.map.space;
|
||||
if (center !== false) this.centerXY();
|
||||
if (floor !== false) this.floor();
|
||||
return this;
|
||||
}
|
||||
|
||||
rotate(x = 0, y = 0, z = 0) {
|
||||
this.log('group-rotate', ...arguments);
|
||||
for (let model of this.models) {
|
||||
model.rotate(...arguments);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
qrotate(quaternion) {
|
||||
this.log('group-rotate', quaternion.toArray());
|
||||
for (let model of this.models) {
|
||||
model.qrotate(quaternion);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
scale(x = 1, y = 1, z = 1) {
|
||||
this.log('group-scale', ...arguments);
|
||||
for (let m of this.models) {
|
||||
m.scale(x, y, z);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
move(x = 0, y = 0, z = 0) {
|
||||
this.log('group-move', ...arguments);
|
||||
if (!(x || y || z)) return;
|
||||
for (let model of this.models) {
|
||||
model.move(x, y, z);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
center() {
|
||||
let b = this.bounds;
|
||||
return this.move(-b.mid.x, -b.mid.y, -b.mid.z);
|
||||
}
|
||||
|
||||
centerXY() {
|
||||
let b = this.bounds;
|
||||
return this.move(-b.mid.x, -b.mid.y, 0);
|
||||
}
|
||||
|
||||
opacity() {
|
||||
for (let model of this.models) {
|
||||
model.opacity(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
wireframe() {
|
||||
for (let model of this.models) {
|
||||
model.wireframe(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
normals() {
|
||||
for (let model of this.models) {
|
||||
model.normals(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
select() {
|
||||
for (let model of this.models) {
|
||||
model.select(...arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { MeshGroup as group };
|
||||
Loading…
Reference in a new issue