mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-12-03 04:40:46 +08:00
9926202d28
closes #795
335 lines
8.7 KiB
JavaScript
335 lines
8.7 KiB
JavaScript
class ModelProject {
|
|
constructor() {
|
|
for (var key in ModelProject.properties) {
|
|
ModelProject.properties[key].reset(this);
|
|
}
|
|
|
|
this._box_uv = false;
|
|
this._texture_width = 16;
|
|
this._texture_height = 16;
|
|
}
|
|
extend() {
|
|
for (var key in ModelProject.properties) {
|
|
ModelProject.properties[key].merge(this, object)
|
|
}
|
|
}
|
|
get box_uv() {return Project._box_uv}
|
|
set box_uv(v) {
|
|
if (Project._box_uv != v) {
|
|
Project._box_uv = v;
|
|
switchBoxUV(v);
|
|
}
|
|
}
|
|
get texture_width() {return this._texture_width}
|
|
get texture_height() {return this._texture_height}
|
|
set texture_width(n) {
|
|
n = parseInt(n)||16
|
|
Vue.nextTick(updateProjectResolution)
|
|
this._texture_width = n;
|
|
}
|
|
set texture_height(n) {
|
|
n = parseInt(n)||16
|
|
Vue.nextTick(updateProjectResolution)
|
|
this._texture_height = n;
|
|
}
|
|
get optional_box_uv() {
|
|
return Format.optional_box_uv;
|
|
}
|
|
reset() {
|
|
if (isApp) updateRecentProjectThumbnail();
|
|
|
|
Blockbench.dispatchEvent('reset_project');
|
|
|
|
if (isApp) BedrockEntityManager.reset();
|
|
|
|
if (Toolbox.selected.id !== 'move_tool') BarItems.move_tool.select();
|
|
|
|
Screencam.stopTimelapse();
|
|
|
|
Format = 0;
|
|
for (var uuid in OutlinerElement.uuids) {
|
|
delete OutlinerElement.uuids[uuid];
|
|
}
|
|
Outliner.elements.empty();
|
|
Outliner.root.purge();
|
|
for (var key in Canvas.materials) {
|
|
delete Canvas.materials[key];
|
|
}
|
|
for (var key in Canvas.bones) {
|
|
delete Canvas.bones[key];
|
|
}
|
|
selected.empty();
|
|
Group.all.empty();
|
|
Group.selected = undefined;
|
|
Cube.all.empty();
|
|
Cube.selected.empty();
|
|
Locator.all.empty();
|
|
Locator.selected.empty();
|
|
Texture.all.empty();
|
|
Texture.selected = undefined;
|
|
|
|
for (var key in ModelProject.properties) {
|
|
ModelProject.properties[key].reset(this)
|
|
}
|
|
this.texture_width = this.texture_height = 16;
|
|
this.overrides = null;
|
|
|
|
Blockbench.display_settings = display = {};
|
|
ModelMeta.save_path = ModelMeta.export_path = ModelMeta.name = '';
|
|
ModelMeta.saved = true;
|
|
Prop.project_saved = true;
|
|
Prop.added_models = 0;
|
|
Canvas.updateAll();
|
|
Outliner.vue.$forceUpdate();
|
|
Interface.Panels.textures.inside_vue.$forceUpdate();
|
|
Undo.history.empty();
|
|
Undo.index = 0;
|
|
Undo.current_save = null;
|
|
Painter.current = {};
|
|
Animator.animations.purge();
|
|
Timeline.animators.purge();
|
|
Animation.selected = undefined;
|
|
delete Animator.motion_trail_lock;
|
|
$('#var_placeholder_area').val('');
|
|
}
|
|
}
|
|
new Property(ModelProject, 'string', 'name', {
|
|
label: 'dialog.project.name'
|
|
});
|
|
new Property(ModelProject, 'string', 'parent', {
|
|
label: 'dialog.project.parent',
|
|
condition: {formats: ['java_block']
|
|
}});
|
|
new Property(ModelProject, 'string', 'geometry_name', {
|
|
label: 'dialog.project.geoname',
|
|
condition: () => Format.bone_rig
|
|
});
|
|
new Property(ModelProject, 'string', 'modded_entity_version', {
|
|
label: 'dialog.project.modded_entity_version',
|
|
default: '1.15',
|
|
condition: {formats: ['modded_entity']},
|
|
options() {
|
|
let options = {}
|
|
for (var key in Codecs.modded_entity.templates) {
|
|
if (Codecs.modded_entity.templates[key] instanceof Function == false) {
|
|
options[key] = Codecs.modded_entity.templates[key].name;
|
|
}
|
|
}
|
|
return options;
|
|
}
|
|
});
|
|
new Property(ModelProject, 'boolean', 'ambientocclusion', {
|
|
label: 'dialog.project.ao',
|
|
default: true,
|
|
condition: {formats: ['java_block']}
|
|
});
|
|
new Property(ModelProject, 'boolean', 'front_gui_light', {
|
|
exposed: false,
|
|
condition: () => Format.display_mode});
|
|
new Property(ModelProject, 'vector', 'visible_box', {
|
|
exposed: false,
|
|
default: [1, 1, 0]
|
|
});
|
|
new Property(ModelProject, 'boolean', 'layered_textures', {
|
|
label: 'dialog.project.layered_textures',
|
|
description: 'dialog.project.layered_textures.desc',
|
|
condition() {return Format.single_texture}
|
|
});
|
|
|
|
|
|
const Project = new ModelProject();
|
|
|
|
|
|
//New
|
|
function resetProject() {
|
|
Project.reset()
|
|
}
|
|
function newProject(format, force) {
|
|
if (force || showSaveDialog()) {
|
|
if (Format) {
|
|
Project.reset();
|
|
}
|
|
if (format instanceof ModelFormat) {
|
|
format.select();
|
|
}
|
|
Modes.options.edit.select();
|
|
Blockbench.dispatchEvent('new_project');
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
BARS.defineActions(function() {
|
|
|
|
new Action('project_window', {
|
|
icon: 'featured_play_list',
|
|
category: 'file',
|
|
condition: () => Format,
|
|
click: function () {
|
|
|
|
let form = {
|
|
format: {type: 'info', label: 'data.format', text: Format.name||'unknown'}
|
|
}
|
|
|
|
for (var key in ModelProject.properties) {
|
|
let property = ModelProject.properties[key];
|
|
if (property.exposed == false || !Condition(property.condition)) continue;
|
|
|
|
let entry = form[property.name] = {
|
|
label: property.label,
|
|
description: property.description,
|
|
value: Project[property.name],
|
|
type: property.type
|
|
}
|
|
if (property.type == 'boolean') entry.type = 'checkbox';
|
|
if (property.type == 'string') entry.type = 'text';
|
|
if (property.options) {
|
|
entry.options = typeof property.options == 'function' ? property.options() : property.options;
|
|
entry.type = 'select';
|
|
}
|
|
}
|
|
|
|
form.uv_mode = {
|
|
label: 'dialog.project.uv_mode',
|
|
type: 'select',
|
|
condition: Format.optional_box_uv,
|
|
options: {
|
|
face_uv: 'dialog.project.uv_mode.face_uv',
|
|
box_uv: 'dialog.project.uv_mode.box_uv',
|
|
},
|
|
value: Project.box_uv ? 'box_uv' : 'face_uv',
|
|
};
|
|
|
|
form.texture_size = {
|
|
label: 'dialog.project.texture_size',
|
|
type: 'vector',
|
|
dimensions: 2,
|
|
value: [Project.texture_width, Project.texture_height],
|
|
min: 1
|
|
};
|
|
|
|
var dialog = new Dialog({
|
|
id: 'project',
|
|
title: 'dialog.project.title',
|
|
width: 500,
|
|
form,
|
|
onConfirm: function(formResult) {
|
|
var save;
|
|
let box_uv = formResult.uv_mode == 'box_uv';
|
|
let texture_width = Math.clamp(formResult.texture_size[0], 1, Infinity);
|
|
let texture_height = Math.clamp(formResult.texture_size[1], 1, Infinity);
|
|
|
|
if (Project.box_uv != box_uv ||
|
|
Project.texture_width != texture_width ||
|
|
Project.texture_height != texture_height
|
|
) {
|
|
if (!Project.box_uv && !box_uv
|
|
&& (Project.texture_width != texture_width
|
|
|| Project.texture_height != texture_height)
|
|
) {
|
|
save = Undo.initEdit({uv_only: true, elements: Cube.all, uv_mode: true})
|
|
Cube.all.forEach(cube => {
|
|
for (var key in cube.faces) {
|
|
var uv = cube.faces[key].uv;
|
|
uv[0] *= texture_width / Project.texture_width;
|
|
uv[2] *= texture_width / Project.texture_width;
|
|
uv[1] *= texture_height / Project.texture_height;
|
|
uv[3] *= texture_height / Project.texture_height;
|
|
}
|
|
})
|
|
} else {
|
|
save = Undo.initEdit({uv_mode: true})
|
|
}
|
|
Project.texture_width = texture_width;
|
|
Project.texture_height = texture_height;
|
|
|
|
if (Format.optional_box_uv) Project.box_uv = box_uv;
|
|
Canvas.updateAllUVs()
|
|
updateSelection()
|
|
}
|
|
|
|
if (Format.single_texture) {
|
|
if (Project.layered_textures !== formResult.layered_textures && Texture.all.length >= 2) {
|
|
Project.layered_textures = formResult.layered_textures;
|
|
Texture.all.forEach((tex, i) => {
|
|
tex.visible = i < 3
|
|
})
|
|
Interface.Panels.textures.inside_vue.$forceUpdate()
|
|
Canvas.updateLayeredTextures();
|
|
}
|
|
}
|
|
|
|
for (var key in ModelProject.properties) {
|
|
ModelProject.properties[key].merge(Project, formResult);
|
|
}
|
|
|
|
if (save) {
|
|
Undo.finishEdit('change global UV')
|
|
}
|
|
|
|
Blockbench.dispatchEvent('update_project_settings', formResult);
|
|
|
|
BARS.updateConditions()
|
|
if (EditSession.active) {
|
|
EditSession.sendAll('change_project_meta', JSON.stringify(Project));
|
|
}
|
|
|
|
dialog.hide()
|
|
}
|
|
})
|
|
dialog.show()
|
|
}
|
|
})
|
|
new Action('close_project', {
|
|
icon: 'cancel_presentation',
|
|
category: 'file',
|
|
condition: () => (!EditSession.active || EditSession.hosting) && Format,
|
|
click: function () {
|
|
if (showSaveDialog()) {
|
|
resetProject()
|
|
Modes.options.start.select()
|
|
Modes.vue.$forceUpdate()
|
|
Blockbench.dispatchEvent('close_project');
|
|
}
|
|
}
|
|
})
|
|
new Action('convert_project', {
|
|
icon: 'fas.fa-file-import',
|
|
category: 'file',
|
|
condition: () => (!EditSession.active || EditSession.hosting),
|
|
click: function () {
|
|
|
|
var options = {};
|
|
for (var key in Formats) {
|
|
if (key !== Format.id && key !== 'skin') {
|
|
options[key] = Formats[key].name;
|
|
}
|
|
}
|
|
|
|
var dialog = new Dialog({
|
|
id: 'convert_project',
|
|
title: 'dialog.convert_project.title',
|
|
width: 540,
|
|
form: {
|
|
text: {type: 'info', text: 'dialog.convert_project.text'},
|
|
format: {
|
|
label: 'data.format',
|
|
type: 'select',
|
|
default: Format.id,
|
|
options,
|
|
},
|
|
},
|
|
onConfirm: function(formResult) {
|
|
var format = Formats[formResult.format]
|
|
if (format && format != Format) {
|
|
format.convertTo()
|
|
}
|
|
dialog.hide()
|
|
}
|
|
})
|
|
dialog.show()
|
|
}
|
|
})
|
|
}) |