diff --git a/doc/classes/ImporterMesh.xml b/doc/classes/ImporterMesh.xml
index 3714f0fcbeb..8d4bc028a0d 100644
--- a/doc/classes/ImporterMesh.xml
+++ b/doc/classes/ImporterMesh.xml
@@ -42,6 +42,13 @@
Removes all surfaces and blend shapes from this [ImporterMesh].
+
+
+
+
+ Converts the given [Mesh] into an [ImporterMesh] by copying all its surfaces, blend shapes, materials, and metadata into a new [ImporterMesh] object.
+
+
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 652ffdbd168..f5342d2c1b0 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -99,49 +99,6 @@ static void _attach_meta_to_extras(Ref p_node, Dictionary &p_json) {
}
}
-static Ref _mesh_to_importer_mesh(Ref p_mesh) {
- Ref importer_mesh;
- importer_mesh.instantiate();
- if (p_mesh.is_null()) {
- return importer_mesh;
- }
-
- Ref array_mesh = p_mesh;
- if (p_mesh->get_blend_shape_count()) {
- ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED;
- if (array_mesh.is_valid()) {
- shape_mode = array_mesh->get_blend_shape_mode();
- }
- importer_mesh->set_blend_shape_mode(shape_mode);
- for (int morph_i = 0; morph_i < p_mesh->get_blend_shape_count(); morph_i++) {
- importer_mesh->add_blend_shape(p_mesh->get_blend_shape_name(morph_i));
- }
- }
- for (int32_t surface_i = 0; surface_i < p_mesh->get_surface_count(); surface_i++) {
- Array array = p_mesh->surface_get_arrays(surface_i);
- Ref mat = p_mesh->surface_get_material(surface_i);
- const String surface_name = array_mesh.is_valid() ? array_mesh->surface_get_name(surface_i) : String();
- String mat_name;
- if (mat.is_valid()) {
- mat_name = mat->get_name();
- if (mat_name.is_empty()) {
- mat_name = surface_name;
- }
- } else {
- mat_name = surface_name;
- // Assign default material when no material is assigned.
- mat.instantiate();
- mat->set_name(mat_name);
- }
- importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i),
- array, p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i), mat,
- mat_name, p_mesh->surface_get_format(surface_i));
- }
- importer_mesh->merge_meta_from(*p_mesh);
- importer_mesh->set_name(p_mesh->get_name());
- return importer_mesh;
-}
-
Error GLTFDocument::_serialize(Ref p_state) {
for (Ref ext : document_extensions) {
ERR_CONTINUE(ext.is_null());
@@ -4074,7 +4031,6 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref p_state, MeshIn
Ref mat = p_mesh_instance->get_active_material(surface_i);
instance_materials.append(mat);
}
- Ref current_mesh = _mesh_to_importer_mesh(mesh_resource);
Vector blend_weights;
int32_t blend_count = mesh_resource->get_blend_shape_count();
blend_weights.resize(blend_count);
@@ -4089,7 +4045,7 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref p_state, MeshIn
gltf_mesh->set_name(_gen_unique_name(p_state, mesh_resource->get_name()));
}
gltf_mesh->set_instance_materials(instance_materials);
- gltf_mesh->set_mesh(current_mesh);
+ gltf_mesh->set_mesh(ImporterMesh::from_mesh(mesh_resource));
gltf_mesh->set_blend_weights(blend_weights);
GLTFMeshIndex mesh_i = p_state->meshes.size();
p_state->meshes.push_back(gltf_mesh);
@@ -4354,7 +4310,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex
Vector3(cell_location.x, cell_location.y, cell_location.z)));
Ref gltf_mesh;
gltf_mesh.instantiate();
- gltf_mesh->set_mesh(_mesh_to_importer_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)));
+ gltf_mesh->set_mesh(ImporterMesh::from_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)));
gltf_mesh->set_original_name(p_grid_map->get_mesh_library()->get_item_name(cell));
const String unique_name = _gen_unique_name(p_state, p_grid_map->get_mesh_library()->get_item_name(cell));
gltf_mesh->set_name(unique_name);
@@ -4385,29 +4341,7 @@ void GLTFDocument::_convert_multi_mesh_instance_to_gltf(
}
gltf_mesh->set_original_name(multi_mesh->get_name());
gltf_mesh->set_name(multi_mesh->get_name());
- Ref importer_mesh;
- importer_mesh.instantiate();
- Ref array_mesh = multi_mesh->get_mesh();
- if (array_mesh.is_valid()) {
- importer_mesh->set_blend_shape_mode(array_mesh->get_blend_shape_mode());
- for (int32_t blend_i = 0; blend_i < array_mesh->get_blend_shape_count(); blend_i++) {
- importer_mesh->add_blend_shape(array_mesh->get_blend_shape_name(blend_i));
- }
- }
- for (int32_t surface_i = 0; surface_i < mesh->get_surface_count(); surface_i++) {
- Ref mat = mesh->surface_get_material(surface_i);
- String material_name;
- if (mat.is_valid()) {
- material_name = mat->get_name();
- }
- Array blend_arrays;
- if (array_mesh.is_valid()) {
- blend_arrays = array_mesh->surface_get_blend_shape_arrays(surface_i);
- }
- importer_mesh->add_surface(mesh->surface_get_primitive_type(surface_i), mesh->surface_get_arrays(surface_i),
- blend_arrays, mesh->surface_get_lods(surface_i), mat, material_name, mesh->surface_get_format(surface_i));
- }
- gltf_mesh->set_mesh(importer_mesh);
+ gltf_mesh->set_mesh(ImporterMesh::from_mesh(mesh));
GLTFMeshIndex mesh_index = p_state->meshes.size();
p_state->meshes.push_back(gltf_mesh);
for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count();
diff --git a/scene/resources/3d/importer_mesh.cpp b/scene/resources/3d/importer_mesh.cpp
index cb70f09eaf6..cd57606417f 100644
--- a/scene/resources/3d/importer_mesh.cpp
+++ b/scene/resources/3d/importer_mesh.cpp
@@ -64,13 +64,13 @@ Mesh::BlendShapeMode ImporterMesh::get_blend_shape_mode() const {
return blend_shape_mode;
}
-void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray &p_blend_shapes, const Dictionary &p_lods, const Ref &p_material, const String &p_name, const uint64_t p_flags) {
+void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray &p_blend_shapes, const Dictionary &p_lods, const Ref &p_material, const String &p_surface_name, const uint64_t p_flags) {
ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size());
ERR_FAIL_COND(p_arrays.size() != Mesh::ARRAY_MAX);
Surface s;
s.primitive = p_primitive;
s.arrays = p_arrays;
- s.name = p_name;
+ s.name = p_surface_name;
s.flags = p_flags;
Vector vertex_array = p_arrays[Mesh::ARRAY_VERTEX];
@@ -627,6 +627,44 @@ Ref ImporterMesh::get_mesh(const Ref &p_base) {
return mesh;
}
+Ref ImporterMesh::from_mesh(const Ref &p_mesh) {
+ Ref importer_mesh;
+ importer_mesh.instantiate();
+ if (p_mesh.is_null()) {
+ return importer_mesh;
+ }
+ Ref array_mesh = p_mesh;
+ // Convert blend shape mode and names if any.
+ if (p_mesh->get_blend_shape_count() > 0) {
+ ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED;
+ if (array_mesh.is_valid()) {
+ shape_mode = array_mesh->get_blend_shape_mode();
+ }
+ importer_mesh->set_blend_shape_mode(shape_mode);
+ for (int morph_i = 0; morph_i < p_mesh->get_blend_shape_count(); morph_i++) {
+ importer_mesh->add_blend_shape(p_mesh->get_blend_shape_name(morph_i));
+ }
+ }
+ // Add surfaces one by one.
+ for (int32_t surface_i = 0; surface_i < p_mesh->get_surface_count(); surface_i++) {
+ Ref mat = p_mesh->surface_get_material(surface_i);
+ String surface_name;
+ if (array_mesh.is_valid()) {
+ surface_name = array_mesh->surface_get_name(surface_i);
+ }
+ if (surface_name.is_empty() && mat.is_valid()) {
+ surface_name = mat->get_name();
+ }
+ importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i), p_mesh->surface_get_arrays(surface_i),
+ p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i),
+ mat, surface_name, p_mesh->surface_get_format(surface_i));
+ }
+ // Merge metadata.
+ importer_mesh->merge_meta_from(*p_mesh);
+ importer_mesh->set_name(p_mesh->get_name());
+ return importer_mesh;
+}
+
void ImporterMesh::clear() {
surfaces.clear();
blend_shapes.clear();
@@ -1255,6 +1293,7 @@ void ImporterMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate_lods", "normal_merge_angle", "normal_split_angle", "bone_transform_array"), &ImporterMesh::_generate_lods_bind);
ClassDB::bind_method(D_METHOD("get_mesh", "base_mesh"), &ImporterMesh::get_mesh, DEFVAL(Ref()));
+ ClassDB::bind_static_method("ImporterMesh", D_METHOD("from_mesh", "mesh"), &ImporterMesh::from_mesh);
ClassDB::bind_method(D_METHOD("clear"), &ImporterMesh::clear);
ClassDB::bind_method(D_METHOD("_set_data", "data"), &ImporterMesh::_set_data);
diff --git a/scene/resources/3d/importer_mesh.h b/scene/resources/3d/importer_mesh.h
index 03cc73e627c..665b461f2a9 100644
--- a/scene/resources/3d/importer_mesh.h
+++ b/scene/resources/3d/importer_mesh.h
@@ -93,7 +93,7 @@ public:
static String validate_blend_shape_name(const String &p_name);
- void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref &p_material = Ref(), const String &p_name = String(), const uint64_t p_flags = 0);
+ void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref &p_material = Ref(), const String &p_surface_name = String(), const uint64_t p_flags = 0);
int get_surface_count() const;
void set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode);
@@ -133,5 +133,6 @@ public:
bool has_mesh() const;
Ref get_mesh(const Ref &p_base = Ref());
+ static Ref from_mesh(const Ref &p_mesh);
void clear();
};