Mesh selection modes

This commit is contained in:
JannisX11 2021-08-22 01:25:50 +02:00
parent 62dd1e54eb
commit b54934c5ce
5 changed files with 78 additions and 29 deletions

View File

@ -149,11 +149,11 @@ class Mesh extends OutlinerElement {
this.addVertices([16, 16, 16], [16, 16, 0], [16, 0, 16], [16, 0, 0], [0, 16, 16], [0, 16, 0], [0, 0, 16], [0, 0, 0]);
let vertex_keys = Object.keys(this.vertices);
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[0], vertex_keys[2], vertex_keys[1], vertex_keys[3]]} )); // East
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[4], vertex_keys[6], vertex_keys[5], vertex_keys[7]]} )); // West
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[0], vertex_keys[4], vertex_keys[1], vertex_keys[5]]} )); // Up
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[2], vertex_keys[3], vertex_keys[6], vertex_keys[7]]} )); // Down
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[0], vertex_keys[2], vertex_keys[4], vertex_keys[6]]} )); // South
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[1], vertex_keys[5], vertex_keys[3], vertex_keys[7]]} )); // North
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[4], vertex_keys[5], vertex_keys[6], vertex_keys[7]]} )); // West
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[0], vertex_keys[1], vertex_keys[4], vertex_keys[5]]} )); // Up
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[2], vertex_keys[6], vertex_keys[3], vertex_keys[7]]} )); // Down
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[0], vertex_keys[4], vertex_keys[2], vertex_keys[6]]} )); // South
this.addFaces(new MeshFace( this, {vertices: [vertex_keys[1], vertex_keys[3], vertex_keys[5], vertex_keys[7]]} )); // North
for (let key in this.faces) {
let face = this.faces[key];
@ -367,7 +367,8 @@ new NodePreviewController(Mesh, {
mesh.geometry.setAttribute('highlight', new THREE.BufferAttribute(new Uint8Array(24), 1));
// Outline
let outline = new THREE.LineSegments(new THREE.BufferGeometry(), Canvas.outlineMaterial);
let outline = new THREE.LineSegments(new THREE.BufferGeometry(), Canvas.meshOutlineMaterial);
outline.geometry.setAttribute('color', new THREE.Float32BufferAttribute(new Array(240).fill(1), 3));
outline.no_export = true;
outline.name = element.uuid+'_outline';
outline.visible = element.selected;
@ -375,10 +376,10 @@ new NodePreviewController(Mesh, {
outline.frustumCulled = false;
mesh.outline = outline;
mesh.add(outline);
outline.vertex_order = [];
// Vertex Points
let material = new THREE.PointsMaterial({size: 7, sizeAttenuation: false, vertexColors: true});
let points = new THREE.Points(new THREE.BufferGeometry(), material);
let points = new THREE.Points(new THREE.BufferGeometry(), Canvas.meshVertexMaterial);
points.geometry.setAttribute('color', new THREE.Float32BufferAttribute(new Array(24).fill(1), 3));
mesh.vertex_points = points;
outline.add(points);
@ -398,6 +399,7 @@ new NodePreviewController(Mesh, {
let normal_array = [];
let indices = [];
let outline_positions = [];
mesh.outline.vertex_order.empty();
for (let key in element.vertices) {
let vector = element.vertices[key];
@ -411,8 +413,8 @@ new NodePreviewController(Mesh, {
if (face.vertices.length == 2) {
// Outline
outline_positions.push(...element.vertices[face.vertices[0]]);
outline_positions.push(...element.vertices[face.vertices[1]]);
mesh.outline.vertex_order.push(face.vertices[0]);
mesh.outline.vertex_order.push(face.vertices[1]);
} else if (face.vertices.length == 3) {
// Tri
@ -426,12 +428,12 @@ new NodePreviewController(Mesh, {
// Outline
face.vertices.forEach((key, i) => {
outline_positions.push(...element.vertices[key]);
mesh.outline.vertex_order.push(key);
if (i) {
outline_positions.push(...element.vertices[key]);
mesh.outline.vertex_order.push(key);
}
})
outline_positions.push(...element.vertices[face.vertices[0]]);
mesh.outline.vertex_order.push(face.vertices[0]);
} else if (face.vertices.length == 4) {
@ -457,13 +459,17 @@ new NodePreviewController(Mesh, {
// Outline
sorted_vertices.forEach((key, i) => {
outline_positions.push(...element.vertices[key]);
if (i != 0) outline_positions.push(...element.vertices[key]);
mesh.outline.vertex_order.push(key);
if (i != 0) mesh.outline.vertex_order.push(key);
})
outline_positions.push(...element.vertices[sorted_vertices[0]]);
mesh.outline.vertex_order.push(sorted_vertices[0]);
}
}
mesh.outline.vertex_order.forEach(key => {
outline_positions.push(...element.vertices[key]);
})
mesh.vertex_points.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(point_position_array), 3));
mesh.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(position_array), 3));
@ -532,6 +538,7 @@ new NodePreviewController(Mesh, {
let mesh = element.mesh;
let colors = [];
let line_colors = [];
for (let key in element.vertices) {
let color;
@ -542,9 +549,21 @@ new NodePreviewController(Mesh, {
}
colors.push(color.r, color.g, color.b);
}
mesh.outline.vertex_order.forEach(key => {
let color;
if (!Modes.edit || BarItems.selection_mode.value == 'object' || (Project.selected_vertices[element.uuid] && Project.selected_vertices[element.uuid].includes(key))) {
color = gizmo_colors.outline;
} else {
color = gizmo_colors.grid;
}
line_colors.push(color.r, color.g, color.b);
})
mesh.vertex_points.geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
mesh.vertex_points.visible = Mode.selected.id == 'edit';
mesh.outline.geometry.setAttribute('color', new THREE.Float32BufferAttribute(line_colors, 3));
mesh.outline.geometry.needsUpdate = true
mesh.vertex_points.visible = Mode.selected.id == 'edit' && BarItems.selection_mode.value == 'vertex';
}
})
@ -597,8 +616,8 @@ BARS.defineActions(function() {
new BarSelect('selection_mode', {
options: {
object: true,
vertex: true,
face: true,
vertex: true,
},
condition: () => Format && Format.meshes,
onChange: function(slider) {

View File

@ -24,6 +24,12 @@ const Canvas = {
transparent: true,
color: gizmo_colors.outline
}),
meshOutlineMaterial: new THREE.LineBasicMaterial({
linewidth: 2,
//color: gizmo_colors.outline,
vertexColors: true
}),
meshVertexMaterial: new THREE.PointsMaterial({size: 7, sizeAttenuation: false, vertexColors: true}),
wireframeMaterial: new THREE.MeshBasicMaterial({
color: gizmo_colors.wire,
wireframe: true

View File

@ -350,7 +350,7 @@ class Preview {
Outliner.elements.forEach(element => {
if (element.mesh.geometry && element.visibility && !element.locked) {
objects.push(element.mesh);
if (element.mesh.vertex_points) {
if (element.mesh.vertex_points && element.mesh.vertex_points.visible) {
objects.push(element.mesh.vertex_points);
}
}
@ -682,9 +682,11 @@ class Preview {
var data = this.raycast(event);
if (data) {
//this.static_rclick = false
this.controls.hasMoved = true
let select_mode = BarItems.selection_mode.value
if (data.element && data.element.locked) {
this.controls.hasMoved = true
$('#preview').css('cursor', 'not-allowed')
function resetCursor() {
$('#preview').css('cursor', (Toolbox.selected.cursor ? Toolbox.selected.cursor : 'default'))
@ -693,7 +695,6 @@ class Preview {
addEventListeners(document, 'mouseup touchend', resetCursor, false)
} else if (Toolbox.selected.selectElements && Modes.selected.selectElements && data.type === 'element') {
this.controls.hasMoved = true
if (Toolbox.selected.selectFace) {
UVEditor.setFace(data.face, false)
}
@ -709,17 +710,30 @@ class Preview {
data.element.parent.select().showInOutliner();
} else if (!Animator.open) {
data.element.select(event)
if (data.element instanceof Mesh && select_mode == 'face') {
if (!data.element.selected) data.element.select(event);
if (!Project.selected_vertices[data.element.uuid]) {
Project.selected_vertices[data.element.uuid] = [];
}
if (!(event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift)) {
Project.selected_vertices[data.element.uuid].empty();
}
Project.selected_vertices[data.element.uuid].safePush(...data.element.faces[data.face].vertices);
} else {
data.element.select(event)
}
updateSelection();
}
} else if (Animator.open && data.type == 'keyframe') {
this.controls.hasMoved = true
if (data.keyframe instanceof Keyframe) {
data.keyframe.select(event).callPlayhead();
updateSelection();
}
} else if (data.type == 'vertex') {
this.controls.hasMoved = true
if (!Project.selected_vertices[data.element.uuid]) {
Project.selected_vertices[data.element.uuid] = [];

View File

@ -2151,7 +2151,18 @@ Interface.definePanels(function() {
if (pos[0] != last_pos[0] || pos[1] != last_pos[1]) {
elements.forEach(element => {
offset(element, pos[0] - last_pos[0], pos[1] - last_pos[1])
if (element instanceof Mesh) {
scope.selected_faces.forEach(key => {
let face = element.faces[key];
if (!face) return;
face.vertices.forEach(vertex_key => {
face.uv[vertex_key][0] += pos[0] - last_pos[0];
face.uv[vertex_key][1] += pos[1] - last_pos[1];
})
})
} else {
offset(element, pos[0] - last_pos[0], pos[1] - last_pos[1]);
}
})
last_pos.replace(pos);
}
@ -2421,7 +2432,7 @@ Interface.definePanels(function() {
v-for="(face, key) in element.faces" :key="key"
v-if="face.vertices.length > 2 && face.getTexture() == texture"
:class="{selected: selected_faces.includes(key)}"
@click.prevent.stop="selectFace(key, $event)"
@mousedown.prevent="dragFace(key, $event)"
:style="{
left: toPixels(getMeshFaceCorner(face, 0), -1),
top: toPixels(getMeshFaceCorner(face, 1), -1),
@ -2433,7 +2444,6 @@ Interface.definePanels(function() {
<polygon :points="getMeshFaceOutline(face)" />
</svg>
<template v-if="selected_faces.includes(key)">
{{ key }}
<div class="uv_mesh_vertex" v-for="key in face.vertices"
:class="{selected: selected_vertices[element.uuid] && selected_vertices[element.uuid].includes(key)}"
@mousedown.prevent.stop="dragVertices(element, key, $event)"

View File

@ -150,7 +150,7 @@ class UndoSystem {
new_element.faces[face].reset()
}
new_element.extend(element)
element.preview_controller.updateAll(element);
new_element.preview_controller.updateAll(new_element);
} else {
new_element = OutlinerElement.fromSave(element, true);
}