This commit is contained in:
JannisX11 2023-04-27 23:08:18 +02:00
commit b8212ae763
17 changed files with 242 additions and 48 deletions

View File

@ -2256,6 +2256,18 @@ const BARS = {
'slider_inflate'
]
})
Toolbars.element_stretch = new Toolbar({
id: 'element_stretch',
name: 'panel.element.stretch',
label: true,
condition: () => Format.stretch_cubes,
children: [
'slider_stretch_x',
'slider_stretch_y',
'slider_stretch_z',
'toggle_stretch_linked'
]
})
Toolbars.element_origin = new Toolbar({
id: 'element_origin',
name: 'panel.element.origin',
@ -2281,6 +2293,7 @@ const BARS = {
if (Blockbench.isMobile) {
[Toolbars.element_position,
Toolbars.element_size,
Toolbars.element_stretch,
Toolbars.element_origin,
Toolbars.element_rotation
].forEach(toolbar => {

View File

@ -458,6 +458,7 @@ const Settings = {
'face': tl('menu.paste.face'),
'mesh_selection': tl('menu.paste.mesh_selection'),
}});
new Setting('stretch_linked',{category: 'edit', value: true});
//Grid
new Setting('base_grid', {category: 'grid', value: true,});

View File

@ -241,6 +241,7 @@ new Property(ModelFormat, 'boolean', 'animated_textures');
new Property(ModelFormat, 'boolean', 'bone_rig');
new Property(ModelFormat, 'boolean', 'centered_grid');
new Property(ModelFormat, 'boolean', 'rotate_cubes');
new Property(ModelFormat, 'boolean', 'stretch_cubes');
new Property(ModelFormat, 'boolean', 'integer_size');
new Property(ModelFormat, 'boolean', 'meshes');
new Property(ModelFormat, 'boolean', 'texture_meshes');

View File

@ -168,14 +168,18 @@ var codec = new Codec('collada', {
);
}
addPosition(cube.to[0] + cube.inflate, cube.to[1] + cube.inflate, cube.to[2] + cube.inflate);
addPosition(cube.to[0] + cube.inflate, cube.to[1] + cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.to[0] + cube.inflate, cube.from[1] - cube.inflate, cube.to[2] + cube.inflate);
addPosition(cube.to[0] + cube.inflate, cube.from[1] - cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.to[1] + cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.to[1] + cube.inflate, cube.to[2] + cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.from[1] - cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.from[1] - cube.inflate, cube.to[2] + cube.inflate);
var adjustedFrom = cube.from.slice();
var adjustedTo = cube.to.slice();
adjustFromAndToForInflateAndStretch(adjustedFrom, adjustedTo, cube);
addPosition(adjustedTo[0], adjustedTo[1], adjustedTo[2] );
addPosition(adjustedTo[0], adjustedTo[1], adjustedFrom[2]);
addPosition(adjustedTo[0], adjustedFrom[1], adjustedTo[2] );
addPosition(adjustedTo[0], adjustedFrom[1], adjustedFrom[2]);
addPosition(adjustedFrom[0], adjustedTo[1], adjustedFrom[2]);
addPosition(adjustedFrom[0], adjustedTo[1], adjustedTo[2] );
addPosition(adjustedFrom[0], adjustedFrom[1], adjustedFrom[2]);
addPosition(adjustedFrom[0], adjustedFrom[1], adjustedTo[2] );
for (let fkey in cube.faces) {
let face = cube.faces[fkey];

View File

@ -384,14 +384,18 @@ var codec = new Codec('fbx', {
);
}
addPosition(cube.to[0] + cube.inflate, cube.to[1] + cube.inflate, cube.to[2] + cube.inflate);
addPosition(cube.to[0] + cube.inflate, cube.to[1] + cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.to[0] + cube.inflate, cube.from[1] - cube.inflate, cube.to[2] + cube.inflate);
addPosition(cube.to[0] + cube.inflate, cube.from[1] - cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.to[1] + cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.to[1] + cube.inflate, cube.to[2] + cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.from[1] - cube.inflate, cube.from[2] - cube.inflate);
addPosition(cube.from[0] - cube.inflate, cube.from[1] - cube.inflate, cube.to[2] + cube.inflate);
var adjustedFrom = cube.from.slice();
var adjustedTo = cube.to.slice();
adjustFromAndToForInflateAndStretch(adjustedFrom, adjustedTo, cube);
addPosition(adjustedTo[0], adjustedTo[1], adjustedTo[2] );
addPosition(adjustedTo[0], adjustedTo[1], adjustedFrom[2]);
addPosition(adjustedTo[0], adjustedFrom[1], adjustedTo[2] );
addPosition(adjustedTo[0], adjustedFrom[1], adjustedFrom[2]);
addPosition(adjustedFrom[0], adjustedTo[1], adjustedFrom[2]);
addPosition(adjustedFrom[0], adjustedTo[1], adjustedTo[2] );
addPosition(adjustedFrom[0], adjustedFrom[1], adjustedFrom[2]);
addPosition(adjustedFrom[0], adjustedFrom[1], adjustedTo[2] );
let textures = [];

View File

@ -69,6 +69,12 @@ function updateNslideValues() {
BarItems.slider_inflate.update()
}
if (Condition(BarItems.slider_stretch_x)) {
BarItems.slider_stretch_x.update()
BarItems.slider_stretch_y.update()
BarItems.slider_stretch_z.update()
}
if (Condition(BarItems.slider_face_tint)) {
BarItems.slider_face_tint.update()
}

View File

@ -748,15 +748,22 @@ BARS.defineActions(function() {
rotation: cube.rotation,
vertices: []
})
var adjustedFrom = cube.from.slice();
var adjustedTo = cube.to.slice();
adjustFromAndToForInflateAndStretch(adjustedFrom, adjustedTo, cube);
for (let i = 0; i < adjustedFrom.length; i++) {
adjustedFrom[i] - cube.origin[i];
adjustedTo[i] - cube.origin[i]
}
let vertex_keys = [
mesh.addVertices([cube.to[0] + cube.inflate - cube.origin[0], cube.to[1] + cube.inflate - cube.origin[1], cube.to[2] + cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.to[0] + cube.inflate - cube.origin[0], cube.to[1] + cube.inflate - cube.origin[1], cube.from[2] - cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.to[0] + cube.inflate - cube.origin[0], cube.from[1] - cube.inflate - cube.origin[1], cube.to[2] + cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.to[0] + cube.inflate - cube.origin[0], cube.from[1] - cube.inflate - cube.origin[1], cube.from[2] - cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.from[0] - cube.inflate - cube.origin[0], cube.to[1] + cube.inflate - cube.origin[1], cube.to[2] + cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.from[0] - cube.inflate - cube.origin[0], cube.to[1] + cube.inflate - cube.origin[1], cube.from[2] - cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.from[0] - cube.inflate - cube.origin[0], cube.from[1] - cube.inflate - cube.origin[1], cube.to[2] + cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([cube.from[0] - cube.inflate - cube.origin[0], cube.from[1] - cube.inflate - cube.origin[1], cube.from[2] - cube.inflate - cube.origin[2]] )[0],
mesh.addVertices([adjustedTo[0], adjustedTo[1], adjustedTo[2] ])[0],
mesh.addVertices([adjustedTo[0], adjustedTo[1], adjustedFrom[2] ])[0],
mesh.addVertices([adjustedTo[0], adjustedFrom[1], adjustedTo[2] ])[0],
mesh.addVertices([adjustedTo[0], adjustedFrom[1], adjustedFrom[2] ])[0],
mesh.addVertices([adjustedFrom[0], adjustedTo[1], adjustedTo[2] ])[0],
mesh.addVertices([adjustedFrom[0], adjustedTo[1], adjustedFrom[2] ])[0],
mesh.addVertices([adjustedFrom[0], adjustedFrom[1], adjustedTo[2] ])[0],
mesh.addVertices([adjustedFrom[0], adjustedFrom[1], adjustedFrom[2] ])[0],
];
let unused_vkeys = vertex_keys.slice();

View File

@ -1199,6 +1199,109 @@ BARS.defineActions(function() {
}
})
//Stretch
new NumSlider('slider_stretch_x', {
name: tl('action.slider_stretch', ['X']),
description: tl('action.slider_stretch.desc', ['X']),
color: 'x',
category: 'transform',
condition: function() {return Format.stretch_cubes && Cube.selected.length && Modes.edit},
getInterval: getSpatialInterval,
get: function() {
return Cube.selected[0].stretch[0]
},
change: function(modify) {
Cube.selected.forEach(function(obj, i) {
let v_before = obj.stretch[0];
var v = modify(obj.stretch[0]);
if (settings.stretch_linked.value === true) {
obj.stretch.forEach(function (stretch, axis) {
obj.stretch[axis] = v;
});
} else {
obj.stretch[0] = v;
}
})
Canvas.updatePositions()
},
onBefore: function() {
Undo.initEdit({elements: Cube.selected})
},
onAfter: function() {
Undo.finishEdit('Stretch elements')
}
})
new NumSlider('slider_stretch_y', {
name: tl('action.slider_stretch', ['Y']),
description: tl('action.slider_stretch.desc', ['Y']),
color: 'y',
category: 'transform',
condition: function() {return Format.stretch_cubes && Cube.selected.length && Modes.edit},
getInterval: getSpatialInterval,
get: function() {
return Cube.selected[0].stretch[1]
},
change: function(modify) {
Cube.selected.forEach(function(obj, i) {
let v_before = obj.stretch[1];
var v = modify(obj.stretch[1]);
if (settings.stretch_linked.value === true) {
obj.stretch.forEach(function (stretch, axis) {
obj.stretch[axis] = v;
});
} else {
obj.stretch[1] = v;
}
})
Canvas.updatePositions()
},
onBefore: function() {
Undo.initEdit({elements: Cube.selected})
},
onAfter: function() {
Undo.finishEdit('Stretch elements')
}
})
new NumSlider('slider_stretch_z', {
name: tl('action.slider_stretch', ['Z']),
description: tl('action.slider_stretch.desc', ['Z']),
color: 'z',
category: 'transform',
condition: function() {return Format.stretch_cubes && Cube.selected.length && Modes.edit},
getInterval: getSpatialInterval,
get: function() {
return Cube.selected[0].stretch[2]
},
change: function(modify) {
Cube.selected.forEach(function(obj, i) {
let v_before = obj.stretch[2];
var v = modify(obj.stretch[2]);
if (settings.stretch_linked.value === true) {
obj.stretch.forEach(function (stretch, axis) {
obj.stretch[axis] = v;
});
} else {
obj.stretch[2] = v;
}
})
Canvas.updatePositions()
},
onBefore: function() {
Undo.initEdit({elements: Cube.selected})
},
onAfter: function() {
Undo.finishEdit('Stretch elements')
}
})
let slider_vector_stretch = [BarItems.slider_stretch_x, BarItems.slider_stretch_y, BarItems.slider_stretch_z];
slider_vector_stretch.forEach(slider => slider.slider_vector = slider_vector_stretch);
//Rotation
new NumSlider('slider_rotation_x', {
name: tl('action.slider_rotation', ['X']),
@ -1648,6 +1751,12 @@ BARS.defineActions(function() {
}
}
})
new Toggle('toggle_stretch_linked', {
icon: 'fas.fa-link',
category: 'transform',
linked_setting: 'stretch_linked',
condition: () => Format.stretch_cubes && Cube.selected.length && Modes.edit
})
new Action('origin_to_geometry', {
icon: 'filter_center_focus',
category: 'transform',

View File

@ -76,6 +76,7 @@ class Cube extends OutlinerElement {
this.color = Math.floor(Math.random()*markerColors.length)
this.uv_offset = [0,0]
this.inflate = 0;
this.stretch = [1, 1, 1];
this.rotation = [0, 0, 0];
this.origin = [0, 0, 0];
this.visibility = true;
@ -130,6 +131,11 @@ class Cube extends OutlinerElement {
Merge.number(this.uv_offset, object.uv_offset, 0)
Merge.number(this.uv_offset, object.uv_offset, 1)
}
if (object.stretch) {
Merge.number(this.stretch, object.stretch, 0)
Merge.number(this.stretch, object.stretch, 1)
Merge.number(this.stretch, object.stretch, 2)
}
if (typeof object.rotation === 'object' && object.rotation.constructor.name === 'Object') {
if (object.rotation.angle && object.rotation.axis) {
var axis = getAxisNumber(object.rotation.axis)
@ -258,6 +264,7 @@ class Cube extends OutlinerElement {
if (!this.shade) el.shade = false;
if (this.mirror_uv) el.mirror_uv = true;
if (this.inflate) el.inflate = this.inflate;
if (this.isStretched()) el.stretch = this.stretch;
if (!this.rotation.allEqual(0)) el.rotation = this.rotation;
el.origin = this.origin;
if (!this.uv_offset.allEqual(0)) el.uv_offset = this.uv_offset;
@ -499,15 +506,19 @@ class Cube extends OutlinerElement {
return pos;
}
getGlobalVertexPositions() {
var adjustedFrom = this.from.slice();
var adjustedTo = this.to.slice();
adjustFromAndToForInflateAndStretch(adjustedFrom, adjustedTo, this);
let vertices = [
[this.to[0] + this.inflate, this.to[1] + this.inflate, this.to[2] + this.inflate],
[this.to[0] + this.inflate, this.to[1] + this.inflate, this.from[2] - this.inflate],
[this.to[0] + this.inflate, this.from[1] - this.inflate, this.to[2] + this.inflate],
[this.to[0] + this.inflate, this.from[1] - this.inflate, this.from[2] - this.inflate],
[this.from[0] - this.inflate, this.to[1] + this.inflate, this.from[2] - this.inflate],
[this.from[0] - this.inflate, this.to[1] + this.inflate, this.to[2] + this.inflate],
[this.from[0] - this.inflate, this.from[1] - this.inflate, this.from[2] - this.inflate],
[this.from[0] - this.inflate, this.from[1] - this.inflate, this.to[2] + this.inflate],
[adjustedTo[0] , adjustedTo[1] , adjustedTo[2] ],
[adjustedTo[0] , adjustedTo[1] , adjustedFrom[2]],
[adjustedTo[0] , adjustedFrom[1], adjustedTo[2] ],
[adjustedTo[0] , adjustedFrom[1], adjustedFrom[2]],
[adjustedFrom[0], adjustedTo[1] , adjustedFrom[2]],
[adjustedFrom[0], adjustedTo[1] , adjustedTo[2] ],
[adjustedFrom[0], adjustedFrom[1], adjustedFrom[2]],
[adjustedFrom[0], adjustedFrom[1], adjustedTo[2] ],
];
let vec = new THREE.Vector3();
return vertices.map(coords => {
@ -796,6 +807,9 @@ class Cube extends OutlinerElement {
TickUpdates.selection = true;
return this;
}
isStretched() {
return !this.stretch.allEqual(1);
}
}
Cube.prototype.title = tl('data.cube');
Cube.prototype.type = 'cube';
@ -864,6 +878,22 @@ new Property(Cube, 'boolean', 'locked');
OutlinerElement.registerType(Cube, 'cube');
function adjustFromAndToForInflateAndStretch(from, to, element) {
var halfSize = element.size().slice();
halfSize.forEach((v, i) => {
halfSize[i] /= 2;
});
var center = [
element.from[0] + halfSize[0],
element.from[1] + halfSize[1],
element.from[2] + halfSize[2]
];
for (let i = 0; i < from.length; i++) {
from[i] = center[i] - (halfSize[i] + element.inflate) * element.stretch[i];
to[i] = center[i] + (halfSize[i] + element.inflate) * element.stretch[i];
}
}
new NodePreviewController(Cube, {
setup(element) {
@ -914,13 +944,14 @@ new NodePreviewController(Cube, {
if (element.resizable) {
let mesh = element.mesh;
var from = element.from.slice()
var to = element.to.slice()
adjustFromAndToForInflateAndStretch(from, to, element);
from.forEach((v, i) => {
from[i] -= element.inflate;
from[i] -= element.origin[i];
})
var to = element.to.slice()
to.forEach((v, i) => {
to[i] += element.inflate
to[i] -= element.origin[i];
if (from[i] === to[i]) {
to[i] += 0.001
@ -1142,9 +1173,8 @@ new NodePreviewController(Cube, {
var from = cube.from.slice();
var to = cube.to.slice();
if (cube.inflate) {
from[0] -= cube.inflate; from[1] -= cube.inflate; from[2] -= cube.inflate;
to[0] += cube.inflate; to[1] += cube.inflate; to[2] += cube.inflate;
if (cube.inflate || cube.isStretched()) {
adjustFromAndToForInflateAndStretch(from, to, cube);
}
var vertices = [];

View File

@ -1646,6 +1646,7 @@ Interface.definePanels(function() {
toolbars: [
Toolbars.element_position,
Toolbars.element_size,
Toolbars.element_stretch,
Toolbars.element_origin,
Toolbars.element_rotation,
]

View File

@ -1243,15 +1243,19 @@ class Preview {
}
} else if (element instanceof Cube && (selection_mode == 'object' || !Format.meshes || !scope.selection.old_selected.find(el => el instanceof Mesh))) {
var adjustedFrom = element.from.slice();
var adjustedTo = element.to.slice();
adjustFromAndToForInflateAndStretch(adjustedFrom, adjustedTo, element);
let vertices = [
[element.from[0] - element.inflate, element.from[1] - element.inflate, element.from[2] - element.inflate],
[element.from[0] - element.inflate, element.from[1] - element.inflate, element.to[2] + element.inflate],
[element.from[0] - element.inflate, element.to[1] + element.inflate, element.to[2] + element.inflate],
[element.from[0] - element.inflate, element.to[1] + element.inflate, element.from[2] - element.inflate],
[element.to[0] + element.inflate, element.from[1] - element.inflate, element.from[2] - element.inflate],
[element.to[0] + element.inflate, element.from[1] - element.inflate, element.to[2] + element.inflate],
[element.to[0] + element.inflate, element.to[1] + element.inflate, element.to[2] + element.inflate],
[element.to[0] + element.inflate, element.to[1] + element.inflate, element.from[2] - element.inflate],
[adjustedFrom[0] , adjustedFrom[1] , adjustedFrom[2] ],
[adjustedFrom[0] , adjustedFrom[1] , adjustedTo[2] ],
[adjustedFrom[0] , adjustedTo[1] , adjustedTo[2] ],
[adjustedFrom[0] , adjustedTo[1] , adjustedFrom[2] ],
[adjustedTo[0] , adjustedFrom[1] , adjustedFrom[2] ],
[adjustedTo[0] , adjustedFrom[1] , adjustedTo[2] ],
[adjustedTo[0] , adjustedTo[1] , adjustedTo[2] ],
[adjustedTo[0] , adjustedTo[1] , adjustedFrom[2] ],
].map(coords => {
coords.V3_subtract(element.origin);
vector.fromArray(coords);

View File

@ -167,7 +167,7 @@ new ValidatorCheck('box_uv', {
Cube.all.forEach(cube => {
if (!cube.box_uv) return;
let size = cube.size();
let invalid_size_axes = size.filter(value => value < 0.999 && (value+cube.inflate*2) > 0.005);
let invalid_size_axes = size.filter((value, axis) => value < 0.999 && (value+cube.inflate*2) * cube.stretch[axis] > 0.005);
if (invalid_size_axes.length) {
let buttons = [
{

File diff suppressed because one or more lines are too long

View File

@ -111,6 +111,9 @@
"slider_size_y": null,
"slider_size_z": null,
"slider_inflate": null,
"slider_stretch_x": null,
"slider_stretch_y": null,
"slider_stretch_z": null,
"slider_rotation_x": null,
"slider_rotation_y": null,
"slider_rotation_z": null,

View File

@ -95,6 +95,9 @@
"slider_size_y": null,
"slider_size_z": null,
"slider_inflate": null,
"slider_stretch_x": null,
"slider_stretch_y": null,
"slider_stretch_z": null,
"slider_rotation_x": null,
"slider_rotation_y": null,
"slider_rotation_z": null,

View File

@ -95,6 +95,9 @@
"slider_size_y": null,
"slider_size_z": null,
"slider_inflate": null,
"slider_stretch_x": null,
"slider_stretch_y": null,
"slider_stretch_z": null,
"slider_rotation_x": null,
"slider_rotation_y": null,
"slider_rotation_z": null,

View File

@ -821,6 +821,8 @@
"settings.timecode_frame_number.desc": "Display fraction timecodes in the timeline as frame number instead of centisecond",
"settings.only_selected_bezier_handles": "Show Only Selected Bézier Handles",
"settings.only_selected_bezier_handles.desc": "Hide handles of bézier keyframes that are not currently selected",
"settings.stretch_linked": "Link Stretching",
"settings.stretch_linked.desc": "Stretch the cube in all directions with the same value",
"settings.base_grid": "Small Grid",
"settings.base_grid.desc": "Show small grid and axes",
@ -977,6 +979,8 @@
"action.slider_size.desc": "Resize elements on the %0 axis",
"action.slider_inflate": "Inflate",
"action.slider_inflate.desc": "Inflate cubes in all directions without changing the UV",
"action.slider_stretch": "Stretch",
"action.slider_stretch.desc": "Stretches cubes multiplicatively on the %0 axis without changing the UV",
"action.slider_rotation": "Rotation %0",
"action.slider_rotation.desc": "Rotate elements on the %0 axis",
"action.slider_origin": "Pivot %0",
@ -1923,6 +1927,7 @@
"panel.element": "Element",
"panel.element.position": "Position",
"panel.element.size": "Size",
"panel.element.stretch": "Stretch",
"panel.element.origin": "Pivot Point",
"panel.element.rotation": "Rotation",