mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-21 01:13:37 +08:00
Basic model merging function
This commit is contained in:
parent
b6c3c3fbaa
commit
c2ed10d547
@ -504,7 +504,8 @@ const MenuBar = {
|
||||
'close_project',
|
||||
'_',
|
||||
{name: 'menu.file.import', id: 'import', icon: 'insert_drive_file', children: [
|
||||
'add_model',
|
||||
'import_project',
|
||||
'import_java_block_model',
|
||||
'import_optifine_part',
|
||||
'extrude_texture'
|
||||
]},
|
||||
|
@ -9,6 +9,7 @@ class Codec {
|
||||
Merge.function(this, data, 'load');
|
||||
Merge.function(this, data, 'compile');
|
||||
Merge.function(this, data, 'parse');
|
||||
Merge.function(this, data, 'merge');
|
||||
Merge.function(this, data, 'write');
|
||||
Merge.function(this, data, 'overwrite');
|
||||
Merge.function(this, data, 'export');
|
||||
|
@ -2,6 +2,56 @@
|
||||
|
||||
let FORMATV = '3.6';
|
||||
|
||||
function processHeader(model) {
|
||||
if (!model.meta) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'invalid_model',
|
||||
icon: 'error',
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (!model.meta.format_version) {
|
||||
model.meta.format_version = model.meta.format;
|
||||
}
|
||||
if (compareVersions(model.meta.format_version, FORMATV)) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'outdated_client',
|
||||
icon: 'error',
|
||||
})
|
||||
return;
|
||||
}
|
||||
}
|
||||
function processCompatibility(model) {
|
||||
|
||||
if (!model.meta.model_format) {
|
||||
if (model.meta.bone_rig) {
|
||||
model.meta.model_format = 'bedrock_old';
|
||||
} else {
|
||||
model.meta.model_format = 'java_block';
|
||||
}
|
||||
}
|
||||
|
||||
if (model.cubes && !model.elements) {
|
||||
model.elements = model.cubes;
|
||||
}
|
||||
|
||||
if (model.outliner) {
|
||||
if (compareVersions('3.2', model.meta.format_version)) {
|
||||
//Fix Z-axis inversion pre 3.2
|
||||
function iterate(list) {
|
||||
for (var child of list) {
|
||||
if (typeof child == 'object' ) {
|
||||
iterate(child.children);
|
||||
if (child.rotation) child.rotation[2] *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
iterate(model.outliner)
|
||||
}
|
||||
parseGroups(model.outliner)
|
||||
}
|
||||
}
|
||||
|
||||
var codec = new Codec('project', {
|
||||
name: 'Blockbench Project',
|
||||
extension: 'bbmodel',
|
||||
@ -124,30 +174,13 @@ var codec = new Codec('project', {
|
||||
}
|
||||
},
|
||||
parse(model, path) {
|
||||
if (!model.meta) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'invalid_model',
|
||||
icon: 'error',
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (!model.meta.format_version) {
|
||||
model.meta.format_version = model.meta.format;
|
||||
}
|
||||
if (compareVersions(model.meta.format_version, FORMATV)) {
|
||||
Blockbench.showMessageBox({
|
||||
translateKey: 'outdated_client',
|
||||
icon: 'error',
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
processHeader(model);
|
||||
processCompatibility(model);
|
||||
|
||||
if (model.meta.model_format) {
|
||||
var format = Formats[model.meta.model_format]||Formats.free;
|
||||
format.select()
|
||||
} else if (model.meta.bone_rig) {
|
||||
Formats.bedrock_old.select()
|
||||
} else {
|
||||
Formats.java_block.select()
|
||||
}
|
||||
|
||||
Blockbench.dispatchEvent('load_project', {model, path});
|
||||
@ -179,10 +212,8 @@ var codec = new Codec('project', {
|
||||
}
|
||||
})
|
||||
}
|
||||
if (model.cubes && !model.elements) {
|
||||
model.elements = model.cubes;
|
||||
}
|
||||
if (model.elements) {
|
||||
let default_texture = Texture.getDefault();
|
||||
model.elements.forEach(function(element) {
|
||||
|
||||
var copy = NonGroup.fromSave(element, true)
|
||||
@ -192,8 +223,8 @@ var codec = new Codec('project', {
|
||||
if (texture) {
|
||||
copy.faces[face].texture = texture.uuid
|
||||
}
|
||||
} else if (Texture.getDefault() && copy.faces && copy.faces[face].texture !== null) {
|
||||
copy.faces[face].texture = Texture.getDefault().uuid
|
||||
} else if (default_texture && copy.faces && copy.faces[face].texture !== null) {
|
||||
copy.faces[face].texture = default_texture.uuid
|
||||
}
|
||||
}
|
||||
copy.init()
|
||||
@ -202,18 +233,6 @@ var codec = new Codec('project', {
|
||||
loadOutlinerDraggable()
|
||||
}
|
||||
if (model.outliner) {
|
||||
if (compareVersions('3.2', model.meta.format_version)) {
|
||||
//Fix Z-axis inversion pre 3.2
|
||||
function iterate(list) {
|
||||
for (var child of list) {
|
||||
if (typeof child == 'object' ) {
|
||||
iterate(child.children);
|
||||
if (child.rotation) child.rotation[2] *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
iterate(model.outliner)
|
||||
}
|
||||
parseGroups(model.outliner)
|
||||
}
|
||||
if (model.animations) {
|
||||
@ -236,6 +255,89 @@ var codec = new Codec('project', {
|
||||
Canvas.updateAllBones()
|
||||
Canvas.updateAllPositions()
|
||||
this.dispatchEvent('parsed', {model})
|
||||
},
|
||||
merge(model, path) {
|
||||
|
||||
/**
|
||||
* Todo
|
||||
*
|
||||
* texture merging
|
||||
* UV handling
|
||||
* Outliner issue
|
||||
* undo
|
||||
*/
|
||||
|
||||
processHeader(model);
|
||||
processCompatibility(model);
|
||||
|
||||
Blockbench.dispatchEvent('merge_project', {model, path});
|
||||
this.dispatchEvent('merge', {model})
|
||||
|
||||
|
||||
if (model.overrides instanceof Array && Project.overrides instanceof Array) {
|
||||
Project.overrides.push(...model.overrides);
|
||||
}
|
||||
|
||||
let width = model.resolution.width || Project.texture_width;
|
||||
let height = model.resolution.height || Project.texture_height;
|
||||
|
||||
function loadTexture(tex) {
|
||||
var tex_copy = new Texture(tex, tex.uuid).add(false);
|
||||
if (isApp && tex.path && fs.existsSync(tex.path) && !model.meta.backup) {
|
||||
tex_copy.fromPath(tex.path)
|
||||
} else if (tex.source && tex.source.substr(0, 5) == 'data:') {
|
||||
tex_copy.fromDataURL(tex.source)
|
||||
}
|
||||
}
|
||||
|
||||
if (model.textures && (!Format.single_texture || Texture.all.length == 0)) {
|
||||
model.textures.forEach(loadTexture)
|
||||
}
|
||||
|
||||
if (model.elements) {
|
||||
let default_texture = Texture.getDefault();
|
||||
model.elements.forEach(function(element) {
|
||||
|
||||
var copy = NonGroup.fromSave(element, true)
|
||||
for (var face in copy.faces) {
|
||||
if (!Format.single_texture && element.faces) {
|
||||
var texture = element.faces[face].texture !== null && textures[element.faces[face].texture]
|
||||
if (texture) {
|
||||
copy.faces[face].texture = texture.uuid
|
||||
}
|
||||
} else if (default_texture && copy.faces && copy.faces[face].texture !== null) {
|
||||
copy.faces[face].texture = default_texture.uuid
|
||||
}
|
||||
}
|
||||
copy.init()
|
||||
|
||||
})
|
||||
loadOutlinerDraggable()
|
||||
}
|
||||
if (model.outliner) {
|
||||
parseGroups(model.outliner)
|
||||
}
|
||||
if (model.animations) {
|
||||
model.animations.forEach(ani => {
|
||||
var base_ani = new Animation()
|
||||
base_ani.uuid = ani.uuid;
|
||||
base_ani.extend(ani).add();
|
||||
})
|
||||
}
|
||||
if (model.animation_variable_placeholders) {
|
||||
let vue = Interface.Panels.variable_placeholders.inside_vue;
|
||||
if (vue._data.text) {
|
||||
vue._data.text = vue._data.text + '\n\n' + model.animation_variable_placeholders;
|
||||
} else {
|
||||
vue._data.text = model.animation_variable_placeholders;
|
||||
}
|
||||
}
|
||||
if (model.display !== undefined) {
|
||||
DisplayMode.loadJSON(model.display)
|
||||
}
|
||||
Canvas.updateAllBones()
|
||||
Canvas.updateAllPositions()
|
||||
this.dispatchEvent('parsed', {model})
|
||||
}
|
||||
})
|
||||
|
||||
@ -263,6 +365,24 @@ BARS.defineActions(function() {
|
||||
codec.export()
|
||||
}
|
||||
})
|
||||
|
||||
new Action('import_project', {
|
||||
icon: 'icon-blockbench_file',
|
||||
category: 'file',
|
||||
click: function () {
|
||||
Blockbench.import({
|
||||
resource_id: 'model',
|
||||
extensions: [codec.extension],
|
||||
type: codec.name,
|
||||
multiple: true,
|
||||
}, function(files) {
|
||||
files.forEach(file => {
|
||||
var model = autoParseJSON(file.content);
|
||||
codec.merge(model);
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
})()
|
||||
|
@ -473,6 +473,24 @@ BARS.defineActions(function() {
|
||||
codec.export();
|
||||
}
|
||||
})
|
||||
new Action('import_java_block_model', {
|
||||
icon: 'assessment',
|
||||
category: 'file',
|
||||
condition: () => Format == format,
|
||||
click: function () {
|
||||
Blockbench.import({
|
||||
resource_id: 'model',
|
||||
extensions: ['json'],
|
||||
type: codec.name,
|
||||
multiple: true,
|
||||
}, function(files) {
|
||||
files.forEach(file => {
|
||||
var model = autoParseJSON(file.content)
|
||||
codec.parse(model, file.path, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
})()
|
18
js/io/io.js
18
js/io/io.js
@ -496,24 +496,6 @@ BARS.defineActions(function() {
|
||||
})
|
||||
}
|
||||
})
|
||||
new Action('add_model', {
|
||||
icon: 'assessment',
|
||||
category: 'file',
|
||||
condition: _ => (Format.id == 'java_block'),
|
||||
click: function () {
|
||||
Blockbench.import({
|
||||
resource_id: 'model',
|
||||
extensions: ['json'],
|
||||
type: 'JSON Model',
|
||||
multiple: true,
|
||||
}, function(files) {
|
||||
files.forEach(file => {
|
||||
var model = autoParseJSON(file.content)
|
||||
Codecs.java_block.parse(model, file.path, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
new Action('extrude_texture', {
|
||||
icon: 'eject',
|
||||
category: 'file',
|
||||
|
@ -701,8 +701,8 @@
|
||||
"action.convert_project.desc": "Converts the current project to a project for another model format",
|
||||
"action.close_project": "Close Project",
|
||||
"action.close_project.desc": "Closes the currently open project",
|
||||
"action.add_model": "Add Model",
|
||||
"action.add_model.desc": "Add a model from a file to the current model",
|
||||
"action.import_java_block_model": "Add Java Block/Item Model",
|
||||
"action.import_java_block_model.desc": "Add a Minecraft Java block/item model from a json file to the current model",
|
||||
"action.extrude_texture": "Extruded Texture",
|
||||
"action.extrude_texture.desc": "Generate a model by stretching out a texture",
|
||||
"action.export_blockmodel": "Export Block/Item Model",
|
||||
@ -732,6 +732,8 @@
|
||||
"action.save_project.desc": "Saves the current model as a project file",
|
||||
"action.save_project_as": "Save Project As",
|
||||
"action.save_project_as.desc": "Saves the current model as a project file at a new location",
|
||||
"action.import_project": "Import Project",
|
||||
"action.import_project.desc": "Import another project from a .bbmodel file into the current project",
|
||||
"action.export_over": "Save Model",
|
||||
"action.export_over.desc": "Saves the model, textures and animations by overwriting the files",
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user