mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-04-06 17:31:09 +08:00
Convert last dialogs from legacy system
Convert Transform > Scale dialog to new system Convert extrude image dialog
This commit is contained in:
parent
b255db0192
commit
d35653db8b
@ -197,7 +197,7 @@
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
padding-top: 4px;
|
||||
padding-left: 6px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.tab_bar {
|
||||
height: 30px;
|
||||
@ -331,7 +331,7 @@
|
||||
}
|
||||
dialog .dialog_content,
|
||||
dialog .dialog_bar.button_bar {
|
||||
margin: 24px;
|
||||
margin: 16px 24px;
|
||||
}
|
||||
@media (max-device-width: 640px) {
|
||||
dialog {
|
||||
@ -952,25 +952,11 @@
|
||||
color: var(--color-accent);
|
||||
}
|
||||
/*Scale*/
|
||||
#model_scale_range {
|
||||
width: calc(100% - 50px);
|
||||
float: left;
|
||||
height: 31px;
|
||||
padding-top: 3px;
|
||||
dialog#scale .form_bar_overflow_info {
|
||||
color: #ff5767;
|
||||
}
|
||||
#model_scale_label {
|
||||
width: 50px;
|
||||
padding-top: 3px;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
#scaling_clipping_warning {
|
||||
color: #ff384b;
|
||||
}
|
||||
.borderless {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
dialog#scale .toggle_panel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*Extrusion*/
|
||||
|
@ -708,14 +708,18 @@
|
||||
width: 56px;
|
||||
padding: 4px;
|
||||
display: inline-block;
|
||||
background-color: var(--color-back);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
flex-grow: 1;
|
||||
margin: 2px;
|
||||
}
|
||||
label.toggle_panel:hover {
|
||||
color: var(--color-light);
|
||||
}
|
||||
input:checked + label.toggle_panel {
|
||||
background-color: var(--color-button);
|
||||
}
|
||||
input:checked + label.toggle_panel:hover {
|
||||
background-color: var(--color-selected);
|
||||
}
|
||||
.y_scrollable {
|
||||
|
87
index.html
87
index.html
@ -130,6 +130,7 @@
|
||||
<script src="js/preview/canvas.js"></script>
|
||||
<script src="js/modeling/transform_gizmo.js"></script>
|
||||
<script src="js/modeling/transform.js"></script>
|
||||
<script src="js/modeling/scale.js"></script>
|
||||
<script src="js/modeling/mesh_editing.js"></script>
|
||||
<script src="js/texturing/textures.js"></script>
|
||||
<script src="js/texturing/uv.js"></script>
|
||||
@ -182,92 +183,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dialog class="dialog draggable" id="image_extruder">
|
||||
<div class="dialog_handle">
|
||||
<div class="dialog_title tl">dialog.extrude.title</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog_content">
|
||||
<div class="dialog_bar">
|
||||
<label class="tl">dialog.extrude.mode</label>
|
||||
<div class="bar_select f_left">
|
||||
<select id="scan_mode" name="scan_mode">
|
||||
<option class="tl" id="areas" selected>dialog.extrude.mode.areas</option>
|
||||
<option class="tl" id="lines">dialog.extrude.mode.lines</option>
|
||||
<option class="tl" id="columns">dialog.extrude.mode.columns</option>
|
||||
<option class="tl" id="pixels">dialog.extrude.mode.pixels</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar">
|
||||
<label class="tl">dialog.extrude.opacity</label>
|
||||
<input class="tool" type="range" id="scan_tolerance" value="255" min="1" max="255">
|
||||
<label id="scan_tolerance_label">255</label>
|
||||
</div>
|
||||
|
||||
<canvas height="256" width="256" id="extrusion_canvas"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar button_bar">
|
||||
<button type="button" class="confirm_btn tl" onclick="Extruder.startConversion()">Scan and Import</button>
|
||||
<button type="button" class="cancel_btn tl" onclick="hideDialog()">dialog.cancel</button>
|
||||
</div>
|
||||
<div class="dialog_close_button" onclick="hideDialog()"><i class="material-icons">clear</i></div>
|
||||
</dialog>
|
||||
|
||||
<dialog class="dialog draggable" id="scaling">
|
||||
<div class="dialog_handle">
|
||||
<div class="dialog_title tl">dialog.scale.title</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog_content">
|
||||
<label class="tl">dialog.scale.axis</label>
|
||||
|
||||
<div class="dialog_bar" style="height: 32px;">
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_x_axis" onchange="scaleAll()" checked>
|
||||
<label class="toggle_panel" for="model_scale_x_axis">X</label>
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_y_axis" onchange="scaleAll()" checked>
|
||||
<label class="toggle_panel" for="model_scale_y_axis">Y</label>
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_z_axis" onchange="scaleAll()" checked>
|
||||
<label class="toggle_panel" for="model_scale_z_axis">Z</label>
|
||||
</div>
|
||||
|
||||
<label class="tl">data.origin</label>
|
||||
<div class="dialog_bar">
|
||||
<label for="scaling_origin_x" class="inline_label tl">X</label>
|
||||
<input type="number" id="scaling_origin_x" class="dark_bordered medium_width" oninput="scaleAll()">
|
||||
<label for="scaling_origin_y" class="inline_label tl">Y</label>
|
||||
<input type="number" id="scaling_origin_y" class="dark_bordered medium_width" oninput="scaleAll()">
|
||||
<label for="scaling_origin_z" class="inline_label tl">Z</label>
|
||||
<input type="number" id="scaling_origin_z" class="dark_bordered medium_width" oninput="scaleAll()">
|
||||
<div class="tool" style="float: none" onclick="setScaleAllPivot('origin')">
|
||||
<div class="tooltip tl">dialog.scale.element_pivot</div>
|
||||
<i class="material-icons">center_focus_strong</i>
|
||||
</div>
|
||||
<div class="tool" style="float: none" onclick="setScaleAllPivot('selection')">
|
||||
<div class="tooltip tl">dialog.scale.selection_center</div>
|
||||
<i class="material-icons">filter_tilt_shift</i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label class="tl">dialog.scale.scale</label>
|
||||
<div class="dialog_bar" style="height: 32px;">
|
||||
<input type="range" id="model_scale_range" value="1" min="0" max="4" step="0.02" oninput="modelScaleSync()">
|
||||
<input type="number" class="f_left dark_bordered" id="model_scale_label" min="0" max="4" step="0.02" value="1" oninput="modelScaleSync(true)">
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar narrow" id="scaling_clipping_warning"></div>
|
||||
</div>
|
||||
|
||||
<div class="dialog_bar button_bar">
|
||||
<button type="button" onclick="scaleAll(true)" class="confirm_btn tl">dialog.scale.confirm</button>
|
||||
<button type="button" class="cancel_btn tl" onclick="cancelScaleAll()">dialog.cancel</button>
|
||||
<button type="button" class="minor hidden tl" id="scale_overflow_btn" onclick="scaleAllSelectOverflow()">dialog.scale.select_overflow</button>
|
||||
</div>
|
||||
<div class="dialog_close_button" onclick="cancelScaleAll()"><i class="material-icons">clear</i></div>
|
||||
</dialog>
|
||||
|
||||
<div id="dialog_wrapper"></div>
|
||||
|
||||
<header>
|
||||
|
@ -151,15 +151,36 @@ function buildForm(dialog) {
|
||||
input_element = $(`<input class="half focusable_input" type="range" id="${form_id}"
|
||||
value="${parseFloat(data.value)||0}" min="${data.min}" max="${data.max}" step="${data.step||1}">`)
|
||||
bar.append(input_element)
|
||||
let display = Interface.createElement('span', {class: 'range_input_label'}, (data.value||0).toString())
|
||||
bar.append(display);
|
||||
input_element.on('input', () => {
|
||||
let result = dialog.getFormResult();
|
||||
display.textContent = trimFloatNumber(result[form_id]);
|
||||
})
|
||||
input_element.on('change', () => {
|
||||
dialog.updateFormValues();
|
||||
})
|
||||
|
||||
if (!data.editable_range_label) {
|
||||
let display = Interface.createElement('span', {class: 'range_input_label'}, (data.value||0).toString())
|
||||
bar.append(display);
|
||||
input_element.on('input', () => {
|
||||
let result = dialog.getFormResult();
|
||||
display.textContent = trimFloatNumber(result[form_id]);
|
||||
})
|
||||
} else {
|
||||
let display = Interface.createElement('input', {
|
||||
class: 'range_input_label dark_bordered focusable_input',
|
||||
type: 'number',
|
||||
value: data.value,
|
||||
min: data.min,
|
||||
max: data.max,
|
||||
step: data.step || 1,
|
||||
});
|
||||
bar.append(display);
|
||||
input_element.on('input', () => {
|
||||
let result = dialog.getFormResult();
|
||||
display.value = result[form_id];
|
||||
})
|
||||
display.addEventListener('input', (e) => {
|
||||
input_element.val(parseFloat(display.value));
|
||||
dialog.updateFormValues();
|
||||
})
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@ -924,43 +945,9 @@ window.MessageBox = class MessageBox extends Dialog {
|
||||
|
||||
})()
|
||||
|
||||
|
||||
// Legacy Dialogs
|
||||
function legacyShowDialog(dialog) { // todo: remove
|
||||
var obj = $('.dialog#'+dialog)
|
||||
$('.dialog').hide()
|
||||
if (open_menu) {
|
||||
open_menu.hide()
|
||||
}
|
||||
$('#blackout').show()
|
||||
obj.show()
|
||||
open_dialog = dialog
|
||||
open_interface = {
|
||||
confirm() {
|
||||
$('dialog#'+open_dialog).find('.confirm_btn:not([disabled])').trigger('click');
|
||||
},
|
||||
cancel() {
|
||||
$('dialog#'+open_dialog).find('.cancel_btn:not([disabled])').trigger('click');
|
||||
}
|
||||
}
|
||||
Prop.active_panel = 'dialog'
|
||||
//Draggable
|
||||
if (obj.hasClass('draggable')) {
|
||||
obj.draggable({
|
||||
handle: ".dialog_handle",
|
||||
containment: '#page_wrapper'
|
||||
})
|
||||
var x = (window.innerWidth-obj.outerWidth()) / 2;
|
||||
obj.css('left', x+'px')
|
||||
obj.css('max-height', (window.innerHeight-128)+'px')
|
||||
}
|
||||
}
|
||||
function legacyHideDialog() { // todo: remove
|
||||
$('#blackout').hide()
|
||||
$('.dialog').hide()
|
||||
open_dialog = false;
|
||||
open_interface = false;
|
||||
Prop.active_panel = undefined
|
||||
// Legacy Dialog
|
||||
function showDialog() {
|
||||
console.warn('"showDialog" is no longer supported!')
|
||||
}
|
||||
function hideDialog() {
|
||||
console.warn('"hideDialog" is no longer supported!')
|
||||
|
61
js/io/io.js
61
js/io/io.js
@ -143,7 +143,7 @@ async function loadImages(files, event) {
|
||||
})
|
||||
|
||||
} else if (method == 'extrude_with_cubes') {
|
||||
legacyShowDialog('image_extruder');
|
||||
Extruder.dialog.show();
|
||||
Extruder.drawImage(files[0]);
|
||||
}
|
||||
}
|
||||
@ -169,17 +169,41 @@ async function loadImages(files, event) {
|
||||
}
|
||||
|
||||
//Extruder
|
||||
var Extruder = {
|
||||
drawImage: function(file) {
|
||||
const Extruder = {
|
||||
dialog: new Dialog({
|
||||
id: 'image_extruder',
|
||||
title: 'dialog.extrude.title',
|
||||
buttons: ['dialog.confirm', 'dialog.cancel'],
|
||||
part_order: ['form', 'lines'],
|
||||
form: {
|
||||
mode: {
|
||||
label: 'dialog.extrude.mode',
|
||||
type: 'select',
|
||||
options: {
|
||||
areas: 'dialog.extrude.mode.areas',
|
||||
lines: 'dialog.extrude.mode.lines',
|
||||
columns: 'dialog.extrude.mode.columns',
|
||||
pixels: 'dialog.extrude.mode.pixels'
|
||||
}
|
||||
},
|
||||
scan_tolerance: {
|
||||
label: 'dialog.extrude.opacity',
|
||||
type: 'range',
|
||||
min: 1, max: 255, value: 255, step: 1,
|
||||
editable_range_label: true
|
||||
}
|
||||
},
|
||||
lines: [
|
||||
`<canvas height="256" width="256" id="extrusion_canvas"></canvas>`
|
||||
],
|
||||
onConfirm(formResult) {
|
||||
Extruder.startConversion(formResult);
|
||||
}
|
||||
}),
|
||||
drawImage(file) {
|
||||
Extruder.canvas = $('#extrusion_canvas').get(0)
|
||||
var ctx = Extruder.canvas.getContext('2d')
|
||||
|
||||
setProgressBar('extrusion_bar', 0)
|
||||
$('#scan_tolerance').on('input', function() {
|
||||
$('#scan_tolerance_label').text($(this).val())
|
||||
})
|
||||
legacyShowDialog('image_extruder')
|
||||
|
||||
Extruder.ext_img = new Image()
|
||||
Extruder.ext_img.src = isApp ? file.path.replace(/#/g, '%23') : file.content
|
||||
Extruder.image_file = file
|
||||
@ -216,12 +240,9 @@ var Extruder = {
|
||||
|
||||
//Grid
|
||||
},
|
||||
startConversion: function() {
|
||||
var scan_mode = $('select#scan_mode option:selected').attr('id') /*areas, lines, columns, pixels*/
|
||||
var isNewProject = elements.length === 0;
|
||||
|
||||
var pixel_opacity_tolerance = parseInt($('#scan_tolerance').val())
|
||||
|
||||
startConversion(formResult) {
|
||||
var scan_mode = formResult.mode;
|
||||
var pixel_opacity_tolerance = Math.round(formResult.scan_tolerance);
|
||||
|
||||
//Undo
|
||||
Undo.initEdit({elements: selected, outliner: true, textures: []})
|
||||
@ -364,8 +385,6 @@ var Extruder = {
|
||||
})
|
||||
|
||||
Undo.finishEdit('Add extruded texture', {elements: selected, outliner: true, textures: [Texture.all[Texture.all.length-1]]})
|
||||
|
||||
legacyHideDialog()
|
||||
}
|
||||
}
|
||||
//Export
|
||||
@ -670,16 +689,16 @@ BARS.defineActions(function() {
|
||||
icon: 'eject',
|
||||
category: 'file',
|
||||
condition: _ => (Project && (!Project.box_uv || Format.optional_box_uv)),
|
||||
click: function () {
|
||||
click() {
|
||||
Blockbench.import({
|
||||
resource_id: 'texture',
|
||||
extensions: ['png'],
|
||||
type: 'PNG Texture',
|
||||
readtype: 'image'
|
||||
}, function(files) {
|
||||
}, (files) => {
|
||||
if (files.length) {
|
||||
legacyShowDialog('image_extruder')
|
||||
Extruder.drawImage(files[0])
|
||||
Extruder.dialog.show();
|
||||
Extruder.drawImage(files[0]);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
258
js/modeling/scale.js
Normal file
258
js/modeling/scale.js
Normal file
@ -0,0 +1,258 @@
|
||||
const ModelScaler = {
|
||||
dialog: new Dialog({
|
||||
id: 'scale',
|
||||
title: 'dialog.scale.title',
|
||||
darken: false,
|
||||
buttons: ['dialog.scale.confirm', 'dialog.cancel'],
|
||||
lines: [
|
||||
`<div class="dialog_bar form_bar" style="height: 32px;">
|
||||
<label class="name_space_left" for="origin">${tl('dialog.scale.axis')}:</label>
|
||||
<div class="dialog_vector_group half">
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_x_axis" checked>
|
||||
<label class="toggle_panel" for="model_scale_x_axis" style="color: var(--color-axis-x)">X</label>
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_y_axis" checked>
|
||||
<label class="toggle_panel" for="model_scale_y_axis" style="color: var(--color-axis-y)">Y</label>
|
||||
<input type="checkbox" class="toggle_panel" id="model_scale_z_axis" checked>
|
||||
<label class="toggle_panel" for="model_scale_z_axis" style="color: var(--color-axis-z)">Z</label>
|
||||
</div>
|
||||
</div>`
|
||||
],
|
||||
form: {
|
||||
origin: {label: 'data.origin', type: 'vector', dimensions: 3, value: [0, 0, 0]},
|
||||
pivot_options: {label: ' ', nocolon: true, type: 'buttons', buttons: ['dialog.scale.element_pivot', 'dialog.scale.selection_center'], click(index) {
|
||||
ModelScaler.setPivot(['pivot', 'selection'][index]);
|
||||
}},
|
||||
scale: {label: '', type: 'range', min: 0, max: 4, step: 0.01, value: 1, full_width: true, editable_range_label: true},
|
||||
overflow_info: {
|
||||
condition: () => ModelScaler.overflow,
|
||||
type: 'info',
|
||||
text: 'dialog.scale.clipping'
|
||||
},
|
||||
select_overflow: {
|
||||
condition: () => ModelScaler.overflow,
|
||||
type: 'buttons',
|
||||
buttons: ['dialog.scale.select_overflow'],
|
||||
click() {
|
||||
ModelScaler.selectOverflow();
|
||||
}
|
||||
}
|
||||
},
|
||||
onFormChange() {
|
||||
ModelScaler.scaleAll();
|
||||
},
|
||||
onBuild() {
|
||||
this.object.querySelector('#model_scale_x_axis').addEventListener('change', e => {ModelScaler.scaleAll()});
|
||||
this.object.querySelector('#model_scale_y_axis').addEventListener('change', e => {ModelScaler.scaleAll()});
|
||||
this.object.querySelector('#model_scale_z_axis').addEventListener('change', e => {ModelScaler.scaleAll()});
|
||||
},
|
||||
onOpen() {
|
||||
setTimeout(() => {
|
||||
this.object.style.top = Interface.page_wrapper.offsetTop+'px';
|
||||
}, 0);
|
||||
},
|
||||
onConfirm() {
|
||||
ModelScaler.scaleAll(true);
|
||||
},
|
||||
onCancel() {
|
||||
ModelScaler.cancel();
|
||||
}
|
||||
}),
|
||||
overflow: null,
|
||||
getScaleGroups() {
|
||||
let groups = [];
|
||||
if (!Format.bone_rig) return groups;
|
||||
if (Group.selected) {
|
||||
Group.selected.forEachChild((g) => {
|
||||
groups.push(g);
|
||||
}, Group)
|
||||
} else if (Outliner.selected.length == Outliner.elements.length && Group.all.length) {
|
||||
groups = Group.all;
|
||||
}
|
||||
return groups;
|
||||
},
|
||||
scaleAll(save, size) {
|
||||
let data = ModelScaler.dialog.getFormResult();
|
||||
if (save === true) {
|
||||
ModelScaler.dialog.hide();
|
||||
}
|
||||
if (size === undefined) size = data.scale;
|
||||
let {origin} = data;
|
||||
let axis_enabled = ['x', 'y', 'z'].map(axis => document.getElementById(`model_scale_${axis}_axis`).checked);
|
||||
let overflow = [];
|
||||
|
||||
Outliner.selected.forEach(function(obj) {
|
||||
obj.autouv = 0;
|
||||
origin.forEach(function(ogn, i) {
|
||||
if (axis_enabled[i]) {
|
||||
|
||||
if (obj.from) {
|
||||
obj.from[i] = (obj.before.from[i] - obj.inflate - ogn) * size;
|
||||
obj.from[i] = obj.from[i] + obj.inflate + ogn;
|
||||
}
|
||||
|
||||
if (obj.to) {
|
||||
obj.to[i] = (obj.before.to[i] + obj.inflate - ogn) * size;
|
||||
obj.to[i] = obj.to[i] - obj.inflate + ogn;
|
||||
if (Format.integer_size) {
|
||||
obj.to[i] = obj.from[i] + Math.round(obj.to[i] - obj.from[i])
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.origin) {
|
||||
obj.origin[i] = (obj.before.origin[i] - ogn) * size;
|
||||
obj.origin[i] = obj.origin[i] + ogn;
|
||||
}
|
||||
|
||||
if (obj instanceof Mesh) {
|
||||
for (let key in obj.vertices) {
|
||||
obj.vertices[key][i] = obj.before.vertices[key][i] * size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (obj.from) obj.from[i] = obj.before.from[i];
|
||||
if (obj.to) obj.to[i] = obj.before.to[i];
|
||||
|
||||
if (obj.origin) obj.origin[i] = obj.before.origin[i];
|
||||
|
||||
if (obj instanceof Mesh) {
|
||||
for (let key in obj.vertices) {
|
||||
obj.vertices[key][i] = obj.before.vertices[key][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (obj instanceof Cube && Format.cube_size_limiter) {
|
||||
if (Format.cube_size_limiter.test(obj)) {
|
||||
overflow.push(obj);
|
||||
}
|
||||
if (!settings.deactivate_size_limit.value) {
|
||||
Format.cube_size_limiter.clamp(obj);
|
||||
}
|
||||
}
|
||||
if (save === true) {
|
||||
delete obj.before
|
||||
}
|
||||
if (obj instanceof Cube && obj.box_uv) {
|
||||
Canvas.updateUV(obj)
|
||||
}
|
||||
})
|
||||
ModelScaler.getScaleGroups().forEach((g) => {
|
||||
g.origin[0] = g.old_origin[0] * size
|
||||
g.origin[1] = g.old_origin[1] * size
|
||||
g.origin[2] = g.old_origin[2] * size
|
||||
if (save === true) {
|
||||
delete g.old_origin
|
||||
}
|
||||
}, Group)
|
||||
if (overflow.length && Format.cube_size_limiter && !settings.deactivate_size_limit.value) {
|
||||
ModelScaler.overflow = overflow;
|
||||
} else {
|
||||
ModelScaler.overflow = null;
|
||||
}
|
||||
Canvas.updateView({
|
||||
elements: Outliner.selected,
|
||||
element_aspects: {geometry: true, transform: true},
|
||||
groups: ModelScaler.getScaleGroups(),
|
||||
group_aspects: {transform: true},
|
||||
})
|
||||
if (save === true) {
|
||||
Undo.finishEdit('Scale model')
|
||||
}
|
||||
},
|
||||
cancel() {
|
||||
Outliner.selected.forEach(function(obj) {
|
||||
if (obj === undefined) return;
|
||||
if (obj.from) obj.from.V3_set(obj.before.from);
|
||||
if (obj.to) obj.to.V3_set(obj.before.to);
|
||||
if (obj.origin) obj.origin.V3_set(obj.before.origin);
|
||||
if (obj instanceof Mesh) {
|
||||
for (let key in obj.vertices) {
|
||||
obj.vertices[key].V3_set(obj.before.vertices[key]);
|
||||
}
|
||||
}
|
||||
delete obj.before
|
||||
if (obj instanceof Cube && obj.box_uv) {
|
||||
Canvas.updateUV(obj)
|
||||
}
|
||||
})
|
||||
ModelScaler.getScaleGroups().forEach((g) => {
|
||||
g.origin[0] = g.old_origin[0]
|
||||
g.origin[1] = g.old_origin[1]
|
||||
g.origin[2] = g.old_origin[2]
|
||||
delete g.old_origin
|
||||
}, Group)
|
||||
Canvas.updateView({
|
||||
elements: Outliner.selected,
|
||||
element_aspects: {geometry: true, transform: true},
|
||||
groups: ModelScaler.getScaleGroups(),
|
||||
group_aspects: {transform: true},
|
||||
})
|
||||
},
|
||||
setPivot(mode) {
|
||||
let center;
|
||||
if (mode === 'selection') {
|
||||
center = getSelectionCenter()
|
||||
} else {
|
||||
center = Cube.selected[0]?.origin || Mesh.selected[0]?.origin;
|
||||
}
|
||||
if (center) {
|
||||
ModelScaler.dialog.setFormValues({origin: center});
|
||||
}
|
||||
},
|
||||
selectOverflow() {
|
||||
ModelScaler.cancel()
|
||||
ModelScaler.dialog.hide();
|
||||
|
||||
Outliner.selected.empty();
|
||||
ModelScaler.overflow.forEach(obj => {
|
||||
obj.selectLow()
|
||||
})
|
||||
updateSelection();
|
||||
},
|
||||
}
|
||||
|
||||
BARS.defineActions(function() {
|
||||
new Action('scale', {
|
||||
icon: 'settings_overscan',
|
||||
category: 'transform',
|
||||
condition: () => (Modes.edit && Outliner.elements.length),
|
||||
click() {
|
||||
if (Outliner.selected.length == 0) {
|
||||
Prop.active_panel = 'preview';
|
||||
selectAll();
|
||||
}
|
||||
|
||||
Undo.initEdit({elements: Outliner.selected, outliner: Format.bone_rig});
|
||||
|
||||
Outliner.selected.forEach((obj) => {
|
||||
obj.before = {
|
||||
from: obj.from ? obj.from.slice() : undefined,
|
||||
to: obj.to ? obj.to.slice() : undefined,
|
||||
origin: obj.origin ? obj.origin.slice() : undefined
|
||||
}
|
||||
if (obj instanceof Mesh) {
|
||||
obj.before.vertices = {};
|
||||
for (let key in obj.vertices) {
|
||||
obj.before.vertices[key] = obj.vertices[key].slice();
|
||||
}
|
||||
}
|
||||
})
|
||||
ModelScaler.getScaleGroups().forEach((g) => {
|
||||
g.old_origin = g.origin.slice();
|
||||
}, Group, true)
|
||||
|
||||
ModelScaler.dialog.show();
|
||||
|
||||
ModelScaler.overflow = null;
|
||||
let v = Format.centered_grid ? 0 : 8;
|
||||
let origin = Group.selected ? Group.selected.origin : [v, 0, v];
|
||||
ModelScaler.dialog.setFormValues({
|
||||
origin,
|
||||
scale: 1
|
||||
});
|
||||
|
||||
ModelScaler.scaleAll(false, 1);
|
||||
}
|
||||
})
|
||||
})
|
@ -483,180 +483,7 @@ const Vertexsnap = {
|
||||
Vertexsnap.step1 = true;
|
||||
}
|
||||
}
|
||||
//Scale
|
||||
function getScaleAllGroups() {
|
||||
let groups = [];
|
||||
if (!Format.bone_rig) return groups;
|
||||
if (Group.selected) {
|
||||
Group.selected.forEachChild((g) => {
|
||||
groups.push(g);
|
||||
}, Group)
|
||||
} else if (Outliner.selected.length == Outliner.elements.length && Group.all.length) {
|
||||
groups = Group.all;
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
function scaleAll(save, size) {
|
||||
if (save === true) {
|
||||
legacyHideDialog()
|
||||
}
|
||||
if (size === undefined) {
|
||||
size = $('#model_scale_label').val()
|
||||
}
|
||||
let origin = [
|
||||
parseFloat($('#scaling_origin_x').val())||0,
|
||||
parseFloat($('#scaling_origin_y').val())||0,
|
||||
parseFloat($('#scaling_origin_z').val())||0,
|
||||
]
|
||||
let axis_enabled = [
|
||||
$('#model_scale_x_axis').is(':checked'),
|
||||
$('#model_scale_y_axis').is(':checked'),
|
||||
$('#model_scale_z_axis').is(':checked'),
|
||||
];
|
||||
let overflow = [];
|
||||
Outliner.selected.forEach(function(obj) {
|
||||
obj.autouv = 0;
|
||||
origin.forEach(function(ogn, i) {
|
||||
if (axis_enabled[i]) {
|
||||
|
||||
if (obj.from) {
|
||||
obj.from[i] = (obj.before.from[i] - obj.inflate - ogn) * size;
|
||||
obj.from[i] = obj.from[i] + obj.inflate + ogn;
|
||||
}
|
||||
|
||||
if (obj.to) {
|
||||
obj.to[i] = (obj.before.to[i] + obj.inflate - ogn) * size;
|
||||
obj.to[i] = obj.to[i] - obj.inflate + ogn;
|
||||
if (Format.integer_size) {
|
||||
obj.to[i] = obj.from[i] + Math.round(obj.to[i] - obj.from[i])
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.origin) {
|
||||
obj.origin[i] = (obj.before.origin[i] - ogn) * size;
|
||||
obj.origin[i] = obj.origin[i] + ogn;
|
||||
}
|
||||
|
||||
if (obj instanceof Mesh) {
|
||||
for (let key in obj.vertices) {
|
||||
obj.vertices[key][i] = obj.before.vertices[key][i] * size;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (obj.from) obj.from[i] = obj.before.from[i];
|
||||
if (obj.to) obj.to[i] = obj.before.to[i];
|
||||
|
||||
if (obj.origin) obj.origin[i] = obj.before.origin[i];
|
||||
|
||||
if (obj instanceof Mesh) {
|
||||
for (let key in obj.vertices) {
|
||||
obj.vertices[key][i] = obj.before.vertices[key][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (obj instanceof Cube && Format.cube_size_limiter) {
|
||||
if (Format.cube_size_limiter.test(obj)) {
|
||||
overflow.push(obj);
|
||||
}
|
||||
if (!settings.deactivate_size_limit.value) {
|
||||
Format.cube_size_limiter.clamp(obj);
|
||||
}
|
||||
}
|
||||
if (save === true) {
|
||||
delete obj.before
|
||||
}
|
||||
if (obj instanceof Cube && obj.box_uv) {
|
||||
Canvas.updateUV(obj)
|
||||
}
|
||||
})
|
||||
getScaleAllGroups().forEach((g) => {
|
||||
g.origin[0] = g.old_origin[0] * size
|
||||
g.origin[1] = g.old_origin[1] * size
|
||||
g.origin[2] = g.old_origin[2] * size
|
||||
if (save === true) {
|
||||
delete g.old_origin
|
||||
}
|
||||
}, Group)
|
||||
if (overflow.length && Format.cube_size_limiter && !settings.deactivate_size_limit.value) {
|
||||
scaleAll.overflow = overflow;
|
||||
$('#scaling_clipping_warning').text('Model clipping: Your model is too large for the canvas')
|
||||
$('#scale_overflow_btn').css('display', 'inline-block')
|
||||
} else {
|
||||
$('#scaling_clipping_warning').text('')
|
||||
$('#scale_overflow_btn').hide()
|
||||
}
|
||||
Canvas.updateView({
|
||||
elements: Outliner.selected,
|
||||
element_aspects: {geometry: true, transform: true},
|
||||
groups: getScaleAllGroups(),
|
||||
group_aspects: {transform: true},
|
||||
})
|
||||
if (save === true) {
|
||||
Undo.finishEdit('Scale model')
|
||||
}
|
||||
}
|
||||
function modelScaleSync(label) {
|
||||
if (label) {
|
||||
var size = $('#model_scale_label').val()
|
||||
$('#model_scale_range').val(size)
|
||||
} else {
|
||||
var size = $('#model_scale_range').val()
|
||||
$('#model_scale_label').val(size)
|
||||
}
|
||||
scaleAll(false, size)
|
||||
}
|
||||
function cancelScaleAll() {
|
||||
Outliner.selected.forEach(function(obj) {
|
||||
if (obj === undefined) return;
|
||||
if (obj.from) obj.from.V3_set(obj.before.from);
|
||||
if (obj.to) obj.to.V3_set(obj.before.to);
|
||||
if (obj.origin) obj.origin.V3_set(obj.before.origin);
|
||||
if (obj instanceof Mesh) {
|
||||
for (let key in obj.vertices) {
|
||||
obj.vertices[key].V3_set(obj.before.vertices[key]);
|
||||
}
|
||||
}
|
||||
delete obj.before
|
||||
if (obj instanceof Cube && obj.box_uv) {
|
||||
Canvas.updateUV(obj)
|
||||
}
|
||||
})
|
||||
getScaleAllGroups().forEach((g) => {
|
||||
g.origin[0] = g.old_origin[0]
|
||||
g.origin[1] = g.old_origin[1]
|
||||
g.origin[2] = g.old_origin[2]
|
||||
delete g.old_origin
|
||||
}, Group)
|
||||
Canvas.updateView({
|
||||
elements: Outliner.selected,
|
||||
element_aspects: {geometry: true, transform: true},
|
||||
groups: getScaleAllGroups(),
|
||||
group_aspects: {transform: true},
|
||||
})
|
||||
legacyHideDialog()
|
||||
}
|
||||
function setScaleAllPivot(mode) {
|
||||
if (mode === 'selection') {
|
||||
var center = getSelectionCenter()
|
||||
} else {
|
||||
var center = Cube.selected[0] && Cube.selected[0].origin;
|
||||
}
|
||||
if (center) {
|
||||
$('input#scaling_origin_x').val(center[0]);
|
||||
$('input#scaling_origin_y').val(center[1]);
|
||||
$('input#scaling_origin_z').val(center[2]);
|
||||
}
|
||||
}
|
||||
function scaleAllSelectOverflow() {
|
||||
cancelScaleAll()
|
||||
selected.empty();
|
||||
scaleAll.overflow.forEach(obj => {
|
||||
obj.selectLow()
|
||||
})
|
||||
updateSelection();
|
||||
}
|
||||
//Center
|
||||
function centerElementsAll(axis) {
|
||||
centerElements(0, false);
|
||||
@ -1561,46 +1388,6 @@ BARS.defineActions(function() {
|
||||
let slider_vector_origin = [BarItems.slider_origin_x, BarItems.slider_origin_y, BarItems.slider_origin_z];
|
||||
slider_vector_origin.forEach(slider => slider.slider_vector = slider_vector_origin);
|
||||
|
||||
new Action('scale', {
|
||||
icon: 'settings_overscan',
|
||||
category: 'transform',
|
||||
condition: () => (Modes.edit && Outliner.elements.length),
|
||||
click() {
|
||||
$('#model_scale_range, #model_scale_label').val(1)
|
||||
$('#scaling_clipping_warning').text('')
|
||||
|
||||
if (Outliner.selected.length == 0) {
|
||||
Prop.active_panel = 'preview';
|
||||
selectAll();
|
||||
}
|
||||
|
||||
Undo.initEdit({elements: Outliner.selected, outliner: Format.bone_rig});
|
||||
|
||||
Outliner.selected.forEach(function(obj) {
|
||||
obj.before = {
|
||||
from: obj.from ? obj.from.slice() : undefined,
|
||||
to: obj.to ? obj.to.slice() : undefined,
|
||||
origin: obj.origin ? obj.origin.slice() : undefined
|
||||
}
|
||||
if (obj instanceof Mesh) {
|
||||
obj.before.vertices = {};
|
||||
for (let key in obj.vertices) {
|
||||
obj.before.vertices[key] = obj.vertices[key].slice();
|
||||
}
|
||||
}
|
||||
})
|
||||
getScaleAllGroups().forEach((g) => {
|
||||
g.old_origin = g.origin.slice();
|
||||
}, Group, true)
|
||||
legacyShowDialog('scaling')
|
||||
var v = Format.centered_grid ? 0 : 8;
|
||||
var origin = Group.selected ? Group.selected.origin : [v, 0, v];
|
||||
$('#scaling_origin_x').val(origin[0])
|
||||
$('#scaling_origin_y').val(origin[1])
|
||||
$('#scaling_origin_z').val(origin[2])
|
||||
scaleAll(false, 1)
|
||||
}
|
||||
})
|
||||
new Action('rotate_x_cw', {
|
||||
name: tl('action.rotate_cw', 'X'),
|
||||
icon: 'rotate_right',
|
||||
|
@ -460,7 +460,6 @@
|
||||
|
||||
"dialog.scale.title": "Scale Model",
|
||||
"dialog.scale.axis": "Axis",
|
||||
"dialog.scale.scale": "Scale",
|
||||
"dialog.scale.element_pivot": "Element Pivot",
|
||||
"dialog.scale.selection_center": "Selection Center",
|
||||
"dialog.scale.clipping": "Model clipping: Your model is too large for the canvas",
|
||||
|
Loading…
x
Reference in New Issue
Block a user