blockbench/js/io.js
2018-04-05 17:11:29 +02:00

649 lines
21 KiB
JavaScript

//New
function newProject(entity_mode) {
if (showSaveDialog()) {
if (display_mode === true) exitDisplaySettings()
TextureAnimator
projectTagSetup()
elements.length = 0;
TreeElements.length = 1
TreeElements.splice(0, 1)
Canvas.materials.length = 0
textures.length = 0
selected.length = 0
selected_group = undefined
display = {}
Prop.file_path = 'Unknown';
Prop.file_name = '-';
setProjectTitle()
Canvas.updateAll()
outliner.$forceUpdate();
texturelist.$forceUpdate();
Undo.history.length = 0;
Undo.index = 0;
added_model_index = 0;
if (entity_mode) {
entityMode.join()
} else {
entityMode.leave()
}
setUndo('Created project')
return true;
} else {
return false;
}
}
function newEntityProject() {
newProject(function () {
Blockbench.entity_mode = true
entity_mode.join()
})
}
//Import
function loadFile(data, filepath, makeNew) {
var previous_length = 0
var previous_texture_length = 0
if (makeNew === true) {
//Create New Project
if (newProject() == false) return;
Blockbench.addFlag('importing')
Prop.project_saved = true;
Prop.file_path = filepath
setProjectTitle(pathToName(filepath, true))
} else {
//Add to Current Project
Blockbench.addFlag('importing')
previous_length = elements.length
previous_texture_length = textures.length
added_model_index++;
var import_group = new Group(pathToName(filepath, false))
}
data = JSON.parse(data)
//Check if PE Model
for (var key in data) {
if (key.includes('geometry.')) {
loadPEModelFile(data)
return;
}
}
Blockbench.entity_mode = false;
saveSettings()
//Load
if (data.display !== undefined) {
display = data.display
}
var oid = elements.length
if (data.elements) {
data.elements.forEach(function(obj) {
base_cube = new Cube(obj)
for (var face in base_cube.faces) {
if (obj.faces[face] === undefined) {
base_cube.faces[face].texture = '$transparent'
base_cube.faces[face].uv = [0,0,0,0]
}
}
base_cube.uuid = guid()
base_cube.display.autouv = false;
elements.push(base_cube);
if (makeNew === true) {
base_cube.addTo()
} else if (import_group) {
base_cube.addTo(import_group)
}
})
}
if (data.groups && data.groups.length > 0) {
if (makeNew === true) {
parseGroups(data.groups)
} else if (import_group) {
parseGroups(data.groups, import_group, oid)
}
}
if (import_group) {
import_group.addTo()
}
if (
!data.elements &&
data.parent == 'item/generated' &&
data.textures &&
typeof data.textures.layer0 === 'string'
) {
base_cube = new Cube()
base_cube.extend({
name: 'Item Dummy',
from: [0, 0, 7.5],
to: [16, 16, 7.8],
faces: {
north: {uv: [16,0,0,16], texture: 'layer0'},
south: {uv: [16,0,16,0], texture: 'layer0'},
east: {uv: [0,0,0,0], texture: '$transparent'},
west: {uv: [0,0,0,0], texture: '$transparent'},
up: {uv: [0,0,0,0], texture: '$transparent'},
down: {uv: [0,0,0,0], texture: '$transparent'},
},
display: {
autouv: false,
export: false,
}
})
elements.push(base_cube);
base_cube.addTo()
}
if (data.textures) {
//Create Path Array to fetch textures
var path_arr = filepath.split(osfs)
var index = path_arr.length - path_arr.indexOf('models')
path_arr.splice(-index)
path_arr = path_arr.join(osfs)
var texture_arr = data.textures
var names = []
for (var tex in texture_arr) {
if (texture_arr.hasOwnProperty(tex)) {
if (tex != 'particle') {
var path = path_arr+osfs+'textures'+osfs+texture_arr[tex].split('/').join(osfs)+'.png'
new Texture({id: tex}).fromPath(path).add()
names.push(texture_arr[tex])
}
}
}
if (texture_arr === undefined) texture_arr = {}
if (texture_arr.particle) {
var path = path_arr+osfs+'textures'+osfs+texture_arr.particle.split('/').join(osfs)+'.png'
if (names.includes(texture_arr.particle)) {
textures.forEach(function(s) {
if (s.path == path) {
s.enableParticle()
}
})
} else {
new Texture({id: 'particle'}).enableParticle().fromPath(path).add()
}
}
//Get Rid Of ID overlapping
textures.forEach(function(t, i) {
if (i >= previous_texture_length) {
if (getTexturesById(t.id).length > 1) {
var before = t.id
t.id = added_model_index + '_' + t.id
elements.forEach(function(s, si) {
if (si >= previous_length) {
for (var face in s.faces) {
if (s.faces[face].texture === '#'+before) {
s.faces[face].texture = '#'+t.id
}
}
}
})
}
}
})
//Select Last Texture
if (textures.length > 0) {
textures.forEach(function(s) {
s.selected = false;
})
textures[textures.length-1].selected = true;
}
}
//Set Parent
if (data.parent !== undefined) {
Project.parent = data.parent;
}
//Set Ambient Occlusion
if (data.ambientocclusion === false) {
Project.ambientocclusion = false;
}
loadTextureDraggable()
Canvas.updateAll()
setUndo('Opened project')
Blockbench.removeFlag('importing')
if (makeNew) {
Prop.project_saved = true;
}
}
function loadPEModelFile(data) {
pe_list_data.length = 0
entityMode.join()
$('#pe_search_bar').val('')
if (pe_list && pe_list._data) {
pe_list._data.search_text = ''
}
saveSettings()
for (var key in data) {
if (key.includes('geometry.') && data.hasOwnProperty(key)) {
var base_model = {name: key, bonecount: 0, selected: false, object: data[key]}
if (data[key].bones) {
base_model.bonecount = data[key].bones.length
}
pe_list_data.push(base_model)
}
}
if (pe_list == undefined) {
pe_list = new Vue({
el: '#pe_list',
data: {
search_text: '',
list: pe_list_data
},
methods: {
selectE: function(item, event) {
var index = pe_list_data.indexOf(item)
pe_list_data.forEach(function(s) {
s.selected = false;
})
pe_list_data[index].selected = true
}
},
computed: {
searched() {
var scope = this;
return this.list.filter(item => {
return item.name.toUpperCase().includes(scope.search_text)
})
}
}
})
} else {
// pe_list._data = {pe_list_data}
// pe_list.$forceUpdate();
}
showDialog('entity_import')
$('#pe_list').css('max-height', ($(window).height() - 320) +'px')
$('input#pe_search_bar').select()
//texturelist._data.elements = textures
}
function loadPEModel() {
var data;
pe_list_data.forEach(function(s) {
if (s.selected === true) {
data = s
}
})
if (data == undefined) {
data = pe_list_data[0]
}
Project.parent = data.name
if (data.object.texturewidth !== undefined) {
Project.texture_width = data.object.texturewidth
}
if (data.object.textureheight !== undefined) {
Project.texture_height = data.object.textureheight
}
if (data.object.bones) {
var included_bones = []
data.object.bones.forEach(function(b) {
included_bones.push(b.name)
})
data.object.bones.forEach(function(b) {
var group = new Group(b.name)
if (b.pivot) {
group.origin = b.pivot
} else {
group.origin = [0, 0, 0]
}
if (b.rotation) {
group.rotation = b.rotation.slice()
group.rotation.forEach(function(br, ri) {
group.rotation[ri] *= -1
})
}
if (b.name === 'body' &&
included_bones.includes('leg3') &&
included_bones.includes('leg4') === false &&
!data.name.includes('creeper') &&
(group.rotation.join('_') === '0_0_0' || group.rotation === undefined)
) {
group.rotation = [-90, 0, 0]
}
group.shade = !b.mirror
group.reset = b.reset === true
if (b.cubes) {
b.cubes.forEach(function(s) {
var base_cube = new Cube({name: b.name, display:{autouv: false}})
if (s.origin) {
base_cube.from = s.origin
base_cube.from[0] = -(base_cube.from[0] + s.size[0])
if (s.size) {
base_cube.to[0] = s.size[0] + base_cube.from[0]
base_cube.to[1] = s.size[1] + base_cube.from[1]
base_cube.to[2] = s.size[2] + base_cube.from[2]
}
}
if (s.uv) {
base_cube.uv_offset[0] = s.uv[0]
base_cube.uv_offset[1] = s.uv[1]
}
if (s.inflate && typeof s.inflate === 'number') {
base_cube.inflate = s.inflate
}
base_cube.shade = !s.mirror
elements.push(base_cube)
base_cube.addTo(group)
})
}
group.addTo()
})
}
pe_list_data.length = 0;
hideDialog()
loadTextureDraggable()
Canvas.updateAll()
setProjectTitle()
setUndo('Opened entity model')
if (isApp && data.name) {
findEntityTexture(data.name)
}
}
//Export
function buildBlockModel(options) {
if (options === undefined) options = {}
var clear_elements = []
var textures_used = []
var element_index_lut = []
var largerCubesNr = 0;
function computeCube(s) {
if (s.display.export == false) return;
//Create Element
var element = {}
element_index_lut[s.index()] = clear_elements.length
if (options.cube_name !== false && !settings.minifiedout.value) {
element.name = s.name
}
element.from = s.from.slice()
element.to = s.to.slice()
if (s.shade === false) {
element.shade = false
}
if (s.rotation) {
element.rotation = {
angle: s.rotation.angle,
axis: s.rotation.axis,
origin: s.rotation.origin
}
if (s.rotation.rescale === true) {
element.rotation.rescale = true
}
}
element.faces = {}
for (var face in s.faces) {
if (s.faces.hasOwnProperty(face)) {
if (s.faces[face].texture !== '$transparent') {
var tag = {}
if (s.faces[face].enabled !== false) {
tag.uv = s.faces[face].uv
}
tag.texture = s.faces[face].texture ? s.faces[face].texture : '#missing'
if (s.faces[face].rotation) {
tag.rotation = s.faces[face].rotation
}
if (s.faces[face].cullface !== undefined) {
tag.cullface = s.faces[face].cullface
}
if (s.faces[face].tintindex !== undefined) {
tag.tintindex = s.faces[face].tintindex
}
element.faces[face] = tag
}
}
}
//Gather Textures
for (var face in s.faces) {
if (s.faces.hasOwnProperty(face)) {
if (!textures_used.includes(s.faces[face].texture)) {
textures_used.push(s.faces[face].texture)
}
}
}
function inVd(n) {
return n > 32 || n < -16
}
if (inVd(s.from[0]) ||
inVd(s.from[1]) ||
inVd(s.from[2]) ||
inVd(s.to[0]) ||
inVd(s.to[1]) ||
inVd(s.to[2])
) {
largerCubesNr++;
}
clear_elements.push(element)
}
function iterate(arr) {
var i = 0;
if (!arr || !arr.length) {
return;
}
for (i=0; i<arr.length; i++) {
if (arr[i].type === 'cube') {
computeCube(arr[i])
} else if (arr[i].title === 'Group') {
iterate(arr[i].children)
}
}
}
iterate(TreeElements)
function checkExport(key, condition) {
key = options[key]
if (key === undefined) {
return condition;
} else {
return key
}
}
var texturesObj = {}
var hasUnsavedTextures = false
textures.forEach(function(s, i){
if (!textures_used.includes('#'+s.id)) return;
texturesObj[s.id] = s.javaTextureLink()
if (s.particle) {
texturesObj.particle = s.javaTextureLink()
}
if (s.mode === 'bitmap') {
hasUnsavedTextures = true
}
})
if (options.prevent_dialog !== true && hasUnsavedTextures && settings.dialog_unsaved_textures.value) {
Blockbench.showMessageBox({
title: 'Unsaved Textures',
icon: 'broken_image',
message: 'Your model has unsaved textures. Make sure to save them and paste them into your resource pack in the correct folder.',
buttons: ['OK']
})
}
if (options.prevent_dialog !== true && largerCubesNr > 0 && settings.dialog_larger_cubes.value) {
Blockbench.showMessageBox({
title: 'Model Too Large',
icon: 'settings_overscan',
message: 'Your model contains '+largerCubesNr+' cubes that are larger than the 3x3x3 limit allowed by Minecraft. This model will not work in Minecraft. Enable the option "Restricted Canvas" to prevent this.',
buttons: ['OK']
})
}
var blockmodel = {}
if (checkExport('description', Project.description !== '')) {
blockmodel.description = Project.description;
}
if (checkExport('comment', settings.comment.value === true)) {
blockmodel.credit = settings.comment_text.value
}
if (checkExport('parent', Project.parent != '')) {
blockmodel.parent = Project.parent
}
if (checkExport('ambientocclusion', Project.ambientocclusion === false)) {
blockmodel.ambientocclusion = false
}
if (checkExport('textures', Object.keys(texturesObj).length >= 1)) {
blockmodel.textures = texturesObj
}
if (checkExport('elements', elements.length >= 1)) {
blockmodel.elements = clear_elements
}
if (checkExport('display', Object.keys(display).length >= 1)) {
var new_display = {}
var entries = 0;
for (var key in display) {
if (display.hasOwnProperty(key)) {
if ((typeof display[key].scale === 'object' && display[key].scale.join('_') !== '1_1_1') ||
display[key].rotation ||
display[key].translation
) {
new_display[key] = display[key]
entries++;
if (new_display[key].scale && new_display[key].scale.join('_') === '1_1_1') {
new_display[key].scale = undefined
}
}
}
}
if (entries) {
blockmodel.display = new_display
}
}
if (checkExport('groups', (settings.export_groups.value && getAllOutlinerGroups().length))) {
groups = compileGroups(undefined, element_index_lut)
var i = 0;
while (i < groups.length) {
if (typeof groups[i] === 'object') {
i = Infinity
}
i++
}
if (i === Infinity) {
blockmodel.groups = groups
}
}
if (options.raw) {
return blockmodel
} else {
return autoStringify(blockmodel)
}
}
function buildEntityModel(options) {
if (options === undefined) options = {}
var entitymodel = {}
entitymodel.texturewidth = parseInt(Project.texture_width);
entitymodel.textureheight = parseInt(Project.texture_height);
var bones = []
TreeElements.forEach(function(g) {
if (g.type !== 'group') return;
//Bone
var bone = {}
bone.name = g.name
bone.pivot = g.origin
if (g.rotation.join('_') !== '0_0_0') {
bone.rotation = g.rotation.slice()
bone.rotation.forEach(function(br, ri) {
bone.rotation[ri] *= -1
})
}
if (g.reset) {
bone.reset = true
}
if (g.shade === false) {
bone.mirror = true
}
//Cubes
if (g.children && g.children.length) {
bone.cubes = []
function iterate(arr) {
var i = 0;
while (i < arr.length) {
if (arr[i].type === 'group') {
iterate(arr[i].children)
} else if (arr[i].type === 'cube') {
var s = arr[i]
if (s === undefined) return;
if (s.display.export === false) return;
var cube = {}
cube.origin = s.from.slice()
cube.size = s.size()
cube.origin[0] = -(cube.origin[0] + cube.size[0])
cube.uv = s.uv_offset
if (s.inflate && typeof s.inflate === 'number') {
cube.inflate = s.inflate
}
if (s.shade === false) {
cube.mirror = true
}
bone.cubes.push(cube)
}
i++;
}
}
iterate(g.children)
}
bones.push(bone)
})
entitymodel.bones = bones
if (options.raw) {
return entitymodel
} else {
return autoStringify(entitymodel)
}
}
function buildOptifineModel() {
var jpm = {}
if (textures[0]) {
jpm.texture = pathToName(textures[0].name, false)
} else {
showQuickMessage('No texture found')
}
jpm.textureSize = [Project.texture_width, Project.texture_height]
if (settings.comment.value === true) {
jpm.credit = settings.comment_text.value
}
if (Project.description !== '') {
jpm.description = Project.description;
}
var submodels = []
elements.forEach(function(s) {
if (s.display.export === false) return;
var submodel = {boxes: [{}]}
var box = submodel.boxes[0]
submodel.id = s.name
box.coordinates = [s.from[0], s.from[1], s.from[2], s.size(0), s.size(1), s.size(2)]
for (var face in s.faces) {
if (s.faces.hasOwnProperty(face)) {
if (s.faces[face].texture !== undefined && s.faces[face].texture !== '$transparent') {
box['uv'+capitalizeFirstLetter(face)] = [
s.faces[face].uv[0] / 16 * Project.texture_width,
s.faces[face].uv[1] / 16 * Project.texture_height,
s.faces[face].uv[2] / 16 * Project.texture_width,
s.faces[face].uv[3] / 16 * Project.texture_height
]
}
}
}
submodels.push(submodel)
})
jpm.submodels = submodels
return autoStringify(jpm)
}