summaryrefslogtreecommitdiff
path: root/editor/import
diff options
context:
space:
mode:
Diffstat (limited to 'editor/import')
-rw-r--r--editor/import/collada.cpp56
-rw-r--r--editor/import/dynamicfont_import_settings.cpp46
-rw-r--r--editor/import/editor_import_collada.cpp206
-rw-r--r--editor/import/editor_import_collada.h6
-rw-r--r--editor/import/editor_import_plugin.cpp14
-rw-r--r--editor/import/editor_import_plugin.h8
-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.cpp4
-rw-r--r--editor/import/resource_importer_bitmask.h4
-rw-r--r--editor/import/resource_importer_bmfont.cpp33
-rw-r--r--editor/import/resource_importer_bmfont.h4
-rw-r--r--editor/import/resource_importer_csv_translation.cpp4
-rw-r--r--editor/import/resource_importer_csv_translation.h4
-rw-r--r--editor/import/resource_importer_dynamicfont.cpp10
-rw-r--r--editor/import/resource_importer_dynamicfont.h4
-rw-r--r--editor/import/resource_importer_image.cpp4
-rw-r--r--editor/import/resource_importer_image.h4
-rw-r--r--editor/import/resource_importer_imagefont.cpp4
-rw-r--r--editor/import/resource_importer_imagefont.h4
-rw-r--r--editor/import/resource_importer_layered_texture.cpp4
-rw-r--r--editor/import/resource_importer_layered_texture.h6
-rw-r--r--editor/import/resource_importer_obj.cpp22
-rw-r--r--editor/import/resource_importer_obj.h11
-rw-r--r--editor/import/resource_importer_scene.cpp890
-rw-r--r--editor/import/resource_importer_scene.h323
-rw-r--r--editor/import/resource_importer_shader_file.cpp4
-rw-r--r--editor/import/resource_importer_shader_file.h4
-rw-r--r--editor/import/resource_importer_texture.cpp25
-rw-r--r--editor/import/resource_importer_texture.h4
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp17
-rw-r--r--editor/import/resource_importer_texture_atlas.h5
-rw-r--r--editor/import/resource_importer_wav.cpp20
-rw-r--r--editor/import/resource_importer_wav.h4
-rw-r--r--editor/import/scene_import_settings.cpp149
-rw-r--r--editor/import/scene_import_settings.h4
-rw-r--r--editor/import/scene_importer_mesh.cpp861
-rw-r--r--editor/import/scene_importer_mesh.h119
-rw-r--r--editor/import/scene_importer_mesh_node_3d.cpp83
-rw-r--r--editor/import/scene_importer_mesh_node_3d.h64
40 files changed, 1460 insertions, 1866 deletions
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index b6d0927ce6..c34379f1ec 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -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;
}
}
@@ -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--;
}
}
@@ -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/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp
index 37ca40287f..a44ee8a3f6 100644
--- a/editor/import/dynamicfont_import_settings.cpp
+++ b/editor/import/dynamicfont_import_settings.cpp
@@ -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() }
};
@@ -994,9 +1011,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);
}
@@ -1141,8 +1159,8 @@ 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->set_position(lang_list->get_screen_position() + lang_list->get_local_mouse_position());
+ menu_langs->reset_size();
menu_langs->popup();
}
@@ -1168,8 +1186,8 @@ void DynamicFontImportSettings::_lang_remove(Object *p_item, int p_column, int p
}
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();
}
@@ -1799,7 +1817,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);
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 7ab80ac3b4..076c0cc62b 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -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: {
@@ -304,7 +314,7 @@ 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 != "") {
@@ -457,7 +467,7 @@ 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) {
@@ -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);
@@ -1194,7 +1204,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
meshid = ng2->source;
}
- Ref<EditorSceneImporterMesh> mesh;
+ Ref<ImporterMesh> mesh;
if (mesh_cache.has(meshid)) {
mesh = mesh_cache[meshid];
} else {
@@ -1202,7 +1212,7 @@ 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 == "") {
@@ -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
@@ -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, 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,7 +1792,7 @@ 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;
@@ -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, 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..055a6fe178 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -33,8 +33,8 @@
#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;
@@ -42,7 +42,7 @@ public:
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;
- EditorSceneImporterCollada();
+ EditorSceneFormatImporterCollada();
};
#endif
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
index d219f6e325..1a002569c5 100644
--- a/editor/import/editor_import_plugin.cpp
+++ b/editor/import/editor_import_plugin.cpp
@@ -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..6c5f4f6005 100644
--- a/editor/import/editor_import_plugin.h
+++ b/editor/import/editor_import_plugin.h
@@ -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..c43052593d 100644
--- a/editor/import/resource_importer_bitmask.cpp
+++ b/editor/import/resource_importer_bitmask.cpp
@@ -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..f3da5f9a31 100644
--- a/editor/import/resource_importer_bitmask.h
+++ b/editor/import/resource_importer_bitmask.h
@@ -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..f54065416e 100644
--- a/editor/import/resource_importer_bmfont.cpp
+++ b/editor/import/resource_importer_bmfont.cpp
@@ -56,11 +56,11 @@ 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));
}
@@ -359,6 +359,8 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
int height = 0;
int ascent = 0;
int outline = 0;
+ uint32_t st_flags = 0;
+ String font_name;
bool packed = false;
uint8_t ch[4] = { 0, 0, 0, 0 }; // RGBA
@@ -382,13 +384,23 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
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."));
+ if (flags & (1 << 3)) {
+ st_flags |= TextServer::FONT_BOLD;
+ }
+ if (flags & (1 << 2)) {
+ st_flags |= TextServer::FONT_ITALIC;
+ }
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 name
+ PackedByteArray name_data;
+ name_data.resize(block_size - 14);
+ f->get_buffer(name_data.ptrw(), block_size - 14);
+ font_name = String::utf8((const char *)name_data.ptr(), block_size - 14);
font->set_fixed_size(base_size);
} break;
case 2: /* common */ {
@@ -601,6 +613,19 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
if (keys.has("outline")) {
outline = keys["outline"].to_int();
}
+ if (keys.has("bold")) {
+ if (keys["bold"].to_int()) {
+ st_flags |= TextServer::FONT_BOLD;
+ }
+ }
+ if (keys.has("italic")) {
+ if (keys["italic"].to_int()) {
+ st_flags |= TextServer::FONT_ITALIC;
+ }
+ }
+ if (keys.has("face")) {
+ font_name = keys["face"];
+ }
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")) {
@@ -778,6 +803,8 @@ Error ResourceImporterBMFont::import(const String &p_source_file, const String &
}
}
+ font->set_font_name(font_name);
+ font->set_font_style(st_flags);
font->set_ascent(0, base_size, ascent);
font->set_descent(0, base_size, height - ascent);
diff --git a/editor/import/resource_importer_bmfont.h b/editor/import/resource_importer_bmfont.h
index 065703132a..64d536535c 100644
--- a/editor/import/resource_importer_bmfont.h
+++ b/editor/import/resource_importer_bmfont.h
@@ -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..7948d9e577 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -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));
}
diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h
index d53e91e38b..de7ba3e3a0 100644
--- a/editor/import/resource_importer_csv_translation.h
+++ b/editor/import/resource_importer_csv_translation.h
@@ -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..f7363a565d 100644
--- a/editor/import/resource_importer_dynamicfont.cpp
+++ b/editor/import/resource_importer_dynamicfont.cpp
@@ -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));
diff --git a/editor/import/resource_importer_dynamicfont.h b/editor/import/resource_importer_dynamicfont.h
index 52f256ab96..cb5294b9dd 100644
--- a/editor/import/resource_importer_dynamicfont.h
+++ b/editor/import/resource_importer_dynamicfont.h
@@ -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..45cb5e2f9d 100644
--- a/editor/import/resource_importer_image.cpp
+++ b/editor/import/resource_importer_image.cpp
@@ -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..b7131ec850 100644
--- a/editor/import/resource_importer_image.h
+++ b/editor/import/resource_importer_image.h
@@ -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..04a68e4a53 100644
--- a/editor/import/resource_importer_imagefont.cpp
+++ b/editor/import/resource_importer_imagefont.cpp
@@ -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..d600c35e1c 100644
--- a/editor/import/resource_importer_imagefont.h
+++ b/editor/import/resource_importer_imagefont.h
@@ -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..89c62ab5cb 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -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));
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 86e9c5bde8..29dfe7263a 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -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..bb68de99b1 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -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"
@@ -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;
}
@@ -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);
}
@@ -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..c3e46b6eb5 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -33,8 +33,8 @@
#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;
@@ -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 c2244befa1..a25b694a60 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -32,11 +32,11 @@
#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,7 +73,7 @@ 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) {
+Node *EditorSceneFormatImporter::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)) {
return Object::cast_to<Node>(ret);
@@ -81,7 +82,7 @@ Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags,
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, int p_bake_fps) {
Ref<Animation> ret;
if (GDVIRTUAL_CALL(_import_animation, p_path, p_flags, p_bake_fps, ret)) {
return ret;
@@ -90,25 +91,37 @@ Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint3
ERR_FAIL_V(nullptr);
}
+void EditorSceneFormatImporter::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) {
+ GDVIRTUAL_CALL(_get_import_options, p_path);
+}
+
+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;
+}
+
//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) {
+Node *EditorSceneFormatImporter::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);
}
-Ref<Animation> EditorSceneImporter::import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorSceneFormatImporter::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);
}
-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() {
+ ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneFormatImporter::import_scene_from_other_importer);
+ ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneFormatImporter::import_animation_from_other_importer);
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(_get_import_options, "path");
+ GDVIRTUAL_BIND(_get_option_visibility, "path", "option");
BIND_CONSTANT(IMPORT_SCENE);
BIND_CONSTANT(IMPORT_ANIMATION);
@@ -143,6 +156,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 +264,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 +281,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 +292,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,13 +359,15 @@ static String _fixstr(const String &p_what, const String &p_str) {
return what;
}
-static void _pre_gen_shape_list(const Ref<EditorSceneImporterMesh> &mesh, List<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);
} else {
- Vector<Ref<Shape3D>> cd = mesh->convex_decompose();
+ Vector<Ref<Shape3D>> cd;
+ cd.push_back(mesh->get_mesh()->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
if (cd.size()) {
for (int i = 0; i < cd.size(); i++) {
r_shape_list.push_back(cd[i]);
@@ -248,7 +376,7 @@ static void _pre_gen_shape_list(const Ref<EditorSceneImporterMesh> &mesh, List<R
}
}
-Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map) {
+Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map) {
// 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);
@@ -266,10 +394,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++) {
@@ -315,10 +443,10 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
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);
}
@@ -330,12 +458,12 @@ 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);
+ 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()) {
- List<Ref<Shape3D>> shapes;
+ Vector<Ref<Shape3D>> shapes;
String fixed_name;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
@@ -386,52 +514,52 @@ 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()) {
- List<Ref<Shape3D>> shapes;
+ Vector<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
} else {
_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()) {
- List<Ref<Shape3D>> shapes;
+ Vector<Ref<Shape3D>> shapes;
String fixed_name;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
@@ -457,21 +585,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);
@@ -483,14 +611,14 @@ 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()) {
- List<Ref<Shape3D>> shapes;
+ Vector<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
} else if (_teststr(mesh->get_name(), "col")) {
@@ -505,7 +633,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);
@@ -516,7 +644,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E
return p_node;
}
-Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<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);
@@ -545,10 +673,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;
+ }
+ }
+ }
- Ref<EditorSceneImporterMesh> m = mi->get_mesh();
+ 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<ImporterMesh> m = mi->get_mesh();
if (m.is_valid()) {
if (!r_scanned_meshes.has(m)) {
@@ -564,6 +712,11 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
if (mat_id != String() && 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);
@@ -579,28 +732,35 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
}
if (node_settings.has("generate/physics")) {
- int mesh_physics_mode = node_settings["generate/physics"];
-
- if (mesh_physics_mode != MESH_PHYSICS_DISABLED) {
- List<Ref<Shape3D>> shapes;
+ int mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_DISABLED;
+
+ const bool generate_collider = node_settings["generate/physics"];
+ if (generate_collider) {
+ mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_MESH_AND_STATIC_COLLIDER;
+ if (node_settings.has("physics/body_type")) {
+ const BodyType body_type = (BodyType)node_settings["physics/body_type"].operator int();
+ switch (body_type) {
+ case BODY_TYPE_STATIC:
+ mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_MESH_AND_STATIC_COLLIDER;
+ break;
+ case BODY_TYPE_DYNAMIC:
+ mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_RIGID_BODY_AND_MESH;
+ break;
+ case BODY_TYPE_AREA:
+ mesh_physics_mode = MeshPhysicsMode::MESH_PHYSICS_AREA_ONLY;
+ break;
+ }
+ }
+ }
+ if (mesh_physics_mode != MeshPhysicsMode::MESH_PHYSICS_DISABLED) {
+ Vector<Ref<Shape3D>> shapes;
if (collision_map.has(m)) {
shapes = collision_map[m];
} else {
- switch (mesh_physics_mode) {
- case MESH_PHYSICS_MESH_AND_STATIC_COLLIDER: {
- _pre_gen_shape_list(m, shapes, false);
- } break;
- case MESH_PHYSICS_RIGID_BODY_AND_MESH: {
- _pre_gen_shape_list(m, shapes, true);
- } break;
- case MESH_PHYSICS_STATIC_COLLIDER_ONLY: {
- _pre_gen_shape_list(m, shapes, false);
- } break;
- case MESH_PHYSICS_AREA_ONLY: {
- _pre_gen_shape_list(m, shapes, true);
- } break;
- }
+ shapes = get_collision_shapes(
+ m->get_mesh(),
+ node_settings);
}
if (shapes.size()) {
@@ -608,23 +768,25 @@ 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());
+ 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;
case MESH_PHYSICS_STATIC_COLLIDER_ONLY: {
StaticBody3D *col = memnew(StaticBody3D);
- col->set_transform(mi->get_transform());
+ col->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
col->set_name(p_node->get_name());
p_node->replace_by(col);
memdelete(p_node);
@@ -633,7 +795,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref<
} break;
case MESH_PHYSICS_AREA_ONLY: {
Area3D *area = memnew(Area3D);
- area->set_transform(mi->get_transform());
+ area->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
area->set_name(p_node->get_name());
p_node->replace_by(area);
memdelete(p_node);
@@ -647,7 +809,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++;
@@ -659,10 +821,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")) {
@@ -680,7 +842,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());
}
}
@@ -704,6 +866,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"];
@@ -721,7 +887,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"];
@@ -729,7 +895,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);
@@ -756,7 +922,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"];
@@ -768,6 +934,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);
}
}
@@ -788,7 +996,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());
}
}
@@ -816,7 +1024,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];
@@ -840,44 +1048,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);
}
}
}
@@ -886,25 +1121,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);
@@ -926,6 +1176,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: {
@@ -933,8 +1192,35 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
} break;
case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/physics", PROPERTY_HINT_ENUM, "Disabled,Mesh + Static Collider,Rigid Body + Mesh,Static Collider Only,Area Only"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate/physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/navmesh", PROPERTY_HINT_ENUM, "Disabled,Mesh + NavMesh,NavMesh Only"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/body_type", PROPERTY_HINT_ENUM, "Static,Dynamic,Area"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "physics/shape_type", PROPERTY_HINT_ENUM, "Decompose Convex,Simple Convex,Trimesh,Box,Sphere,Cylinder,Capsule", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
+
+ // Decomposition
+ Mesh::ConvexDecompositionSettings decomposition_default;
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/advanced", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/precision", PROPERTY_HINT_RANGE, "1,10,1"), 5));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/max_concavity", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_concavity));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/symmetry_planes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.symmetry_planes_clipping_bias));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/revolution_axes_clipping_bias", PROPERTY_HINT_RANGE, "0.0,1.0,0.001", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.revolution_axes_clipping_bias));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "decomposition/min_volume_per_convex_hull", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.min_volume_per_convex_hull));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/resolution", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.resolution));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_num_vertices_per_convex_hull", PROPERTY_HINT_RANGE, "5,512,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_num_vertices_per_convex_hull));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/plane_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.plane_downsampling));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/convexhull_downsampling", PROPERTY_HINT_RANGE, "1,16,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.convexhull_downsampling));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/normalize_mesh", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.normalize_mesh));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/mode", PROPERTY_HINT_ENUM, "Voxel,Tetrahedron", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), static_cast<int>(decomposition_default.mode)));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/convexhull_approximation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.convexhull_approximation));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "decomposition/max_convex_hulls", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.max_convex_hulls));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "decomposition/project_hull_vertices", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), decomposition_default.project_hull_vertices));
+
+ // Primitives: Box, Sphere, Cylinder, Capsule.
+ r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3(2.0, 2.0, 2.0)));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/height", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1.0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "primitive/radius", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1.0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3()));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "primitive/rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Vector3()));
} break;
case INTERNAL_IMPORT_CATEGORY_MESH: {
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));
@@ -943,13 +1229,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"), ""));
@@ -960,13 +1248,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));
@@ -975,6 +1268,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 {
@@ -985,6 +1282,66 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
case INTERNAL_IMPORT_CATEGORY_NODE: {
} break;
case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
+ const bool generate_physics =
+ p_options.has("generate/physics") &&
+ p_options["generate/physics"].operator bool();
+
+ if (
+ p_option == "physics/body_type" ||
+ p_option == "physics/shape_type") {
+ // Show if need to generate collisions.
+ return generate_physics;
+ }
+
+ if (p_option.find("decomposition/") >= 0) {
+ // Show if need to generate collisions.
+ if (generate_physics &&
+ // Show if convex is enabled.
+ p_options["physics/shape_type"] == Variant(SHAPE_TYPE_DECOMPOSE_CONVEX)) {
+ if (p_option == "decomposition/advanced") {
+ return true;
+ }
+
+ const bool decomposition_advanced =
+ p_options.has("decomposition/advanced") &&
+ p_options["decomposition/advanced"].operator bool();
+
+ if (p_option == "decomposition/precision") {
+ return !decomposition_advanced;
+ } else {
+ return decomposition_advanced;
+ }
+ }
+
+ return false;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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);
+ }
+
+ 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);
+ }
} break;
case INTERNAL_IMPORT_CATEGORY_MESH: {
if (p_option == "save_to_file/path" || p_option == "save_to_file/make_streamable") {
@@ -1002,13 +1359,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;
}
@@ -1018,10 +1378,52 @@ 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;
}
-void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+bool ResourceImporterScene::get_internal_option_update_view_required(InternalImportCategory p_category, const String &p_option, const Map<StringName, Variant> &p_options) const {
+ switch (p_category) {
+ case INTERNAL_IMPORT_CATEGORY_NODE: {
+ } break;
+ case INTERNAL_IMPORT_CATEGORY_MESH_3D_NODE: {
+ if (
+ p_option == "generate/physics" ||
+ p_option == "physics/shape_type" ||
+ p_option.find("decomposition/") >= 0 ||
+ p_option.find("primitive/") >= 0) {
+ return true;
+ }
+ } break;
+ case INTERNAL_IMPORT_CATEGORY_MESH: {
+ } break;
+ case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
+ } break;
+ case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
+ } break;
+ case INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE: {
+ } break;
+ 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(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"));
@@ -1045,11 +1447,18 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
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) {
@@ -1063,11 +1472,11 @@ 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;
+Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
+ Ref<EditorSceneFormatImporter> importer;
String ext = p_path.get_extension().to_lower();
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
+ for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
if (E->get().ptr() == p_exception) {
continue;
}
@@ -1076,7 +1485,7 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte
for (const String &F : extensions) {
if (F.to_lower() == ext) {
- importer = E;
+ importer = E->get();
break;
}
}
@@ -1093,11 +1502,11 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte
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;
+Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
+ Ref<EditorSceneFormatImporter> importer;
String ext = p_path.get_extension().to_lower();
- for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
+ for (Set<Ref<EditorSceneFormatImporter>>::Element *E = importers.front(); E; E = E->next()) {
if (E->get().ptr() == p_exception) {
continue;
}
@@ -1106,7 +1515,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito
for (const String &F : extensions) {
if (F.to_lower() == ext) {
- importer = E;
+ importer = E->get();
break;
}
}
@@ -1122,7 +1531,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito
}
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);
@@ -1136,6 +1545,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;
@@ -1178,17 +1589,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();
}
@@ -1275,24 +1699,174 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m
}
}
-void ResourceImporterScene::_add_shapes(Node *p_node, const List<Ref<Shape3D>> &p_shapes) {
+void ResourceImporterScene::_add_shapes(Node *p_node, const Vector<Ref<Shape3D>> &p_shapes) {
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;
+ }
+ 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);
@@ -1311,12 +1885,12 @@ 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, 15, nullptr, &err);
if (!scene || err != OK) {
return nullptr;
}
- Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> collision_map;
+ Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
_pre_fix_node(scene, scene, collision_map);
@@ -1326,13 +1900,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);
@@ -1355,16 +1929,16 @@ 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;
@@ -1391,17 +1965,17 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
animation_data = subresources["animations"];
}
- Set<Ref<EditorSceneImporterMesh>> scanned_meshes;
- Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> collision_map;
+ Set<Ref<ImporterMesh>> scanned_meshes;
+ Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
_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");
+
+ 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.
@@ -1503,6 +2077,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);
@@ -1534,15 +2112,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, 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 + "'.");
@@ -1553,6 +2131,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, 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 542959be02..5437ecd159 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -41,9 +41,9 @@
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();
@@ -55,6 +55,8 @@ protected:
GDVIRTUAL0RC(Vector<String>, _get_extensions)
GDVIRTUAL3R(Object *, _import_scene, String, uint32_t, uint32_t)
GDVIRTUAL3R(Ref<Animation>, _import_animation, String, uint32_t, uint32_t)
+ GDVIRTUAL1(_get_import_options, String)
+ GDVIRTUAL2RC(Variant, _get_option_visibility, String, String)
public:
enum ImportFlags {
@@ -63,15 +65,16 @@ public:
IMPORT_FAIL_ON_MISSING_DEPENDENCIES = 4,
IMPORT_GENERATE_TANGENT_ARRAYS = 8,
IMPORT_USE_NAMED_SKIN_BINDS = 16,
-
};
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 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 {
@@ -91,10 +94,64 @@ 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;
@@ -125,17 +182,53 @@ class ResourceImporterScene : public ResourceImporter {
MESH_OVERRIDE_DISABLE,
};
+ enum BodyType {
+ BODY_TYPE_STATIC,
+ BODY_TYPE_DYNAMIC,
+ BODY_TYPE_AREA
+ };
+
+ enum ShapeType {
+ SHAPE_TYPE_DECOMPOSE_CONVEX,
+ SHAPE_TYPE_SIMPLE_CONVEX,
+ SHAPE_TYPE_TRIMESH,
+ SHAPE_TYPE_BOX,
+ SHAPE_TYPE_SPHERE,
+ SHAPE_TYPE_CYLINDER,
+ SHAPE_TYPE_CAPSULE,
+ };
+
void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
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 List<Ref<Shape3D>> &p_shapes);
+ 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); }
- void add_importer(Ref<EditorSceneImporter> p_importer) { importers.insert(p_importer); }
- void remove_importer(Ref<EditorSceneImporter> p_importer) { importers.erase(p_importer); }
+ const Set<Ref<EditorSceneFormatImporter>> &get_importers() const { return importers; }
+
+ 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;
@@ -148,35 +241,37 @@ 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>, List<Ref<Shape3D>>> &collision_map);
- Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<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);
+ 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);
+ Node *import_scene_from_other_importer(EditorSceneFormatImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
+ Ref<Animation> import_animation_from_other_importer(EditorSceneFormatImporter *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;
@@ -184,10 +279,16 @@ public:
virtual bool can_import_threaded() const override { return false; }
ResourceImporterScene();
+
+ template <class M>
+ static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options);
+
+ template <class M>
+ 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;
@@ -196,4 +297,176 @@ public:
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) override;
};
+#include "scene/resources/box_shape_3d.h"
+#include "scene/resources/capsule_shape_3d.h"
+#include "scene/resources/cylinder_shape_3d.h"
+#include "scene/resources/sphere_shape_3d.h"
+
+template <class M>
+Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options) {
+ ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
+ if (p_options.has(SNAME("physics/shape_type"))) {
+ generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
+ }
+
+ if (generate_shape_type == SHAPE_TYPE_DECOMPOSE_CONVEX) {
+ Mesh::ConvexDecompositionSettings decomposition_settings;
+ bool advanced = false;
+ if (p_options.has(SNAME("decomposition/advanced"))) {
+ advanced = p_options[SNAME("decomposition/advanced")];
+ }
+
+ if (advanced) {
+ if (p_options.has(SNAME("decomposition/max_concavity"))) {
+ decomposition_settings.max_concavity = p_options[SNAME("decomposition/max_concavity")];
+ }
+
+ if (p_options.has(SNAME("decomposition/symmetry_planes_clipping_bias"))) {
+ decomposition_settings.symmetry_planes_clipping_bias = p_options[SNAME("decomposition/symmetry_planes_clipping_bias")];
+ }
+
+ if (p_options.has(SNAME("decomposition/revolution_axes_clipping_bias"))) {
+ decomposition_settings.revolution_axes_clipping_bias = p_options[SNAME("decomposition/revolution_axes_clipping_bias")];
+ }
+
+ if (p_options.has(SNAME("decomposition/min_volume_per_convex_hull"))) {
+ decomposition_settings.min_volume_per_convex_hull = p_options[SNAME("decomposition/min_volume_per_convex_hull")];
+ }
+
+ if (p_options.has(SNAME("decomposition/resolution"))) {
+ decomposition_settings.resolution = p_options[SNAME("decomposition/resolution")];
+ }
+
+ if (p_options.has(SNAME("decomposition/max_num_vertices_per_convex_hull"))) {
+ decomposition_settings.max_num_vertices_per_convex_hull = p_options[SNAME("decomposition/max_num_vertices_per_convex_hull")];
+ }
+
+ if (p_options.has(SNAME("decomposition/plane_downsampling"))) {
+ decomposition_settings.plane_downsampling = p_options[SNAME("decomposition/plane_downsampling")];
+ }
+
+ if (p_options.has(SNAME("decomposition/convexhull_downsampling"))) {
+ decomposition_settings.convexhull_downsampling = p_options[SNAME("decomposition/convexhull_downsampling")];
+ }
+
+ if (p_options.has(SNAME("decomposition/normalize_mesh"))) {
+ decomposition_settings.normalize_mesh = p_options[SNAME("decomposition/normalize_mesh")];
+ }
+
+ if (p_options.has(SNAME("decomposition/mode"))) {
+ decomposition_settings.mode = (Mesh::ConvexDecompositionSettings::Mode)p_options[SNAME("decomposition/mode")].operator int();
+ }
+
+ if (p_options.has(SNAME("decomposition/convexhull_approximation"))) {
+ decomposition_settings.convexhull_approximation = p_options[SNAME("decomposition/convexhull_approximation")];
+ }
+
+ if (p_options.has(SNAME("decomposition/max_convex_hulls"))) {
+ decomposition_settings.max_convex_hulls = p_options[SNAME("decomposition/max_convex_hulls")];
+ }
+
+ if (p_options.has(SNAME("decomposition/project_hull_vertices"))) {
+ decomposition_settings.project_hull_vertices = p_options[SNAME("decomposition/project_hull_vertices")];
+ }
+ } else {
+ int precision_level = 5;
+ if (p_options.has(SNAME("decomposition/precision"))) {
+ precision_level = p_options[SNAME("decomposition/precision")];
+ }
+
+ const real_t precision = real_t(precision_level - 1) / 9.0;
+
+ decomposition_settings.max_concavity = Math::lerp(real_t(1.0), real_t(0.001), precision);
+ decomposition_settings.min_volume_per_convex_hull = Math::lerp(real_t(0.01), real_t(0.0001), precision);
+ decomposition_settings.resolution = Math::lerp(10'000, 100'000, precision);
+ decomposition_settings.max_num_vertices_per_convex_hull = Math::lerp(32, 64, precision);
+ decomposition_settings.plane_downsampling = Math::lerp(3, 16, precision);
+ decomposition_settings.convexhull_downsampling = Math::lerp(3, 16, precision);
+ decomposition_settings.max_convex_hulls = Math::lerp(1, 32, precision);
+ }
+
+ return p_mesh->convex_decompose(decomposition_settings);
+ } else if (generate_shape_type == SHAPE_TYPE_SIMPLE_CONVEX) {
+ Vector<Ref<Shape3D>> shapes;
+ shapes.push_back(p_mesh->create_convex_shape(true, /*Passing false, otherwise VHACD will be used to simplify (Decompose) the Mesh.*/ false));
+ return shapes;
+ } else if (generate_shape_type == SHAPE_TYPE_TRIMESH) {
+ Vector<Ref<Shape3D>> shapes;
+ shapes.push_back(p_mesh->create_trimesh_shape());
+ return shapes;
+ } else if (generate_shape_type == SHAPE_TYPE_BOX) {
+ Ref<BoxShape3D> box;
+ box.instantiate();
+ if (p_options.has(SNAME("primitive/size"))) {
+ box->set_size(p_options[SNAME("primitive/size")]);
+ }
+
+ Vector<Ref<Shape3D>> shapes;
+ shapes.push_back(box);
+ return shapes;
+
+ } else if (generate_shape_type == SHAPE_TYPE_SPHERE) {
+ Ref<SphereShape3D> sphere;
+ sphere.instantiate();
+ if (p_options.has(SNAME("primitive/radius"))) {
+ sphere->set_radius(p_options[SNAME("primitive/radius")]);
+ }
+
+ Vector<Ref<Shape3D>> shapes;
+ shapes.push_back(sphere);
+ return shapes;
+ } else if (generate_shape_type == SHAPE_TYPE_CYLINDER) {
+ Ref<CylinderShape3D> cylinder;
+ cylinder.instantiate();
+ if (p_options.has(SNAME("primitive/height"))) {
+ cylinder->set_height(p_options[SNAME("primitive/height")]);
+ }
+ if (p_options.has(SNAME("primitive/radius"))) {
+ cylinder->set_radius(p_options[SNAME("primitive/radius")]);
+ }
+
+ Vector<Ref<Shape3D>> shapes;
+ shapes.push_back(cylinder);
+ return shapes;
+ } else if (generate_shape_type == SHAPE_TYPE_CAPSULE) {
+ Ref<CapsuleShape3D> capsule;
+ capsule.instantiate();
+ if (p_options.has(SNAME("primitive/height"))) {
+ capsule->set_height(p_options[SNAME("primitive/height")]);
+ }
+ if (p_options.has(SNAME("primitive/radius"))) {
+ capsule->set_radius(p_options[SNAME("primitive/radius")]);
+ }
+
+ Vector<Ref<Shape3D>> shapes;
+ shapes.push_back(capsule);
+ return shapes;
+ }
+ return Vector<Ref<Shape3D>>();
+}
+
+template <class M>
+Transform3D ResourceImporterScene::get_collision_shapes_transform(const M &p_options) {
+ Transform3D transform;
+
+ ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
+ if (p_options.has(SNAME("physics/shape_type"))) {
+ generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
+ }
+
+ if (generate_shape_type == SHAPE_TYPE_BOX ||
+ generate_shape_type == SHAPE_TYPE_SPHERE ||
+ generate_shape_type == SHAPE_TYPE_CYLINDER ||
+ generate_shape_type == SHAPE_TYPE_CAPSULE) {
+ if (p_options.has(SNAME("primitive/position"))) {
+ transform.origin = p_options[SNAME("primitive/position")];
+ }
+
+ if (p_options.has(SNAME("primitive/rotation"))) {
+ transform.basis.set_euler((p_options[SNAME("primitive/rotation")].operator Vector3() / 180.0) * Math_PI);
+ }
+ }
+ return transform;
+}
+
#endif // RESOURCEIMPORTERSCENE_H
diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp
index c01d8068da..797e11f5ea 100644
--- a/editor/import/resource_importer_shader_file.cpp
+++ b/editor/import/resource_importer_shader_file.cpp
@@ -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..3ed489e9fb 100644
--- a/editor/import/resource_importer_shader_file.h
+++ b/editor/import/resource_importer_shader_file.h
@@ -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 daf7b15794..b1fa2eda28 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -86,28 +86,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 +121,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 +153,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 +194,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));
@@ -218,7 +218,8 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
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());
@@ -393,7 +394,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
float lossy = p_options["compress/lossy_quality"];
int pack_channels = p_options["compress/channel_pack"];
bool mipmaps = p_options["mipmaps/generate"];
- uint32_t mipmap_limit = int(mipmaps ? int(p_options["mipmaps/limit"]) : int(-1));
+ uint32_t mipmap_limit = mipmaps ? uint32_t(p_options["mipmaps/limit"]) : uint32_t(-1);
bool fix_alpha_border = p_options["process/fix_alpha_border"];
bool premult_alpha = p_options["process/premult_alpha"];
bool normal_map_invert_y = p_options["process/normal_map_invert_y"];
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index 41220009cd..cb9d1b08cd 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -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..048d84d1f9 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -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..177ef949ac 100644
--- a/editor/import/resource_importer_texture_atlas.h
+++ b/editor/import/resource_importer_texture_atlas.h
@@ -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..820eba951f 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -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..e3e605aeb2 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -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 19a8f209bb..5690d49a55 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -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 {
@@ -53,6 +54,11 @@ class SceneImportSettingsData : public Object {
}
current[p_name] = p_value;
+
+ if (ResourceImporterScene::get_singleton()->get_internal_option_update_view_required(category, p_name, current)) {
+ SceneImportSettings::get_singleton()->update_view();
+ }
+
return true;
}
return false;
@@ -235,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);
@@ -244,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());
}
@@ -317,6 +323,13 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) {
if (mesh_node && mesh_node->get_mesh().is_valid()) {
_fill_mesh(scene_tree, mesh_node->get_mesh(), item);
+ // Add the collider view.
+ MeshInstance3D *collider_view = memnew(MeshInstance3D);
+ collider_view->set_name("collider_view");
+ collider_view->set_visible(false);
+ mesh_node->add_child(collider_view, true);
+ collider_view->set_owner(mesh_node);
+
Transform3D accum_xform;
Node3D *base = mesh_node;
while (base) {
@@ -346,6 +359,54 @@ void SceneImportSettings::_update_scene() {
_fill_scene(scene, nullptr);
}
+void SceneImportSettings::_update_view_gizmos() {
+ for (const KeyValue<String, NodeData> &e : node_map) {
+ bool generate_collider = false;
+ if (e.value.settings.has(SNAME("generate/physics"))) {
+ generate_collider = e.value.settings[SNAME("generate/physics")];
+ }
+
+ MeshInstance3D *mesh_node = Object::cast_to<MeshInstance3D>(e.value.node);
+ if (mesh_node == nullptr || mesh_node->get_mesh().is_null()) {
+ // Nothing to do
+ continue;
+ }
+
+ MeshInstance3D *collider_view = static_cast<MeshInstance3D *>(mesh_node->find_node("collider_view"));
+ CRASH_COND_MSG(collider_view == nullptr, "This is unreachable, since the collider view is always created even when the collision is not used! If this is triggered there is a bug on the function `_fill_scene`.");
+
+ collider_view->set_visible(generate_collider);
+ if (generate_collider) {
+ // This collider_view doesn't have a mesh so we need to generate a new one.
+
+ // Generate the mesh collider.
+ Vector<Ref<Shape3D>> shapes = ResourceImporterScene::get_collision_shapes(mesh_node->get_mesh(), e.value.settings);
+ const Transform3D transform = ResourceImporterScene::get_collision_shapes_transform(e.value.settings);
+
+ Ref<ArrayMesh> collider_view_mesh;
+ collider_view_mesh.instantiate();
+ for (Ref<Shape3D> shape : shapes) {
+ Ref<ArrayMesh> debug_shape_mesh;
+ if (shape.is_valid()) {
+ debug_shape_mesh = shape->get_debug_mesh();
+ }
+ if (debug_shape_mesh.is_valid()) {
+ collider_view_mesh->add_surface_from_arrays(
+ debug_shape_mesh->surface_get_primitive_type(0),
+ debug_shape_mesh->surface_get_arrays(0));
+
+ collider_view_mesh->surface_set_material(
+ collider_view_mesh->get_surface_count() - 1,
+ collider_mat);
+ }
+ }
+
+ collider_view->set_mesh(collider_view_mesh);
+ collider_view->set_transform(transform);
+ }
+ }
+}
+
void SceneImportSettings::_update_camera() {
AABB camera_aabb;
@@ -374,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);
@@ -404,11 +465,16 @@ void SceneImportSettings::_load_default_subresource_settings(Map<StringName, Var
}
}
+void SceneImportSettings::update_view() {
+ _update_view_gizmos();
+}
+
void SceneImportSettings::open_settings(const String &p_path) {
if (scene) {
memdelete(scene);
scene = nullptr;
}
+ scene_import_settings_data->settings = nullptr;
scene = ResourceImporterScene::get_singleton()->pre_import(p_path);
if (scene == nullptr) {
EditorNode::get_singleton()->show_warning(TTR("Error opening scene"));
@@ -463,6 +529,7 @@ void SceneImportSettings::open_settings(const String &p_path) {
}
popup_centered_ratio();
+ _update_view_gizmos();
_update_camera();
set_title(vformat(TTR("Advanced Import Settings for '%s'"), base_path.get_file()));
@@ -597,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);
}
@@ -629,6 +696,7 @@ void SceneImportSettings::_material_tree_selected() {
_select(material_tree, type, import_id);
}
+
void SceneImportSettings::_mesh_tree_selected() {
if (selecting) {
return;
@@ -640,6 +708,7 @@ void SceneImportSettings::_mesh_tree_selected() {
_select(mesh_tree, type, import_id);
}
+
void SceneImportSettings::_scene_tree_selected() {
if (selecting) {
return;
@@ -668,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;
@@ -703,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()) {
@@ -821,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);
@@ -837,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);
@@ -874,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);
@@ -890,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);
@@ -927,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);
@@ -942,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);
@@ -1144,6 +1213,12 @@ SceneImportSettings::SceneImportSettings() {
material_preview.instantiate();
}
+ {
+ collider_mat.instantiate();
+ collider_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ collider_mat->set_albedo(Color(0.5, 0.5, 1.0));
+ }
+
inspector = memnew(EditorInspector);
inspector->set_custom_minimum_size(Size2(300 * EDSCALE, 0));
diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h
index ddcf4a6d5d..c7c94af493 100644
--- a/editor/import/scene_import_settings.h
+++ b/editor/import/scene_import_settings.h
@@ -84,6 +84,8 @@ class SceneImportSettings : public ConfirmationDialog {
MeshInstance3D *mesh_preview;
Ref<SphereMesh> material_preview;
+ Ref<StandardMaterial3D> collider_mat;
+
float cam_rot_x;
float cam_rot_y;
float cam_zoom;
@@ -145,6 +147,7 @@ class SceneImportSettings : public ConfirmationDialog {
bool selecting = false;
+ void _update_view_gizmos();
void _update_camera();
void _select(Tree *p_from, String p_type, String p_id);
void _material_tree_selected();
@@ -190,6 +193,7 @@ protected:
void _notification(int p_what);
public:
+ void update_view();
void open_settings(const String &p_path);
static SceneImportSettings *get_singleton();
SceneImportSettings();
diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp
deleted file mode 100644
index 06f373c54f..0000000000
--- a/editor/import/scene_importer_mesh.cpp
+++ /dev/null
@@ -1,861 +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"
-
-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) {
- 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;
-
- 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;
-}
-
-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);
- 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);
- }
-}
-
-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"];
- }
- add_surface(prim, arr, blend_shapes, lods, material, name);
- }
- }
-}
-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;
- }
-
- 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 {
- ERR_FAIL_COND_V(!Mesh::convex_composition_function, Vector<Ref<Shape3D>>());
-
- const Vector<Face3> faces = get_faces();
-
- Vector<Vector<Face3>> decomposed = Mesh::convex_composition_function(faces, -1);
-
- Vector<Ref<Shape3D>> ret;
-
- for (int i = 0; i < decomposed.size(); i++) {
- Set<Vector3> points;
- for (int j = 0; j < decomposed[i].size(); j++) {
- points.insert(decomposed[i][j].vertex[0]);
- points.insert(decomposed[i][j].vertex[1]);
- points.insert(decomposed[i][j].vertex[2]);
- }
-
- Vector<Vector3> convex_points;
- convex_points.resize(points.size());
- {
- Vector3 *w = convex_points.ptrw();
- int idx = 0;
- for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) {
- w[idx++] = E->get();
- }
- }
-
- Ref<ConvexPolygonShape3D> shape;
- shape.instantiate();
- shape->set_points(convex_points);
- 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"), &EditorSceneImporterMesh::add_surface, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(Ref<Material>()), DEFVAL(String()));
-
- 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("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 e57e479d8e..0000000000
--- a/editor/import/scene_importer_mesh.h
+++ /dev/null
@@ -1,119 +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"
-// 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;
- };
- 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());
- 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;
-
- 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;
- 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