2017-10-27 01:00:52 +08:00
|
|
|
var osfs = '/'
|
|
|
|
var File, i;
|
2018-10-18 01:50:25 +08:00
|
|
|
const elements = [];
|
|
|
|
const TreeElements = [];
|
|
|
|
const textures = [];
|
2018-03-29 02:48:11 +08:00
|
|
|
var selected = [];
|
2017-10-27 01:00:52 +08:00
|
|
|
var prev_side = 'north';
|
|
|
|
var uv_clipboard;
|
|
|
|
var outliner, texturelist;
|
|
|
|
var pe_list_data = []
|
|
|
|
var open_dialog = false;
|
2018-10-18 01:50:25 +08:00
|
|
|
var open_interface = false;
|
2017-10-27 01:00:52 +08:00
|
|
|
var tex_version = 1;
|
|
|
|
var pe_list;
|
2019-04-13 00:44:18 +08:00
|
|
|
const Pressing = {
|
|
|
|
shift: false,
|
|
|
|
ctrl: false,
|
|
|
|
alt: false,
|
|
|
|
}
|
2017-10-27 01:00:52 +08:00
|
|
|
var main_uv;
|
2018-10-18 01:50:25 +08:00
|
|
|
const Prop = {
|
|
|
|
active_panel: 'preview',
|
|
|
|
wireframe: false,
|
|
|
|
file_path: '',
|
|
|
|
file_name: '',
|
|
|
|
added_models: 0,
|
|
|
|
project_saved: true,
|
|
|
|
fps: 0,
|
|
|
|
zoom: 100,
|
2018-12-27 21:03:04 +08:00
|
|
|
progress: 0,
|
2019-04-08 00:53:33 +08:00
|
|
|
session: false,
|
|
|
|
connections: 0,
|
2018-10-18 01:50:25 +08:00
|
|
|
facing: 'north'
|
|
|
|
}
|
|
|
|
const Project = {
|
|
|
|
name : '',
|
|
|
|
parent : '',
|
|
|
|
description : '',
|
|
|
|
texture_width : 16,
|
|
|
|
texture_height : 16,
|
|
|
|
ambientocclusion: true,
|
2019-03-10 05:06:35 +08:00
|
|
|
get geometry_name() {
|
|
|
|
return this.parent;
|
|
|
|
},
|
|
|
|
set geometry_name(n) {
|
|
|
|
this.parent = n;
|
|
|
|
},
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
2019-01-09 22:54:35 +08:00
|
|
|
const mouse_pos = {x:0,y:0}
|
|
|
|
const sort_collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
|
2017-10-27 01:00:52 +08:00
|
|
|
|
|
|
|
$.ajaxSetup({ cache: false });
|
|
|
|
|
|
|
|
|
|
|
|
function initializeApp() {
|
2018-10-18 01:50:25 +08:00
|
|
|
//Browser Detection
|
|
|
|
Blockbench.browser = 'electron'
|
|
|
|
if (isApp === false) {
|
|
|
|
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
|
|
|
|
Blockbench.browser = 'firefox'
|
|
|
|
} else if (!!window.chrome && !!window.chrome.webstore) {
|
|
|
|
Blockbench.browser = 'chrome'
|
|
|
|
} else if ((!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0) {
|
|
|
|
Blockbench.browser = 'opera'
|
|
|
|
} else if (/constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification))) {
|
|
|
|
Blockbench.browser = 'safari'
|
|
|
|
} else if (!!document.documentMode) {
|
|
|
|
Blockbench.browser = 'internet_explorer'
|
|
|
|
} else if (!!window.StyleMedia) {
|
|
|
|
Blockbench.browser = 'edge'
|
|
|
|
}
|
|
|
|
if (navigator.appVersion.indexOf("Win") != -1) OSName = 'Windows';
|
|
|
|
if (navigator.appVersion.indexOf("Mac") != -1) OSName = 'MacOS';
|
|
|
|
if (navigator.appVersion.indexOf("Linux") != -1)OSName = 'Linux';
|
|
|
|
if (['edge', 'internet_explorer'].includes(Blockbench.browser)) {
|
|
|
|
alert(capitalizeFirstLetter(Blockbench.browser)+' does not support Blockbench')
|
|
|
|
}
|
|
|
|
$('.local_only').remove()
|
|
|
|
} else {
|
|
|
|
$('.web_only').remove()
|
|
|
|
}
|
2018-12-29 19:26:02 +08:00
|
|
|
if (localStorage.getItem('welcomed_version') != appVersion) {
|
|
|
|
Blockbench.addFlag('after_update')
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
BARS.setupActions()
|
|
|
|
BARS.setupToolbars()
|
|
|
|
BARS.setupVue()
|
|
|
|
MenuBar.setup()
|
|
|
|
|
|
|
|
//Misc
|
|
|
|
translateUI()
|
2019-02-04 04:09:35 +08:00
|
|
|
console.log('Blockbench ' + appVersion + (isApp
|
|
|
|
? (' Desktop (' + Blockbench.operating_system +')')
|
|
|
|
: (' Web ('+capitalizeFirstLetter(Blockbench.browser)+')')
|
|
|
|
))
|
2018-10-18 01:50:25 +08:00
|
|
|
if (localStorage.getItem('donated') == 'true') {
|
|
|
|
$('#donation_hint').remove()
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isApp) {
|
|
|
|
updateRecentProjects()
|
|
|
|
}
|
|
|
|
|
|
|
|
setInterval(function() {
|
|
|
|
Prop.fps = framespersecond;
|
|
|
|
framespersecond = 0;
|
|
|
|
}, 1000)
|
|
|
|
Blockbench.entity_mode = false
|
|
|
|
|
|
|
|
main_uv = new UVEditor('main_uv', false, true)
|
|
|
|
main_uv.setToMainSlot()
|
|
|
|
|
2019-02-04 04:09:35 +08:00
|
|
|
onVueSetup.funcs.forEach((func) => {
|
|
|
|
if (typeof func === 'function') {
|
|
|
|
func()
|
|
|
|
}
|
|
|
|
})
|
2017-10-27 01:00:52 +08:00
|
|
|
|
|
|
|
//JQuery UI
|
2018-10-18 01:50:25 +08:00
|
|
|
$('#cubes_list').droppable({
|
|
|
|
greedy: true,
|
|
|
|
accept: 'div.outliner_object',
|
|
|
|
tolerance: 'pointer',
|
|
|
|
hoverClass: 'drag_hover',
|
|
|
|
drop: function(event, ui) {
|
|
|
|
var item = TreeElements.findRecursive('uuid', $(ui.draggable).parent().attr('id'))
|
|
|
|
dropOutlinerObjects(item, undefined, event)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
$('#cubes_list').contextmenu(function(event) {
|
2018-12-03 02:37:06 +08:00
|
|
|
Interface.Panels.outliner.menu.show(event)
|
2018-10-18 01:50:25 +08:00
|
|
|
})
|
|
|
|
$('#texture_list').contextmenu(function(event) {
|
2018-12-03 02:37:06 +08:00
|
|
|
Interface.Panels.textures.menu.show(event)
|
2018-10-18 01:50:25 +08:00
|
|
|
})
|
|
|
|
$(window).on( "unload", saveLocalStorages)
|
|
|
|
|
|
|
|
setupInterface()
|
|
|
|
setupDragHandlers()
|
2018-12-27 21:03:04 +08:00
|
|
|
Modes.options.edit.select()
|
2018-11-12 04:19:08 +08:00
|
|
|
Blockbench.setup_successful = true
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
2019-02-04 04:09:35 +08:00
|
|
|
function onVueSetup(func) {
|
|
|
|
if (!onVueSetup.funcs) {
|
|
|
|
onVueSetup.funcs = []
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
2019-02-04 04:09:35 +08:00
|
|
|
onVueSetup.funcs.push(func)
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
2017-11-17 05:23:41 +08:00
|
|
|
function canvasGridSize(shift, ctrl) {
|
2018-10-18 01:50:25 +08:00
|
|
|
if (!shift && !ctrl) {
|
2018-12-27 21:03:04 +08:00
|
|
|
return 16 / limitNumber(settings.edit_size.value, 1, 1024)
|
2018-10-18 01:50:25 +08:00
|
|
|
} else if (ctrl && shift) {
|
2018-12-27 21:03:04 +08:00
|
|
|
var basic = 16 / limitNumber(settings.edit_size.value, 1, 1024)
|
2018-10-18 01:50:25 +08:00
|
|
|
var control = 16 / limitNumber(settings.ctrl_size.value, 1, 1024)
|
|
|
|
var shift = 16 / limitNumber(settings.shift_size.value, 1, 1024)
|
|
|
|
control = basic / control
|
|
|
|
return shift / control
|
|
|
|
} else if (ctrl) {
|
|
|
|
return 16 / limitNumber(settings.ctrl_size.value, 1, 1024)
|
|
|
|
} else {
|
|
|
|
return 16 / limitNumber(settings.shift_size.value, 1, 1024)
|
|
|
|
}
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
|
|
|
function updateNslideValues() {
|
2018-10-18 01:50:25 +08:00
|
|
|
//if (!selected.length && (!Blockbench.entity_mode || !selected_group)) return;
|
|
|
|
|
|
|
|
if (selected.length) {
|
|
|
|
BarItems.slider_pos_x.update()
|
|
|
|
BarItems.slider_pos_y.update()
|
|
|
|
BarItems.slider_pos_z.update()
|
|
|
|
|
|
|
|
BarItems.slider_size_x.update()
|
|
|
|
BarItems.slider_size_y.update()
|
|
|
|
BarItems.slider_size_z.update()
|
|
|
|
|
2019-03-10 05:06:35 +08:00
|
|
|
BarItems.slider_inflate.update()
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
if (selected.length || (Blockbench.entity_mode && selected_group)) {
|
|
|
|
BarItems.slider_origin_x.update()
|
|
|
|
BarItems.slider_origin_y.update()
|
|
|
|
BarItems.slider_origin_z.update()
|
|
|
|
|
|
|
|
BarItems.slider_rotation_x.update()
|
|
|
|
BarItems.slider_rotation_y.update()
|
|
|
|
BarItems.slider_rotation_z.update()
|
|
|
|
if (Blockbench.entity_mode) {
|
|
|
|
BarItems.bone_reset_toggle.setIcon(selected_group && selected_group.reset ? 'check_box' : 'check_box_outline_blank')
|
|
|
|
} else {
|
|
|
|
BarItems.rescale_toggle.setIcon(selected[0].rescale ? 'check_box' : 'check_box_outline_blank')
|
|
|
|
}
|
|
|
|
}
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//Selections
|
|
|
|
function updateSelection() {
|
2018-10-18 01:50:25 +08:00
|
|
|
//Clear
|
2018-11-12 04:19:08 +08:00
|
|
|
if (rot_origin.parent) {
|
|
|
|
rot_origin.parent.remove(rot_origin)
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
Transformer.detach()
|
|
|
|
Transformer.hoverAxis = null;
|
2018-12-27 21:03:04 +08:00
|
|
|
if (display_mode) {
|
|
|
|
DisplayMode.centerTransformer()
|
|
|
|
}
|
|
|
|
|
2018-10-18 01:50:25 +08:00
|
|
|
elements.forEach(function(obj) {
|
|
|
|
var is_in_selection = selected.includes(obj)
|
|
|
|
if (is_in_selection !== obj.selected) {
|
|
|
|
obj.selected = is_in_selection
|
|
|
|
}
|
|
|
|
if (obj.selected === true) {
|
2018-12-27 21:03:04 +08:00
|
|
|
if (Toolbox.selected.transformerMode !== 'hidden' && obj.visibility === true && (Toolbox.selected.transformerMode !== 'rotate' || !Blockbench.entity_mode)) {
|
2019-01-09 22:54:35 +08:00
|
|
|
Transformer.attach(obj.mesh)
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj.visibility) {
|
2019-01-09 22:54:35 +08:00
|
|
|
var mesh = obj.mesh
|
2018-12-03 02:37:06 +08:00
|
|
|
if (mesh && mesh.outline) {
|
2018-10-18 01:50:25 +08:00
|
|
|
mesh.outline.visible = obj.selected
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
//Interface
|
|
|
|
if (selected.length > 0) {
|
|
|
|
$('.selection_only').css('visibility', 'visible')
|
2019-02-04 04:09:35 +08:00
|
|
|
main_uv.jquery.size.find('.uv_mapping_overlay').remove()
|
2018-10-18 01:50:25 +08:00
|
|
|
main_uv.loadData()
|
2019-02-04 04:09:35 +08:00
|
|
|
} else {
|
2018-10-18 01:50:25 +08:00
|
|
|
$('.selection_only').css('visibility', 'hidden')
|
|
|
|
}
|
2018-12-29 19:26:02 +08:00
|
|
|
BarItems.cube_counter.update()
|
2018-10-18 01:50:25 +08:00
|
|
|
updateNslideValues()
|
|
|
|
//Misc
|
|
|
|
Blockbench.globalMovement = isMovementGlobal()
|
|
|
|
centerTransformer()
|
|
|
|
if (Blockbench.entity_mode) {
|
|
|
|
if (selected_group) {
|
|
|
|
$('.selection_only#options').css('visibility', 'visible')
|
2018-12-03 02:37:06 +08:00
|
|
|
if (settings.origin_size.value > 0 && selected_group.visibility) {
|
2019-01-09 22:54:35 +08:00
|
|
|
selected_group.mesh.add(rot_origin)
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
2018-12-27 21:03:04 +08:00
|
|
|
if (Toolbox.selected.transformerMode === 'rotate') {
|
2019-01-09 22:54:35 +08:00
|
|
|
Transformer.attach(selected_group.mesh)
|
2018-12-27 21:03:04 +08:00
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
} else {
|
|
|
|
$('.selection_only#options').css('visibility', 'hidden')
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
if (Animator.open && Animator.selected && selected_group) {
|
|
|
|
Animator.selected.getBoneAnimator().select()
|
|
|
|
}
|
|
|
|
if (Animator.open) {
|
|
|
|
updateKeyframeSelection()
|
2018-10-24 03:49:04 +08:00
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
} else {
|
|
|
|
//Origin Helper
|
2018-11-12 04:19:08 +08:00
|
|
|
if (selected.length === 1 && selected[0].visibility) {
|
2019-01-09 22:54:35 +08:00
|
|
|
let mesh = selected[0].mesh
|
2018-12-03 02:37:06 +08:00
|
|
|
if (mesh) {
|
|
|
|
mesh.add(rot_origin)
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
} else if (selected.length > 0) {
|
|
|
|
var origin = null;
|
|
|
|
var first_visible = null;
|
|
|
|
var i = 0;
|
|
|
|
while (i < selected.length) {
|
|
|
|
if (selected[i].visibility) {
|
|
|
|
|
|
|
|
if (first_visible === null) {
|
|
|
|
first_visible = selected[i]
|
|
|
|
}
|
|
|
|
if (origin === null) {
|
|
|
|
origin = selected[i].origin
|
|
|
|
} else if (!origin.equals(selected[i].origin)) {
|
|
|
|
origin = false;
|
|
|
|
i = Infinity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (first_visible && typeof origin === 'object') {
|
2019-01-09 22:54:35 +08:00
|
|
|
let mesh = first_visible.mesh
|
2018-12-03 02:37:06 +08:00
|
|
|
if (mesh) {
|
|
|
|
mesh.add(rot_origin)
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Transformer.update()
|
|
|
|
BARS.updateConditions()
|
|
|
|
Blockbench.dispatchEvent('update_selection')
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
|
|
|
function selectAll() {
|
2018-10-18 01:50:25 +08:00
|
|
|
if (selected.length < elements.length) {
|
|
|
|
selected.length = 0
|
|
|
|
var i = 0;
|
|
|
|
while (elements.length > i) {
|
|
|
|
selected.push(elements[i])
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
selected.length = 0
|
|
|
|
if (selected_group) selected_group.unselect()
|
|
|
|
}
|
|
|
|
updateSelection()
|
|
|
|
Blockbench.dispatchEvent('select_all')
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
|
|
|
function unselectAll() {
|
2018-10-18 01:50:25 +08:00
|
|
|
selected.length = 0
|
|
|
|
if (selected_group) selected_group.unselect()
|
|
|
|
getAllOutlinerGroups().forEach(function(s) {
|
|
|
|
s.selected = false
|
|
|
|
})
|
|
|
|
updateSelection()
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
|
|
|
function createSelection() {
|
2018-10-18 01:50:25 +08:00
|
|
|
if ($('#selgen_new').is(':checked')) {
|
|
|
|
selected.length = 0
|
|
|
|
}
|
|
|
|
if (selected_group) {
|
|
|
|
selected_group.unselect()
|
|
|
|
}
|
|
|
|
var name_seg = $('#selgen_name').val().toUpperCase()
|
|
|
|
var rdm = $('#selgen_random').val()/100
|
|
|
|
|
|
|
|
var array = elements
|
|
|
|
if ($('#selgen_group').is(':checked') && selected_group) {
|
|
|
|
array = selected_group.children
|
|
|
|
}
|
|
|
|
|
|
|
|
array.forEach(function(s) {
|
|
|
|
if (s.name.toUpperCase().includes(name_seg) === false) return;
|
|
|
|
if (Math.random() > rdm) return;
|
|
|
|
selected.push(s)
|
|
|
|
})
|
|
|
|
updateSelection()
|
|
|
|
if (selected.length) {
|
|
|
|
selected[0].showInOutliner()
|
|
|
|
}
|
|
|
|
hideDialog()
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
2018-12-27 21:03:04 +08:00
|
|
|
//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.selectCubes = data.selectCubes !== false
|
|
|
|
this.condition = data.condition;
|
|
|
|
this.onSelect = data.onSelect;
|
|
|
|
this.onUnselect = data.onUnselect;
|
|
|
|
Modes.options[this.id] = this;
|
|
|
|
}
|
|
|
|
select() {
|
|
|
|
if (typeof Modes.selected.onUnselect === 'function') {
|
|
|
|
Modes.selected.onUnselect()
|
|
|
|
}
|
|
|
|
if (Modes.selected.selected) {
|
|
|
|
Modes.selected.selected = false
|
|
|
|
}
|
|
|
|
if (typeof this.onSelect === 'function') {
|
|
|
|
this.onSelect()
|
|
|
|
}
|
|
|
|
this.selected = true;
|
|
|
|
Modes.id = this.id
|
|
|
|
Modes.selected = this;
|
|
|
|
updateInterface()
|
|
|
|
Canvas.updateRenderSides()
|
|
|
|
if (BarItems[this.default_tool]) {
|
|
|
|
BarItems[this.default_tool].select()
|
|
|
|
} else {
|
|
|
|
BarItems.move_tool.select()
|
|
|
|
}
|
|
|
|
updateSelection()
|
|
|
|
}
|
|
|
|
trigger() {
|
|
|
|
if (Condition(this.condition)) {
|
|
|
|
this.select()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const Modes = {
|
|
|
|
id: 'edit',
|
|
|
|
selected: false,
|
|
|
|
options: {},
|
|
|
|
};
|
2019-02-04 04:09:35 +08:00
|
|
|
onVueSetup(function() {
|
|
|
|
Modes.vue = new Vue({
|
|
|
|
el: '#mode_selector',
|
|
|
|
data: {
|
|
|
|
options: Modes.options
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
2018-12-27 21:03:04 +08:00
|
|
|
BARS.defineActions(function() {
|
|
|
|
new Mode({
|
|
|
|
id: 'edit',
|
|
|
|
default_tool: 'move_tool',
|
2019-04-08 00:53:33 +08:00
|
|
|
category: 'navigate',
|
2018-12-27 21:03:04 +08:00
|
|
|
keybind: new Keybind({key: 49})
|
|
|
|
})
|
|
|
|
new Mode({
|
|
|
|
id: 'paint',
|
|
|
|
default_tool: 'brush_tool',
|
2019-04-08 00:53:33 +08:00
|
|
|
category: 'navigate',
|
2018-12-27 21:03:04 +08:00
|
|
|
keybind: new Keybind({key: 50})
|
|
|
|
})
|
|
|
|
new Mode({
|
|
|
|
id: 'display',
|
|
|
|
selectCubes: false,
|
|
|
|
default_tool: 'move_tool',
|
2019-04-08 00:53:33 +08:00
|
|
|
category: 'navigate',
|
2018-12-27 21:03:04 +08:00
|
|
|
keybind: new Keybind({key: 51}),
|
|
|
|
condition: () => !Blockbench.entity_mode,
|
|
|
|
onSelect: () => {
|
|
|
|
enterDisplaySettings()
|
|
|
|
},
|
|
|
|
onUnselect: () => {
|
|
|
|
exitDisplaySettings()
|
|
|
|
},
|
|
|
|
})
|
|
|
|
new Mode({
|
|
|
|
id: 'animate',
|
|
|
|
default_tool: 'move_tool',
|
2019-04-08 00:53:33 +08:00
|
|
|
category: 'navigate',
|
2018-12-27 21:03:04 +08:00
|
|
|
keybind: new Keybind({key: 51}),
|
|
|
|
condition: () => Blockbench.entity_mode,
|
|
|
|
onSelect: () => {
|
|
|
|
Animator.join()
|
|
|
|
},
|
|
|
|
onUnselect: () => {
|
|
|
|
Animator.leave()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
2019-04-08 00:53:33 +08:00
|
|
|
//Backup
|
|
|
|
setInterval(function() {
|
|
|
|
if (TreeElements.length || textures.length) {
|
|
|
|
try {
|
|
|
|
var model = buildBBModel()
|
|
|
|
localStorage.setItem('backup_model', model)
|
|
|
|
} catch (err) {
|
|
|
|
console.log('Unable to create backup. ', err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 1e3*30)
|
2017-10-27 01:00:52 +08:00
|
|
|
//Misc
|
2019-03-10 05:06:35 +08:00
|
|
|
const TickUpdates = {
|
|
|
|
Run: function() {
|
|
|
|
if (TickUpdates.outliner) {
|
|
|
|
delete TickUpdates.outliner;
|
|
|
|
loadOutlinerDraggable()
|
|
|
|
}
|
|
|
|
if (TickUpdates.selection) {
|
|
|
|
delete TickUpdates.selection;
|
|
|
|
updateSelection()
|
|
|
|
}
|
2019-04-08 00:53:33 +08:00
|
|
|
if (TickUpdates.main_uv) {
|
|
|
|
delete TickUpdates.main_uv;
|
|
|
|
main_uv.loadData()
|
|
|
|
}
|
|
|
|
if (TickUpdates.texture_list) {
|
|
|
|
delete TickUpdates.texture_list;
|
|
|
|
loadTextureDraggable();
|
|
|
|
}
|
|
|
|
if (TickUpdates.keyframes) {
|
|
|
|
delete TickUpdates.keyframes;
|
|
|
|
Vue.nextTick(Timeline.update)
|
|
|
|
}
|
2019-03-10 05:06:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
const Screencam = {
|
2018-10-18 01:50:25 +08:00
|
|
|
fullScreen: function(options, cb) {
|
|
|
|
setTimeout(function() {
|
|
|
|
currentwindow.capturePage(function(screenshot) {
|
|
|
|
var dataUrl = screenshot.toDataURL()
|
|
|
|
dataUrl = dataUrl.replace('data:image/png;base64,','')
|
2018-11-12 04:19:08 +08:00
|
|
|
Jimp.read(Buffer.from(dataUrl, 'base64')).then(function(image) {
|
2018-10-18 01:50:25 +08:00
|
|
|
|
|
|
|
if (options && options.width && options.height) {
|
|
|
|
image.contain(options.width, options.height)
|
|
|
|
}
|
|
|
|
|
|
|
|
image.getBase64(Jimp.MIME_PNG, function(a, dataUrl){
|
|
|
|
Screencam.returnScreenshot(dataUrl, cb)
|
|
|
|
})
|
|
|
|
});
|
|
|
|
})
|
|
|
|
}, 40)
|
|
|
|
},
|
|
|
|
returnScreenshot: function(dataUrl, cb) {
|
|
|
|
if (cb) {
|
|
|
|
cb(dataUrl)
|
|
|
|
} else if (isApp) {
|
|
|
|
var screenshot = nativeImage.createFromDataURL(dataUrl)
|
|
|
|
var img = new Image()
|
2018-12-03 02:37:06 +08:00
|
|
|
var is_gif = dataUrl.substr(5, 9) == 'image/gif'
|
2018-10-18 01:50:25 +08:00
|
|
|
img.src = dataUrl
|
2018-12-03 02:37:06 +08:00
|
|
|
|
2018-12-27 21:03:04 +08:00
|
|
|
var btns = [tl('dialog.cancel'), tl('dialog.save')]
|
2018-12-03 02:37:06 +08:00
|
|
|
if (!is_gif) {
|
|
|
|
btns.push(tl('message.screenshot.clipboard'))
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
Blockbench.showMessageBox({
|
|
|
|
translateKey: 'screenshot',
|
|
|
|
icon: img,
|
2018-12-03 02:37:06 +08:00
|
|
|
buttons: btns,
|
2018-12-27 21:03:04 +08:00
|
|
|
confirm: 1,
|
|
|
|
cancel: 0
|
2018-10-18 01:50:25 +08:00
|
|
|
}, function(result) {
|
2018-12-27 21:03:04 +08:00
|
|
|
if (result === 1) {
|
2019-01-09 22:54:35 +08:00
|
|
|
electron.dialog.showSaveDialog(currentwindow, {filters: [ {name: tl('data.image'), extensions: [is_gif ? 'gif' : 'png']} ]}, function (fileName) {
|
2018-10-18 01:50:25 +08:00
|
|
|
if (fileName === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
2018-12-03 02:37:06 +08:00
|
|
|
//fs.writeFile(fileName, screenshot.toPNG(), function (err) {})
|
|
|
|
fs.writeFile(fileName, Buffer(dataUrl.split(',')[1],'base64'), err => {})
|
2018-10-18 01:50:25 +08:00
|
|
|
})
|
2018-12-27 21:03:04 +08:00
|
|
|
} else if (result === 2) {
|
2018-10-18 01:50:25 +08:00
|
|
|
clipboard.writeImage(screenshot)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
new Dialog({
|
|
|
|
title: tl('message.screenshot.right_click'),
|
|
|
|
id: 'screenie',
|
|
|
|
lines: ['<img src="'+dataUrl+'" width="600px" class="allow_default_menu"></img>'],
|
|
|
|
draggable: true,
|
|
|
|
singleButton: true
|
|
|
|
}).show()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
cleanCanvas: function(options, cb) {
|
|
|
|
quad_previews.current.screenshot(options, cb)
|
2018-12-03 02:37:06 +08:00
|
|
|
},
|
|
|
|
createGif: function(options, cb) {
|
|
|
|
if (typeof options !== 'object') {
|
|
|
|
options = {}
|
|
|
|
}
|
2018-12-27 21:03:04 +08:00
|
|
|
if (!options.length) {
|
|
|
|
options.length = 1000
|
|
|
|
}
|
2019-04-08 00:53:33 +08:00
|
|
|
var preview = quad_previews.current;
|
2018-12-03 02:37:06 +08:00
|
|
|
var interval = options.fps ? (1000/options.fps) : 100
|
|
|
|
var gif = new GIF({
|
|
|
|
repeat: options.repeat,
|
|
|
|
quality: options.quality,
|
|
|
|
transparent: 0x000000,
|
|
|
|
})
|
2018-12-27 21:03:04 +08:00
|
|
|
var frame_count = (options.length/interval)
|
|
|
|
|
2019-04-08 00:53:33 +08:00
|
|
|
if (options.turnspeed) {
|
|
|
|
preview.controls.autoRotate = true;
|
|
|
|
preview.controls.autoRotateSpeed = options.turnspeed;
|
|
|
|
}
|
|
|
|
|
2018-12-27 21:03:04 +08:00
|
|
|
gif.on('finished', blob => {
|
|
|
|
var reader = new FileReader()
|
|
|
|
reader.onload = () => {
|
|
|
|
if (!options.silent) {
|
|
|
|
Blockbench.setProgress(0)
|
|
|
|
Blockbench.setStatusBarText()
|
|
|
|
}
|
|
|
|
Screencam.returnScreenshot(reader.result, cb)
|
|
|
|
}
|
|
|
|
reader.readAsDataURL(blob)
|
|
|
|
})
|
|
|
|
if (!options.silent) {
|
|
|
|
Blockbench.setStatusBarText(tl('status_bar.recording_gif'))
|
|
|
|
gif.on('progress', Blockbench.setProgress)
|
|
|
|
}
|
|
|
|
var frames = 0;
|
|
|
|
var loop = setInterval(() => {
|
|
|
|
var img = new Image()
|
2019-04-08 00:53:33 +08:00
|
|
|
img.src = preview.canvas.toDataURL()
|
2018-12-27 21:03:04 +08:00
|
|
|
img.onload = () => {
|
|
|
|
gif.addFrame(img, {delay: interval})
|
|
|
|
}
|
|
|
|
Blockbench.setProgress(interval*frames/options.length)
|
|
|
|
frames++;
|
2018-12-03 02:37:06 +08:00
|
|
|
}, interval)
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
clearInterval(loop)
|
2018-12-27 21:03:04 +08:00
|
|
|
if (!options.silent) {
|
|
|
|
Blockbench.setStatusBarText(tl('status_bar.processing_gif'))
|
|
|
|
}
|
2018-12-03 02:37:06 +08:00
|
|
|
gif.render()
|
|
|
|
if (Animator.open && Timeline.playing) {
|
|
|
|
Timeline.pause()
|
|
|
|
}
|
2019-04-08 00:53:33 +08:00
|
|
|
if (options.turnspeed) {
|
|
|
|
preview.controls.autoRotate = false;
|
|
|
|
}
|
2018-12-27 21:03:04 +08:00
|
|
|
}, options.length)
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
2019-03-10 05:06:35 +08:00
|
|
|
const Clipbench = {
|
2018-10-18 01:50:25 +08:00
|
|
|
cubes: [],
|
|
|
|
copy: function(event, cut) {
|
|
|
|
var p = Prop.active_panel
|
2019-04-13 00:44:18 +08:00
|
|
|
var text = window.getSelection()+''
|
|
|
|
if (text) {
|
|
|
|
Clipbench.setText(text)
|
|
|
|
|
|
|
|
} else if (open_dialog == 'uv_dialog') {
|
2018-10-18 01:50:25 +08:00
|
|
|
uv_dialog.copy(event)
|
2019-04-13 00:44:18 +08:00
|
|
|
|
2018-10-18 01:50:25 +08:00
|
|
|
} else if (display_mode) {
|
2018-12-16 23:18:20 +08:00
|
|
|
DisplayMode.copy()
|
2019-04-13 00:44:18 +08:00
|
|
|
|
2018-11-12 04:19:08 +08:00
|
|
|
} else if (Animator.open) {
|
|
|
|
if (Timeline.selected.length) {
|
|
|
|
Clipbench.setKeyframes(Timeline.selected)
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
} else if (p == 'uv' || p == 'preview') {
|
|
|
|
main_uv.copy(event)
|
2019-04-13 00:44:18 +08:00
|
|
|
|
2018-10-18 01:50:25 +08:00
|
|
|
} else if (p == 'textures' && isApp) {
|
|
|
|
if (textures.selected) {
|
|
|
|
Clipbench.setTexture(textures.selected)
|
|
|
|
}
|
|
|
|
} else if (p == 'outliner') {
|
|
|
|
Clipbench.setCubes()
|
|
|
|
Clipbench.setGroup()
|
|
|
|
if (selected_group) {
|
|
|
|
Clipbench.setGroup(selected_group)
|
|
|
|
} else {
|
|
|
|
Clipbench.setCubes(selected)
|
|
|
|
}
|
|
|
|
if (cut) {
|
2019-04-08 00:53:33 +08:00
|
|
|
BarItems.delete.trigger()
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
paste: function(event) {
|
|
|
|
var p = Prop.active_panel
|
|
|
|
if (open_dialog == 'uv_dialog') {
|
|
|
|
uv_dialog.paste(event)
|
|
|
|
} else if (display_mode) {
|
2018-12-16 23:18:20 +08:00
|
|
|
DisplayMode.paste()
|
2018-11-12 04:19:08 +08:00
|
|
|
} else if (Animator.open) {
|
|
|
|
//
|
|
|
|
if (isApp) {
|
|
|
|
var raw = clipboard.readHTML()
|
|
|
|
try {
|
|
|
|
var data = JSON.parse(raw)
|
|
|
|
if (data.type === 'keyframes' && data.content) {
|
|
|
|
Clipbench.keyframes = data.content
|
|
|
|
}
|
|
|
|
} catch (err) {}
|
|
|
|
}
|
|
|
|
if (Clipbench.keyframes && Clipbench.keyframes.length) {
|
|
|
|
|
|
|
|
if (!Animator.selected) return;
|
|
|
|
var bone = Animator.selected.getBoneAnimator()
|
|
|
|
if (bone) {
|
|
|
|
Clipbench.keyframes.forEach(function(data) {
|
|
|
|
var base_kf = new Keyframe(data)
|
|
|
|
base_kf.time = Timeline.second + data.time_offset
|
|
|
|
bone.pushKeyframe(base_kf)
|
|
|
|
})
|
|
|
|
Vue.nextTick(Timeline.update)
|
|
|
|
}
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
} else if (p == 'uv' || p == 'preview') {
|
|
|
|
main_uv.paste(event)
|
|
|
|
} else if (p == 'textures' && isApp) {
|
|
|
|
var img = clipboard.readImage()
|
|
|
|
if (img) {
|
|
|
|
var dataUrl = img.toDataURL()
|
2019-04-08 00:53:33 +08:00
|
|
|
var texture = new Texture({name: 'pasted', folder: 'blocks' }).fromDataURL(dataUrl).fillParticle().add(true)
|
2018-10-18 01:50:25 +08:00
|
|
|
setTimeout(function() {
|
|
|
|
texture.openMenu()
|
|
|
|
},40)
|
|
|
|
}
|
|
|
|
} else if (p == 'outliner') {
|
|
|
|
|
|
|
|
Undo.initEdit({outliner: true, cubes: [], selection: true});
|
|
|
|
//Group
|
2019-03-10 05:06:35 +08:00
|
|
|
var target = 'root'
|
2018-10-18 01:50:25 +08:00
|
|
|
if (selected_group) {
|
2019-03-10 05:06:35 +08:00
|
|
|
target = selected_group
|
2019-01-09 22:54:35 +08:00
|
|
|
selected_group.isOpen = true
|
2018-10-18 01:50:25 +08:00
|
|
|
} else if (selected[0]) {
|
2019-03-10 05:06:35 +08:00
|
|
|
target = selected[0]
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
selected.length = 0
|
|
|
|
if (isApp) {
|
|
|
|
var raw = clipboard.readHTML()
|
|
|
|
try {
|
|
|
|
var data = JSON.parse(raw)
|
|
|
|
if (data.type === 'cubes' && data.content) {
|
|
|
|
Clipbench.group = undefined
|
|
|
|
Clipbench.cubes = data.content
|
|
|
|
} else if (data.type === 'group' && data.content) {
|
|
|
|
Clipbench.group = data.content
|
|
|
|
Clipbench.cubes = []
|
|
|
|
}
|
|
|
|
} catch (err) {}
|
|
|
|
}
|
|
|
|
if (Clipbench.group) {
|
2019-03-10 05:06:35 +08:00
|
|
|
function iterate(obj, parent) {
|
|
|
|
if (obj.children) {
|
|
|
|
var copy = new Group(obj)
|
|
|
|
if (obj.children && obj.children.length) {
|
|
|
|
obj.children.forEach((child) => {
|
|
|
|
iterate(child, copy)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
copy.addTo(parent)
|
|
|
|
} else {
|
|
|
|
var copy = new Cube(obj)
|
|
|
|
copy.addTo(parent).init()
|
|
|
|
selected.push(elements[elements.length-1])
|
|
|
|
}
|
2019-01-09 22:54:35 +08:00
|
|
|
}
|
2019-03-10 05:06:35 +08:00
|
|
|
iterate(Clipbench.group, target)
|
|
|
|
updateSelection()
|
2018-10-18 01:50:25 +08:00
|
|
|
|
2019-03-10 05:06:35 +08:00
|
|
|
} else if (Clipbench.cubes && Clipbench.cubes.length) {
|
|
|
|
Clipbench.cubes.forEach(function(obj) {
|
|
|
|
var copy = new Cube(obj)
|
|
|
|
copy.addTo(target).init()
|
2018-10-18 01:50:25 +08:00
|
|
|
selected.push(elements[elements.length-1])
|
|
|
|
})
|
|
|
|
updateSelection()
|
|
|
|
}
|
|
|
|
Undo.finishEdit('paste', {outliner: true, cubes: selected, selection: true});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setTexture: function(texture) {
|
|
|
|
//Sets the raw image of the texture
|
|
|
|
if (!isApp) return;
|
|
|
|
|
|
|
|
if (texture.mode === 'bitmap') {
|
|
|
|
var img = nativeImage.createFromDataURL(texture.source)
|
|
|
|
} else {
|
|
|
|
var img = nativeImage.createFromPath(texture.source.split('?')[0])
|
|
|
|
}
|
|
|
|
clipboard.writeImage(img)
|
|
|
|
},
|
|
|
|
setGroup: function(group) {
|
|
|
|
if (!group) {
|
|
|
|
Clipbench.group = undefined
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Clipbench.group = group.duplicate('cache')
|
|
|
|
if (isApp) {
|
|
|
|
clipboard.writeHTML(JSON.stringify({type: 'group', content: Clipbench.group}))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
setCubes: function(cubes) {
|
|
|
|
if (!cubes) {
|
|
|
|
Clipbench.cubes = []
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
cubes.forEach(function(obj) {
|
|
|
|
var base_cube = new Cube(obj)
|
|
|
|
Clipbench.cubes.push(base_cube)
|
|
|
|
})
|
|
|
|
if (isApp) {
|
|
|
|
clipboard.writeHTML(JSON.stringify({type: 'cubes', content: Clipbench.cubes}))
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
},
|
|
|
|
setKeyframes: function(keyframes) {
|
|
|
|
Clipbench.keyframes = []
|
|
|
|
if (!keyframes || keyframes.length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var first = keyframes[0];
|
|
|
|
keyframes.forEach(function(kf) {
|
|
|
|
if (kf.time < first.time) {
|
|
|
|
first = kf
|
|
|
|
}
|
|
|
|
})
|
|
|
|
keyframes.forEach(function(kf) {
|
|
|
|
Clipbench.keyframes.push({
|
|
|
|
channel: kf.channel,
|
|
|
|
x: kf.x,
|
|
|
|
y: kf.y,
|
|
|
|
z: kf.z,
|
|
|
|
w: kf.w,
|
|
|
|
isQuaternion: kf.isQuaternion,
|
|
|
|
time_offset: kf.time - first.time,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if (isApp) {
|
|
|
|
clipboard.writeHTML(JSON.stringify({type: 'keyframes', content: Clipbench.keyframes}))
|
|
|
|
}
|
2019-04-08 00:53:33 +08:00
|
|
|
},
|
|
|
|
setText: function(text) {
|
|
|
|
if (isApp) {
|
|
|
|
clipboard.writeText(text)
|
|
|
|
} else {
|
|
|
|
document.execCommand('copy')
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
2017-10-27 01:00:52 +08:00
|
|
|
}
|
2019-03-10 05:06:35 +08:00
|
|
|
|
|
|
|
const Vertexsnap = {
|
2018-10-18 01:50:25 +08:00
|
|
|
step1: true,
|
|
|
|
vertexes: new THREE.Object3D(),
|
|
|
|
vertexed_cubes: [],
|
|
|
|
hovering: false,
|
|
|
|
addVertexes: function(cube) {
|
|
|
|
if (Vertexsnap.vertexed_cubes.includes(cube)) return;
|
|
|
|
if (cube.visibility === false) return;
|
|
|
|
|
|
|
|
$('#preview').get(0).removeEventListener("mousemove", Vertexsnap.hoverCanvas)
|
|
|
|
$('#preview').get(0).addEventListener("mousemove", Vertexsnap.hoverCanvas)
|
|
|
|
|
2019-01-09 22:54:35 +08:00
|
|
|
var o_vertices = cube.mesh.geometry.vertices
|
|
|
|
cube.mesh.updateMatrixWorld()
|
2018-10-18 01:50:25 +08:00
|
|
|
o_vertices.forEach(function(v, id) {
|
|
|
|
var outline_color = '0x'+app_colors.accent.hex.replace('#', '')
|
2019-02-04 04:09:35 +08:00
|
|
|
//Each vertex needs it's own material for hovering
|
|
|
|
var material = new THREE.MeshBasicMaterial({color: parseInt(outline_color)})
|
|
|
|
var mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material)
|
2018-10-18 01:50:25 +08:00
|
|
|
var pos = mesh.position.copy(v)
|
2019-01-09 22:54:35 +08:00
|
|
|
pos.applyMatrix4(cube.mesh.matrixWorld)
|
2018-10-18 01:50:25 +08:00
|
|
|
pos.addScalar(8)
|
2019-01-09 22:54:35 +08:00
|
|
|
mesh.rotation.copy(cube.mesh.rotation)
|
2018-10-18 01:50:25 +08:00
|
|
|
mesh.cube = cube
|
|
|
|
mesh.isVertex = true
|
|
|
|
mesh.vertex_id = id
|
|
|
|
Vertexsnap.vertexes.add(mesh)
|
|
|
|
})
|
|
|
|
Vertexsnap.vertexed_cubes.push(cube)
|
|
|
|
Vertexsnap.updateVertexSize()
|
|
|
|
},
|
|
|
|
removeVertexes: function() {
|
|
|
|
var i = Vertexsnap.vertexes.children.length
|
|
|
|
while (i >= 0) {
|
|
|
|
Vertexsnap.vertexes.remove(Vertexsnap.vertexes.children[i])
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
Vertexsnap.vertexed_cubes = []
|
|
|
|
$('#preview').get(0).removeEventListener("mousemove", Vertexsnap.hoverCanvas)
|
|
|
|
},
|
|
|
|
hoverCanvas: function(event) {
|
|
|
|
if (Vertexsnap.hovering) {
|
|
|
|
Vertexsnap.vertexes.children.forEach(function(v) {
|
|
|
|
if (v.type === 'Line') {
|
|
|
|
Vertexsnap.vertexes.remove(v)
|
|
|
|
} else {
|
|
|
|
v.material.color.set(parseInt('0x'+app_colors.accent.hex.replace('#', '')))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
let data = Canvas.raycast()
|
2018-11-12 04:19:08 +08:00
|
|
|
if (!data || !data.vertex) {
|
|
|
|
Blockbench.setStatusBarText()
|
|
|
|
return;
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
var vertex = data.vertex
|
|
|
|
vertex.material.color.g = 1
|
|
|
|
Vertexsnap.hovering = true
|
|
|
|
|
|
|
|
if (Vertexsnap.step1 === false) {
|
2018-11-12 04:19:08 +08:00
|
|
|
//Line
|
2018-10-18 01:50:25 +08:00
|
|
|
var geometry = new THREE.Geometry();
|
|
|
|
geometry.vertices.push(Vertexsnap.vertex_pos);
|
|
|
|
geometry.vertices.push(vertex.position);
|
2018-11-12 04:19:08 +08:00
|
|
|
var line = new THREE.Line(geometry, Vertexsnap.lineMaterial);
|
2018-10-18 01:50:25 +08:00
|
|
|
line.renderOrder = 900
|
|
|
|
Vertexsnap.vertexes.add(line)
|
2018-11-12 04:19:08 +08:00
|
|
|
//Measure
|
|
|
|
var diff = new THREE.Vector3().copy(Vertexsnap.vertex_pos)
|
|
|
|
diff.sub(vertex.position)
|
|
|
|
Blockbench.setStatusBarText(tl('status_bar.vertex_distance', [trimFloatNumber(diff.length())] ))
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
select: function() {
|
|
|
|
Vertexsnap.removeVertexes()
|
|
|
|
selected.forEach(function(obj) {
|
|
|
|
Vertexsnap.addVertexes(obj)
|
|
|
|
})
|
|
|
|
if (selected.length) {
|
|
|
|
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
Vertexsnap.lineMaterial = Canvas.outlineMaterial.clone()
|
|
|
|
Vertexsnap.lineMaterial.depthTest = false
|
2018-10-18 01:50:25 +08:00
|
|
|
},
|
|
|
|
canvasClick: function(data) {
|
|
|
|
if (!data.vertex) return;
|
|
|
|
|
|
|
|
if (Vertexsnap.step1) {
|
|
|
|
Vertexsnap.step1 = false
|
|
|
|
Vertexsnap.vertex_pos = data.vertex.position
|
|
|
|
Vertexsnap.vertex_id = data.vertex.vertex_id
|
|
|
|
Vertexsnap.cubes = selected.slice()
|
|
|
|
Vertexsnap.removeVertexes()
|
|
|
|
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
|
|
|
|
} else {
|
|
|
|
Vertexsnap.snap(data)
|
|
|
|
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
Blockbench.setStatusBarText()
|
2018-10-18 01:50:25 +08:00
|
|
|
},
|
|
|
|
snap: function(data) {
|
|
|
|
Undo.initEdit({cubes: Vertexsnap.cubes})
|
|
|
|
|
|
|
|
var pos = data.vertex.position
|
|
|
|
pos.sub(Vertexsnap.vertex_pos)
|
|
|
|
|
|
|
|
if (BarItems.vertex_snap_mode.get() === 'scale') {
|
|
|
|
//Scale
|
|
|
|
|
|
|
|
var m;
|
|
|
|
switch (Vertexsnap.vertex_id) {
|
|
|
|
case 0: m=[ 1,1,1 ]; break;
|
|
|
|
case 1: m=[ 1,1,0 ]; break;
|
|
|
|
case 2: m=[ 1,0,1 ]; break;
|
|
|
|
case 3: m=[ 1,0,0 ]; break;
|
|
|
|
case 4: m=[ 0,1,0 ]; break;
|
|
|
|
case 5: m=[ 0,1,1 ]; break;
|
|
|
|
case 6: m=[ 0,0,0 ]; break;
|
|
|
|
case 7: m=[ 0,0,1 ]; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertexsnap.cubes.forEach(function(obj) {
|
2019-01-09 22:54:35 +08:00
|
|
|
var q = obj.mesh.getWorldQuaternion(new THREE.Quaternion()).inverse()
|
2018-11-12 04:19:08 +08:00
|
|
|
var cube_pos = new THREE.Vector3().copy(pos).applyQuaternion(q)
|
|
|
|
|
2018-10-18 01:50:25 +08:00
|
|
|
for (i=0; i<3; i++) {
|
|
|
|
if (m[i] === 1) {
|
|
|
|
obj.to[i] += cube_pos.getComponent(i)
|
|
|
|
} else {
|
|
|
|
obj.from[i] += cube_pos.getComponent(i)
|
|
|
|
}
|
|
|
|
}
|
2018-11-12 04:19:08 +08:00
|
|
|
if (Blockbench.entity_mode && obj.visibility) {
|
|
|
|
Canvas.updateUV(obj)
|
|
|
|
}
|
2018-10-18 01:50:25 +08:00
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Vertexsnap.cubes.forEach(function(obj) {
|
|
|
|
var cube_pos = new THREE.Vector3().copy(pos)
|
|
|
|
if (Blockbench.entity_mode === false) {
|
|
|
|
obj.origin[0] += cube_pos.getComponent(0)
|
|
|
|
obj.origin[1] += cube_pos.getComponent(1)
|
|
|
|
obj.origin[2] += cube_pos.getComponent(2)
|
|
|
|
} else {
|
2019-01-09 22:54:35 +08:00
|
|
|
var q = obj.mesh.getWorldQuaternion(new THREE.Quaternion()).inverse()
|
2018-11-12 04:19:08 +08:00
|
|
|
cube_pos.applyQuaternion(q)
|
2018-10-18 01:50:25 +08:00
|
|
|
}
|
|
|
|
obj.from[0] += cube_pos.getComponent(0)
|
|
|
|
obj.from[1] += cube_pos.getComponent(1)
|
|
|
|
obj.from[2] += cube_pos.getComponent(2)
|
|
|
|
obj.to[0] += cube_pos.getComponent(0)
|
|
|
|
obj.to[1] += cube_pos.getComponent(1)
|
|
|
|
obj.to[2] += cube_pos.getComponent(2)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
Vertexsnap.removeVertexes()
|
|
|
|
Canvas.updateAllPositions()
|
|
|
|
Undo.finishEdit('vertex_snap')
|
|
|
|
Vertexsnap.step1 = true
|
|
|
|
},
|
|
|
|
updateVertexSize: function() {
|
|
|
|
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
|
|
|
|
v.scale.set(scale, scale, scale)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const entityMode = {
|
|
|
|
state: false,
|
|
|
|
old_res: {},
|
|
|
|
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]}}},
|
|
|
|
join: function() {
|
|
|
|
if (display_mode) {
|
|
|
|
BarItems.move_tool.select()
|
|
|
|
}
|
|
|
|
Blockbench.entity_mode = true
|
|
|
|
$('body').addClass('entity_mode')
|
|
|
|
$('label[for="project_parent"]').text(tl('dialog.project.geoname'))
|
|
|
|
$('button#entity_mode_convert').text(tl('dialog.project.to_blockmodel'))
|
|
|
|
//Rotation Menu
|
|
|
|
if (textures.length > 1) {
|
|
|
|
textures.splice(1)
|
|
|
|
}
|
|
|
|
if (textures.length) {
|
|
|
|
var tex = textures[0]
|
|
|
|
tex.particle = false
|
|
|
|
if (tex.img.naturalWidth !== tex.img.naturalWidth && tex.error) {
|
|
|
|
tex.error = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Canvas.updateRenderSides()
|
|
|
|
|
|
|
|
//UI Changes
|
|
|
|
$('.block_mode_only').hide()
|
|
|
|
$('.entity_mode_only').show()
|
2018-12-27 21:03:04 +08:00
|
|
|
Modes.options.edit.select()
|
2018-10-18 01:50:25 +08:00
|
|
|
//UV
|
2019-02-04 04:09:35 +08:00
|
|
|
//main_uv.buildDom(true).setToMainSlot().setFace('north')
|
2018-10-18 01:50:25 +08:00
|
|
|
main_uv.autoGrid = true
|
|
|
|
main_uv.setGrid()
|
|
|
|
//Update
|
|
|
|
buildGrid()
|
|
|
|
Canvas.updateAllPositions()
|
|
|
|
Canvas.updateAllFaces()
|
|
|
|
Blockbench.dispatchEvent('join_entity_mode')
|
|
|
|
},
|
|
|
|
leave: function() {
|
|
|
|
Blockbench.entity_mode = false
|
|
|
|
$('body').removeClass('entity_mode')
|
|
|
|
$('label[for="project_parent"]').text(tl('dialog.project.parent'))
|
|
|
|
$('button#entity_mode_convert').text(tl('dialog.project.to_entitymodel'))
|
|
|
|
//Rotation Menu
|
|
|
|
$('input#cube_rotate').attr('min', '-67.5').attr('max', '67.5').attr('step', '22.5').removeClass('entity_mode')
|
|
|
|
//UV
|
2019-02-04 04:09:35 +08:00
|
|
|
//main_uv.buildDom(true).setToMainSlot()
|
|
|
|
main_uv.autoGrid = false
|
|
|
|
main_uv.showing_overlays = false
|
|
|
|
main_uv.displayAllMappingOverlays()
|
|
|
|
main_uv.setGrid()
|
2018-10-18 01:50:25 +08:00
|
|
|
if (textures[0]) {
|
|
|
|
textures[0].load()
|
|
|
|
}
|
|
|
|
//UI Changes
|
|
|
|
$('.block_mode_only').show()
|
|
|
|
$('.entity_mode_only').hide()
|
2018-12-27 21:03:04 +08:00
|
|
|
Modes.options.edit.select()
|
2018-10-18 01:50:25 +08:00
|
|
|
//Update
|
|
|
|
if (textures.length) {
|
|
|
|
textures[0].load()
|
|
|
|
}
|
|
|
|
Canvas.updateRenderSides()
|
|
|
|
buildGrid()
|
|
|
|
if (settings.restricted_canvas.value) moveIntoBox(elements, true)
|
|
|
|
Canvas.updateAllPositions()
|
|
|
|
Blockbench.dispatchEvent('leave_entity_mode')
|
|
|
|
},
|
|
|
|
convert: function() {
|
|
|
|
Blockbench.showMessageBox({
|
2018-10-24 03:49:04 +08:00
|
|
|
title: tl('message.convert_mode.title'),
|
2018-10-18 01:50:25 +08:00
|
|
|
icon: 'warning',
|
2018-10-24 03:49:04 +08:00
|
|
|
message: tl('message.convert_mode.message', [tl(Blockbench.entity_mode?'message.convert_mode.block':'message.convert_mode.entity')]),
|
|
|
|
buttons: [tl('message.convert_mode.convert'), tl('dialog.cancel')],
|
2018-10-18 01:50:25 +08:00
|
|
|
confirm: 0,
|
|
|
|
cancel: 1
|
|
|
|
}, function(result) {
|
|
|
|
if (result === 0) {
|
|
|
|
Undo.history.length = 0;
|
|
|
|
Undo.index = 0;
|
|
|
|
if (Blockbench.entity_mode) {
|
|
|
|
entityMode.leave()
|
|
|
|
elements.forEach(function(obj) {
|
|
|
|
obj.autouv = 0
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
entityMode.join()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
|
|
|
setResolution: function(x, y, lockUV) {
|
|
|
|
if (!Blockbench.entity_mode) return;
|
|
|
|
//lockUV > If true, keep the uv_offset numbers the same
|
|
|
|
|
|
|
|
Project.texture_width = parseInt(Project.texture_width)
|
|
|
|
Project.texture_height = parseInt(Project.texture_height)
|
|
|
|
if (typeof entityMode.old_res.x !== 'number' || typeof entityMode.old_res.y !== 'number') {
|
|
|
|
entityMode.old_res.x = Project.texture_width
|
|
|
|
entityMode.old_res.y = Project.texture_height
|
|
|
|
}
|
|
|
|
|
|
|
|
Math.areMultiples = function(n1, n2) {
|
|
|
|
return (
|
|
|
|
(n1/n2)%1 === 0 ||
|
|
|
|
(n2/n1)%1 === 0
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x && y) {
|
|
|
|
entityMode.old_res.x = Project.texture_width
|
|
|
|
entityMode.old_res.y = Project.texture_height
|
|
|
|
}
|
|
|
|
if (x) {Project.texture_width = x}
|
|
|
|
if (y) {Project.texture_height = y}
|
|
|
|
if (entityMode.old_res.x/entityMode.old_res.y !== Project.texture_width/Project.texture_height) {lockUV = true}
|
|
|
|
|
|
|
|
if (!lockUV &&
|
|
|
|
entityMode.old_res.x != Project.texture_width &&
|
|
|
|
Math.areMultiples(entityMode.old_res.x, Project.texture_width)
|
|
|
|
) {
|
|
|
|
elements.forEach(function(obj) {
|
|
|
|
obj.uv_offset[0] *= Project.texture_width/entityMode.old_res.x
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if (!lockUV &&
|
|
|
|
entityMode.old_res.y != Project.texture_height &&
|
|
|
|
Math.areMultiples(entityMode.old_res.x, Project.texture_width)
|
|
|
|
) {
|
|
|
|
elements.forEach(function(obj) {
|
|
|
|
obj.uv_offset[1] *= Project.texture_height/entityMode.old_res.y
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
entityMode.old_res.x = Project.texture_width
|
|
|
|
entityMode.old_res.y = Project.texture_height
|
|
|
|
Canvas.updateAllUVs()
|
|
|
|
if (selected.length) {
|
|
|
|
main_uv.loadData()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|