diff --git a/.travis.yml b/.travis.yml index b9f200e..045d2a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,20 +6,17 @@ node_js: "10" matrix: include: - - name: "macOS" + - name: "macOS + Win Portable" os: osx + script: + - electron-builder --publish=always + - electron-builder -w --x64 --publish=always - name: "Windows" os: osx - script: electron-builder -w --x64 --publish=always - - - name: "Windows 32" - os: osx - script: electron-builder -w --ia32 --publish=always -c.productName='Blockbench_32bit' - - - name: "Windows Portable" - os: osx - script: electron-builder --windows portable --x64 --publish=always -c.productName='Blockbench_portable' + script: + - electron-builder -w --x64 --publish=always + - electron-builder -w --ia32 --publish=always -c.productName='Blockbench_32bit' - name: "Linux" os: linux diff --git a/index.html b/index.html index ab6376d..c637448 100644 --- a/index.html +++ b/index.html @@ -28,7 +28,7 @@ diff --git a/js/api.js b/js/api.js index b02bffb..382bcb5 100644 --- a/js/api.js +++ b/js/api.js @@ -355,13 +355,17 @@ const Blockbench = { cb(results) } } - if (options.readtype === 'image') { + let readtype = options.readtype; + if (typeof readtype == 'function') { + readtype = readtype(file.name); + } + if (readtype === 'image') { if (pathToExtension(file.name) === 'tga') { reader.readAsArrayBuffer(file) } else { reader.readAsDataURL(file) } - } else if (options.readtype === 'buffer') { + } else if (readtype === 'buffer') { reader.readAsArrayBuffer(file) } else /*text*/ { reader.readAsText(file) @@ -384,8 +388,12 @@ const Blockbench = { (function() { var this_i = i; var file = paths[i] + let readtype = options.readtype; + if (typeof readtype == 'function') { + readtype = readtype(file); + } - if (options.readtype === 'image') { + if (readtype === 'image') { // var extension = pathToExtension(file) if (extension === 'tga') { @@ -427,7 +435,7 @@ const Blockbench = { errant = true return; } - if (options.readtype != 'buffer' && data.charCodeAt(0) === 0xFEFF) { + if (readtype != 'buffer' && data.charCodeAt(0) === 0xFEFF) { data = data.substr(1) } results[this_i] = { @@ -440,7 +448,7 @@ const Blockbench = { cb(results) } } - if (options.readtype === 'buffer') { + if (readtype === 'buffer') { fs.readFile(file, load); } else { fs.readFile(file, 'utf8', load); diff --git a/js/display_mode.js b/js/display_mode.js index b7f7c7a..b73332b 100644 --- a/js/display_mode.js +++ b/js/display_mode.js @@ -1453,7 +1453,7 @@ exitDisplaySettings = function() { //Enterung Display Setting Mode, changes the setDisplayArea(0,0,0, 0,0,0, 1,1,1) display_area.updateMatrixWorld() display_base.updateMatrixWorld() - lights.rotation.y = 0 + lights.rotation.set(0, 0, 0); display_mode = false; main_preview.fullscreen() diff --git a/js/interface/actions.js b/js/interface/actions.js index 6d20705..d7c570c 100644 --- a/js/interface/actions.js +++ b/js/interface/actions.js @@ -1325,8 +1325,8 @@ const BARS = { 'add_cube', 'add_group', 'outliner_toggle', - 'toggle_', - 'toggle_skin_layer' + 'toggle_skin_layer', + 'cube_counter' ], default_place: true }) @@ -1335,6 +1335,10 @@ const BARS = { if (!Toolbars.outliner.children.includes(BarItems.toggle_skin_layer)) { Toolbars.outliner.add(BarItems.toggle_skin_layer, -1) } + //update 3.3.1 + if (!Toolbars.outliner.children.includes(BarItems.cube_counter)) { + Toolbars.outliner.add(BarItems.cube_counter) + } Toolbars.texturelist = new Toolbar({ id: 'texturelist', @@ -1446,6 +1450,10 @@ const BARS = { ], default_place: true }) + //update 3.3.1 + if (!Toolbars.display.children.includes(BarItems.gui_light)) { + Toolbars.display.add(BarItems.gui_light) + } //UV Toolbars.main_uv = new Toolbar({ id: 'main_uv', diff --git a/js/interface/dialog.js b/js/interface/dialog.js index 1c3e70b..27187cc 100644 --- a/js/interface/dialog.js +++ b/js/interface/dialog.js @@ -145,8 +145,16 @@ function Dialog(settings) { case 'folder': bar.append('folder'); break; case 'save': bar.append('save'); break; } - + let remove_button = $('
clear
'); + bar.append(remove_button); + remove_button.on('click', e => { + e.stopPropagation(); + data.value = ''; + input.val(''); + }) + bar.on('click', e => { + cl(e.target); function fileCB(files) { data.value = files[0].path; input.val(data.value); diff --git a/js/io/java_block.js b/js/io/java_block.js index 153cbe5..b2599c6 100644 --- a/js/io/java_block.js +++ b/js/io/java_block.js @@ -179,9 +179,6 @@ var codec = new Codec('java_block', { if (checkExport('ambientocclusion', Project.ambientocclusion === false)) { blockmodel.ambientocclusion = false } - if (checkExport('front_gui_light', Project.front_gui_light)) { - blockmodel.gui_light = 'front'; - } if (Project.texture_width !== 16 || Project.texture_height !== 16) { blockmodel.texture_size = [Project.texture_width, Project.texture_height] } @@ -191,6 +188,9 @@ var codec = new Codec('java_block', { if (checkExport('elements', clear_elements.length >= 1)) { blockmodel.elements = clear_elements } + if (checkExport('front_gui_light', Project.front_gui_light)) { + blockmodel.gui_light = 'front'; + } if (checkExport('display', Object.keys(display).length >= 1)) { var new_display = {} var entries = 0; diff --git a/js/io/skin.js b/js/io/skin.js index 6e08463..04f51b6 100644 --- a/js/io/skin.js +++ b/js/io/skin.js @@ -240,25 +240,29 @@ const skin_dialog = new Dialog({ options: { steve: 'Steve', alex: 'Alex', - creeper: 'Creeper', - creeper: 'Creeper', armor_stand: 'Armor Stand', bat: 'Bat', bee: 'Bee', + boat: 'Boat', cat: 'Cat', chicken: 'Chicken', cod: 'Cod', cow: 'Cow', + creeper: 'Creeper', dolphin: 'Dolphin', + enderdragon: 'Ender Dragon', enderman: 'Enderman', endermite: 'Endermite', evoker: 'Evoker', - fox: 'Fox', + fox_bedrock: 'Fox (Bedrock)', + fox_java: 'Fox (Java)', ghast: 'Ghast', guardian: 'Guardian', horse: 'Horse', llama: 'Llama', lavaslime: 'Lava Slime', + irongolem: 'Iron Golem', + minecart: 'Minecart', panda: 'Panda', parrot: 'Parrot', phantom: 'Phantom', @@ -452,7 +456,7 @@ skin_presets.alex = `{ "rotation": [-10, 0, 0], "cubes": [ {"name": "Right Arm", "origin": [-7, 12, -2], "size": [3, 12, 4], "uv": [40, 16]}, - {"name": "Right Sleeve", "visibility": false, "origin": [-7, 12, -2], "size": [3, 12, 4], "uv": [40, 32], "inflate": 0.25} + {"name": "Right Arm Layer", "visibility": false, "origin": [-7, 12, -2], "size": [3, 12, 4], "uv": [40, 32], "inflate": 0.25} ] }, { @@ -462,7 +466,7 @@ skin_presets.alex = `{ "rotation": [12, 0, 0], "cubes": [ {"name": "Left Arm", "origin": [4, 12, -2], "size": [3, 12, 4], "uv": [32, 48]}, - {"name": "Left Sleeve", "visibility": false, "origin": [4, 12, -2], "size": [3, 12, 4], "uv": [48, 48], "inflate": 0.25} + {"name": "Left Arm Layer", "visibility": false, "origin": [4, 12, -2], "size": [3, 12, 4], "uv": [48, 48], "inflate": 0.25} ] }, { @@ -487,64 +491,6 @@ skin_presets.alex = `{ } ] }`; -skin_presets.creeper = `{ - "name": "alex", - "texturewidth": 64, - "textureheight": 32, - "eyes": [ - [9, 10], - [13, 10] - ], - "bones": [ - { - "name": "body", - "pivot": [0, 0, 0], - "cubes": [ - {"name": "body", "origin": [-4, 6, -2], "size": [8, 12, 4], "uv": [16, 16]} - ] - }, - { - "name": "head", - "parent": "body", - "pivot": [0, 18, 0], - "cubes": [ - {"name": "head", "origin": [-4, 18, -4], "size": [8, 8, 8], "uv": [0, 0]} - ] - }, - { - "name": "leg0", - "parent": "body", - "pivot": [-2, 6, 4], - "cubes": [ - {"name": "leg0", "origin": [-4, 0, 2], "size": [4, 6, 4], "uv": [0, 16]} - ] - }, - { - "name": "leg1", - "parent": "body", - "pivot": [2, 6, 4], - "cubes": [ - {"name": "leg1", "origin": [0, 0, 2], "size": [4, 6, 4], "uv": [0, 16]} - ] - }, - { - "name": "leg2", - "parent": "body", - "pivot": [-2, 6, -4], - "cubes": [ - {"name": "leg2", "origin": [-4, 0, -6], "size": [4, 6, 4], "uv": [0, 16]} - ] - }, - { - "name": "leg3", - "parent": "body", - "pivot": [2, 6, -4], - "cubes": [ - {"name": "leg3", "origin": [0, 0, -6], "size": [4, 6, 4], "uv": [0, 16]} - ] - } - ] -}`; skin_presets.armor_stand = `{ "name": "armor_stand", "texturewidth": 64, @@ -727,8 +673,8 @@ skin_presets.bee = `{ "pivot": [0.5, 5, 0], "cubes": [ {"name": "body", "origin": [-3, 2, -5], "size": [7, 7, 10], "uv": [0, 0]}, - {"name": "body", "origin": [2, 7, -8], "size": [1, 2, 3], "uv": [2, 0]}, - {"name": "body", "origin": [-2, 7, -8], "size": [1, 2, 3], "uv": [2, 3]} + {"name": "body", "origin": [-2, 7, -8], "size": [1, 2, 3], "uv": [2, 3]}, + {"name": "body", "origin": [2, 7, -8], "size": [1, 2, 3], "uv": [2, 0]} ] }, { @@ -783,6 +729,77 @@ skin_presets.bee = `{ } ] }`; +skin_presets.boat = `{ + "name": "boat", + "texturewidth": 128, + "textureheight": 64, + "bones": [ + { + "name": "bottom", + "pivot": [0, 18, 0], + "rotation": [90, 0, 0], + "mirror": true, + "cubes": [ + {"name": "bottom", "origin": [-14, 10, 0], "size": [28, 16, 3], "uv": [0, 0]} + ] + }, + { + "name": "front", + "pivot": [15, 24, 0], + "rotation": [0, 90, 0], + "mirror": true, + "cubes": [ + {"name": "front", "origin": [7, 21, -1], "size": [16, 6, 2], "uv": [0, 27]} + ] + }, + { + "name": "back", + "pivot": [-15, 24, 0], + "rotation": [0, -90, 0], + "mirror": true, + "cubes": [ + {"name": "back", "origin": [-24, 21, -1], "size": [18, 6, 2], "uv": [0, 19]} + ] + }, + { + "name": "right", + "pivot": [0, 24, -9], + "rotation": [0, -180, 0], + "mirror": true, + "cubes": [ + {"name": "right", "origin": [-14, 21, -10], "size": [28, 6, 2], "uv": [0, 35]} + ] + }, + { + "name": "left", + "pivot": [0, 24, 9], + "mirror": true, + "cubes": [ + {"name": "left", "origin": [-14, 21, 8], "size": [28, 6, 2], "uv": [0, 43]} + ] + }, + { + "name": "paddle_left", + "pivot": [-2.5, 28, 9], + "rotation": [-30, 0, 0], + "mirror": true, + "cubes": [ + {"name": "paddle_left", "origin": [-3.5, 27, 3.5], "size": [2, 2, 18], "uv": [62, 0]}, + {"name": "paddle_left", "origin": [-2.51, 26, 17.5], "size": [1, 6, 7], "uv": [62, 0]} + ] + }, + { + "name": "paddle_right", + "pivot": [-2.5, 28, -9], + "rotation": [-30, 180, 0], + "mirror": true, + "cubes": [ + {"name": "paddle_right", "origin": [-3.5, 27, -14.5], "size": [2, 2, 18], "uv": [62, 20]}, + {"name": "paddle_right", "origin": [-3.49, 26, -0.5], "size": [1, 6, 7], "uv": [62, 20]} + ] + } + ] +}`; skin_presets.cat = `{ "name": "cat", "texturewidth": 64, @@ -1049,6 +1066,64 @@ skin_presets.cow = `{ } ] }`; +skin_presets.creeper = `{ + "name": "alex", + "texturewidth": 64, + "textureheight": 32, + "eyes": [ + [9, 10], + [13, 10] + ], + "bones": [ + { + "name": "body", + "pivot": [0, 0, 0], + "cubes": [ + {"name": "body", "origin": [-4, 6, -2], "size": [8, 12, 4], "uv": [16, 16]} + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 18, 0], + "cubes": [ + {"name": "head", "origin": [-4, 18, -4], "size": [8, 8, 8], "uv": [0, 0]} + ] + }, + { + "name": "leg0", + "parent": "body", + "pivot": [-2, 6, 4], + "cubes": [ + {"name": "leg0", "origin": [-4, 0, 2], "size": [4, 6, 4], "uv": [0, 16]} + ] + }, + { + "name": "leg1", + "parent": "body", + "pivot": [2, 6, 4], + "cubes": [ + {"name": "leg1", "origin": [0, 0, 2], "size": [4, 6, 4], "uv": [0, 16]} + ] + }, + { + "name": "leg2", + "parent": "body", + "pivot": [-2, 6, -4], + "cubes": [ + {"name": "leg2", "origin": [-4, 0, -6], "size": [4, 6, 4], "uv": [0, 16]} + ] + }, + { + "name": "leg3", + "parent": "body", + "pivot": [2, 6, -4], + "cubes": [ + {"name": "leg3", "origin": [0, 0, -6], "size": [4, 6, 4], "uv": [0, 16]} + ] + } + ] +}`; skin_presets.dolphin = `{ "name": "dolphin", "texturewidth": 64, @@ -1122,6 +1197,363 @@ skin_presets.dolphin = `{ } ] }`; +skin_presets.enderdragon = `{ + "name": "enderdragon", + "texturewidth": 256, + "textureheight": 256, + "bones": [ + { + "name": "neck", + "pivot": [0, 7, -8], + "rotation": [-5, 0, 0], + "cubes": [ + {"name": "neck", "origin": [-5, 2, -18], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "neck", "origin": [-1, 12, -16], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "neck2", + "parent": "neck", + "pivot": [0, 7, -18], + "rotation": [5, 0, 0], + "cubes": [ + {"name": "neck", "origin": [-5, 2, -28], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "neck", "origin": [-1, 12, -26], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "neck3", + "parent": "neck2", + "pivot": [0, 7, -28], + "rotation": [5, 0, 0], + "cubes": [ + {"name": "neck", "origin": [-5, 2, -38], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "neck", "origin": [-1, 12, -36], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "neck4", + "parent": "neck3", + "pivot": [0, 7, -38], + "rotation": [5, 0, 0], + "cubes": [ + {"name": "neck", "origin": [-5, 2, -48], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "neck", "origin": [-1, 12, -46], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "neck5", + "parent": "neck4", + "pivot": [0, 7, -48], + "rotation": [5, 0, 0], + "cubes": [ + {"name": "neck", "origin": [-5, 2, -58], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "neck", "origin": [-1, 12, -56], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "head", + "parent": "neck5", + "pivot": [0, 7, -58], + "rotation": [5, 0, 0], + "cubes": [ + {"name": "head", "origin": [-6, 3, -88], "size": [12, 5, 16], "uv": [176, 44]}, + {"name": "head", "origin": [-8, -1, -74], "size": [16, 16, 16], "uv": [112, 30]}, + {"name": "head", "origin": [-5, 15, -68], "size": [2, 4, 6], "uv": [0, 0], "mirror": true}, + {"name": "head", "origin": [-5, 8, -86], "size": [2, 2, 4], "uv": [112, 0], "mirror": true}, + {"name": "head", "origin": [3, 15, -68], "size": [2, 4, 6], "uv": [0, 0]}, + {"name": "head", "origin": [3, 8, -86], "size": [2, 2, 4], "uv": [112, 0]} + ] + }, + { + "name": "jaw", + "parent": "head", + "pivot": [0, 3, -71], + "rotation": [15, 0, 0], + "cubes": [ + {"name": "jaw", "origin": [-6, -1, -88], "size": [12, 4, 16], "uv": [176, 65]} + ] + }, + { + "name": "body", + "pivot": [0, 20, 8], + "cubes": [ + {"name": "body", "origin": [-12, -4, -8], "size": [24, 24, 64], "uv": [0, 0]}, + {"name": "body", "origin": [-1, 20, -2], "size": [2, 6, 12], "uv": [220, 53]}, + {"name": "body", "origin": [-1, 20, 18], "size": [2, 6, 12], "uv": [220, 53]}, + {"name": "body", "origin": [-1, 20, 38], "size": [2, 6, 12], "uv": [220, 53]} + ] + }, + { + "name": "wing", + "pivot": [-12, 19, 2], + "rotation": [0, 10, 10], + "cubes": [ + {"name": "wing", "origin": [-68, 15, -2], "size": [56, 8, 8], "uv": [112, 88]}, + {"name": "wing", "origin": [-68, 19, 4], "size": [56, 0, 56], "uv": [-56, 88]} + ] + }, + { + "name": "wingtip", + "parent": "wing", + "pivot": [-68, 19, 0], + "rotation": [0, 0, -20], + "cubes": [ + {"name": "wingtip", "origin": [-124, 17, 0], "size": [56, 4, 4], "uv": [112, 136]}, + {"name": "wingtip", "origin": [-124, 19, 4], "size": [56, 0, 56], "uv": [-56, 144]} + ] + }, + { + "name": "wing1", + "pivot": [12, 19, 2], + "rotation": [0, -10, -10], + "mirror": true, + "cubes": [ + {"name": "wing1", "origin": [12, 15, -2], "size": [56, 8, 8], "uv": [112, 88]}, + {"name": "wing1", "origin": [12, 19, 4], "size": [56, 0, 56], "uv": [-56, 88]} + ] + }, + { + "name": "wingtip1", + "parent": "wing1", + "pivot": [68, 19, 0], + "rotation": [0, 0, 20], + "mirror": true, + "cubes": [ + {"name": "wingtip1", "origin": [68, 17, 0], "size": [56, 4, 4], "uv": [112, 136]}, + {"name": "wingtip1", "origin": [68, 19, 4], "size": [56, 0, 56], "uv": [-56, 144]} + ] + }, + { + "name": "rearleg", + "pivot": [-16, 8, 42], + "rotation": [60, 0, 0], + "cubes": [ + {"name": "rearleg", "origin": [-24, -20, 34], "size": [16, 32, 16], "uv": [0, 0]} + ] + }, + { + "name": "rearlegtip", + "parent": "rearleg", + "pivot": [-16, -20, 43], + "rotation": [25, 0, 0], + "cubes": [ + {"name": "rearlegtip", "origin": [-22, -52, 36], "size": [12, 32, 12], "uv": [196, 0]} + ] + }, + { + "name": "rearfoot", + "parent": "rearlegtip", + "pivot": [-16, -52, 41], + "rotation": [45, 0, 0], + "cubes": [ + {"name": "rearfoot", "origin": [-25, -58, 21], "size": [18, 6, 24], "uv": [112, 0]} + ] + }, + { + "name": "rearleg1", + "pivot": [16, 8, 42], + "rotation": [60, 0, 0], + "mirror": true, + "cubes": [ + {"name": "rearleg1", "origin": [8, -20, 34], "size": [16, 32, 16], "uv": [0, 0]} + ] + }, + { + "name": "rearlegtip1", + "parent": "rearleg1", + "pivot": [16, -20, 43], + "rotation": [25, 0, 0], + "mirror": true, + "cubes": [ + {"name": "rearlegtip", "origin": [10, -52, 36], "size": [12, 32, 12], "uv": [196, 0]} + ] + }, + { + "name": "rearfoot1", + "parent": "rearlegtip1", + "pivot": [16, -52, 41], + "rotation": [45, 0, 0], + "mirror": true, + "cubes": [ + {"name": "rearfoot", "origin": [7, -58, 21], "size": [18, 6, 24], "uv": [112, 0]} + ] + }, + { + "name": "frontleg", + "pivot": [-12, 4, 2], + "rotation": [65, 0, 0], + "cubes": [ + {"name": "frontleg", "origin": [-16, -16, -2], "size": [8, 24, 8], "uv": [112, 104]} + ] + }, + { + "name": "frontlegtip", + "parent": "frontleg", + "pivot": [-12, -16, 2], + "rotation": [-20, 0, 0], + "cubes": [ + {"name": "frontlegtip", "origin": [-15, -39, -1], "size": [6, 24, 6], "uv": [226, 138]} + ] + }, + { + "name": "frontfoot", + "parent": "frontlegtip", + "pivot": [-12, -38, 2], + "rotation": [45, 0, 0], + "cubes": [ + {"name": "frontfoot", "origin": [-16, -42, -10], "size": [8, 4, 16], "uv": [144, 104]} + ] + }, + { + "name": "frontleg1", + "pivot": [12, 4, 2], + "rotation": [65, 0, 0], + "mirror": true, + "cubes": [ + {"name": "frontleg1", "origin": [8, -16, -2], "size": [8, 24, 8], "uv": [112, 104]} + ] + }, + { + "name": "frontlegtip1", + "parent": "frontleg1", + "pivot": [12, -16, 2], + "rotation": [-20, 0, 0], + "mirror": true, + "cubes": [ + {"name": "frontlegtip", "origin": [9, -39, -1], "size": [6, 24, 6], "uv": [226, 138]} + ] + }, + { + "name": "frontfoot1", + "parent": "frontlegtip1", + "pivot": [12, -38, 2], + "rotation": [45, 0, 0], + "mirror": true, + "cubes": [ + {"name": "frontfoot", "origin": [8, -42, -10], "size": [8, 4, 16], "uv": [144, 104]} + ] + }, + { + "name": "tail", + "pivot": [0, 14, 56], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 56], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 58], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail2", + "parent": "tail", + "pivot": [0, 14, 66], + "rotation": [1, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 66], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 68], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail3", + "parent": "tail2", + "pivot": [0, 14, 76], + "rotation": [1, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 76], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 78], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail4", + "parent": "tail3", + "pivot": [0, 14, 86], + "rotation": [1, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 86], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 88], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail5", + "parent": "tail4", + "pivot": [0, 14, 96], + "rotation": [2, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 96], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 98], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail6", + "parent": "tail5", + "pivot": [0, 14, 106], + "rotation": [3, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 106], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 108], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail7", + "parent": "tail6", + "pivot": [0, 14, 116], + "rotation": [3, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 116], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 118], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail8", + "parent": "tail7", + "pivot": [0, 14, 126], + "rotation": [1, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 126], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 128], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail9", + "parent": "tail8", + "pivot": [0, 14, 136], + "rotation": [-1, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 136], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 138], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail10", + "parent": "tail9", + "pivot": [0, 14, 146], + "rotation": [-2, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 146], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 148], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail11", + "parent": "tail10", + "pivot": [0, 14, 156], + "rotation": [-3, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 156], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 158], "size": [2, 4, 6], "uv": [48, 0]} + ] + }, + { + "name": "tail12", + "parent": "tail11", + "pivot": [0, 14, 166], + "rotation": [-3, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-5, 9, 166], "size": [10, 10, 10], "uv": [192, 104]}, + {"name": "tail", "origin": [-1, 19, 168], "size": [2, 4, 6], "uv": [48, 0]} + ] + } + ] +}`; skin_presets.enderman = `{ "name": "enderman:geometry", "texturewidth": 64, @@ -1292,7 +1724,7 @@ skin_presets.evoker = `{ } ] }`; -skin_presets.fox = `{ +skin_presets.fox_bedrock = `{ "name": "fox", "texturewidth": 64, "textureheight": 32, @@ -1354,6 +1786,67 @@ skin_presets.fox = `{ } ] }`; +skin_presets.fox_java = `{ + "name": "fox", + "texturewidth": 48, + "textureheight": 32, + "bones": [ + { + "name": "body", + "pivot": [0, 8, 0], + "rotation": [90, 0, 0], + "cubes": [ + {"name": "body", "origin": [-3, 0, -3], "size": [6, 11, 6], "uv": [24, 15]} + ] + }, + { + "name": "head", + "pivot": [0, 8, -3], + "cubes": [ + {"name": "head", "origin": [-4, 4, -9], "size": [8, 6, 6], "uv": [1, 5]}, + {"name": "head", "origin": [-4, 10, -8], "size": [2, 2, 1], "uv": [8, 1]}, + {"name": "head", "origin": [2, 10, -8], "size": [2, 2, 1], "uv": [15, 1]}, + {"name": "head", "origin": [-2, 4, -12], "size": [4, 2, 3], "uv": [6, 18]} + ] + }, + { + "name": "leg0", + "pivot": [-3, 6, 6], + "cubes": [ + {"name": "leg0", "origin": [-3.005, 0, 5], "size": [2, 6, 2], "uv": [13, 24]} + ] + }, + { + "name": "leg1", + "pivot": [1, 6, 6], + "cubes": [ + {"name": "leg1", "origin": [1.005, 0, 5], "size": [2, 6, 2], "uv": [4, 24]} + ] + }, + { + "name": "leg2", + "pivot": [-3, 6, -1], + "cubes": [ + {"name": "leg2", "origin": [-3.005, 0, -2], "size": [2, 6, 2], "uv": [13, 24]} + ] + }, + { + "name": "leg3", + "pivot": [1, 6, -1], + "cubes": [ + {"name": "leg3", "origin": [1.005, 0, -2], "size": [2, 6, 2], "uv": [4, 24]} + ] + }, + { + "name": "tail", + "pivot": [0, 8, 7], + "rotation": [90, 0, 0], + "cubes": [ + {"name": "tail", "origin": [-2, -2, 4.75], "size": [4, 9, 5], "uv": [30, 0]} + ] + } + ] +}`; skin_presets.ghast = `{ "name": "ghast", "texturewidth": 64, @@ -1765,6 +2258,63 @@ skin_presets.horse = `{ } ] }`; +skin_presets.irongolem = `{ + "name": "irongolem", + "texturewidth": 128, + "textureheight": 128, + "bones": [ + { + "name": "body", + "pivot": [0, 31, 0], + "cubes": [ + {"name": "body", "origin": [-9, 21, -6], "size": [18, 12, 11], "uv": [0, 40]}, + {"name": "body", "origin": [-4.5, 16, -3], "size": [9, 5, 6], "uv": [0, 70], "inflate": 0.5} + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 31, -2], + "cubes": [ + {"name": "head", "origin": [-4, 33, -7.5], "size": [8, 10, 8], "uv": [0, 0]}, + {"name": "head", "origin": [-1, 32, -9.5], "size": [2, 4, 2], "uv": [24, 0]} + ] + }, + { + "name": "arm0", + "parent": "body", + "pivot": [0, 31, 0], + "cubes": [ + {"name": "arm0", "origin": [-13, 3.5, -3], "size": [4, 30, 6], "uv": [60, 21]} + ] + }, + { + "name": "arm1", + "parent": "body", + "pivot": [0, 31, 0], + "cubes": [ + {"name": "arm1", "origin": [9, 3.5, -3], "size": [4, 30, 6], "uv": [60, 58]} + ] + }, + { + "name": "leg0", + "parent": "body", + "pivot": [-4, 13, 0], + "cubes": [ + {"name": "leg0", "origin": [-7.5, 0, -3], "size": [6, 16, 5], "uv": [37, 0]} + ] + }, + { + "name": "leg1", + "parent": "body", + "pivot": [5, 13, 0], + "mirror": true, + "cubes": [ + {"name": "leg1", "origin": [1.5, 0, -3], "size": [6, 16, 5], "uv": [60, 0]} + ] + } + ] +}`; skin_presets.llama = `{ "name": "llama", "texturewidth": 128, @@ -1922,6 +2472,57 @@ skin_presets.lavaslime = `{ } ] }`; +skin_presets.minecart = `{ + "name": "minecart", + "texturewidth": 64, + "textureheight": 32, + "bones": [ + { + "name": "bottom", + "pivot": [0, 20, 0], + "rotation": [90, 0, 0], + "mirror": true, + "cubes": [ + {"name": "bottom", "origin": [-10, 12, -20], "size": [20, 16, 2], "uv": [0, 10]} + ] + }, + { + "name": "front", + "pivot": [-9, 25, 0], + "rotation": [0, -90, 0], + "mirror": true, + "cubes": [ + {"name": "front", "origin": [-17, 2, -1], "size": [16, 8, 2], "uv": [0, 0]} + ] + }, + { + "name": "back", + "pivot": [9, 25, 0], + "rotation": [0, 90, 0], + "mirror": true, + "cubes": [ + {"name": "back", "origin": [1, 2, -1], "size": [16, 8, 2], "uv": [0, 0]} + ] + }, + { + "name": "right", + "pivot": [0, 25, -7], + "rotation": [0, -180, 0], + "mirror": true, + "cubes": [ + {"name": "right", "origin": [-8, 2, -8], "size": [16, 8, 2], "uv": [0, 0]} + ] + }, + { + "name": "left", + "pivot": [0, 25, 7], + "mirror": true, + "cubes": [ + {"name": "left", "origin": [-8, 2, 6], "size": [16, 8, 2], "uv": [0, 0]} + ] + } + ] +}`; skin_presets.panda = `{ "name": "panda", "texturewidth": 64, diff --git a/js/texturing/color.js b/js/texturing/color.js index 7129a0e..5b3f87c 100644 --- a/js/texturing/color.js +++ b/js/texturing/color.js @@ -185,13 +185,28 @@ onVueSetup(() => { //$(this).animate({scrollLeft: current + delta}, 200) }) - ColorPanel.importPalette = function(string) { + ColorPanel.importPalette = function(file) { + + if (pathToExtension(file.path) == 'png') { + var img = new Image(file.content); + img.src = file.content || file.path; + img.onload = function() { + var c = document.createElement('canvas'); + var ctx = c.getContext('2d'); + c.width = img.naturalWidth; + c.height = img.naturalHeight; + ctx.drawImage(img, 0, 0); + ColorPanel.generatePalette(ctx); + } + return; + } + var string = file.content; var colors = []; - var m_hex = string.match(/(#|FF)?[a-fA-F0-9]{6}/g) + var m_hex = string.match(/(#|FF)?[a-fA-F0-9]{6}/g); if (m_hex) m_hex.forEach(color => { color = color.substr(-6).toLowerCase(); - colors.safePush(color); + colors.safePush('#'+color); }) var m_rgb = string.match(/\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}\s*\)/g) if (m_rgb) m_rgb.forEach(color => { @@ -229,15 +244,118 @@ onVueSetup(() => { }); dialog.show(); } + ColorPanel.generatePalette = function(source) { + + var options = {}; + if (!source) { + textures.forEach((tex, i) => { + if (!tex.error) { + options[i] = tex.name; + } + }) + } + var dialog = new Dialog({ + id: 'generate_palette', + title: 'action.import_palette', + width: 460, + form: { + texture: {label: 'data.texture', type: 'select', options, condition: !source}, + replace: {label: 'message.import_palette.replace_palette', type: 'checkbox', value: true}, + threshold: {label: 'message.import_palette.threshold', type: 'number', value: 10, min: 0, max: 100}, + }, + onConfirm(formData) { + var colors = {}; + var result_palette = []; + + if (!source) { + var texture = textures[formData.texture]; + var ctx = Painter.getCanvas(texture).getContext('2d'); + } else { + var ctx = source; + } + Painter.scanCanvas(ctx, 0, 0, ctx.canvas.width, ctx.canvas.height, (x, y, px) => { + if (px[3] < 12) return; + var t = tinycolor({ + r: px[0], + g: px[1], + b: px[2] + }) + var hex = t.toHexString(); + if (colors[hex]) { + colors[hex].count++; + } else { + colors[hex] = t; + t.count = 1; + } + }) + var pots = {gray:[], red:[], orange:[], yellow:[], green:[], blue:[], magenta:[]} + for (var hex in colors) { + var color = colors[hex]; + if (Math.abs(color._r - color._g) + Math.abs(color._g - color._b) + Math.abs(color._r - color._b) < 74) { + //gray + pots.gray.push(color); + } else { + var distances = { + red: colorDistance(color, {_r: 250, _g: 0, _b: 0}), + orange: colorDistance(color, {_r: 240, _g: 127, _b: 0})*1.4, + yellow: colorDistance(color, {_r: 265, _g: 240, _b: 0})*1.4, + green: colorDistance(color, {_r: 0, _g: 255, _b: 0}), + blue: colorDistance(color, {_r: 0, _g: 50, _b: 240}), + magenta: colorDistance(color,{_r: 255, _g: 0, _b: 255})*1.4, + } + var closest = highestInObject(distances, true); + pots[closest].push(color); + } + } + for (var pot in pots) { + pots[pot].sort((a, b) => { + return (a._r + a._g + a._b) - (b._r + b._g + b._b); + }) + if (pots[pot].length > 1) { + for (var i = pots[pot].length-2; i >= 0; i--) { + var col = pots[pot][i]; + var abv = pots[pot][i+1]; + var distance = colorDistance(col, abv); + if (distance < formData.threshold) { + if (col.count < col.count) { + pots[pot].splice(i, 1); + } else { + pots[pot].splice(i+1, 1); + } + } + } + } + pots[pot].forEach(color => { + result_palette.push(color.toHexString()); + }) + } + + + + + if (formData.replace) { + ColorPanel.palette.purge(); + ColorPanel.palette.push(...result_palette); + } else { + result_palette.forEach(color => { + ColorPanel.palette.safePush(color); + }) + } + dialog.hide(); + } + }); + dialog.show(); + } Blockbench.addDragHandler('palette', { - extensions: ['bbpalette', 'css', 'txt', 'gpl', 'hex'], + extensions: ['bbpalette', 'css', 'txt', 'gpl', 'hex', 'png'], readtype: 'text', + readtype: (path) => (pathToExtension(path) == 'png' ? 'image' : 'text'), element: '#color', propagate: true, }, function(files) { - if (files && files[0] && typeof files[0].content == 'string') { - ColorPanel.importPalette(files[0].content); + if (files && files[0]) { + ColorPanel.importPalette(files[0]); } }) Toolbars.palette.toPlace(); @@ -245,6 +363,8 @@ onVueSetup(() => { }) + + BARS.defineActions(function() { new Action('add_to_palette', { @@ -263,11 +383,12 @@ BARS.defineActions(function() { category: 'color', click: function () { Blockbench.import({ - extensions: ['bbpalette', 'css', 'txt', 'gpl', 'hex'], - type: 'Blockbench Palette' + extensions: ['bbpalette', 'css', 'txt', 'gpl', 'hex', 'png'], + type: 'Blockbench Palette', + readtype: (path) => (pathToExtension(path) == 'png' ? 'image' : 'text'), }, function(files) { - if (files && files[0] && typeof files[0].content == 'string') { - ColorPanel.importPalette(files[0].content); + if (files && files[0]) { + ColorPanel.importPalette(files[0]); } }) } @@ -289,99 +410,7 @@ BARS.defineActions(function() { icon: 'blur_linear', category: 'color', click: function () { - var options = {}; - textures.forEach((tex, i) => { - if (!tex.error) { - options[i] = tex.name; - } - }) - var dialog = new Dialog({ - id: 'generate_palette', - title: 'action.import_palette', - width: 460, - form: { - texture: {label: 'data.texture', type: 'select', options}, - replace: {label: 'message.import_palette.replace_palette', type: 'checkbox', value: true}, - threshold: {label: 'message.import_palette.threshold', type: 'number', value: 10, min: 0, max: 100}, - }, - onConfirm(formData) { - var colors = {}; - var result_palette = []; - - var texture = textures[formData.texture]; - var ctx = Painter.getCanvas(texture).getContext('2d') - Painter.scanCanvas(ctx, 0, 0, texture.width, texture.height, (x, y, px) => { - if (px[3] < 12) return; - var t = tinycolor({ - r: px[0], - g: px[1], - b: px[2] - }) - var hex = t.toHexString(); - if (colors[hex]) { - colors[hex].count++; - } else { - colors[hex] = t; - t.count = 1; - } - }) - var pots = {gray:[], red:[], orange:[], yellow:[], green:[], blue:[], magenta:[]} - for (var hex in colors) { - var color = colors[hex]; - if (Math.abs(color._r - color._g) + Math.abs(color._g - color._b) + Math.abs(color._r - color._b) < 74) { - //gray - pots.gray.push(color); - } else { - var distances = { - red: colorDistance(color, {_r: 250, _g: 0, _b: 0}), - orange: colorDistance(color, {_r: 240, _g: 127, _b: 0})*1.4, - yellow: colorDistance(color, {_r: 265, _g: 240, _b: 0})*1.4, - green: colorDistance(color, {_r: 0, _g: 255, _b: 0}), - blue: colorDistance(color, {_r: 0, _g: 50, _b: 240}), - magenta: colorDistance(color,{_r: 255, _g: 0, _b: 255})*1.4, - } - var closest = highestInObject(distances, true); - pots[closest].push(color); - } - } - for (var pot in pots) { - pots[pot].sort((a, b) => { - return (a._r + a._g + a._b) - (b._r + b._g + b._b); - }) - if (pots[pot].length > 1) { - for (var i = pots[pot].length-2; i >= 0; i--) { - var col = pots[pot][i]; - var abv = pots[pot][i+1]; - var distance = colorDistance(col, abv); - if (distance < formData.threshold) { - if (col.count < col.count) { - pots[pot].splice(i, 1); - } else { - pots[pot].splice(i+1, 1); - } - } - } - } - pots[pot].forEach(color => { - result_palette.push(color.toHexString()); - }) - } - - - - - if (formData.replace) { - ColorPanel.palette.purge(); - ColorPanel.palette.push(...result_palette); - } else { - result_palette.forEach(color => { - ColorPanel.palette.safePush(color); - }) - } - dialog.hide(); - } - }); - dialog.show(); + ColorPanel.generatePalette(); } }) new Action('sort_palette', { diff --git a/js/texturing/painter.js b/js/texturing/painter.js index 1d8401a..41328d8 100644 --- a/js/texturing/painter.js +++ b/js/texturing/painter.js @@ -673,10 +673,6 @@ const TextureGenerator = { }) if (Project.box_uv || options.box_uv) { TextureGenerator.generateTemplate(options, makeTexture) - if (options.box_uv && !Project.box_uv) { - //todo: Undo Integration - Project.box_uv = true; - } } else { TextureGenerator.generateFaceTemplate(options, makeTexture) } @@ -886,6 +882,9 @@ const TextureGenerator = { t.obj.autouv = 0 }) } + if (options.box_uv && !Project.box_uv) { + Project.box_uv = true; + } updateSelection() Undo.finishEdit('create template', { textures: [texture], diff --git a/js/texturing/uv.js b/js/texturing/uv.js index 9b05c29..3f86a75 100644 --- a/js/texturing/uv.js +++ b/js/texturing/uv.js @@ -894,7 +894,7 @@ class UVEditor { } contextMenu() { var scope = this; - this.reference_face = Cube.selected[0].faces[scope.face] + this.reference_face = Cube.selected[0] && Cube.selected[0].faces[scope.face]; this.menu.open(event, this) return this; } diff --git a/lang/es.json b/lang/es.json index 48a09ab..8229e5a 100644 --- a/lang/es.json +++ b/lang/es.json @@ -1003,25 +1003,25 @@ "action.add_marker.desc": "Pone un marcador de línea de tiempo", "timeline.pre_effect_script": "Guión\n", "format.skin": "Skin", - "format.skin.desc": "Edit player and entity skins", - "message.sketchfab.setup_guide": "Want to learn how to set up models in Sketchfab? Read %0", - "dialog.skin.title": "Create Skin", + "format.skin.desc": "Editar las skins de entidades y jugadores", + "message.sketchfab.setup_guide": "¿Quieres aprender a preparar modelos en Sketchfab? Lee %0", + "dialog.skin.title": "Crear Skin", "dialog.skin.model": "Skin", - "dialog.skin.texture": "Texture (Optional)", - "action.toggle_skin_layer": "Toggle Skin Layer", - "action.toggle_skin_layer.desc": "Toggle the hat and clothing layer of the skin model", - "action.gui_light": "GUI Light", - "action.gui_light.desc": "Select the way the item is lit in the inventory", - "action.gui_light.side": "Side Light", - "action.gui_light.front": "Front Light", - "action.move_keyframe_back": "Move Keyframes Back", - "action.move_keyframe_forth": "Move Keyframes Forth", - "menu.help": "Help", - "menu.help.discord": "Discord Server", - "menu.help.report_issue": "Report an Issue", - "menu.help.plugin_documentation": "Plugin API Documentation", - "menu.help.search_action": "Search and Run Action", - "menu.help.donate": "Donate", - "menu.help.about": "About...", - "menu.preview.background.clipboard": "Load from Clipboard" + "dialog.skin.texture": "Textura (Opcional)", + "action.toggle_skin_layer": "Cambiar Capa de Skin", + "action.toggle_skin_layer.desc": "Cambia la capa del gorro y de la ropa en el modelo de skin", + "action.gui_light": "Luz en GUI", + "action.gui_light.desc": "Selecciona la forma en la que el ítem es iluminado en el inventario", + "action.gui_light.side": "Luz Lateral", + "action.gui_light.front": "Luz Frontal", + "action.move_keyframe_back": "Mover Frames Clave Atrás", + "action.move_keyframe_forth": "Mover Frames Clave Adelante", + "menu.help": "Ayuda", + "menu.help.discord": "Servidor de Discord", + "menu.help.report_issue": "Reportar un Problema", + "menu.help.plugin_documentation": "Documentación de la API de Plugins", + "menu.help.search_action": "Buscar y Ejecutar Acción", + "menu.help.donate": "Donar", + "menu.help.about": "Acerca de...", + "menu.preview.background.clipboard": "Cargar desde Portapapeles" } \ No newline at end of file diff --git a/package.json b/package.json index 015ba6e..98d843f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Blockbench", "description": "Model editing and animation software", - "version": "3.3.0", + "version": "3.3.1", "license": "MIT", "author": { "name": "JannisX11",