blockbench/js/transform.js

1592 lines
46 KiB
JavaScript
Raw Normal View History

2018-03-29 02:48:11 +08:00
//Actions
function origin2geometry() {
2019-02-04 04:09:35 +08:00
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
Undo.initEdit({group: Group.selected})
2019-02-04 04:09:35 +08:00
2019-07-18 00:02:07 +08:00
if (!Group.selected || Group.selected.children.length === 0) return;
2018-10-18 01:50:25 +08:00
var position = [0, 0, 0]
2019-07-18 00:02:07 +08:00
Group.selected.children.forEach(function(obj) {
2019-02-04 04:09:35 +08:00
if (obj.type === 'cube') {
position[0] += obj.from[0] + obj.size(0)/2
position[1] += obj.from[1] + obj.size(1)/2
position[2] += obj.from[2] + obj.size(2)/2
}
2018-10-18 01:50:25 +08:00
})
position.forEach(function(p, pi) {
2019-07-18 00:02:07 +08:00
position[pi] = p / Group.selected.children.length
2018-10-18 01:50:25 +08:00
})
2020-03-05 03:56:17 +08:00
Group.selected.origin.V3_set(position)
2018-03-29 02:48:11 +08:00
2019-07-18 00:02:07 +08:00
} else if (Cube.selected) {
Undo.initEdit({elements: Cube.selected})
2018-03-29 02:48:11 +08:00
2019-12-23 00:33:55 +08:00
var center = getSelectionCenter();
var original_center = center.slice();
2019-02-04 04:09:35 +08:00
2019-07-18 00:02:07 +08:00
Cube.selected.forEach(cube => {
2019-12-23 00:33:55 +08:00
if (Format.bone_rig && cube.parent instanceof Group) {
var v = new THREE.Vector3().fromArray(original_center);
cube.parent.mesh.worldToLocal(v);
v.x += cube.parent.origin[0];
v.y += cube.parent.origin[1];
v.z += cube.parent.origin[2];
center = v.toArray();
cube.transferOrigin(center)
} else {
cube.transferOrigin(original_center)
}
2019-02-04 04:09:35 +08:00
})
}
Canvas.updateView({
elements: Cube.selected,
element_aspects: {geometry: true},
groups: Group.selected && [Group.selected]
});
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Center pivot')
2019-02-04 04:09:35 +08:00
}
2020-07-16 15:32:59 +08:00
function getSelectionCenter(all = false) {
if (Group.selected && selected.length == 0 && !all) {
let vec = THREE.fastWorldPosition(Group.selected.mesh, new THREE.Vector3());
return vec.toArray();
}
2019-02-04 04:09:35 +08:00
var center = [0, 0, 0]
var i = 0;
2020-07-16 15:32:59 +08:00
let items = (selected.length == 0 || all) ? elements : selected;
items.forEach(obj => {
2020-03-11 05:19:17 +08:00
if (obj.getWorldCenter) {
2019-09-04 15:37:38 +08:00
var pos = obj.getWorldCenter();
center[0] += pos.x
center[1] += pos.y
center[2] += pos.z
2018-04-15 22:06:43 +08:00
}
2019-02-04 04:09:35 +08:00
})
2020-07-16 15:32:59 +08:00
if (items.length) {
for (var i = 0; i < 3; i++) {
center[i] = center[i] / items.length
}
2018-03-29 02:48:11 +08:00
}
2019-12-16 03:04:31 +08:00
if (!Format.centered_grid) {
2020-07-16 15:32:59 +08:00
center.V3_add(8, 8, 8)
2019-07-18 00:02:07 +08:00
}
2019-02-04 04:09:35 +08:00
return center;
2018-03-29 02:48:11 +08:00
}
2019-08-01 06:01:47 +08:00
function limitToBox(val, inflate) {
if (typeof inflate != 'number') inflate = 0;
2019-12-16 03:04:31 +08:00
if (!(Format.canvas_limit && !settings.deactivate_size_limit.value)) {
2018-10-18 01:50:25 +08:00
return val;
2019-08-01 06:01:47 +08:00
} else if (val + inflate > 32) {
return 32 - inflate;
} else if (val - inflate < -16) {
return -16 + inflate;
2018-10-18 01:50:25 +08:00
} else {
return val;
}
2018-03-29 02:48:11 +08:00
}
//Movement
2018-10-24 03:49:04 +08:00
function moveCubesRelative(difference, index, event) { //Multiple
2019-07-18 00:02:07 +08:00
if (!quad_previews.current || !Cube.selected.length) {
2018-10-24 03:49:04 +08:00
return;
}
2019-12-16 03:04:31 +08:00
var _has_groups = Format.bone_rig && Group.selected && Group.selected.matchesSelection() && Toolbox.selected.transformerMode == 'translate';
Undo.initEdit({elements: Cube.selected, outliner: _has_groups})
2020-10-05 05:44:06 +08:00
var axes = []
// < >
// PageUpDown
// ^ v
var facing = quad_previews.current.getFacingDirection()
var height = quad_previews.current.getFacingHeight()
switch (facing) {
case 'north': axes = [0, 2, 1]; break;
case 'south': axes = [0, 2, 1]; break;
case 'west': axes = [2, 0, 1]; break;
case 'east': axes = [2, 0, 1]; break;
}
2018-10-24 03:49:04 +08:00
2020-10-05 05:44:06 +08:00
if (height !== 'middle') {
if (index === 1) {
index = 2
} else if (index === 2) {
index = 1
}
}
if (facing === 'south' && (index === 0 || index === 1)) difference *= -1
if (facing === 'west' && index === 0) difference *= -1
if (facing === 'east' && index === 1) difference *= -1
if (index === 2 && height !== 'down') difference *= -1
if (index === 1 && height === 'up') difference *= -1
2018-10-24 03:49:04 +08:00
2020-10-05 05:44:06 +08:00
if (event) {
difference *= canvasGridSize(event.shiftKey || Pressing.overrides.shift, event.ctrlOrCmd || Pressing.overrides.ctrl);
2020-10-05 05:44:06 +08:00
}
2019-12-16 03:04:31 +08:00
2020-12-31 22:08:35 +08:00
moveElementsInSpace(difference, axes[index]);
updateSelection();
2019-12-16 03:04:31 +08:00
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Move elements')
2018-10-24 03:49:04 +08:00
}
2018-03-29 02:48:11 +08:00
//Rotate
2018-10-18 01:50:25 +08:00
function rotateSelected(axis, steps) {
2019-07-18 00:02:07 +08:00
if (!Cube.selected.length) return;
Undo.initEdit({elements: Cube.selected});
2018-10-18 01:50:25 +08:00
if (!steps) steps = 1
var origin = [8, 8, 8]
2019-07-18 00:02:07 +08:00
if (Group.selected && Format.bone_rig) {
origin = Group.selected.origin.slice()
2019-12-16 03:04:31 +08:00
} else if (Format.centered_grid) {
2018-10-18 01:50:25 +08:00
origin = [0, 0, 0]
} else {
2019-07-18 00:02:07 +08:00
origin = Cube.selected[0].origin.slice()
2018-10-18 01:50:25 +08:00
}
2019-07-18 00:02:07 +08:00
Cube.selected.forEach(function(obj) {
2018-10-18 01:50:25 +08:00
obj.roll(axis, steps, origin)
})
updateSelection()
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Rotate elements')
2018-03-29 02:48:11 +08:00
}
//Mirror
2018-10-18 01:50:25 +08:00
function mirrorSelected(axis) {
2019-08-18 00:26:14 +08:00
if (Modes.animate && Timeline.selected.length) {
Undo.initEdit({keyframes: Timeline.selected})
for (var kf of Timeline.selected) {
kf.flip(axis)
}
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Flipped keyframes');
2019-08-18 00:26:14 +08:00
updateKeyframeSelection();
Animator.preview();
2019-12-16 03:04:31 +08:00
} else if (Modes.edit && selected.length) {
Undo.initEdit({elements: selected, outliner: Format.bone_rig})
var center = Format.centered_grid ? 0 : 8;
2019-08-18 00:26:14 +08:00
if (Format.bone_rig) {
if (Group.selected && Group.selected.matchesSelection()) {
function flipGroup(group) {
if (group.type === 'group') {
for (var i = 0; i < 3; i++) {
if (i === axis) {
group.origin[i] *= -1
} else {
group.rotation[i] *= -1
}
}
if (axis == 0 && group.name.includes('right')) {
group.name = group.name.replace(/right/g, 'left').replace(/2/, '');
} else if (axis == 0 && group.name.includes('left')) {
group.name = group.name.replace(/left/g, 'right').replace(/2/, '');
2018-12-16 23:18:20 +08:00
}
2019-07-18 00:02:07 +08:00
}
2021-03-09 00:05:00 +08:00
Canvas.updateAllBones([group]);
2018-12-16 23:18:20 +08:00
}
2019-08-18 00:26:14 +08:00
flipGroup(Group.selected)
Group.selected.forEachChild(flipGroup)
2018-12-16 23:18:20 +08:00
}
}
2019-12-16 03:04:31 +08:00
selected.forEach(function(obj) {
2019-08-18 00:26:14 +08:00
obj.flip(axis, center, false)
2019-12-16 03:04:31 +08:00
if (Project.box_uv && obj instanceof Cube && axis === 0) {
2019-08-18 00:26:14 +08:00
obj.shade = !obj.shade
Canvas.updateUV(obj)
}
})
updateSelection()
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Flip selection')
2018-10-18 01:50:25 +08:00
}
2019-07-18 00:02:07 +08:00
}
const Vertexsnap = {
step1: true,
vertexes: new THREE.Object3D(),
vertexed_cubes: [],
hovering: false,
2020-04-26 02:25:07 +08:00
createVertexGizmo(cube, vec, id) {
//Each vertex needs it's own material for hovering
let outline_color = '0x'+CustomTheme.data.colors.accent.replace('#', '')
let material = new THREE.MeshBasicMaterial({color: parseInt(outline_color)})
let geometry = id == 100 ? new THREE.SphereGeometry(1, 7, 7) : new THREE.BoxGeometry(1, 1, 1)
let mesh = new THREE.Mesh(geometry, material)
2020-04-26 02:25:07 +08:00
let pos = mesh.position.copy(vec)
pos.applyMatrix4(cube.mesh.matrixWorld)
if (!Format.centered_grid) {
pos.addScalar(8)
}
mesh.rotation.copy(cube.mesh.rotation)
if (id == 100) {
mesh.rotation.y += Math.PI/4;
}
mesh.cube = cube
mesh.isVertex = true
mesh.vertex_id = id
mesh.material.transparent = true;
mesh.renderOrder = 999;
Vertexsnap.vertexes.add(mesh)
},
addVertices: function(cube) {
2019-07-18 00:02:07 +08:00
if (Vertexsnap.vertexed_cubes.includes(cube)) return;
if (cube.visibility === false) return;
$('#preview').get(0).removeEventListener("mousemove", Vertexsnap.hoverCanvas)
$('#preview').get(0).addEventListener("mousemove", Vertexsnap.hoverCanvas)
var o_vertices = cube.mesh.geometry.vertices
cube.mesh.updateMatrixWorld()
o_vertices.forEach(function(v, id) {
2020-04-26 02:25:07 +08:00
Vertexsnap.createVertexGizmo(cube, v, id)
2019-07-18 00:02:07 +08:00
})
2020-04-26 02:25:07 +08:00
Vertexsnap.createVertexGizmo(cube, new THREE.Vector3(), 100)
2019-07-18 00:02:07 +08:00
Vertexsnap.vertexed_cubes.push(cube)
Vertexsnap.updateVertexSize()
},
removeVertexes: function() {
var i = Vertexsnap.vertexes.children.length
while (i >= 0) {
Vertexsnap.vertexes.remove(Vertexsnap.vertexes.children[i])
i--;
}
Vertexsnap.vertexed_cubes = []
$('#preview').get(0).removeEventListener("mousemove", Vertexsnap.hoverCanvas)
},
hoverCanvas: function(event) {
if (Vertexsnap.hovering) {
Vertexsnap.vertexes.children.forEach(function(v) {
if (v.type === 'Line') {
Vertexsnap.vertexes.remove(v)
} else {
2019-12-16 03:04:31 +08:00
v.material.color.set(parseInt('0x'+CustomTheme.data.colors.accent.replace('#', '')))
2020-04-26 02:25:07 +08:00
v.material.depthTest = true;
2019-07-18 00:02:07 +08:00
}
})
}
2019-12-16 03:04:31 +08:00
let data = Canvas.raycast(event)
2019-07-18 00:02:07 +08:00
if (!data || !data.vertex) {
Blockbench.setStatusBarText()
return;
}
var vertex = data.vertex
vertex.material.color.g = 1
Vertexsnap.hovering = true
2020-04-26 02:25:07 +08:00
vertex.material.depthTest = false;
2019-07-18 00:02:07 +08:00
if (Vertexsnap.step1 === false) {
//Line
var geometry = new THREE.Geometry();
geometry.vertices.push(Vertexsnap.vertex_pos);
geometry.vertices.push(vertex.position);
var line = new THREE.Line(geometry, Vertexsnap.lineMaterial);
line.renderOrder = 900
Vertexsnap.vertexes.add(line)
//Measure
var diff = new THREE.Vector3().copy(Vertexsnap.vertex_pos)
diff.sub(vertex.position)
Blockbench.setStatusBarText(tl('status_bar.vertex_distance', [trimFloatNumber(diff.length())] ))
}
},
select: function() {
Vertexsnap.removeVertexes()
Cube.selected.forEach(function(obj) {
2020-04-26 02:25:07 +08:00
Vertexsnap.addVertices(obj)
2019-07-18 00:02:07 +08:00
})
if (Cube.selected.length) {
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
}
Vertexsnap.lineMaterial = Canvas.outlineMaterial.clone()
Vertexsnap.lineMaterial.depthTest = false
},
canvasClick: function(data) {
2019-12-16 03:04:31 +08:00
if (!data || !data.vertex) return;
2019-07-18 00:02:07 +08:00
if (Vertexsnap.step1) {
Vertexsnap.step1 = false
Vertexsnap.vertex_pos = data.vertex.position
Vertexsnap.vertex_id = data.vertex.vertex_id
Vertexsnap.cubes = Cube.selected.slice()
Vertexsnap.removeVertexes()
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
2020-04-26 02:25:07 +08:00
2019-07-18 00:02:07 +08:00
} else {
Vertexsnap.snap(data)
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
}
Blockbench.setStatusBarText()
},
snap: function(data) {
Undo.initEdit({elements: Vertexsnap.cubes})
2020-04-26 02:25:07 +08:00
let mode = BarItems.vertex_snap_mode.get()
2019-07-18 00:02:07 +08:00
2020-04-26 02:25:07 +08:00
if (Vertexsnap.vertex_id === 100) {
2019-07-18 00:02:07 +08:00
2020-04-26 02:25:07 +08:00
Vertexsnap.cubes.forEach(function(cube) {
let vec = new THREE.Vector3().copy(data.vertex.position)
if (Format.bone_rig && cube.parent instanceof Group && cube.mesh.parent) {
cube.mesh.parent.worldToLocal(vec);
2019-07-18 00:02:07 +08:00
}
2020-04-26 02:25:07 +08:00
let vec_array = vec.toArray()
vec_array.V3_add(cube.parent.origin);
cube.transferOrigin(vec_array)
2019-07-18 00:02:07 +08:00
})
} else {
2019-09-06 06:16:54 +08:00
2020-04-26 02:25:07 +08:00
var global_delta = data.vertex.position
global_delta.sub(Vertexsnap.vertex_pos)
if (mode === 'scale' && !Format.integer_size) {
2020-04-26 02:25:07 +08:00
//Scale
var m;
switch (Vertexsnap.vertex_id) {
case 0: m=[ 1,1,1 ]; break;
case 1: m=[ 1,1,0 ]; break;
case 2: m=[ 1,0,1 ]; break;
case 3: m=[ 1,0,0 ]; break;
case 4: m=[ 0,1,0 ]; break;
case 5: m=[ 0,1,1 ]; break;
case 6: m=[ 0,0,0 ]; break;
case 7: m=[ 0,0,1 ]; break;
2019-08-01 06:01:47 +08:00
}
2020-04-26 02:25:07 +08:00
Vertexsnap.cubes.forEach(function(obj) {
var q = obj.mesh.getWorldQuaternion(new THREE.Quaternion()).inverse()
var cube_pos = new THREE.Vector3().copy(global_delta).applyQuaternion(q)
for (i=0; i<3; i++) {
if (m[i] === 1) {
obj.to[i] = limitToBox(obj.to[i] + cube_pos.getComponent(i), obj.inflate)
} else {
obj.from[i] = limitToBox(obj.from[i] + cube_pos.getComponent(i), -obj.inflate)
}
}
if (Project.box_uv && obj.visibility) {
Canvas.updateUV(obj)
}
})
} else if (mode === 'move') {
Vertexsnap.cubes.forEach(function(obj) {
var cube_pos = new THREE.Vector3().copy(global_delta)
if (Format.bone_rig && obj.parent instanceof Group && obj.mesh.parent) {
var q = obj.mesh.parent.getWorldQuaternion(new THREE.Quaternion()).inverse();
cube_pos.applyQuaternion(q);
}
if (Format.rotate_cubes) {
obj.origin.V3_add(cube_pos);
}
var in_box = obj.moveVector(cube_pos.toArray());
if (!in_box && Format.canvas_limit && !settings.deactivate_size_limit.value) {
Blockbench.showMessageBox({translateKey: 'canvas_limit_error'})
}
})
}
2019-07-18 00:02:07 +08:00
}
2018-12-16 23:18:20 +08:00
2019-07-18 00:02:07 +08:00
Vertexsnap.removeVertexes()
Canvas.updateAllPositions()
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Use vertex snap')
2019-07-18 00:02:07 +08:00
Vertexsnap.step1 = true
},
updateVertexSize: function() {
if (!Preview.selected) return;
2019-07-18 00:02:07 +08:00
Vertexsnap.vertexes.children.forEach(function(v,i) {
let scale = Preview.selected.calculateControlScale(v.position) * 0.6;
v.scale.set(scale, scale, scale);
2019-07-18 00:02:07 +08:00
})
}
2018-03-29 02:48:11 +08:00
}
Blockbench.on('update_camera_position resize_window', e => {
if (Toolbox && Toolbox.selected.id == 'vertex_snap_tool') {
Vertexsnap.updateVertexSize();
}
})
2018-03-29 02:48:11 +08:00
//Scale
function scaleAll(save, size) {
2018-10-18 01:50:25 +08:00
if (save === true) {
hideDialog()
}
if (size === undefined) {
size = $('#model_scale_label').val()
}
2019-04-08 00:53:33 +08:00
var origin = [
parseFloat($('#scaling_origin_x').val())||0,
parseFloat($('#scaling_origin_y').val())||0,
parseFloat($('#scaling_origin_z').val())||0,
]
2019-07-19 23:31:22 +08:00
var overflow = [];
2018-10-18 01:50:25 +08:00
selected.forEach(function(obj) {
obj.autouv = 0;
origin.forEach(function(ogn, i) {
if ($('#model_scale_'+getAxisLetter(i)+'_axis').is(':checked')) {
2018-03-29 02:48:11 +08:00
2019-07-18 00:02:07 +08:00
if (obj.from) {
obj.from[i] = (obj.before.from[i] - obj.inflate - ogn) * size;
2019-07-19 23:31:22 +08:00
if (obj.from[i] + ogn > 32 || obj.from[i] + ogn < -16) overflow.push(obj);
obj.from[i] = limitToBox(obj.from[i] + obj.inflate + ogn, -obj.inflate);
2019-07-18 00:02:07 +08:00
}
2018-03-29 02:48:11 +08:00
2019-07-18 00:02:07 +08:00
if (obj.to) {
obj.to[i] = (obj.before.to[i] + obj.inflate - ogn) * size;
2019-07-19 23:31:22 +08:00
if (obj.to[i] + ogn > 32 || obj.to[i] + ogn < -16) overflow.push(obj);
obj.to[i] = limitToBox(obj.to[i] - obj.inflate + ogn, obj.inflate);
2019-12-16 03:04:31 +08:00
if (Format.integer_size) {
obj.to[i] = obj.from[i] + Math.round(obj.to[i] - obj.from[i])
}
2019-07-18 00:02:07 +08:00
}
2018-03-29 02:48:11 +08:00
2019-07-18 00:02:07 +08:00
if (obj.origin) {
obj.origin[i] = (obj.before.origin[i] - ogn) * size;
obj.origin[i] = obj.origin[i] + ogn;
}
2018-10-18 01:50:25 +08:00
} else {
2018-03-29 02:48:11 +08:00
2019-07-18 00:02:07 +08:00
if (obj.from) obj.from[i] = obj.before.from[i];
if (obj.to) obj.to[i] = obj.before.to[i];
2018-03-29 02:48:11 +08:00
2019-07-18 00:02:07 +08:00
if (obj.origin) obj.origin[i] = obj.before.origin[i];
2018-03-29 02:48:11 +08:00
2018-10-18 01:50:25 +08:00
}
})
if (save === true) {
delete obj.before
}
2019-07-18 00:02:07 +08:00
if (Project.box_uv) {
2018-10-18 01:50:25 +08:00
Canvas.updateUV(obj)
}
})
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
Group.selected.forEachChild((g) => {
2018-12-29 19:26:02 +08:00
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
}
2019-07-18 00:02:07 +08:00
}, Group)
2018-12-29 19:26:02 +08:00
}
2019-12-16 03:04:31 +08:00
if (overflow.length && Format.canvas_limit && !settings.deactivate_size_limit.value) {
2019-07-19 23:31:22 +08:00
scaleAll.overflow = overflow;
2018-10-18 01:50:25 +08:00
$('#scaling_clipping_warning').text('Model clipping: Your model is too large for the canvas')
2019-02-04 04:09:35 +08:00
$('#scale_overflow_btn').css('display', 'inline-block')
2018-10-18 01:50:25 +08:00
} else {
$('#scaling_clipping_warning').text('')
2019-02-04 04:09:35 +08:00
$('#scale_overflow_btn').hide()
2018-10-18 01:50:25 +08:00
}
Canvas.updatePositions()
if (save === true) {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Scale model')
2018-10-18 01:50:25 +08:00
}
2018-03-29 02:48:11 +08:00
}
function modelScaleSync(label) {
2018-10-18 01:50:25 +08:00
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)
2018-03-29 02:48:11 +08:00
}
function cancelScaleAll() {
2018-10-18 01:50:25 +08:00
selected.forEach(function(obj) {
if (obj === undefined) return;
2020-03-05 03:56:17 +08:00
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);
2018-10-18 01:50:25 +08:00
delete obj.before
2019-07-18 00:02:07 +08:00
if (Project.box_uv) {
Canvas.updateUV(obj)
}
2018-10-18 01:50:25 +08:00
})
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
Group.selected.forEachChild((g) => {
2018-12-29 19:26:02 +08:00
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
2019-07-18 00:02:07 +08:00
}, Group)
2018-12-29 19:26:02 +08:00
}
2018-10-18 01:50:25 +08:00
Canvas.updatePositions()
hideDialog()
2018-03-29 02:48:11 +08:00
}
2020-03-05 03:56:17 +08:00
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]);
}
}
2019-02-04 04:09:35 +08:00
function scaleAllSelectOverflow() {
cancelScaleAll()
2020-04-26 02:25:07 +08:00
selected.empty();
2019-07-19 23:31:22 +08:00
scaleAll.overflow.forEach(obj => {
2019-07-18 00:02:07 +08:00
obj.selectLow()
2019-02-04 04:09:35 +08:00
})
updateSelection();
}
2018-03-29 02:48:11 +08:00
//Center
function centerCubesAll(axis) {
2018-10-18 01:50:25 +08:00
centerCubes(0, false)
centerCubes(1, false)
centerCubes(2, false)
Canvas.updatePositions()
2018-03-29 02:48:11 +08:00
}
function centerCubes(axis, update) {
2018-11-12 04:19:08 +08:00
if (!selected.length) return;
2018-10-18 01:50:25 +08:00
var average = 0;
selected.forEach(function(obj) {
2019-07-18 00:02:07 +08:00
if (obj.movable) average += obj.from[axis]
2019-08-18 00:26:14 +08:00
if (obj.resizable) average += obj.to[axis]
2018-10-18 01:50:25 +08:00
})
average = average / (selected.length * 2)
2019-12-16 03:04:31 +08:00
var difference = (Format.centered_grid ? 0 : 8) - average
2018-03-29 02:48:11 +08:00
2018-10-18 01:50:25 +08:00
selected.forEach(function(obj) {
2019-08-01 06:01:47 +08:00
if (obj.movable) obj.from[axis] = limitToBox(obj.from[axis] + difference, obj.inflate);
2019-08-18 00:26:14 +08:00
if (obj.resizable) obj.to[axis] = limitToBox(obj.to[axis] + difference, obj.inflate);
2019-07-18 00:02:07 +08:00
if (obj.origin) obj.origin[axis] += difference;
2018-10-18 01:50:25 +08:00
})
2018-03-29 02:48:11 +08:00
2018-10-18 01:50:25 +08:00
if (update !== false) {
Canvas.updatePositions()
}
2018-03-29 02:48:11 +08:00
}
2020-03-05 03:56:17 +08:00
//Move
function moveElementsInSpace(difference, axis) {
let space = Transformer.getTransformSpace()
let group = Format.bone_rig && Group.selected && Group.selected.matchesSelection() && Group.selected;
var group_m;
if (group) {
if (space === 0) {
group_m = new THREE.Vector3();
group_m[getAxisLetter(axis)] = difference;
var rotation = new THREE.Quaternion();
group.mesh.parent.getWorldQuaternion(rotation);
group_m.applyQuaternion(rotation.inverse());
group.forEachChild(g => {
g.origin.V3_add(group_m.x, group_m.y, group_m.z);
}, Group, true)
} else if (space === 2) {
group_m = new THREE.Vector3();
group_m[getAxisLetter(axis)] = difference;
2021-02-02 06:37:59 +08:00
group_m.applyQuaternion(group.mesh.quaternion);
2020-03-05 03:56:17 +08:00
group.forEachChild(g => {
g.origin.V3_add(group_m.x, group_m.y, group_m.z);
}, Group, true)
} else {
group.forEachChild(g => {
g.origin[axis] += difference
}, Group, true)
}
Canvas.updateAllBones([Group.selected]);
2020-03-05 03:56:17 +08:00
}
selected.forEach(el => {
if (space == 2 && !group_m) {
if (el instanceof Locator) {
let m = new THREE.Vector3();
m[getAxisLetter(axis)] = difference;
m.applyQuaternion(el.mesh.quaternion);
el.from.V3_add(m.x, m.y, m.z);
} else {
if (el.movable) el.from[axis] += difference;
if (el.resizable) el.to[axis] += difference;
}
2020-03-05 03:56:17 +08:00
} else if (space instanceof Group) {
if (el.movable) el.from[axis] += difference;
if (el.resizable) el.to[axis] += difference;
if (el.rotatable && el instanceof Locator == false) el.origin[axis] += difference;
2020-03-05 03:56:17 +08:00
} else {
2020-04-26 02:25:07 +08:00
let move_origin = !!group;
2020-03-05 03:56:17 +08:00
if (group_m) {
var m = group_m
} else {
var m = new THREE.Vector3();
m[getAxisLetter(axis)] = difference;
2020-04-26 02:25:07 +08:00
let parent = el.parent;
while (parent instanceof Group) {
if (!parent.rotation.allEqual(0)) break;
parent = parent.parent;
}
if (parent == 'root') {
// If none of the parent groups are rotated, move origin.
move_origin = true;
} else {
var rotation = new THREE.Quaternion();
if (el.mesh && el instanceof Locator == false) {
2020-04-26 02:25:07 +08:00
el.mesh.getWorldQuaternion(rotation);
} else if (el.parent instanceof Group) {
el.parent.mesh.getWorldQuaternion(rotation);
}
m.applyQuaternion(rotation.inverse());
2020-03-05 03:56:17 +08:00
}
}
if (el.movable) el.from.V3_add(m.x, m.y, m.z);
if (el.resizable) el.to.V3_add(m.x, m.y, m.z);
2020-04-26 02:25:07 +08:00
if (move_origin) {
if (el.rotatable && el instanceof Locator == false) el.origin.V3_add(m.x, m.y, m.z);
2020-03-05 03:56:17 +08:00
}
}
if (el instanceof Cube) {
el.mapAutoUV()
}
Canvas.adaptObjectPosition(el);
2020-03-05 03:56:17 +08:00
})
}
2019-07-18 00:02:07 +08:00
//Rotate
2018-12-27 21:03:04 +08:00
function getRotationInterval(event) {
2019-07-18 00:02:07 +08:00
if (Format.rotation_limit) {
2018-12-27 21:03:04 +08:00
return 22.5;
} else if ((event.shiftKey || Pressing.overrides.shift) && (event.ctrlOrCmd || Pressing.overrides.ctrl)) {
2018-12-27 21:03:04 +08:00
return 0.25;
} else if (event.shiftKey || Pressing.overrides.shift) {
2020-07-16 15:32:59 +08:00
return 22.5;
} else if (event.ctrlOrCmd || Pressing.overrides.ctrl) {
2018-12-27 21:03:04 +08:00
return 1;
} else {
2020-07-16 15:32:59 +08:00
return 2.5;
2018-12-27 21:03:04 +08:00
}
}
2019-07-18 00:02:07 +08:00
function getRotationObject() {
if (Format.bone_rig && Group.selected) return Group.selected;
if (Format.rotate_cubes && Cube.selected.length) return Cube.selected;
2021-05-28 19:19:09 +08:00
if (Locator.selected.length) return Locator.selected;
2019-07-18 00:02:07 +08:00
}
2020-07-16 15:32:59 +08:00
function rotateOnAxis(modify, axis, slider) {
var things;
if (Format.bone_rig && Group.selected) {
things = [Group.selected]
} else if (Format.rotate_cubes && Cube.selected.length) {
things = Cube.selected;
2021-05-28 19:19:09 +08:00
} else if (Locator.selected.length) {
things = Locator.selected;
2020-07-16 15:32:59 +08:00
}
if (!things) return;
/*
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
if (!Group.selected) return;
2020-07-16 15:32:59 +08:00
let obj = Group.selected.mesh
if (typeof space == 'object') {
let normal = axis == 0 ? THREE.NormalX : (axis == 1 ? THREE.NormalY : THREE.NormalZ)
let rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(normal, Math.degToRad(modify(0)))
rotWorldMatrix.multiply(obj.matrix)
obj.matrix.copy(rotWorldMatrix)
obj.setRotationFromMatrix(rotWorldMatrix)
let e = obj.rotation;
Group.selected.rotation[0] = Math.radToDeg(e.x);
Group.selected.rotation[1] = Math.radToDeg(e.y);
Group.selected.rotation[2] = Math.radToDeg(e.z);
Canvas.updateAllBones()
} else if (space == 0) {
let normal = axis == 0 ? THREE.NormalX : (axis == 1 ? THREE.NormalY : THREE.NormalZ)
let rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(normal, Math.degToRad(modify(0)))
rotWorldMatrix.multiply(obj.matrixWorld)
let inverse = new THREE.Matrix4().getInverse(obj.parent.matrixWorld)
rotWorldMatrix.premultiply(inverse)
obj.matrix.copy(rotWorldMatrix)
obj.setRotationFromMatrix(rotWorldMatrix)
let e = obj.rotation;
Group.selected.rotation[0] = Math.radToDeg(e.x);
Group.selected.rotation[1] = Math.radToDeg(e.y);
Group.selected.rotation[2] = Math.radToDeg(e.z);
Canvas.updateAllBones()
} else {
var value = modify(Group.selected.rotation[axis]);
Group.selected.rotation[axis] = Math.trimDeg(value)
Canvas.updateAllBones()
}
return;
2018-12-27 21:03:04 +08:00
}
2020-07-16 15:32:59 +08:00
*/
2018-12-27 21:03:04 +08:00
//Warning
2019-07-18 00:02:07 +08:00
if (Format.rotation_limit && settings.dialog_rotation_limit.value) {
2018-12-27 21:03:04 +08:00
var i = 0;
2019-07-18 00:02:07 +08:00
while (i < Cube.selected.length) {
if (Cube.selected[i].rotation[(axis+1)%3] ||
Cube.selected[i].rotation[(axis+2)%3]
2018-12-27 21:03:04 +08:00
) {
i = Infinity
Blockbench.showMessageBox({
title: tl('message.rotation_limit.title'),
icon: 'rotate_right',
message: tl('message.rotation_limit.message'),
buttons: [tl('dialog.ok'), tl('dialog.dontshowagain')]
}, function(r) {
if (r === 1) {
settings.dialog_rotation_limit.value = false
2019-07-18 00:02:07 +08:00
Settings.save()
2018-12-27 21:03:04 +08:00
}
})
return;
//Gotta stop the numslider here
}
i++;
}
}
var axis_letter = getAxisLetter(axis)
2020-07-16 15:32:59 +08:00
var origin =things[0].origin
things.forEach(function(obj, i) {
2019-02-04 04:09:35 +08:00
if (!obj.rotation.allEqual(0)) {
2018-12-27 21:03:04 +08:00
origin = obj.origin
}
})
2020-07-16 15:32:59 +08:00
let space = Transformer.getTransformSpace()
things.forEach(obj => {
let mesh = obj.mesh;
if (obj instanceof Cube && !Format.bone_rig) {
if (obj.origin.allEqual(0)) {
2020-07-16 15:32:59 +08:00
obj.origin.V3_set(origin)
}
}
if (slider || (space == 2 && Format.rotation_limit)) {
2020-07-16 15:32:59 +08:00
var obj_val = modify(obj.rotation[axis]);
obj_val = Math.trimDeg(obj_val)
if (Format.rotation_limit) {
//Limit To 1 Axis
obj.rotation[(axis+1)%3] = 0
obj.rotation[(axis+2)%3] = 0
//Limit Angle
obj_val = Math.round(obj_val/22.5)*22.5
if (obj_val > 45 || obj_val < -45) {
let f = obj_val > 45
let can_roll = obj.roll(axis, f!=(axis==1) ? 1 : 3);
if (can_roll) {
obj_val = f ? -22.5 : 22.5;
} else {
obj_val = Math.clamp(obj_val, -45, 45);
}
2020-07-16 15:32:59 +08:00
}
}
obj.rotation[axis] = obj_val
if (obj instanceof Cube) {
obj.rotation_axis = axis_letter
}
} else if (space == 2) {
let old_order = mesh.rotation.order;
mesh.rotation.reorder(axis == 0 ? 'ZYX' : (axis == 1 ? 'ZXY' : 'XYZ'))
var obj_val = modify(Math.radToDeg(mesh.rotation[axis_letter]));
obj_val = Math.trimDeg(obj_val)
mesh.rotation[axis_letter] = Math.degToRad(obj_val);
mesh.rotation.reorder(old_order);
obj.rotation[0] = Math.radToDeg(mesh.rotation.x);
obj.rotation[1] = Math.radToDeg(mesh.rotation.y);
obj.rotation[2] = Math.radToDeg(mesh.rotation.z);
2020-07-16 15:32:59 +08:00
} else if (space instanceof Group) {
let normal = axis == 0 ? THREE.NormalX : (axis == 1 ? THREE.NormalY : THREE.NormalZ)
let rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(normal, Math.degToRad(modify(0)))
rotWorldMatrix.multiply(mesh.matrix)
mesh.matrix.copy(rotWorldMatrix)
mesh.setRotationFromMatrix(rotWorldMatrix)
let e = mesh.rotation;
obj.rotation[0] = Math.radToDeg(e.x);
obj.rotation[1] = Math.radToDeg(e.y);
obj.rotation[2] = Math.radToDeg(e.z);
} else if (space == 0) {
let normal = axis == 0 ? THREE.NormalX : (axis == 1 ? THREE.NormalY : THREE.NormalZ)
let rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(normal, Math.degToRad(modify(0)))
rotWorldMatrix.multiply(mesh.matrixWorld)
let inverse = new THREE.Matrix4().getInverse(mesh.parent.matrixWorld)
rotWorldMatrix.premultiply(inverse)
mesh.matrix.copy(rotWorldMatrix)
mesh.setRotationFromMatrix(rotWorldMatrix)
let e = mesh.rotation;
obj.rotation[0] = Math.radToDeg(e.x);
obj.rotation[1] = Math.radToDeg(e.y);
obj.rotation[2] = Math.radToDeg(e.z);
}
if (obj instanceof Group) {
2021-05-22 18:27:29 +08:00
Canvas.updateView({groups: [obj]});
2020-07-16 15:32:59 +08:00
}
})
2018-12-27 21:03:04 +08:00
}
2018-11-12 04:19:08 +08:00
BARS.defineActions(function() {
2020-03-05 03:56:17 +08:00
new BarSelect('transform_space', {
condition: {modes: ['edit', 'animate'], tools: ['move_tool', 'pivot_tool']},
2020-03-05 03:56:17 +08:00
category: 'transform',
2021-02-01 03:31:45 +08:00
value: 'local',
2020-03-05 03:56:17 +08:00
options: {
global: true,
bone: {condition: () => Format.bone_rig, name: true},
local: true
},
onChange() {
updateSelection();
}
})
2020-07-16 15:32:59 +08:00
new BarSelect('rotation_space', {
condition: {modes: ['edit', 'animate'], tools: ['rotate_tool']},
2020-07-16 15:32:59 +08:00
category: 'transform',
value: 'local',
options: {
global: 'action.transform_space.global',
bone: {condition: () => Format.bone_rig, name: true, name: 'action.transform_space.bone'},
local: 'action.transform_space.local'
},
onChange() {
updateSelection();
}
})
2020-03-05 03:56:17 +08:00
let grid_locked_interval = function(event) {
event = event||0;
return canvasGridSize(event.shiftKey || Pressing.overrides.shift, event.ctrlOrCmd || Pressing.overrides.ctrl);
2020-03-05 03:56:17 +08:00
}
2019-12-16 03:04:31 +08:00
function moveOnAxis(modify, axis) {
2018-11-12 04:19:08 +08:00
selected.forEach(function(obj, i) {
2019-07-18 00:02:07 +08:00
if (obj.movable) {
2019-12-16 03:04:31 +08:00
var val = modify(obj.from[axis])
if (Format.canvas_limit && !settings.deactivate_size_limit.value) {
2019-09-06 06:16:54 +08:00
var size = obj.resizable ? obj.size(axis) : 0;
val = limitToBox(limitToBox(val, -obj.inflate) + size, obj.inflate) - size
}
2019-12-16 03:04:31 +08:00
//val -= obj.from[axis];
var before = obj.from[axis];
obj.from[axis] = val;
2019-09-06 06:16:54 +08:00
if (obj.resizable) {
2019-12-16 03:04:31 +08:00
obj.to[axis] += (val - before);
2019-09-06 06:16:54 +08:00
}
if (obj instanceof Cube) {
obj.mapAutoUV()
Canvas.adaptObjectPosition(obj);
}
2018-11-12 04:19:08 +08:00
}
})
2019-09-04 15:37:38 +08:00
TickUpdates.selection = true;
2018-11-12 04:19:08 +08:00
}
2019-08-18 00:26:14 +08:00
new NumSlider('slider_pos_x', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_pos', ['X']),
description: tl('action.slider_pos.desc', ['X']),
2020-01-24 01:53:36 +08:00
color: 'x',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (selected.length && Modes.edit),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
return selected[0].from[0]
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
moveOnAxis(modify, 0)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change element position')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_pos_y', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_pos', ['Y']),
description: tl('action.slider_pos.desc', ['Y']),
2020-01-24 01:53:36 +08:00
color: 'y',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (selected.length && Modes.edit),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
return selected[0].from[1]
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
moveOnAxis(modify, 1)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change element position')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_pos_z', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_pos', ['Z']),
description: tl('action.slider_pos.desc', ['Z']),
2020-01-24 01:53:36 +08:00
color: 'z',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (selected.length && Modes.edit),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
return selected[0].from[2]
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
moveOnAxis(modify, 2)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change element position')
2018-11-12 04:19:08 +08:00
}
})
2019-12-16 03:04:31 +08:00
function resizeOnAxis(modify, axis) {
2018-11-12 04:19:08 +08:00
selected.forEach(function(obj, i) {
2019-08-18 00:26:14 +08:00
if (obj.resizable) {
2019-12-16 03:04:31 +08:00
obj.resize(modify, axis, false, true)
2018-11-12 04:19:08 +08:00
}
})
}
2019-08-18 00:26:14 +08:00
new NumSlider('slider_size_x', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_size', ['X']),
description: tl('action.slider_size.desc', ['X']),
2020-01-24 01:53:36 +08:00
color: 'x',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (Cube.selected.length && Modes.edit),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
return Cube.selected[0].to[0] - Cube.selected[0].from[0]
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
resizeOnAxis(modify, 0)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: Cube.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change element size')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_size_y', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_size', ['Y']),
description: tl('action.slider_size.desc', ['Y']),
2020-01-24 01:53:36 +08:00
color: 'y',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (Cube.selected.length && Modes.edit),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
return Cube.selected[0].to[1] - Cube.selected[0].from[1]
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
resizeOnAxis(modify, 1)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: Cube.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change element size')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_size_z', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_size', ['Z']),
description: tl('action.slider_size.desc', ['Z']),
2020-01-24 01:53:36 +08:00
color: 'z',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (Cube.selected.length && Modes.edit),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
return Cube.selected[0].to[2] - Cube.selected[0].from[2]
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
resizeOnAxis(modify, 2)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: Cube.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change element size')
2018-11-12 04:19:08 +08:00
}
})
2019-08-01 06:01:47 +08:00
//Inflate
2019-08-18 00:26:14 +08:00
new NumSlider('slider_inflate', {
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: function() {return Cube.selected.length && Modes.edit},
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
return Cube.selected[0].inflate
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
2019-07-18 00:02:07 +08:00
Cube.selected.forEach(function(obj, i) {
2019-12-16 03:04:31 +08:00
var v = modify(obj.inflate)
if (Format.canvas_limit && !settings.deactivate_size_limit.value) {
2019-09-04 15:37:38 +08:00
v = obj.from[0] - Math.clamp(obj.from[0]-v, -16, 32);
v = obj.from[1] - Math.clamp(obj.from[1]-v, -16, 32);
v = obj.from[2] - Math.clamp(obj.from[2]-v, -16, 32);
v = Math.clamp(obj.to[0]+v, -16, 32) - obj.to[0];
v = Math.clamp(obj.to[1]+v, -16, 32) - obj.to[1];
v = Math.clamp(obj.to[2]+v, -16, 32) - obj.to[2];
}
2019-08-18 00:26:14 +08:00
obj.inflate = v
2018-11-12 04:19:08 +08:00
})
Canvas.updatePositions()
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: Cube.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Inflate elements')
2018-11-12 04:19:08 +08:00
}
})
2019-07-18 00:02:07 +08:00
2018-12-27 21:03:04 +08:00
//Rotation
2019-08-18 00:26:14 +08:00
new NumSlider('slider_rotation_x', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_rotation', ['X']),
description: tl('action.slider_rotation.desc', ['X']),
2020-01-24 01:53:36 +08:00
color: 'x',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (Modes.edit && getRotationObject()),
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
return Group.selected.rotation[0];
}
if (Format.rotate_cubes && Cube.selected[0]) {
return Cube.selected[0].rotation[0];
}
2021-05-28 19:19:09 +08:00
if (Locator.selected[0]) {
return Locator.selected[0].rotation[0];
}
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
2020-07-16 15:32:59 +08:00
rotateOnAxis(modify, 0, true)
2018-12-27 21:03:04 +08:00
Canvas.updatePositions()
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: Cube.selected, group: Group.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit(getRotationObject() instanceof Group ? 'Rotate group' : 'Rotate elements');
2018-11-12 04:19:08 +08:00
},
getInterval: getRotationInterval
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_rotation_y', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_rotation', ['Y']),
description: tl('action.slider_rotation.desc', ['Y']),
2020-01-24 01:53:36 +08:00
color: 'y',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (Modes.edit && getRotationObject()),
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
return Group.selected.rotation[1];
}
if (Format.rotate_cubes && Cube.selected[0]) {
return Cube.selected[0].rotation[1];
}
2021-05-28 19:19:09 +08:00
if (Locator.selected[0]) {
return Locator.selected[0].rotation[1];
}
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
2020-07-16 15:32:59 +08:00
rotateOnAxis(modify, 1, true)
2018-12-27 21:03:04 +08:00
Canvas.updatePositions()
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected, group: Group.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit(getRotationObject() instanceof Group ? 'Rotate group' : 'Rotate elements');
2018-11-12 04:19:08 +08:00
},
getInterval: getRotationInterval
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_rotation_z', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_rotation', ['Z']),
description: tl('action.slider_rotation.desc', ['Z']),
2020-01-24 01:53:36 +08:00
color: 'z',
2020-03-05 03:56:17 +08:00
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: () => (Modes.edit && getRotationObject()),
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
return Group.selected.rotation[2];
}
if (Format.rotate_cubes && Cube.selected[0]) {
return Cube.selected[0].rotation[2];
}
2021-05-28 19:19:09 +08:00
if (Locator.selected[0]) {
return Locator.selected[0].rotation[2];
}
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
2020-07-16 15:32:59 +08:00
rotateOnAxis(modify, 2, true)
2018-12-27 21:03:04 +08:00
Canvas.updatePositions()
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected, group: Group.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit(getRotationObject() instanceof Group ? 'Rotate group' : 'Rotate elements');
2018-11-12 04:19:08 +08:00
},
getInterval: getRotationInterval
})
2019-07-18 00:02:07 +08:00
function rotateCondition() {
return (Modes.edit && (
(Format.bone_rig && Group.selected) ||
(Format.rotate_cubes && Cube.selected.length)
))
}
2018-11-12 04:19:08 +08:00
2019-08-01 06:01:47 +08:00
//Origin
2019-12-16 03:04:31 +08:00
function moveOriginOnAxis(modify, axis) {
2019-09-06 06:16:54 +08:00
var rotation_object = getRotationObject()
if (rotation_object instanceof Group) {
2019-12-16 03:04:31 +08:00
var val = modify(rotation_object.origin[axis]);
rotation_object.origin[axis] = val;
2021-05-22 18:27:29 +08:00
Canvas.updateView({elements: Cube.selected, element_aspects: {geometry: true}})
2019-07-18 00:02:07 +08:00
if (Format.bone_rig) {
2019-04-08 00:53:33 +08:00
Canvas.updateAllBones()
}
2019-09-06 06:16:54 +08:00
} else {
rotation_object.forEach(function(obj, i) {
2019-12-16 03:04:31 +08:00
var val = modify(obj.origin[axis]);
obj.origin[axis] = val;
2019-09-06 06:16:54 +08:00
})
2021-05-22 18:27:29 +08:00
Canvas.updateView({elements: Cube.selected, element_aspects: {geometry: true}})
2018-11-12 04:19:08 +08:00
}
2019-12-16 03:04:31 +08:00
if (Modes.animate) {
Animator.preview();
}
2018-11-12 04:19:08 +08:00
}
2019-08-18 00:26:14 +08:00
new NumSlider('slider_origin_x', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_origin', ['X']),
description: tl('action.slider_origin.desc', ['X']),
2020-01-24 01:53:36 +08:00
color: 'x',
2020-03-05 03:56:17 +08:00
category: 'transform',
2021-05-28 19:19:09 +08:00
condition: () => (Modes.edit || Modes.animate) && getRotationObject() && (Group.selected || Outliner.selected.length > Locator.selected.length),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
return Group.selected.origin[0];
}
if (Format.rotate_cubes && Cube.selected[0]) {
return Cube.selected[0].origin[0];
}
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
moveOriginOnAxis(modify, 0)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected, group: Group.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change pivot point')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_origin_y', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_origin', ['Y']),
description: tl('action.slider_origin.desc', ['Y']),
2020-01-24 01:53:36 +08:00
color: 'y',
2020-03-05 03:56:17 +08:00
category: 'transform',
2021-05-28 19:19:09 +08:00
condition: () => (Modes.edit || Modes.animate) && getRotationObject() && (Group.selected || Outliner.selected.length > Locator.selected.length),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
return Group.selected.origin[1];
}
if (Format.rotate_cubes && Cube.selected[0]) {
return Cube.selected[0].origin[1];
}
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
moveOriginOnAxis(modify, 1)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected, group: Group.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change pivot point')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new NumSlider('slider_origin_z', {
2019-12-16 03:04:31 +08:00
name: tl('action.slider_origin', ['Z']),
description: tl('action.slider_origin.desc', ['Z']),
2020-01-24 01:53:36 +08:00
color: 'z',
2020-03-05 03:56:17 +08:00
category: 'transform',
2021-05-28 19:19:09 +08:00
condition: () => (Modes.edit || Modes.animate) && getRotationObject() && (Group.selected || Outliner.selected.length > Locator.selected.length),
2020-03-05 03:56:17 +08:00
getInterval: grid_locked_interval,
2018-11-12 04:19:08 +08:00
get: function() {
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
return Group.selected.origin[2];
}
if (Format.rotate_cubes && Cube.selected[0]) {
return Cube.selected[0].origin[2];
}
2018-11-12 04:19:08 +08:00
},
2019-12-16 03:04:31 +08:00
change: function(modify) {
moveOriginOnAxis(modify, 2)
2018-11-12 04:19:08 +08:00
},
onBefore: function() {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected, group: Group.selected})
2018-11-12 04:19:08 +08:00
},
onAfter: function() {
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Change pivot point')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('scale', {
2018-11-12 04:19:08 +08:00
icon: 'settings_overscan',
category: 'transform',
2020-03-05 03:56:17 +08:00
condition: () => (Modes.edit && selected.length),
2018-11-12 04:19:08 +08:00
click: function () {
2018-12-03 02:37:06 +08:00
$('#model_scale_range, #model_scale_label').val(1)
$('#scaling_clipping_warning').text('')
2018-11-12 04:19:08 +08:00
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected, outliner: Format.bone_rig})
2018-11-12 04:19:08 +08:00
selected.forEach(function(obj) {
obj.before = {
2019-07-18 00:02:07 +08:00
from: obj.from ? obj.from.slice() : undefined,
to: obj.to ? obj.to.slice() : undefined,
origin: obj.origin ? obj.origin.slice() : undefined
2018-11-12 04:19:08 +08:00
}
})
2019-07-18 00:02:07 +08:00
if (Format.bone_rig && Group.selected) {
Group.selected.forEachChild((g) => {
2018-12-29 19:26:02 +08:00
g.old_origin = g.origin.slice();
2019-07-18 00:02:07 +08:00
}, Group, true)
2018-12-29 19:26:02 +08:00
}
2018-11-12 04:19:08 +08:00
showDialog('scaling')
2019-12-16 03:04:31 +08:00
var v = Format.centered_grid ? 0 : 8;
2019-07-18 00:02:07 +08:00
var origin = Group.selected ? Group.selected.origin : [v, 0, v];
2019-04-08 00:53:33 +08:00
$('#scaling_origin_x').val(origin[0])
$('#scaling_origin_y').val(origin[1])
$('#scaling_origin_z').val(origin[2])
2019-02-04 04:09:35 +08:00
scaleAll(false, 1)
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('rotate_x_cw', {
2019-12-16 03:04:31 +08:00
name: tl('action.rotate_cw', 'X'),
2018-11-12 04:19:08 +08:00
icon: 'rotate_right',
color: 'x',
category: 'transform',
click: function () {
rotateSelected(0, 1);
}
})
2019-08-18 00:26:14 +08:00
new Action('rotate_x_ccw', {
2019-12-16 03:04:31 +08:00
name: tl('action.rotate_ccw', 'X'),
2018-11-12 04:19:08 +08:00
icon: 'rotate_left',
color: 'x',
category: 'transform',
click: function () {
rotateSelected(0, 3);
}
})
2019-08-18 00:26:14 +08:00
new Action('rotate_y_cw', {
2019-12-16 03:04:31 +08:00
name: tl('action.rotate_cw', 'Y'),
2018-11-12 04:19:08 +08:00
icon: 'rotate_right',
color: 'y',
category: 'transform',
click: function () {
rotateSelected(1, 1);
}
})
2019-08-18 00:26:14 +08:00
new Action('rotate_y_ccw', {
2019-12-16 03:04:31 +08:00
name: tl('action.rotate_ccw', 'Y'),
2018-11-12 04:19:08 +08:00
icon: 'rotate_left',
color: 'y',
category: 'transform',
click: function () {
rotateSelected(1, 3);
}
})
2019-08-18 00:26:14 +08:00
new Action('rotate_z_cw', {
2019-12-16 03:04:31 +08:00
name: tl('action.rotate_cw', 'Z'),
2018-11-12 04:19:08 +08:00
icon: 'rotate_right',
color: 'z',
category: 'transform',
click: function () {
rotateSelected(2, 1);
}
})
2019-08-18 00:26:14 +08:00
new Action('rotate_z_ccw', {
2019-12-16 03:04:31 +08:00
name: tl('action.rotate_ccw', 'Z'),
2018-11-12 04:19:08 +08:00
icon: 'rotate_left',
color: 'z',
category: 'transform',
click: function () {
rotateSelected(2, 3);
}
})
2019-08-18 00:26:14 +08:00
new Action('flip_x', {
2019-12-16 03:04:31 +08:00
name: tl('action.flip', 'X'),
2018-11-12 04:19:08 +08:00
icon: 'icon-mirror_x',
color: 'x',
category: 'transform',
click: function () {
2021-03-09 00:05:00 +08:00
mirrorSelected(0);
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('flip_y', {
2019-12-16 03:04:31 +08:00
name: tl('action.flip', 'Y'),
2018-11-12 04:19:08 +08:00
icon: 'icon-mirror_y',
color: 'y',
category: 'transform',
click: function () {
mirrorSelected(1);
}
})
2019-08-18 00:26:14 +08:00
new Action('flip_z', {
2019-12-16 03:04:31 +08:00
name: tl('action.flip', 'Z'),
2018-11-12 04:19:08 +08:00
icon: 'icon-mirror_z',
color: 'z',
category: 'transform',
click: function () {
mirrorSelected(2);
}
})
2019-08-18 00:26:14 +08:00
new Action('center_x', {
2019-12-16 03:04:31 +08:00
name: tl('action.center', 'X'),
2018-11-12 04:19:08 +08:00
icon: 'vertical_align_center',
color: 'x',
category: 'transform',
click: function () {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected});
2018-11-12 04:19:08 +08:00
centerCubes(0);
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Center selection on X axis')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('center_y', {
2019-12-16 03:04:31 +08:00
name: tl('action.center', 'Y'),
2018-11-12 04:19:08 +08:00
icon: 'vertical_align_center',
color: 'y',
category: 'transform',
click: function () {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected});
2018-11-12 04:19:08 +08:00
centerCubes(1);
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Center selection on Y axis')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('center_z', {
2019-12-16 03:04:31 +08:00
name: tl('action.center', 'Z'),
2018-11-12 04:19:08 +08:00
icon: 'vertical_align_center',
color: 'z',
category: 'transform',
click: function () {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected});
2018-11-12 04:19:08 +08:00
centerCubes(2);
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Center selection on Z axis')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('center_all', {
2018-11-12 04:19:08 +08:00
icon: 'filter_center_focus',
category: 'transform',
click: function () {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: selected});
2018-11-12 04:19:08 +08:00
centerCubesAll();
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Center selection')
2018-11-12 04:19:08 +08:00
}
})
2019-12-16 03:04:31 +08:00
//Move Cube Keys
new Action('move_up', {
icon: 'arrow_upward',
category: 'transform',
2020-01-24 01:53:36 +08:00
condition: {modes: ['edit'], method: () => (!open_menu && selected.length)},
2019-12-16 03:04:31 +08:00
keybind: new Keybind({key: 38, ctrl: null, shift: null}),
click: function (e) {moveCubesRelative(-1, 2, e)}
})
new Action('move_down', {
icon: 'arrow_downward',
category: 'transform',
2020-01-24 01:53:36 +08:00
condition: {modes: ['edit'], method: () => (!open_menu && selected.length)},
2019-12-16 03:04:31 +08:00
keybind: new Keybind({key: 40, ctrl: null, shift: null}),
click: function (e) {moveCubesRelative(1, 2, e)}
})
new Action('move_left', {
icon: 'arrow_back',
category: 'transform',
2020-01-24 01:53:36 +08:00
condition: {modes: ['edit'], method: () => (!open_menu && selected.length)},
2019-12-16 03:04:31 +08:00
keybind: new Keybind({key: 37, ctrl: null, shift: null}),
click: function (e) {moveCubesRelative(-1, 0, e)}
})
new Action('move_right', {
icon: 'arrow_forward',
category: 'transform',
2020-01-24 01:53:36 +08:00
condition: {modes: ['edit'], method: () => (!open_menu && selected.length)},
2019-12-16 03:04:31 +08:00
keybind: new Keybind({key: 39, ctrl: null, shift: null}),
click: function (e) {moveCubesRelative(1, 0, e)}
})
new Action('move_forth', {
icon: 'keyboard_arrow_up',
category: 'transform',
2020-01-24 01:53:36 +08:00
condition: {modes: ['edit'], method: () => (!open_menu && selected.length)},
2019-12-16 03:04:31 +08:00
keybind: new Keybind({key: 33, ctrl: null, shift: null}),
click: function (e) {moveCubesRelative(-1, 1, e)}
})
new Action('move_back', {
icon: 'keyboard_arrow_down',
category: 'transform',
2020-01-24 01:53:36 +08:00
condition: {modes: ['edit'], method: () => (!open_menu && selected.length)},
2019-12-16 03:04:31 +08:00
keybind: new Keybind({key: 34, ctrl: null, shift: null}),
click: function (e) {moveCubesRelative(1, 1, e)}
})
2019-08-18 00:26:14 +08:00
new Action('toggle_visibility', {
2018-11-12 04:19:08 +08:00
icon: 'visibility',
category: 'transform',
click: function () {toggleCubeProperty('visibility')}
})
2020-04-26 02:25:07 +08:00
new Action('toggle_locked', {
icon: 'fas.fa-lock',
category: 'transform',
click: function () {toggleCubeProperty('locked')}
})
2019-08-18 00:26:14 +08:00
new Action('toggle_export', {
2018-11-12 04:19:08 +08:00
icon: 'save',
category: 'transform',
click: function () {toggleCubeProperty('export')}
})
2019-08-18 00:26:14 +08:00
new Action('toggle_autouv', {
2018-11-12 04:19:08 +08:00
icon: 'fullscreen_exit',
category: 'transform',
2020-03-11 05:19:17 +08:00
condition: {modes: ['edit']},
2018-11-12 04:19:08 +08:00
click: function () {toggleCubeProperty('autouv')}
})
2019-08-18 00:26:14 +08:00
new Action('toggle_shade', {
2018-11-12 04:19:08 +08:00
icon: 'wb_sunny',
category: 'transform',
2020-03-11 05:19:17 +08:00
condition: () => !Project.box_uv && Modes.edit,
2019-02-04 04:09:35 +08:00
click: function () {toggleCubeProperty('shade')}
})
2019-08-18 00:26:14 +08:00
new Action('toggle_mirror_uv', {
2019-02-04 04:09:35 +08:00
icon: 'icon-mirror_x',
category: 'transform',
2020-04-26 02:25:07 +08:00
condition: () => Project.box_uv && (Modes.edit || Modes.paint),
2018-11-12 04:19:08 +08:00
click: function () {toggleCubeProperty('shade')}
})
2019-08-18 00:26:14 +08:00
new Action('update_autouv', {
2018-11-12 04:19:08 +08:00
icon: 'brightness_auto',
category: 'transform',
2020-03-11 05:19:17 +08:00
condition: () => !Project.box_uv && Modes.edit,
2018-11-12 04:19:08 +08:00
click: function () {
2019-07-18 00:02:07 +08:00
if (Cube.selected.length) {
Undo.initEdit({elements: Cube.selected[0].forSelected(), selection: true})
Cube.selected[0].forSelected(function(cube) {
2018-11-12 04:19:08 +08:00
cube.mapAutoUV()
})
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Update auto UV')
2018-11-12 04:19:08 +08:00
}
}
})
2019-08-18 00:26:14 +08:00
new Action('origin_to_geometry', {
2018-11-12 04:19:08 +08:00
icon: 'filter_center_focus',
category: 'transform',
condition: {modes: ['edit', 'animate']},
2018-11-12 04:19:08 +08:00
click: function () {origin2geometry()}
})
2019-08-18 00:26:14 +08:00
new Action('rescale_toggle', {
2018-11-12 04:19:08 +08:00
icon: 'check_box_outline_blank',
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: function() {return Format.rotation_limit && Cube.selected.length;},
2018-11-12 04:19:08 +08:00
click: function () {
2019-07-18 00:02:07 +08:00
Undo.initEdit({elements: Cube.selected})
var value = !Cube.selected[0].rescale
Cube.selected.forEach(function(cube) {
2018-11-12 04:19:08 +08:00
cube.rescale = value
})
Canvas.updatePositions()
updateNslideValues()
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Toggle cube rescale')
2018-11-12 04:19:08 +08:00
}
})
2019-08-18 00:26:14 +08:00
new Action('bone_reset_toggle', {
2018-11-12 04:19:08 +08:00
icon: 'check_box_outline_blank',
category: 'transform',
2019-07-18 00:02:07 +08:00
condition: function() {return Format.bone_rig && Group.selected;},
2018-11-12 04:19:08 +08:00
click: function () {
2019-07-18 00:02:07 +08:00
Undo.initEdit({group: Group.selected})
Group.selected.reset = !Group.selected.reset
2018-11-12 04:19:08 +08:00
updateNslideValues()
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Toggle bone reset')
2018-11-12 04:19:08 +08:00
}
})
2019-07-18 00:02:07 +08:00
2019-08-18 00:26:14 +08:00
new Action('remove_blank_faces', {
2019-07-18 00:02:07 +08:00
icon: 'cancel_presentation',
category: 'filter',
condition: () => !Format.box_uv,
click: function () {
Undo.initEdit({elements: Cube.selected})
var arr = Cube.selected.slice()
var empty_cubes = [];
2019-12-16 03:04:31 +08:00
var cleared_total = 0;
2019-07-18 00:02:07 +08:00
unselectAll()
arr.forEach(cube => {
var clear_count = 0;
for (var face in cube.faces) {
var face_tag = cube.faces[face];
if (face_tag.texture == false) {
face_tag.texture = null
clear_count++;
2019-12-16 03:04:31 +08:00
cleared_total++;
2019-07-18 00:02:07 +08:00
}
}
if (clear_count == 6) {
empty_cubes.push(cube);
}
})
updateSelection();
2019-12-16 03:04:31 +08:00
Blockbench.showQuickMessage(tl('message.removed_faces', [cleared_total]))
2019-07-18 00:02:07 +08:00
if (empty_cubes.length) {
Blockbench.showMessageBox({
title: tl('message.cleared_blank_faces.title'),
icon: 'rotate_right',
message: tl('message.cleared_blank_faces.message', [empty_cubes.length]),
buttons: ['generic.remove', 'dialog.cancel'],
confirm: 0,
cancel: 1,
2019-07-18 00:02:07 +08:00
}, function(r) {
empty_cubes.forEach(cube => {
if (r == 0) {
cube.remove();
} else {
for (var face in cube.faces) {
cube.faces[face].texture = false;
}
}
})
updateSelection();
Canvas.updateAllFaces();
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Remove blank faces');
2019-07-18 00:02:07 +08:00
})
} else {
Canvas.updateAllFaces();
2021-06-06 15:28:22 +08:00
Undo.finishEdit('Remove blank faces');
2019-07-18 00:02:07 +08:00
}
}
})
2018-11-12 04:19:08 +08:00
})