summaryrefslogtreecommitdiff
path: root/editor/import
diff options
context:
space:
mode:
Diffstat (limited to 'editor/import')
-rw-r--r--editor/import/collada.cpp86
-rw-r--r--editor/import/collada.h4
-rw-r--r--editor/import/dynamicfont_import_settings.cpp629
-rw-r--r--editor/import/dynamicfont_import_settings.h26
-rw-r--r--editor/import/editor_import_collada.cpp262
-rw-r--r--editor/import/editor_import_collada.h14
-rw-r--r--editor/import/editor_import_plugin.cpp18
-rw-r--r--editor/import/editor_import_plugin.h12
-rw-r--r--editor/import/editor_importer_bake_reset.cpp234
-rw-r--r--editor/import/editor_importer_bake_reset.h54
-rw-r--r--editor/import/resource_importer_bitmask.cpp8
-rw-r--r--editor/import/resource_importer_bitmask.h8
-rw-r--r--editor/import/resource_importer_bmfont.cpp723
-rw-r--r--editor/import/resource_importer_bmfont.h8
-rw-r--r--editor/import/resource_importer_csv_translation.cpp13
-rw-r--r--editor/import/resource_importer_csv_translation.h8
-rw-r--r--editor/import/resource_importer_dynamicfont.cpp17
-rw-r--r--editor/import/resource_importer_dynamicfont.h8
-rw-r--r--editor/import/resource_importer_image.cpp8
-rw-r--r--editor/import/resource_importer_image.h8
-rw-r--r--editor/import/resource_importer_imagefont.cpp8
-rw-r--r--editor/import/resource_importer_imagefont.h8
-rw-r--r--editor/import/resource_importer_layered_texture.cpp17
-rw-r--r--editor/import/resource_importer_layered_texture.h10
-rw-r--r--editor/import/resource_importer_obj.cpp38
-rw-r--r--editor/import/resource_importer_obj.h19
-rw-r--r--editor/import/resource_importer_scene.cpp882
-rw-r--r--editor/import/resource_importer_scene.h150
-rw-r--r--editor/import/resource_importer_shader_file.cpp8
-rw-r--r--editor/import/resource_importer_shader_file.h8
-rw-r--r--editor/import/resource_importer_texture.cpp52
-rw-r--r--editor/import/resource_importer_texture.h8
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp21
-rw-r--r--editor/import/resource_importer_texture_atlas.h9
-rw-r--r--editor/import/resource_importer_wav.cpp24
-rw-r--r--editor/import/resource_importer_wav.h8
-rw-r--r--editor/import/scene_import_settings.cpp87
-rw-r--r--editor/import/scene_import_settings.h4
-rw-r--r--editor/import/scene_importer_mesh.cpp889
-rw-r--r--editor/import/scene_importer_mesh.h124
-rw-r--r--editor/import/scene_importer_mesh_node_3d.cpp83
-rw-r--r--editor/import/scene_importer_mesh_node_3d.h64
42 files changed, 1413 insertions, 3256 deletions
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index b6d0927ce6..2cc534d96d 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -541,7 +541,10 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
COLLADA_PRINT("node name: " + parser.get_node_name());
- if (!parser.is_empty() && (parser.get_node_name() == "profile_COMMON" || parser.get_node_name() == "technique" || parser.get_node_name() == "extra")) {
+ if (!parser.is_empty() &&
+ (parser.get_node_name() == "profile_COMMON" ||
+ parser.get_node_name() == "technique" ||
+ parser.get_node_name() == "extra")) {
_parse_effect_material(parser, effect, id); // try again
} else if (parser.get_node_name() == "newparam") {
@@ -551,9 +554,9 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
COLLADA_PRINT("param: " + name + " value:" + String(value));
} else if (parser.get_node_name() == "constant" ||
- parser.get_node_name() == "lambert" ||
- parser.get_node_name() == "phong" ||
- parser.get_node_name() == "blinn") {
+ parser.get_node_name() == "lambert" ||
+ parser.get_node_name() == "phong" ||
+ parser.get_node_name() == "blinn") {
COLLADA_PRINT("shade model: " + parser.get_node_name());
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
@@ -627,10 +630,11 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
} else if (what == "shininess") {
effect.shininess = _parse_param(parser);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && (parser.get_node_name() == "constant" ||
- parser.get_node_name() == "lambert" ||
- parser.get_node_name() == "phong" ||
- parser.get_node_name() == "blinn")) {
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END &&
+ (parser.get_node_name() == "constant" ||
+ parser.get_node_name() == "lambert" ||
+ parser.get_node_name() == "phong" ||
+ parser.get_node_name() == "blinn")) {
break;
}
}
@@ -681,10 +685,10 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
parser.skip_section();
}
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END &&
- (parser.get_node_name() == "effect" ||
- parser.get_node_name() == "profile_COMMON" ||
- parser.get_node_name() == "technique" ||
- parser.get_node_name() == "extra")) {
+ (parser.get_node_name() == "effect" ||
+ parser.get_node_name() == "profile_COMMON" ||
+ parser.get_node_name() == "technique" ||
+ parser.get_node_name() == "extra")) {
break;
}
}
@@ -1358,7 +1362,7 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
} else if (parser.get_node_name() == "skeleton") {
parser.read();
String uri = _uri_to_id(parser.get_node_data());
- if (uri != "") {
+ if (!uri.is_empty()) {
geom->skeletons.push_back(uri);
}
}
@@ -1460,7 +1464,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
bool found_name = false;
- if (id == "") {
+ if (id.is_empty()) {
id = "%NODEID%" + itos(Math::rand());
} else {
@@ -1475,7 +1479,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
Node *node = nullptr;
name = parser.has_attribute("name") ? parser.get_attribute_value_safe("name") : parser.get_attribute_value_safe("id");
- if (name == "") {
+ if (name.is_empty()) {
name = id;
} else {
found_name = true;
@@ -1495,7 +1499,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
joint->sid = parser.get_attribute_value_safe("name");
}
- if (joint->sid != "") {
+ if (!joint->sid.is_empty()) {
state.sid_to_node_map[joint->sid] = id;
}
@@ -1692,16 +1696,16 @@ void Collada::_parse_animation(XMLParser &parser) {
source_param_types[current_source] = Vector<String>();
} else if (name == "float_array") {
- if (current_source != "") {
+ if (!current_source.is_empty()) {
float_sources[current_source] = _read_float_array(parser);
}
} else if (name == "Name_array") {
- if (current_source != "") {
+ if (!current_source.is_empty()) {
string_sources[current_source] = _read_string_array(parser);
}
} else if (name == "accessor") {
- if (current_source != "" && parser.has_attribute("stride")) {
+ if (!current_source.is_empty() && parser.has_attribute("stride")) {
source_strides[current_source] = parser.get_attribute_value("stride").to_int();
}
} else if (name == "sampler") {
@@ -1721,7 +1725,7 @@ void Collada::_parse_animation(XMLParser &parser) {
}
} else if (name == "input") {
- if (current_sampler != "") {
+ if (!current_sampler.is_empty()) {
samplers[current_sampler][parser.get_attribute_value("semantic")] = parser.get_attribute_value("source");
}
@@ -1834,7 +1838,7 @@ void Collada::_parse_animation(XMLParser &parser) {
track.component = track.param.get_slice(".", 1).to_upper();
}
track.param = track.param.get_slice(".", 0);
- if (names.size() > 1 && track.component == "") {
+ if (names.size() > 1 && track.component.is_empty()) {
//this is a guess because the collada spec is ambiguous here...
//i suppose if you have many names (outputs) you can't use a component and i should abide to that.
track.component = name;
@@ -1851,7 +1855,7 @@ void Collada::_parse_animation(XMLParser &parser) {
state.referenced_tracks[target].push_back(state.animation_tracks.size() - 1);
- if (id != "") {
+ if (!id.is_empty()) {
if (!state.by_id_tracks.has(id)) {
state.by_id_tracks[id] = Vector<int>();
}
@@ -1949,10 +1953,10 @@ void Collada::_parse_library(XMLParser &parser) {
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "mesh") {
- state.mesh_name_map[id] = (name2 != "") ? name2 : id;
+ state.mesh_name_map[id] = (!name2.is_empty()) ? name2 : id;
_parse_mesh_geometry(parser, id, name2);
} else if (parser.get_node_name() == "spline") {
- state.mesh_name_map[id] = (name2 != "") ? name2 : id;
+ state.mesh_name_map[id] = (!name2.is_empty()) ? name2 : id;
_parse_curve_geometry(parser, id, name2);
} else if (!parser.is_empty()) {
parser.skip_section();
@@ -2020,7 +2024,7 @@ void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton
bool Collada::_remove_node(Node *p_parent, Node *p_node) {
for (int i = 0; i < p_parent->children.size(); i++) {
if (p_parent->children[i] == p_node) {
- p_parent->children.remove(i);
+ p_parent->children.remove_at(i);
return true;
}
if (_remove_node(p_parent->children[i], p_node)) {
@@ -2034,7 +2038,7 @@ bool Collada::_remove_node(Node *p_parent, Node *p_node) {
void Collada::_remove_node(VisualScene *p_vscene, Node *p_node) {
for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
if (p_vscene->root_nodes[i] == p_node) {
- p_vscene->root_nodes.remove(i);
+ p_vscene->root_nodes.remove_at(i);
return;
}
if (_remove_node(p_vscene->root_nodes[i], p_node)) {
@@ -2095,19 +2099,19 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
}
void Collada::_merge_skeletons2(VisualScene *p_vscene) {
- for (Map<String, SkinControllerData>::Element *E = state.skin_controller_data_map.front(); E; E = E->next()) {
- SkinControllerData &cd = E->get();
+ for (KeyValue<String, SkinControllerData> &E : state.skin_controller_data_map) {
+ SkinControllerData &cd = E.value;
NodeSkeleton *skeleton = nullptr;
- for (Map<String, Transform3D>::Element *F = cd.bone_rest_map.front(); F; F = F->next()) {
+ for (const KeyValue<String, Transform3D> &F : cd.bone_rest_map) {
String name;
- if (!state.sid_to_node_map.has(F->key())) {
+ if (!state.sid_to_node_map.has(F.key)) {
continue;
}
- name = state.sid_to_node_map[F->key()];
+ name = state.sid_to_node_map[F.key];
ERR_CONTINUE(!state.scene_map.has(name));
@@ -2248,9 +2252,9 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L
p_node->default_transform = skel_inv * (skin.bind_shape /* p_node->get_global_transform()*/); // i honestly have no idea what to do with a previous model xform.. most exporters ignore it
//make rests relative to the skeleton (they seem to be always relative to world)
- for (Map<String, Transform3D>::Element *E = skin.bone_rest_map.front(); E; E = E->next()) {
- E->get() = skel_inv * E->get(); //make the bone rest local to the skeleton
- state.bone_rest_map[E->key()] = E->get(); // make it remember where the bone is globally, now that it's relative
+ for (KeyValue<String, Transform3D> &E : skin.bone_rest_map) {
+ E.value = skel_inv * E.value; //make the bone rest local to the skeleton
+ state.bone_rest_map[E.key] = E.value; // make it remember where the bone is globally, now that it's relative
}
//but most exporters seem to work only if i do this..
@@ -2267,7 +2271,7 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L
for (int i = 0; i < p_node->children.size(); i++) {
if (_move_geometry_to_skeletons(p_vscene, p_node->children[i], p_mgeom)) {
- p_node->children.remove(i);
+ p_node->children.remove_at(i);
i--;
}
}
@@ -2282,7 +2286,7 @@ void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
if (nj->controller) {
String base = nj->source;
- while (base != "" && !state.mesh_data_map.has(base)) {
+ while (!base.is_empty() && !state.mesh_data_map.has(base)) {
if (state.skin_controller_data_map.has(base)) {
SkinControllerData &sk = state.skin_controller_data_map[base];
base = sk.base;
@@ -2302,8 +2306,8 @@ void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
}
void Collada::_optimize() {
- for (Map<String, VisualScene>::Element *E = state.visual_scene_map.front(); E; E = E->next()) {
- VisualScene &vs = E->get();
+ for (KeyValue<String, VisualScene> &E : state.visual_scene_map) {
+ VisualScene &vs = E.value;
for (int i = 0; i < vs.root_nodes.size(); i++) {
_create_skeletons(&vs.root_nodes.write[i]);
}
@@ -2321,7 +2325,7 @@ void Collada::_optimize() {
for (int i = 0; i < vs.root_nodes.size(); i++) {
List<Node *> mgeom;
if (_move_geometry_to_skeletons(&vs, vs.root_nodes[i], &mgeom)) {
- vs.root_nodes.remove(i);
+ vs.root_nodes.remove_at(i);
i--;
}
diff --git a/editor/import/collada.h b/editor/import/collada.h
index 5e38637504..b5e4cd9983 100644
--- a/editor/import/collada.h
+++ b/editor/import/collada.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp
index 37ca40287f..f4b1468314 100644
--- a/editor/import/dynamicfont_import_settings.cpp
+++ b/editor/import/dynamicfont_import_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -92,6 +92,8 @@ struct UniRange {
String name;
};
+// Unicode Character Blocks
+// Source: https://www.unicode.org/Public/14.0.0/ucd/Blocks.txt
static UniRange unicode_ranges[] = {
{ 0x0000, 0x007F, U"Basic Latin" },
{ 0x0080, 0x00FF, U"Latin-1 Supplement" },
@@ -109,10 +111,11 @@ static UniRange unicode_ranges[] = {
{ 0x0700, 0x074F, U"Syriac" },
{ 0x0750, 0x077F, U"Arabic Supplement" },
{ 0x0780, 0x07BF, U"Thaana" },
- { 0x07C0, 0x07FF, U"N'Ko" },
+ { 0x07C0, 0x07FF, U"NKo" },
{ 0x0800, 0x083F, U"Samaritan" },
{ 0x0840, 0x085F, U"Mandaic" },
{ 0x0860, 0x086F, U"Syriac Supplement" },
+ { 0x0870, 0x089F, U"Arabic Extended-B" },
{ 0x08A0, 0x08FF, U"Arabic Extended-A" },
{ 0x0900, 0x097F, U"Devanagari" },
{ 0x0980, 0x09FF, U"Bengali" },
@@ -239,9 +242,12 @@ static UniRange unicode_ranges[] = {
{ 0xAB30, 0xAB6F, U"Latin Extended-E" },
{ 0xAB70, 0xABBF, U"Cherokee Supplement" },
{ 0xABC0, 0xABFF, U"Meetei Mayek" },
+ { 0xAC00, 0xD7AF, U"Hangul Syllables" },
{ 0xD7B0, 0xD7FF, U"Hangul Jamo Extended-B" },
- //{ 0xF800, 0xDFFF, U"Surrogates" },
- { 0xE000, 0xE2FE, U"Private Use Area" },
+ //{ 0xD800, 0xDB7F, U"High Surrogates" },
+ //{ 0xDB80, 0xDBFF, U"High Private Use Surrogates" },
+ //{ 0xDC00, 0xDFFF, U"Low Surrogates" },
+ { 0xE000, 0xF8FF, U"Private Use Area" },
{ 0xF900, 0xFAFF, U"CJK Compatibility Ideographs" },
{ 0xFB00, 0xFB4F, U"Alphabetic Presentation Forms" },
{ 0xFB50, 0xFDFF, U"Arabic Presentation Forms-A" },
@@ -273,7 +279,9 @@ static UniRange unicode_ranges[] = {
{ 0x104B0, 0x104FF, U"Osage" },
{ 0x10500, 0x1052F, U"Elbasan" },
{ 0x10530, 0x1056F, U"Caucasian Albanian" },
+ { 0x10570, 0x105BF, U"Vithkuqi" },
{ 0x10600, 0x1077F, U"Linear A" },
+ { 0x10780, 0x107BF, U"Latin Extended-F" },
{ 0x10800, 0x1083F, U"Cypriot Syllabary" },
{ 0x10840, 0x1085F, U"Imperial Aramaic" },
{ 0x10860, 0x1087F, U"Palmyrene" },
@@ -298,6 +306,7 @@ static UniRange unicode_ranges[] = {
{ 0x10E80, 0x10EBF, U"Yezidi" },
{ 0x10F00, 0x10F2F, U"Old Sogdian" },
{ 0x10F30, 0x10F6F, U"Sogdian" },
+ { 0x10F70, 0x10FAF, U"Old Uyghur" },
{ 0x10FB0, 0x10FDF, U"Chorasmian" },
{ 0x10FE0, 0x10FFF, U"Elymaic" },
{ 0x11000, 0x1107F, U"Brahmi" },
@@ -317,13 +326,14 @@ static UniRange unicode_ranges[] = {
{ 0x11600, 0x1165F, U"Modi" },
{ 0x11660, 0x1167F, U"Mongolian Supplement" },
{ 0x11680, 0x116CF, U"Takri" },
- { 0x11700, 0x1173F, U"Ahom" },
+ { 0x11700, 0x1174F, U"Ahom" },
{ 0x11800, 0x1184F, U"Dogra" },
{ 0x118A0, 0x118FF, U"Warang Citi" },
{ 0x11900, 0x1195F, U"Dives Akuru" },
{ 0x119A0, 0x119FF, U"Nandinagari" },
{ 0x11A00, 0x11A4F, U"Zanabazar Square" },
{ 0x11A50, 0x11AAF, U"Soyombo" },
+ { 0x11AB0, 0x11ABF, U"Unified Canadian Aboriginal Syllabics Extended-A" },
{ 0x11AC0, 0x11AFF, U"Pau Cin Hau" },
{ 0x11C00, 0x11C6F, U"Bhaiksuki" },
{ 0x11C70, 0x11CBF, U"Marchen" },
@@ -335,11 +345,13 @@ static UniRange unicode_ranges[] = {
{ 0x12000, 0x123FF, U"Cuneiform" },
{ 0x12400, 0x1247F, U"Cuneiform Numbers and Punctuation" },
{ 0x12480, 0x1254F, U"Early Dynastic Cuneiform" },
+ { 0x12F90, 0x12FFF, U"Cypro-Minoan" },
{ 0x13000, 0x1342F, U"Egyptian Hieroglyphs" },
{ 0x13430, 0x1343F, U"Egyptian Hieroglyph Format Controls" },
{ 0x14400, 0x1467F, U"Anatolian Hieroglyphs" },
{ 0x16800, 0x16A3F, U"Bamum Supplement" },
{ 0x16A40, 0x16A6F, U"Mro" },
+ { 0x16A70, 0x16ACF, U"Tangsa" },
{ 0x16AD0, 0x16AFF, U"Bassa Vah" },
{ 0x16B00, 0x16B8F, U"Pahawh Hmong" },
{ 0x16E40, 0x16E9F, U"Medefaidrin" },
@@ -348,13 +360,15 @@ static UniRange unicode_ranges[] = {
{ 0x17000, 0x187FF, U"Tangut" },
{ 0x18800, 0x18AFF, U"Tangut Components" },
{ 0x18B00, 0x18CFF, U"Khitan Small Script" },
- { 0x18D00, 0x18D8F, U"Tangut Supplement" },
+ { 0x18D00, 0x18D7F, U"Tangut Supplement" },
+ { 0x1AFF0, 0x1AFFF, U"Kana Extended-B" },
{ 0x1B000, 0x1B0FF, U"Kana Supplement" },
{ 0x1B100, 0x1B12F, U"Kana Extended-A" },
{ 0x1B130, 0x1B16F, U"Small Kana Extension" },
{ 0x1B170, 0x1B2FF, U"Nushu" },
{ 0x1BC00, 0x1BC9F, U"Duployan" },
{ 0x1BCA0, 0x1BCAF, U"Shorthand Format Controls" },
+ { 0x1CF00, 0x1CFCF, U"Znamenny Musical Notation" },
{ 0x1D000, 0x1D0FF, U"Byzantine Musical Symbols" },
{ 0x1D100, 0x1D1FF, U"Musical Symbols" },
{ 0x1D200, 0x1D24F, U"Ancient Greek Musical Notation" },
@@ -363,9 +377,12 @@ static UniRange unicode_ranges[] = {
{ 0x1D360, 0x1D37F, U"Counting Rod Numerals" },
{ 0x1D400, 0x1D7FF, U"Mathematical Alphanumeric Symbols" },
{ 0x1D800, 0x1DAAF, U"Sutton SignWriting" },
+ { 0x1DF00, 0x1DFFF, U"Latin Extended-G" },
{ 0x1E000, 0x1E02F, U"Glagolitic Supplement" },
{ 0x1E100, 0x1E14F, U"Nyiakeng Puachue Hmong" },
+ { 0x1E290, 0x1E2BF, U"Toto" },
{ 0x1E2C0, 0x1E2FF, U"Wancho" },
+ { 0x1E7E0, 0x1E7FF, U"Ethiopic Extended-B" },
{ 0x1E800, 0x1E8DF, U"Mende Kikakui" },
{ 0x1E900, 0x1E95F, U"Adlam" },
{ 0x1EC70, 0x1ECBF, U"Indic Siyaq Numbers" },
@@ -396,8 +413,8 @@ static UniRange unicode_ranges[] = {
{ 0x30000, 0x3134F, U"CJK Unified Ideographs Extension G" },
//{ 0xE0000, 0xE007F, U"Tags" },
//{ 0xE0100, 0xE01EF, U"Variation Selectors Supplement" },
- { 0xF0000, 0xFFFFD, U"Supplementary Private Use Area-A" },
- { 0x100000, 0x10FFFD, U"Supplementary Private Use Area-B" },
+ { 0xF0000, 0xFFFFF, U"Supplementary Private Use Area-A" },
+ { 0x100000, 0x10FFFF, U"Supplementary Private Use Area-B" },
{ 0x10FFFF, 0x10FFFF, String() }
};
@@ -425,398 +442,6 @@ void DynamicFontImportSettings::_add_glyph_range_item(int32_t p_start, int32_t p
}
/*************************************************************************/
-/* Languages and scripts */
-/*************************************************************************/
-
-struct CodeInfo {
- String name;
- String code;
-};
-
-static CodeInfo langs[] = {
- { U"Custom", U"xx" },
- { U"-", U"-" },
- { U"Abkhazian", U"ab" },
- { U"Afar", U"aa" },
- { U"Afrikaans", U"af" },
- { U"Akan", U"ak" },
- { U"Albanian", U"sq" },
- { U"Amharic", U"am" },
- { U"Arabic", U"ar" },
- { U"Aragonese", U"an" },
- { U"Armenian", U"hy" },
- { U"Assamese", U"as" },
- { U"Avaric", U"av" },
- { U"Avestan", U"ae" },
- { U"Aymara", U"ay" },
- { U"Azerbaijani", U"az" },
- { U"Bambara", U"bm" },
- { U"Bashkir", U"ba" },
- { U"Basque", U"eu" },
- { U"Belarusian", U"be" },
- { U"Bengali", U"bn" },
- { U"Bihari", U"bh" },
- { U"Bislama", U"bi" },
- { U"Bosnian", U"bs" },
- { U"Breton", U"br" },
- { U"Bulgarian", U"bg" },
- { U"Burmese", U"my" },
- { U"Catalan", U"ca" },
- { U"Chamorro", U"ch" },
- { U"Chechen", U"ce" },
- { U"Chichewa", U"ny" },
- { U"Chinese", U"zh" },
- { U"Chuvash", U"cv" },
- { U"Cornish", U"kw" },
- { U"Corsican", U"co" },
- { U"Cree", U"cr" },
- { U"Croatian", U"hr" },
- { U"Czech", U"cs" },
- { U"Danish", U"da" },
- { U"Divehi", U"dv" },
- { U"Dutch", U"nl" },
- { U"Dzongkha", U"dz" },
- { U"English", U"en" },
- { U"Esperanto", U"eo" },
- { U"Estonian", U"et" },
- { U"Ewe", U"ee" },
- { U"Faroese", U"fo" },
- { U"Fijian", U"fj" },
- { U"Finnish", U"fi" },
- { U"French", U"fr" },
- { U"Fulah", U"ff" },
- { U"Galician", U"gl" },
- { U"Georgian", U"ka" },
- { U"German", U"de" },
- { U"Greek", U"el" },
- { U"Guarani", U"gn" },
- { U"Gujarati", U"gu" },
- { U"Haitian", U"ht" },
- { U"Hausa", U"ha" },
- { U"Hebrew", U"he" },
- { U"Herero", U"hz" },
- { U"Hindi", U"hi" },
- { U"Hiri Motu", U"ho" },
- { U"Hungarian", U"hu" },
- { U"Interlingua", U"ia" },
- { U"Indonesian", U"id" },
- { U"Interlingue", U"ie" },
- { U"Irish", U"ga" },
- { U"Igbo", U"ig" },
- { U"Inupiaq", U"ik" },
- { U"Ido", U"io" },
- { U"Icelandic", U"is" },
- { U"Italian", U"it" },
- { U"Inuktitut", U"iu" },
- { U"Japanese", U"ja" },
- { U"Javanese", U"jv" },
- { U"Kalaallisut", U"kl" },
- { U"Kannada", U"kn" },
- { U"Kanuri", U"kr" },
- { U"Kashmiri", U"ks" },
- { U"Kazakh", U"kk" },
- { U"Central Khmer", U"km" },
- { U"Kikuyu", U"ki" },
- { U"Kinyarwanda", U"rw" },
- { U"Kirghiz", U"ky" },
- { U"Komi", U"kv" },
- { U"Kongo", U"kg" },
- { U"Korean", U"ko" },
- { U"Kurdish", U"ku" },
- { U"Kuanyama", U"kj" },
- { U"Latin", U"la" },
- { U"Luxembourgish", U"lb" },
- { U"Ganda", U"lg" },
- { U"Limburgan", U"li" },
- { U"Lingala", U"ln" },
- { U"Lao", U"lo" },
- { U"Lithuanian", U"lt" },
- { U"Luba-Katanga", U"lu" },
- { U"Latvian", U"lv" },
- { U"Man", U"gv" },
- { U"Macedonian", U"mk" },
- { U"Malagasy", U"mg" },
- { U"Malay", U"ms" },
- { U"Malayalam", U"ml" },
- { U"Maltese", U"mt" },
- { U"Maori", U"mi" },
- { U"Marathi", U"mr" },
- { U"Marshallese", U"mh" },
- { U"Mongolian", U"mn" },
- { U"Nauru", U"na" },
- { U"Navajo", U"nv" },
- { U"North Ndebele", U"nd" },
- { U"Nepali", U"ne" },
- { U"Ndonga", U"ng" },
- { U"Norwegian Bokmål", U"nb" },
- { U"Norwegian Nynorsk", U"nn" },
- { U"Norwegian", U"no" },
- { U"Sichuan Yi, Nuosu", U"ii" },
- { U"South Ndebele", U"nr" },
- { U"Occitan", U"oc" },
- { U"Ojibwa", U"oj" },
- { U"Church Slavic", U"cu" },
- { U"Oromo", U"om" },
- { U"Oriya", U"or" },
- { U"Ossetian", U"os" },
- { U"Punjabi", U"pa" },
- { U"Pali", U"pi" },
- { U"Persian", U"fa" },
- { U"Polish", U"pl" },
- { U"Pashto", U"ps" },
- { U"Portuguese", U"pt" },
- { U"Quechua", U"qu" },
- { U"Romansh", U"rm" },
- { U"Rundi", U"rn" },
- { U"Romanian", U"ro" },
- { U"Russian", U"ru" },
- { U"Sanskrit", U"sa" },
- { U"Sardinian", U"sc" },
- { U"Sindhi", U"sd" },
- { U"Northern Sami", U"se" },
- { U"Samoan", U"sm" },
- { U"Sango", U"sg" },
- { U"Serbian", U"sr" },
- { U"Gaelic", U"gd" },
- { U"Shona", U"sn" },
- { U"Sinhala", U"si" },
- { U"Slovak", U"sk" },
- { U"Slovenian", U"sl" },
- { U"Somali", U"so" },
- { U"Southern Sotho", U"st" },
- { U"Spanish", U"es" },
- { U"Sundanese", U"su" },
- { U"Swahili", U"sw" },
- { U"Swati", U"ss" },
- { U"Swedish", U"sv" },
- { U"Tamil", U"ta" },
- { U"Telugu", U"te" },
- { U"Tajik", U"tg" },
- { U"Thai", U"th" },
- { U"Tigrinya", U"ti" },
- { U"Tibetan", U"bo" },
- { U"Turkmen", U"tk" },
- { U"Tagalog", U"tl" },
- { U"Tswana", U"tn" },
- { U"Tonga", U"to" },
- { U"Turkish", U"tr" },
- { U"Tsonga", U"ts" },
- { U"Tatar", U"tt" },
- { U"Twi", U"tw" },
- { U"Tahitian", U"ty" },
- { U"Uighur", U"ug" },
- { U"Ukrainian", U"uk" },
- { U"Urdu", U"ur" },
- { U"Uzbek", U"uz" },
- { U"Venda", U"ve" },
- { U"Vietnamese", U"vi" },
- { U"Volapük", U"vo" },
- { U"Walloon", U"wa" },
- { U"Welsh", U"cy" },
- { U"Wolof", U"wo" },
- { U"Western Frisian", U"fy" },
- { U"Xhosa", U"xh" },
- { U"Yiddish", U"yi" },
- { U"Yoruba", U"yo" },
- { U"Zhuang", U"za" },
- { U"Zulu", U"zu" },
- { String(), String() }
-};
-
-static CodeInfo scripts[] = {
- { U"Custom", U"Qaaa" },
- { U"-", U"-" },
- { U"Adlam", U"Adlm" },
- { U"Afaka", U"Afak" },
- { U"Caucasian Albanian", U"Aghb" },
- { U"Ahom", U"Ahom" },
- { U"Arabic", U"Arab" },
- { U"Imperial Aramaic", U"Armi" },
- { U"Armenian", U"Armn" },
- { U"Avestan", U"Avst" },
- { U"Balinese", U"Bali" },
- { U"Bamum", U"Bamu" },
- { U"Bassa Vah", U"Bass" },
- { U"Batak", U"Batk" },
- { U"Bengali", U"Beng" },
- { U"Bhaiksuki", U"Bhks" },
- { U"Blissymbols", U"Blis" },
- { U"Bopomofo", U"Bopo" },
- { U"Brahmi", U"Brah" },
- { U"Braille", U"Brai" },
- { U"Buginese", U"Bugi" },
- { U"Buhid", U"Buhd" },
- { U"Chakma", U"Cakm" },
- { U"Unified Canadian Aboriginal", U"Cans" },
- { U"Carian", U"Cari" },
- { U"Cham", U"Cham" },
- { U"Cherokee", U"Cher" },
- { U"Chorasmian", U"Chrs" },
- { U"Cirth", U"Cirt" },
- { U"Coptic", U"Copt" },
- { U"Cypro-Minoan", U"Cpmn" },
- { U"Cypriot", U"Cprt" },
- { U"Cyrillic", U"Cyrl" },
- { U"Devanagari", U"Deva" },
- { U"Dives Akuru", U"Diak" },
- { U"Dogra", U"Dogr" },
- { U"Deseret", U"Dsrt" },
- { U"Duployan", U"Dupl" },
- { U"Egyptian demotic", U"Egyd" },
- { U"Egyptian hieratic", U"Egyh" },
- { U"Egyptian hieroglyphs", U"Egyp" },
- { U"Elbasan", U"Elba" },
- { U"Elymaic", U"Elym" },
- { U"Ethiopic", U"Ethi" },
- { U"Khutsuri", U"Geok" },
- { U"Georgian", U"Geor" },
- { U"Glagolitic", U"Glag" },
- { U"Gunjala Gondi", U"Gong" },
- { U"Masaram Gondi", U"Gonm" },
- { U"Gothic", U"Goth" },
- { U"Grantha", U"Gran" },
- { U"Greek", U"Grek" },
- { U"Gujarati", U"Gujr" },
- { U"Gurmukhi", U"Guru" },
- { U"Hangul", U"Hang" },
- { U"Han", U"Hani" },
- { U"Hanunoo", U"Hano" },
- { U"Hatran", U"Hatr" },
- { U"Hebrew", U"Hebr" },
- { U"Hiragana", U"Hira" },
- { U"Anatolian Hieroglyphs", U"Hluw" },
- { U"Pahawh Hmong", U"Hmng" },
- { U"Nyiakeng Puachue Hmong", U"Hmnp" },
- { U"Old Hungarian", U"Hung" },
- { U"Indus", U"Inds" },
- { U"Old Italic", U"Ital" },
- { U"Javanese", U"Java" },
- { U"Jurchen", U"Jurc" },
- { U"Kayah Li", U"Kali" },
- { U"Katakana", U"Kana" },
- { U"Kharoshthi", U"Khar" },
- { U"Khmer", U"Khmr" },
- { U"Khojki", U"Khoj" },
- { U"Khitan large script", U"Kitl" },
- { U"Khitan small script", U"Kits" },
- { U"Kannada", U"Knda" },
- { U"Kpelle", U"Kpel" },
- { U"Kaithi", U"Kthi" },
- { U"Tai Tham", U"Lana" },
- { U"Lao", U"Laoo" },
- { U"Latin", U"Latn" },
- { U"Leke", U"Leke" },
- { U"Lepcha", U"Lepc" },
- { U"Limbu", U"Limb" },
- { U"Linear A", U"Lina" },
- { U"Linear B", U"Linb" },
- { U"Lisu", U"Lisu" },
- { U"Loma", U"Loma" },
- { U"Lycian", U"Lyci" },
- { U"Lydian", U"Lydi" },
- { U"Mahajani", U"Mahj" },
- { U"Makasar", U"Maka" },
- { U"Mandaic", U"Mand" },
- { U"Manichaean", U"Mani" },
- { U"Marchen", U"Marc" },
- { U"Mayan Hieroglyphs", U"Maya" },
- { U"Medefaidrin", U"Medf" },
- { U"Mende Kikakui", U"Mend" },
- { U"Meroitic Cursive", U"Merc" },
- { U"Meroitic Hieroglyphs", U"Mero" },
- { U"Malayalam", U"Mlym" },
- { U"Modi", U"Modi" },
- { U"Mongolian", U"Mong" },
- { U"Moon", U"Moon" },
- { U"Mro", U"Mroo" },
- { U"Meitei Mayek", U"Mtei" },
- { U"Multani", U"Mult" },
- { U"Myanmar (Burmese)", U"Mymr" },
- { U"Nandinagari", U"Nand" },
- { U"Old North Arabian", U"Narb" },
- { U"Nabataean", U"Nbat" },
- { U"Newa", U"Newa" },
- { U"Naxi Dongba", U"Nkdb" },
- { U"Nakhi Geba", U"Nkgb" },
- { U"N’Ko", U"Nkoo" },
- { U"Nüshu", U"Nshu" },
- { U"Ogham", U"Ogam" },
- { U"Ol Chiki", U"Olck" },
- { U"Old Turkic", U"Orkh" },
- { U"Oriya", U"Orya" },
- { U"Osage", U"Osge" },
- { U"Osmanya", U"Osma" },
- { U"Old Uyghur", U"Ougr" },
- { U"Palmyrene", U"Palm" },
- { U"Pau Cin Hau", U"Pauc" },
- { U"Proto-Cuneiform", U"Pcun" },
- { U"Proto-Elamite", U"Pelm" },
- { U"Old Permic", U"Perm" },
- { U"Phags-pa", U"Phag" },
- { U"Inscriptional Pahlavi", U"Phli" },
- { U"Psalter Pahlavi", U"Phlp" },
- { U"Book Pahlavi", U"Phlv" },
- { U"Phoenician", U"Phnx" },
- { U"Klingon", U"Piqd" },
- { U"Miao", U"Plrd" },
- { U"Inscriptional Parthian", U"Prti" },
- { U"Proto-Sinaitic", U"Psin" },
- { U"Ranjana", U"Ranj" },
- { U"Rejang", U"Rjng" },
- { U"Hanifi Rohingya", U"Rohg" },
- { U"Rongorongo", U"Roro" },
- { U"Runic", U"Runr" },
- { U"Samaritan", U"Samr" },
- { U"Sarati", U"Sara" },
- { U"Old South Arabian", U"Sarb" },
- { U"Saurashtra", U"Saur" },
- { U"SignWriting", U"Sgnw" },
- { U"Shavian", U"Shaw" },
- { U"Sharada", U"Shrd" },
- { U"Shuishu", U"Shui" },
- { U"Siddham", U"Sidd" },
- { U"Khudawadi", U"Sind" },
- { U"Sinhala", U"Sinh" },
- { U"Sogdian", U"Sogd" },
- { U"Old Sogdian", U"Sogo" },
- { U"Sora Sompeng", U"Sora" },
- { U"Soyombo", U"Soyo" },
- { U"Sundanese", U"Sund" },
- { U"Syloti Nagri", U"Sylo" },
- { U"Syriac", U"Syrc" },
- { U"Tagbanwa", U"Tagb" },
- { U"Takri", U"Takr" },
- { U"Tai Le", U"Tale" },
- { U"New Tai Lue", U"Talu" },
- { U"Tamil", U"Taml" },
- { U"Tangut", U"Tang" },
- { U"Tai Viet", U"Tavt" },
- { U"Telugu", U"Telu" },
- { U"Tengwar", U"Teng" },
- { U"Tifinagh", U"Tfng" },
- { U"Tagalog", U"Tglg" },
- { U"Thaana", U"Thaa" },
- { U"Thai", U"Thai" },
- { U"Tibetan", U"Tibt" },
- { U"Tirhuta", U"Tirh" },
- { U"Tangsa", U"Tnsa" },
- { U"Toto", U"Toto" },
- { U"Ugaritic", U"Ugar" },
- { U"Vai", U"Vaii" },
- { U"Visible Speech", U"Visp" },
- { U"Vithkuqi", U"Vith" },
- { U"Warang Citi", U"Wara" },
- { U"Wancho", U"Wcho" },
- { U"Woleai", U"Wole" },
- { U"Old Persian", U"Xpeo" },
- { U"Cuneiform", U"Xsux" },
- { U"Yezidi", U"Yezi" },
- { U"Yi", U"Yiii" },
- { U"Zanabazar Square", U"Zanb" },
- { String(), String() }
-};
-
-/*************************************************************************/
/* Page 1 callbacks: Rendering Options */
/*************************************************************************/
@@ -994,9 +619,10 @@ void DynamicFontImportSettings::_glyph_text_selected() {
if (text_rid.is_valid()) {
TS->shaped_text_add_string(text_rid, text_edit->get_text(), font_main->get_rids(), 16, ftrs, text_edit->get_language());
TS->shaped_text_shape(text_rid);
- const Vector<TextServer::Glyph> &gl = TS->shaped_text_get_glyphs(text_rid);
+ const Glyph *gl = TS->shaped_text_get_glyphs(text_rid);
+ const int gl_size = TS->shaped_text_get_glyph_count(text_rid);
- for (int i = 0; i < gl.size(); i++) {
+ for (int i = 0; i < gl_size; i++) {
if (gl[i].font_rid.is_valid() && gl[i].index != 0) {
selected_glyphs.insert(gl[i].index);
}
@@ -1065,7 +691,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item = glyph_table->create_item(root);
ERR_FAIL_NULL(item);
item->set_text(0, _pad_zeros(String::num_int64(c, 16)));
- item->set_text_align(0, TreeItem::ALIGN_LEFT);
+ item->set_text_alignment(0, HORIZONTAL_ALIGNMENT_LEFT);
item->set_selectable(0, false);
item->set_custom_bg_color(0, glyph_table->get_theme_color("dark_color_3", "Editor"));
}
@@ -1083,7 +709,7 @@ void DynamicFontImportSettings::_edit_range(int32_t p_start, int32_t p_end) {
item->set_custom_bg_color(col + 1, glyph_table->get_theme_color("dark_color_2", "Editor"));
}
item->set_metadata(col + 1, c);
- item->set_text_align(col + 1, TreeItem::ALIGN_CENTER);
+ item->set_text_alignment(col + 1, HORIZONTAL_ALIGNMENT_CENTER);
item->set_selectable(col + 1, true);
item->set_custom_font(col + 1, font_main);
item->set_custom_font_size(col + 1, get_theme_font_size("font_size") * 2);
@@ -1141,19 +767,17 @@ void DynamicFontImportSettings::_range_update(int32_t p_start, int32_t p_end) {
/*************************************************************************/
void DynamicFontImportSettings::_lang_add() {
- menu_langs->set_position(lang_list->get_screen_transform().xform(lang_list->get_local_mouse_position()));
- menu_langs->set_size(Vector2(1, 1));
- menu_langs->popup();
+ locale_select->popup_locale_dialog();
}
-void DynamicFontImportSettings::_lang_add_item(int p_option) {
+void DynamicFontImportSettings::_lang_add_item(const String &p_locale) {
TreeItem *lang_item = lang_list->create_item(lang_list_root);
ERR_FAIL_NULL(lang_item);
lang_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
lang_item->set_editable(0, true);
lang_item->set_checked(0, false);
- lang_item->set_text(1, langs[p_option].code);
+ lang_item->set_text(1, p_locale);
lang_item->set_editable(1, true);
lang_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
lang_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
@@ -1167,9 +791,41 @@ void DynamicFontImportSettings::_lang_remove(Object *p_item, int p_column, int p
memdelete(lang_item);
}
+void DynamicFontImportSettings::_ot_add() {
+ menu_ot->set_position(ot_list->get_screen_transform().xform(ot_list->get_local_mouse_position()));
+ menu_ot->set_size(Vector2(1, 1));
+ menu_ot->popup();
+}
+
+void DynamicFontImportSettings::_ot_add_item(int p_option) {
+ String name = TS->tag_to_name(p_option);
+ for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) {
+ if (ot_item->get_text(0) == name) {
+ return;
+ }
+ }
+ TreeItem *ot_item = ot_list->create_item(ot_list_root);
+ ERR_FAIL_NULL(ot_item);
+
+ ot_item->set_text(0, name);
+ ot_item->set_editable(0, false);
+ ot_item->set_text(1, "1");
+ ot_item->set_editable(1, true);
+ ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
+ ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
+}
+
+void DynamicFontImportSettings::_ot_remove(Object *p_item, int p_column, int p_id) {
+ TreeItem *ot_item = (TreeItem *)p_item;
+ ERR_FAIL_NULL(ot_item);
+
+ ot_list_root->remove_child(ot_item);
+ memdelete(ot_item);
+}
+
void DynamicFontImportSettings::_script_add() {
- menu_scripts->set_position(script_list->get_screen_transform().xform(script_list->get_local_mouse_position()));
- menu_scripts->set_size(Vector2(1, 1));
+ menu_scripts->set_position(script_list->get_screen_position() + script_list->get_local_mouse_position());
+ menu_scripts->reset_size();
menu_scripts->popup();
}
@@ -1180,7 +836,7 @@ void DynamicFontImportSettings::_script_add_item(int p_option) {
script_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
script_item->set_editable(0, true);
script_item->set_checked(0, false);
- script_item->set_text(1, scripts[p_option].code);
+ script_item->set_text(1, script_codes[p_option]);
script_item->set_editable(1, true);
script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
script_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
@@ -1212,6 +868,7 @@ void DynamicFontImportSettings::_notification(int p_what) {
add_lang->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
add_script->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
add_var->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
+ add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
}
}
@@ -1299,6 +956,14 @@ void DynamicFontImportSettings::_re_import() {
main_settings["preload/glyph_ranges"] = ranges;
}
+ Dictionary ot_ov;
+ for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) {
+ String tag = ot_item->get_text(0);
+ int32_t value = ot_item->get_text(1).to_int();
+ ot_ov[tag] = value;
+ }
+ main_settings["opentype_feature_overrides"] = ot_ov;
+
if (OS::get_singleton()->is_stdout_verbose()) {
print_line("Import settings:");
for (Map<StringName, Variant>::Element *E = main_settings.front(); E; E = E->next()) {
@@ -1355,6 +1020,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
vars_list->clear();
lang_list->clear();
script_list->clear();
+ ot_list->clear();
selected_chars.clear();
selected_glyphs.clear();
@@ -1363,6 +1029,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
vars_list_root = vars_list->create_item();
lang_list_root = lang_list->create_item();
script_list_root = script_list->create_item();
+ ot_list_root = ot_list->create_item();
options_variations.clear();
Dictionary var_list = dfont_main->get_supported_variation_list();
@@ -1528,6 +1195,23 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
script_item->set_editable(1, true);
script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
}
+ } else if (key == "opentype_feature_overrides") {
+ Dictionary features = config->get_value("params", key);
+ for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
+ TreeItem *ot_item = ot_list->create_item(ot_list_root);
+ ERR_FAIL_NULL(ot_item);
+ int32_t value = features[*ftr];
+ if (ftr->get_type() == Variant::STRING) {
+ ot_item->set_text(0, *ftr);
+ } else {
+ ot_item->set_text(0, TS->tag_to_name(*ftr));
+ }
+ ot_item->set_editable(0, false);
+ ot_item->set_text(1, itos(value));
+ ot_item->set_editable(1, true);
+ ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
+ ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
+ }
} else {
Variant value = config->get_value("params", key);
import_settings_data->defaults[key] = value;
@@ -1552,6 +1236,39 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
font_preview_label->add_theme_font_override("font", font_preview);
font_preview_label->update();
+ menu_ot->clear();
+ menu_ot_ss->clear();
+ menu_ot_cv->clear();
+ menu_ot_cu->clear();
+ bool have_ss = false;
+ bool have_cv = false;
+ bool have_cu = false;
+ Dictionary features = font_preview->get_feature_list();
+ for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
+ String ftr_name = TS->tag_to_name(*ftr);
+ if (ftr_name.begins_with("stylistic_set_")) {
+ menu_ot_ss->add_item(ftr_name.capitalize(), (int32_t)*ftr);
+ have_ss = true;
+ } else if (ftr_name.begins_with("character_variant_")) {
+ menu_ot_cv->add_item(ftr_name.capitalize(), (int32_t)*ftr);
+ have_cv = true;
+ } else if (ftr_name.begins_with("custom_")) {
+ menu_ot_cu->add_item(ftr_name.replace("custom_", ""), (int32_t)*ftr);
+ have_cu = true;
+ } else {
+ menu_ot->add_item(ftr_name.capitalize(), (int32_t)*ftr);
+ }
+ }
+ if (have_ss) {
+ menu_ot->add_submenu_item(RTR("Stylistic Sets"), "SSMenu");
+ }
+ if (have_cv) {
+ menu_ot->add_submenu_item(RTR("Character Variants"), "CVMenu");
+ }
+ if (have_cu) {
+ menu_ot->add_submenu_item(RTR("Custom"), "CUMenu");
+ }
+
_variations_validate();
popup_centered_ratio();
@@ -1577,30 +1294,38 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
// Popup menus
- menu_langs = memnew(PopupMenu);
- menu_langs->set_name("Language");
- for (int i = 0; langs[i].name != String(); i++) {
- if (langs[i].name == "-") {
- menu_langs->add_separator();
- } else {
- menu_langs->add_item(langs[i].name + " (" + langs[i].code + ")", i);
- }
- }
- add_child(menu_langs);
- menu_langs->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_lang_add_item));
+ locale_select = memnew(EditorLocaleDialog);
+ locale_select->connect("locale_selected", callable_mp(this, &DynamicFontImportSettings::_lang_add_item));
+ add_child(locale_select);
menu_scripts = memnew(PopupMenu);
menu_scripts->set_name("Script");
- for (int i = 0; scripts[i].name != String(); i++) {
- if (scripts[i].name == "-") {
- menu_scripts->add_separator();
- } else {
- menu_scripts->add_item(scripts[i].name + " (" + scripts[i].code + ")", i);
- }
+ script_codes = TranslationServer::get_singleton()->get_all_scripts();
+ for (int i = 0; i < script_codes.size(); i++) {
+ menu_scripts->add_item(TranslationServer::get_singleton()->get_script_name(script_codes[i]) + " (" + script_codes[i] + ")", i);
}
add_child(menu_scripts);
menu_scripts->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_script_add_item));
+ menu_ot = memnew(PopupMenu);
+ add_child(menu_ot);
+ menu_ot->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
+ menu_ot_cv = memnew(PopupMenu);
+ menu_ot_cv->set_name("CVMenu");
+ menu_ot->add_child(menu_ot_cv);
+ menu_ot_cv->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
+ menu_ot_ss = memnew(PopupMenu);
+ menu_ot_ss->set_name("SSMenu");
+ menu_ot->add_child(menu_ot_ss);
+ menu_ot_ss->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
+ menu_ot_cu = memnew(PopupMenu);
+ menu_ot_cu->set_name("CUMenu");
+ menu_ot->add_child(menu_ot_cu);
+ menu_ot_cu->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor") : Color(1, 1, 0);
// Root layout
@@ -1614,7 +1339,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
root_vb->add_child(main_pages);
label_warn = memnew(Label);
- label_warn->set_align(Label::ALIGN_CENTER);
+ label_warn->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_warn->set_text("");
root_vb->add_child(label_warn);
label_warn->add_theme_color_override("font_color", warn_color);
@@ -1638,8 +1363,8 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
font_preview_label = memnew(Label);
font_preview_label->add_theme_font_size_override("font_size", 200 * EDSCALE);
- font_preview_label->set_align(Label::ALIGN_CENTER);
- font_preview_label->set_valign(Label::VALIGN_CENTER);
+ font_preview_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ font_preview_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
font_preview_label->set_autowrap_mode(Label::AUTOWRAP_ARBITRARY);
font_preview_label->set_clip_text(true);
font_preview_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -1676,7 +1401,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
label_vars = memnew(Label);
page2_hb_vars->add_child(label_vars);
- label_vars->set_align(Label::ALIGN_CENTER);
+ label_vars->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_vars->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_vars->set_text(TTR("Configuration:"));
@@ -1799,7 +1524,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
glyph_tree = memnew(Tree);
glyphs_split->add_child(glyph_tree);
glyph_tree->set_custom_minimum_size(Size2(300 * EDSCALE, 0));
- glyph_tree->set_columns(3);
+ glyph_tree->set_columns(2);
glyph_tree->set_hide_root(true);
glyph_tree->set_column_expand(0, false);
glyph_tree->set_column_expand(1, true);
@@ -1808,7 +1533,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
glyph_tree->connect("item_selected", callable_mp(this, &DynamicFontImportSettings::_range_selected));
glyph_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
glyph_root = glyph_tree->create_item();
- for (int i = 0; unicode_ranges[i].name != String(); i++) {
+ for (int i = 0; !unicode_ranges[i].name.is_empty(); i++) {
_add_glyph_range_item(unicode_ranges[i].start, unicode_ranges[i].end, unicode_ranges[i].name);
}
@@ -1827,7 +1552,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
page5_vb->add_child(hb_lang);
label_langs = memnew(Label);
- label_langs->set_align(Label::ALIGN_CENTER);
+ label_langs->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_langs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_langs->set_text(TTR("Language support overrides"));
hb_lang->add_child(label_langs);
@@ -1855,7 +1580,7 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
page5_vb->add_child(hb_script);
label_script = memnew(Label);
- label_script->set_align(Label::ALIGN_CENTER);
+ label_script->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
label_script->set_h_size_flags(Control::SIZE_EXPAND_FILL);
label_script->set_text(TTR("Script support overrides"));
hb_script->add_child(label_script);
@@ -1879,6 +1604,34 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
script_list->connect("button_pressed", callable_mp(this, &DynamicFontImportSettings::_script_remove));
script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ HBoxContainer *hb_ot = memnew(HBoxContainer);
+ page5_vb->add_child(hb_ot);
+
+ label_ot = memnew(Label);
+ label_ot->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ label_ot->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ label_ot->set_text(TTR("OpenType feature overrides"));
+ hb_ot->add_child(label_ot);
+
+ add_ot = memnew(Button);
+ hb_ot->add_child(add_ot);
+ add_ot->set_tooltip(TTR("Add feature override"));
+ add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
+ add_ot->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add));
+
+ ot_list = memnew(Tree);
+ page5_vb->add_child(ot_list);
+ ot_list->set_hide_root(true);
+ ot_list->set_columns(3);
+ ot_list->set_column_expand(0, true);
+ ot_list->set_column_custom_minimum_width(0, 80 * EDSCALE);
+ ot_list->set_column_expand(1, true);
+ ot_list->set_column_custom_minimum_width(1, 80 * EDSCALE);
+ ot_list->set_column_expand(2, false);
+ ot_list->set_column_custom_minimum_width(2, 50 * EDSCALE);
+ ot_list->connect("button_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_remove));
+ ot_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
// Common
import_settings_data.instantiate();
diff --git a/editor/import/dynamicfont_import_settings.h b/editor/import/dynamicfont_import_settings.h
index 05f5e8e00b..5d37f58b9b 100644
--- a/editor/import/dynamicfont_import_settings.h
+++ b/editor/import/dynamicfont_import_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,6 +33,7 @@
#include "editor/editor_file_dialog.h"
#include "editor/editor_inspector.h"
+#include "editor/editor_locale_dialog.h"
#include "editor/import/resource_importer_dynamicfont.h"
@@ -67,6 +68,9 @@ class DynamicFontImportSettings : public ConfirmationDialog {
List<ResourceImporter::ImportOption> options_variations;
List<ResourceImporter::ImportOption> options_general;
+ EditorLocaleDialog *locale_select;
+ Vector<String> script_codes;
+
// Root layout
Label *label_warn = nullptr;
TabContainer *main_pages = nullptr;
@@ -120,26 +124,38 @@ class DynamicFontImportSettings : public ConfirmationDialog {
Label *page5_description = nullptr;
Button *add_lang = nullptr;
Button *add_script = nullptr;
+ Button *add_ot = nullptr;
- PopupMenu *menu_langs = nullptr;
PopupMenu *menu_scripts = nullptr;
+ PopupMenu *menu_ot = nullptr;
+ PopupMenu *menu_ot_ss = nullptr;
+ PopupMenu *menu_ot_cv = nullptr;
+ PopupMenu *menu_ot_cu = nullptr;
Tree *lang_list = nullptr;
TreeItem *lang_list_root = nullptr;
+ Label *label_langs = nullptr;
Tree *script_list = nullptr;
TreeItem *script_list_root = nullptr;
- Label *label_langs = nullptr;
Label *label_script = nullptr;
+ Tree *ot_list = nullptr;
+ TreeItem *ot_list_root = nullptr;
+ Label *label_ot = nullptr;
+
void _lang_add();
- void _lang_add_item(int p_option);
+ void _lang_add_item(const String &p_locale);
void _lang_remove(Object *p_item, int p_column, int p_id);
void _script_add();
void _script_add_item(int p_option);
void _script_remove(Object *p_item, int p_column, int p_id);
+ void _ot_add();
+ void _ot_add_item(int p_option);
+ void _ot_remove(Object *p_item, int p_column, int p_id);
+
// Common
void _add_glyph_range_item(int32_t p_start, int32_t p_end, const String &p_name);
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 7ab80ac3b4..c1ae5be0bb 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,8 +33,8 @@
#include "core/os/os.h"
#include "editor/editor_node.h"
#include "editor/import/collada.h"
-#include "editor/import/scene_importer_mesh_node_3d.h"
#include "scene/3d/camera_3d.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/light_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/node_3d.h"
@@ -42,6 +42,7 @@
#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
+#include "scene/resources/importer_mesh.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/surface_tool.h"
@@ -68,7 +69,7 @@ struct ColladaImport {
Map<String, NodeMap> node_map; //map from collada node to engine node
Map<String, String> node_name_map; //map from collada node to engine node
- Map<String, Ref<EditorSceneImporterMesh>> mesh_cache;
+ Map<String, Ref<ImporterMesh>> mesh_cache;
Map<String, Ref<Curve3D>> curve_cache;
Map<String, Ref<Material>> material_cache;
Map<Collada::Node *, Skeleton3D *> skeleton_map;
@@ -87,11 +88,11 @@ struct ColladaImport {
Error _create_scene(Collada::Node *p_node, Node3D *p_parent);
Error _create_resources(Collada::Node *p_node, bool p_use_compression);
Error _create_material(const String &p_target);
- Error _create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform3D &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes = Vector<Ref<EditorSceneImporterMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false);
+ Error _create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform3D &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ImporterMesh>> p_morph_meshes = Vector<Ref<ImporterMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false);
Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false, bool p_use_compression = false);
void _fix_param_animation_tracks();
- void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
- void create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
+ void create_animation(int p_clip, bool p_import_value_tracks);
+ void create_animations(bool p_import_value_tracks);
Set<String> tracks_in_clips;
Vector<String> missing_textures;
@@ -119,6 +120,15 @@ Error ColladaImport::_populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p
skeleton_bone_map[p_skeleton][joint->sid] = r_bone;
+ {
+ Transform3D xform = joint->compute_transform(collada);
+ xform = collada.fix_transform(xform) * joint->post_transform;
+
+ p_skeleton->set_bone_pose_position(r_bone, xform.origin);
+ p_skeleton->set_bone_pose_rotation(r_bone, xform.basis.get_rotation_quaternion());
+ p_skeleton->set_bone_pose_scale(r_bone, xform.basis.get_scale());
+ }
+
if (collada.state.bone_rest_map.has(joint->sid)) {
p_skeleton->set_bone_rest(r_bone, collada.fix_transform(collada.state.bone_rest_map[joint->sid]));
//should map this bone to something for animation?
@@ -282,8 +292,8 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
node = memnew(Path3D);
} else {
//mesh since nothing else
- node = memnew(EditorSceneImporterMeshNode3D);
- //Object::cast_to<EditorSceneImporterMeshNode3D>(node)->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
+ node = memnew(ImporterMeshInstance3D);
+ //Object::cast_to<ImporterMeshInstance3D>(node)->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
}
} break;
case Collada::Node::TYPE_SKELETON: {
@@ -293,7 +303,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
} break;
}
- if (p_node->name != "") {
+ if (!p_node->name.is_empty()) {
node->set_name(p_node->name);
}
NodeMap nm;
@@ -304,10 +314,10 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
xf = collada.fix_transform(xf) * p_node->post_transform;
node->set_transform(xf);
- p_parent->add_child(node);
+ p_parent->add_child(node, true);
node->set_owner(scene);
- if (p_node->empty_draw_type != "") {
+ if (!p_node->empty_draw_type.is_empty()) {
node->set_meta("empty_draw_type", Variant(p_node->empty_draw_type));
}
@@ -330,9 +340,9 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<StandardMaterial3D> material = memnew(StandardMaterial3D);
String base_name;
- if (src_mat.name != "") {
+ if (!src_mat.name.is_empty()) {
base_name = src_mat.name;
- } else if (effect.name != "") {
+ } else if (!effect.name.is_empty()) {
base_name = effect.name;
} else {
base_name = "Material";
@@ -350,9 +360,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// DIFFUSE
- if (effect.diffuse.texture != "") {
+ if (!effect.diffuse.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.diffuse.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -371,9 +381,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// SPECULAR
- if (effect.specular.texture != "") {
+ if (!effect.specular.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.specular.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -396,9 +406,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// EMISSION
- if (effect.emission.texture != "") {
+ if (!effect.emission.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.emission.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -423,9 +433,9 @@ Error ColladaImport::_create_material(const String &p_target) {
// NORMAL
- if (effect.bump.texture != "") {
+ if (!effect.bump.texture.is_empty()) {
String texfile = effect.get_texture_path(effect.bump.texture, collada);
- if (texfile != "") {
+ if (!texfile.is_empty()) {
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -457,11 +467,11 @@ Error ColladaImport::_create_material(const String &p_target) {
return OK;
}
-Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform3D &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) {
+Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform3D &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ImporterMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) {
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
if (p_morph_data) {
- //add morphie target
+ //add morph target
ERR_FAIL_COND_V(!p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA);
String mt = p_morph_data->targets["MORPH_TARGET"];
ERR_FAIL_COND_V(!p_morph_data->sources.has(mt), ERR_INVALID_DATA);
@@ -515,7 +525,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
normal_ofs = vertex_ofs;
}
- if (normal_source_id != "") {
+ if (!normal_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(normal_source_id), ERR_INVALID_DATA);
normal_src = &meshdata.sources[normal_source_id];
}
@@ -535,7 +545,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
binormal_ofs = vertex_ofs;
}
- if (binormal_source_id != "") {
+ if (!binormal_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(binormal_source_id), ERR_INVALID_DATA);
binormal_src = &meshdata.sources[binormal_source_id];
}
@@ -555,7 +565,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
tangent_ofs = vertex_ofs;
}
- if (tangent_source_id != "") {
+ if (!tangent_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(tangent_source_id), ERR_INVALID_DATA);
tangent_src = &meshdata.sources[tangent_source_id];
}
@@ -575,7 +585,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
uv_ofs = vertex_ofs;
}
- if (uv_source_id != "") {
+ if (!uv_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(uv_source_id), ERR_INVALID_DATA);
uv_src = &meshdata.sources[uv_source_id];
}
@@ -595,7 +605,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
uv2_ofs = vertex_ofs;
}
- if (uv2_source_id != "") {
+ if (!uv2_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(uv2_source_id), ERR_INVALID_DATA);
uv2_src = &meshdata.sources[uv2_source_id];
}
@@ -615,7 +625,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
color_ofs = vertex_ofs;
}
- if (color_source_id != "") {
+ if (!color_source_id.is_empty()) {
ERR_FAIL_COND_V(!meshdata.sources.has(color_source_id), ERR_INVALID_DATA);
color_src = &meshdata.sources[color_source_id];
}
@@ -904,7 +914,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor
material = material_cache[target];
}
- } else if (p.material != "") {
+ } else if (!p.material.is_empty()) {
WARN_PRINT("Collada: Unreferenced material in geometry instance: " + p.material);
}
}
@@ -1087,10 +1097,10 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
}
- if (Object::cast_to<EditorSceneImporterMeshNode3D>(node)) {
+ if (Object::cast_to<ImporterMeshInstance3D>(node)) {
Collada::NodeGeometry *ng2 = static_cast<Collada::NodeGeometry *>(p_node);
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(node);
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(node);
ERR_FAIL_COND_V(!mi, ERR_BUG);
@@ -1099,7 +1109,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
String meshid;
Transform3D apply_xform;
Vector<int> bone_remap;
- Vector<Ref<EditorSceneImporterMesh>> morphs;
+ Vector<Ref<ImporterMesh>> morphs;
if (ng2->controller) {
String ngsource = ng2->source;
@@ -1168,10 +1178,10 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
for (int i = 0; i < names.size(); i++) {
String meshid2 = names[i];
if (collada.state.mesh_data_map.has(meshid2)) {
- Ref<EditorSceneImporterMesh> mesh = Ref<EditorSceneImporterMesh>(memnew(EditorSceneImporterMesh));
+ Ref<ImporterMesh> mesh = Ref<ImporterMesh>(memnew(ImporterMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
mesh->set_name(meshdata.name);
- Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, nullptr, Vector<Ref<EditorSceneImporterMesh>>(), false);
+ Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, nullptr, Vector<Ref<ImporterMesh>>(), false);
ERR_FAIL_COND_V(err, err);
morphs.push_back(mesh);
@@ -1188,13 +1198,13 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
}
- ERR_FAIL_COND_V_MSG(ngsource != "", ERR_INVALID_DATA, "Controller instance source '" + ngsource + "' is neither skin or morph!");
+ ERR_FAIL_COND_V_MSG(!ngsource.is_empty(), ERR_INVALID_DATA, "Controller instance source '" + ngsource + "' is neither skin or morph!");
} else {
meshid = ng2->source;
}
- Ref<EditorSceneImporterMesh> mesh;
+ Ref<ImporterMesh> mesh;
if (mesh_cache.has(meshid)) {
mesh = mesh_cache[meshid];
} else {
@@ -1202,16 +1212,16 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
//bleh, must ignore invalid
ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid), ERR_INVALID_DATA);
- mesh = Ref<EditorSceneImporterMesh>(memnew(EditorSceneImporterMesh));
+ mesh = Ref<ImporterMesh>(memnew(ImporterMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
String name = meshdata.name;
- if (name == "") {
+ if (name.is_empty()) {
name = "Mesh";
}
int counter = 2;
while (mesh_unique_names.has(name)) {
name = meshdata.name;
- if (name == "") {
+ if (name.is_empty()) {
name = "Mesh";
}
name += itos(counter++);
@@ -1251,7 +1261,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
mi->set_surface_material(i, material);
- } else if (matname != "") {
+ } else if (!matname.is_empty()) {
WARN_PRINT("Collada: Unreferenced material in geometry instance: " + matname);
}
}
@@ -1314,8 +1324,8 @@ Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_t
}
void ColladaImport::_fix_param_animation_tracks() {
- for (Map<String, Collada::Node *>::Element *E = collada.state.scene_map.front(); E; E = E->next()) {
- Collada::Node *n = E->get();
+ for (KeyValue<String, Collada::Node *> &E : collada.state.scene_map) {
+ Collada::Node *n = E.value;
switch (n->type) {
case Collada::Node::TYPE_NODE: {
// ? do nothing
@@ -1333,7 +1343,7 @@ void ColladaImport::_fix_param_animation_tracks() {
// test source(s)
String source = ng->source;
- while (source != "") {
+ while (!source.is_empty()) {
if (collada.state.skin_controller_data_map.has(source)) {
const Collada::SkinControllerData &skin = collada.state.skin_controller_data_map[source];
@@ -1363,7 +1373,7 @@ void ColladaImport::_fix_param_animation_tracks() {
for (int rti = 0; rti < rt.size(); rti++) {
Collada::AnimationTrack *at = &collada.state.animation_tracks.write[rt[rti]];
- at->target = E->key();
+ at->target = E.key;
at->param = "morph/" + collada.state.mesh_name_map[mesh_name];
at->property = true;
//at->param
@@ -1383,7 +1393,7 @@ void ColladaImport::_fix_param_animation_tracks() {
}
}
-void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks) {
+void ColladaImport::create_animations(bool p_import_value_tracks) {
_fix_param_animation_tracks();
for (int i = 0; i < collada.state.animation_clips.size(); i++) {
for (int j = 0; j < collada.state.animation_clips[i].tracks.size(); j++) {
@@ -1416,13 +1426,13 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_im
}
}
- create_animation(-1, p_make_tracks_in_all_bones, p_import_value_tracks);
+ create_animation(-1, p_import_value_tracks);
for (int i = 0; i < collada.state.animation_clips.size(); i++) {
- create_animation(i, p_make_tracks_in_all_bones, p_import_value_tracks);
+ create_animation(i, p_import_value_tracks);
}
}
-void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks) {
+void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) {
Ref<Animation> animation = Ref<Animation>(memnew(Animation));
if (p_clip == -1) {
@@ -1431,11 +1441,11 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
animation->set_name(collada.state.animation_clips[p_clip].name);
}
- for (Map<String, NodeMap>::Element *E = node_map.front(); E; E = E->next()) {
- if (E->get().bone < 0) {
+ for (const KeyValue<String, NodeMap> &E : node_map) {
+ if (E.value.bone < 0) {
continue;
}
- bones_with_animation[E->key()] = false;
+ bones_with_animation[E.key] = false;
}
//store and validate tracks
@@ -1521,10 +1531,55 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
continue;
}
- animation->add_track(Animation::TYPE_TRANSFORM3D);
- int track = animation->get_track_count() - 1;
- animation->track_set_path(track, path);
- animation->track_set_imported(track, true); //helps merging later
+ bool has_position = false;
+ bool has_rotation = false;
+ bool has_scale = false;
+
+ for (int i = 0; cn->xform_list.size(); i++) {
+ switch (cn->xform_list[i].op) {
+ case Collada::Node::XForm::OP_ROTATE: {
+ has_rotation = true;
+ } break;
+ case Collada::Node::XForm::OP_SCALE: {
+ has_scale = true;
+ } break;
+ case Collada::Node::XForm::OP_TRANSLATE: {
+ has_position = true;
+ } break;
+ case Collada::Node::XForm::OP_MATRIX: {
+ has_position = true;
+ has_rotation = true;
+ has_scale = true;
+ } break;
+ case Collada::Node::XForm::OP_VISIBILITY: {
+ } break;
+ }
+ }
+
+ int base_track = animation->get_track_count();
+ int position_idx = -1;
+ if (has_position) {
+ position_idx = animation->get_track_count();
+ animation->add_track(Animation::TYPE_POSITION_3D);
+ animation->track_set_path(position_idx, path);
+ animation->track_set_imported(position_idx, true); //helps merging later
+ }
+
+ int rotation_idx = -1;
+ if (has_rotation) {
+ rotation_idx = animation->get_track_count();
+ animation->add_track(Animation::TYPE_ROTATION_3D);
+ animation->track_set_path(rotation_idx, path);
+ animation->track_set_imported(rotation_idx, true); //helps merging later
+ }
+
+ int scale_idx = -1;
+ if (has_scale) {
+ scale_idx = animation->get_track_count();
+ animation->add_track(Animation::TYPE_SCALE_3D);
+ animation->track_set_path(scale_idx, path);
+ animation->track_set_imported(scale_idx, true); //helps merging later
+ }
Vector<real_t> snapshots = base_snapshots;
@@ -1593,22 +1648,20 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Transform3D xform = cn->compute_transform(collada);
xform = collada.fix_transform(xform) * cn->post_transform;
- if (nm.bone >= 0) {
- //make bone transform relative to rest (in case of skeleton)
- Skeleton3D *sk = Object::cast_to<Skeleton3D>(nm.node);
- if (sk) {
- xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform;
- } else {
- ERR_PRINT("Collada: Invalid skeleton");
- }
- }
-
Vector3 s = xform.basis.get_scale();
bool singular_matrix = Math::is_zero_approx(s.x) || Math::is_zero_approx(s.y) || Math::is_zero_approx(s.z);
Quaternion q = singular_matrix ? Quaternion() : xform.basis.get_rotation_quaternion();
Vector3 l = xform.origin;
- animation->transform_track_insert_key(track, snapshots[i], l, q, s);
+ if (position_idx >= 0) {
+ animation->position_track_insert_key(position_idx, snapshots[i], l);
+ }
+ if (rotation_idx >= 0) {
+ animation->rotation_track_insert_key(rotation_idx, snapshots[i], q);
+ }
+ if (scale_idx >= 0) {
+ animation->scale_track_insert_key(scale_idx, snapshots[i], s);
+ }
}
if (nm.bone >= 0) {
@@ -1620,48 +1673,15 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
if (found_anim) {
tracks_found = true;
} else {
- animation->remove_track(track);
- }
- }
-
- if (p_make_tracks_in_all_bones) {
- //some bones may lack animation, but since we don't store pose as a property, we must add keyframes!
- for (Map<String, bool>::Element *E = bones_with_animation.front(); E; E = E->next()) {
- if (E->get()) {
- continue;
+ if (position_idx >= 0) {
+ animation->remove_track(base_track);
}
-
- NodeMap &nm = node_map[E->key()];
- String path = scene->get_path_to(nm.node);
- ERR_CONTINUE(nm.bone < 0);
- Skeleton3D *sk = static_cast<Skeleton3D *>(nm.node);
- String name = sk->get_bone_name(nm.bone);
- path = path + ":" + name;
-
- Collada::Node *cn = collada.state.scene_map[E->key()];
- if (cn->ignore_anim) {
- WARN_PRINT("Collada: Ignoring animation on node: " + path);
- continue;
+ if (rotation_idx >= 0) {
+ animation->remove_track(base_track);
+ }
+ if (scale_idx >= 0) {
+ animation->remove_track(base_track);
}
-
- animation->add_track(Animation::TYPE_TRANSFORM3D);
- int track = animation->get_track_count() - 1;
- animation->track_set_path(track, path);
- animation->track_set_imported(track, true); //helps merging later
-
- Transform3D xform = cn->compute_transform(collada);
- xform = collada.fix_transform(xform) * cn->post_transform;
-
- xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform;
-
- Vector3 s = xform.basis.get_scale();
- bool singular_matrix = Math::is_zero_approx(s.x) || Math::is_zero_approx(s.y) || Math::is_zero_approx(s.z);
- Quaternion q = singular_matrix ? Quaternion() : xform.basis.get_rotation_quaternion();
- Vector3 l = xform.origin;
-
- animation->transform_track_insert_key(track, 0, l, q, s);
-
- tracks_found = true;
}
}
@@ -1689,7 +1709,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
NodeMap &nm = node_map[at.target];
String path = scene->get_path_to(nm.node);
- animation->add_track(Animation::TYPE_VALUE);
+ animation->add_track(Animation::TYPE_BLEND_SHAPE);
int track = animation->get_track_count() - 1;
path = path + ":" + at.param;
@@ -1711,7 +1731,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
WARN_PRINT("Collada: Unexpected amount of value keys: " + itos(data.size()));
}
- animation->track_insert_key(track, time, value);
+ animation->blend_shape_track_insert_key(track, time, value);
}
tracks_found = true;
@@ -1727,15 +1747,15 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
/*************************************** SCENE ***********************************/
/*********************************************************************************/
-uint32_t EditorSceneImporterCollada::get_import_flags() const {
+uint32_t EditorSceneFormatImporterCollada::get_import_flags() const {
return IMPORT_SCENE | IMPORT_ANIMATION;
}
-void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) const {
+void EditorSceneFormatImporterCollada::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("dae");
}
-Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
if (r_err) {
*r_err = OK;
}
@@ -1748,7 +1768,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
state.use_mesh_builtin_materials = true;
state.bake_fps = p_bake_fps;
- Error err = state.load(p_path, flags, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, false);
+ Error err = state.load(p_path, flags, p_flags & EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, false);
if (r_err) {
*r_err = err;
@@ -1772,11 +1792,11 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
}
if (p_flags & IMPORT_ANIMATION) {
- state.create_animations(true, true);
+ state.create_animations(true);
AnimationPlayer *ap = memnew(AnimationPlayer);
for (int i = 0; i < state.animations.size(); i++) {
String name;
- if (state.animations[i]->get_name() == "") {
+ if (state.animations[i]->get_name().is_empty()) {
name = "default";
} else {
name = state.animations[i]->get_name();
@@ -1784,22 +1804,22 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
ap->add_animation(name, state.animations[i]);
}
- state.scene->add_child(ap);
+ state.scene->add_child(ap, true);
ap->set_owner(state.scene);
}
return state.scene;
}
-Ref<Animation> EditorSceneImporterCollada::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporterCollada::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
ColladaImport state;
state.use_mesh_builtin_materials = false;
- Error err = state.load(p_path, Collada::IMPORT_FLAG_ANIMATION, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS);
+ Error err = state.load(p_path, Collada::IMPORT_FLAG_ANIMATION, p_flags & EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS);
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load animation from file '" + p_path + "'.");
- state.create_animations(true, true);
+ state.create_animations(true);
if (state.scene) {
memdelete(state.scene);
}
@@ -1812,5 +1832,5 @@ Ref<Animation> EditorSceneImporterCollada::import_animation(const String &p_path
return anim;
}
-EditorSceneImporterCollada::EditorSceneImporterCollada() {
+EditorSceneFormatImporterCollada::EditorSceneFormatImporterCollada() {
}
diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h
index bf45322765..c32d785d1c 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,16 +33,16 @@
#include "editor/import/resource_importer_scene.h"
-class EditorSceneImporterCollada : public EditorSceneImporter {
- GDCLASS(EditorSceneImporterCollada, EditorSceneImporter);
+class EditorSceneFormatImporterCollada : public EditorSceneFormatImporter {
+ GDCLASS(EditorSceneFormatImporterCollada, EditorSceneFormatImporter);
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override;
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
- EditorSceneImporterCollada();
+ EditorSceneFormatImporterCollada();
};
#endif
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
index d219f6e325..cf3464b168 100644
--- a/editor/import/editor_import_plugin.cpp
+++ b/editor/import/editor_import_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,6 +57,7 @@ void EditorImportPlugin::get_recognized_extensions(List<String> *p_extensions) c
for (int i = 0; i < extensions.size(); i++) {
p_extensions->push_back(extensions[i]);
}
+ return;
}
ERR_FAIL_MSG("Unimplemented _get_recognized_extensions in add-on.");
}
@@ -109,12 +110,12 @@ int EditorImportPlugin::get_import_order() const {
ERR_FAIL_V_MSG(-1, "Unimplemented _get_import_order in add-on.");
}
-void EditorImportPlugin::get_import_options(List<ResourceImporter::ImportOption> *r_options, int p_preset) const {
+void EditorImportPlugin::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options, int p_preset) const {
Array needed;
needed.push_back("name");
needed.push_back("default_value");
Array options;
- if (GDVIRTUAL_CALL(_get_import_options, p_preset, options)) {
+ if (GDVIRTUAL_CALL(_get_import_options, p_path, p_preset, options)) {
for (int i = 0; i < options.size(); i++) {
Dictionary d = options[i];
ERR_FAIL_COND(!d.has_all(needed));
@@ -139,12 +140,13 @@ void EditorImportPlugin::get_import_options(List<ResourceImporter::ImportOption>
ImportOption option(PropertyInfo(default_value.get_type(), name, hint, hint_string, usage), default_value);
r_options->push_back(option);
}
+ return;
}
ERR_FAIL_MSG("Unimplemented _get_import_options in add-on.");
}
-bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool EditorImportPlugin::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
Dictionary d;
Map<StringName, Variant>::Element *E = p_options.front();
while (E) {
@@ -152,7 +154,7 @@ bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map
E = E->next();
}
bool visible;
- if (GDVIRTUAL_CALL(_get_option_visibility, p_option, d, visible)) {
+ if (GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, d, visible)) {
return visible;
}
@@ -190,11 +192,11 @@ void EditorImportPlugin::_bind_methods() {
GDVIRTUAL_BIND(_get_preset_count)
GDVIRTUAL_BIND(_get_preset_name, "preset_index")
GDVIRTUAL_BIND(_get_recognized_extensions)
- GDVIRTUAL_BIND(_get_import_options, "preset_index")
+ GDVIRTUAL_BIND(_get_import_options, "path", "preset_index")
GDVIRTUAL_BIND(_get_save_extension)
GDVIRTUAL_BIND(_get_resource_type)
GDVIRTUAL_BIND(_get_priority)
GDVIRTUAL_BIND(_get_import_order)
- GDVIRTUAL_BIND(_get_option_visibility, "option_name", "options")
+ GDVIRTUAL_BIND(_get_option_visibility, "path", "option_name", "options")
GDVIRTUAL_BIND(_import, "source_file", "save_path", "options", "platform_variants", "gen_files");
}
diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h
index 49c959ab44..6cff8fb917 100644
--- a/editor/import/editor_import_plugin.h
+++ b/editor/import/editor_import_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,12 +44,12 @@ protected:
GDVIRTUAL0RC(int, _get_preset_count)
GDVIRTUAL1RC(String, _get_preset_name, int)
GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions)
- GDVIRTUAL1RC(Array, _get_import_options, int)
+ GDVIRTUAL2RC(Array, _get_import_options, String, int)
GDVIRTUAL0RC(String, _get_save_extension)
GDVIRTUAL0RC(String, _get_resource_type)
GDVIRTUAL0RC(float, _get_priority)
GDVIRTUAL0RC(int, _get_import_order)
- GDVIRTUAL2RC(bool, _get_option_visibility, StringName, Dictionary)
+ GDVIRTUAL3RC(bool, _get_option_visibility, String, StringName, Dictionary)
GDVIRTUAL5RC(int, _import, String, String, Dictionary, Array, Array)
public:
@@ -63,8 +63,8 @@ public:
virtual String get_resource_type() const override;
virtual float get_priority() const override;
virtual int get_import_order() const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = nullptr) override;
};
diff --git a/editor/import/editor_importer_bake_reset.cpp b/editor/import/editor_importer_bake_reset.cpp
deleted file mode 100644
index 00dce6850e..0000000000
--- a/editor/import/editor_importer_bake_reset.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*************************************************************************/
-/* editor_importer_bake_reset.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "editor/import/editor_importer_bake_reset.h"
-
-#include "core/error/error_list.h"
-#include "core/error/error_macros.h"
-#include "core/math/transform_3d.h"
-#include "editor/import/scene_importer_mesh_node_3d.h"
-#include "resource_importer_scene.h"
-#include "scene/3d/mesh_instance_3d.h"
-#include "scene/3d/node_3d.h"
-#include "scene/3d/skeleton_3d.h"
-#include "scene/animation/animation_player.h"
-
-// Given that an engineering team has made a reference character, one wants ten animators to create animations.
-// Currently, a tech artist needs to combine the ten files into one exported gltf2 to import into Godot Engine.
-// We bake the RESET animation and then set it to identity,
-// so that rigs with corresponding RESET animation can have their animations transferred with ease.
-//
-// The original algorithm for the code was used to change skeleton bone rolls to be parent to child.
-//
-// Reference https://github.com/godotengine/godot-proposals/issues/2961
-void BakeReset::_bake_animation_pose(Node *scene, const String &p_bake_anim) {
- Map<StringName, BakeResetRestBone> r_rest_bones;
- Vector<Node3D *> r_meshes;
- List<Node *> queue;
- queue.push_back(scene);
- while (!queue.is_empty()) {
- List<Node *>::Element *E = queue.front();
- Node *node = E->get();
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(node);
- // Step 1: import scene with animations into the rest bones data structure.
- _fetch_reset_animation(ap, r_rest_bones, p_bake_anim);
-
- int child_count = node->get_child_count();
- for (int i = 0; i < child_count; i++) {
- queue.push_back(node->get_child(i));
- }
- queue.pop_front();
- }
-
- queue.push_back(scene);
- while (!queue.is_empty()) {
- List<Node *>::Element *E = queue.front();
- Node *node = E->get();
- EditorSceneImporterMeshNode3D *editor_mesh_3d = scene->cast_to<EditorSceneImporterMeshNode3D>(node);
- MeshInstance3D *mesh_3d = scene->cast_to<MeshInstance3D>(node);
- if (scene->cast_to<Skeleton3D>(node)) {
- Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
-
- // Step 2: Bake the RESET animation from the RestBone to the skeleton.
- _fix_skeleton(skeleton, r_rest_bones);
- }
- if (editor_mesh_3d) {
- NodePath path = editor_mesh_3d->get_skeleton_path();
- if (!path.is_empty() && editor_mesh_3d->get_node_or_null(path) && Object::cast_to<Skeleton3D>(editor_mesh_3d->get_node_or_null(path))) {
- r_meshes.push_back(editor_mesh_3d);
- }
- } else if (mesh_3d) {
- NodePath path = mesh_3d->get_skeleton_path();
- if (!path.is_empty() && mesh_3d->get_node_or_null(path) && Object::cast_to<Skeleton3D>(mesh_3d->get_node_or_null(path))) {
- r_meshes.push_back(mesh_3d);
- }
- }
- int child_count = node->get_child_count();
- for (int i = 0; i < child_count; i++) {
- queue.push_back(node->get_child(i));
- }
- queue.pop_front();
- }
-
- queue.push_back(scene);
- while (!queue.is_empty()) {
- List<Node *>::Element *E = queue.front();
- Node *node = E->get();
- AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(node);
- if (ap) {
- // Step 3: Key all RESET animation frames to identity.
- _align_animations(ap, r_rest_bones);
- }
-
- int child_count = node->get_child_count();
- for (int i = 0; i < child_count; i++) {
- queue.push_back(node->get_child(i));
- }
- queue.pop_front();
- }
-}
-
-void BakeReset::_align_animations(AnimationPlayer *p_ap, const Map<StringName, BakeResetRestBone> &r_rest_bones) {
- ERR_FAIL_NULL(p_ap);
- List<StringName> anim_names;
- p_ap->get_animation_list(&anim_names);
- for (List<StringName>::Element *anim_i = anim_names.front(); anim_i; anim_i = anim_i->next()) {
- Ref<Animation> a = p_ap->get_animation(anim_i->get());
- ERR_CONTINUE(a.is_null());
- for (Map<StringName, BakeResetRestBone>::Element *rest_bone_i = r_rest_bones.front(); rest_bone_i; rest_bone_i = rest_bone_i->next()) {
- int track = a->find_track(NodePath(rest_bone_i->key()));
- if (track == -1) {
- continue;
- }
- int new_track = a->add_track(Animation::TYPE_TRANSFORM3D);
- NodePath new_path = NodePath(rest_bone_i->key());
- BakeResetRestBone rest_bone = rest_bone_i->get();
- a->track_set_path(new_track, new_path);
- for (int key_i = 0; key_i < a->track_get_key_count(track); key_i++) {
- Vector3 loc;
- Quaternion rot;
- Vector3 scale;
- Error err = a->transform_track_get_key(track, key_i, &loc, &rot, &scale);
- ERR_CONTINUE(err);
- real_t time = a->track_get_key_time(track, key_i);
- rot.normalize();
- loc = loc - rest_bone.loc;
- rot = rest_bone.rest_delta.get_rotation_quaternion().inverse() * rot;
- rot.normalize();
- scale = Vector3(1, 1, 1) - (rest_bone.rest_delta.get_scale() - scale);
- // Apply the reverse of the rest changes to make the key be close to identity transform.
- a->transform_track_insert_key(new_track, time, loc, rot, scale);
- }
- a->remove_track(track);
- }
- }
-}
-
-void BakeReset::_fetch_reset_animation(AnimationPlayer *p_ap, Map<StringName, BakeResetRestBone> &r_rest_bones, const String &p_bake_anim) {
- if (!p_ap) {
- return;
- }
- List<StringName> anim_names;
- p_ap->get_animation_list(&anim_names);
- Node *root = p_ap->get_owner();
- ERR_FAIL_NULL(root);
- if (!p_ap->has_animation(p_bake_anim)) {
- return;
- }
- Ref<Animation> a = p_ap->get_animation(p_bake_anim);
- if (a.is_null()) {
- return;
- }
- for (int32_t track = 0; track < a->get_track_count(); track++) {
- NodePath path = a->track_get_path(track);
- String string_path = path;
- Skeleton3D *skeleton = root->cast_to<Skeleton3D>(root->get_node(string_path.get_slice(":", 0)));
- if (!skeleton) {
- continue;
- }
- String bone_name = string_path.get_slice(":", 1);
- for (int key_i = 0; key_i < a->track_get_key_count(track); key_i++) {
- Vector3 loc;
- Quaternion rot;
- Vector3 scale;
- Error err = a->transform_track_get_key(track, key_i, &loc, &rot, &scale);
- if (err != OK) {
- ERR_PRINT_ONCE("Reset animation baker can't get key.");
- continue;
- }
- rot.normalize();
- Basis rot_basis = Basis(rot, scale);
- BakeResetRestBone rest_bone;
- rest_bone.rest_delta = rot_basis;
- rest_bone.loc = loc;
- // Store the animation into the RestBone.
- r_rest_bones[StringName(String(skeleton->get_owner()->get_path_to(skeleton)) + ":" + bone_name)] = rest_bone;
- break;
- }
- }
-}
-
-void BakeReset::_fix_skeleton(Skeleton3D *p_skeleton, Map<StringName, BakeReset::BakeResetRestBone> &r_rest_bones) {
- int bone_count = p_skeleton->get_bone_count();
-
- // First iterate through all the bones and update the RestBone.
- for (int j = 0; j < bone_count; j++) {
- StringName final_path = String(p_skeleton->get_owner()->get_path_to(p_skeleton)) + String(":") + p_skeleton->get_bone_name(j);
- BakeResetRestBone &rest_bone = r_rest_bones[final_path];
- rest_bone.rest_local = p_skeleton->get_bone_rest(j);
- }
- for (int i = 0; i < bone_count; i++) {
- int parent_bone = p_skeleton->get_bone_parent(i);
- String path = p_skeleton->get_owner()->get_path_to(p_skeleton);
- StringName final_path = String(path) + String(":") + p_skeleton->get_bone_name(parent_bone);
- if (parent_bone >= 0) {
- r_rest_bones[path].children.push_back(i);
- }
- }
-
- // When we apply transform to a bone, we also have to move all of its children in the opposite direction.
- for (int i = 0; i < bone_count; i++) {
- StringName final_path = String(p_skeleton->get_owner()->get_path_to(p_skeleton)) + String(":") + p_skeleton->get_bone_name(i);
- r_rest_bones[final_path].rest_local = r_rest_bones[final_path].rest_local * Transform3D(r_rest_bones[final_path].rest_delta, r_rest_bones[final_path].loc);
- // Iterate through the children and move in the opposite direction.
- for (int j = 0; j < r_rest_bones[final_path].children.size(); j++) {
- int child_index = r_rest_bones[final_path].children[j];
- StringName children_path = String(p_skeleton->get_name()) + String(":") + p_skeleton->get_bone_name(child_index);
- r_rest_bones[children_path].rest_local = Transform3D(r_rest_bones[final_path].rest_delta, r_rest_bones[final_path].loc).affine_inverse() * r_rest_bones[children_path].rest_local;
- }
- }
-
- for (int i = 0; i < bone_count; i++) {
- StringName final_path = String(p_skeleton->get_owner()->get_path_to(p_skeleton)) + String(":") + p_skeleton->get_bone_name(i);
- ERR_CONTINUE(!r_rest_bones.has(final_path));
- Transform3D rest_transform = r_rest_bones[final_path].rest_local;
- p_skeleton->set_bone_rest(i, rest_transform);
- }
-}
diff --git a/editor/import/editor_importer_bake_reset.h b/editor/import/editor_importer_bake_reset.h
deleted file mode 100644
index e36ae86181..0000000000
--- a/editor/import/editor_importer_bake_reset.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*************************************************************************/
-/* editor_importer_bake_reset.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef RESOURCE_IMPORTER_BAKE_RESET_H
-#define RESOURCE_IMPORTER_BAKE_RESET_H
-
-#include "scene/main/node.h"
-
-class Skeleton3D;
-class AnimationPlayer;
-class BakeReset {
- struct BakeResetRestBone {
- Transform3D rest_local;
- Basis rest_delta;
- Vector3 loc;
- Vector<int> children;
- };
-
-public:
- void _bake_animation_pose(Node *scene, const String &p_bake_anim);
-
-private:
- void _fix_skeleton(Skeleton3D *p_skeleton, Map<StringName, BakeReset::BakeResetRestBone> &r_rest_bones);
- void _align_animations(AnimationPlayer *p_ap, const Map<StringName, BakeResetRestBone> &r_rest_bones);
- void _fetch_reset_animation(AnimationPlayer *p_ap, Map<StringName, BakeResetRestBone> &r_rest_bones, const String &p_bake_anim);
-};
-#endif
diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp
index 7fd9230284..16b68bcc22 100644
--- a/editor/import/resource_importer_bitmask.cpp
+++ b/editor/import/resource_importer_bitmask.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,7 +57,7 @@ String ResourceImporterBitMap::get_resource_type() const {
return "BitMap";
}
-bool ResourceImporterBitMap::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterBitMap::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
@@ -69,7 +69,7 @@ String ResourceImporterBitMap::get_preset_name(int p_idx) const {
return String();
}
-void ResourceImporterBitMap::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterBitMap::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "create_from", PROPERTY_HINT_ENUM, "Black & White,Alpha"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.5));
}
diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h
index d68693c54a..e5cf1facff 100644
--- a/editor/import/resource_importer_bitmask.h
+++ b/editor/import/resource_importer_bitmask.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -49,8 +49,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
ResourceImporterBitMap();
diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp
index 2e7ef1402b..8a655fbc0c 100644
--- a/editor/import/resource_importer_bmfont.cpp
+++ b/editor/import/resource_importer_bmfont.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,7 +30,6 @@
#include "resource_importer_bmfont.h"
-#include "core/io/image_loader.h"
#include "core/io/resource_saver.h"
String ResourceImporterBMFont::get_importer_name() const {
@@ -56,730 +55,22 @@ String ResourceImporterBMFont::get_resource_type() const {
return "FontData";
}
-bool ResourceImporterBMFont::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterBMFont::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
-void ResourceImporterBMFont::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterBMFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
}
-void _convert_packed_8bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_sz) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- PackedByteArray imgdata_r;
- imgdata_r.resize(w * h * 2);
- uint8_t *wr = imgdata_r.ptrw();
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_b;
- imgdata_b.resize(w * h * 2);
- uint8_t *wb = imgdata_b.ptrw();
-
- PackedByteArray imgdata_a;
- imgdata_a.resize(w * h * 2);
- uint8_t *wa = imgdata_a.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * 4;
- int ofs_dst = (i * w + j) * 2;
- wr[ofs_dst + 0] = 255;
- wr[ofs_dst + 1] = r[ofs_src + 0];
- wg[ofs_dst + 0] = 255;
- wg[ofs_dst + 1] = r[ofs_src + 1];
- wb[ofs_dst + 0] = 255;
- wb[ofs_dst + 1] = r[ofs_src + 2];
- wa[ofs_dst + 0] = 255;
- wa[ofs_dst + 1] = r[ofs_src + 3];
- }
- }
- Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
- Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
- Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
-}
-
-void _convert_packed_4bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_sz) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- PackedByteArray imgdata_r;
- imgdata_r.resize(w * h * 2);
- uint8_t *wr = imgdata_r.ptrw();
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_b;
- imgdata_b.resize(w * h * 2);
- uint8_t *wb = imgdata_b.ptrw();
-
- PackedByteArray imgdata_a;
- imgdata_a.resize(w * h * 2);
- uint8_t *wa = imgdata_a.ptrw();
-
- PackedByteArray imgdata_ro;
- imgdata_ro.resize(w * h * 2);
- uint8_t *wro = imgdata_ro.ptrw();
-
- PackedByteArray imgdata_go;
- imgdata_go.resize(w * h * 2);
- uint8_t *wgo = imgdata_go.ptrw();
-
- PackedByteArray imgdata_bo;
- imgdata_bo.resize(w * h * 2);
- uint8_t *wbo = imgdata_bo.ptrw();
-
- PackedByteArray imgdata_ao;
- imgdata_ao.resize(w * h * 2);
- uint8_t *wao = imgdata_ao.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * 4;
- int ofs_dst = (i * w + j) * 2;
- wr[ofs_dst + 0] = 255;
- wro[ofs_dst + 0] = 255;
- if (r[ofs_src + 0] > 0x0F) {
- wr[ofs_dst + 1] = (r[ofs_src + 0] - 0x0F) * 2;
- wro[ofs_dst + 1] = 0;
- } else {
- wr[ofs_dst + 1] = 0;
- wro[ofs_dst + 1] = r[ofs_src + 0] * 2;
- }
- wg[ofs_dst + 0] = 255;
- wgo[ofs_dst + 0] = 255;
- if (r[ofs_src + 1] > 0x0F) {
- wg[ofs_dst + 1] = (r[ofs_src + 1] - 0x0F) * 2;
- wgo[ofs_dst + 1] = 0;
- } else {
- wg[ofs_dst + 1] = 0;
- wgo[ofs_dst + 1] = r[ofs_src + 1] * 2;
- }
- wb[ofs_dst + 0] = 255;
- wbo[ofs_dst + 0] = 255;
- if (r[ofs_src + 2] > 0x0F) {
- wb[ofs_dst + 1] = (r[ofs_src + 2] - 0x0F) * 2;
- wbo[ofs_dst + 1] = 0;
- } else {
- wb[ofs_dst + 1] = 0;
- wbo[ofs_dst + 1] = r[ofs_src + 2] * 2;
- }
- wa[ofs_dst + 0] = 255;
- wao[ofs_dst + 0] = 255;
- if (r[ofs_src + 3] > 0x0F) {
- wa[ofs_dst + 1] = (r[ofs_src + 3] - 0x0F) * 2;
- wao[ofs_dst + 1] = 0;
- } else {
- wa[ofs_dst + 1] = 0;
- wao[ofs_dst + 1] = r[ofs_src + 3] * 2;
- }
- }
- }
- Ref<Image> img_r = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_r));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 0, img_r);
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 1, img_g);
- Ref<Image> img_b = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_b));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 2, img_b);
- Ref<Image> img_a = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_a));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page * 4 + 3, img_a);
-
- Ref<Image> img_ro = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ro));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 0, img_ro);
- Ref<Image> img_go = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_go));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 1, img_go);
- Ref<Image> img_bo = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_bo));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 2, img_bo);
- Ref<Image> img_ao = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_ao));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page * 4 + 3, img_ao);
-}
-
-void _convert_rgba_4bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_sz) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 4);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_o;
- imgdata_o.resize(w * h * 4);
- uint8_t *wo = imgdata_o.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs = (i * w + j) * 4;
-
- if (r[ofs + 0] > 0x7F) {
- wg[ofs + 0] = r[ofs + 0];
- wo[ofs + 0] = 0;
- } else {
- wg[ofs + 0] = 0;
- wo[ofs + 0] = r[ofs + 0] * 2;
- }
- if (r[ofs + 1] > 0x7F) {
- wg[ofs + 1] = r[ofs + 1];
- wo[ofs + 1] = 0;
- } else {
- wg[ofs + 1] = 0;
- wo[ofs + 1] = r[ofs + 1] * 2;
- }
- if (r[ofs + 2] > 0x7F) {
- wg[ofs + 2] = r[ofs + 2];
- wo[ofs + 2] = 0;
- } else {
- wg[ofs + 2] = 0;
- wo[ofs + 2] = r[ofs + 2] * 2;
- }
- if (r[ofs + 3] > 0x7F) {
- wg[ofs + 3] = r[ofs + 3];
- wo[ofs + 3] = 0;
- } else {
- wg[ofs + 3] = 0;
- wo[ofs + 3] = r[ofs + 3] * 2;
- }
- }
- }
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
-
- Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_RGBA8, imgdata_o));
- r_font->set_texture_image(0, Vector2i(p_sz, 1), p_page, img_o);
-}
-
-void _convert_mono_8bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- int size = 4;
- if (p_source->get_format() == Image::FORMAT_L8) {
- size = 1;
- p_ch = 0;
- }
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * size;
- int ofs_dst = (i * w + j) * 2;
- wg[ofs_dst + 0] = 255;
- wg[ofs_dst + 1] = r[ofs_src + p_ch];
- }
- }
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_g);
-}
-
-void _convert_mono_4bit(Ref<FontData> &r_font, Ref<Image> &p_source, int p_page, int p_ch, int p_sz, int p_ol) {
- int w = p_source->get_width();
- int h = p_source->get_height();
-
- PackedByteArray imgdata = p_source->get_data();
- const uint8_t *r = imgdata.ptr();
-
- int size = 4;
- if (p_source->get_format() == Image::FORMAT_L8) {
- size = 1;
- p_ch = 0;
- }
-
- PackedByteArray imgdata_g;
- imgdata_g.resize(w * h * 2);
- uint8_t *wg = imgdata_g.ptrw();
-
- PackedByteArray imgdata_o;
- imgdata_o.resize(w * h * 2);
- uint8_t *wo = imgdata_o.ptrw();
-
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int ofs_src = (i * w + j) * size;
- int ofs_dst = (i * w + j) * 2;
- wg[ofs_dst + 0] = 255;
- wo[ofs_dst + 0] = 255;
- if (r[ofs_src + p_ch] > 0x7F) {
- wg[ofs_dst + 1] = r[ofs_src + p_ch];
- wo[ofs_dst + 1] = 0;
- } else {
- wg[ofs_dst + 1] = 0;
- wo[ofs_dst + 1] = r[ofs_src + p_ch] * 2;
- }
- }
- }
- Ref<Image> img_g = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_g));
- r_font->set_texture_image(0, Vector2i(p_sz, 0), p_page, img_g);
-
- Ref<Image> img_o = memnew(Image(w, h, 0, Image::FORMAT_LA8, imgdata_o));
- r_font->set_texture_image(0, Vector2i(p_sz, p_ol), p_page, img_o);
-}
-
Error ResourceImporterBMFont::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
print_verbose("Importing BMFont font from: " + p_source_file);
Ref<FontData> font;
font.instantiate();
- font->set_antialiased(false);
- font->set_multichannel_signed_distance_field(false);
- font->set_force_autohinter(false);
- font->set_hinting(TextServer::HINTING_NONE);
- font->set_oversampling(1.0f);
-
- FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
- if (f == nullptr) {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Cannot open font from file ") + "\"" + p_source_file + "\".");
- }
-
- int base_size = 16;
- int height = 0;
- int ascent = 0;
- int outline = 0;
-
- bool packed = false;
- uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA
- int first_gl_ch = -1;
- int first_ol_ch = -1;
- int first_cm_ch = -1;
-
- unsigned char magic[4];
- f->get_buffer((unsigned char *)&magic, 4);
- if (magic[0] == 'B' && magic[1] == 'M' && magic[2] == 'F') {
- // Binary BMFont file.
- ERR_FAIL_COND_V_MSG(magic[3] != 3, ERR_CANT_CREATE, vformat(TTR("Version %d of BMFont is not supported."), (int)magic[3]));
-
- uint8_t block_type = f->get_8();
- uint32_t block_size = f->get_32();
- while (!f->eof_reached()) {
- uint64_t off = f->get_position();
- switch (block_type) {
- case 1: /* info */ {
- ERR_FAIL_COND_V_MSG(block_size < 15, ERR_CANT_CREATE, TTR("Invalid BMFont info block size."));
- base_size = f->get_16();
- uint8_t flags = f->get_8();
- ERR_FAIL_COND_V_MSG(flags & 0x02, ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
- f->get_8(); // non-unicode charset, skip
- f->get_16(); // stretch_h, skip
- f->get_8(); // aa, skip
- f->get_32(); // padding, skip
- f->get_16(); // spacing, skip
- outline = f->get_8();
- // font name, skip
- font->set_fixed_size(base_size);
- } break;
- case 2: /* common */ {
- ERR_FAIL_COND_V_MSG(block_size != 15, ERR_CANT_CREATE, TTR("Invalid BMFont common block size."));
- height = f->get_16();
- ascent = f->get_16();
- f->get_32(); // scale, skip
- f->get_16(); // pages, skip
- uint8_t flags = f->get_8();
- packed = (flags & 0x01);
- ch[3] = f->get_8();
- ch[0] = f->get_8();
- ch[1] = f->get_8();
- ch[2] = f->get_8();
- for (int i = 0; i < 4; i++) {
- if (ch[i] == 0 && first_gl_ch == -1) {
- first_gl_ch = i;
- }
- if (ch[i] == 1 && first_ol_ch == -1) {
- first_ol_ch = i;
- }
- if (ch[i] == 2 && first_cm_ch == -1) {
- first_cm_ch = i;
- }
- }
- } break;
- case 3: /* pages */ {
- int page = 0;
- CharString cs;
- char32_t c = f->get_8();
- while (!f->eof_reached() && f->get_position() <= off + block_size) {
- if (c == '\0') {
- String base_dir = p_source_file.get_base_dir();
- String file = base_dir.plus_file(String::utf8(cs.ptr(), cs.length()));
- if (RenderingServer::get_singleton() != nullptr) {
- Ref<Image> img;
- img.instantiate();
- Error err = ImageLoader::load_image(file, img);
- ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\".");
-
- if (packed) {
- if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_8bit(font, img, page, base_size);
- } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_4bit(font, img, page, base_size);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- } else {
- if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- font->set_texture_image(0, Vector2i(base_size, 0), page, img);
- } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_rgba_4bit(font, img, page, base_size);
- } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- _convert_mono_8bit(font, img, page, first_ol_ch, base_size, 1);
- } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_4bit(font, img, page, first_cm_ch, base_size, 1);
- } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- }
- }
- page++;
- cs = "";
- } else {
- cs += c;
- }
- c = f->get_8();
- }
- } break;
- case 4: /* chars */ {
- int char_count = block_size / 20;
- for (int i = 0; i < char_count; i++) {
- Vector2 advance;
- Vector2 size;
- Vector2 offset;
- Rect2 uv_rect;
-
- char32_t idx = f->get_32();
- uv_rect.position.x = (int16_t)f->get_16();
- uv_rect.position.y = (int16_t)f->get_16();
- uv_rect.size.width = (int16_t)f->get_16();
- size.width = uv_rect.size.width;
- uv_rect.size.height = (int16_t)f->get_16();
- size.height = uv_rect.size.height;
- offset.x = (int16_t)f->get_16();
- offset.y = (int16_t)f->get_16() - ascent;
- advance.x = (int16_t)f->get_16();
- if (advance.x < 0) {
- advance.x = size.width + 1;
- }
-
- int texture_idx = f->get_8();
- uint8_t channel = f->get_8();
-
- ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel."));
- int ch_off = 0;
- switch (channel) {
- case 1:
- ch_off = 2;
- break; // B
- case 2:
- ch_off = 1;
- break; // G
- case 4:
- ch_off = 0;
- break; // R
- case 8:
- ch_off = 3;
- break; // A
- default:
- ch_off = 0;
- break;
- }
- font->set_glyph_advance(0, base_size, idx, advance);
- font->set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 0), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- if (outline > 0) {
- font->set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 1), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- }
- }
- } break;
- case 5: /* kerning */ {
- int pair_count = block_size / 10;
- for (int i = 0; i < pair_count; i++) {
- Vector2i kpk;
- kpk.x = f->get_32();
- kpk.y = f->get_32();
- font->set_kerning(0, base_size, kpk, Vector2((int16_t)f->get_16(), 0));
- }
- } break;
- default: {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Invalid BMFont block type."));
- } break;
- }
- f->seek(off + block_size);
- block_type = f->get_8();
- block_size = f->get_32();
- }
-
- } else {
- // Text BMFont file.
- f->seek(0);
- while (true) {
- String line = f->get_line();
-
- int delimiter = line.find(" ");
- String type = line.substr(0, delimiter);
- int pos = delimiter + 1;
- Map<String, String> keys;
-
- while (pos < line.size() && line[pos] == ' ') {
- pos++;
- }
-
- while (pos < line.size()) {
- int eq = line.find("=", pos);
- if (eq == -1) {
- break;
- }
- String key = line.substr(pos, eq - pos);
- int end = -1;
- String value;
- if (line[eq + 1] == '"') {
- end = line.find("\"", eq + 2);
- if (end == -1) {
- break;
- }
- value = line.substr(eq + 2, end - 1 - eq - 1);
- pos = end + 1;
- } else {
- end = line.find(" ", eq + 1);
- if (end == -1) {
- end = line.size();
- }
- value = line.substr(eq + 1, end - eq);
- pos = end;
- }
-
- while (pos < line.size() && line[pos] == ' ') {
- pos++;
- }
-
- keys[key] = value;
- }
-
- if (type == "info") {
- if (keys.has("size")) {
- base_size = keys["size"].to_int();
- font->set_fixed_size(base_size);
- }
- if (keys.has("outline")) {
- outline = keys["outline"].to_int();
- }
- ERR_FAIL_COND_V_MSG((!keys.has("unicode") || keys["unicode"].to_int() != 1), ERR_CANT_CREATE, TTR("Non-unicode version of BMFont is not supported."));
- } else if (type == "common") {
- if (keys.has("lineHeight")) {
- height = keys["lineHeight"].to_int();
- }
- if (keys.has("base")) {
- ascent = keys["base"].to_int();
- }
- if (keys.has("packed")) {
- packed = (keys["packed"].to_int() == 1);
- }
- if (keys.has("alphaChnl")) {
- ch[3] = keys["alphaChnl"].to_int();
- }
- if (keys.has("redChnl")) {
- ch[0] = keys["redChnl"].to_int();
- }
- if (keys.has("greenChnl")) {
- ch[1] = keys["greenChnl"].to_int();
- }
- if (keys.has("blueChnl")) {
- ch[2] = keys["blueChnl"].to_int();
- }
- for (int i = 0; i < 4; i++) {
- if (ch[i] == 0 && first_gl_ch == -1) {
- first_gl_ch = i;
- }
- if (ch[i] == 1 && first_ol_ch == -1) {
- first_ol_ch = i;
- }
- if (ch[i] == 2 && first_cm_ch == -1) {
- first_cm_ch = i;
- }
- }
- } else if (type == "page") {
- int page = 0;
- if (keys.has("id")) {
- page = keys["id"].to_int();
- }
- if (keys.has("file")) {
- String base_dir = p_source_file.get_base_dir();
- String file = base_dir.plus_file(keys["file"]);
- if (RenderingServer::get_singleton() != nullptr) {
- Ref<Image> img;
- img.instantiate();
- Error err = ImageLoader::load_image(file, img);
- ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_READ, TTR("Can't load font texture: ") + "\"" + file + "\".");
- if (packed) {
- if (ch[3] == 0) { // 4 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_8bit(font, img, page, base_size);
- } else if ((ch[3] == 2) && (outline > 0)) { // 4 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_packed_4bit(font, img, page, base_size);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- } else {
- if ((ch[0] == 0) && (ch[1] == 0) && (ch[2] == 0) && (ch[3] == 0)) { // RGBA8 color, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- font->set_texture_image(0, Vector2i(base_size, 0), page, img);
- } else if ((ch[0] == 2) && (ch[1] == 2) && (ch[2] == 2) && (ch[3] == 2) && (outline > 0)) { // RGBA4 color, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_rgba_4bit(font, img, page, base_size);
- } else if ((first_gl_ch >= 0) && (first_ol_ch >= 0) && (outline > 0)) { // 1 x 8 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- _convert_mono_8bit(font, img, page, first_ol_ch, base_size, 1);
- } else if ((first_cm_ch >= 0) && (outline > 0)) { // 1 x 4 bit monochrome, gl + outline
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_4bit(font, img, page, first_cm_ch, base_size, 1);
- } else if (first_gl_ch >= 0) { // 1 x 8 bit monochrome, no outline
- outline = 0;
- ERR_FAIL_COND_V_MSG(img->get_format() != Image::FORMAT_RGBA8 && img->get_format() != Image::FORMAT_L8, ERR_FILE_CANT_READ, TTR("Unsupported BMFont texture format."));
- _convert_mono_8bit(font, img, page, first_gl_ch, base_size, 0);
- } else {
- ERR_FAIL_V_MSG(ERR_CANT_CREATE, TTR("Unsupported BMFont texture format."));
- }
- }
- }
- }
- } else if (type == "char") {
- char32_t idx = 0;
- Vector2 advance;
- Vector2 size;
- Vector2 offset;
- Rect2 uv_rect;
- int texture_idx = -1;
- uint8_t channel = 15;
-
- if (keys.has("id")) {
- idx = keys["id"].to_int();
- }
- if (keys.has("x")) {
- uv_rect.position.x = keys["x"].to_int();
- }
- if (keys.has("y")) {
- uv_rect.position.y = keys["y"].to_int();
- }
- if (keys.has("width")) {
- uv_rect.size.width = keys["width"].to_int();
- size.width = keys["width"].to_int();
- }
- if (keys.has("height")) {
- uv_rect.size.height = keys["height"].to_int();
- size.height = keys["height"].to_int();
- }
- if (keys.has("xoffset")) {
- offset.x = keys["xoffset"].to_int();
- }
- if (keys.has("yoffset")) {
- offset.y = keys["yoffset"].to_int() - ascent;
- }
- if (keys.has("page")) {
- texture_idx = keys["page"].to_int();
- }
- if (keys.has("xadvance")) {
- advance.x = keys["xadvance"].to_int();
- }
- if (advance.x < 0) {
- advance.x = size.width + 1;
- }
- if (keys.has("chnl")) {
- channel = keys["chnl"].to_int();
- }
-
- ERR_FAIL_COND_V_MSG(!packed && channel != 15, ERR_CANT_CREATE, TTR("Invalid glyph channel."));
- int ch_off = 0;
- switch (channel) {
- case 1:
- ch_off = 2;
- break; // B
- case 2:
- ch_off = 1;
- break; // G
- case 4:
- ch_off = 0;
- break; // R
- case 8:
- ch_off = 3;
- break; // A
- default:
- ch_off = 0;
- break;
- }
- font->set_glyph_advance(0, base_size, idx, advance);
- font->set_glyph_offset(0, Vector2i(base_size, 0), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 0), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 0), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 0), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- if (outline > 0) {
- font->set_glyph_offset(0, Vector2i(base_size, 1), idx, offset);
- font->set_glyph_size(0, Vector2i(base_size, 1), idx, size);
- font->set_glyph_uv_rect(0, Vector2i(base_size, 1), idx, uv_rect);
- font->set_glyph_texture_idx(0, Vector2i(base_size, 1), idx, texture_idx * (packed ? 4 : 1) + ch_off);
- }
- } else if (type == "kerning") {
- Vector2i kpk;
- if (keys.has("first")) {
- kpk.x = keys["first"].to_int();
- }
- if (keys.has("second")) {
- kpk.y = keys["second"].to_int();
- }
- if (keys.has("amount")) {
- font->set_kerning(0, base_size, kpk, Vector2(keys["amount"].to_int(), 0));
- }
- }
-
- if (f->eof_reached()) {
- break;
- }
- }
- }
- font->set_ascent(0, base_size, ascent);
- font->set_descent(0, base_size, height - ascent);
+ Error err = font->load_bitmap_font(p_source_file);
+ ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load font to file \"" + p_source_file + "\".");
int flg = ResourceSaver::SaverFlags::FLAG_BUNDLE_RESOURCES | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
if ((bool)p_options["compress"]) {
@@ -787,7 +78,7 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
}
print_verbose("Saving to: " + p_save_path + ".fontdata");
- Error err = ResourceSaver::save(p_save_path + ".fontdata", font, flg);
+ err = ResourceSaver::save(p_save_path + ".fontdata", font, flg);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save font to file \"" + p_save_path + ".res\".");
print_verbose("Done saving to: " + p_save_path + ".fontdata");
return OK;
diff --git a/editor/import/resource_importer_bmfont.h b/editor/import/resource_importer_bmfont.h
index 065703132a..e5a96e2c40 100644
--- a/editor/import/resource_importer_bmfont.h
+++ b/editor/import/resource_importer_bmfont.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,8 +45,8 @@ public:
virtual String get_save_extension() const override;
virtual String get_resource_type() const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index 07647d8b6a..f0ee14bdcb 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,7 +55,7 @@ String ResourceImporterCSVTranslation::get_resource_type() const {
return "Translation";
}
-bool ResourceImporterCSVTranslation::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterCSVTranslation::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
@@ -67,7 +67,7 @@ String ResourceImporterCSVTranslation::get_preset_name(int p_idx) const {
return "";
}
-void ResourceImporterCSVTranslation::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterCSVTranslation::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "delimiter", PROPERTY_HINT_ENUM, "Comma,Semicolon,Tab"), 0));
}
@@ -99,8 +99,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
Vector<Ref<Translation>> translations;
for (int i = 1; i < line.size(); i++) {
- String locale = line[i];
- ERR_FAIL_COND_V_MSG(!TranslationServer::is_locale_valid(locale), ERR_PARSE_ERROR, "Error importing CSV translation: '" + locale + "' is not a valid locale.");
+ String locale = TranslationServer::get_singleton()->standardize_locale(line[i]);
locales.push_back(locale);
Ref<Translation> translation;
@@ -113,7 +112,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
while (line.size() == locales.size() + 1) {
String key = line[0];
- if (key != "") {
+ if (!key.is_empty()) {
for (int i = 1; i < line.size(); i++) {
translations.write[i - 1]->add_message(key, line[i].c_unescape());
}
diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h
index d53e91e38b..8f6cf94984 100644
--- a/editor/import/resource_importer_csv_translation.h
+++ b/editor/import/resource_importer_csv_translation.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,8 +46,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_dynamicfont.cpp b/editor/import/resource_importer_dynamicfont.cpp
index 8e01adbd56..11f563a982 100644
--- a/editor/import/resource_importer_dynamicfont.cpp
+++ b/editor/import/resource_importer_dynamicfont.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,12 +30,12 @@
#include "resource_importer_dynamicfont.h"
-#include "dynamicfont_import_settings.h"
-
#include "core/io/file_access.h"
#include "core/io/resource_saver.h"
+#include "dynamicfont_import_settings.h"
#include "editor/editor_node.h"
-#include "modules/modules_enabled.gen.h"
+
+#include "modules/modules_enabled.gen.h" // For freetype.
String ResourceImporterDynamicFont::get_importer_name() const {
return "font_data_dynamic";
@@ -66,7 +66,7 @@ String ResourceImporterDynamicFont::get_resource_type() const {
return "FontData";
}
-bool ResourceImporterDynamicFont::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterDynamicFont::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
if (p_option == "msdf_pixel_range" && !bool(p_options["multichannel_signed_distance_field"])) {
return false;
}
@@ -94,7 +94,7 @@ String ResourceImporterDynamicFont::get_preset_name(int p_idx) const {
}
}
-void ResourceImporterDynamicFont::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterDynamicFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
bool msdf = p_preset == PRESET_MSDF;
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "antialiased"), true));
@@ -107,6 +107,7 @@ void ResourceImporterDynamicFont::get_import_options(List<ImportOption> *r_optio
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides"), Dictionary()));
r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/char_ranges"), Vector<String>()));
r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/glyph_ranges"), Vector<String>()));
@@ -174,6 +175,7 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str
bool msdf = p_options["multichannel_signed_distance_field"];
int px_range = p_options["msdf_pixel_range"];
int px_size = p_options["msdf_size"];
+ Dictionary ot_ov = p_options["opentype_feature_overrides"];
bool autohinter = p_options["force_autohinter"];
int hinting = p_options["hinting"];
@@ -190,6 +192,7 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str
font->set_multichannel_signed_distance_field(msdf);
font->set_msdf_pixel_range(px_range);
font->set_msdf_size(px_size);
+ font->set_opentype_feature_overrides(ot_ov);
font->set_fixed_size(0);
font->set_force_autohinter(autohinter);
font->set_hinting((TextServer::Hinting)hinting);
diff --git a/editor/import/resource_importer_dynamicfont.h b/editor/import/resource_importer_dynamicfont.h
index 52f256ab96..a55d639e10 100644
--- a/editor/import/resource_importer_dynamicfont.h
+++ b/editor/import/resource_importer_dynamicfont.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,8 +57,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
bool has_advanced_options() const override;
void show_advanced_options(const String &p_path) override;
diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp
index 2dea359188..e6a822d827 100644
--- a/editor/import/resource_importer_image.cpp
+++ b/editor/import/resource_importer_image.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,7 +55,7 @@ String ResourceImporterImage::get_resource_type() const {
return "Image";
}
-bool ResourceImporterImage::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterImage::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
@@ -67,7 +67,7 @@ String ResourceImporterImage::get_preset_name(int p_idx) const {
return String();
}
-void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterImage::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
}
Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h
index 7c8d5e228e..81aedc91e8 100644
--- a/editor/import/resource_importer_image.h
+++ b/editor/import/resource_importer_image.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,8 +47,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp
index 997280d1dd..0a15284ef5 100644
--- a/editor/import/resource_importer_imagefont.cpp
+++ b/editor/import/resource_importer_imagefont.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,11 +55,11 @@ String ResourceImporterImageFont::get_resource_type() const {
return "FontData";
}
-bool ResourceImporterImageFont::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterImageFont::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
-void ResourceImporterImageFont::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterImageFont::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "character_ranges"), Vector<String>()));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "columns"), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "rows"), 1));
diff --git a/editor/import/resource_importer_imagefont.h b/editor/import/resource_importer_imagefont.h
index 9b2b38596f..c1116d5a83 100644
--- a/editor/import/resource_importer_imagefont.h
+++ b/editor/import/resource_importer_imagefont.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,8 +47,8 @@ public:
virtual String get_save_extension() const override;
virtual String get_resource_type() const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index d5bb21443c..7ca61e83e7 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -118,7 +118,7 @@ String ResourceImporterLayeredTexture::get_resource_type() const {
ERR_FAIL_V(String());
}
-bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
if (p_option == "compress/lossy_quality" && p_options.has("compress/mode")) {
return int(p_options["compress/mode"]) == COMPRESS_LOSSY;
}
@@ -133,7 +133,7 @@ String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
return "";
}
-void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterLayeredTexture::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless (PNG),Lossy (WebP),Video RAM (S3TC/ETC/BPTC),Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
@@ -392,7 +392,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_s3tc");
if (can_bptc) {
- formats_imported.push_back("bptc"); //needs to be aded anyway
+ formats_imported.push_back("bptc"); // Needs to be added anyway.
}
bool can_compress_hdr = hdr_compression > 0;
@@ -450,12 +450,6 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
formats_imported.push_back("etc2");
}
- if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) {
- _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true);
- r_platform_variants->push_back("pvrtc");
- formats_imported.push_back("pvrtc");
- }
-
if (!ok_on_pc) {
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.");
}
@@ -481,7 +475,6 @@ const char *ResourceImporterLayeredTexture::compression_formats[] = {
"s3tc",
"etc",
"etc2",
- "pvrtc",
nullptr
};
String ResourceImporterLayeredTexture::get_import_settings_string() const {
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 86e9c5bde8..ee8e7dc615 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -84,15 +84,13 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
void _save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2);
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
- void update_imports();
-
virtual bool are_import_settings_valid(const String &p_path) const override;
virtual String get_import_settings_string() const override;
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 34bc0a7d8d..96645665aa 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,10 +32,10 @@
#include "core/io/file_access.h"
#include "core/io/resource_saver.h"
-#include "editor/import/scene_importer_mesh.h"
-#include "editor/import/scene_importer_mesh_node_3d.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/node_3d.h"
+#include "scene/resources/importer_mesh.h"
#include "scene/resources/mesh.h"
#include "scene/resources/surface_tool.h"
@@ -235,7 +235,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
while (l.length() && l[l.length() - 1] == '\\') {
String add = f->get_line().strip_edges();
l += add;
- if (add == String()) {
+ if (add.is_empty()) {
break;
}
}
@@ -301,7 +301,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
surf_tool->set_normal(normals[norm]);
}
- if (face[idx].size() >= 2 && face[idx][1] != String()) {
+ if (face[idx].size() >= 2 && !face[idx][1].is_empty()) {
int uv = face[idx][1].to_int() - 1;
if (uv < 0) {
uv += uvs.size() + 1;
@@ -363,9 +363,9 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
mesh = surf_tool->commit(mesh, mesh_flags);
- if (current_material != String()) {
+ if (!current_material.is_empty()) {
mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename());
- } else if (current_group != String()) {
+ } else if (!current_group.is_empty()) {
mesh->surface_set_name(mesh->get_surface_count() - 1, current_group);
}
@@ -405,11 +405,11 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
current_material_library = l.replace("mtllib", "").strip_edges();
if (!material_map.has(current_material_library)) {
Map<String, Ref<StandardMaterial3D>> lib;
- Error err = _parse_material_library(current_material_library, lib, r_missing_deps);
- if (err == ERR_CANT_OPEN) {
- String dir = p_path.get_base_dir();
- err = _parse_material_library(dir.plus_file(current_material_library), lib, r_missing_deps);
+ String lib_path = current_material_library;
+ if (lib_path.is_relative_path()) {
+ lib_path = p_path.get_base_dir().plus_file(current_material_library);
}
+ Error err = _parse_material_library(lib_path, lib, r_missing_deps);
if (err == OK) {
material_map[current_material_library] = lib;
}
@@ -424,7 +424,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
return OK;
}
-Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
List<Ref<Mesh>> meshes;
Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, false, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
@@ -439,16 +439,16 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
Node3D *scene = memnew(Node3D);
for (const Ref<Mesh> &m : meshes) {
- Ref<EditorSceneImporterMesh> mesh;
+ Ref<ImporterMesh> mesh;
mesh.instantiate();
for (int i = 0; i < m->get_surface_count(); i++) {
mesh->add_surface(m->surface_get_primitive_type(i), m->surface_get_arrays(i), Array(), Dictionary(), m->surface_get_material(i));
}
- EditorSceneImporterMeshNode3D *mi = memnew(EditorSceneImporterMeshNode3D);
+ ImporterMeshInstance3D *mi = memnew(ImporterMeshInstance3D);
mi->set_mesh(mesh);
mi->set_name(m->get_name());
- scene->add_child(mi);
+ scene->add_child(mi, true);
mi->set_owner(scene);
}
@@ -459,7 +459,7 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
return scene;
}
-Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
return Ref<Animation>();
}
@@ -504,14 +504,14 @@ String ResourceImporterOBJ::get_preset_name(int p_idx) const {
return "";
}
-void ResourceImporterOBJ::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterOBJ::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "scale_mesh"), Vector3(1, 1, 1)));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "offset_mesh"), Vector3(0, 0, 0)));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "optimize_mesh"), true));
}
-bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterOBJ::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index 414e0c1fe6..d7e3f0209d 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -33,14 +33,14 @@
#include "resource_importer_scene.h"
-class EditorOBJImporter : public EditorSceneImporter {
- GDCLASS(EditorOBJImporter, EditorSceneImporter);
+class EditorOBJImporter : public EditorSceneFormatImporter {
+ GDCLASS(EditorOBJImporter, EditorSceneFormatImporter);
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
EditorOBJImporter();
};
@@ -59,11 +59,14 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
+ // Threaded import can currently cause deadlocks, see GH-48265.
+ virtual bool can_import_threaded() const override { return false; }
+
ResourceImporterOBJ();
};
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 9f617be4ee..af9a2f9ebe 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,13 +30,13 @@
#include "resource_importer_scene.h"
+#include "core/error/error_macros.h"
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
-#include "editor/import/editor_importer_bake_reset.h"
#include "editor/import/scene_import_settings.h"
-#include "editor/import/scene_importer_mesh_node_3d.h"
#include "scene/3d/area_3d.h"
#include "scene/3d/collision_shape_3d.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/3d/physics_body_3d.h"
@@ -44,14 +44,15 @@
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/box_shape_3d.h"
+#include "scene/resources/importer_mesh.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/resource_format_text.h"
#include "scene/resources/separation_ray_shape_3d.h"
#include "scene/resources/sphere_shape_3d.h"
#include "scene/resources/surface_tool.h"
-#include "scene/resources/world_margin_shape_3d.h"
+#include "scene/resources/world_boundary_shape_3d.h"
-uint32_t EditorSceneImporter::get_import_flags() const {
+uint32_t EditorSceneFormatImporter::get_import_flags() const {
int ret;
if (GDVIRTUAL_CALL(_get_import_flags, ret)) {
return ret;
@@ -60,7 +61,7 @@ uint32_t EditorSceneImporter::get_import_flags() const {
ERR_FAIL_V(0);
}
-void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
+void EditorSceneFormatImporter::get_extensions(List<String> *r_extensions) const {
Vector<String> arr;
if (GDVIRTUAL_CALL(_get_extensions, arr)) {
for (int i = 0; i < arr.size(); i++) {
@@ -72,43 +73,49 @@ void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
ERR_FAIL();
}
-Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
- Object *ret;
- if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, p_bake_fps, ret)) {
+Node *EditorSceneFormatImporter::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+ Dictionary options_dict;
+ for (const KeyValue<StringName, Variant> &elem : p_options) {
+ options_dict[elem.key] = elem.value;
+ }
+ Object *ret = nullptr;
+ if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, options_dict, p_bake_fps, ret)) {
return Object::cast_to<Node>(ret);
}
ERR_FAIL_V(nullptr);
}
-Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporter::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
+ Dictionary options_dict;
+ for (const KeyValue<StringName, Variant> &elem : p_options) {
+ options_dict[elem.key] = elem.value;
+ }
Ref<Animation> ret;
- if (GDVIRTUAL_CALL(_import_animation, p_path, p_flags, p_bake_fps, ret)) {
+ if (GDVIRTUAL_CALL(_import_animation, p_path, p_flags, options_dict, p_bake_fps, ret)) {
return ret;
}
ERR_FAIL_V(nullptr);
}
-//for documenters, these functions are useful when an importer calls an external conversion helper (like, fbx2gltf),
-//and you want to load the resulting file
-
-Node *EditorSceneImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
- return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this, p_path, p_flags, p_bake_fps);
+void EditorSceneFormatImporter::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
+ GDVIRTUAL_CALL(_get_import_options, p_path);
}
-Ref<Animation> EditorSceneImporter::import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
- return ResourceImporterScene::get_singleton()->import_animation_from_other_importer(this, p_path, p_flags, p_bake_fps);
+Variant EditorSceneFormatImporter::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) {
+ Variant ret;
+ GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, ret);
+ return ret;
}
-void EditorSceneImporter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_scene_from_other_importer);
- ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_animation_from_other_importer);
-
+void EditorSceneFormatImporter::_bind_methods() {
GDVIRTUAL_BIND(_get_import_flags);
GDVIRTUAL_BIND(_get_extensions);
- GDVIRTUAL_BIND(_import_scene, "path", "flags", "bake_fps");
- GDVIRTUAL_BIND(_import_animation, "path", "flags", "bake_fps");
+ GDVIRTUAL_BIND(_import_scene, "path", "flags", "options", "bake_fps");
+ GDVIRTUAL_BIND(_import_animation, "path", "flags", "options", "bake_fps");
+ GDVIRTUAL_BIND(_get_import_options, "path");
+ GDVIRTUAL_BIND(_get_option_visibility, "path", "option");
BIND_CONSTANT(IMPORT_SCENE);
BIND_CONSTANT(IMPORT_ANIMATION);
@@ -143,6 +150,105 @@ void EditorScenePostImport::init(const String &p_source_file) {
EditorScenePostImport::EditorScenePostImport() {
}
+///////////////////////////////////////////////////////
+
+Variant EditorScenePostImportPlugin::get_option_value(const StringName &p_name) const {
+ ERR_FAIL_COND_V_MSG(current_options == nullptr && current_options_dict == nullptr, Variant(), "get_option_value called from a function where option values are not available.");
+ ERR_FAIL_COND_V_MSG(current_options && !current_options->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
+ ERR_FAIL_COND_V_MSG(current_options_dict && !current_options_dict->has(p_name), Variant(), "get_option_value called with unexisting option argument: " + String(p_name));
+ if (current_options) {
+ (*current_options)[p_name];
+ }
+ if (current_options_dict) {
+ (*current_options_dict)[p_name];
+ }
+ return Variant();
+}
+void EditorScenePostImportPlugin::add_import_option(const String &p_name, Variant p_default_value) {
+ ERR_FAIL_COND_MSG(current_option_list == nullptr, "add_import_option() can only be called from get_import_options()");
+ add_import_option_advanced(p_default_value.get_type(), p_name, p_default_value);
+}
+void EditorScenePostImportPlugin::add_import_option_advanced(Variant::Type p_type, const String &p_name, Variant p_default_value, PropertyHint p_hint, const String &p_hint_string, int p_usage_flags) {
+ ERR_FAIL_COND_MSG(current_option_list == nullptr, "add_import_option_advanced() can only be called from get_import_options()");
+ current_option_list->push_back(ResourceImporter::ImportOption(PropertyInfo(p_type, p_name, p_hint, p_hint_string, p_usage_flags), p_default_value));
+}
+
+void EditorScenePostImportPlugin::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
+ current_option_list = r_options;
+ GDVIRTUAL_CALL(_get_internal_import_options, p_category);
+ current_option_list = nullptr;
+}
+Variant EditorScenePostImportPlugin::get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const {
+ current_options = &p_options;
+ Variant ret;
+ GDVIRTUAL_CALL(_get_internal_option_visibility, p_category, p_option, ret);
+ current_options = nullptr;
+ return ret;
+}
+Variant EditorScenePostImportPlugin::get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const {
+ current_options = &p_options;
+ Variant ret;
+ GDVIRTUAL_CALL(_get_internal_option_update_view_required, p_category, p_option, ret);
+ current_options = nullptr;
+ return ret;
+}
+
+void EditorScenePostImportPlugin::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, RES p_resource, const Dictionary &p_options) {
+ current_options_dict = &p_options;
+ GDVIRTUAL_CALL(_internal_process, p_category, p_base_scene, p_node, p_resource);
+ current_options_dict = nullptr;
+}
+
+void EditorScenePostImportPlugin::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
+ current_option_list = r_options;
+ GDVIRTUAL_CALL(_get_import_options, p_path);
+ current_option_list = nullptr;
+}
+Variant EditorScenePostImportPlugin::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
+ current_options = &p_options;
+ Variant ret;
+ GDVIRTUAL_CALL(_get_option_visibility, p_path, p_option, ret);
+ current_options = nullptr;
+ return ret;
+}
+
+void EditorScenePostImportPlugin::pre_process(Node *p_scene, const Map<StringName, Variant> &p_options) {
+ current_options = &p_options;
+ GDVIRTUAL_CALL(_pre_process, p_scene);
+ current_options = nullptr;
+}
+void EditorScenePostImportPlugin::post_process(Node *p_scene, const Map<StringName, Variant> &p_options) {
+ current_options = &p_options;
+ GDVIRTUAL_CALL(_post_process, p_scene);
+ current_options = nullptr;
+}
+
+void EditorScenePostImportPlugin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_option_value", "name"), &EditorScenePostImportPlugin::get_option_value);
+
+ ClassDB::bind_method(D_METHOD("add_import_option", "name", "value"), &EditorScenePostImportPlugin::add_import_option);
+ ClassDB::bind_method(D_METHOD("add_import_option_advanced", "type", "name", "default_value", "hint", "hint_string", "usage_flags"), &EditorScenePostImportPlugin::add_import_option_advanced, DEFVAL(PROPERTY_HINT_NONE), DEFVAL(""), DEFVAL(PROPERTY_USAGE_DEFAULT));
+
+ GDVIRTUAL_BIND(_get_internal_import_options, "category");
+ GDVIRTUAL_BIND(_get_internal_option_visibility, "category", "option");
+ GDVIRTUAL_BIND(_get_internal_option_update_view_required, "category", "option");
+ GDVIRTUAL_BIND(_internal_process, "category", "base_node", "node", "resource");
+ GDVIRTUAL_BIND(_get_import_options, "path");
+ GDVIRTUAL_BIND(_get_option_visibility, "path", "option");
+ GDVIRTUAL_BIND(_pre_process, "scene");
+ GDVIRTUAL_BIND(_post_process, "scene");
+
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_NODE);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MESH);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MATERIAL);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE);
+ BIND_ENUM_CONSTANT(INTERNAL_IMPORT_CATEGORY_MAX);
+}
+
+/////////////////////////////////////////////////////////
+
String ResourceImporterScene::get_importer_name() const {
return "scene";
}
@@ -152,7 +258,7 @@ String ResourceImporterScene::get_visible_name() const {
}
void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const {
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
+ for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
E->get()->get_extensions(p_extensions);
}
}
@@ -169,7 +275,7 @@ int ResourceImporterScene::get_format_version() const {
return 1;
}
-bool ResourceImporterScene::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterScene::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
if (p_option.begins_with("animation/")) {
if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
return false;
@@ -180,6 +286,20 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const
return false;
}
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ Variant ret = post_importer_plugins.write[i]->get_option_visibility(p_path, p_option, p_options);
+ if (ret.get_type() == Variant::BOOL) {
+ return ret;
+ }
+ }
+
+ for (Ref<EditorSceneFormatImporter> importer : importers) {
+ Variant ret = importer->get_option_visibility(p_path, p_option, p_options);
+ if (ret.get_type() == Variant::BOOL) {
+ return ret;
+ }
+ }
+
return true;
}
@@ -233,8 +353,9 @@ static String _fixstr(const String &p_what, const String &p_str) {
return what;
}
-static void _pre_gen_shape_list(Ref<EditorSceneImporterMesh> &mesh, Vector<Ref<Shape3D>> &r_shape_list, bool p_convex) {
+static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r_shape_list, bool p_convex) {
ERR_FAIL_NULL_MSG(mesh, "Cannot generate shape list with null mesh value");
+ ERR_FAIL_NULL_MSG(mesh->get_mesh(), "Cannot generate shape list with null mesh value");
if (!p_convex) {
Ref<Shape3D> shape = mesh->create_trimesh_shape();
r_shape_list.push_back(shape);
@@ -249,16 +370,17 @@ static void _pre_gen_shape_list(Ref<EditorSceneImporterMesh> &mesh, Vector<Ref<S
}
}
-Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> &collision_map) {
- // children first
+Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames) {
+ // Children first.
for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *r = _pre_fix_node(p_node->get_child(i), p_root, collision_map);
+ Node *r = _pre_fix_node(p_node->get_child(i), p_root, collision_map, r_node_renames);
if (!r) {
- i--; //was erased
+ i--; // Was erased.
}
}
String name = p_node->get_name();
+ NodePath original_path = p_root->get_path_to(p_node); // Used to detect renames due to import hints.
bool isroot = p_node == p_root;
@@ -267,10 +389,10 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
return nullptr;
}
- if (Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
- Ref<EditorSceneImporterMesh> m = mi->get_mesh();
+ Ref<ImporterMesh> m = mi->get_mesh();
if (m.is_valid()) {
for (int i = 0; i < m->get_surface_count(); i++) {
@@ -293,14 +415,21 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
}
if (Object::cast_to<AnimationPlayer>(p_node)) {
- //remove animations referencing non-importable nodes
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
+ // Node paths in animation tracks are relative to the following path (this is used to fix node paths below).
+ Node *ap_root = ap->get_node(ap->get_root());
+ NodePath path_prefix = p_root->get_path_to(ap_root);
+
+ bool nodes_were_renamed = r_node_renames.size() != 0;
+
List<StringName> anims;
ap->get_animation_list(&anims);
for (const StringName &E : anims) {
Ref<Animation> anim = ap->get_animation(E);
ERR_CONTINUE(anim.is_null());
+
+ // Remove animation tracks referencing non-importable nodes.
for (int i = 0; i < anim->get_track_count(); i++) {
NodePath path = anim->track_get_path(i);
@@ -314,12 +443,33 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
}
}
+ // Fix node paths in animations, in case nodes were renamed earlier due to import hints.
+ if (nodes_were_renamed) {
+ for (int i = 0; i < anim->get_track_count(); i++) {
+ NodePath path = anim->track_get_path(i);
+ // Convert track path to absolute node path without subnames (some manual work because we are not in the scene tree).
+ Vector<StringName> absolute_path_names = path_prefix.get_names();
+ absolute_path_names.append_array(path.get_names());
+ NodePath absolute_path(absolute_path_names, false);
+ absolute_path.simplify();
+ // Fix paths to renamed nodes.
+ for (const Pair<NodePath, Node *> &F : r_node_renames) {
+ if (F.first == absolute_path) {
+ NodePath new_path(ap_root->get_path_to(F.second).get_names(), path.get_subnames(), false);
+ print_verbose(vformat("Fix: Correcting node path in animation track: %s should be %s", path, new_path));
+ anim->track_set_path(i, new_path);
+ break; // Only one match is possible.
+ }
+ }
+ }
+ }
+
String animname = E;
const int loop_string_count = 3;
- static const char *loop_strings[loop_string_count] = { "loops", "loop", "cycle" };
+ static const char *loop_strings[loop_string_count] = { "loop_mode", "loop", "cycle" };
for (int i = 0; i < loop_string_count; i++) {
if (_teststr(animname, loop_strings[i])) {
- anim->set_loop(true);
+ anim->set_loop_mode(Animation::LoopMode::LOOP_LINEAR);
animname = _fixstr(animname, loop_strings[i]);
ap->rename_animation(E, animname);
}
@@ -331,13 +481,22 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
if (isroot) {
return p_node;
}
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+
+ String fixed_name;
+ if (_teststr(name, "colonly")) {
+ fixed_name = _fixstr(name, "colonly");
+ } else if (_teststr(name, "convcolonly")) {
+ fixed_name = _fixstr(name, "convcolonly");
+ }
+
+ ERR_FAIL_COND_V(fixed_name.is_empty(), nullptr);
+
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
if (mi) {
- Ref<EditorSceneImporterMesh> mesh = mi->get_mesh();
+ Ref<ImporterMesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
Vector<Ref<Shape3D>> shapes;
- String fixed_name;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
} else if (_teststr(name, "colonly")) {
@@ -348,14 +507,6 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
collision_map[mesh] = shapes;
}
- if (_teststr(name, "colonly")) {
- fixed_name = _fixstr(name, "colonly");
- } else if (_teststr(name, "convcolonly")) {
- fixed_name = _fixstr(name, "convcolonly");
- }
-
- ERR_FAIL_COND_V(fixed_name == String(), nullptr);
-
if (shapes.size()) {
StaticBody3D *col = memnew(StaticBody3D);
col->set_transform(mi->get_transform());
@@ -371,11 +522,11 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
} else if (p_node->has_meta("empty_draw_type")) {
String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
StaticBody3D *sb = memnew(StaticBody3D);
- sb->set_name(_fixstr(name, "colonly"));
+ sb->set_name(fixed_name);
Object::cast_to<Node3D>(sb)->set_transform(Object::cast_to<Node3D>(p_node)->get_transform());
p_node->replace_by(sb);
memdelete(p_node);
- p_node = nullptr;
+ p_node = sb;
CollisionShape3D *colshape = memnew(CollisionShape3D);
if (empty_draw_type == "CUBE") {
BoxShape3D *boxShape = memnew(BoxShape3D);
@@ -387,24 +538,24 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
colshape->set_shape(rayShape);
Object::cast_to<Node3D>(sb)->rotate_x(Math_PI / 2);
} else if (empty_draw_type == "IMAGE") {
- WorldMarginShape3D *world_margin_shape = memnew(WorldMarginShape3D);
- colshape->set_shape(world_margin_shape);
+ WorldBoundaryShape3D *world_boundary_shape = memnew(WorldBoundaryShape3D);
+ colshape->set_shape(world_boundary_shape);
} else {
SphereShape3D *sphereShape = memnew(SphereShape3D);
sphereShape->set_radius(1);
colshape->set_shape(sphereShape);
}
- sb->add_child(colshape);
+ sb->add_child(colshape, true);
colshape->set_owner(sb->get_owner());
}
- } else if (_teststr(name, "rigid") && Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
+ } else if (_teststr(name, "rigid") && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
if (isroot) {
return p_node;
}
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
- Ref<EditorSceneImporterMesh> mesh = mi->get_mesh();
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
+ Ref<ImporterMesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
Vector<Ref<Shape3D>> shapes;
@@ -414,22 +565,22 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
_pre_gen_shape_list(mesh, shapes, true);
}
- RigidBody3D *rigid_body = memnew(RigidBody3D);
- rigid_body->set_name(_fixstr(name, "rigid"));
+ RigidDynamicBody3D *rigid_body = memnew(RigidDynamicBody3D);
+ rigid_body->set_name(_fixstr(name, "rigid_body"));
p_node->replace_by(rigid_body);
rigid_body->set_transform(mi->get_transform());
p_node = rigid_body;
mi->set_transform(Transform3D());
- rigid_body->add_child(mi);
+ rigid_body->add_child(mi, true);
mi->set_owner(rigid_body->get_owner());
_add_shapes(rigid_body, shapes);
}
- } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
- Ref<EditorSceneImporterMesh> mesh = mi->get_mesh();
+ Ref<ImporterMesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
Vector<Ref<Shape3D>> shapes;
@@ -450,7 +601,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
fixed_name = _fixstr(name, "convcol");
}
- if (fixed_name != String()) {
+ if (!fixed_name.is_empty()) {
if (mi->get_parent() && !mi->get_parent()->has_node(fixed_name)) {
mi->set_name(fixed_name);
}
@@ -458,21 +609,21 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
if (shapes.size()) {
StaticBody3D *col = memnew(StaticBody3D);
- mi->add_child(col);
+ mi->add_child(col, true);
col->set_owner(mi->get_owner());
_add_shapes(col, shapes);
}
}
- } else if (_teststr(name, "navmesh") && Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
+ } else if (_teststr(name, "navmesh") && Object::cast_to<ImporterMeshInstance3D>(p_node)) {
if (isroot) {
return p_node;
}
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
- Ref<EditorSceneImporterMesh> mesh = mi->get_mesh();
+ Ref<ImporterMesh> mesh = mi->get_mesh();
ERR_FAIL_COND_V(mesh.is_null(), nullptr);
NavigationRegion3D *nmi = memnew(NavigationRegion3D);
@@ -484,12 +635,12 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
memdelete(p_node);
p_node = nmi;
- } else if (Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
+ } else if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
//last attempt, maybe collision inside the mesh data
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
- Ref<EditorSceneImporterMesh> mesh = mi->get_mesh();
+ Ref<ImporterMesh> mesh = mi->get_mesh();
if (!mesh.is_null()) {
Vector<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
@@ -506,7 +657,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
if (shapes.size()) {
StaticBody3D *col = memnew(StaticBody3D);
- p_node->add_child(col);
+ p_node->add_child(col, true);
col->set_owner(p_node->get_owner());
_add_shapes(col, shapes);
@@ -514,10 +665,18 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
}
}
+ if (p_node) {
+ NodePath new_path = p_root->get_path_to(p_node);
+ if (new_path != original_path) {
+ print_verbose(vformat("Fix: Renamed %s to %s", original_path, new_path));
+ r_node_renames.push_back({ original_path, p_node });
+ }
+ }
+
return p_node;
}
-Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
+Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
// children first
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps);
@@ -546,10 +705,30 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
return nullptr;
}
- if (Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ {
+ ObjectID node_id = p_node->get_instance_id();
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE, p_root, p_node, RES(), node_settings);
+ if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
+ break;
+ }
+ }
+ }
+
+ if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
+ ObjectID node_id = p_node->get_instance_id();
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE, p_root, p_node, RES(), node_settings);
+ if (ObjectDB::get_instance(node_id) == nullptr) { //may have been erased, so do not continue
+ break;
+ }
+ }
+ }
+
+ if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
- Ref<EditorSceneImporterMesh> m = mi->get_mesh();
+ Ref<ImporterMesh> m = mi->get_mesh();
if (m.is_valid()) {
if (!r_scanned_meshes.has(m)) {
@@ -563,8 +742,13 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
mat_id = mat->get_name();
}
- if (mat_id != String() && p_material_data.has(mat_id)) {
+ if (!mat_id.is_empty() && p_material_data.has(mat_id)) {
Dictionary matdata = p_material_data[mat_id];
+
+ for (int j = 0; j < post_importer_plugins.size(); j++) {
+ post_importer_plugins.write[j]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL, p_root, p_node, mat, matdata);
+ }
+
if (matdata.has("use_external/enabled") && bool(matdata["use_external/enabled"]) && matdata.has("use_external/path")) {
String path = matdata["use_external/path"];
Ref<Material> external_mat = ResourceLoader::load(path);
@@ -616,19 +800,19 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
switch (mesh_physics_mode) {
case MESH_PHYSICS_MESH_AND_STATIC_COLLIDER: {
StaticBody3D *col = memnew(StaticBody3D);
- p_node->add_child(col);
+ p_node->add_child(col, true);
col->set_owner(p_node->get_owner());
col->set_transform(get_collision_shapes_transform(node_settings));
base = col;
} break;
case MESH_PHYSICS_RIGID_BODY_AND_MESH: {
- RigidBody3D *rigid_body = memnew(RigidBody3D);
+ RigidDynamicBody3D *rigid_body = memnew(RigidDynamicBody3D);
rigid_body->set_name(p_node->get_name());
p_node->replace_by(rigid_body);
rigid_body->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
p_node = rigid_body;
mi->set_transform(Transform3D());
- rigid_body->add_child(mi);
+ rigid_body->add_child(mi, true);
mi->set_owner(rigid_body->get_owner());
base = rigid_body;
} break;
@@ -657,7 +841,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
for (const Ref<Shape3D> &E : shapes) {
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E);
- base->add_child(cshape);
+ base->add_child(cshape, true);
cshape->set_owner(base->get_owner());
idx++;
@@ -669,10 +853,10 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
}
//navmesh (node may have changed type above)
- if (Object::cast_to<EditorSceneImporterMeshNode3D>(p_node)) {
- EditorSceneImporterMeshNode3D *mi = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ if (Object::cast_to<ImporterMeshInstance3D>(p_node)) {
+ ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
- Ref<EditorSceneImporterMesh> m = mi->get_mesh();
+ Ref<ImporterMesh> m = mi->get_mesh();
if (m.is_valid()) {
if (node_settings.has("generate/navmesh")) {
@@ -690,7 +874,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
memdelete(p_node);
p_node = nmi;
} else {
- mi->add_child(nmi);
+ mi->add_child(nmi, true);
nmi->set_owner(mi->get_owner());
}
}
@@ -714,6 +898,10 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
}
}
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, RES(), node_settings);
+ }
+
bool use_optimizer = node_settings["optimizer/enabled"];
float anim_optimizer_linerr = node_settings["optimizer/max_linear_error"];
float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"];
@@ -731,7 +919,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
String name = node_settings["clip_" + itos(i + 1) + "/name"];
int from_frame = node_settings["clip_" + itos(i + 1) + "/start_frame"];
int end_frame = node_settings["clip_" + itos(i + 1) + "/end_frame"];
- bool loop = node_settings["clip_" + itos(i + 1) + "/loops"];
+ Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)node_settings["clip_" + itos(i + 1) + "/loop_mode"]);
bool save_to_file = node_settings["clip_" + itos(i + 1) + "/save_to_file/enabled"];
bool save_to_path = node_settings["clip_" + itos(i + 1) + "/save_to_file/path"];
bool save_to_file_keep_custom = node_settings["clip_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"];
@@ -739,7 +927,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
animation_clips.push_back(name);
animation_clips.push_back(from_frame / p_animation_fps);
animation_clips.push_back(end_frame / p_animation_fps);
- animation_clips.push_back(loop);
+ animation_clips.push_back(loop_mode);
animation_clips.push_back(save_to_file);
animation_clips.push_back(save_to_path);
animation_clips.push_back(save_to_file_keep_custom);
@@ -766,7 +954,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
}
}
- anim->set_loop(anim_settings["settings/loops"]);
+ anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"]));
bool save = anim_settings["save_to_file/enabled"];
String path = anim_settings["save_to_file/path"];
bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"];
@@ -778,6 +966,48 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
}
}
}
+
+ AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = {
+ AnimationImportTracks(int(node_settings["import_tracks/position"])),
+ AnimationImportTracks(int(node_settings["import_tracks/rotation"])),
+ AnimationImportTracks(int(node_settings["import_tracks/scale"]))
+ };
+
+ if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) {
+ _optimize_track_usage(ap, import_tracks_mode);
+ }
+ }
+
+ if (post_importer_plugins.size()) {
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (const StringName &name : anims) {
+ if (p_animation_data.has(name)) {
+ Ref<Animation> anim = ap->get_animation(name);
+ Dictionary anim_settings = p_animation_data[name];
+ {
+ //fill with default values
+ List<ImportOption> iopts;
+ get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts);
+ for (const ImportOption &F : iopts) {
+ if (!anim_settings.has(F.option.name)) {
+ anim_settings[F.option.name] = F.default_value;
+ }
+ }
+ }
+
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION, p_root, p_node, anim, node_settings);
+ }
+ }
+ }
+ }
+
+ bool use_compression = node_settings["compression/enabled"];
+ int anim_compression_page_size = node_settings["compression/page_size"];
+
+ if (use_compression) {
+ _compress_animations(ap, anim_compression_page_size);
}
}
@@ -798,7 +1028,7 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani
old_anim->copy_track(i, anim);
}
}
- anim->set_loop(old_anim->has_loop());
+ anim->set_loop_mode(old_anim->get_loop_mode());
}
}
@@ -817,6 +1047,7 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani
void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all) {
if (!anim->has_animation("default")) {
+ ERR_FAIL_COND_MSG(p_clips.size() > 0, "To create clips, animations must be named \"default\".");
return;
}
@@ -826,7 +1057,7 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_
String name = p_clips[i];
float from = p_clips[i + 1];
float to = p_clips[i + 2];
- bool loop = p_clips[i + 3];
+ Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)p_clips[i + 3]);
bool save_to_file = p_clips[i + 4];
String save_to_path = p_clips[i + 5];
bool keep_current = p_clips[i + 6];
@@ -850,44 +1081,71 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_
new_anim->track_set_path(dtrack, default_anim->track_get_path(j));
if (kt > (from + 0.01) && k > 0) {
- if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) {
- Quaternion q;
+ if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
Vector3 p;
+ default_anim->position_track_interpolate(j, from, &p);
+ new_anim->position_track_insert_key(dtrack, 0, p);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
+ Quaternion r;
+ default_anim->rotation_track_interpolate(j, from, &r);
+ new_anim->rotation_track_insert_key(dtrack, 0, r);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
Vector3 s;
- default_anim->transform_track_interpolate(j, from, &p, &q, &s);
- new_anim->transform_track_insert_key(dtrack, 0, p, q, s);
- }
- if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
+ default_anim->scale_track_interpolate(j, from, &s);
+ new_anim->scale_track_insert_key(dtrack, 0, s);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
Variant var = default_anim->value_track_interpolate(j, from);
new_anim->track_insert_key(dtrack, 0, var);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
+ float interp;
+ default_anim->blend_shape_track_interpolate(j, from, &interp);
+ new_anim->blend_shape_track_insert_key(dtrack, 0, interp);
}
}
}
- if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) {
- Quaternion q;
+ if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
Vector3 p;
+ default_anim->position_track_get_key(j, k, &p);
+ new_anim->position_track_insert_key(dtrack, kt - from, p);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
+ Quaternion r;
+ default_anim->rotation_track_get_key(j, k, &r);
+ new_anim->rotation_track_insert_key(dtrack, kt - from, r);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
Vector3 s;
- default_anim->transform_track_get_key(j, k, &p, &q, &s);
- new_anim->transform_track_insert_key(dtrack, kt - from, p, q, s);
- }
- if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
+ default_anim->scale_track_get_key(j, k, &s);
+ new_anim->scale_track_insert_key(dtrack, kt - from, s);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
Variant var = default_anim->track_get_key_value(j, k);
new_anim->track_insert_key(dtrack, kt - from, var);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
+ float interp;
+ default_anim->blend_shape_track_get_key(j, k, &interp);
+ new_anim->blend_shape_track_insert_key(dtrack, kt - from, interp);
}
}
if (dtrack != -1 && kt >= to) {
- if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) {
- Quaternion q;
+ if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
Vector3 p;
+ default_anim->position_track_interpolate(j, to, &p);
+ new_anim->position_track_insert_key(dtrack, to - from, p);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
+ Quaternion r;
+ default_anim->rotation_track_interpolate(j, to, &r);
+ new_anim->rotation_track_insert_key(dtrack, to - from, r);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
Vector3 s;
- default_anim->transform_track_interpolate(j, to, &p, &q, &s);
- new_anim->transform_track_insert_key(dtrack, to - from, p, q, s);
- }
- if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
+ default_anim->scale_track_interpolate(j, to, &s);
+ new_anim->scale_track_insert_key(dtrack, to - from, s);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
Variant var = default_anim->value_track_interpolate(j, to);
new_anim->track_insert_key(dtrack, to - from, var);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
+ float interp;
+ default_anim->blend_shape_track_interpolate(j, to, &interp);
+ new_anim->blend_shape_track_insert_key(dtrack, to - from, interp);
}
}
}
@@ -896,25 +1154,40 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_
new_anim->add_track(default_anim->track_get_type(j));
dtrack = new_anim->get_track_count() - 1;
new_anim->track_set_path(dtrack, default_anim->track_get_path(j));
- if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM3D) {
- Quaternion q;
+ if (default_anim->track_get_type(j) == Animation::TYPE_POSITION_3D) {
Vector3 p;
+ default_anim->position_track_interpolate(j, from, &p);
+ new_anim->position_track_insert_key(dtrack, 0, p);
+ default_anim->position_track_interpolate(j, to, &p);
+ new_anim->position_track_insert_key(dtrack, to - from, p);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_ROTATION_3D) {
+ Quaternion r;
+ default_anim->rotation_track_interpolate(j, from, &r);
+ new_anim->rotation_track_insert_key(dtrack, 0, r);
+ default_anim->rotation_track_interpolate(j, to, &r);
+ new_anim->rotation_track_insert_key(dtrack, to - from, r);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_SCALE_3D) {
Vector3 s;
- default_anim->transform_track_interpolate(j, from, &p, &q, &s);
- new_anim->transform_track_insert_key(dtrack, 0, p, q, s);
- default_anim->transform_track_interpolate(j, to, &p, &q, &s);
- new_anim->transform_track_insert_key(dtrack, to - from, p, q, s);
- }
- if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
+ default_anim->scale_track_interpolate(j, from, &s);
+ new_anim->scale_track_insert_key(dtrack, 0, s);
+ default_anim->scale_track_interpolate(j, to, &s);
+ new_anim->scale_track_insert_key(dtrack, to - from, s);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_VALUE) {
Variant var = default_anim->value_track_interpolate(j, from);
new_anim->track_insert_key(dtrack, 0, var);
Variant to_var = default_anim->value_track_interpolate(j, to);
new_anim->track_insert_key(dtrack, to - from, to_var);
+ } else if (default_anim->track_get_type(j) == Animation::TYPE_BLEND_SHAPE) {
+ float interp;
+ default_anim->blend_shape_track_interpolate(j, from, &interp);
+ new_anim->blend_shape_track_insert_key(dtrack, 0, interp);
+ default_anim->blend_shape_track_interpolate(j, to, &interp);
+ new_anim->blend_shape_track_insert_key(dtrack, to - from, interp);
}
}
}
- new_anim->set_loop(loop);
+ new_anim->set_loop_mode(loop_mode);
new_anim->set_length(to - from);
anim->add_animation(name, new_anim);
@@ -936,6 +1209,15 @@ void ResourceImporterScene::_optimize_animations(AnimationPlayer *anim, float p_
}
}
+void ResourceImporterScene::_compress_animations(AnimationPlayer *anim, int p_page_size_kb) {
+ List<StringName> anim_names;
+ anim->get_animation_list(&anim_names);
+ for (const StringName &E : anim_names) {
+ Ref<Animation> a = anim->get_animation(E);
+ a->compress(p_page_size_kb * 1024);
+ }
+}
+
void ResourceImporterScene::get_internal_import_options(InternalImportCategory p_category, List<ImportOption> *r_options) const {
switch (p_category) {
case INTERNAL_IMPORT_CATEGORY_NODE: {
@@ -980,13 +1262,15 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/shadow_meshes", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lightmap_uv", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lods", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_split_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 25.0f));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "lods/normal_merge_angle", PROPERTY_HINT_RANGE, "0,180,0.1,degrees"), 60.0f));
} break;
case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "use_external/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "use_external/path", PROPERTY_HINT_FILE, "*.material,*.res,*.tres"), ""));
} break;
case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
- r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "settings/loops"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "settings/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/keep_custom_tracks"), ""));
@@ -997,13 +1281,18 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_linear_error"), 0.05));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_angular_error"), 0.01));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "optimizer/max_angle"), 22));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compression/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compression/page_size", PROPERTY_HINT_RANGE, "4,512,1,suffix:kb"), 8));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/position", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/rotation", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_tracks/scale", PROPERTY_HINT_ENUM, "IfPresent,IfPresentForAll,Never"), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
for (int i = 0; i < 256; i++) {
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/name"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/start_frame"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/end_frame"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/loops"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, ".res,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false));
@@ -1012,6 +1301,10 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
default: {
}
}
+
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->get_internal_import_options(EditorScenePostImportPlugin::InternalImportCategory(p_category), r_options);
+ }
}
bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const {
@@ -1059,27 +1352,28 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
if (p_option == "primitive/position" || p_option == "primitive/rotation") {
const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
return generate_physics &&
- physics_shape >= SHAPE_TYPE_BOX;
+ physics_shape >= SHAPE_TYPE_BOX;
}
if (p_option == "primitive/size") {
const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
return generate_physics &&
- physics_shape == SHAPE_TYPE_BOX;
+ physics_shape == SHAPE_TYPE_BOX;
}
if (p_option == "primitive/radius") {
const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
- return generate_physics && (physics_shape == SHAPE_TYPE_SPHERE ||
- physics_shape == SHAPE_TYPE_CYLINDER ||
- physics_shape == SHAPE_TYPE_CAPSULE);
+ return generate_physics &&
+ (physics_shape == SHAPE_TYPE_SPHERE ||
+ physics_shape == SHAPE_TYPE_CYLINDER ||
+ physics_shape == SHAPE_TYPE_CAPSULE);
}
if (p_option == "primitive/height") {
const ShapeType physics_shape = (ShapeType)p_options["physics/shape_type"].operator int();
return generate_physics &&
- (physics_shape == SHAPE_TYPE_CYLINDER ||
- physics_shape == SHAPE_TYPE_CAPSULE);
+ (physics_shape == SHAPE_TYPE_CYLINDER ||
+ physics_shape == SHAPE_TYPE_CAPSULE);
}
} break;
case INTERNAL_IMPORT_CATEGORY_MESH: {
@@ -1098,13 +1392,16 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
}
} break;
case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
- if (p_option.begins_with("animation/optimizer/") && p_option != "animation/optimizer/enabled" && !bool(p_options["animation/optimizer/enabled"])) {
+ if (p_option.begins_with("optimizer/") && p_option != "optimizer/enabled" && !bool(p_options["optimizer/enabled"])) {
+ return false;
+ }
+ if (p_option.begins_with("compression/") && p_option != "compression/enabled" && !bool(p_options["compression/enabled"])) {
return false;
}
- if (p_option.begins_with("animation/slice_")) {
- int max_slice = p_options["animation/slices/amount"];
- int slice = p_option.get_slice("/", 1).get_slice("_", 1).to_int() - 1;
+ if (p_option.begins_with("slice_")) {
+ int max_slice = p_options["slices/amount"];
+ int slice = p_option.get_slice("_", 1).to_int() - 1;
if (slice >= max_slice) {
return false;
}
@@ -1114,6 +1411,13 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
}
}
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ Variant ret = post_importer_plugins.write[i]->get_internal_option_visibility(EditorScenePostImportPlugin::InternalImportCategory(p_category), p_option, p_options);
+ if (ret.get_type() == Variant::BOOL) {
+ return ret;
+ }
+ }
+
return true;
}
@@ -1141,10 +1445,18 @@ bool ResourceImporterScene::get_internal_option_update_view_required(InternalImp
default: {
}
}
+
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ Variant ret = post_importer_plugins.write[i]->get_internal_option_update_view_required(EditorScenePostImportPlugin::InternalImportCategory(p_category), p_option, p_options);
+ if (ret.get_type() == Variant::BOOL) {
+ return ret;
+ }
+ }
+
return false;
}
-void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterScene::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "Node3D"));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), "Scene Root"));
@@ -1154,7 +1466,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
String script_ext_hint;
for (const String &E : script_extentions) {
- if (script_ext_hint != "") {
+ if (!script_ext_hint.is_empty()) {
script_ext_hint += ",";
}
script_ext_hint += "*." + E;
@@ -1164,15 +1476,22 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Dynamic,Static,Static Lightmaps", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 2));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI),Static Lightmaps,Dynamic (VoxelGI only)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/bake_reset_animation"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
- r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), Dictionary()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary()));
+
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->get_import_options(p_path, r_options);
+ }
+
+ for (Ref<EditorSceneFormatImporter> importer : importers) {
+ importer->get_import_options(p_path, r_options);
+ }
}
void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) {
@@ -1186,66 +1505,8 @@ void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_
}
}
-Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
- Ref<EditorSceneImporter> importer;
- String ext = p_path.get_extension().to_lower();
-
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
- if (E->get().ptr() == p_exception) {
- continue;
- }
- List<String> extensions;
- E->get()->get_extensions(&extensions);
-
- for (const String &F : extensions) {
- if (F.to_lower() == ext) {
- importer = E;
- break;
- }
- }
-
- if (importer.is_valid()) {
- break;
- }
- }
-
- ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
-
- List<String> missing;
- Error err;
- return importer->import_scene(p_path, p_flags, p_bake_fps, &missing, &err);
-}
-
-Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
- Ref<EditorSceneImporter> importer;
- String ext = p_path.get_extension().to_lower();
-
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
- if (E->get().ptr() == p_exception) {
- continue;
- }
- List<String> extensions;
- E->get()->get_extensions(&extensions);
-
- for (const String &F : extensions) {
- if (F.to_lower() == ext) {
- importer = E;
- break;
- }
- }
-
- if (importer.is_valid()) {
- break;
- }
- }
-
- ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
-
- return importer->import_animation(p_path, p_flags, p_bake_fps);
-}
-
void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches) {
- EditorSceneImporterMeshNode3D *src_mesh_node = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ ImporterMeshInstance3D *src_mesh_node = Object::cast_to<ImporterMeshInstance3D>(p_node);
if (src_mesh_node) {
//is mesh
MeshInstance3D *mesh_node = memnew(MeshInstance3D);
@@ -1259,6 +1520,8 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
//do mesh processing
bool generate_lods = p_generate_lods;
+ float split_angle = 25.0f;
+ float merge_angle = 60.0f;
bool create_shadow_meshes = p_create_shadow_meshes;
bool bake_lightmaps = p_light_bake_mode == LIGHT_BAKE_STATIC_LIGHTMAPS;
String save_to_file;
@@ -1271,7 +1534,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
mesh_id = src_mesh_node->get_mesh()->get_name();
}
- if (mesh_id != String() && p_mesh_data.has(mesh_id)) {
+ if (!mesh_id.is_empty() && p_mesh_data.has(mesh_id)) {
Dictionary mesh_settings = p_mesh_data[mesh_id];
if (mesh_settings.has("generate/shadow_meshes")) {
@@ -1301,17 +1564,30 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
}
+ if (mesh_settings.has("lods/normal_split_angle")) {
+ split_angle = mesh_settings["lods/normal_split_angle"];
+ }
+
+ if (mesh_settings.has("lods/normal_merge_angle")) {
+ merge_angle = mesh_settings["lods/normal_merge_angle"];
+ }
+
if (mesh_settings.has("save_to_file/enabled") && bool(mesh_settings["save_to_file/enabled"]) && mesh_settings.has("save_to_file/path")) {
save_to_file = mesh_settings["save_to_file/path"];
if (!save_to_file.is_resource_file()) {
save_to_file = "";
}
}
+
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH, nullptr, src_mesh_node, src_mesh_node->get_mesh(), mesh_settings);
+ }
}
if (generate_lods) {
- src_mesh_node->get_mesh()->generate_lods();
+ src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle);
}
+
if (create_shadow_meshes) {
src_mesh_node->get_mesh()->create_shadow_mesh();
}
@@ -1348,7 +1624,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
}
- if (save_to_file != String()) {
+ if (!save_to_file.is_empty()) {
Ref<Mesh> existing = Ref<Resource>(ResourceCache::get(save_to_file));
if (existing.is_valid()) {
//if somehow an existing one is useful, create
@@ -1384,7 +1660,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
} break;
case LIGHT_BAKE_STATIC:
case LIGHT_BAKE_STATIC_LIGHTMAPS: {
- mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_BAKED);
+ mesh_node->set_gi_mode(GeometryInstance3D::GI_MODE_STATIC);
} break;
}
@@ -1402,20 +1678,171 @@ void ResourceImporterScene::_add_shapes(Node *p_node, const Vector<Ref<Shape3D>>
for (const Ref<Shape3D> &E : p_shapes) {
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E);
- p_node->add_child(cshape);
+ p_node->add_child(cshape, true);
cshape->set_owner(p_node->get_owner());
}
}
+void ResourceImporterScene::_optimize_track_usage(AnimationPlayer *p_player, AnimationImportTracks *p_track_actions) {
+ List<StringName> anims;
+ p_player->get_animation_list(&anims);
+ Node *parent = p_player->get_parent();
+ ERR_FAIL_COND(parent == nullptr);
+ OrderedHashMap<NodePath, uint32_t> used_tracks[TRACK_CHANNEL_MAX];
+ bool tracks_to_add = false;
+ static const Animation::TrackType track_types[TRACK_CHANNEL_MAX] = { Animation::TYPE_POSITION_3D, Animation::TYPE_ROTATION_3D, Animation::TYPE_SCALE_3D, Animation::TYPE_BLEND_SHAPE };
+ for (const StringName &I : anims) {
+ Ref<Animation> anim = p_player->get_animation(I);
+ for (int i = 0; i < anim->get_track_count(); i++) {
+ for (int j = 0; j < TRACK_CHANNEL_MAX; j++) {
+ if (anim->track_get_type(i) != track_types[j]) {
+ continue;
+ }
+ switch (p_track_actions[j]) {
+ case ANIMATION_IMPORT_TRACKS_IF_PRESENT: {
+ // Do Nothing.
+ } break;
+ case ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL: {
+ used_tracks[j].insert(anim->track_get_path(i), 0);
+ tracks_to_add = true;
+ } break;
+ case ANIMATION_IMPORT_TRACKS_NEVER: {
+ anim->remove_track(i);
+ i--;
+ } break;
+ }
+ }
+ }
+ }
+
+ if (!tracks_to_add) {
+ return;
+ }
+
+ uint32_t pass = 0;
+ for (const StringName &I : anims) {
+ Ref<Animation> anim = p_player->get_animation(I);
+ for (int j = 0; j < TRACK_CHANNEL_MAX; j++) {
+ if (p_track_actions[j] != ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL) {
+ continue;
+ }
+
+ pass++;
+
+ for (int i = 0; i < anim->get_track_count(); i++) {
+ if (anim->track_get_type(i) != track_types[j]) {
+ continue;
+ }
+
+ NodePath path = anim->track_get_path(i);
+
+ ERR_CONTINUE(!used_tracks[j].has(path)); // Should never happen.
+
+ used_tracks[j][path] = pass;
+ }
+
+ for (OrderedHashMap<NodePath, uint32_t>::Element J = used_tracks[j].front(); J; J = J.next()) {
+ if (J.get() == pass) {
+ continue;
+ }
+
+ NodePath path = J.key();
+ Node *n = parent->get_node(path);
+
+ if (j == TRACK_CHANNEL_BLEND_SHAPE) {
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n);
+ if (mi && path.get_subname_count() > 0) {
+ StringName bs = path.get_subname(0);
+ bool valid;
+ float value = mi->get(bs, &valid);
+ if (valid) {
+ int track_idx = anim->add_track(track_types[j]);
+ anim->track_set_path(track_idx, path);
+ anim->track_set_imported(track_idx, true);
+ anim->blend_shape_track_insert_key(track_idx, 0, value);
+ }
+ }
+
+ } else {
+ Skeleton3D *skel = Object::cast_to<Skeleton3D>(n);
+ Node3D *n3d = Object::cast_to<Node3D>(n);
+ Vector3 loc;
+ Quaternion rot;
+ Vector3 scale;
+ if (skel && path.get_subname_count() > 0) {
+ StringName bone = path.get_subname(0);
+ int bone_idx = skel->find_bone(bone);
+ if (bone_idx == -1) {
+ continue;
+ }
+ // Note that this is using get_bone_pose to update the bone pose cache.
+ _ALLOW_DISCARD_ skel->get_bone_pose(bone_idx);
+ loc = skel->get_bone_pose_position(bone_idx);
+ rot = skel->get_bone_pose_rotation(bone_idx);
+ scale = skel->get_bone_pose_scale(bone_idx);
+ } else if (n3d) {
+ loc = n3d->get_position();
+ rot = n3d->get_transform().basis.get_rotation_quaternion();
+ scale = n3d->get_scale();
+ } else {
+ continue;
+ }
+
+ // Ensure insertion keeps tracks together and ordered by type (loc/rot/scale)
+ int insert_at_pos = -1;
+ for (int k = 0; k < anim->get_track_count(); k++) {
+ NodePath tpath = anim->track_get_path(k);
+
+ if (path == tpath) {
+ Animation::TrackType ttype = anim->track_get_type(k);
+ if (insert_at_pos == -1) {
+ // First insert, determine whether replacing or kicking back
+ if (track_types[j] < ttype) {
+ insert_at_pos = k;
+ break; // No point in continuing.
+ } else {
+ insert_at_pos = k + 1;
+ }
+ } else if (ttype < track_types[j]) {
+ // Kick back.
+ insert_at_pos = k + 1;
+ }
+ } else if (insert_at_pos >= 0) {
+ break;
+ }
+ }
+ int track_idx = anim->add_track(track_types[j], insert_at_pos);
+
+ anim->track_set_path(track_idx, path);
+ anim->track_set_imported(track_idx, true);
+ switch (j) {
+ case TRACK_CHANNEL_POSITION: {
+ anim->position_track_insert_key(track_idx, 0, loc);
+ } break;
+ case TRACK_CHANNEL_ROTATION: {
+ anim->rotation_track_insert_key(track_idx, 0, rot);
+ } break;
+ case TRACK_CHANNEL_SCALE: {
+ anim->scale_track_insert_key(track_idx, 0, scale);
+ } break;
+ default: {
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
Node *ResourceImporterScene::pre_import(const String &p_source_file) {
- Ref<EditorSceneImporter> importer;
+ Ref<EditorSceneFormatImporter> importer;
String ext = p_source_file.get_extension().to_lower();
EditorProgress progress("pre-import", TTR("Pre-Import Scene"), 0);
progress.step(TTR("Importing Scene..."), 0);
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
+ for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
List<String> extensions;
E->get()->get_extensions(&extensions);
@@ -1434,14 +1861,14 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) {
ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
Error err = OK;
- Node *scene = importer->import_scene(p_source_file, EditorSceneImporter::IMPORT_ANIMATION | EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, 15, nullptr, &err);
+ Node *scene = importer->import_scene(p_source_file, EditorSceneFormatImporter::IMPORT_ANIMATION | EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS, Map<StringName, Variant>(), 15, nullptr, &err);
if (!scene || err != OK) {
return nullptr;
}
- Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
-
- _pre_fix_node(scene, scene, collision_map);
+ Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
+ List<Pair<NodePath, Node *>> node_renames;
+ _pre_fix_node(scene, scene, collision_map, node_renames);
return scene;
}
@@ -1449,13 +1876,13 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) {
Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
const String &src_path = p_source_file;
- Ref<EditorSceneImporter> importer;
+ Ref<EditorSceneFormatImporter> importer;
String ext = src_path.get_extension().to_lower();
EditorProgress progress("import", TTR("Import Scene"), 104);
progress.step(TTR("Importing Scene..."), 0);
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
+ for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
List<String> extensions;
E->get()->get_extensions(&extensions);
@@ -1478,21 +1905,21 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
int import_flags = 0;
if (bool(p_options["animation/import"])) {
- import_flags |= EditorSceneImporter::IMPORT_ANIMATION;
+ import_flags |= EditorSceneFormatImporter::IMPORT_ANIMATION;
}
if (bool(p_options["skins/use_named_skins"])) {
- import_flags |= EditorSceneImporter::IMPORT_USE_NAMED_SKIN_BINDS;
+ import_flags |= EditorSceneFormatImporter::IMPORT_USE_NAMED_SKIN_BINDS;
}
bool ensure_tangents = p_options["meshes/ensure_tangents"];
if (ensure_tangents) {
- import_flags |= EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
+ import_flags |= EditorSceneFormatImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
}
Error err = OK;
List<String> missing_deps; // for now, not much will be done with this
- Node *scene = importer->import_scene(src_path, import_flags, fps, &missing_deps, &err);
+ Node *scene = importer->import_scene(src_path, import_flags, p_options, fps, &missing_deps, &err);
if (!scene || err != OK) {
return err;
}
@@ -1514,17 +1941,18 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
animation_data = subresources["animations"];
}
- Set<Ref<EditorSceneImporterMesh>> scanned_meshes;
- Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
+ Set<Ref<ImporterMesh>> scanned_meshes;
+ Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
+ List<Pair<NodePath, Node *>> node_renames;
- _pre_fix_node(scene, scene, collision_map);
- _post_fix_node(scene, scene, collision_map, scanned_meshes, node_data, material_data, animation_data, fps);
- bool use_bake_reset_animation = p_options["animation/bake_reset_animation"];
- if (use_bake_reset_animation) {
- BakeReset bake_reset;
- bake_reset._bake_animation_pose(scene, "RESET");
+ _pre_fix_node(scene, scene, collision_map, node_renames);
+
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->pre_process(scene, p_options);
}
+ _post_fix_node(scene, scene, collision_map, scanned_meshes, node_data, material_data, animation_data, fps);
+
String root_type = p_options["nodes/root_type"];
root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class.
@@ -1600,7 +2028,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
String post_import_script_path = p_options["import_script/path"];
Ref<EditorScenePostImport> post_import_script;
- if (post_import_script_path != "") {
+ if (!post_import_script_path.is_empty()) {
Ref<Script> scr = ResourceLoader::load(post_import_script_path);
if (!scr.is_valid()) {
EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path);
@@ -1626,6 +2054,10 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
}
}
+ for (int i = 0; i < post_importer_plugins.size(); i++) {
+ post_importer_plugins.write[i]->post_process(scene, p_options);
+ }
+
progress.step(TTR("Saving..."), 104);
Ref<PackedScene> packer = memnew(PackedScene);
@@ -1657,15 +2089,15 @@ ResourceImporterScene::ResourceImporterScene() {
///////////////////////////////////////
-uint32_t EditorSceneImporterESCN::get_import_flags() const {
+uint32_t EditorSceneFormatImporterESCN::get_import_flags() const {
return IMPORT_SCENE;
}
-void EditorSceneImporterESCN::get_extensions(List<String> *r_extensions) const {
+void EditorSceneFormatImporterESCN::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("escn");
}
-Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneFormatImporterESCN::import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Error error;
Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");
@@ -1676,6 +2108,6 @@ Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_fla
return scene;
}
-Ref<Animation> EditorSceneImporterESCN::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporterESCN::import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) {
ERR_FAIL_V(Ref<Animation>());
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index e232b715be..13b55b5754 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,9 @@
#ifndef RESOURCEIMPORTERSCENE_H
#define RESOURCEIMPORTERSCENE_H
+#include "core/error/error_macros.h"
#include "core/io/resource_importer.h"
+#include "core/variant/dictionary.h"
#include "scene/3d/node_3d.h"
#include "scene/resources/animation.h"
#include "scene/resources/mesh.h"
@@ -41,20 +43,22 @@
class Material;
class AnimationPlayer;
-class EditorSceneImporterMesh;
-class EditorSceneImporter : public RefCounted {
- GDCLASS(EditorSceneImporter, RefCounted);
+class ImporterMesh;
+class EditorSceneFormatImporter : public RefCounted {
+ GDCLASS(EditorSceneFormatImporter, RefCounted);
protected:
static void _bind_methods();
- Node *import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
- Ref<Animation> import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
+ Node *import_scene_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options, int p_bake_fps);
+ Ref<Animation> import_animation_wrapper(const String &p_path, uint32_t p_flags, Dictionary p_options, int p_bake_fps);
GDVIRTUAL0RC(int, _get_import_flags)
GDVIRTUAL0RC(Vector<String>, _get_extensions)
- GDVIRTUAL3R(Object *, _import_scene, String, uint32_t, uint32_t)
- GDVIRTUAL3R(Ref<Animation>, _import_animation, String, uint32_t, uint32_t)
+ GDVIRTUAL4R(Object *, _import_scene, String, uint32_t, Dictionary, uint32_t)
+ GDVIRTUAL4R(Ref<Animation>, _import_animation, String, uint32_t, Dictionary, uint32_t)
+ GDVIRTUAL1(_get_import_options, String)
+ GDVIRTUAL2RC(Variant, _get_option_visibility, String, String)
public:
enum ImportFlags {
@@ -67,10 +71,12 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps);
+ virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options);
+ virtual Variant get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options);
- EditorSceneImporter() {}
+ EditorSceneFormatImporter() {}
};
class EditorScenePostImport : public RefCounted {
@@ -90,18 +96,72 @@ public:
EditorScenePostImport();
};
+class EditorScenePostImportPlugin : public RefCounted {
+ GDCLASS(EditorScenePostImportPlugin, RefCounted);
+
+public:
+ enum InternalImportCategory {
+ INTERNAL_IMPORT_CATEGORY_NODE,
+ INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE,
+ INTERNAL_IMPORT_CATEGORY_MESH,
+ INTERNAL_IMPORT_CATEGORY_MATERIAL,
+ INTERNAL_IMPORT_CATEGORY_ANIMATION,
+ INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE,
+ INTERNAL_IMPORT_CATEGORY_MAX
+ };
+
+private:
+ mutable const Map<StringName, Variant> *current_options = nullptr;
+ mutable const Dictionary *current_options_dict = nullptr;
+ List<ResourceImporter::ImportOption> *current_option_list = nullptr;
+ InternalImportCategory current_category = INTERNAL_IMPORT_CATEGORY_MAX;
+
+protected:
+ GDVIRTUAL1(_get_internal_import_options, int)
+ GDVIRTUAL2RC(Variant, _get_internal_option_visibility, int, String)
+ GDVIRTUAL2RC(Variant, _get_internal_option_update_view_required, int, String)
+ GDVIRTUAL4(_internal_process, int, Node *, Node *, RES)
+ GDVIRTUAL1(_get_import_options, String)
+ GDVIRTUAL2RC(Variant, _get_option_visibility, String, String)
+ GDVIRTUAL1(_pre_process, Node *)
+ GDVIRTUAL1(_post_process, Node *)
+
+ static void _bind_methods();
+
+public:
+ Variant get_option_value(const StringName &p_name) const;
+ void add_import_option(const String &p_name, Variant p_default_value);
+ void add_import_option_advanced(Variant::Type p_type, const String &p_name, Variant p_default_value, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = String(), int p_usage_flags = PROPERTY_USAGE_DEFAULT);
+
+ virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options);
+ virtual Variant get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
+ virtual Variant get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, RES p_resource, const Dictionary &p_options);
+
+ virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options);
+ virtual Variant get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual void pre_process(Node *p_scene, const Map<StringName, Variant> &p_options);
+ virtual void post_process(Node *p_scene, const Map<StringName, Variant> &p_options);
+
+ EditorScenePostImportPlugin() {}
+};
+
+VARIANT_ENUM_CAST(EditorScenePostImportPlugin::InternalImportCategory)
+
class ResourceImporterScene : public ResourceImporter {
GDCLASS(ResourceImporterScene, ResourceImporter);
- Set<Ref<EditorSceneImporter>> importers;
+ Set<Ref<EditorSceneFormatImporter>> importers;
static ResourceImporterScene *singleton;
enum LightBakeMode {
LIGHT_BAKE_DISABLED,
- LIGHT_BAKE_DYNAMIC,
LIGHT_BAKE_STATIC,
- LIGHT_BAKE_STATIC_LIGHTMAPS
+ LIGHT_BAKE_STATIC_LIGHTMAPS,
+ LIGHT_BAKE_DYNAMIC,
};
enum MeshPhysicsMode {
@@ -144,13 +204,33 @@ class ResourceImporterScene : public ResourceImporter {
void _generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches);
void _add_shapes(Node *p_node, const Vector<Ref<Shape3D>> &p_shapes);
+ enum AnimationImportTracks {
+ ANIMATION_IMPORT_TRACKS_IF_PRESENT,
+ ANIMATION_IMPORT_TRACKS_IF_PRESENT_FOR_ALL,
+ ANIMATION_IMPORT_TRACKS_NEVER,
+ };
+ enum TrackChannel {
+ TRACK_CHANNEL_POSITION,
+ TRACK_CHANNEL_ROTATION,
+ TRACK_CHANNEL_SCALE,
+ TRACK_CHANNEL_BLEND_SHAPE,
+ TRACK_CHANNEL_MAX
+ };
+
+ void _optimize_track_usage(AnimationPlayer *p_player, AnimationImportTracks *p_track_actions);
+
+ mutable Vector<Ref<EditorScenePostImportPlugin>> post_importer_plugins;
+
public:
static ResourceImporterScene *get_singleton() { return singleton; }
- const Set<Ref<EditorSceneImporter>> &get_importers() const { return importers; }
+ void add_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { post_importer_plugins.push_back(p_plugin); }
+ void remove_post_importer_plugin(const Ref<EditorScenePostImportPlugin> &p_plugin) { post_importer_plugins.erase(p_plugin); }
+
+ const Set<Ref<EditorSceneFormatImporter>> &get_importers() const { return importers; }
- void add_importer(Ref<EditorSceneImporter> p_importer) { importers.insert(p_importer); }
- void remove_importer(Ref<EditorSceneImporter> p_importer) { importers.erase(p_importer); }
+ void add_importer(Ref<EditorSceneFormatImporter> p_importer) { importers.insert(p_importer); }
+ void remove_importer(Ref<EditorSceneFormatImporter> p_importer) { importers.erase(p_importer); }
virtual String get_importer_name() const override;
virtual String get_visible_name() const override;
@@ -163,37 +243,35 @@ public:
virtual String get_preset_name(int p_idx) const override;
enum InternalImportCategory {
- INTERNAL_IMPORT_CATEGORY_NODE,
- INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE,
- INTERNAL_IMPORT_CATEGORY_MESH,
- INTERNAL_IMPORT_CATEGORY_MATERIAL,
- INTERNAL_IMPORT_CATEGORY_ANIMATION,
- INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE,
- INTERNAL_IMPORT_CATEGORY_MAX
+ INTERNAL_IMPORT_CATEGORY_NODE = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_NODE,
+ INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE,
+ INTERNAL_IMPORT_CATEGORY_MESH = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH,
+ INTERNAL_IMPORT_CATEGORY_MATERIAL = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL,
+ INTERNAL_IMPORT_CATEGORY_ANIMATION = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION,
+ INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE,
+ INTERNAL_IMPORT_CATEGORY_MAX = EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MAX
};
void get_internal_import_options(InternalImportCategory p_category, List<ImportOption> *r_options) const;
bool get_internal_option_visibility(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
bool get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
// Import scenes *after* everything else (such as textures).
virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; }
- Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> &collision_map);
- Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
+ Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames);
+ Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all);
void _optimize_animations(AnimationPlayer *anim, float p_max_lin_error, float p_max_ang_error, float p_max_angle);
+ void _compress_animations(AnimationPlayer *anim, int p_page_size_kb);
Node *pre_import(const String &p_source_file);
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
- Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
- Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
-
virtual bool has_advanced_options() const override;
virtual void show_advanced_options(const String &p_path) override;
@@ -208,14 +286,14 @@ public:
static Transform3D get_collision_shapes_transform(const M &p_options);
};
-class EditorSceneImporterESCN : public EditorSceneImporter {
- GDCLASS(EditorSceneImporterESCN, EditorSceneImporter);
+class EditorSceneFormatImporterESCN : public EditorSceneFormatImporter {
+ GDCLASS(EditorSceneFormatImporterESCN, EditorSceneFormatImporter);
public:
virtual uint32_t get_import_flags() const override;
virtual void get_extensions(List<String> *r_extensions) const override;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
- virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, const Map<StringName, Variant> &p_options, int p_bake_fps) override;
};
#include "scene/resources/box_shape_3d.h"
diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp
index c01d8068da..cc34259a2d 100644
--- a/editor/import/resource_importer_shader_file.cpp
+++ b/editor/import/resource_importer_shader_file.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,10 +65,10 @@ String ResourceImporterShaderFile::get_preset_name(int p_idx) const {
return String();
}
-void ResourceImporterShaderFile::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterShaderFile::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
}
-bool ResourceImporterShaderFile::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterShaderFile::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h
index c421132ec2..858c2e783c 100644
--- a/editor/import/resource_importer_shader_file.h
+++ b/editor/import/resource_importer_shader_file.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,8 +46,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 61745cb6ee..f21012258c 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -37,6 +37,8 @@
#include "editor/editor_node.h"
void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture2D> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) {
+ ERR_FAIL_COND(p_tex.is_null());
+
MutexLock lock(singleton->mutex);
StringName path = p_tex->get_path();
@@ -51,6 +53,8 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTextur
}
void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture2D> &p_tex) {
+ ERR_FAIL_COND(p_tex.is_null());
+
MutexLock lock(singleton->mutex);
StringName path = p_tex->get_path();
@@ -63,6 +67,8 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture2D> &p
}
void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture2D> &p_tex) {
+ ERR_FAIL_COND(p_tex.is_null());
+
MutexLock lock(singleton->mutex);
StringName path = p_tex->get_path();
@@ -86,28 +92,28 @@ void ResourceImporterTexture::update_imports() {
return;
}
- for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) {
+ for (const KeyValue<StringName, MakeInfo> &E : make_flags) {
Ref<ConfigFile> cf;
cf.instantiate();
- String src_path = String(E->key()) + ".import";
+ String src_path = String(E.key) + ".import";
Error err = cf->load(src_path);
ERR_CONTINUE(err != OK);
bool changed = false;
- if (E->get().flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) {
+ if (E.value.flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) {
cf->set_value("params", "compress/normal_map", 1);
changed = true;
}
- if (E->get().flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) {
- cf->set_value("params", "roughness/mode", E->get().channel_for_roughness + 2);
- cf->set_value("params", "roughness/src_normal", E->get().normal_path_for_roughness);
+ if (E.value.flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) {
+ cf->set_value("params", "roughness/mode", E.value.channel_for_roughness + 2);
+ cf->set_value("params", "roughness/src_normal", E.value.normal_path_for_roughness);
changed = true;
}
- if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) {
+ if (E.value.flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) {
int compress_to = cf->get_value("params", "detect_3d/compress_to");
cf->set_value("params", "detect_3d/compress_to", 0);
if (compress_to == 1) {
@@ -121,7 +127,7 @@ void ResourceImporterTexture::update_imports() {
if (changed) {
cf->save(src_path);
- to_reimport.push_back(E->key());
+ to_reimport.push_back(E.key);
}
}
@@ -153,7 +159,7 @@ String ResourceImporterTexture::get_resource_type() const {
return "StreamTexture2D";
}
-bool ResourceImporterTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterTexture::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
if (p_option == "compress/lossy_quality") {
int compress_mode = int(p_options["compress/mode"]);
if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VRAM_COMPRESSED) {
@@ -194,7 +200,7 @@ String ResourceImporterTexture::get_preset_name(int p_idx) const {
return preset_names[p_idx];
}
-void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterTexture::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
@@ -205,20 +211,24 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), (p_preset == PRESET_3D ? true : false)));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "roughness/mode", PROPERTY_HINT_ENUM, "Detect,Disabled,Red,Green,Blue,Alpha,Gray"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.svgz,*.tga,*.webp"), ""));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "roughness/src_normal", PROPERTY_HINT_FILE, "*.bmp,*.dds,*.exr,*.jpeg,*.jpg,*.hdr,*.png,*.svg,*.tga,*.webp"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
+
+ if (p_path.get_extension() == "svg") {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
+ }
}
void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) {
switch (p_compress_mode) {
case COMPRESS_LOSSLESS: {
- bool lossless_force_png = ProjectSettings::get_singleton()->get("rendering/textures/lossless_compression/force_png");
+ bool lossless_force_png = ProjectSettings::get_singleton()->get("rendering/textures/lossless_compression/force_png") ||
+ !Image::_webp_mem_loader_func; // WebP module disabled.
bool use_webp = !lossless_force_png && p_image->get_width() <= 16383 && p_image->get_height() <= 16383; // WebP has a size limit
f->store_32(use_webp ? StreamTexture2D::DATA_FORMAT_WEBP : StreamTexture2D::DATA_FORMAT_PNG);
f->store_16(p_image->get_width());
@@ -401,11 +411,14 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
int size_limit = p_options["process/size_limit"];
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
int normal = p_options["compress/normal_map"];
- float scale = p_options["svg/scale"];
int hdr_compression = p_options["compress/hdr_compression"];
int bptc_ldr = p_options["compress/bptc_ldr"];
int roughness = p_options["roughness/mode"];
String normal_map = p_options["roughness/src_normal"];
+ float scale = 1.0;
+ if (p_options.has("svg/scale")) {
+ scale = p_options["svg/scale"];
+ }
Ref<Image> normal_image;
Image::RoughnessChannel roughness_channel = Image::ROUGHNESS_CHANNEL_R;
@@ -549,12 +562,6 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
formats_imported.push_back("etc");
}
- if (ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_pvrtc")) {
- _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC1_4, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
- r_platform_variants->push_back("pvrtc");
- formats_imported.push_back("pvrtc");
- }
-
if (!ok_on_pc) {
EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correctly on PC.");
}
@@ -579,7 +586,6 @@ const char *ResourceImporterTexture::compression_formats[] = {
"s3tc",
"etc",
"etc2",
- "pvrtc",
nullptr
};
String ResourceImporterTexture::get_import_settings_string() const {
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index 41220009cd..ea2318fb33 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -95,8 +95,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index dec1466da1..d2a9fe2538 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -59,7 +59,7 @@ String ResourceImporterTextureAtlas::get_resource_type() const {
return "Texture2D";
}
-bool ResourceImporterTextureAtlas::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterTextureAtlas::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
@@ -71,9 +71,10 @@ String ResourceImporterTextureAtlas::get_preset_name(int p_idx) const {
return String();
}
-void ResourceImporterTextureAtlas::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterTextureAtlas::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "atlas_file", PROPERTY_HINT_SAVE_FILE, "*.png"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_mode", PROPERTY_HINT_ENUM, "Region,Mesh2D"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "crop_to_region"), false));
}
String ResourceImporterTextureAtlas::get_option_group_file() const {
@@ -131,9 +132,9 @@ static void _plot_triangle(Vector2i *vertices, const Vector2i &p_offset, bool p_
double xf = x[0];
double xt = x[0] + dx_upper; // if y[0] == y[1], special case
int max_y = MIN(y[2], height - p_offset.y - 1);
- for (int yi = y[0]; yi <= max_y; yi++) {
+ for (int yi = y[0]; yi < max_y; yi++) {
if (yi >= 0) {
- for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
+ for (int xi = (xf > 0 ? int(xf) : 0); xi < (xt <= src_width ? xt : src_width); xi++) {
int px = xi, py = yi;
int sx = px, sy = py;
sx = CLAMP(sx, 0, src_width - 1);
@@ -155,7 +156,7 @@ static void _plot_triangle(Vector2i *vertices, const Vector2i &p_offset, bool p_
p_image->set_pixel(px, py, color);
}
- for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
+ for (int xi = (xf < src_width ? int(xf) : src_width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
int px = xi, py = yi;
int sx = px, sy = py;
sx = CLAMP(sx, 0, src_width - 1);
@@ -206,6 +207,7 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
ERR_CONTINUE(err != OK);
pack_data.image = image;
+ pack_data.is_cropped = options["crop_to_region"];
int mode = options["import_mode"];
@@ -324,7 +326,10 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
atlas_texture.instantiate();
atlas_texture->set_atlas(cache);
atlas_texture->set_region(Rect2(offset, pack_data.region.size));
- atlas_texture->set_margin(Rect2(pack_data.region.position, Size2(pack_data.image->get_width(), pack_data.image->get_height()) - pack_data.region.size));
+
+ if (!pack_data.is_cropped) {
+ atlas_texture->set_margin(Rect2(pack_data.region.position, pack_data.image->get_size() - pack_data.region.size));
+ }
texture = atlas_texture;
} else {
diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h
index b675d12477..a5e47dee99 100644
--- a/editor/import/resource_importer_texture_atlas.h
+++ b/editor/import/resource_importer_texture_atlas.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,6 +38,7 @@ class ResourceImporterTextureAtlas : public ResourceImporter {
struct PackData {
Rect2 region;
+ bool is_cropped = false;
bool is_mesh = false;
Vector<int> chart_pieces; //one for region, many for mesh
Vector<Vector<Vector2>> chart_vertices; //for mesh
@@ -59,8 +60,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
virtual String get_option_group_file() const override;
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 2db1db9e51..8cb9a47fb5 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -58,7 +58,7 @@ String ResourceImporterWAV::get_resource_type() const {
return "AudioStreamSample";
}
-bool ResourceImporterWAV::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterWAV::get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const {
if (p_option == "force/max_rate_hz" && !bool(p_options["force/max_rate"])) {
return false;
}
@@ -74,7 +74,7 @@ String ResourceImporterWAV::get_preset_name(int p_idx) const {
return String();
}
-void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+void ResourceImporterWAV::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/8_bit"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/mono"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/max_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
@@ -252,13 +252,13 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
//loop point info!
/**
- * Consider exploring next document:
- * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/RIFFNEW.pdf
- * Especially on page:
- * 16 - 17
- * Timestamp:
- * 22:38 06.07.2017 GMT
- **/
+ * Consider exploring next document:
+ * http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/RIFFNEW.pdf
+ * Especially on page:
+ * 16 - 17
+ * Timestamp:
+ * 22:38 06.07.2017 GMT
+ **/
for (int i = 0; i < 10; i++) {
file->get_32(); // i wish to know why should i do this... no doc!
@@ -272,7 +272,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
if (loop_type == 0x00) {
loop = AudioStreamSample::LOOP_FORWARD;
} else if (loop_type == 0x01) {
- loop = AudioStreamSample::LOOP_PING_PONG;
+ loop = AudioStreamSample::LOOP_PINGPONG;
} else if (loop_type == 0x02) {
loop = AudioStreamSample::LOOP_BACKWARD;
}
diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h
index 7413dbd11c..a5b576ceb9 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,8 +46,8 @@ public:
virtual int get_preset_count() const override;
virtual String get_preset_name(int p_idx) const override;
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override;
+ virtual bool get_option_visibility(const String &p_path, const String &p_option, const Map<StringName, Variant> &p_options) const override;
static void _compress_ima_adpcm(const Vector<float> &p_data, Vector<uint8_t> &dst_data) {
/*p_sample_data->data = (void*)malloc(len);
diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index 4bcb6863fb..eed1888c6a 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,7 +31,8 @@
#include "scene_import_settings.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
-#include "editor/import/scene_importer_mesh_node_3d.h"
+#include "scene/3d/importer_mesh_instance_3d.h"
+#include "scene/resources/importer_mesh.h"
#include "scene/resources/surface_tool.h"
class SceneImportSettingsData : public Object {
@@ -91,7 +92,7 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma
if (p_material->has_meta("import_id")) {
import_id = p_material->get_meta("import_id");
has_import_id = true;
- } else if (p_material->get_name() != "") {
+ } else if (!p_material->get_name().is_empty()) {
import_id = p_material->get_name();
has_import_id = true;
} else {
@@ -147,7 +148,7 @@ void SceneImportSettings::_fill_mesh(Tree *p_tree, const Ref<Mesh> &p_mesh, Tree
if (p_mesh->has_meta("import_id")) {
import_id = p_mesh->get_meta("import_id");
has_import_id = true;
- } else if (p_mesh->get_name() != String()) {
+ } else if (!p_mesh->get_name().is_empty()) {
import_id = p_mesh->get_name();
has_import_id = true;
} else {
@@ -240,7 +241,7 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
p_node->set_meta("import_id", import_id);
}
- EditorSceneImporterMeshNode3D *src_mesh_node = Object::cast_to<EditorSceneImporterMeshNode3D>(p_node);
+ ImporterMeshInstance3D *src_mesh_node = Object::cast_to<ImporterMeshInstance3D>(p_node);
if (src_mesh_node) {
MeshInstance3D *mesh_node = memnew(MeshInstance3D);
@@ -249,7 +250,7 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
mesh_node->set_skin(src_mesh_node->get_skin());
mesh_node->set_skeleton_path(src_mesh_node->get_skeleton_path());
if (src_mesh_node->get_mesh().is_valid()) {
- Ref<EditorSceneImporterMesh> editor_mesh = src_mesh_node->get_mesh();
+ Ref<ImporterMesh> editor_mesh = src_mesh_node->get_mesh();
mesh_node->set_mesh(editor_mesh->get_mesh());
}
@@ -326,7 +327,7 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
MeshInstance3D *collider_view = memnew(MeshInstance3D);
collider_view->set_name("collider_view");
collider_view->set_visible(false);
- mesh_node->add_child(collider_view);
+ mesh_node->add_child(collider_view, true);
collider_view->set_owner(mesh_node);
Transform3D accum_xform;
@@ -413,7 +414,7 @@ void SceneImportSettings::_update_camera() {
float rot_y = cam_rot_y;
float zoom = cam_zoom;
- if (selected_type == "Node" || selected_type == "") {
+ if (selected_type == "Node" || selected_type.is_empty()) {
camera_aabb = contents_aabb;
} else {
if (mesh_preview->get_mesh().is_valid()) {
@@ -434,7 +435,7 @@ void SceneImportSettings::_update_camera() {
}
}
- Vector3 center = camera_aabb.position + camera_aabb.size * 0.5;
+ Vector3 center = camera_aabb.get_center();
float camera_size = camera_aabb.get_longest_axis_size();
camera->set_orthogonal(camera_size * zoom, 0.0001, camera_size * 2);
@@ -663,7 +664,7 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
List<ResourceImporter::ImportOption> options;
if (scene_import_settings_data->category == ResourceImporterScene::INTERNAL_IMPORT_CATEGORY_MAX) {
- ResourceImporterScene::get_singleton()->get_import_options(&options);
+ ResourceImporterScene::get_singleton()->get_import_options(base_path, &options);
} else {
ResourceImporterScene::get_singleton()->get_internal_import_options(scene_import_settings_data->category, &options);
}
@@ -736,21 +737,21 @@ void SceneImportSettings::_viewport_input(const Ref<InputEvent> &p_input) {
zoom = &md.cam_zoom;
}
Ref<InputEventMouseMotion> mm = p_input;
- if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
+ if (mm.is_valid() && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
(*rot_x) -= mm->get_relative().y * 0.01 * EDSCALE;
(*rot_y) -= mm->get_relative().x * 0.01 * EDSCALE;
(*rot_x) = CLAMP((*rot_x), -Math_PI / 2, Math_PI / 2);
_update_camera();
}
Ref<InputEventMouseButton> mb = p_input;
- if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN) {
+ if (mb.is_valid() && mb->get_button_index() == MouseButton::WHEEL_DOWN) {
(*zoom) *= 1.1;
if ((*zoom) > 10.0) {
(*zoom) = 10.0;
}
_update_camera();
}
- if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP) {
+ if (mb.is_valid() && mb->get_button_index() == MouseButton::WHEEL_UP) {
(*zoom) /= 1.1;
if ((*zoom) < 0.1) {
(*zoom) = 0.1;
@@ -771,52 +772,52 @@ void SceneImportSettings::_re_import() {
Dictionary subresources;
- for (Map<String, NodeData>::Element *E = node_map.front(); E; E = E->next()) {
- if (E->get().settings.size()) {
+ for (KeyValue<String, NodeData> &E : node_map) {
+ if (E.value.settings.size()) {
Dictionary d;
- for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) {
- d[String(F->key())] = F->get();
+ for (const KeyValue<StringName, Variant> &F : E.value.settings) {
+ d[String(F.key)] = F.value;
}
- nodes[E->key()] = d;
+ nodes[E.key] = d;
}
}
if (nodes.size()) {
subresources["nodes"] = nodes;
}
- for (Map<String, MaterialData>::Element *E = material_map.front(); E; E = E->next()) {
- if (E->get().settings.size()) {
+ for (KeyValue<String, MaterialData> &E : material_map) {
+ if (E.value.settings.size()) {
Dictionary d;
- for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) {
- d[String(F->key())] = F->get();
+ for (const KeyValue<StringName, Variant> &F : E.value.settings) {
+ d[String(F.key)] = F.value;
}
- materials[E->key()] = d;
+ materials[E.key] = d;
}
}
if (materials.size()) {
subresources["materials"] = materials;
}
- for (Map<String, MeshData>::Element *E = mesh_map.front(); E; E = E->next()) {
- if (E->get().settings.size()) {
+ for (KeyValue<String, MeshData> &E : mesh_map) {
+ if (E.value.settings.size()) {
Dictionary d;
- for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) {
- d[String(F->key())] = F->get();
+ for (const KeyValue<StringName, Variant> &F : E.value.settings) {
+ d[String(F.key)] = F.value;
}
- meshes[E->key()] = d;
+ meshes[E.key] = d;
}
}
if (meshes.size()) {
subresources["meshes"] = meshes;
}
- for (Map<String, AnimationData>::Element *E = animation_map.front(); E; E = E->next()) {
- if (E->get().settings.size()) {
+ for (KeyValue<String, AnimationData> &E : animation_map) {
+ if (E.value.settings.size()) {
Dictionary d;
- for (Map<StringName, Variant>::Element *F = E->get().settings.front(); F; F = F->next()) {
- d[String(F->key())] = F->get();
+ for (const KeyValue<StringName, Variant> &F : E.value.settings) {
+ d[String(F.key)] = F.value;
}
- animations[E->key()] = d;
+ animations[E.key] = d;
}
}
if (animations.size()) {
@@ -889,8 +890,8 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
switch (current_action) {
case ACTION_EXTRACT_MATERIALS: {
- for (Map<String, MaterialData>::Element *E = material_map.front(); E; E = E->next()) {
- MaterialData &md = material_map[E->key()];
+ for (const KeyValue<String, MaterialData> &E : material_map) {
+ MaterialData &md = material_map[E.key];
TreeItem *item = external_path_tree->create_item(root);
@@ -905,7 +906,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
item->set_text(2, "Already External");
item->set_tooltip(2, TTR("This material already references an external file, no action will be taken.\nDisable the external property for it to be extracted again."));
} else {
- item->set_metadata(0, E->key());
+ item->set_metadata(0, E.key);
item->set_editable(0, true);
item->set_checked(0, true);
String path = p_path.plus_file(name);
@@ -942,8 +943,8 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
external_paths->get_ok_button()->set_text(TTR("Extract"));
} break;
case ACTION_CHOOSE_MESH_SAVE_PATHS: {
- for (Map<String, MeshData>::Element *E = mesh_map.front(); E; E = E->next()) {
- MeshData &md = mesh_map[E->key()];
+ for (const KeyValue<String, MeshData> &E : mesh_map) {
+ MeshData &md = mesh_map[E.key];
TreeItem *item = external_path_tree->create_item(root);
@@ -958,7 +959,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
item->set_text(2, "Already Saving");
item->set_tooltip(2, TTR("This mesh already saves to an external resource, no action will be taken."));
} else {
- item->set_metadata(0, E->key());
+ item->set_metadata(0, E.key);
item->set_editable(0, true);
item->set_checked(0, true);
String path = p_path.plus_file(name);
@@ -995,8 +996,8 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
external_paths->get_ok_button()->set_text(TTR("Set Paths"));
} break;
case ACTION_CHOOSE_ANIMATION_SAVE_PATHS: {
- for (Map<String, AnimationData>::Element *E = animation_map.front(); E; E = E->next()) {
- AnimationData &ad = animation_map[E->key()];
+ for (const KeyValue<String, AnimationData> &E : animation_map) {
+ AnimationData &ad = animation_map[E.key];
TreeItem *item = external_path_tree->create_item(root);
@@ -1010,7 +1011,7 @@ void SceneImportSettings::_save_dir_callback(const String &p_path) {
item->set_text(2, "Already Saving");
item->set_tooltip(2, TTR("This animation already saves to an external resource, no action will be taken."));
} else {
- item->set_metadata(0, E->key());
+ item->set_metadata(0, E.key);
item->set_editable(0, true);
item->set_checked(0, true);
String path = p_path.plus_file(name);
diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h
index c7c94af493..4edf05c7bb 100644
--- a/editor/import/scene_import_settings.h
+++ b/editor/import/scene_import_settings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp
deleted file mode 100644
index 5e6dd08e79..0000000000
--- a/editor/import/scene_importer_mesh.cpp
+++ /dev/null
@@ -1,889 +0,0 @@
-/*************************************************************************/
-/* scene_importer_mesh.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene_importer_mesh.h"
-
-#include "core/math/math_defs.h"
-#include "scene/resources/surface_tool.h"
-
-#include <cstdint>
-
-void EditorSceneImporterMesh::add_blend_shape(const String &p_name) {
- ERR_FAIL_COND(surfaces.size() > 0);
- blend_shapes.push_back(p_name);
-}
-
-int EditorSceneImporterMesh::get_blend_shape_count() const {
- return blend_shapes.size();
-}
-
-String EditorSceneImporterMesh::get_blend_shape_name(int p_blend_shape) const {
- ERR_FAIL_INDEX_V(p_blend_shape, blend_shapes.size(), String());
- return blend_shapes[p_blend_shape];
-}
-
-void EditorSceneImporterMesh::set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode) {
- blend_shape_mode = p_blend_shape_mode;
-}
-
-Mesh::BlendShapeMode EditorSceneImporterMesh::get_blend_shape_mode() const {
- return blend_shape_mode;
-}
-
-void EditorSceneImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint32_t p_flags) {
- ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size());
- ERR_FAIL_COND(p_arrays.size() != Mesh::ARRAY_MAX);
- Surface s;
- s.primitive = p_primitive;
- s.arrays = p_arrays;
- s.name = p_name;
- s.flags = p_flags;
-
- Vector<Vector3> vertex_array = p_arrays[Mesh::ARRAY_VERTEX];
- int vertex_count = vertex_array.size();
- ERR_FAIL_COND(vertex_count == 0);
-
- for (int i = 0; i < blend_shapes.size(); i++) {
- Array bsdata = p_blend_shapes[i];
- ERR_FAIL_COND(bsdata.size() != Mesh::ARRAY_MAX);
- Vector<Vector3> vertex_data = bsdata[Mesh::ARRAY_VERTEX];
- ERR_FAIL_COND(vertex_data.size() != vertex_count);
- Surface::BlendShape bs;
- bs.arrays = bsdata;
- s.blend_shape_data.push_back(bs);
- }
-
- List<Variant> lods;
- p_lods.get_key_list(&lods);
- for (const Variant &E : lods) {
- ERR_CONTINUE(!E.is_num());
- Surface::LOD lod;
- lod.distance = E;
- lod.indices = p_lods[E];
- ERR_CONTINUE(lod.indices.size() == 0);
- s.lods.push_back(lod);
- }
-
- s.material = p_material;
-
- surfaces.push_back(s);
- mesh.unref();
-}
-
-int EditorSceneImporterMesh::get_surface_count() const {
- return surfaces.size();
-}
-
-Mesh::PrimitiveType EditorSceneImporterMesh::get_surface_primitive_type(int p_surface) {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Mesh::PRIMITIVE_MAX);
- return surfaces[p_surface].primitive;
-}
-Array EditorSceneImporterMesh::get_surface_arrays(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
- return surfaces[p_surface].arrays;
-}
-String EditorSceneImporterMesh::get_surface_name(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), String());
- return surfaces[p_surface].name;
-}
-void EditorSceneImporterMesh::set_surface_name(int p_surface, const String &p_name) {
- ERR_FAIL_INDEX(p_surface, surfaces.size());
- surfaces.write[p_surface].name = p_name;
- mesh.unref();
-}
-
-Array EditorSceneImporterMesh::get_surface_blend_shape_arrays(int p_surface, int p_blend_shape) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
- ERR_FAIL_INDEX_V(p_blend_shape, surfaces[p_surface].blend_shape_data.size(), Array());
- return surfaces[p_surface].blend_shape_data[p_blend_shape].arrays;
-}
-int EditorSceneImporterMesh::get_surface_lod_count(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), 0);
- return surfaces[p_surface].lods.size();
-}
-Vector<int> EditorSceneImporterMesh::get_surface_lod_indices(int p_surface, int p_lod) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Vector<int>());
- ERR_FAIL_INDEX_V(p_lod, surfaces[p_surface].lods.size(), Vector<int>());
-
- return surfaces[p_surface].lods[p_lod].indices;
-}
-
-float EditorSceneImporterMesh::get_surface_lod_size(int p_surface, int p_lod) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), 0);
- ERR_FAIL_INDEX_V(p_lod, surfaces[p_surface].lods.size(), 0);
- return surfaces[p_surface].lods[p_lod].distance;
-}
-
-uint32_t EditorSceneImporterMesh::get_surface_format(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), 0);
- return surfaces[p_surface].flags;
-}
-
-Ref<Material> EditorSceneImporterMesh::get_surface_material(int p_surface) const {
- ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Ref<Material>());
- return surfaces[p_surface].material;
-}
-
-void EditorSceneImporterMesh::set_surface_material(int p_surface, const Ref<Material> &p_material) {
- ERR_FAIL_INDEX(p_surface, surfaces.size());
- surfaces.write[p_surface].material = p_material;
- mesh.unref();
-}
-
-Basis EditorSceneImporterMesh::compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 p_y_raw) {
- Vector3 x = p_x_raw.normalized();
- Vector3 z = x.cross(p_y_raw);
- z = z.normalized();
- Vector3 y = z.cross(x);
- Basis basis;
- basis.set_axis(Vector3::AXIS_X, x);
- basis.set_axis(Vector3::AXIS_Y, y);
- basis.set_axis(Vector3::AXIS_Z, z);
- return basis;
-}
-
-void EditorSceneImporterMesh::generate_lods() {
- if (!SurfaceTool::simplify_func) {
- return;
- }
- if (!SurfaceTool::simplify_scale_func) {
- return;
- }
- if (!SurfaceTool::simplify_sloppy_func) {
- return;
- }
- if (!SurfaceTool::simplify_with_attrib_func) {
- return;
- }
-
- for (int i = 0; i < surfaces.size(); i++) {
- if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) {
- continue;
- }
-
- surfaces.write[i].lods.clear();
- Vector<Vector3> vertices = surfaces[i].arrays[RS::ARRAY_VERTEX];
- Vector<int> indices = surfaces[i].arrays[RS::ARRAY_INDEX];
- if (indices.size() == 0) {
- continue; //no lods if no indices
- }
- Vector<Vector3> normals = surfaces[i].arrays[RS::ARRAY_NORMAL];
- uint32_t vertex_count = vertices.size();
- const Vector3 *vertices_ptr = vertices.ptr();
- Vector<float> attributes;
- Vector<float> normal_weights;
- int32_t attribute_count = 6;
- if (normals.size()) {
- attributes.resize(normals.size() * attribute_count);
- for (int32_t normal_i = 0; normal_i < normals.size(); normal_i++) {
- Basis basis;
- basis.set_euler(normals[normal_i]);
- Vector3 basis_x = basis.get_axis(0);
- Vector3 basis_y = basis.get_axis(1);
- basis = compute_rotation_matrix_from_ortho_6d(basis_x, basis_y);
- basis_x = basis.get_axis(0);
- basis_y = basis.get_axis(1);
- attributes.write[normal_i * attribute_count + 0] = basis_x.x;
- attributes.write[normal_i * attribute_count + 1] = basis_x.y;
- attributes.write[normal_i * attribute_count + 2] = basis_x.z;
- attributes.write[normal_i * attribute_count + 3] = basis_y.x;
- attributes.write[normal_i * attribute_count + 4] = basis_y.y;
- attributes.write[normal_i * attribute_count + 5] = basis_y.z;
- }
- normal_weights.resize(vertex_count);
- for (int32_t weight_i = 0; weight_i < normal_weights.size(); weight_i++) {
- normal_weights.write[weight_i] = 1.0;
- }
- } else {
- attribute_count = 0;
- }
- const int min_indices = 10;
- const float error_tolerance = 1.44224'95703; // Cube root of 3
- const float threshold = 1.0 / error_tolerance;
- int index_target = indices.size() * threshold;
- float max_mesh_error_percentage = 1e0f;
- float mesh_error = 0.0f;
- float scale = SurfaceTool::simplify_scale_func((const float *)vertices_ptr, vertex_count, sizeof(Vector3));
- while (index_target > min_indices) {
- Vector<int> new_indices;
- new_indices.resize(indices.size());
- size_t new_len = SurfaceTool::simplify_with_attrib_func((unsigned int *)new_indices.ptrw(), (const unsigned int *)indices.ptr(), indices.size(), (const float *)vertices_ptr, vertex_count, sizeof(Vector3), index_target, max_mesh_error_percentage, &mesh_error, (float *)attributes.ptrw(), normal_weights.ptrw(), attribute_count);
- if ((int)new_len > (index_target * error_tolerance)) {
- break;
- }
- Surface::LOD lod;
- lod.distance = mesh_error * scale;
- if (Math::is_zero_approx(mesh_error)) {
- break;
- }
- if (new_len <= 0) {
- break;
- }
- new_indices.resize(new_len);
- lod.indices = new_indices;
- print_line("Lod " + itos(surfaces.write[i].lods.size()) + " begin with " + itos(indices.size() / 3) + " triangles and shoot for " + itos(index_target / 3) + " triangles. Got " + itos(new_len / 3) + " triangles. Lod screen ratio " + rtos(lod.distance));
- surfaces.write[i].lods.push_back(lod);
- index_target *= threshold;
- }
- }
-}
-
-bool EditorSceneImporterMesh::has_mesh() const {
- return mesh.is_valid();
-}
-
-Ref<ArrayMesh> EditorSceneImporterMesh::get_mesh(const Ref<ArrayMesh> &p_base) {
- ERR_FAIL_COND_V(surfaces.size() == 0, Ref<ArrayMesh>());
-
- if (mesh.is_null()) {
- if (p_base.is_valid()) {
- mesh = p_base;
- }
- if (mesh.is_null()) {
- mesh.instantiate();
- }
- mesh->set_name(get_name());
- if (has_meta("import_id")) {
- mesh->set_meta("import_id", get_meta("import_id"));
- }
- for (int i = 0; i < blend_shapes.size(); i++) {
- mesh->add_blend_shape(blend_shapes[i]);
- }
- mesh->set_blend_shape_mode(blend_shape_mode);
- for (int i = 0; i < surfaces.size(); i++) {
- Array bs_data;
- if (surfaces[i].blend_shape_data.size()) {
- for (int j = 0; j < surfaces[i].blend_shape_data.size(); j++) {
- bs_data.push_back(surfaces[i].blend_shape_data[j].arrays);
- }
- }
- Dictionary lods;
- if (surfaces[i].lods.size()) {
- for (int j = 0; j < surfaces[i].lods.size(); j++) {
- lods[surfaces[i].lods[j].distance] = surfaces[i].lods[j].indices;
- }
- }
-
- mesh->add_surface_from_arrays(surfaces[i].primitive, surfaces[i].arrays, bs_data, lods, surfaces[i].flags);
- if (surfaces[i].material.is_valid()) {
- mesh->surface_set_material(mesh->get_surface_count() - 1, surfaces[i].material);
- }
- if (surfaces[i].name != String()) {
- mesh->surface_set_name(mesh->get_surface_count() - 1, surfaces[i].name);
- }
- }
-
- mesh->set_lightmap_size_hint(lightmap_size_hint);
-
- if (shadow_mesh.is_valid()) {
- Ref<ArrayMesh> shadow = shadow_mesh->get_mesh();
- mesh->set_shadow_mesh(shadow);
- }
- }
-
- return mesh;
-}
-
-void EditorSceneImporterMesh::clear() {
- surfaces.clear();
- blend_shapes.clear();
- mesh.unref();
-}
-
-void EditorSceneImporterMesh::create_shadow_mesh() {
- if (shadow_mesh.is_valid()) {
- shadow_mesh.unref();
- }
-
- //no shadow mesh for blendshapes
- if (blend_shapes.size() > 0) {
- return;
- }
- //no shadow mesh for skeletons
- for (int i = 0; i < surfaces.size(); i++) {
- if (surfaces[i].arrays[RS::ARRAY_BONES].get_type() != Variant::NIL) {
- return;
- }
- if (surfaces[i].arrays[RS::ARRAY_WEIGHTS].get_type() != Variant::NIL) {
- return;
- }
- }
-
- shadow_mesh.instantiate();
-
- for (int i = 0; i < surfaces.size(); i++) {
- LocalVector<int> vertex_remap;
- Vector<Vector3> new_vertices;
- Vector<Vector3> vertices = surfaces[i].arrays[RS::ARRAY_VERTEX];
- int vertex_count = vertices.size();
- {
- Map<Vector3, int> unique_vertices;
- const Vector3 *vptr = vertices.ptr();
- for (int j = 0; j < vertex_count; j++) {
- Vector3 v = vptr[j];
-
- Map<Vector3, int>::Element *E = unique_vertices.find(v);
-
- if (E) {
- vertex_remap.push_back(E->get());
- } else {
- int vcount = unique_vertices.size();
- unique_vertices[v] = vcount;
- vertex_remap.push_back(vcount);
- new_vertices.push_back(v);
- }
- }
- }
-
- Array new_surface;
- new_surface.resize(RS::ARRAY_MAX);
- Dictionary lods;
-
- // print_line("original vertex count: " + itos(vertices.size()) + " new vertex count: " + itos(new_vertices.size()));
-
- new_surface[RS::ARRAY_VERTEX] = new_vertices;
-
- Vector<int> indices = surfaces[i].arrays[RS::ARRAY_INDEX];
- if (indices.size()) {
- int index_count = indices.size();
- const int *index_rptr = indices.ptr();
- Vector<int> new_indices;
- new_indices.resize(indices.size());
- int *index_wptr = new_indices.ptrw();
-
- for (int j = 0; j < index_count; j++) {
- int index = index_rptr[j];
- ERR_FAIL_INDEX(index, vertex_count);
- index_wptr[j] = vertex_remap[index];
- }
-
- new_surface[RS::ARRAY_INDEX] = new_indices;
-
- // Make sure the same LODs as the full version are used.
- // This makes it more coherent between rendered model and its shadows.
- for (int j = 0; j < surfaces[i].lods.size(); j++) {
- indices = surfaces[i].lods[j].indices;
-
- index_count = indices.size();
- index_rptr = indices.ptr();
- new_indices.resize(indices.size());
- index_wptr = new_indices.ptrw();
-
- for (int k = 0; k < index_count; k++) {
- int index = index_rptr[j];
- ERR_FAIL_INDEX(index, vertex_count);
- index_wptr[j] = vertex_remap[index];
- }
-
- lods[surfaces[i].lods[j].distance] = new_indices;
- }
- }
-
- shadow_mesh->add_surface(surfaces[i].primitive, new_surface, Array(), lods, Ref<Material>(), surfaces[i].name, surfaces[i].flags);
- }
-}
-
-Ref<EditorSceneImporterMesh> EditorSceneImporterMesh::get_shadow_mesh() const {
- return shadow_mesh;
-}
-
-void EditorSceneImporterMesh::_set_data(const Dictionary &p_data) {
- clear();
- if (p_data.has("blend_shape_names")) {
- blend_shapes = p_data["blend_shape_names"];
- }
- if (p_data.has("surfaces")) {
- Array surface_arr = p_data["surfaces"];
- for (int i = 0; i < surface_arr.size(); i++) {
- Dictionary s = surface_arr[i];
- ERR_CONTINUE(!s.has("primitive"));
- ERR_CONTINUE(!s.has("arrays"));
- Mesh::PrimitiveType prim = Mesh::PrimitiveType(int(s["primitive"]));
- ERR_CONTINUE(prim >= Mesh::PRIMITIVE_MAX);
- Array arr = s["arrays"];
- Dictionary lods;
- String name;
- if (s.has("name")) {
- name = s["name"];
- }
- if (s.has("lods")) {
- lods = s["lods"];
- }
- Array blend_shapes;
- if (s.has("blend_shapes")) {
- blend_shapes = s["blend_shapes"];
- }
- Ref<Material> material;
- if (s.has("material")) {
- material = s["material"];
- }
- uint32_t flags = 0;
- if (s.has("flags")) {
- flags = s["flags"];
- }
- add_surface(prim, arr, blend_shapes, lods, material, name, flags);
- }
- }
-}
-Dictionary EditorSceneImporterMesh::_get_data() const {
- Dictionary data;
- if (blend_shapes.size()) {
- data["blend_shape_names"] = blend_shapes;
- }
- Array surface_arr;
- for (int i = 0; i < surfaces.size(); i++) {
- Dictionary d;
- d["primitive"] = surfaces[i].primitive;
- d["arrays"] = surfaces[i].arrays;
- if (surfaces[i].blend_shape_data.size()) {
- Array bs_data;
- for (int j = 0; j < surfaces[i].blend_shape_data.size(); j++) {
- bs_data.push_back(surfaces[i].blend_shape_data[j].arrays);
- }
- d["blend_shapes"] = bs_data;
- }
- if (surfaces[i].lods.size()) {
- Dictionary lods;
- for (int j = 0; j < surfaces[i].lods.size(); j++) {
- lods[surfaces[i].lods[j].distance] = surfaces[i].lods[j].indices;
- }
- d["lods"] = lods;
- }
-
- if (surfaces[i].material.is_valid()) {
- d["material"] = surfaces[i].material;
- }
-
- if (surfaces[i].name != String()) {
- d["name"] = surfaces[i].name;
- }
-
- if (surfaces[i].flags != 0) {
- d["flags"] = surfaces[i].flags;
- }
-
- surface_arr.push_back(d);
- }
- data["surfaces"] = surface_arr;
- return data;
-}
-
-Vector<Face3> EditorSceneImporterMesh::get_faces() const {
- Vector<Face3> faces;
- for (int i = 0; i < surfaces.size(); i++) {
- if (surfaces[i].primitive == Mesh::PRIMITIVE_TRIANGLES) {
- Vector<Vector3> vertices = surfaces[i].arrays[Mesh::ARRAY_VERTEX];
- Vector<int> indices = surfaces[i].arrays[Mesh::ARRAY_INDEX];
- if (indices.size()) {
- for (int j = 0; j < indices.size(); j += 3) {
- Face3 f;
- f.vertex[0] = vertices[indices[j + 0]];
- f.vertex[1] = vertices[indices[j + 1]];
- f.vertex[2] = vertices[indices[j + 2]];
- faces.push_back(f);
- }
- } else {
- for (int j = 0; j < vertices.size(); j += 3) {
- Face3 f;
- f.vertex[0] = vertices[j + 0];
- f.vertex[1] = vertices[j + 1];
- f.vertex[2] = vertices[j + 2];
- faces.push_back(f);
- }
- }
- }
- }
-
- return faces;
-}
-
-Vector<Ref<Shape3D>> EditorSceneImporterMesh::convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const {
- ERR_FAIL_COND_V(!Mesh::convex_decomposition_function, Vector<Ref<Shape3D>>());
-
- const Vector<Face3> faces = get_faces();
- int face_count = faces.size();
-
- Vector<Vector3> vertices;
- uint32_t vertex_count = 0;
- vertices.resize(face_count * 3);
- Vector<uint32_t> indices;
- indices.resize(face_count * 3);
- {
- Map<Vector3, uint32_t> vertex_map;
- Vector3 *vertex_w = vertices.ptrw();
- uint32_t *index_w = indices.ptrw();
- for (int i = 0; i < face_count; i++) {
- for (int j = 0; j < 3; j++) {
- const Vector3 &vertex = faces[i].vertex[j];
- Map<Vector3, uint32_t>::Element *found_vertex = vertex_map.find(vertex);
- uint32_t index;
- if (found_vertex) {
- index = found_vertex->get();
- } else {
- index = ++vertex_count;
- vertex_map[vertex] = index;
- vertex_w[index] = vertex;
- }
- index_w[i * 3 + j] = index;
- }
- }
- }
- vertices.resize(vertex_count);
-
- Vector<Vector<Vector3>> decomposed = Mesh::convex_decomposition_function((real_t *)vertices.ptr(), vertex_count, indices.ptr(), face_count, p_settings, nullptr);
-
- Vector<Ref<Shape3D>> ret;
-
- for (int i = 0; i < decomposed.size(); i++) {
- Ref<ConvexPolygonShape3D> shape;
- shape.instantiate();
- shape->set_points(decomposed[i]);
- ret.push_back(shape);
- }
-
- return ret;
-}
-
-Ref<Shape3D> EditorSceneImporterMesh::create_trimesh_shape() const {
- Vector<Face3> faces = get_faces();
- if (faces.size() == 0) {
- return Ref<Shape3D>();
- }
-
- Vector<Vector3> face_points;
- face_points.resize(faces.size() * 3);
-
- for (int i = 0; i < face_points.size(); i += 3) {
- Face3 f = faces.get(i / 3);
- face_points.set(i, f.vertex[0]);
- face_points.set(i + 1, f.vertex[1]);
- face_points.set(i + 2, f.vertex[2]);
- }
-
- Ref<ConcavePolygonShape3D> shape = memnew(ConcavePolygonShape3D);
- shape->set_faces(face_points);
- return shape;
-}
-
-Ref<NavigationMesh> EditorSceneImporterMesh::create_navigation_mesh() {
- Vector<Face3> faces = get_faces();
- if (faces.size() == 0) {
- return Ref<NavigationMesh>();
- }
-
- Map<Vector3, int> unique_vertices;
- LocalVector<int> face_indices;
-
- for (int i = 0; i < faces.size(); i++) {
- for (int j = 0; j < 3; j++) {
- Vector3 v = faces[i].vertex[j];
- int idx;
- if (unique_vertices.has(v)) {
- idx = unique_vertices[v];
- } else {
- idx = unique_vertices.size();
- unique_vertices[v] = idx;
- }
- face_indices.push_back(idx);
- }
- }
-
- Vector<Vector3> vertices;
- vertices.resize(unique_vertices.size());
- for (Map<Vector3, int>::Element *E = unique_vertices.front(); E; E = E->next()) {
- vertices.write[E->get()] = E->key();
- }
-
- Ref<NavigationMesh> nm;
- nm.instantiate();
- nm->set_vertices(vertices);
-
- Vector<int> v3;
- v3.resize(3);
- for (uint32_t i = 0; i < face_indices.size(); i += 3) {
- v3.write[0] = face_indices[i + 0];
- v3.write[1] = face_indices[i + 1];
- v3.write[2] = face_indices[i + 2];
- nm->add_polygon(v3);
- }
-
- return nm;
-}
-
-extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, const uint8_t *p_cache_data, bool *r_use_cache, uint8_t **r_mesh_cache, int *r_mesh_cache_size, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y);
-
-struct EditorSceneImporterMeshLightmapSurface {
- Ref<Material> material;
- LocalVector<SurfaceTool::Vertex> vertices;
- Mesh::PrimitiveType primitive = Mesh::PrimitiveType::PRIMITIVE_MAX;
- uint32_t format = 0;
- String name;
-};
-
-Error EditorSceneImporterMesh::lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache) {
- ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
- ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes.");
-
- LocalVector<float> vertices;
- LocalVector<float> normals;
- LocalVector<int> indices;
- LocalVector<float> uv;
- LocalVector<Pair<int, int>> uv_indices;
-
- Vector<EditorSceneImporterMeshLightmapSurface> lightmap_surfaces;
-
- // Keep only the scale
- Basis basis = p_base_transform.get_basis();
- Vector3 scale = Vector3(basis.get_axis(0).length(), basis.get_axis(1).length(), basis.get_axis(2).length());
-
- Transform3D transform;
- transform.scale(scale);
-
- Basis normal_basis = transform.basis.inverse().transposed();
-
- for (int i = 0; i < get_surface_count(); i++) {
- EditorSceneImporterMeshLightmapSurface s;
- s.primitive = get_surface_primitive_type(i);
-
- ERR_FAIL_COND_V_MSG(s.primitive != Mesh::PRIMITIVE_TRIANGLES, ERR_UNAVAILABLE, "Only triangles are supported for lightmap unwrap.");
- Array arrays = get_surface_arrays(i);
- s.material = get_surface_material(i);
- s.name = get_surface_name(i);
-
- SurfaceTool::create_vertex_array_from_triangle_arrays(arrays, s.vertices, &s.format);
-
- PackedVector3Array rvertices = arrays[Mesh::ARRAY_VERTEX];
- int vc = rvertices.size();
-
- PackedVector3Array rnormals = arrays[Mesh::ARRAY_NORMAL];
-
- int vertex_ofs = vertices.size() / 3;
-
- vertices.resize((vertex_ofs + vc) * 3);
- normals.resize((vertex_ofs + vc) * 3);
- uv_indices.resize(vertex_ofs + vc);
-
- for (int j = 0; j < vc; j++) {
- Vector3 v = transform.xform(rvertices[j]);
- Vector3 n = normal_basis.xform(rnormals[j]).normalized();
-
- vertices[(j + vertex_ofs) * 3 + 0] = v.x;
- vertices[(j + vertex_ofs) * 3 + 1] = v.y;
- vertices[(j + vertex_ofs) * 3 + 2] = v.z;
- normals[(j + vertex_ofs) * 3 + 0] = n.x;
- normals[(j + vertex_ofs) * 3 + 1] = n.y;
- normals[(j + vertex_ofs) * 3 + 2] = n.z;
- uv_indices[j + vertex_ofs] = Pair<int, int>(i, j);
- }
-
- PackedInt32Array rindices = arrays[Mesh::ARRAY_INDEX];
- int ic = rindices.size();
-
- float eps = 1.19209290e-7F; // Taken from xatlas.h
- if (ic == 0) {
- for (int j = 0; j < vc / 3; j++) {
- Vector3 p0 = transform.xform(rvertices[j * 3 + 0]);
- Vector3 p1 = transform.xform(rvertices[j * 3 + 1]);
- Vector3 p2 = transform.xform(rvertices[j * 3 + 2]);
-
- if ((p0 - p1).length_squared() < eps || (p1 - p2).length_squared() < eps || (p2 - p0).length_squared() < eps) {
- continue;
- }
-
- indices.push_back(vertex_ofs + j * 3 + 0);
- indices.push_back(vertex_ofs + j * 3 + 1);
- indices.push_back(vertex_ofs + j * 3 + 2);
- }
-
- } else {
- for (int j = 0; j < ic / 3; j++) {
- Vector3 p0 = transform.xform(rvertices[rindices[j * 3 + 0]]);
- Vector3 p1 = transform.xform(rvertices[rindices[j * 3 + 1]]);
- Vector3 p2 = transform.xform(rvertices[rindices[j * 3 + 2]]);
-
- if ((p0 - p1).length_squared() < eps || (p1 - p2).length_squared() < eps || (p2 - p0).length_squared() < eps) {
- continue;
- }
-
- indices.push_back(vertex_ofs + rindices[j * 3 + 0]);
- indices.push_back(vertex_ofs + rindices[j * 3 + 1]);
- indices.push_back(vertex_ofs + rindices[j * 3 + 2]);
- }
- }
-
- lightmap_surfaces.push_back(s);
- }
-
- //unwrap
-
- bool use_cache = true; // Used to request cache generation and to know if cache was used
- uint8_t *gen_cache;
- int gen_cache_size;
- float *gen_uvs;
- int *gen_vertices;
- int *gen_indices;
- int gen_vertex_count;
- int gen_index_count;
- int size_x;
- int size_y;
-
- bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), indices.size(), p_src_cache.ptr(), &use_cache, &gen_cache, &gen_cache_size, &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);
-
- if (!ok) {
- return ERR_CANT_CREATE;
- }
-
- //remove surfaces
- clear();
-
- //create surfacetools for each surface..
- LocalVector<Ref<SurfaceTool>> surfaces_tools;
-
- for (int i = 0; i < lightmap_surfaces.size(); i++) {
- Ref<SurfaceTool> st;
- st.instantiate();
- st->begin(Mesh::PRIMITIVE_TRIANGLES);
- st->set_material(lightmap_surfaces[i].material);
- st->set_meta("name", lightmap_surfaces[i].name);
- surfaces_tools.push_back(st); //stay there
- }
-
- print_verbose("Mesh: Gen indices: " + itos(gen_index_count));
-
- //go through all indices
- for (int i = 0; i < gen_index_count; i += 3) {
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], (int)uv_indices.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], (int)uv_indices.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], (int)uv_indices.size(), ERR_BUG);
-
- ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
-
- int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first;
-
- for (int j = 0; j < 3; j++) {
- SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second];
-
- if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_COLOR) {
- surfaces_tools[surface]->set_color(v.color);
- }
- if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_TEX_UV) {
- surfaces_tools[surface]->set_uv(v.uv);
- }
- if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_NORMAL) {
- surfaces_tools[surface]->set_normal(v.normal);
- }
- if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_TANGENT) {
- Plane t;
- t.normal = v.tangent;
- t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
- surfaces_tools[surface]->set_tangent(t);
- }
- if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_BONES) {
- surfaces_tools[surface]->set_bones(v.bones);
- }
- if (lightmap_surfaces[surface].format & Mesh::ARRAY_FORMAT_WEIGHTS) {
- surfaces_tools[surface]->set_weights(v.weights);
- }
-
- Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
- surfaces_tools[surface]->set_uv2(uv2);
-
- surfaces_tools[surface]->add_vertex(v.vertex);
- }
- }
-
- //generate surfaces
- for (unsigned int i = 0; i < surfaces_tools.size(); i++) {
- surfaces_tools[i]->index();
- Array arrays = surfaces_tools[i]->commit_to_arrays();
- add_surface(surfaces_tools[i]->get_primitive(), arrays, Array(), Dictionary(), surfaces_tools[i]->get_material(), surfaces_tools[i]->get_meta("name"));
- }
-
- set_lightmap_size_hint(Size2(size_x, size_y));
-
- if (gen_cache_size > 0) {
- r_dst_cache.resize(gen_cache_size);
- memcpy(r_dst_cache.ptrw(), gen_cache, gen_cache_size);
- memfree(gen_cache);
- }
-
- if (!use_cache) {
- // Cache was not used, free the buffers
- memfree(gen_vertices);
- memfree(gen_indices);
- memfree(gen_uvs);
- }
-
- return OK;
-}
-
-void EditorSceneImporterMesh::set_lightmap_size_hint(const Size2i &p_size) {
- lightmap_size_hint = p_size;
-}
-
-Size2i EditorSceneImporterMesh::get_lightmap_size_hint() const {
- return lightmap_size_hint;
-}
-
-void EditorSceneImporterMesh::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &EditorSceneImporterMesh::add_blend_shape);
- ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &EditorSceneImporterMesh::get_blend_shape_count);
- ClassDB::bind_method(D_METHOD("get_blend_shape_name", "blend_shape_idx"), &EditorSceneImporterMesh::get_blend_shape_name);
-
- ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &EditorSceneImporterMesh::set_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &EditorSceneImporterMesh::get_blend_shape_mode);
-
- ClassDB::bind_method(D_METHOD("add_surface", "primitive", "arrays", "blend_shapes", "lods", "material", "name", "flags"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()), DEFVAL(0));
-
- ClassDB::bind_method(D_METHOD("get_surface_count"), &EditorSceneImporterMesh::get_surface_count);
- ClassDB::bind_method(D_METHOD("get_surface_primitive_type", "surface_idx"), &EditorSceneImporterMesh::get_surface_primitive_type);
- ClassDB::bind_method(D_METHOD("get_surface_name", "surface_idx"), &EditorSceneImporterMesh::get_surface_name);
- ClassDB::bind_method(D_METHOD("get_surface_arrays", "surface_idx"), &EditorSceneImporterMesh::get_surface_arrays);
- ClassDB::bind_method(D_METHOD("get_surface_blend_shape_arrays", "surface_idx", "blend_shape_idx"), &EditorSceneImporterMesh::get_surface_blend_shape_arrays);
- ClassDB::bind_method(D_METHOD("get_surface_lod_count", "surface_idx"), &EditorSceneImporterMesh::get_surface_lod_count);
- ClassDB::bind_method(D_METHOD("get_surface_lod_size", "surface_idx", "lod_idx"), &EditorSceneImporterMesh::get_surface_lod_size);
- ClassDB::bind_method(D_METHOD("get_surface_lod_indices", "surface_idx", "lod_idx"), &EditorSceneImporterMesh::get_surface_lod_indices);
- ClassDB::bind_method(D_METHOD("get_surface_material", "surface_idx"), &EditorSceneImporterMesh::get_surface_material);
- ClassDB::bind_method(D_METHOD("get_surface_format", "surface_idx"), &EditorSceneImporterMesh::get_surface_format);
-
- ClassDB::bind_method(D_METHOD("set_surface_name", "surface_idx", "name"), &EditorSceneImporterMesh::set_surface_name);
- ClassDB::bind_method(D_METHOD("set_surface_material", "surface_idx", "material"), &EditorSceneImporterMesh::set_surface_material);
-
- ClassDB::bind_method(D_METHOD("get_mesh", "base_mesh"), &EditorSceneImporterMesh::get_mesh, DEFVAL(Ref<ArrayMesh>()));
- ClassDB::bind_method(D_METHOD("clear"), &EditorSceneImporterMesh::clear);
-
- ClassDB::bind_method(D_METHOD("_set_data", "data"), &EditorSceneImporterMesh::_set_data);
- ClassDB::bind_method(D_METHOD("_get_data"), &EditorSceneImporterMesh::_get_data);
-
- ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &EditorSceneImporterMesh::set_lightmap_size_hint);
- ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &EditorSceneImporterMesh::get_lightmap_size_hint);
-
- ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
-}
diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h
deleted file mode 100644
index d32b1fdf74..0000000000
--- a/editor/import/scene_importer_mesh.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************/
-/* scene_importer_mesh.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef EDITOR_SCENE_IMPORTER_MESH_H
-#define EDITOR_SCENE_IMPORTER_MESH_H
-
-#include "core/io/resource.h"
-#include "scene/resources/concave_polygon_shape_3d.h"
-#include "scene/resources/convex_polygon_shape_3d.h"
-#include "scene/resources/mesh.h"
-#include "scene/resources/navigation_mesh.h"
-
-#include <cstdint>
-
-// The following classes are used by importers instead of ArrayMesh and MeshInstance3D
-// so the data is not registered (hence, quality loss), importing happens faster and
-// its easier to modify before saving
-
-class EditorSceneImporterMesh : public Resource {
- GDCLASS(EditorSceneImporterMesh, Resource)
-
- struct Surface {
- Mesh::PrimitiveType primitive;
- Array arrays;
- struct BlendShape {
- Array arrays;
- };
- Vector<BlendShape> blend_shape_data;
- struct LOD {
- Vector<int> indices;
- float distance;
- };
- Vector<LOD> lods;
- Ref<Material> material;
- String name;
- uint32_t flags = 0;
- };
- Vector<Surface> surfaces;
- Vector<String> blend_shapes;
- Mesh::BlendShapeMode blend_shape_mode = Mesh::BLEND_SHAPE_MODE_NORMALIZED;
-
- Ref<ArrayMesh> mesh;
-
- Ref<EditorSceneImporterMesh> shadow_mesh;
-
- Size2i lightmap_size_hint;
- Basis compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 y_raw);
-
-protected:
- void _set_data(const Dictionary &p_data);
- Dictionary _get_data() const;
-
- static void _bind_methods();
-
-public:
- void add_blend_shape(const String &p_name);
- int get_blend_shape_count() const;
- String get_blend_shape_name(int p_blend_shape) const;
-
- void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint32_t p_flags = 0);
- int get_surface_count() const;
-
- void set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode);
- Mesh::BlendShapeMode get_blend_shape_mode() const;
-
- Mesh::PrimitiveType get_surface_primitive_type(int p_surface);
- String get_surface_name(int p_surface) const;
- void set_surface_name(int p_surface, const String &p_name);
- Array get_surface_arrays(int p_surface) const;
- Array get_surface_blend_shape_arrays(int p_surface, int p_blend_shape) const;
- int get_surface_lod_count(int p_surface) const;
- Vector<int> get_surface_lod_indices(int p_surface, int p_lod) const;
- float get_surface_lod_size(int p_surface, int p_lod) const;
- Ref<Material> get_surface_material(int p_surface) const;
- uint32_t get_surface_format(int p_surface) const;
-
- void set_surface_material(int p_surface, const Ref<Material> &p_material);
-
- void generate_lods();
-
- void create_shadow_mesh();
- Ref<EditorSceneImporterMesh> get_shadow_mesh() const;
-
- Vector<Face3> get_faces() const;
- Vector<Ref<Shape3D>> convex_decompose(const Mesh::ConvexDecompositionSettings &p_settings) const;
- Ref<Shape3D> create_trimesh_shape() const;
- Ref<NavigationMesh> create_navigation_mesh();
- Error lightmap_unwrap_cached(const Transform3D &p_base_transform, float p_texel_size, const Vector<uint8_t> &p_src_cache, Vector<uint8_t> &r_dst_cache);
-
- void set_lightmap_size_hint(const Size2i &p_size);
- Size2i get_lightmap_size_hint() const;
-
- bool has_mesh() const;
- Ref<ArrayMesh> get_mesh(const Ref<ArrayMesh> &p_base = Ref<ArrayMesh>());
- void clear();
-};
-#endif // EDITOR_SCENE_IMPORTER_MESH_H
diff --git a/editor/import/scene_importer_mesh_node_3d.cpp b/editor/import/scene_importer_mesh_node_3d.cpp
deleted file mode 100644
index 3c201cf674..0000000000
--- a/editor/import/scene_importer_mesh_node_3d.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*************************************************************************/
-/* scene_importer_mesh_node_3d.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "scene_importer_mesh_node_3d.h"
-
-void EditorSceneImporterMeshNode3D::set_mesh(const Ref<EditorSceneImporterMesh> &p_mesh) {
- mesh = p_mesh;
-}
-Ref<EditorSceneImporterMesh> EditorSceneImporterMeshNode3D::get_mesh() const {
- return mesh;
-}
-
-void EditorSceneImporterMeshNode3D::set_skin(const Ref<Skin> &p_skin) {
- skin = p_skin;
-}
-Ref<Skin> EditorSceneImporterMeshNode3D::get_skin() const {
- return skin;
-}
-
-void EditorSceneImporterMeshNode3D::set_surface_material(int p_idx, const Ref<Material> &p_material) {
- ERR_FAIL_COND(p_idx < 0);
- if (p_idx >= surface_materials.size()) {
- surface_materials.resize(p_idx + 1);
- }
-
- surface_materials.write[p_idx] = p_material;
-}
-Ref<Material> EditorSceneImporterMeshNode3D::get_surface_material(int p_idx) const {
- ERR_FAIL_COND_V(p_idx < 0, Ref<Material>());
- if (p_idx >= surface_materials.size()) {
- return Ref<Material>();
- }
- return surface_materials[p_idx];
-}
-
-void EditorSceneImporterMeshNode3D::set_skeleton_path(const NodePath &p_path) {
- skeleton_path = p_path;
-}
-NodePath EditorSceneImporterMeshNode3D::get_skeleton_path() const {
- return skeleton_path;
-}
-
-void EditorSceneImporterMeshNode3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &EditorSceneImporterMeshNode3D::set_mesh);
- ClassDB::bind_method(D_METHOD("get_mesh"), &EditorSceneImporterMeshNode3D::get_mesh);
-
- ClassDB::bind_method(D_METHOD("set_skin", "skin"), &EditorSceneImporterMeshNode3D::set_skin);
- ClassDB::bind_method(D_METHOD("get_skin"), &EditorSceneImporterMeshNode3D::get_skin);
-
- ClassDB::bind_method(D_METHOD("set_skeleton_path", "skeleton_path"), &EditorSceneImporterMeshNode3D::set_skeleton_path);
- ClassDB::bind_method(D_METHOD("get_skeleton_path"), &EditorSceneImporterMeshNode3D::get_skeleton_path);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "EditorSceneImporterMesh"), "set_mesh", "get_mesh");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skin", PROPERTY_HINT_RESOURCE_TYPE, "Skin"), "set_skin", "get_skin");
- ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path");
-}
diff --git a/editor/import/scene_importer_mesh_node_3d.h b/editor/import/scene_importer_mesh_node_3d.h
deleted file mode 100644
index dec1717c99..0000000000
--- a/editor/import/scene_importer_mesh_node_3d.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*************************************************************************/
-/* scene_importer_mesh_node_3d.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef EDITOR_SCENE_IMPORTER_MESH_NODE_3D_H
-#define EDITOR_SCENE_IMPORTER_MESH_NODE_3D_H
-
-#include "editor/import/scene_importer_mesh.h"
-#include "scene/3d/node_3d.h"
-#include "scene/resources/skin.h"
-
-class EditorSceneImporterMesh;
-
-class EditorSceneImporterMeshNode3D : public Node3D {
- GDCLASS(EditorSceneImporterMeshNode3D, Node3D)
-
- Ref<EditorSceneImporterMesh> mesh;
- Ref<Skin> skin;
- NodePath skeleton_path;
- Vector<Ref<Material>> surface_materials;
-
-protected:
- static void _bind_methods();
-
-public:
- void set_mesh(const Ref<EditorSceneImporterMesh> &p_mesh);
- Ref<EditorSceneImporterMesh> get_mesh() const;
-
- void set_skin(const Ref<Skin> &p_skin);
- Ref<Skin> get_skin() const;
-
- void set_surface_material(int p_idx, const Ref<Material> &p_material);
- Ref<Material> get_surface_material(int p_idx) const;
-
- void set_skeleton_path(const NodePath &p_path);
- NodePath get_skeleton_path() const;
-};
-#endif