persist object scale / rotation / position
This commit is contained in:
parent
1e5a84dfe9
commit
55b59d9cb1
7 changed files with 81 additions and 22 deletions
|
|
@ -79,6 +79,12 @@ function restore_space() {
|
||||||
space.view.setFocus(saved.focus);
|
space.view.setFocus(saved.focus);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mesh.db.admin.get("matrices")
|
||||||
|
.then(data => {
|
||||||
|
if (data) {
|
||||||
|
matrixCache = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
mesh.db.space.iterate({ map: true }).then(cached => {
|
mesh.db.space.iterate({ map: true }).then(cached => {
|
||||||
for (let [id, data] of Object.entries(cached)) {
|
for (let [id, data] of Object.entries(cached)) {
|
||||||
if (count++ === 0) {
|
if (count++ === 0) {
|
||||||
|
|
@ -86,16 +92,21 @@ function restore_space() {
|
||||||
}
|
}
|
||||||
// restore group
|
// restore group
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
let models = data.map(id => {
|
let models = data
|
||||||
let md = cached[id];
|
.map(id => { return { id, md: cached[id] } })
|
||||||
let m = md ? new mesh.model(md, id) : undefined;
|
.filter(r => r.md) // filter cache misses
|
||||||
return m;
|
.map(r => new mesh.model(r.md, r.id).applyMatrix(matrixCache[r.id]));
|
||||||
}).filter(m => m);
|
|
||||||
mesh.api.log.emit(`restored ${models.length} model(s)`);
|
mesh.api.log.emit(`restored ${models.length} model(s)`);
|
||||||
mesh.api.group.new(models, id)
|
let group = mesh.api.group.new(models, id);
|
||||||
.centerModels()
|
let matrix = matrixCache[id];
|
||||||
.centerXY()
|
if (matrix) {
|
||||||
.floor();
|
group.applyMatrix(matrix);
|
||||||
|
} else {
|
||||||
|
group
|
||||||
|
.centerModels()
|
||||||
|
.centerXY()
|
||||||
|
.floor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -281,11 +292,32 @@ function space_load(data) {
|
||||||
.focus();
|
.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let matrixCache = {};
|
||||||
|
|
||||||
|
// todo deferred with util
|
||||||
|
function store_matrices() {
|
||||||
|
mesh.db.admin.put("matrices", matrixCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache model matrices for page restores
|
||||||
|
function object_matrix(data) {
|
||||||
|
let { id, matrix } = data;
|
||||||
|
matrixCache[id] = matrix.elements;
|
||||||
|
store_matrices();
|
||||||
|
}
|
||||||
|
|
||||||
|
function object_destroy(id) {
|
||||||
|
delete matrixCache[id];
|
||||||
|
store_matrices();
|
||||||
|
}
|
||||||
|
|
||||||
// bind functions to topics
|
// bind functions to topics
|
||||||
broker.listeners({
|
broker.listeners({
|
||||||
load_files,
|
load_files,
|
||||||
space_init,
|
space_init,
|
||||||
space_load,
|
space_load,
|
||||||
|
object_matrix,
|
||||||
|
object_destroy,
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove version cache bust from url
|
// remove version cache bust from url
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,7 @@ function ui_build() {
|
||||||
selection_scale: defer_selection,
|
selection_scale: defer_selection,
|
||||||
selection_rotate: defer_selection,
|
selection_rotate: defer_selection,
|
||||||
selection_qrotate: defer_selection,
|
selection_qrotate: defer_selection,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,8 @@ mesh.group = class MeshGroup extends mesh.object {
|
||||||
// auto-remove group when empty
|
// auto-remove group when empty
|
||||||
if (this.group.children.length === 0) {
|
if (this.group.children.length === 0) {
|
||||||
mesh.api.group.remove(this);
|
mesh.api.group.remove(this);
|
||||||
// update worker state
|
// manage lifecycle with worker, mesh app caches, etc
|
||||||
worker.object_destroy({id: this.id});
|
this.destroy();
|
||||||
// update object store
|
|
||||||
mesh.db.space.remove(this.id);
|
|
||||||
} else {
|
} else {
|
||||||
// update data store
|
// update data store
|
||||||
mesh.db.space.put(this.id, this.models.map(m => m.id));
|
mesh.db.space.put(this.id, this.models.map(m => m.id));
|
||||||
|
|
|
||||||
|
|
@ -219,16 +219,15 @@ mesh.model = class MeshModel extends mesh.object {
|
||||||
this.group = undefined;
|
this.group = undefined;
|
||||||
this.removed = 'pending';
|
this.removed = 'pending';
|
||||||
} else {
|
} else {
|
||||||
// update worker state
|
// manage lifecycle with worker, mesh app caches, etc
|
||||||
worker.object_destroy({id: this.id});
|
this.destroy();
|
||||||
// update object store
|
|
||||||
mesh.db.space.remove(this.id);
|
|
||||||
// tag removed for debugging
|
// tag removed for debugging
|
||||||
this.removed = 'complete';
|
this.removed = 'complete';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBoundsBox() {
|
updateBoundsBox() {
|
||||||
|
this.updateMatrix();
|
||||||
mesh.util.defer(this.group.deferUBB);
|
mesh.util.defer(this.group.deferUBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
gapp.register("mesh.object", [
|
gapp.register("mesh.object", [
|
||||||
"add.three", // dep: add.three
|
"add.three", // dep: add.three
|
||||||
"moto.license", // dep: moto.license
|
"moto.license", // dep: moto.license
|
||||||
|
"moto.broker", // dep: moto.broker
|
||||||
"mesh.api", // dep: mesh.api
|
"mesh.api", // dep: mesh.api
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -16,6 +17,12 @@ if (mesh.object) return;
|
||||||
let space = moto.Space;
|
let space = moto.Space;
|
||||||
let worker = moto.client.fn;
|
let worker = moto.client.fn;
|
||||||
|
|
||||||
|
// broker updates generated by objects
|
||||||
|
let publish = {
|
||||||
|
matrix: gapp.broker.bind("object_matrix"),
|
||||||
|
destroy: gapp.broker.bind("object_destroy"),
|
||||||
|
};
|
||||||
|
|
||||||
mesh.object = class MeshObject {
|
mesh.object = class MeshObject {
|
||||||
|
|
||||||
constructor(id) {
|
constructor(id) {
|
||||||
|
|
@ -37,8 +44,30 @@ mesh.object = class MeshObject {
|
||||||
return mesh.util.bounds(this.object);
|
return mesh.util.bounds(this.object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// manage lifecycle with worker, mesh app caches, etc
|
||||||
|
destroy() {
|
||||||
|
// update worker state
|
||||||
|
worker.object_destroy({id: this.id});
|
||||||
|
// update object store
|
||||||
|
mesh.db.space.remove(this.id);
|
||||||
|
// main app cache workspace updates
|
||||||
|
publish.destroy(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMatrix() {
|
||||||
|
publish.matrix({ id: this.id, matrix: this.object.matrix });
|
||||||
|
}
|
||||||
|
|
||||||
|
applyMatrix(elements) {
|
||||||
|
if (elements) {
|
||||||
|
this.object.applyMatrix4(new THREE.Matrix4().fromArray(elements));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
mesh.api.focus(this.object);
|
mesh.api.focus(this.object);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
floor() {
|
floor() {
|
||||||
|
|
@ -132,6 +161,7 @@ mesh.object = class MeshObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBoundsBox() {
|
updateBoundsBox() {
|
||||||
|
this.updateMatrix();
|
||||||
let helper = this._boundsBox;
|
let helper = this._boundsBox;
|
||||||
let world = space.world;
|
let world = space.world;
|
||||||
if (helper) {
|
if (helper) {
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ gapp.broker = new class Broker {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return function bound to a topic
|
// return function bound to a topic for publishing
|
||||||
bind(topic, message, options) {
|
bind(topic, message, options) {
|
||||||
let broker = this;
|
let broker = this;
|
||||||
return function(msg, opt) {
|
return function(msg, opt) {
|
||||||
|
|
|
||||||
|
|
@ -202,8 +202,8 @@ button:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
#modal_frame {
|
#modal_frame {
|
||||||
border-radius: 4px;
|
border-radius: 4px !important;
|
||||||
background-color: white;
|
background-color: rgba(255,255,255,0.9) !important;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0 !important; /* override common below */
|
padding: 0 !important; /* override common below */
|
||||||
z-index: 51;
|
z-index: 51;
|
||||||
|
|
@ -218,7 +218,7 @@ button:hover {
|
||||||
border-top-left-radius: 4px;
|
border-top-left-radius: 4px;
|
||||||
border-top-right-radius: 4px;
|
border-top-right-radius: 4px;
|
||||||
border-bottom: 1px solid gray;
|
border-bottom: 1px solid gray;
|
||||||
background-color: #ccc;
|
background-color: rgba(0,0,0,0.2);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue