|
@@ -78,108 +78,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
|
|
|
HashMap<int, MeshInstance3D *> mesh_instances;
|
|
|
|
|
|
for (int i = 0; i < p_scene->get_child_count(); i++) {
|
|
|
- Node *child = p_scene->get_child(i);
|
|
|
-
|
|
|
- if (!Object::cast_to<MeshInstance3D>(child)) {
|
|
|
- if (child->get_child_count() > 0) {
|
|
|
- child = child->get_child(0);
|
|
|
- if (!Object::cast_to<MeshInstance3D>(child)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(child);
|
|
|
- Ref<Mesh> mesh = mi->get_mesh();
|
|
|
- if (mesh.is_null()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- mesh = mesh->duplicate();
|
|
|
- for (int j = 0; j < mesh->get_surface_count(); ++j) {
|
|
|
- Ref<Material> mat = mi->get_surface_override_material(j);
|
|
|
-
|
|
|
- if (mat.is_valid()) {
|
|
|
- mesh->surface_set_material(j, mat);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- int id = p_library->find_item_by_name(mi->get_name());
|
|
|
- if (id < 0) {
|
|
|
- id = p_library->get_last_unused_item_id();
|
|
|
- p_library->create_item(id);
|
|
|
- p_library->set_item_name(id, mi->get_name());
|
|
|
- }
|
|
|
-
|
|
|
- p_library->set_item_mesh(id, mesh);
|
|
|
-
|
|
|
- if (p_apply_xforms) {
|
|
|
- p_library->set_item_mesh_transform(id, mi->get_transform());
|
|
|
- } else {
|
|
|
- p_library->set_item_mesh_transform(id, Transform3D());
|
|
|
- }
|
|
|
-
|
|
|
- mesh_instances[id] = mi;
|
|
|
-
|
|
|
- Vector<MeshLibrary::ShapeData> collisions;
|
|
|
-
|
|
|
- for (int j = 0; j < mi->get_child_count(); j++) {
|
|
|
- Node *child2 = mi->get_child(j);
|
|
|
- if (!Object::cast_to<StaticBody3D>(child2)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- StaticBody3D *sb = Object::cast_to<StaticBody3D>(child2);
|
|
|
- List<uint32_t> shapes;
|
|
|
- sb->get_shape_owners(&shapes);
|
|
|
-
|
|
|
- for (uint32_t &E : shapes) {
|
|
|
- if (sb->is_shape_owner_disabled(E)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Transform3D shape_transform;
|
|
|
- if (p_apply_xforms) {
|
|
|
- shape_transform = mi->get_transform();
|
|
|
- }
|
|
|
- shape_transform *= sb->get_transform() * sb->shape_owner_get_transform(E);
|
|
|
-
|
|
|
- for (int k = 0; k < sb->shape_owner_get_shape_count(E); k++) {
|
|
|
- Ref<Shape3D> collision = sb->shape_owner_get_shape(E, k);
|
|
|
- if (!collision.is_valid()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- MeshLibrary::ShapeData shape_data;
|
|
|
- shape_data.shape = collision;
|
|
|
- shape_data.local_transform = shape_transform;
|
|
|
- collisions.push_back(shape_data);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- p_library->set_item_shapes(id, collisions);
|
|
|
-
|
|
|
- Ref<NavigationMesh> navigation_mesh;
|
|
|
- Transform3D navigation_mesh_transform;
|
|
|
- for (int j = 0; j < mi->get_child_count(); j++) {
|
|
|
- Node *child2 = mi->get_child(j);
|
|
|
- if (!Object::cast_to<NavigationRegion3D>(child2)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- NavigationRegion3D *sb = Object::cast_to<NavigationRegion3D>(child2);
|
|
|
- navigation_mesh = sb->get_navigation_mesh();
|
|
|
- navigation_mesh_transform = sb->get_transform();
|
|
|
- if (!navigation_mesh.is_null()) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (!navigation_mesh.is_null()) {
|
|
|
- p_library->set_item_navigation_mesh(id, navigation_mesh);
|
|
|
- p_library->set_item_navigation_mesh_transform(id, navigation_mesh_transform);
|
|
|
- }
|
|
|
+ _import_scene_parse_node(p_library, mesh_instances, p_scene->get_child(i), p_merge, p_apply_xforms);
|
|
|
}
|
|
|
|
|
|
//generate previews!
|
|
@@ -221,6 +120,93 @@ void MeshLibraryEditor::_import_scene_cbk(const String &p_str) {
|
|
|
menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE), false);
|
|
|
}
|
|
|
|
|
|
+void MeshLibraryEditor::_import_scene_parse_node(Ref<MeshLibrary> p_library, HashMap<int, MeshInstance3D *> &p_mesh_instances, Node *p_node, bool p_merge, bool p_apply_xforms) {
|
|
|
+ MeshInstance3D *mesh_instance_node = Object::cast_to<MeshInstance3D>(p_node);
|
|
|
+
|
|
|
+ if (!mesh_instance_node) {
|
|
|
+ // No MeshInstance so search deeper ...
|
|
|
+ for (int i = 0; i < p_node->get_child_count(); i++) {
|
|
|
+ _import_scene_parse_node(p_library, p_mesh_instances, p_node->get_child(i), p_merge, p_apply_xforms);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Ref<Mesh> source_mesh = mesh_instance_node->get_mesh();
|
|
|
+ if (source_mesh.is_null()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int item_id = p_library->find_item_by_name(mesh_instance_node->get_name());
|
|
|
+ if (item_id < 0) {
|
|
|
+ item_id = p_library->get_last_unused_item_id();
|
|
|
+ p_library->create_item(item_id);
|
|
|
+ p_library->set_item_name(item_id, mesh_instance_node->get_name());
|
|
|
+ } else if (!p_merge) {
|
|
|
+ WARN_PRINT(vformat("MeshLibrary export found a MeshInstance3D with a duplicated name '%s' in the exported scene that overrides a previously parsed MeshInstance3D item with the same name.", mesh_instance_node->get_name()));
|
|
|
+ }
|
|
|
+ p_mesh_instances[item_id] = mesh_instance_node;
|
|
|
+
|
|
|
+ Ref<Mesh> item_mesh = source_mesh->duplicate();
|
|
|
+ for (int i = 0; i < item_mesh->get_surface_count(); i++) {
|
|
|
+ Ref<Material> surface_override_material = mesh_instance_node->get_surface_override_material(i);
|
|
|
+ if (surface_override_material.is_valid()) {
|
|
|
+ item_mesh->surface_set_material(i, surface_override_material);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p_library->set_item_mesh(item_id, item_mesh);
|
|
|
+
|
|
|
+ Transform3D item_mesh_transform;
|
|
|
+ if (p_apply_xforms) {
|
|
|
+ item_mesh_transform = mesh_instance_node->get_transform();
|
|
|
+ }
|
|
|
+ p_library->set_item_mesh_transform(item_id, item_mesh_transform);
|
|
|
+
|
|
|
+ Vector<MeshLibrary::ShapeData> collisions;
|
|
|
+ for (int i = 0; i < mesh_instance_node->get_child_count(); i++) {
|
|
|
+ StaticBody3D *static_body_node = Object::cast_to<StaticBody3D>(mesh_instance_node->get_child(i));
|
|
|
+ if (!static_body_node) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<uint32_t> shapes;
|
|
|
+ static_body_node->get_shape_owners(&shapes);
|
|
|
+ for (uint32_t &E : shapes) {
|
|
|
+ if (static_body_node->is_shape_owner_disabled(E)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Transform3D shape_transform;
|
|
|
+ if (p_apply_xforms) {
|
|
|
+ shape_transform = mesh_instance_node->get_transform();
|
|
|
+ }
|
|
|
+ shape_transform *= static_body_node->get_transform() * static_body_node->shape_owner_get_transform(E);
|
|
|
+ for (int k = 0; k < static_body_node->shape_owner_get_shape_count(E); k++) {
|
|
|
+ Ref<Shape3D> collision_shape = static_body_node->shape_owner_get_shape(E, k);
|
|
|
+ if (!collision_shape.is_valid()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ MeshLibrary::ShapeData shape_data;
|
|
|
+ shape_data.shape = collision_shape;
|
|
|
+ shape_data.local_transform = shape_transform;
|
|
|
+ collisions.push_back(shape_data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p_library->set_item_shapes(item_id, collisions);
|
|
|
+
|
|
|
+ for (int i = 0; i < mesh_instance_node->get_child_count(); i++) {
|
|
|
+ NavigationRegion3D *navigation_region_node = Object::cast_to<NavigationRegion3D>(mesh_instance_node->get_child(i));
|
|
|
+ if (!navigation_region_node) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Ref<NavigationMesh> navigation_mesh = navigation_region_node->get_navigation_mesh();
|
|
|
+ if (!navigation_mesh.is_null()) {
|
|
|
+ Transform3D navigation_mesh_transform = navigation_region_node->get_transform();
|
|
|
+ p_library->set_item_navigation_mesh(item_id, navigation_mesh);
|
|
|
+ p_library->set_item_navigation_mesh_transform(item_id, navigation_mesh_transform);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
Error MeshLibraryEditor::update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge, bool p_apply_xforms) {
|
|
|
_import_scene(p_base_scene, ml, p_merge, p_apply_xforms);
|
|
|
return OK;
|