diff --git a/js/desktop.js b/js/desktop.js index 33d6e979..2a270f15 100644 --- a/js/desktop.js +++ b/js/desktop.js @@ -289,20 +289,25 @@ function selectImageEditorFile(texture) { } //Default Pack function openDefaultTexturePath() { + let detail = tl('message.default_textures.detail'); + if (settings.default_path.value) { + detail += '\n\n' + tl('message.default_textures.current') + ': ' + settings.default_path.value; + } + let buttons = ( + settings.default_path.value ? [tl('dialog.continue'), tl('generic.remove'), tl('dialog.cancel')] + : [tl('dialog.continue'), tl('dialog.cancel')] + ) var answer = electron.dialog.showMessageBoxSync(currentwindow, { type: 'info', - buttons: ( - settings.default_path.value ? [tl('dialog.cancel'), tl('dialog.continue'), tl('generic.remove')] - : [tl('dialog.cancel'), tl('dialog.continue')] - ), + buttons, noLink: true, title: tl('message.default_textures.title'), message: tl('message.default_textures.message'), - detail: tl('message.default_textures.detail'), + detail }) - if (answer === 0) { + if (answer === buttons.length-1) { return; - } else if (answer === 1) { + } else if (answer === 0) { let path = Blockbench.pickDirectory({ title: tl('message.default_textures.select'), @@ -310,9 +315,11 @@ function openDefaultTexturePath() { }); if (path) { settings.default_path.value = path; + Settings.saveLocalStorages(); } } else { - settings.default_path.value = false + settings.default_path.value = false; + Settings.saveLocalStorages(); } } function findExistingFile(paths) { diff --git a/js/interface/dialog.js b/js/interface/dialog.js index 568cc845..1c33175d 100644 --- a/js/interface/dialog.js +++ b/js/interface/dialog.js @@ -73,7 +73,7 @@ function buildForm(dialog) { let this_input_element = input_element; this_bar.find('.password_toggle').on('click', e => { hidden = !hidden; - this_input_element.attr('type', hidden ? 'password' : 'text'); + this_input_element.attributes.type.value = hidden ? 'password' : 'text'; this_bar.find('.password_toggle i')[0].className = hidden ? 'fas fa-eye-slash' : 'fas fa-eye'; }) } diff --git a/js/interface/settings.js b/js/interface/settings.js index 4a9d4698..68b9d13e 100644 --- a/js/interface/settings.js +++ b/js/interface/settings.js @@ -336,7 +336,6 @@ const Settings = { function hasSettingChanged(id) { return (settings[id].value !== Settings.old[id]) } - hideDialog() updateSelection() for (var key in BarItems) { diff --git a/js/outliner/mesh.js b/js/outliner/mesh.js index e1b66e79..08d9d9c4 100644 --- a/js/outliner/mesh.js +++ b/js/outliner/mesh.js @@ -1090,11 +1090,41 @@ BARS.defineActions(function() { selected_face_keys.push(key); } } - let direction = selected_faces[0] && selected_faces[0].vertices.length > 2 && selected_faces[0].getNormal(true); - if (!direction) direction = [0, 1, 0]; new_vertices = mesh.addVertices(...original_vertices.map(key => { let vector = mesh.vertices[key].slice(); + let direction; + let count = 0; + selected_faces.forEach(face => { + if (face.vertices.includes(key)) { + count++; + if (!direction) { + direction = face.getNormal(true); + } else { + direction.V3_add(face.getNormal(true)); + } + } + }) + if (count > 1) { + direction.V3_divide(count); + } + if (!direction) { + let match; + let match_level = 0; + for (let key in mesh.faces) { + let face = mesh.faces[key]; + let matches = face.vertices.filter(vkey => original_vertices.includes(vkey)); + if (match_level < matches.length) { + match_level = matches.length; + match = face; + } + if (match_level == 3) break; + } + if (match) { + direction = match.getNormal(true); + } + } + vector.V3_add(direction); return vector; })) diff --git a/js/preview/canvas.js b/js/preview/canvas.js index bcddb50b..b6728cb9 100644 --- a/js/preview/canvas.js +++ b/js/preview/canvas.js @@ -328,11 +328,13 @@ const Canvas = { }, updateRenderSides() { var side = Canvas.getRenderSide(); - Texture.all.forEach(function(t) { - var mat = Project.materials[t.uuid] - if (mat) { - mat.side = side - } + ModelProject.all.forEach(project => { + project.textures.forEach(function(t) { + var mat = Project.materials[t.uuid] + if (mat) { + mat.side = side + } + }) }) if (Canvas.layered_material) { Canvas.layered_material.side = side; diff --git a/lang/en.json b/lang/en.json index d8bb9596..7491ccd6 100644 --- a/lang/en.json +++ b/lang/en.json @@ -194,6 +194,7 @@ "message.default_textures.title": "Default Textures", "message.default_textures.message": "Select the \"textures\"-folder of the default resource pack", "message.default_textures.detail": "Extract the default resource pack from the Minecraft jar or google and download it. Then locate the \"textures\" folder and open it. Blockbench will remember that location and try to fetch textures from there if it can't find them in the current resource pack.", + "message.default_textures.current": "Current path", "message.default_textures.select": "Select default \"textures\"-folder", "message.square_textures": "Textures have to be square", "message.unsaved_texture.title": "Unsaved Texture", @@ -673,7 +674,7 @@ "settings.credit.desc": "Add a credit comment to exported files", "settings.sketchfab_token": "Sketchfab Token", "settings.sketchfab_token.desc": "Token to authorize Blockbench to upload to your Sketchfab account", - "settings.default_path": "Default Path", + "settings.default_path": "Default Minecraft Textures Path", "settings.default_path.desc": "Folder from where Blockbench loads default textures", "settings.recent_projects": "Recent Model Cap", @@ -917,6 +918,8 @@ "action.add_locator.desc": "Adds a new locator to control positions of particles, leashes etc", "action.add_null_object": "Add Null Object", "action.add_null_object.desc": "Adds a new null object", + "action.add_texture_mesh": "Add Texture Mesh", + "action.add_texture_mesh.desc": "Adds a new Texture Mesh", "action.add_group": "Add Group", "action.add_group.desc": "Adds a new group or bone", "action.group_elements": "Group Elements",