improve shift + z split snapping

This commit is contained in:
Stewart Allen 2022-05-13 15:05:21 -04:00
commit 3a869e3904
3 changed files with 27 additions and 23 deletions

View file

@ -36,9 +36,9 @@ Full docs @ https://docs.grid.space/projects/kiri-moto
* quick add primitives: cube, cylinder
* control wireframe transparency
* parameterize png image import
* code added to show camera focal point
* ~ undo / redo for some operations
* ~ show camera focal point
* ~ better Z split snapping and split at defined Z index
* better Z split snapping using vertex closest to mouse
# Release 3.3 (2022-04-01)

View file

@ -14,7 +14,7 @@
// dep: load.file
gapp.main("main.mesh", [], (root) => {
const { Quaternion, Mesh, MeshPhongMaterial, PlaneGeometry, DoubleSide } = THREE;
const { Quaternion, Mesh, MeshPhongMaterial, PlaneGeometry, DoubleSide, Vector3 } = THREE;
const { broker } = gapp;
const { moto } = root;
const { space } = moto;
@ -179,15 +179,9 @@ let split = {
// hide until first hover
obj.visible = false;
// enable temp mode
let state = split.state = { button, obj, zlist:[] };
let state = split.state = { button, obj };
let models = state.models = api.selection.models();
let meshes = models.map(m => m.mesh);
// get z list for snapping
Promise.all(models.map(m => m.zlist(3))).then(zs => {
for (let z of zs.flat()) {
state.zlist.addOnce(z);
}
});
// for split and lay flat modes
space.mouse.onHover((int, event, ints) => {
if (!event) {
@ -199,19 +193,13 @@ let split = {
return;
}
let { dim, mid } = util.bounds(meshes);
let { x, y, z } = int.point;
// snap to zlist when shift pressed
let { zlist } = state;
let { point, face, object } = int;
let { x, y, z } = point;
mat.color.set(0x5555aa);
obj.visible = true;
if (event.shiftKey && zlist.length) {
for (let v of zlist) {
if (Math.abs(v - y) < 0.1) {
mat.color.set(0xaa5555);
y = v;
break;
}
}
if (event.shiftKey) {
y = split.closestZ(y, object, face).y;
}
// y is z in model space for the purposes of a split
state.plane = { z: y };
@ -223,7 +211,7 @@ let split = {
select() {
let { log } = mesh.api;
let { models, plane, zlist } = split.state;
let { models, plane } = split.state;
log.emit(`splitting ${models.length} model(s) at ${plane.z.round(3)}`).pin();
Promise.all(models.map(m => m.split(plane))).then(models => {
mesh.api.selection.set(models);
@ -240,6 +228,18 @@ let split = {
space.mouse.onHover(undefined);
temp_mode = split.state = undefined;
mesh.api.selection.update();
},
closestZ(z, object, face) {
let { position } = object.geometry.attributes;
let matrix = object.matrixWorld;
let v0 = new Vector3(position.getX(face.a), position.getY(face.a), position.getZ(face.a)).applyMatrix4(matrix);
let v1 = new Vector3(position.getX(face.b), position.getY(face.b), position.getZ(face.b)).applyMatrix4(matrix);
let v2 = new Vector3(position.getX(face.c), position.getY(face.c), position.getZ(face.c)).applyMatrix4(matrix);
v0._d = Math.abs(v0.y - z);
v1._d = Math.abs(v1.y - z);
v2._d = Math.abs(v2.y - z);
return [ v0, v1, v2 ].sort((a,b) => a._d - b._d)[0];
}
}
@ -503,7 +503,7 @@ function load_files(files) {
]) ]
});
} else {
load_files(files);
load_files_opt(files);
}
}

View file

@ -115,6 +115,10 @@ mesh.model = class MeshModel extends mesh.object {
return this.mesh.matrixWorld.elements;
}
get matrixWorld() {
return this.mesh.matrixWorld;
}
// override and translate mesh
move(x = 0, y = 0, z = 0) {
let arr = this.attributes.position.array;