Skip to content

Commit

Permalink
3.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
JannisX11 committed Mar 10, 2020
1 parent d3d50ff commit 7941f20
Show file tree
Hide file tree
Showing 31 changed files with 622 additions and 690 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/dist/
index.php
package-lock.json
node_modules/
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
# Blockbench

Blockbench is a free, modern model editor for Minecraft Java and Bedrock Edition.
Blockbench is a free, modern model editor for boxy models and pixel art textures.
Models can be exported for Minecraft Java and Bedrock Edition as well as most game engines and other 3D applications.
Blockbench features a modern and intuitive UI, plugin support and innovative features. It is the industry standard for creating custom 3D models for the Minecraft Marketplace.
Project and download page: [blockbench.net](https://www.blockbench.net)
Website and download: [blockbench.net](https://www.blockbench.net)

![Interface](https://blockbench.net/wp-content/uploads/2019/07/interface_skidsteer.png)

## Contribution

I am not actively using this repository to develop Blockbench. Therefore, I currently won't accept pull requests, sorry!
If you want something implemented in Blockbench, please write a plugin, create an issue labeled [Suggestion], or contact me on Discord.
If you want to Blockbench translations, please visit [blockbench.net/translations](https://blockbench.net/translations/). Thank you!

## Plugins

Blockbench supports Javascript-based plugins. Learn more about creating plugins on [jannisx11.github.io/blockbench-docs](https://jannisx11.github.io/blockbench-docs/#creating-a-plugin).
5 changes: 5 additions & 0 deletions css/panels.css
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,9 @@
cursor: default;
pointer-events: none;
z-index: 5;
color: white;
mix-blend-mode: difference;
font-weight: 300;
}
.panel .bar.next_to_title {
margin-top: -30px;
Expand Down Expand Up @@ -1231,5 +1234,7 @@
}
.panel#color .sp-container.sp-flat {
overflow: visible;
margin: 2px 4px 0 4px;
width: calc(100% - 8px);
}

3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<script>
if (typeof module === 'object') {window.module = module; module = undefined;}//jQuery Fix
const isApp = typeof require !== 'undefined';
const appVersion = '3.4.0';
const appVersion = '3.4.1';
</script>
<div id="loading_error_message" style="display: none;">
<div>An error occurred while loading Blockbench</div>
Expand Down Expand Up @@ -58,6 +58,7 @@
<script src="js/interface/actions.js"></script>
<script src="js/interface/themes.js"></script>
<script src="js/blockbench.js"></script>
<script src="js/modes.js"></script>
<script src="js/interface/keyboard.js"></script>
<script src="js/interface/settings.js"></script>
<script src="js/interface/dialog.js"></script>
Expand Down
1 change: 1 addition & 0 deletions js/animations.js
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,7 @@ const Animator = {
animation.getBoneAnimator(group).displayFrame(Timeline.time)
}
})
group.mesh.updateMatrixWorld()
})

Animator.animations.forEach(animation => {
Expand Down
248 changes: 1 addition & 247 deletions js/blockbench.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,163 +294,6 @@ function createSelection() {
}
hideDialog()
}
//Modes
class Mode extends KeybindItem {
constructor(data) {
super(data)
this.id = data.id;
this.name = data.name || tl('mode.'+this.id);
this.selected = false
this.default_tool = data.default_tool;
this.center_windows = data.center_windows||['preview'];
this.selectCubes = data.selectCubes !== false
this.hide_toolbars = data.hide_toolbars
this.condition = data.condition;
this.onSelect = data.onSelect;
this.onUnselect = data.onUnselect;
Modes.options[this.id] = this;
}
select() {
var scope = this;
if (Modes.selected) {
delete Modes[Modes.selected.id];
Modes.previous_id = Modes.selected.id;
}
if (typeof Modes.selected.onUnselect === 'function') {
Modes.selected.onUnselect()
}
if (Modes.selected.selected) {
Modes.selected.selected = false
}
this.selected = true;
Modes.id = this.id
Modes.selected = this;
Modes[Modes.selected.id] = true;

document.body.setAttribute('mode', this.id);

$('#center > #preview').toggle(this.center_windows.includes('preview'));
$('#center > #timeline').toggle(this.center_windows.includes('timeline'));
$('#center > #start_screen').toggle(this.center_windows.includes('start_screen'));

if (this.hide_toolbars) {
$('#main_toolbar .toolbar_wrapper').css('visibility', 'hidden')
} else {
$('#main_toolbar .toolbar_wrapper').css('visibility', 'visible')
}

if (typeof this.onSelect === 'function') {
this.onSelect()
}

updateInterface()
Canvas.updateRenderSides()
if (BarItems[this.default_tool]) {
BarItems[this.default_tool].select()
} else {
BarItems.move_tool.select()
}
TickUpdates.selection = true;
}
trigger() {
if (Condition(this.condition)) {
this.select()
}
}
}
const Modes = {
id: 'edit',
selected: false,
options: {},
};
onVueSetup(function() {
Modes.vue = new Vue({
el: '#mode_selector',
data: {
options: Modes.options
}
})
});
BARS.defineActions(function() {
new Mode({
id: 'start',
category: 'navigate',
center_windows: ['start_screen'],
hide_toolbars: true,
onSelect: function () {
},
onUnselect: function () {
}
})
new Mode({
id: 'edit',
default_tool: 'move_tool',
category: 'navigate',
condition: () => Format,
keybind: new Keybind({key: 49})
})
new Mode({
id: 'paint',
default_tool: 'brush_tool',
category: 'navigate',
condition: () => Format,
keybind: new Keybind({key: 50}),
onSelect: () => {
if (Modes.previous_id == 'animate') {
Animator.preview();
}
Cube.all.forEach(cube => {
Canvas.buildGridBox(cube)
})
$('#main_colorpicker').spectrum('set', ColorPanel.vue._data.main_color);
BarItems.slider_color_h.update();
BarItems.slider_color_s.update();
BarItems.slider_color_v.update();

$('.UVEditor').find('#uv_size').hide()
three_grid.visible = false;
},
onUnselect: () => {
Cube.all.forEach(cube => {
Canvas.buildGridBox(cube)
})
$('.UVEditor').find('#uv_size').show();
three_grid.visible = true;
},
})
new Mode({
id: 'display',
selectCubes: false,
default_tool: 'move_tool',
category: 'navigate',
keybind: new Keybind({key: 51}),
condition: () => Format.display_mode,
onSelect: () => {
enterDisplaySettings()
},
onUnselect: () => {
exitDisplaySettings()
},
})
new Mode({
id: 'animate',
default_tool: 'move_tool',
category: 'navigate',
center_windows: ['preview', 'timeline'],
keybind: new Keybind({key: 52}),
condition: () => Format.animation_mode,
onSelect: () => {
Animator.join()
},
onUnselect: () => {
Animator.leave()
}
})
//Update to 3.2.0
if (Modes.options.animate.keybind.key == 51) {
Modes.options.animate.keybind.set({key: 52})
}
})
//Backup
setInterval(function() {
if (Outliner.root.length || textures.length) {
Expand Down Expand Up @@ -500,95 +343,6 @@ const TickUpdates = {
}
}

const FormatWizard = {
start() {
var dialog_1 = new Dialog({
id: 'format_wizard_1',
title: 'format_wizard.title',
width: 540,
form: {
question: {type: 'text', text: 'Which platform do you want to create a model for?'},
platform: {label: 'dialog.radio', type: 'radio', options: {
'mcj': 'Minecraft: Java Edition',
'mcbe': 'Minecraft: Bedrock Edition',
'obj': 'Game Engine'
}},
},
onConfirm: function(formResult1) {
if (formResult1.platform == 'obj') {

FormatWizard.result('free');

} else if (formResult1.platform == 'mcbe') {
var types = {
block: 'format_wizard.type.block',
item: 'format_wizard.type.item',
entity: 'format_wizard.type.entity',
}
} else {
var types = {
block: 'format_wizard.type.block',
item: 'format_wizard.type.item',
entity: 'format_wizard.type.entity',
armor: 'format_wizard.type.armor',
}
}
var dialog_2 = new Dialog({
id: 'format_wizard_2',
title: 'format_wizard.title',
width: 540,
form: {
question: {type: 'text', text: 'What type of model do you want to edit?'},
type: {label: 'dialog.radio', type: 'radio', options: types},
},
onConfirm: function(formResult2) {
if (formResult1.platform == 'mcj' && (formResult2.type == 'entity' || formResult2.type == 'armor')) {

var dialog_3 = new Dialog({
id: 'format_wizard_3',
title: 'format_wizard.title',
width: 540,
form: {
question: {type: 'text', text: 'What do you want to create the model for?'},
product: {label: 'dialog.radio', type: 'radio', options: {
vanilla: '',
optifine: '',
modded: '',
}},
},
onConfirm: function(formResult3) {
switch (formResult3.product) {
case 'vanilla':
FormatWizard.result(''); break;
case 'optifine':
FormatWizard.result(formResult2.type == 'armor' ? 'java_armor' : 'optifine_entity'); break;
case 'modded': default:
FormatWizard.result('modded_entity'); break;
}
}
}).show();
} else if (formResult1.platform == 'mcj') {
FormatWizard.result('java_block');
} else {
switch (formResult2.type) {
case 'block':
FormatWizard.result('not_supported_yet'); break;
case 'item':
FormatWizard.result('not_supported_yet'); break;
default:
FormatWizard.result('bedrock'); break;
}
}
}
}).show();
}
}).show();
},
result(result) {

}
}

const entityMode = {
hardcodes: {"geometry.chicken":{"body":{"rotation":[90,0,0]}},"geometry.llama":{"chest1":{"rotation":[0,90,0]},"chest2":{"rotation":[0,90,0]},"body":{"rotation":[90,0,0]}},"geometry.cow":{"body":{"rotation":[90,0,0]}},"geometry.sheep.sheared":{"body":{"rotation":[90,0,0]}},"geometry.sheep":{"body":{"rotation":[90,0,0]}},"geometry.phantom":{"body":{"rotation":[0,0,0]},"wing0":{"rotation":[0,0,5.7]},"wingtip0":{"rotation":[0,0,5.7]},"wing1":{"rotation":[0,0,-5.7]},"wingtip1":{"rotation":[0,0,-5.7]},"head":{"rotation":[11.5,0,0]},"tail":{"rotation":[0,0,0]},"tailtip":{"rotation":[0,0,0]}},"geometry.pig":{"body":{"rotation":[90,0,0]}},"geometry.ocelot":{"body":{"rotation":[90,0,0]},"tail1":{"rotation":[90,0,0]},"tail2":{"rotation":[90,0,0]}},"geometry.cat":{"body":{"rotation":[90,0,0]},"tail1":{"rotation":[90,0,0]},"tail2":{"rotation":[90,0,0]}},"geometry.turtle":{"eggbelly":{"rotation":[90,0,0]},"body":{"rotation":[90,0,0]}},"geometry.villager.witch":{"hat2":{"rotation":[-3,0,1.5]},"hat3":{"rotation":[-6,0,3]},"hat4":{"rotation":[-12,0,6]}},"geometry.pufferfish.mid":{"spines_top_front":{"rotation":[45,0,0]},"spines_top_back":{"rotation":[-45,0,0]},"spines_bottom_front":{"rotation":[-45,0,0]},"spines_bottom_back":{"rotation":[45,0,0]},"spines_left_front":{"rotation":[0,45,0]},"spines_left_back":{"rotation":[0,-45,0]},"spines_right_front":{"rotation":[0,-45,0]},"spines_right_back":{"rotation":[0,45,0]}},"geometry.pufferfish.large":{"spines_top_front":{"rotation":[45,0,0]},"spines_top_back":{"rotation":[-45,0,0]},"spines_bottom_front":{"rotation":[-45,0,0]},"spines_bottom_back":{"rotation":[45,0,0]},"spines_left_front":{"rotation":[0,45,0]},"spines_left_back":{"rotation":[0,-45,0]},"spines_right_front":{"rotation":[0,-45,0]},"spines_right_back":{"rotation":[0,45,0]}},"geometry.tropicalfish_a":{"leftFin":{"rotation":[0,-35,0]},"rightFin":{"rotation":[0,35,0]}},"geometry.tropicalfish_b":{"leftFin":{"rotation":[0,-35,0]},"rightFin":{"rotation":[0,35,0]}}},
hardcodes: JSON.parse('{"geometry.chicken":{"body":{"rotation":[90,0,0]}},"geometry.llama":{"chest1":{"rotation":[0,90,0]},"chest2":{"rotation":[0,90,0]},"body":{"rotation":[90,0,0]}},"geometry.cow":{"body":{"rotation":[90,0,0]}},"geometry.sheep.sheared":{"body":{"rotation":[90,0,0]}},"geometry.sheep":{"body":{"rotation":[90,0,0]}},"geometry.phantom":{"body":{"rotation":[0,0,0]},"wing0":{"rotation":[0,0,5.7]},"wingtip0":{"rotation":[0,0,5.7]},"wing1":{"rotation":[0,0,-5.7]},"wingtip1":{"rotation":[0,0,-5.7]},"head":{"rotation":[11.5,0,0]},"tail":{"rotation":[0,0,0]},"tailtip":{"rotation":[0,0,0]}},"geometry.pig":{"body":{"rotation":[90,0,0]}},"geometry.ocelot":{"body":{"rotation":[90,0,0]},"tail1":{"rotation":[90,0,0]},"tail2":{"rotation":[90,0,0]}},"geometry.cat":{"body":{"rotation":[90,0,0]},"tail1":{"rotation":[90,0,0]},"tail2":{"rotation":[90,0,0]}},"geometry.turtle":{"eggbelly":{"rotation":[90,0,0]},"body":{"rotation":[90,0,0]}},"geometry.villager.witch":{"hat2":{"rotation":[-3,0,1.5]},"hat3":{"rotation":[-6,0,3]},"hat4":{"rotation":[-12,0,6]}},"geometry.pufferfish.mid":{"spines_top_front":{"rotation":[45,0,0]},"spines_top_back":{"rotation":[-45,0,0]},"spines_bottom_front":{"rotation":[-45,0,0]},"spines_bottom_back":{"rotation":[45,0,0]},"spines_left_front":{"rotation":[0,45,0]},"spines_left_back":{"rotation":[0,-45,0]},"spines_right_front":{"rotation":[0,-45,0]},"spines_right_back":{"rotation":[0,45,0]}},"geometry.pufferfish.large":{"spines_top_front":{"rotation":[45,0,0]},"spines_top_back":{"rotation":[-45,0,0]},"spines_bottom_front":{"rotation":[-45,0,0]},"spines_bottom_back":{"rotation":[45,0,0]},"spines_left_front":{"rotation":[0,45,0]},"spines_left_back":{"rotation":[0,-45,0]},"spines_right_front":{"rotation":[0,-45,0]},"spines_right_back":{"rotation":[0,45,0]}},"geometry.tropicalfish_a":{"leftFin":{"rotation":[0,-35,0]},"rightFin":{"rotation":[0,35,0]}},"geometry.tropicalfish_b":{"leftFin":{"rotation":[0,-35,0]},"rightFin":{"rotation":[0,35,0]}}}')
}
2 changes: 1 addition & 1 deletion js/copy_paste.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const Clipbench = {
if (display_mode) {
return Clipbench.types.display_slot
}
if (Animator.open && Timeline.animators.length && (Timeline.selected.length || mode === 2)) {
if (Animator.open && Timeline.animators.length && (Timeline.selected.length || mode === 2) && ['keyframe', 'timeline'].includes(p)) {
return Clipbench.types.keyframe
}
if ((p == 'uv' || p == 'preview') && Modes.edit) {
Expand Down
1 change: 1 addition & 0 deletions js/display_mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,7 @@ exitDisplaySettings = function() { //Enterung Display Setting Mode, changes the
display_area.updateMatrixWorld()
display_base.updateMatrixWorld()
lights.rotation.set(0, 0, 0);
if (scene.parent) scene.parent.remove(scene)

display_mode = false;
main_preview.fullscreen()
Expand Down
4 changes: 4 additions & 0 deletions js/interface/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -1632,6 +1632,10 @@ const BARS = {
'transform_space'
]
})
// update 3.4.1
if (!Toolbars.main_tools.children.includes(BarItems.transform_space)) {
Toolbars.main_tools.add(BarItems.transform_space, -1)
}
Toolbars.brush = new Toolbar({
id: 'brush',
children: [
Expand Down
10 changes: 9 additions & 1 deletion js/interface/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ function Dialog(settings) {

switch (data.type) {
default:
bar.append(`<input class="dark_bordered half focusable_input" type="text" id="${form_id}" value="${data.value||''}" placeholder="${data.placeholder||''}">`)
bar.append(`<input class="dark_bordered half focusable_input" type="text" id="${form_id}" value="${data.value||''}" placeholder="${data.placeholder||''}" ${data.list ? `list="${scope.id}_${form_id}_list"` : ''}>`)
if (data.list) {
let id = `${scope.id}_${form_id}_list`
let list = $(`<datalist id="${scope.id}_${form_id}_list"></datalist>`)
for (let value of data.list) {
list.append(`<option value="${value}">`)
}
bar.append(list)
}
break;
case 'textarea':
bar.append(`<textarea class="focusable_input" style="height: ${data.height||150}px;" id="${form_id}"></textarea>`)
Expand Down
2 changes: 1 addition & 1 deletion js/io/bbmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ var codec = new Codec('project', {
var copy = NonGroup.fromSave(element, true)
for (var face in copy.faces) {
if (!Format.single_texture) {
var texture = element.faces[face].texture && textures[element.faces[face].texture]
var texture = element.faces[face].texture !== null && textures[element.faces[face].texture]
if (texture) {
copy.faces[face].texture = texture.uuid
}
Expand Down
1 change: 1 addition & 0 deletions js/io/gltf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var codec = new Codec('gltf', {
let times = [];
let values = [];
let keyframes = animator[channel].slice();
keyframes.sort((a, b) => a.time - b.time)
keyframes.forEach(kf => {
times.push(kf.time);
Timeline.time = kf.time;
Expand Down
Loading

0 comments on commit 7941f20

Please sign in to comment.