mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-04-06 17:31:09 +08:00
parent
1afe9f4130
commit
946d7f4c64
@ -1391,6 +1391,20 @@ const Canvas = {
|
||||
if (height === Infinity) height = 0;
|
||||
|
||||
return [width, height]
|
||||
},
|
||||
getSelectionBounds() {
|
||||
let pivot_marker_parent = Canvas.pivot_marker.parent;
|
||||
let visible_box = new THREE.Box3();
|
||||
if (pivot_marker_parent) pivot_marker_parent.remove(Canvas.pivot_marker);
|
||||
Canvas.withoutGizmos(() => {
|
||||
Outliner.selected.forEach(element => {
|
||||
if (element.visibility && element.mesh && element.mesh.geometry) {
|
||||
visible_box.expandByObject(element.mesh);
|
||||
}
|
||||
})
|
||||
})
|
||||
if (pivot_marker_parent) pivot_marker_parent.add(Canvas.pivot_marker);
|
||||
return visible_box;
|
||||
}
|
||||
}
|
||||
var buildGrid = Canvas.buildGrid;
|
||||
|
@ -2268,14 +2268,19 @@ BARS.defineActions(function() {
|
||||
icon: 'center_focus_weak',
|
||||
category: 'view',
|
||||
condition: () => !Format.image_editor,
|
||||
keybind: new Keybind({}, {rotate_only: 'shift'}),
|
||||
keybind: new Keybind({}, {
|
||||
rotate_only: 'shift',
|
||||
zoom: 'ctrl'
|
||||
}),
|
||||
variations: {
|
||||
rotate_only: {name: 'action.focus_on_selection.rotate_only'}
|
||||
rotate_only: {name: 'action.focus_on_selection.rotate_only'},
|
||||
zoom: {name: 'action.focus_on_selection.zoom'}
|
||||
},
|
||||
click(event = 0) {
|
||||
if (!Project) return;
|
||||
let zoom = this.keybind.additionalModifierTriggered(event, 'zoom');
|
||||
if (Prop.active_panel == 'uv') {
|
||||
UVEditor.focusOnSelection()
|
||||
UVEditor.focusOnSelection(zoom)
|
||||
|
||||
} else {
|
||||
let preview = Preview.selected;
|
||||
@ -2288,8 +2293,24 @@ BARS.defineActions(function() {
|
||||
Transformer.getWorldPosition(center)
|
||||
}
|
||||
|
||||
let zoom_offset;
|
||||
let difference = new THREE.Vector3().copy(preview.controls.target).sub(center);
|
||||
difference.divideScalar(6)
|
||||
let cam_boom = center.clone().sub(preview.camera.position).add(difference);
|
||||
difference.divideScalar(6);
|
||||
|
||||
if (zoom) {
|
||||
let bounds = Canvas.getSelectionBounds();
|
||||
let radius = Math.max(
|
||||
Math.abs(bounds.min.x-center.x), Math.abs(bounds.max.x-center.x),
|
||||
Math.abs(bounds.min.z-center.z), Math.abs(bounds.max.z-center.z),
|
||||
);
|
||||
let height = Math.max(Math.abs(bounds.min.y-center.y), Math.abs(bounds.max.y-center.y));
|
||||
let focal_length = preview.camera.getFocalLength();
|
||||
let cam_distance = cam_boom.length();
|
||||
let target_distance = Math.max(radius, height) * (focal_length / 10);
|
||||
zoom_factor = target_distance / cam_distance;
|
||||
zoom_offset = cam_boom.multiplyScalar((zoom_factor-1) / 6);
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
let interval = setInterval(() => {
|
||||
@ -2298,6 +2319,10 @@ BARS.defineActions(function() {
|
||||
if (this.keybind.additionalModifierTriggered(event) != 'rotate_only' || preview.angle != null) {
|
||||
preview.camera.position.sub(difference);
|
||||
}
|
||||
if (zoom_offset) {
|
||||
preview.camera.position.sub(zoom_offset);
|
||||
}
|
||||
Transformer.update();
|
||||
i++;
|
||||
if (i == 6) clearInterval(interval);
|
||||
|
||||
|
@ -257,40 +257,20 @@ const UVEditor = {
|
||||
}
|
||||
this.vue.selection_outline = outline;
|
||||
},
|
||||
focusOnSelection() {
|
||||
let min_x = UVEditor.getUVWidth();
|
||||
let min_y = UVEditor.getUVHeight();
|
||||
let max_x = 0;
|
||||
let max_y = 0;
|
||||
let elements = UVEditor.getMappableElements();
|
||||
elements.forEach(element => {
|
||||
if (element instanceof Cube && element.box_uv) {
|
||||
let size = element.size(undefined, Format.box_uv_float_size != true)
|
||||
min_x = Math.min(min_x, element.uv_offset[0]);
|
||||
min_y = Math.min(min_y, element.uv_offset[1]);
|
||||
max_x = Math.max(max_x, element.uv_offset[0] + (size[0] + size[2]) * 2);
|
||||
max_y = Math.max(max_y, element.uv_offset[1] + size[1] + size[2]);
|
||||
} else {
|
||||
for (let fkey in element.faces) {
|
||||
if (!UVEditor.getSelectedFaces(element, false).includes(fkey)) continue;
|
||||
let face = element.faces[fkey];
|
||||
if (element instanceof Cube) {
|
||||
min_x = Math.min(min_x, face.uv[0], face.uv[2]);
|
||||
min_y = Math.min(min_y, face.uv[1], face.uv[3]);
|
||||
max_x = Math.max(max_x, face.uv[0], face.uv[2]);
|
||||
max_y = Math.max(max_y, face.uv[1], face.uv[3]);
|
||||
} else if (element instanceof Mesh) {
|
||||
face.vertices.forEach(vkey => {
|
||||
if (!face.uv[vkey]) return;
|
||||
min_x = Math.min(min_x, face.uv[vkey][0]);
|
||||
min_y = Math.min(min_y, face.uv[vkey][1]);
|
||||
max_x = Math.max(max_x, face.uv[vkey][0]);
|
||||
max_y = Math.max(max_y, face.uv[vkey][1]);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
async focusOnSelection(zoom) {
|
||||
if (zoom instanceof Event) {
|
||||
zoom = BarItems.focus_on_selection.keybind.additionalModifierTriggered(zoom, 'zoom');
|
||||
}
|
||||
let [min_x, min_y, max_x, max_y] = this.vue.getSelectedUVBoundingBox();
|
||||
if (zoom) {
|
||||
let width = (max_x-min_x) / UVEditor.getUVWidth();
|
||||
let height = (max_y-min_y) / UVEditor.getUVHeight();
|
||||
let target_zoom_factor = 1/Math.max(width, height);
|
||||
let target_zoom = Math.clamp(UVEditor.zoom, target_zoom_factor * 0.618, Math.max(1, target_zoom_factor * 0.84));
|
||||
UVEditor.setZoom(target_zoom);
|
||||
await new Promise(Vue.nextTick);
|
||||
}
|
||||
|
||||
let pixel_size = UVEditor.inner_width / UVEditor.vue.uv_resolution[0];
|
||||
let focus = [min_x+max_x, min_y+max_y].map(v => v * 0.5 * pixel_size);
|
||||
let {viewport} = UVEditor.vue.$refs;
|
||||
@ -299,7 +279,7 @@ const UVEditor = {
|
||||
scrollLeft: focus[0] + margin[0] - UVEditor.width / 2,
|
||||
scrollTop: focus[1] + margin[1] - UVEditor.height / 2,
|
||||
}, {
|
||||
duration: 100,
|
||||
duration: zoom ? 0 : 100,
|
||||
complete: () => {
|
||||
UVEditor.updateUVNavigator();
|
||||
}
|
||||
@ -4132,8 +4112,8 @@ Interface.definePanels(function() {
|
||||
height: this.toPixels(box[3] - box[1], 0),
|
||||
};
|
||||
},
|
||||
focusOnSelection() {
|
||||
UVEditor.focusOnSelection();
|
||||
focusOnSelection(event) {
|
||||
UVEditor.focusOnSelection(event);
|
||||
},
|
||||
showTransparentFaceText() {
|
||||
return UVEditor.getSelectedFaces(this.mappable_elements[0]).length;
|
||||
@ -4540,7 +4520,7 @@ Interface.definePanels(function() {
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="uv_navigator" @click="focusOnSelection()" v-show="mode == 'uv'">
|
||||
<div class="uv_navigator" @click="focusOnSelection($event)" v-show="mode == 'uv'">
|
||||
<i class="material-icons icon">navigation</i>
|
||||
</div>
|
||||
|
||||
|
@ -1756,6 +1756,7 @@
|
||||
"action.focus_on_selection": "Center View on Selection",
|
||||
"action.focus_on_selection.desc": "Align the camera to face the center of the current selection",
|
||||
"action.focus_on_selection.rotate_only": "Rotate only",
|
||||
"action.focus_on_selection.zoom": "Zoom to fit",
|
||||
|
||||
"action.edit_reference_images": "Edit Reference Images",
|
||||
"action.edit_reference_images.desc": "Turn on reference image mode to add or edit reference images and blueprints",
|
||||
|
Loading…
x
Reference in New Issue
Block a user