mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-02-05 15:50:21 +08:00
Merge branch 'next' of https://github.com/JannisX11/blockbench into next
This commit is contained in:
commit
74cd419934
@ -245,8 +245,8 @@ const Timeline = {
|
||||
return 1/Math.clamp(Animation.selected ? Animation.selected.snapping : settings.animation_snap.value, 1, 120);
|
||||
},
|
||||
setup() {
|
||||
$('#timeline_body').on('mousedown', e => {
|
||||
if (e.which === 2) {
|
||||
document.getElementById('timeline_body').addEventListener('mousedown', e => {
|
||||
if (e.which === 2 || Keybinds.extra.preview_drag.keybind.isTriggered(e)) {
|
||||
let pos = [e.clientX, e.clientY];
|
||||
let timeline = e.currentTarget;
|
||||
function move(e2) {
|
||||
@ -259,6 +259,9 @@ const Timeline = {
|
||||
function stop(e2) {
|
||||
document.removeEventListener('mousemove', move);
|
||||
document.removeEventListener('mouseup', stop);
|
||||
if (e.which == 3 && Math.pow(e.clientX - pos[0], 2) + Math.pow(e.clientY - pos[1], 2) > 40) {
|
||||
preventContextMenu();
|
||||
}
|
||||
}
|
||||
document.addEventListener('mousemove', move);
|
||||
document.addEventListener('mouseup', stop);
|
||||
@ -583,6 +586,7 @@ const Timeline = {
|
||||
},
|
||||
showMenu(event) {
|
||||
if (event.target.nodeName == 'KEYFRAME' || event.target.parentElement.nodeName == 'KEYFRAME') return;
|
||||
if (Blockbench.hasFlag('no_context_menu')) return;
|
||||
Timeline.menu.open(event, event);
|
||||
},
|
||||
menu: new Menu([
|
||||
|
@ -939,7 +939,6 @@ window.MessageBox = class MessageBox extends Dialog {
|
||||
close(button, result, event) {
|
||||
if (this.callback) {
|
||||
let allow_close = this.callback(button, result, event);
|
||||
console.log(allow_close)
|
||||
if (allow_close === false) return;
|
||||
}
|
||||
this.hide();
|
||||
|
@ -646,3 +646,10 @@ class Menu {
|
||||
rm_item.menus.remove(scope)
|
||||
}
|
||||
}
|
||||
|
||||
function preventContextMenu() {
|
||||
Blockbench.addFlag('no_context_menu');
|
||||
setTimeout(() => {
|
||||
Blockbench.removeFlag('no_context_menu');
|
||||
}, 20);
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ onVueSetup(function() {
|
||||
this.updateThumbnails();
|
||||
|
||||
setInterval(() => {
|
||||
if (this.show_splash_screen && this.slideshow_autoplay && this.$el.checkVisibility()) {
|
||||
if (this.show_splash_screen && this.slideshow_autoplay && this.$el.offsetParent) {
|
||||
slideshow_timer += 1;
|
||||
|
||||
if (slideshow_timer == 24) {
|
||||
|
@ -304,6 +304,7 @@ class ModelProject {
|
||||
Animator.MolangParser.context = {};
|
||||
scene.remove(this.model_3d);
|
||||
OutlinerNode.uuids = {};
|
||||
MirrorModeling.cached_elements = {};
|
||||
Format = 0;
|
||||
Project = 0;
|
||||
Undo = 0;
|
||||
|
@ -16,7 +16,7 @@ const MirrorModeling = {
|
||||
},
|
||||
createClone(original, undo_aspects) {
|
||||
// Create or update clone
|
||||
var center = Format.centered_grid ? 0 : 8;
|
||||
let center = Format.centered_grid ? 0 : 8;
|
||||
let mirror_element = MirrorModeling.cached_elements[original.uuid]?.counterpart;
|
||||
let element_before_snapshot;
|
||||
|
||||
@ -78,9 +78,6 @@ const MirrorModeling = {
|
||||
let edit_side = MirrorModeling.getEditSide();
|
||||
// Delete all vertices on the non-edit side
|
||||
let deleted_vertices = {};
|
||||
let selected_vertices = mesh.getSelectedVertices(true);
|
||||
//let selected_vertices = mesh.getSelectedEdges(true);
|
||||
let selected_faces = mesh.getSelectedFaces(true);
|
||||
let deleted_vertices_by_position = {};
|
||||
function positionKey(position) {
|
||||
return position.map(p => Math.roundTo(p, 2)).join(',');
|
||||
@ -205,47 +202,54 @@ const MirrorModeling = {
|
||||
|
||||
Blockbench.on('init_edit', ({aspects}) => {
|
||||
if (!BarItems.mirror_modeling.value) return;
|
||||
if (!aspects.elements) return;
|
||||
|
||||
MirrorModeling.cached_elements = {};
|
||||
MirrorModeling.outliner_snapshot = aspects.outliner ? null : compileGroups(true);
|
||||
let edit_side = MirrorModeling.getEditSide();
|
||||
if (aspects.elements) {
|
||||
MirrorModeling.cached_elements = {};
|
||||
MirrorModeling.outliner_snapshot = aspects.outliner ? null : compileGroups(true);
|
||||
let edit_side = MirrorModeling.getEditSide();
|
||||
|
||||
aspects.elements.forEach((element) => {
|
||||
if (element.allow_mirror_modeling) {
|
||||
let is_centered = MirrorModeling.isCentered(element);
|
||||
aspects.elements.forEach((element) => {
|
||||
if (element.allow_mirror_modeling) {
|
||||
let is_centered = MirrorModeling.isCentered(element);
|
||||
|
||||
let data = MirrorModeling.cached_elements[element.uuid] = {is_centered};
|
||||
if (!is_centered) {
|
||||
data.is_original = Math.sign(element.getWorldCenter().x) != edit_side;
|
||||
data.counterpart = Painter.getMirrorElement(element, [1, 0, 0]);
|
||||
if (!data.counterpart) data.is_original = true;
|
||||
let data = MirrorModeling.cached_elements[element.uuid] = {is_centered};
|
||||
if (!is_centered) {
|
||||
data.is_original = Math.sign(element.getWorldCenter().x) != edit_side;
|
||||
data.counterpart = Painter.getMirrorElement(element, [1, 0, 0]);
|
||||
if (!data.counterpart) data.is_original = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(() => {MirrorModeling.cached_elements = {}}, 10_000);
|
||||
})
|
||||
}
|
||||
})
|
||||
Blockbench.on('finish_edit', ({aspects}) => {
|
||||
if (!BarItems.mirror_modeling.value) return;
|
||||
if (!aspects.elements) return;
|
||||
|
||||
aspects.elements = aspects.elements.slice();
|
||||
let static_elements_copy = aspects.elements.slice();
|
||||
static_elements_copy.forEach((element) => {
|
||||
if (element.allow_mirror_modeling) {
|
||||
let is_centered = MirrorModeling.isCentered(element);
|
||||
if (aspects.elements) {
|
||||
aspects.elements = aspects.elements.slice();
|
||||
let static_elements_copy = aspects.elements.slice();
|
||||
static_elements_copy.forEach((element) => {
|
||||
if (element.allow_mirror_modeling) {
|
||||
let is_centered = MirrorModeling.isCentered(element);
|
||||
|
||||
if (is_centered && element instanceof Mesh) {
|
||||
// Complete other side of mesh
|
||||
MirrorModeling.createLocalSymmetry(element);
|
||||
if (is_centered && element instanceof Mesh) {
|
||||
// Complete other side of mesh
|
||||
MirrorModeling.createLocalSymmetry(element);
|
||||
}
|
||||
if (is_centered) {
|
||||
let mirror_element = MirrorModeling.cached_elements[element.uuid]?.counterpart;
|
||||
if (mirror_element) {
|
||||
MirrorModeling.insertElementIntoUndo(mirror_element, Undo.current_save.aspects, mirror_element.getUndoCopy());
|
||||
mirror_element.remove();
|
||||
aspects.elements.remove(mirror_element);
|
||||
}
|
||||
} else {
|
||||
// Construct clone at other side of model
|
||||
MirrorModeling.createClone(element, aspects);
|
||||
}
|
||||
}
|
||||
if (!is_centered) {
|
||||
// Construct clone at other side of model
|
||||
MirrorModeling.createClone(element, aspects);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Element property on cube and mesh
|
||||
@ -259,6 +263,7 @@ BARS.defineActions(() => {
|
||||
category: 'edit',
|
||||
condition: {modes: ['edit']},
|
||||
onChange() {
|
||||
MirrorModeling.cached_elements = {};
|
||||
updateSelection();
|
||||
}
|
||||
})
|
||||
|
@ -1300,7 +1300,7 @@
|
||||
}
|
||||
})
|
||||
displayDistance(move_value * (scope.direction ? 1 : -1));
|
||||
scope.updateSelection()
|
||||
updateSelection()
|
||||
previousValue = move_value
|
||||
scope.hasChanged = true
|
||||
}
|
||||
|
@ -235,14 +235,16 @@ class MeshFace extends Face {
|
||||
if (this.mesh.faces[fkey] == this) return fkey;
|
||||
}
|
||||
}
|
||||
UVToLocal(uv, vertices = this.vertices) {
|
||||
UVToLocal(uv, vertices = this.getSortedVertices()) {
|
||||
let vert_a = vertices[0];
|
||||
let vert_b = vertices[1];
|
||||
let vert_c = vertices[2];
|
||||
|
||||
if (vertices[3]) {
|
||||
let dist_1 = Math.abs(Math.pow(uv[0] - this.uv[vertices[1]][0], 2) + Math.pow(uv[1] - this.uv[vertices[1]][1], 2));
|
||||
let dist_2 = Math.abs(Math.pow(uv[0] - this.uv[vertices[3]][0], 2) + Math.pow(uv[1] - this.uv[vertices[3]][1], 2));
|
||||
if (dist_1 > dist_2) {
|
||||
let is_in_tri = pointInTriangle(uv, this.uv[vert_a], this.uv[vert_b], this.uv[vert_c]);
|
||||
|
||||
if (!is_in_tri) {
|
||||
vert_a = vertices[0];
|
||||
vert_b = vertices[2];
|
||||
vert_c = vertices[3];
|
||||
}
|
||||
@ -536,6 +538,7 @@ class Mesh extends OutlinerElement {
|
||||
getSize(axis, selection_only) {
|
||||
if (selection_only) {
|
||||
let selected_vertices = Project.mesh_selection[this.uuid]?.vertices || Object.keys(this.vertices);
|
||||
if (!selected_vertices.length) return 0;
|
||||
let range = [Infinity, -Infinity];
|
||||
let {vec1, vec2} = Reusable;
|
||||
let rotation_inverted = new THREE.Euler().copy(Transformer.rotation_selection).invert();
|
||||
|
@ -100,7 +100,7 @@ class ReferenceImage {
|
||||
}
|
||||
addAsReference(save) {
|
||||
Project.reference_images.push(this);
|
||||
if (Preview.selected && Preview.selected.isOrtho) this.changeLayer('blueprint');
|
||||
if (Preview.selected && Preview.selected.angle) this.changeLayer('blueprint');
|
||||
this.scope = 'project';
|
||||
this.update();
|
||||
if (save) this.save();
|
||||
@ -108,7 +108,7 @@ class ReferenceImage {
|
||||
}
|
||||
addAsGlobalReference(save) {
|
||||
ReferenceImage.global.push(this);
|
||||
if (Preview.selected && Preview.selected.isOrtho) this.changeLayer('blueprint');
|
||||
if (Preview.selected && Preview.selected.angle) this.changeLayer('blueprint');
|
||||
this.scope = 'global';
|
||||
this.update();
|
||||
if (save) this.save();
|
||||
@ -256,7 +256,7 @@ class ReferenceImage {
|
||||
pos_x += preview.width/2;
|
||||
pos_y += preview.height/2;
|
||||
|
||||
if (quad_previews.enabled) {
|
||||
if (Preview.split_screen.enabled) {
|
||||
pos_x += preview.node.parentElement.offsetLeft;
|
||||
pos_y += preview.node.parentElement.offsetTop;
|
||||
}
|
||||
|
@ -2275,7 +2275,7 @@ Interface.definePanels(function() {
|
||||
let original_margin = scope.getFrameMargin();
|
||||
let offset = $(scope.$refs.viewport).offset();
|
||||
UVEditor.total_zoom_offset = [6, 6];
|
||||
if (event.which === 2 || (event.touches && !Toolbox.selected.paintTool && event.target.id == 'uv_frame')) {
|
||||
if (event.which === 2 || Keybinds.extra.preview_drag.keybind.isTriggered(event) || (event.touches && !Toolbox.selected.paintTool && event.target.id == 'uv_frame')) {
|
||||
// Drag
|
||||
if (event.touches) {
|
||||
event.clientX = event.touches[0].clientX;
|
||||
@ -2285,8 +2285,8 @@ Interface.definePanels(function() {
|
||||
let margin = this.getFrameMargin();
|
||||
let margin_center = [this.width/2, this.height/2];
|
||||
let original = [
|
||||
viewport.scrollLeft,
|
||||
viewport.scrollTop
|
||||
viewport.scrollLeft - 5,
|
||||
viewport.scrollTop - 5
|
||||
];
|
||||
function dragMouseWheel(e2) {
|
||||
if (e2.touches) {
|
||||
@ -2323,6 +2323,9 @@ Interface.definePanels(function() {
|
||||
function dragMouseWheelStop(e) {
|
||||
removeEventListeners(document, 'mousemove touchmove', dragMouseWheel);
|
||||
removeEventListeners(document, 'mouseup touchend', dragMouseWheelStop);
|
||||
if (e.which == 3 && Math.pow(viewport.scrollLeft - original[0], 2) + Math.pow(viewport.scrollTop - original[1], 2) > 50) {
|
||||
preventContextMenu();
|
||||
}
|
||||
}
|
||||
addEventListeners(document, 'mousemove touchmove', dragMouseWheel);
|
||||
addEventListeners(document, 'mouseup touchend', dragMouseWheelStop);
|
||||
@ -2458,6 +2461,7 @@ Interface.definePanels(function() {
|
||||
},
|
||||
contextMenu(event) {
|
||||
setActivePanel('uv');
|
||||
if (Blockbench.hasFlag('no_context_menu')) return;
|
||||
UVEditor.menu.open(event);
|
||||
},
|
||||
selectTextureMenu(event) {
|
||||
|
@ -515,6 +515,19 @@ function lineIntersectsReactangle(p1, p2, rect_start, rect_end) {
|
||||
|| intersectLines(p1, p2, [rect_end[0], rect_end[1]], [rect_end[0], rect_start[1]])
|
||||
|| intersectLines(p1, p2, [rect_end[0], rect_end[1]], [rect_start[0], rect_end[1]])
|
||||
}
|
||||
function pointInTriangle(pt, v1, v2, v3) {
|
||||
function sign(p1, p2, p3) {
|
||||
return (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1]);
|
||||
}
|
||||
let d1 = sign(pt, v1, v2);
|
||||
let d2 = sign(pt, v2, v3);
|
||||
let d3 = sign(pt, v3, v1);
|
||||
|
||||
let has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
|
||||
let has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
|
||||
|
||||
return !(has_neg && has_pos);
|
||||
}
|
||||
|
||||
function cameraTargetToRotation(position, target) {
|
||||
let spherical = new THREE.Spherical();
|
||||
|
@ -80,7 +80,7 @@ async function loadInfoFromURL() {
|
||||
if (Blockbench.queries.plugins) {
|
||||
let plugin_ids = Blockbench.queries.plugins.split(/,/);
|
||||
let plugins = plugin_ids.map(id => Plugins.all.find(plugin => plugin.id == id))
|
||||
.filter(p => p instanceof Plugin && p.installed == false && p.isInstallable());
|
||||
.filter(p => p instanceof Plugin && p.installed == false && p.isInstallable() == true);
|
||||
if (plugins.length) {
|
||||
await new Promise(resolve => {
|
||||
let form = {
|
||||
|
Loading…
Reference in New Issue
Block a user