2025-03-03 21:53:10 +01:00
|
|
|
import { Vue } from "../../lib/libs";
|
|
|
|
import { Blockbench } from "../api";
|
|
|
|
import { setProjectTitle } from "../interface/interface";
|
|
|
|
import { Settings } from "../interface/settings";
|
|
|
|
import { Mode, Modes } from "../modes";
|
|
|
|
import { Group } from "../outliner/group";
|
|
|
|
import { Canvas } from "../preview/canvas";
|
|
|
|
import { DefaultCameraPresets } from "../preview/preview";
|
|
|
|
import { Property } from "../util/property";
|
|
|
|
|
2025-03-01 23:29:12 +01:00
|
|
|
export const Formats = {};
|
2020-12-13 15:10:08 +01:00
|
|
|
|
2025-03-05 18:10:25 +01:00
|
|
|
Object.defineProperty(window, 'Format', {
|
|
|
|
get() {
|
|
|
|
return Blockbench.Format;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-12-13 15:10:08 +01:00
|
|
|
//Formats
|
2025-03-03 21:53:10 +01:00
|
|
|
interface FormatOptions {
|
|
|
|
id: string
|
|
|
|
icon: string
|
|
|
|
name?: string
|
|
|
|
description?: string
|
|
|
|
category?: string
|
|
|
|
target?: string | string[]
|
|
|
|
confidential?: boolean
|
|
|
|
condition?: ConditionResolvable
|
|
|
|
show_on_start_screen?: boolean
|
|
|
|
show_in_new_list?: boolean
|
|
|
|
can_convert_to?: boolean
|
|
|
|
plugin?: string
|
|
|
|
format_page?: FormatPage
|
|
|
|
onFormatPage?(): void
|
|
|
|
onStart?(): void
|
|
|
|
onSetup?(project: ModelProject, newModel?: boolean): void
|
|
|
|
new?(): boolean
|
|
|
|
convertTo?(): void
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enables Box UV on cubes by default or something
|
|
|
|
*/
|
|
|
|
box_uv: boolean
|
|
|
|
/**
|
|
|
|
* If true, box UV is optional and can be toggled on the project or per cube
|
|
|
|
*/
|
|
|
|
optional_box_uv: boolean
|
|
|
|
/**
|
|
|
|
* If true, only one texture can be assigned to the model at a time, instead of textures being assigned per face
|
|
|
|
*/
|
|
|
|
single_texture: boolean
|
|
|
|
/**
|
|
|
|
* If true, a single texture is used as default, but textures can still be assigned to faces
|
|
|
|
*/
|
|
|
|
single_texture_default: boolean
|
|
|
|
/**
|
|
|
|
* If true, textures can be assigned per group instead of per face
|
|
|
|
*/
|
|
|
|
per_group_texture: boolean
|
|
|
|
/**
|
|
|
|
* If true, UV size (the size of the texture in UV space) will be defined per texture and not per project
|
|
|
|
*/
|
|
|
|
per_texture_uv_size: boolean
|
|
|
|
/**
|
|
|
|
* Enable a model identifier field in the project settings. Default is true
|
|
|
|
*/
|
|
|
|
model_identifier: boolean
|
|
|
|
/**
|
|
|
|
* If true, the file name of a project will be editable in the project settings
|
|
|
|
*/
|
|
|
|
legacy_editable_file_name: boolean
|
|
|
|
/**
|
|
|
|
* If true, enables a field in the project settings to set a parent model ID
|
|
|
|
*/
|
|
|
|
parent_model_id: boolean
|
|
|
|
/**
|
|
|
|
* Adds a toggle in the project settings to enable project wide vertex color ambient occlusion
|
|
|
|
*/
|
|
|
|
vertex_color_ambient_occlusion: boolean
|
|
|
|
/**
|
|
|
|
* Enable flipbook animated textures
|
|
|
|
*/
|
|
|
|
animated_textures: boolean
|
|
|
|
/**
|
|
|
|
* Enable groups to work as bones and rig the model
|
|
|
|
*/
|
|
|
|
bone_rig: boolean
|
|
|
|
/**
|
|
|
|
* Align the grid center with the model origin, instead of the grid corner
|
|
|
|
*/
|
|
|
|
centered_grid: boolean
|
|
|
|
/**
|
|
|
|
* Add the ability to rotate cubes
|
|
|
|
*/
|
|
|
|
rotate_cubes: boolean
|
|
|
|
/**
|
|
|
|
* Add the ability to stretch cubes. Stretch scales cubes from the center without affecting UV
|
|
|
|
*/
|
|
|
|
stretch_cubes: boolean
|
|
|
|
/**
|
|
|
|
* If true, cube sizes are limited to integer values
|
|
|
|
*/
|
|
|
|
integer_size: boolean
|
|
|
|
/**
|
|
|
|
* Enable mesh elements
|
|
|
|
*/
|
|
|
|
meshes: boolean
|
|
|
|
/**
|
|
|
|
* Enable texture meshes
|
|
|
|
*/
|
|
|
|
texture_meshes: boolean
|
|
|
|
/**
|
|
|
|
* Enable locators
|
|
|
|
*/
|
|
|
|
locators: boolean
|
|
|
|
/**
|
|
|
|
* Enforces a rotation limit for cubes of up to 45 degrees in either direction and one axis at a time
|
|
|
|
*/
|
|
|
|
rotation_limit: boolean
|
|
|
|
/**
|
|
|
|
* Forces cube rotations to snap to 22.5 degree increments
|
|
|
|
*/
|
|
|
|
rotation_snap: boolean
|
|
|
|
/**
|
|
|
|
* Allows cube UVs to be rotated
|
|
|
|
*/
|
|
|
|
uv_rotation: boolean
|
|
|
|
/**
|
|
|
|
* Enables Minecraft Java block/item model specific cube face features (tint and export)
|
|
|
|
*/
|
|
|
|
java_face_properties: boolean
|
|
|
|
/**
|
|
|
|
* Allows assigning one texture to be used as a texture for particles related to the model
|
|
|
|
*/
|
|
|
|
select_texture_for_particles: boolean
|
|
|
|
/**
|
|
|
|
* Enable mcmeta files for animated texture files
|
|
|
|
*/
|
|
|
|
texture_mcmeta: boolean
|
|
|
|
/**
|
|
|
|
* Enables an option to set an expression for bone bindings
|
|
|
|
*/
|
|
|
|
bone_binding_expression: boolean
|
|
|
|
/**
|
|
|
|
* If true, animations will be saved into files
|
|
|
|
*/
|
|
|
|
animation_files: boolean
|
|
|
|
/**
|
|
|
|
* Enables a folder path per texture that can be set in the texture properties window
|
|
|
|
*/
|
|
|
|
texture_folder: boolean
|
|
|
|
/**
|
|
|
|
* Enables the 2D image editor
|
|
|
|
*/
|
|
|
|
image_editor: boolean
|
|
|
|
/**
|
|
|
|
* Enables edit mode. Default is true
|
|
|
|
*/
|
|
|
|
edit_mode: boolean
|
|
|
|
/**
|
|
|
|
* Enables paint mode. Default is true
|
|
|
|
*/
|
|
|
|
paint_mode: boolean
|
|
|
|
/**
|
|
|
|
* Enables display mode
|
|
|
|
*/
|
|
|
|
display_mode: boolean
|
|
|
|
/**
|
|
|
|
* Emaböes animation mode
|
|
|
|
*/
|
|
|
|
animation_mode: boolean
|
|
|
|
/**
|
|
|
|
* Enables pose mode
|
|
|
|
*/
|
|
|
|
pose_mode: boolean
|
|
|
|
/**
|
|
|
|
* Enables animation controllers
|
|
|
|
*/
|
|
|
|
animation_controllers: boolean
|
|
|
|
/**
|
|
|
|
* If true, cube sizes will not be floored to calculate UV sizes with box UV. This can result in UVs not aligning with pixel edges
|
|
|
|
*/
|
|
|
|
box_uv_float_size: boolean
|
|
|
|
/**
|
|
|
|
* Enables properties for Minecraft Java block/item models related to block shading (shading option and light emission value)
|
|
|
|
*/
|
|
|
|
java_cube_shading_properties: boolean
|
|
|
|
/**
|
|
|
|
* Enables cullfaces, the ability on faces in Minecraft block models to set a direction, that, if covered by another block, will cause the face to unrender
|
|
|
|
*/
|
|
|
|
cullfaces: boolean
|
|
|
|
/**
|
|
|
|
* A set of characters that is allowed in node names (names of elements and groups that can be referenced externally, this does not apply to cubes or meshes)
|
|
|
|
*/
|
|
|
|
node_name_regex: string
|
|
|
|
/**
|
|
|
|
* Set the default render sides for textures
|
|
|
|
*/
|
|
|
|
render_sides: 'front' | 'double' | 'back' | (() => 'front' | 'double' | 'back')
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Options to limit the size of cubes
|
|
|
|
*/
|
|
|
|
cube_size_limiter?: CubeSizeLimiter
|
|
|
|
|
|
|
|
codec?: Codec
|
|
|
|
onActivation?(): void
|
|
|
|
onDeactivation?(): void
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ModelFormat implements FormatOptions {
|
|
|
|
id: string
|
|
|
|
icon: string
|
|
|
|
name: string
|
|
|
|
description: string
|
|
|
|
category: string
|
|
|
|
target: string | string[]
|
|
|
|
confidential: boolean
|
|
|
|
condition: ConditionResolvable
|
|
|
|
show_on_start_screen: boolean
|
|
|
|
show_in_new_list: boolean
|
|
|
|
can_convert_to: boolean
|
|
|
|
plugin: string
|
|
|
|
format_page?: FormatPage
|
|
|
|
onFormatPage?(): void
|
|
|
|
onStart?(): void
|
|
|
|
onSetup?(project: ModelProject, newModel?: boolean): void
|
|
|
|
|
|
|
|
box_uv: boolean
|
|
|
|
optional_box_uv: boolean
|
|
|
|
single_texture: boolean
|
|
|
|
single_texture_default: boolean
|
|
|
|
per_group_texture: boolean
|
|
|
|
per_texture_uv_size: boolean
|
|
|
|
model_identifier: boolean
|
|
|
|
legacy_editable_file_name: boolean
|
|
|
|
parent_model_id: boolean
|
|
|
|
vertex_color_ambient_occlusion: boolean
|
|
|
|
animated_textures: boolean
|
|
|
|
bone_rig: boolean
|
|
|
|
centered_grid: boolean
|
|
|
|
rotate_cubes: boolean
|
|
|
|
stretch_cubes: boolean
|
|
|
|
integer_size: boolean
|
|
|
|
meshes: boolean
|
|
|
|
texture_meshes: boolean
|
|
|
|
locators: boolean
|
|
|
|
rotation_limit: boolean
|
|
|
|
rotation_snap: boolean
|
|
|
|
uv_rotation: boolean
|
|
|
|
java_face_properties: boolean
|
|
|
|
select_texture_for_particles: boolean
|
|
|
|
texture_mcmeta: boolean
|
|
|
|
bone_binding_expression: boolean
|
|
|
|
animation_files: boolean
|
|
|
|
texture_folder: boolean
|
|
|
|
image_editor: boolean
|
|
|
|
edit_mode: boolean
|
|
|
|
paint_mode: boolean
|
|
|
|
display_mode: boolean
|
|
|
|
animation_mode: boolean
|
|
|
|
pose_mode: boolean
|
|
|
|
animation_controllers: boolean
|
|
|
|
box_uv_float_size: boolean
|
|
|
|
java_cube_shading_properties: boolean
|
|
|
|
cullfaces: boolean
|
|
|
|
node_name_regex: string
|
|
|
|
render_sides: 'front' | 'double' | 'back' | (() => 'front' | 'double' | 'back')
|
|
|
|
|
|
|
|
cube_size_limiter?: CubeSizeLimiter
|
|
|
|
|
|
|
|
codec?: Codec
|
|
|
|
onActivation?(): void
|
|
|
|
onDeactivation?(): void
|
|
|
|
|
|
|
|
static properties: Record<string, Property>
|
|
|
|
|
|
|
|
constructor(id, data: FormatOptions) {
|
2022-05-23 20:46:49 +02:00
|
|
|
if (typeof id == 'object') {
|
|
|
|
data = id;
|
|
|
|
id = data.id;
|
|
|
|
}
|
|
|
|
Formats[id] = this;
|
|
|
|
this.id = id;
|
2020-12-13 15:10:08 +01:00
|
|
|
this.name = data.name || tl('format.'+this.id);
|
|
|
|
this.description = data.description || tl('format.'+this.id+'.desc');
|
2022-10-20 13:05:59 +02:00
|
|
|
if (this.description == 'format.'+this.id+'.desc') this.description = '';
|
2022-05-18 23:44:00 +02:00
|
|
|
this.category = data.category || 'other';
|
|
|
|
this.target = data.target;
|
2020-12-13 15:10:08 +01:00
|
|
|
this.show_on_start_screen = true;
|
2021-12-10 17:14:05 +01:00
|
|
|
this.confidential = false;
|
2020-12-13 15:10:08 +01:00
|
|
|
|
2021-10-07 10:20:58 +03:00
|
|
|
for (let id in ModelFormat.properties) {
|
|
|
|
ModelFormat.properties[id].reset(this);
|
|
|
|
}
|
2022-05-26 20:30:42 +02:00
|
|
|
this.render_sides = data.render_sides;
|
2022-06-02 23:02:13 +02:00
|
|
|
this.cube_size_limiter = data.cube_size_limiter;
|
2020-12-13 15:10:08 +01:00
|
|
|
|
|
|
|
this.codec = data.codec;
|
2022-05-29 12:33:41 +02:00
|
|
|
this.onSetup = data.onSetup;
|
2022-06-15 18:54:38 +02:00
|
|
|
this.onFormatPage = data.onFormatPage;
|
2020-12-13 15:10:08 +01:00
|
|
|
this.onActivation = data.onActivation;
|
|
|
|
this.onDeactivation = data.onDeactivation;
|
2022-05-23 20:46:49 +02:00
|
|
|
this.format_page = data.format_page;
|
2020-12-13 15:10:08 +01:00
|
|
|
Merge.string(this, data, 'icon');
|
|
|
|
Merge.boolean(this, data, 'show_on_start_screen');
|
2022-08-06 13:37:20 +02:00
|
|
|
Merge.boolean(this, data, 'show_in_new_list');
|
2022-05-18 23:52:12 +02:00
|
|
|
Merge.boolean(this, data, 'can_convert_to');
|
2021-12-10 17:14:05 +01:00
|
|
|
Merge.boolean(this, data, 'confidential');
|
2021-10-07 10:20:58 +03:00
|
|
|
|
2022-08-06 13:37:20 +02:00
|
|
|
if (data.new) this.new = data.new;
|
|
|
|
|
2022-11-10 15:04:40 +01:00
|
|
|
if (data.rotation_limit && data.rotation_snap === undefined) {
|
|
|
|
data.rotation_snap = true;
|
|
|
|
}
|
2021-10-07 10:20:58 +03:00
|
|
|
for (let id in ModelFormat.properties) {
|
|
|
|
ModelFormat.properties[id].merge(this, data);
|
|
|
|
}
|
2022-05-23 20:46:49 +02:00
|
|
|
if (this.format_page && this.format_page.component) {
|
|
|
|
Vue.component(`format_page_${this.id}`, this.format_page.component)
|
|
|
|
}
|
2022-09-13 13:30:00 +02:00
|
|
|
Blockbench.dispatchEvent('construct_format', {format: this});
|
2020-12-13 15:10:08 +01:00
|
|
|
}
|
2021-10-15 12:15:11 +02:00
|
|
|
select() {
|
2020-12-13 15:10:08 +01:00
|
|
|
if (Format && typeof Format.onDeactivation == 'function') {
|
|
|
|
Format.onDeactivation()
|
|
|
|
}
|
2025-03-03 23:11:05 +01:00
|
|
|
// @ts-ignore Incompatible internal and external types
|
2025-03-03 21:53:10 +01:00
|
|
|
Blockbench.Format = Blockbench.Project.format = this;
|
2020-12-13 15:10:08 +01:00
|
|
|
if (typeof this.onActivation == 'function') {
|
|
|
|
Format.onActivation()
|
|
|
|
}
|
2022-02-12 00:06:31 +01:00
|
|
|
Canvas.buildGrid()
|
2020-12-13 15:10:08 +01:00
|
|
|
if (Format.centered_grid) {
|
|
|
|
scene.position.set(0, 0, 0);
|
2021-11-11 21:56:21 +01:00
|
|
|
Canvas.ground_plane.position.x = Canvas.ground_plane.position.z = 8;
|
2020-12-13 15:10:08 +01:00
|
|
|
} else {
|
2024-09-11 22:57:09 +02:00
|
|
|
scene.position.set(-8, 0, -8);
|
2021-11-11 21:56:21 +01:00
|
|
|
Canvas.ground_plane.position.x = Canvas.ground_plane.position.z = 0;
|
2020-12-13 15:10:08 +01:00
|
|
|
}
|
2023-07-16 19:36:41 +02:00
|
|
|
PreviewModel.getActiveModels().forEach(model => {
|
|
|
|
model.update();
|
|
|
|
})
|
2022-12-31 01:05:51 +01:00
|
|
|
Settings.updateSettingsInProfiles();
|
2020-12-13 15:10:08 +01:00
|
|
|
Preview.all.forEach(preview => {
|
|
|
|
if (preview.isOrtho && typeof preview.angle == 'number') {
|
2025-03-03 21:53:10 +01:00
|
|
|
// @ts-ignore Incompatible internal and external types
|
|
|
|
preview.loadAnglePreset(DefaultCameraPresets[preview.angle+1] as AnglePreset)
|
2020-12-13 15:10:08 +01:00
|
|
|
}
|
|
|
|
})
|
2021-12-20 22:26:07 +01:00
|
|
|
if (Mode.selected && !Condition(Mode.selected.condition)) {
|
|
|
|
(this.pose_mode ? Modes.options.paint : Modes.options.edit).select();
|
|
|
|
}
|
2025-03-03 21:53:10 +01:00
|
|
|
Interface.Panels.animations.inside_vue.$data.animation_files_enabled = this.animation_files;
|
|
|
|
// @ts-ignore
|
2021-09-21 11:20:10 +02:00
|
|
|
Interface.status_bar.vue.Format = this;
|
2023-04-26 00:45:42 +02:00
|
|
|
UVEditor.vue.cube_uv_rotation = this.uv_rotation;
|
2024-03-16 13:34:01 +01:00
|
|
|
if (Modes.vue) Modes.vue.$forceUpdate();
|
|
|
|
updateInterfacePanels();
|
2022-07-07 07:33:20 +02:00
|
|
|
Canvas.updateShading();
|
2020-12-13 15:10:08 +01:00
|
|
|
Canvas.updateRenderSides()
|
2022-09-13 13:30:00 +02:00
|
|
|
Blockbench.dispatchEvent('select_format', {format: this, project: Project});
|
2020-12-13 15:10:08 +01:00
|
|
|
return this;
|
|
|
|
}
|
2025-03-03 21:53:10 +01:00
|
|
|
new(): boolean {
|
|
|
|
// @ts-ignore Conflicting internal and external types
|
2020-12-13 15:10:08 +01:00
|
|
|
if (newProject(this)) {
|
2025-03-03 21:53:10 +01:00
|
|
|
(BarItems.project_window as Action).click();
|
2020-12-13 15:10:08 +01:00
|
|
|
return true;
|
|
|
|
}
|
2025-03-03 21:53:10 +01:00
|
|
|
return false;
|
2020-12-13 15:10:08 +01:00
|
|
|
}
|
|
|
|
convertTo() {
|
|
|
|
|
2020-12-31 15:08:35 +01:00
|
|
|
Undo.history.empty();
|
2020-12-13 15:10:08 +01:00
|
|
|
Undo.index = 0;
|
2021-05-05 13:54:41 +02:00
|
|
|
Project.export_path = '';
|
2022-12-23 23:29:55 +01:00
|
|
|
Project.unhandled_root_fields = {};
|
2020-12-13 15:10:08 +01:00
|
|
|
|
2022-05-20 00:24:43 +02:00
|
|
|
var old_format = Format;
|
2021-10-15 12:15:11 +02:00
|
|
|
this.select();
|
2020-12-13 15:10:08 +01:00
|
|
|
Modes.options.edit.select()
|
|
|
|
|
2021-10-15 12:15:11 +02:00
|
|
|
// Box UV
|
2022-09-25 01:12:03 +02:00
|
|
|
if (!this.optional_box_uv) {
|
|
|
|
Project.box_uv = this.box_uv;
|
|
|
|
Cube.all.forEach(cube => {
|
|
|
|
cube.setUVMode(this.box_uv);
|
|
|
|
})
|
|
|
|
}
|
2021-10-15 12:15:11 +02:00
|
|
|
|
2023-12-04 14:51:48 +01:00
|
|
|
if (!Format.per_texture_uv_size && old_format.per_texture_uv_size) {
|
|
|
|
let tex = Texture.getDefault();
|
|
|
|
if (tex) {
|
|
|
|
Project.texture_width = tex.uv_width;
|
|
|
|
Project.texture_height = tex.uv_height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Format.per_texture_uv_size && !old_format.per_texture_uv_size) {
|
|
|
|
Texture.all.forEach(tex => {
|
|
|
|
tex.uv_width = Project.texture_width;
|
|
|
|
tex.uv_height = Project.texture_height;
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-13 15:10:08 +01:00
|
|
|
//Bone Rig
|
|
|
|
if (!Format.bone_rig && old_format.bone_rig) {
|
|
|
|
Group.all.forEach(group => {
|
|
|
|
group.rotation.V3_set(0, 0, 0);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if (Format.bone_rig && !old_format.bone_rig) {
|
|
|
|
var loose_stuff = []
|
|
|
|
Outliner.root.forEach(el => {
|
|
|
|
if (el instanceof Group == false) {
|
|
|
|
loose_stuff.push(el)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
if (loose_stuff.length) {
|
|
|
|
var root_group = new Group().init().addTo()
|
|
|
|
loose_stuff.forEach(el => {
|
|
|
|
el.addTo(root_group)
|
|
|
|
})
|
|
|
|
}
|
2025-03-03 21:53:10 +01:00
|
|
|
// @ts-ignore
|
2020-12-13 15:10:08 +01:00
|
|
|
if (!Project.geometry_name && Project.name) {
|
2025-03-03 21:53:10 +01:00
|
|
|
// @ts-ignore
|
2020-12-13 15:10:08 +01:00
|
|
|
Project.geometry_name = Project.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Format.bone_rig) {
|
|
|
|
Group.all.forEach(group => {
|
|
|
|
group.createUniqueName();
|
|
|
|
})
|
|
|
|
}
|
2023-07-10 21:18:12 +02:00
|
|
|
if (Format.centered_grid != old_format.centered_grid) {
|
|
|
|
let offset = Format.centered_grid ? -8 : 8;
|
|
|
|
Cube.all.forEach(cube => {
|
|
|
|
for (let axis of [0, 2]) {
|
|
|
|
cube.from[axis] += offset;
|
|
|
|
cube.to[axis] += offset;
|
|
|
|
cube.origin[axis] += offset;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
Group.all.forEach(group => {
|
|
|
|
group.origin[0] += offset;
|
|
|
|
group.origin[2] += offset;
|
|
|
|
})
|
|
|
|
}
|
2020-12-13 15:10:08 +01:00
|
|
|
|
2021-08-29 10:44:05 +02:00
|
|
|
if (!Format.single_texture && old_format.single_texture && Texture.all.length) {
|
2021-08-30 10:30:46 +02:00
|
|
|
let texture = Texture.getDefault();
|
2025-03-03 21:53:10 +01:00
|
|
|
Outliner.elements.filter((el: OutlinerElement) => 'applyTexture' in el).forEach(el => {
|
|
|
|
// @ts-ignore
|
2021-08-29 10:44:05 +02:00
|
|
|
el.applyTexture(texture, true)
|
2021-07-29 18:17:26 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-13 15:10:08 +01:00
|
|
|
//Rotate Cubes
|
|
|
|
if (!Format.rotate_cubes && old_format.rotate_cubes) {
|
|
|
|
Cube.all.forEach(cube => {
|
|
|
|
cube.rotation.V3_set(0, 0, 0)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-26 17:07:51 +02:00
|
|
|
//Meshes
|
|
|
|
if (!Format.meshes && old_format.meshes) {
|
|
|
|
Mesh.all.slice().forEach(mesh => {
|
|
|
|
mesh.remove()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-13 15:10:08 +01:00
|
|
|
//Locators
|
|
|
|
if (!Format.locators && old_format.locators) {
|
|
|
|
Locator.all.slice().forEach(locator => {
|
|
|
|
locator.remove()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-08-29 10:44:05 +02:00
|
|
|
//Texture Meshes
|
|
|
|
if (!Format.texture_meshes && old_format.texture_meshes) {
|
|
|
|
TextureMesh.all.slice().forEach(tm => {
|
|
|
|
tm.remove()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-12-13 15:10:08 +01:00
|
|
|
//Canvas Limit
|
2022-06-02 23:02:13 +02:00
|
|
|
if (Format.cube_size_limiter && !old_format.cube_size_limiter && !settings.deactivate_size_limit.value) {
|
2022-10-19 13:59:35 +02:00
|
|
|
Cube.all.forEach(cube => {
|
|
|
|
Format.cube_size_limiter.move(cube);
|
|
|
|
})
|
|
|
|
Cube.all.forEach(cube => {
|
|
|
|
Format.cube_size_limiter.clamp(cube);
|
2020-12-13 15:10:08 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
//Rotation Limit
|
|
|
|
if (Format.rotation_limit && !old_format.rotation_limit && Format.rotate_cubes) {
|
|
|
|
Cube.all.forEach(cube => {
|
|
|
|
if (!cube.rotation.allEqual(0)) {
|
2023-07-10 21:18:12 +02:00
|
|
|
var axis = (getAxisNumber(cube.rotationAxis())) || 0;
|
2022-10-17 20:01:31 +10:30
|
|
|
var cube_rotation = Format.rotation_snap ? Math.round(cube.rotation[axis]/22.5)*22.5 : cube.rotation[axis];
|
2022-10-17 19:57:37 +10:30
|
|
|
var angle = limitNumber( cube_rotation, -45, 45 );
|
2020-12-13 15:10:08 +01:00
|
|
|
cube.rotation.V3_set(0, 0, 0)
|
|
|
|
cube.rotation[axis] = angle;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
//Animation Mode
|
|
|
|
if (!Format.animation_mode && old_format.animation_mode) {
|
|
|
|
Animator.animations.length = 0;
|
|
|
|
}
|
2022-05-18 23:52:12 +02:00
|
|
|
|
2022-10-01 17:11:42 +02:00
|
|
|
Project.saved = false;
|
|
|
|
setProjectTitle();
|
|
|
|
|
2022-05-18 23:52:12 +02:00
|
|
|
Blockbench.dispatchEvent('convert_format', {format: this, old_format})
|
|
|
|
|
2022-05-29 12:33:41 +02:00
|
|
|
if (typeof this.onSetup == 'function') {
|
|
|
|
this.onSetup(Project)
|
|
|
|
}
|
|
|
|
|
2020-12-13 15:10:08 +01:00
|
|
|
Canvas.updateAllPositions()
|
|
|
|
Canvas.updateAllBones()
|
|
|
|
Canvas.updateAllFaces()
|
|
|
|
updateSelection()
|
|
|
|
}
|
|
|
|
delete() {
|
|
|
|
delete Formats[this.id];
|
2025-03-03 21:53:10 +01:00
|
|
|
// @ts-ignore
|
2020-12-13 15:10:08 +01:00
|
|
|
if (this.codec && this.codec.format == this) delete this.codec.format;
|
2022-09-13 13:30:00 +02:00
|
|
|
Blockbench.dispatchEvent('delete_format', {format: this});
|
2020-12-13 15:10:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-22 12:37:48 +01:00
|
|
|
new Property(ModelFormat, 'string', 'node_name_regex');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'box_uv');
|
|
|
|
new Property(ModelFormat, 'boolean', 'optional_box_uv');
|
2023-02-16 21:37:47 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'box_uv_float_size');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'single_texture');
|
2024-04-28 21:57:45 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'single_texture_default');
|
2024-04-14 23:06:46 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'per_group_texture');
|
2023-03-18 23:52:19 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'per_texture_uv_size');
|
2022-05-20 00:24:43 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'model_identifier', {default: true});
|
2024-01-12 18:38:44 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'legacy_editable_file_name');
|
2022-05-26 20:30:42 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'parent_model_id');
|
|
|
|
new Property(ModelFormat, 'boolean', 'vertex_color_ambient_occlusion');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'animated_textures');
|
|
|
|
new Property(ModelFormat, 'boolean', 'bone_rig');
|
|
|
|
new Property(ModelFormat, 'boolean', 'centered_grid');
|
|
|
|
new Property(ModelFormat, 'boolean', 'rotate_cubes');
|
2023-04-04 16:57:45 -07:00
|
|
|
new Property(ModelFormat, 'boolean', 'stretch_cubes');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'integer_size');
|
|
|
|
new Property(ModelFormat, 'boolean', 'meshes');
|
|
|
|
new Property(ModelFormat, 'boolean', 'texture_meshes');
|
|
|
|
new Property(ModelFormat, 'boolean', 'locators');
|
|
|
|
new Property(ModelFormat, 'boolean', 'rotation_limit');
|
2022-11-08 21:35:29 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'rotation_snap');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'uv_rotation');
|
2024-08-20 22:45:16 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'java_cube_shading_properties');
|
2022-05-26 20:30:42 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'java_face_properties');
|
2024-09-11 22:57:09 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'cullfaces');
|
2022-05-26 20:30:42 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'select_texture_for_particles');
|
2022-10-07 19:52:36 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'texture_mcmeta');
|
2022-05-26 20:30:42 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'bone_binding_expression');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'animation_files');
|
2022-11-30 20:15:47 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'animation_controllers');
|
2022-11-02 18:33:31 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'image_editor');
|
2022-08-06 13:37:20 +02:00
|
|
|
new Property(ModelFormat, 'boolean', 'edit_mode', {default: true});
|
|
|
|
new Property(ModelFormat, 'boolean', 'paint_mode', {default: true});
|
2021-11-23 12:51:09 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'pose_mode');
|
2021-10-07 10:20:58 +03:00
|
|
|
new Property(ModelFormat, 'boolean', 'display_mode');
|
|
|
|
new Property(ModelFormat, 'boolean', 'animation_mode');
|
|
|
|
new Property(ModelFormat, 'boolean', 'texture_folder');
|
2024-11-09 21:01:12 +01:00
|
|
|
new Property(ModelFormat, 'boolean', 'pbr');
|
2025-03-01 23:29:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
Object.assign(window, {
|
|
|
|
ModelFormat,
|
|
|
|
Formats
|
|
|
|
});
|