This commit is contained in:
JannisX11 2019-07-26 13:33:29 +02:00
parent ae6a2614b4
commit fd3085b8fa
26 changed files with 139 additions and 71 deletions

View File

@ -1,5 +1,5 @@
[!] Before you report an issue, check if if has already been reported. Also check if you are using the latest version of Blockbench.
[!] Prefix the title if your issue with [Issue] or [Suggestion]
[!] Prefix the title of your issue with [Issue] or [Suggestion]
[!] If you are having an issue, please press "Ctrl + Shift + i" and click on console. If there are any error messages, please attach a screenshot of it to your issue.
Supply the following information:

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/dist/
index.php
package-lock.json

View File

@ -2,7 +2,7 @@
/*Layout*/
#page_wrapper {
display: grid;
grid-template-columns: 332px auto 300px;
grid-template-columns: 332px auto 314px;
grid-template-rows: 30px minmax(200px, 5000px) 26px;
grid-template-areas:
"left_bar toolbar toolbar"

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#181a1f">
<meta name="robots" content="noindex">
<link rel="manifest" href="manifest.json">
<!--link rel="manifest" href="manifest.json"-->
<link rel="shortcut icon" href="favicon.png" type="image/x-icon" />
<link rel="stylesheet" href="css/w3.css">
<link rel="stylesheet" href="css/jquery-ui.min.css">
@ -27,7 +27,7 @@
<script>
if (typeof module === 'object') {window.module = module; module = undefined;}//jQuery Fix
const isApp = typeof require !== 'undefined';
const appVersion = '3.0.3';
const appVersion = '3.0.4';
</script>
<script src="lib/vue.min.js"></script>
<script src="lib/vue_sortable.js"></script>
@ -1036,7 +1036,7 @@
<left>
<h2 class="tl">mode.start.new</h2>
<ul>
<li v-for="format in formats" v-if="format.allow_new" v-on:click="newProject(format)">
<li v-for="format in formats" v-if="format.show_on_start_screen" v-on:click="format.new()">
<span class="icon_wrapper f_left" v-html="Blockbench.getIconNode(format.icon).outerHTML"></span>
<h3>{{ format.name }}</h3>
<p>{{ format.description }}</p>

View File

@ -1268,10 +1268,10 @@ Molang.global_variables = {
get 'query.anim_time'() {
return Timeline.second;
},
get 'global.anim_time'() {
get 'query.life_time'() {
return Timeline.second;
},
get 'query.life_time'() {
get 'time'() {
return Timeline.second;
}
}

View File

@ -222,7 +222,8 @@ function updateSelection() {
$('.selection_only').css('visibility', 'visible')
} else {
if (Format.bone_rig && Group.selected) {
$('.selection_only').css('visibility', 'visible')
$('.selection_only').css('visibility', 'hidden')
$('.selection_only#element').css('visibility', 'visible')
} else {
$('.selection_only').css('visibility', 'hidden')
if (Locator.selected.length) {
@ -697,7 +698,7 @@ const Clipbench = {
var img = clipboard.readImage()
if (img) {
var dataUrl = img.toDataURL()
var texture = new Texture({name: 'pasted', folder: 'blocks' }).fromDataURL(dataUrl).fillParticle().add(true)
var texture = new Texture({name: 'pasted', folder: 'block' }).fromDataURL(dataUrl).fillParticle().add(true)
setTimeout(function() {
texture.openMenu()
},40)

View File

@ -282,7 +282,7 @@ EditSession.Client = class {
this.conn.close()
console.error(e)
})
Blockbench.dispatchEvent('user_joins_session', {conn: this.conn})
Blockbench.dispatchEvent('user_joins_session', this)
}
}
send(tag) {

View File

@ -1379,7 +1379,7 @@ const BARS = {
default_place: !Blockbench.isMobile
})
//3.0.3 update
if (Toolbars.element_size.children.includes(BarItems.slider_inflate)) {
if (!Toolbars.element_size.children.includes(BarItems.slider_inflate)) {
Toolbars.element_size.add(BarItems.slider_inflate, -1);
}
Toolbars.element_origin = new Toolbar({

View File

@ -168,7 +168,7 @@ class ResizeLine {
var Interface = {
default_data: {
left_bar_width: 332,
right_bar_width: 300,
right_bar_width: 314,
quad_view_x: 50,
quad_view_y: 50,
left_bar: ['uv', 'textures', 'display', 'animations', 'keyframe', 'variable_placeholders'],
@ -180,7 +180,7 @@ var Interface = {
condition: function() {
var i = 0;
Interface.data.left_bar.forEach(p => {
if (BARS.condition(Interface.Panels[p].condition)) {i++;}
if (Interface.Panels[p] && BARS.condition(Interface.Panels[p].condition)) {i++;}
})
return i;
},

View File

@ -359,7 +359,7 @@ const MenuBar = {
icon: format.icon,
description: format.description,
click: (e) => {
newProject(format)
format.new()
}
})
})()

View File

@ -262,7 +262,7 @@ var codec = new Codec('bedrock', {
var bones = []
var visible_box = new THREE.Box3()
var groups = Group.all.slice()
var groups = getAllGroups();
var loose_cubes = [];
Outliner.root.forEach(obj => {
if (obj.type === 'cube') {

View File

@ -81,6 +81,13 @@ function parseGeometry(data) {
cg.addTo(group)
})
}
if (b.locators) {
for (var key in b.locators) {
var coords = b.locators[key];
coords[0] *= -1
var locator = new Locator({from: coords, name: key}).addTo(group).init();
}
}
var parent_group = 'root';
if (b.parent) {
if (bones[b.parent]) {
@ -122,7 +129,7 @@ var codec = new Codec('bedrock_old', {
var cube_count = 0;
var visible_box = new THREE.Box3()
var groups = Group.all.slice()
var groups = getAllGroups();
var loose_cubes = [];
Outliner.root.forEach(obj => {
if (obj.type === 'cube') {
@ -167,6 +174,7 @@ var codec = new Codec('bedrock_old', {
}
//Cubes
var cubes = []
var locators = {};
for (var obj of g.children) {
if (obj.export) {
@ -191,12 +199,19 @@ var codec = new Codec('bedrock_old', {
cubes.push(cube)
cube_count++;
} else if (obj instanceof Locator) {
locators[obj.name] = obj.from.slice();
locators[obj.name][0] *= -1;
}
}
}
if (cubes.length) {
bone.cubes = cubes
}
if (Object.keys(locators).length) {
bone.locators = locators
}
bones.push(bone)
})
@ -477,11 +492,12 @@ var format = new ModelFormat({
id: 'bedrock_old',
extension: 'json',
icon: 'icon-format_bedrock',
allow_new: false,
show_on_start_screen: false,
box_uv: true,
single_texture: true,
bone_rig: true,
animation_mode: true,
locators: true,
codec,
onActivation: function () {

View File

@ -22,7 +22,7 @@ class ModelFormat {
this.id = data.id;
this.name = tl('format.'+this.id);
this.description = tl('format.'+this.id+'.desc');
this.allow_new = true;
this.show_on_start_screen = true;
this.box_uv = false;
this.optional_box_uv = false;
@ -40,7 +40,7 @@ class ModelFormat {
this.onActivation = data.onActivation;
this.onDeactivation = data.onDeactivation;
Merge.string(this, data, 'icon');
Merge.boolean(this, data, 'allow_new');
Merge.boolean(this, data, 'show_on_start_screen');
Merge.boolean(this, data, 'box_uv');
Merge.boolean(this, data, 'optional_box_uv');
@ -72,17 +72,22 @@ class ModelFormat {
} else {
scene.position.set(-8, -8, -8);
}
/*
var center = Format.bone_rig ? -8 : 0;
var center = Format.bone_rig ? 8 : 0;
previews.forEach(preview => {
preview.controls.target.set(center, -3, center);
preview.controls.target.set(0, center, 0);
preview.camOrtho.position.add(preview.controls.target);
})*/
BARS.updateConditions()
})
updateSelection()
Modes.vue.$forceUpdate()
Canvas.updateRenderSides()
return this;
}
new() {
if (newProject(this)) {
BarItems.project_window.click();
return true;
}
}
convertTo() {
Undo.history.length = 0;
@ -278,12 +283,7 @@ class Codec {
}
afterSave(path) {
var name = pathToName(path, true)
if (this.remember) {
addRecentProject({
name,
path: path,
icon: this.id == 'project' ? 'icon-blockbench_file' : Format.icon
});
if (Format.codec == this || this.id == 'project') {
if (this.id == 'project') {
ModelMeta.save_path = path;
} else {
@ -292,6 +292,13 @@ class Codec {
ModelMeta.name = pathToName(path, false);
Prop.project_saved = true;
}
if (this.remember) {
addRecentProject({
name,
path: path,
icon: this.id == 'project' ? 'icon-blockbench_file' : Format.icon
});
}
Blockbench.showQuickMessage(tl('message.save_file', [name]));
}
}
@ -387,7 +394,9 @@ function setupDragHandlers() {
)
}
function loadModelFile(file) {
if (newProject()) {
if (showSaveDialog()) {
resetProject();
var extension = pathToExtension(file.path);
var model = autoParseJSON(file.content);
if (extension == 'bbmodel') {
@ -827,7 +836,7 @@ BARS.defineActions(function() {
parent: {label: 'dialog.project.parent', value: Project.parent, condition: !Format.bone_rig},
geometry_name: {label: 'dialog.project.geoname', value: Project.geometry_name, condition: Format.bone_rig},
ambientocclusion: {label: 'dialog.project.ao', type: 'checkbox', value: Project.ambientocclusion, condition: !Format.bone_rig},
box_uv: {label: 'dialog.project.box_uv', type: 'checkbox', value: Project.box_uv},
box_uv: {label: 'dialog.project.box_uv', type: 'checkbox', value: Project.box_uv, condition: Format.optional_box_uv},
texture_width: {
label: 'dialog.project.width',
type: 'number',
@ -851,8 +860,9 @@ BARS.defineActions(function() {
save = Undo.initEdit({uv_mode: true})
Project.texture_width = formResult.texture_width;
Project.texture_height = formResult.texture_height;
Project.box_uv = formResult.box_uv;
if (Format.optional_box_uv) Project.box_uv = formResult.box_uv;
Canvas.updateAllUVs()
updateSelection()
}
Project.name = formResult.name;

View File

@ -15,7 +15,7 @@ var codec = new Codec('modded_entity', {
var bone_nr = 1
var model_id = Project.geometry_name;
var all_groups = Group.all.slice()
var all_groups = getAllGroups()
var renderers = {}
var loose_cubes = []

View File

@ -264,6 +264,7 @@ class Cube extends NonGroup {
}
}
copy.uuid = this.uuid
copy.type = this.type;
delete copy.parent;
return copy;
}
@ -702,11 +703,15 @@ class Cube extends NonGroup {
var pos = limitToBox(val + this.from[axis] + before);
if (pos >= this.from[axis] || settings.negative_size.value || allow_negative) {
this.to[axis] = pos;
} else {
this.to[axis] = this.from[axis];
}
} else {
var pos = limitToBox(val + this.to[axis] - before);
if (pos <= this.to[axis] || settings.negative_size.value || allow_negative) {
this.from[axis] = pos;
} else {
this.from[axis] = this.to[axis];
}
}
this.mapAutoUV();
@ -739,7 +744,7 @@ class Cube extends NonGroup {
{icon: 'bubble_chart', color: cubeColors[6].hex, name: 'cube.color.'+cubeColors[6].name, click: function(cube) {cube.forSelected(function(obj){obj.setColor(6)}, 'change color')}},
{icon: 'bubble_chart', color: cubeColors[7].hex, name: 'cube.color.'+cubeColors[7].name, click: function(cube) {cube.forSelected(function(obj){obj.setColor(7)}, 'change color')}}
]},
{name: 'menu.cube.texture', icon: 'collections', condition: function() {return !Project.box_uv}, children: function() {
{name: 'menu.cube.texture', icon: 'collections', condition: () => !Project.single_texture, children: function() {
var arr = [
{icon: 'crop_square', name: 'menu.cube.texture.blank', click: function(cube) {
cube.forSelected(function(obj) {

View File

@ -445,6 +445,19 @@ function getCurrentGroup() {
}
}
}
function getAllGroups() {
var ta = []
function iterate(array) {
for (var obj of array) {
if (obj instanceof Group) {
ta.push(obj)
iterate(obj.children)
}
}
}
iterate(Outliner.root)
return ta;
}
function addGroup() {
Undo.initEdit({outliner: true});
var add_group = Group.selected
@ -460,12 +473,11 @@ function addGroup() {
if (Format.bone_rig) {
base_group.createUniqueName()
}
selected.forEach(function(s, i) {
s.addTo(base_group)
if (i === 0) {
//s.selected = false
}
})
if (add_group instanceof NonGroup) {
selected.forEach(function(s, i) {
s.addTo(base_group)
})
}
base_group.init().select()
Undo.finishEdit('add_group');
loadOutlinerDraggable()

View File

@ -23,6 +23,7 @@ class Locator extends NonGroup {
getUndoCopy() {
var copy = new Locator(this)
copy.uuid = this.uuid
copy.type = this.type;
delete copy.parent;
return copy;
}

View File

@ -507,7 +507,7 @@ const Painter = {
form: {
name: {label: 'dialog.create_texture.name', value: 'texture'},
folder: {label: 'dialog.create_texture.folder'},
entity_template:{label: 'dialog.create_texture.template', type: 'checkbox', condition: elements.length},
entity_template:{label: 'dialog.create_texture.template', type: 'checkbox', condition: Cube.all.length},
compress: {label: 'dialog.create_texture.compress', type: 'checkbox', value: true},
power: {label: 'dialog.create_texture.power', type: 'checkbox', value: true},
double_use: {label: 'dialog.create_texture.double_use', type: 'checkbox', value: true, condition: Project.box_uv},
@ -548,7 +548,7 @@ const Painter = {
keep_size: true,
res: options.resolution,
name: options.name ? options.name : 'texture',
folder: options.folder ? options.folder : 'blocks'
folder: options.folder ? options.folder : 'block'
})
function makeTexture(dataUrl) {
texture.fromDataURL(dataUrl).add(false)
@ -571,9 +571,9 @@ const Painter = {
if (options.entity_template === true) {
Undo.initEdit({
textures: Format.single_texture ? textures : [],
elements: Format.single_texture ? elements : selected,
elements: Format.single_texture ? Cube.all : Cube.selected,
uv_only: true,
resolution: true
uv_mode: true
})
Painter.generateTemplate(options, makeTexture)
} else {
@ -615,7 +615,7 @@ const Painter = {
var extend_x = 0;
var extend_y = 0;
var avg_size = 0;
var cubes = Format.single_texture ? elements.slice() : selected.slice()
var cubes = Format.single_texture ? Cube.all.slice() : Cube.selected.slice()
var i = cubes.length-1
while (i >= 0) {
@ -706,7 +706,7 @@ const Painter = {
} else {
//OLD -------------------------------------------
var lines = [[]]
var line_length = Math.sqrt(elements.length/2)
var line_length = Math.sqrt(cubes.length/2)
avg_size /= templates.length
var o = 0
var i = 0
@ -856,6 +856,7 @@ const Painter = {
}
//Drawing
cl(templates.length)
templates.forEach(function(t) {
let obj = t.obj
@ -868,20 +869,22 @@ const Painter = {
drawTemplateRectangle(d.c1, d.c2, t.obj.faces[face], d.place(t))
}
}
obj.uv_offset[0] = t.posx
obj.uv_offset[1] = t.posy
obj.uv_offset[0] = t.posx;
obj.uv_offset[1] = t.posy;
if (t.duplicates) {
t.duplicates.forEach(t_2 => {
t_2.obj.uv_offset[0] = t.posx;
t_2.obj.uv_offset[1] = t.posy;
if (t_2.obj !== obj) {
t_2.obj.mirror_uv = t_2.obj.mirror_uv != obj.mirror_uv;
}
})
} else {
obj.mirror_uv = false
}
obj.mirror_uv = false;
if (!Project.box_uv) {
var size = obj.size(undefined, true)
var size = obj.size(undefined, true);
size.forEach((n, i) => {
size[i] = n || min_size;
})
@ -913,7 +916,14 @@ const Painter = {
t.obj.autouv = 0
})
}
Undo.finishEdit('create template', {textures: [texture], bitmap: true, elements: Format.single_texture ? elements : selected, uv_only: true})
updateSelection()
Undo.finishEdit('create template', {
textures: [texture],
bitmap: true,
elements: Format.single_texture ? Cube.all : Cube.selected,
uv_only: true,
uv_mode: true
})
}
}

View File

@ -74,6 +74,9 @@ THREE.OrbitControls = function ( object, preview ) {
scope.preview.updateBackground()
}
Transformer.update()
if (Toolbox && Toolbox.selected.id == 'vertex_snap_tool') {
Vertexsnap.updateVertexSize();
}
};
// this method is exposed, but perhaps it would be better if we can make it private...

View File

@ -45,7 +45,6 @@ class Preview {
this.controls = new THREE.OrbitControls(this.camPers, this);
this.controls.minDistance = 1;
this.controls.maxDistance = 320;
this.controls.target.set(0,-3,0);
this.controls.enableKeys = false;
this.controls.zoomSpeed = 1.5
@ -270,7 +269,7 @@ class Preview {
}
resetCamera(init) {
var dis = 24
this.controls.target.set(0, -3, 0);
this.controls.target.set(0, 8+scene.position.y, 0);
this.camPers.position.set(-dis, dis*0.8, -dis)
if (!init) {
this.setNormalCamera()

View File

@ -645,6 +645,7 @@
this.elements.length = 0
this.visible = false;
this.axis = null;
this.hoverAxis = null;
};
this.setMode = function ( mode ) {
if (mode === 'hidden') {
@ -703,8 +704,7 @@
object = Group.selected.parent.mesh
}
if (scope.elements.length == 0) {
this.visible = false;
return;
this.detach()
}
this.getWorldPosition(worldPosition)
this.setScale(this.getScale());
@ -721,6 +721,8 @@
scale = (6 / scope.camera.zoom) * (settings.origin_size.value / 50);
}
rot_origin.scale.set( scale, scale, scale );
if (scope.elements.length == 0) return;
if (object) {
worldRotation.setFromRotationMatrix( tempMatrix.extractRotation( object.matrixWorld ) );
@ -821,7 +823,7 @@
}
}
if (!rotation_object) {
this.visible = false;
this.detach();
return;
}
this.rotation_object = rotation_object;
@ -882,7 +884,7 @@
if ( intersect ) {
scope.hoverAxis = intersect.object.name;
if (scope.camera.axis && (scope.hoverAxis.toLowerCase() === scope.camera.axis) === (_mode !== 'rotate')) {
scope.hoverAxis = null
scope.hoverAxis = null;
}
event.preventDefault();
}

View File

@ -757,25 +757,25 @@ class Texture {
{
icon: 'crop_original',
name: 'menu.texture.face',
condition: function() {return !Project.box_uv && selected.length > 0},
condition() {return !Project.single_texture && selected.length > 0},
click: function(texture) {texture.apply()}
},
{
icon: 'texture',
name: 'menu.texture.blank',
condition: function() {return !Project.box_uv && selected.length > 0},
condition() {return !Project.single_texture && selected.length > 0},
click: function(texture) {texture.apply('blank')}
},
{
icon: 'fa-cube',
name: 'menu.texture.cube',
condition: function() {return !Project.box_uv && selected.length > 0},
condition() {return !Project.single_texture && selected.length > 0},
click: function(texture) {texture.apply(true)}
},
{
icon: 'bubble_chart',
name: 'menu.texture.particle',
condition: function() {return !Project.box_uv},
condition: function() {return Format.id == 'java_block'},
click: function(texture) {
if (texture.particle) {
texture.particle = false
@ -897,11 +897,13 @@ function loadTextureDraggable() {
var data = Canvas.getCurrentPreview().raycast()
if (data.cube && data.face) {
var tex = textures.findInArray('uuid', ui.helper.attr('texid'));
var cubes_list = data.cube.selected ? selected : [data.cube];
var cubes_list = data.cube.selected ? Cube.selected : [data.cube];
Undo.initEdit({elements: cubes_list})
if (tex) {
cubes_list.forEach(cube => {
cube.applyTexture(tex, [data.face])
if (cube instanceof Cube) {
cube.applyTexture(tex, [data.face])
}
})
}
Undo.finishEdit('apply texture')

View File

@ -376,7 +376,7 @@ const Vertexsnap = {
Vertexsnap.vertexes.children.forEach(function(v,i) {
var scaleVector = new THREE.Vector3();
var scale = scaleVector.subVectors(v.position, Transformer.camera.position).length() / 500;
scale = (Math.sqrt(scale) + scale/10) * 1.2
scale = (Math.sqrt(scale) + scale/4) * 1.2
v.scale.set(scale, scale, scale)
})
}

View File

@ -207,13 +207,13 @@ var Undo = {
new_element.faces[face].reset()
}
new_element.extend(element)
if (new_element instanceof Cube) {
if (new_element.type == 'cube') {
Canvas.adaptObjectPosition(new_element)
Canvas.adaptObjectFaces(new_element)
Canvas.updateUV(new_element)
}
} else {
new_element = new element.constructor(element, uuid).init()
new_element = NonGroup.fromSave(element, true);
}
}
}

View File

@ -483,7 +483,7 @@ class UVEditor {
this.jquery.viewport.width(size+8);
this.jquery.main.width(size+8);
if (Format.id === Format.single_texture) {
if (Format.single_texture) {
this.height = size / (Project.texture_width/Project.texture_height)
this.jquery.frame.height(this.inner_height)
this.jquery.viewport.height(this.height+8)
@ -829,7 +829,7 @@ class UVEditor {
}
//Overlay
displayMappingOverlay() {
if (!Project.box_uv) return this;
if (!Project.box_uv || Cube.selected.length == 0) return this;
var scope = this;
var sides = this.getMappingOverlay()
@ -1042,6 +1042,9 @@ class UVEditor {
left2 = limitNumber(obj.size('0'), 0, 16)
top2 = limitNumber(obj.size('2'), 0, 16)
}
if (obj.faces[side].rotation % 180) {
[left2, top2] = [top2, left2];
}
obj.faces[side].uv = [left, top, left2, top2]
})
obj.autouv = 0
@ -1341,6 +1344,7 @@ class UVEditor {
obj.faces[side].reset()
})
Canvas.adaptObjectFaces(obj)
Canvas.updateUV(obj)
})
this.loadData()
this.message('uv_editor.reset')

View File

@ -1,7 +1,7 @@
{
"name": "Blockbench",
"description": "Model editing and animation software",
"version": "3.0.3",
"version": "3.0.4",
"license": "MIT",
"author": {
"name": "JannisX11",