Implement new system to update view

This commit is contained in:
JannisX11 2021-07-29 18:17:26 +02:00
parent 5fe1d62424
commit 45eef76105
14 changed files with 177 additions and 134 deletions

View File

@ -214,6 +214,7 @@
}
div#header_free_bar.app-drag-region {
flex-grow: 1;
overflow: hidden;
height: auto;
padding: 3px;
color: var(--color-subtle_text);
@ -241,6 +242,7 @@
}
#windows_window_menu {
margin-left: auto;
flex-shrink: 0;
}
#windows_window_menu li {
display: block;
@ -264,6 +266,7 @@
}
#mac_window_menu {
width: 68px;
flex-shrink: 0;
}
/*Mobile*/

View File

@ -104,20 +104,20 @@ function updateSelection(options = {}) {
})
if (Group.selected && Group.selected.locked) Group.selected.unselect()
Cube.all.forEach(cube => {
if (cube.visibility) {
var mesh = cube.mesh
Outliner.elements.forEach(element => {
if (element.visibility) {
var mesh = element.mesh
if (mesh && mesh.outline) {
mesh.outline.visible = cube.selected
mesh.outline.visible = element.selected
}
}
})
for (var i = Cube.selected.length-1; i >= 0; i--) {
if (!selected.includes(Cube.selected[i])) {
Cube.selected.splice(i, 1)
for (var i = Outliner.selected.length-1; i >= 0; i--) {
if (!selected.includes(Outliner.selected[i])) {
Outliner.selected.splice(i, 1)
}
}
if (Cube.selected.length) {
if (Outliner.selected.length) {
document.querySelectorAll('.selection_only').forEach(node => node.style.setProperty('visibility', 'visible'));
} else {
if (Format.bone_rig && Group.selected) {
@ -136,7 +136,7 @@ function updateSelection(options = {}) {
document.querySelectorAll('.selection_only#uv').forEach(node => node.style.setProperty('visibility', 'visible'));
}
}
if (Cube.selected.length || (Format.single_texture && Modes.paint)) {
if (Outliner.selected.length || (Format.single_texture && Modes.paint)) {
main_uv.jquery.size.find('.uv_mapping_overlay').remove()
main_uv.loadData()
}
@ -150,7 +150,7 @@ function updateSelection(options = {}) {
BarItems.cube_counter.update();
updateNslideValues();
if (settings.highlight_cubes.value) updateCubeHighlights();
Canvas.updateOrigin();
Canvas.updatePivotMarker();
Transformer.updateSelection();
Transformer.update();
Preview.all.forEach(preview => {

View File

@ -179,12 +179,10 @@ const Clipbench = {
iterate(child, copy)
})
}
} else {
} else if (OutlinerElement.isTypePermitted(obj.type)) {
var el = OutlinerElement.fromSave(obj).addTo(parent).selectLow();
el.createUniqueName();
if (el instanceof Cube) {
Canvas.adaptObjectPosition(el);
}
el.preview_controller.updateTransform(el);
}
}
iterate(Clipbench.group, target)
@ -193,6 +191,7 @@ const Clipbench = {
} else if (Clipbench.elements && Clipbench.elements.length) {
let elements = [];
Clipbench.elements.forEach(function(obj) {
if (!OutlinerElement.isTypePermitted(obj.type)) return;
var el = OutlinerElement.fromSave(obj).addTo(target).selectLow();
el.createUniqueName();
elements.push(el);

View File

@ -133,6 +133,12 @@ class ModelFormat {
})
}
if (!Format.single_texture && old_format.single_texture && Texture.all.length == 1) {
Cube.all.forEach(cube => {
cube.applyTexture(Texture.all[0], true)
})
}
//Rotate Cubes
if (!Format.rotate_cubes && old_format.rotate_cubes) {
Cube.all.forEach(cube => {

View File

@ -389,6 +389,7 @@ var codec = new Codec('project', {
let default_texture = new_textures[0] || Texture.getDefault();
let format = Formats[model.meta.model_format] || Format
model.elements.forEach(function(element) {
if (!OutlinerElement.isTypePermitted(element.type)) return;
var copy = OutlinerElement.fromSave(element, true)
if (copy instanceof Cube) {

View File

@ -415,9 +415,10 @@ class Cube extends OutlinerElement {
}
}
}
Canvas.adaptObjectPosition(this)
Canvas.adaptObjectFaces(this)
Canvas.updateUV(this)
this.preview_controller.updateTransform(this);
this.preview_controller.updateGeometry(this);
this.preview_controller.updateFaces(this);
this.preview_controller.updateUV(this);
return this;
}
flip(axis, center, skipUV) {
@ -480,9 +481,10 @@ class Cube extends OutlinerElement {
this.faces.down.uv = mirrorUVY('down')
}
}
Canvas.adaptObjectPosition(this)
Canvas.adaptObjectFaces(this)
Canvas.updateUV(this)
this.preview_controller.updateTransform(this);
this.preview_controller.updateGeometry(this);
this.preview_controller.updateFaces(this);
this.preview_controller.updateUV(this);
}
transferOrigin(origin, update = true) {
if (!this.mesh) return;
@ -501,7 +503,8 @@ class Cube extends OutlinerElement {
this.origin.V3_set(origin);
Canvas.adaptObjectPosition(this)
this.preview_controller.updateTransform(this);
this.preview_controller.updateGeometry(this);
return this;
}
getWorldCenter() {
@ -525,7 +528,7 @@ class Cube extends OutlinerElement {
setColor(index) {
this.color = index;
if (this.visibility) {
Canvas.adaptObjectFaces(this)
this.preview_controller.updateFaces(this);
}
}
applyTexture(texture, faces) {
@ -550,8 +553,8 @@ class Cube extends OutlinerElement {
main_uv.loadData()
}
if (Prop.view_mode === 'textured' && scope.visibility == true) {
Canvas.adaptObjectFaces(scope)
Canvas.updateUV(scope)
this.preview_controller.updateFaces(this);
this.preview_controller.updateUV(this);
}
}
mapAutoUV() {
@ -700,7 +703,8 @@ class Cube extends OutlinerElement {
})
if (update) {
this.mapAutoUV()
Canvas.adaptObjectPosition(this);
this.preview_controller.updateTransform(this);
this.preview_controller.updateGeometry(this);
}
TickUpdates.selection = true;
return in_box;
@ -750,7 +754,7 @@ class Cube extends OutlinerElement {
if (Project.box_uv) {
Canvas.updateUV(this);
}
Canvas.adaptObjectPosition(this);
this.preview_controller.updateGeometry(this);
TickUpdates.selection = true;
return this;
}
@ -832,9 +836,22 @@ new NodePreviewController(Cube, {
mesh.name = element.uuid;
mesh.type = 'cube';
mesh.isElement = true;
mesh.visible = element.visibility;
mesh.geometry.setAttribute('highlight', new THREE.BufferAttribute(new Uint8Array(24).fill(1), 1));
// Outline
let geometry = new THREE.BufferGeometry();
let line = new THREE.Line(geometry, Canvas.outlineMaterial);
line.no_export = true;
line.name = element.uuid+'_outline';
line.visible = element.selected;
line.renderOrder = 2;
line.frustumCulled = false;
mesh.outline = line;
mesh.add(line);
// Update
this.updateTransform(element);
this.updateGeometry(element);
this.updateFaces(element);
@ -842,8 +859,7 @@ new NodePreviewController(Cube, {
if (Prop.view_mode === 'textured') {
this.updateUV(element);
}
mesh.visible = element.visibility;
Canvas.buildOutline(element);
},
updateTransform(element) {
NodePreviewController.prototype.updateTransform(element);
@ -860,7 +876,6 @@ new NodePreviewController(Cube, {
if (Modes.paint) {
Canvas.buildGridBox(element);
}
Canvas.buildOutline(element);
},
updateGeometry(element) {
if (element.resizable) {
@ -879,9 +894,24 @@ new NodePreviewController(Cube, {
}
})
mesh.geometry.setShape(from, to)
Canvas.getOutlineMesh(mesh, mesh.outline)
mesh.geometry.computeBoundingBox()
mesh.geometry.computeBoundingSphere()
// Update outline
var vs = [0,1,2,3,4,5,6,7].map(i => {
return mesh.geometry.attributes.position.array.slice(i*3, i*3 + 3)
});
let points = [
vs[2], vs[3],
vs[6], vs[7],
vs[2], vs[0],
vs[1], vs[4],
vs[5], vs[0],
vs[5], vs[7],
vs[6], vs[4],
vs[1], vs[3]
].map(a => new THREE.Vector3().fromArray(a))
mesh.outline.geometry.setFromPoints(points);
}
},
updateFaces(cube) {

View File

@ -230,19 +230,31 @@ new NodePreviewController(Mesh, {
mesh.geometry.setAttribute('highlight', new THREE.BufferAttribute(new Uint8Array(24).fill(1), 1));
// Outline
let outline = new THREE.LineSegments(new THREE.BufferGeometry(), Canvas.outlineMaterial);
outline.no_export = true;
outline.name = element.uuid+'_outline';
outline.visible = element.selected;
outline.renderOrder = 2;
outline.frustumCulled = false;
mesh.outline = outline;
mesh.add(outline);
// Vertex Points
let material = new THREE.PointsMaterial({size: 5, sizeAttenuation: false, vertexColors: true});
let points = new THREE.Points(mesh.geometry, material);
points.geometry.setAttribute('color', new THREE.Float32BufferAttribute(new Array(24).fill(1), 3));
mesh.vertex_points = points;
outline.add(points);
// Update
this.updateTransform(element);
this.updateGeometry(element);
this.updateFaces(element);
mesh.visible = element.visibility;
if (Prop.view_mode === 'textured') {
this.updateUV(element);
}
mesh.visible = element.visibility;
let material = new THREE.PointsMaterial({size: 5, sizeAttenuation: false});
let points = new THREE.Points(mesh.geometry, material)
mesh.add(points);
//Canvas.buildOutline(element);
},
updateGeometry(element) {
@ -250,6 +262,7 @@ new NodePreviewController(Mesh, {
let position_array = [];
let position_indices = [];
let indices = [];
let outline_positions = [];
for (let key in element.vertices) {
let vector = element.vertices[key];
@ -260,7 +273,7 @@ new NodePreviewController(Mesh, {
element.faces.forEach(face => {
if (face.vertices.length == 3) {
// Tri
face.vertices.forEach(key => {
face.vertices.forEach((key, i) => {
let index = position_indices.indexOf(key);
indices.push(index);
})
@ -274,14 +287,27 @@ new NodePreviewController(Mesh, {
indices.push(position_indices.indexOf(face.vertices[2]));
indices.push(position_indices.indexOf(face.vertices[3]));
}
// Outline
if (face.vertices.length == 4) {
face.vertices = [face.vertices[0], face.vertices[1], face.vertices[3], face.vertices[2]]
}
face.vertices.forEach((key, i) => {
outline_positions.push(...element.vertices[key]);
if (i && i < face.vertices.length-1) outline_positions.push(...element.vertices[key]);
})
if (face.vertices.length == 4) {
face.vertices = [face.vertices[0], face.vertices[1], face.vertices[3], face.vertices[2]]
}
})
mesh.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(position_array), 3));
mesh.geometry.setIndex( indices );
mesh.geometry.setIndex(indices);
//Canvas.getOutlineMesh(mesh, mesh.outline)
mesh.geometry.computeBoundingBox()
mesh.geometry.computeBoundingSphere()
mesh.outline.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(outline_positions), 3));
mesh.geometry.computeBoundingBox();
mesh.geometry.computeBoundingSphere();
},
updateFaces(element) {
let {mesh} = element;

View File

@ -101,6 +101,9 @@ class OutlinerNode {
}
return this;
}
get preview_controller() {
return this.constructor.preview_controller;
}
//Sorting
sortInBefore(element, index_mod) {
var index = -1;
@ -486,6 +489,12 @@ class OutlinerElement extends OutlinerNode {
return new Type(obj, keep_uuid ? obj.uuid : 0).init()
}
}
OutlinerElement.isTypePermitted = function(type) {
return !(
(obj.type == 'locator' && !Format.locators) ||
(obj.type == 'mesh' && !Format.meshes)
)
}
Object.defineProperty(OutlinerElement, 'all', {
get() {
return Project.elements ? Project.elements : [];
@ -538,6 +547,14 @@ class NodePreviewController {
}
delete Project.nodes_3d[obj.uuid];
}
updateAll(element) {
this.updateTransform(element);
this.updateVisibility(element);
if (this.updateGeometry) this.updateGeometry(element);
if (this.updateUV) this.updateUV(element);
if (this.updateFaces) this.updateFaces(element);
if (this.updatePaintingGrid) this.updatePaintingGrid(element);
}
updateTransform(element) {
let mesh = element.mesh;
@ -718,14 +735,16 @@ function dropOutlinerObjects(item, target, event, order) {
}
if (event.altKey) {
Undo.initEdit({elements: [], outliner: true, selection: true})
selected.empty();
Outliner.selected.empty();
} else {
Undo.initEdit({outliner: true, selection: true})
var updatePosRecursive = function(item) {
if (item.type === 'cube') {
Canvas.adaptObjectPosition(item)
} else if (item.type === 'group' && item.children && item.children.length) {
item.children.forEach(updatePosRecursive)
if (item.type == 'group') {
if (item.children && item.children.length) {
item.children.forEach(updatePosRecursive)
}
} else {
item.preview_controller.updateTransform(item);
}
}
}

View File

@ -259,6 +259,8 @@ const Canvas = {
}
},
updateVisibility() {
Canvas.updateView({elements: Outliner.elements, element_aspects: {visibility: true}})
/*
Cube.all.forEach(function(cube) {
if (cube.visibility && !cube.mesh.visible) {
cube.mesh.visible = true;
@ -274,6 +276,7 @@ const Canvas = {
}
})
TickUpdates.selection = true;
*/
},
updateAllFaces(texture) {
Cube.all.forEach(function(obj) {
@ -288,9 +291,9 @@ const Canvas = {
}
}
if (used === true) {
Canvas.adaptObjectFaces(obj)
obj.preview_controller.updateFaces(obj);
if (Prop.view_mode === 'textured') {
Canvas.updateUV(obj)
obj.preview_controller.updateUV(obj);
}
}
}
@ -298,6 +301,8 @@ const Canvas = {
},
updateAllUVs() {
if (Prop.view_mode !== 'textured') return;
Canvas.updateView({elements: Outliner.elements, element_aspects: {uv: true}});
return;
Cube.all.forEach(function(obj) {
if (obj.visibility == true) {
Canvas.updateUV(obj)
@ -350,9 +355,7 @@ const Canvas = {
Canvas.updateAllBones()
}
}
arr.forEach(function(obj) {
Canvas.adaptObjectPosition(obj)
})
Canvas.updateView({elements: arr, element_aspects: {transform: true, geometry: true}})
if (leave_selection !== true) {
TickUpdates.selection = true;
}
@ -360,9 +363,9 @@ const Canvas = {
updateSelectedFaces() {
Cube.selected.forEach(function(obj) {
if (obj.visibility == true) {
Canvas.adaptObjectFaces(obj)
obj.preview_controller.updateFaces(obj);
if (Prop.view_mode === 'textured') {
Canvas.updateUV(obj)
obj.preview_controller.updateUV(obj);
}
}
})
@ -371,25 +374,26 @@ const Canvas = {
if (Prop.view_mode !== 'textured') return;
Cube.selected.forEach(function(obj) {
if (obj.visibility == true) {
Canvas.updateUV(obj)
obj.preview_controller.updateUV(obj);
}
})
},
outlineObjects(arr) {
arr.forEach(function(obj) {
if (!obj.visibility) return;
var mesh = obj.mesh
var mesh = obj.mesh;
if (!mesh || !mesh.geometry) return;
var line = Canvas.getOutlineMesh(mesh)
var copy = mesh.outline.clone();
copy.geometry = mesh.outline.geometry.clone();
THREE.fastWorldPosition(mesh, line.position)
line.position.sub(scene.position)
line.rotation.setFromQuaternion(mesh.getWorldQuaternion(new THREE.Quaternion()))
mesh.getWorldScale(line.scale)
THREE.fastWorldPosition(mesh, copy.position);
copy.position.sub(scene.position);
copy.rotation.setFromQuaternion(mesh.getWorldQuaternion(new THREE.Quaternion()));
mesh.getWorldScale(copy.scale);
line.name = obj.uuid+'_ghost_outline'
Canvas.outlines.add(line)
copy.name = obj.uuid+'_ghost_outline';
Canvas.outlines.add(copy);
})
},
updateAllBones(bones = Group.all) {
@ -427,7 +431,7 @@ const Canvas = {
})
}
},
updateOrigin() {
updatePivotMarker() {
if (rot_origin.parent) {
rot_origin.parent.remove(rot_origin)
}
@ -778,48 +782,6 @@ const Canvas = {
vertex_uvs.array.set(arr[2], index*8 + 4); //0,0
vertex_uvs.array.set(arr[3], index*8 + 6); //1,0
},
//Outline
getOutlineMesh(mesh, line) {
var vs = [0,1,2,3,4,5,6,7].map(i => {
return mesh.geometry.attributes.position.array.slice(i*3, i*3 + 3)
});
let points = [
vs[2], vs[3],
vs[6], vs[7],
vs[2], vs[0],
vs[1], vs[4],
vs[5], vs[0],
vs[5], vs[7],
vs[6], vs[4],
vs[1], vs[3]
].map(a => new THREE.Vector3().fromArray(a))
if (!line) {
var geometry = new THREE.BufferGeometry();
line = new THREE.Line(geometry, Canvas.outlineMaterial);
line.no_export = true;
}
line.geometry.setFromPoints(points);
return line;
},
buildOutline(obj) {
if (obj.visibility == false) return;
var mesh = obj.mesh;
if (mesh === undefined) return;
if (mesh.outline) {
mesh.outline.geometry.verticesNeedUpdate = true;
return;
}
mesh.remove(mesh.outline);
var line = Canvas.getOutlineMesh(mesh)
line.name = obj.uuid+'_outline';
line.visible = obj.selected;
line.renderOrder = 2;
line.frustumCulled = false;
mesh.outline = line;
mesh.add(line);
},
buildGridBox(cube) {
var mesh = cube.mesh;
if (mesh === undefined) return;

View File

@ -107,8 +107,8 @@ const Painter = {
}
}
}
if (!data.intersects || (data.cube && data.cube.locked)) return;
var texture = data.cube.faces[data.face].getTexture()
if (!data.intersects || (data.element && data.element.locked)) return;
var texture = data.element.faces[data.face].getTexture()
if (!texture || (texture.error && texture.error !== 2)) {
Blockbench.showQuickMessage('message.untextured')
return;
@ -116,7 +116,7 @@ const Painter = {
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brushTool ? 0.5 : 0;
var x = Math.floor( data.intersects[0].uv.x * texture.img.naturalWidth + offset )
var y = Math.floor( (1-data.intersects[0].uv.y) * texture.img.naturalHeight + offset )
Painter.startPaintTool(texture, x, y, data.cube.faces[data.face].uv, e, data)
Painter.startPaintTool(texture, x, y, data.element.faces[data.face].uv, e, data)
if (Toolbox.selected.id !== 'color_picker') {
addEventListeners(document, 'mousemove touchmove', Painter.movePaintToolCanvas, false );
@ -126,8 +126,8 @@ const Painter = {
movePaintToolCanvas(event) {
convertTouchEvent(event);
var data = Canvas.raycast(event)
if (data && data.cube && !data.cube.locked) {
var texture = data.cube.faces[data.face].getTexture()
if (data && data.element && !data.element.locked) {
var texture = data.element.faces[data.face].getTexture()
if (texture) {
var x, y, new_face;
let offset = BarItems.slider_brush_size.get()%2 == 0 && Toolbox.selected.brushTool ? 0.5 : 0;
@ -138,20 +138,20 @@ const Painter = {
if (x === Painter.current.x && y === Painter.current.y) {
return
}
if (Painter.current.face !== data.face || Painter.current.cube !== data.cube) {
if (Painter.current.face !== data.face || Painter.current.cube !== data.element) {
if (Toolbox.selected.id === 'draw_shape_tool' || Toolbox.selected.id === 'gradient_tool') {
return;
}
Painter.current.x = x
Painter.current.y = y
Painter.current.face = data.face
Painter.current.cube = data.cube
Painter.current.cube = data.element
new_face = true
if (texture !== Painter.current.texture) {
Undo.current_save.addTexture(texture)
}
}
Painter.movePaintTool(texture, x, y, event, new_face, data.cube.faces[data.face].uv)
Painter.movePaintTool(texture, x, y, event, new_face, data.element.faces[data.face].uv)
}
}
},
@ -171,7 +171,7 @@ const Painter = {
Painter.brushChanges = false;
Painter.painting = true;
Painter.current = {
cube: data && data.cube,
cube: data && data.element,
face: data && data.face,
x, y,
clear: document.createElement('canvas'),
@ -187,8 +187,8 @@ const Painter = {
Painter.painting = true;
if (data) {
var is_line = event.shiftKey && Painter.current.cube == data.cube && Painter.current.face == data.face
Painter.current.cube = data.cube;
var is_line = event.shiftKey && Painter.current.cube == data.element && Painter.current.face == data.face
Painter.current.cube = data.element;
Painter.current.face = data.face;
} else {
//uv editor

View File

@ -793,8 +793,10 @@ const TextureGenerator = {
cube.faces[key].texture = texture.uuid;
}
}
Canvas.adaptObjectFaces(cube)
Canvas.updateUV(cube)
cube.preview_controller.updateFaces(cube);
if (Prop.view_mode === 'textured') {
cube.preview_controller.updateUV(cube);
}
}
cube.autouv = 0;
})

View File

@ -1407,7 +1407,7 @@ class UVEditor {
obj.faces[side].uv = [0, 0, 0, 0]
obj.faces[side].texture = null;
})
Canvas.adaptObjectFaces(obj)
obj.preview_controller.updateFaces(obj);
})
this.loadData()
this.message('uv_editor.transparent')
@ -1587,8 +1587,10 @@ class UVEditor {
scope.getFaces(event).forEach(function(side) {
obj.faces[side].reset()
})
Canvas.adaptObjectFaces(obj)
Canvas.updateUV(obj)
obj.preview_controller.updateFaces(obj);
if (Prop.view_mode === 'textured') {
obj.preview_controller.updateUV(obj);
}
})
this.loadData()
this.message('uv_editor.reset')
@ -1694,7 +1696,7 @@ class UVEditor {
editor.getFaces(event).forEach(function(side) {
obj.faces[side].texture = false;
})
Canvas.adaptObjectFaces(obj)
obj.preview_controller.updateFaces(obj);
})
editor.loadData()
editor.message('uv_editor.reset')

View File

@ -652,8 +652,8 @@ function moveElementsInSpace(difference, axis) {
if (el instanceof Cube) {
el.mapAutoUV()
}
Canvas.adaptObjectPosition(el);
})
Canvas.updateView({elements: selected, element_aspects: {transform: true, geometry: true}})
}
//Rotate
@ -895,8 +895,8 @@ BARS.defineActions(function() {
}
if (obj instanceof Cube) {
obj.mapAutoUV()
Canvas.adaptObjectPosition(obj);
}
obj.preview_controller.updateTransform(obj);
}
})
TickUpdates.selection = true;

View File

@ -150,14 +150,7 @@ class UndoSystem {
new_element.faces[face].reset()
}
new_element.extend(element)
if (new_element.mesh) {
Canvas.adaptObjectPosition(new_element)
}
if (new_element.type == 'cube') {
Canvas.adaptObjectFaceGeo(new_element)
Canvas.adaptObjectFaces(new_element)
Canvas.updateUV(new_element)
}
element.preview_controller.updateAll(element);
} else {
new_element = OutlinerElement.fromSave(element, true);
}
@ -219,7 +212,7 @@ class UndoSystem {
group.extend(save.group)
if (Format.bone_rig) {
group.forEachChild(function(obj) {
Canvas.adaptObjectPosition(obj)
obj.preview_controller.updateTransform(obj);
}, Cube)
}
}