Skip to content

Commit 68716b6

Browse files
committed
Allow converting from Mesh to ImporterMesh
1 parent 9dd6c4d commit 68716b6

File tree

4 files changed

+53
-72
lines changed

4 files changed

+53
-72
lines changed

doc/classes/ImporterMesh.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
Removes all surfaces and blend shapes from this [ImporterMesh].
4343
</description>
4444
</method>
45+
<method name="from_mesh" qualifiers="static">
46+
<return type="ImporterMesh" />
47+
<param index="0" name="mesh" type="Mesh" />
48+
<description>
49+
Converts the given [Mesh] into an [ImporterMesh] by copying all its surfaces, blend shapes, materials, and metadata into a new [ImporterMesh] object.
50+
</description>
51+
</method>
4552
<method name="generate_lods">
4653
<return type="void" />
4754
<param index="0" name="normal_merge_angle" type="float" />

modules/gltf/gltf_document.cpp

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -99,49 +99,6 @@ static void _attach_meta_to_extras(Ref<Resource> p_node, Dictionary &p_json) {
9999
}
100100
}
101101

102-
static Ref<ImporterMesh> _mesh_to_importer_mesh(Ref<Mesh> p_mesh) {
103-
Ref<ImporterMesh> importer_mesh;
104-
importer_mesh.instantiate();
105-
if (p_mesh.is_null()) {
106-
return importer_mesh;
107-
}
108-
109-
Ref<ArrayMesh> array_mesh = p_mesh;
110-
if (p_mesh->get_blend_shape_count()) {
111-
ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED;
112-
if (array_mesh.is_valid()) {
113-
shape_mode = array_mesh->get_blend_shape_mode();
114-
}
115-
importer_mesh->set_blend_shape_mode(shape_mode);
116-
for (int morph_i = 0; morph_i < p_mesh->get_blend_shape_count(); morph_i++) {
117-
importer_mesh->add_blend_shape(p_mesh->get_blend_shape_name(morph_i));
118-
}
119-
}
120-
for (int32_t surface_i = 0; surface_i < p_mesh->get_surface_count(); surface_i++) {
121-
Array array = p_mesh->surface_get_arrays(surface_i);
122-
Ref<Material> mat = p_mesh->surface_get_material(surface_i);
123-
const String surface_name = array_mesh.is_valid() ? array_mesh->surface_get_name(surface_i) : String();
124-
String mat_name;
125-
if (mat.is_valid()) {
126-
mat_name = mat->get_name();
127-
if (mat_name.is_empty()) {
128-
mat_name = surface_name;
129-
}
130-
} else {
131-
mat_name = surface_name;
132-
// Assign default material when no material is assigned.
133-
mat.instantiate();
134-
mat->set_name(mat_name);
135-
}
136-
importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i),
137-
array, p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i), mat,
138-
mat_name, p_mesh->surface_get_format(surface_i));
139-
}
140-
importer_mesh->merge_meta_from(*p_mesh);
141-
importer_mesh->set_name(p_mesh->get_name());
142-
return importer_mesh;
143-
}
144-
145102
Error GLTFDocument::_serialize(Ref<GLTFState> p_state) {
146103
for (Ref<GLTFDocumentExtension> ext : document_extensions) {
147104
ERR_CONTINUE(ext.is_null());
@@ -4074,7 +4031,6 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshIn
40744031
Ref<Material> mat = p_mesh_instance->get_active_material(surface_i);
40754032
instance_materials.append(mat);
40764033
}
4077-
Ref<ImporterMesh> current_mesh = _mesh_to_importer_mesh(mesh_resource);
40784034
Vector<float> blend_weights;
40794035
int32_t blend_count = mesh_resource->get_blend_shape_count();
40804036
blend_weights.resize(blend_count);
@@ -4089,7 +4045,7 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshIn
40894045
gltf_mesh->set_name(_gen_unique_name(p_state, mesh_resource->get_name()));
40904046
}
40914047
gltf_mesh->set_instance_materials(instance_materials);
4092-
gltf_mesh->set_mesh(current_mesh);
4048+
gltf_mesh->set_mesh(ImporterMesh::from_mesh(mesh_resource));
40934049
gltf_mesh->set_blend_weights(blend_weights);
40944050
GLTFMeshIndex mesh_i = p_state->meshes.size();
40954051
p_state->meshes.push_back(gltf_mesh);
@@ -4354,7 +4310,7 @@ void GLTFDocument::_convert_grid_map_to_gltf(GridMap *p_grid_map, GLTFNodeIndex
43544310
Vector3(cell_location.x, cell_location.y, cell_location.z)));
43554311
Ref<GLTFMesh> gltf_mesh;
43564312
gltf_mesh.instantiate();
4357-
gltf_mesh->set_mesh(_mesh_to_importer_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)));
4313+
gltf_mesh->set_mesh(ImporterMesh::from_mesh(p_grid_map->get_mesh_library()->get_item_mesh(cell)));
43584314
gltf_mesh->set_original_name(p_grid_map->get_mesh_library()->get_item_name(cell));
43594315
const String unique_name = _gen_unique_name(p_state, p_grid_map->get_mesh_library()->get_item_name(cell));
43604316
gltf_mesh->set_name(unique_name);
@@ -4385,29 +4341,7 @@ void GLTFDocument::_convert_multi_mesh_instance_to_gltf(
43854341
}
43864342
gltf_mesh->set_original_name(multi_mesh->get_name());
43874343
gltf_mesh->set_name(multi_mesh->get_name());
4388-
Ref<ImporterMesh> importer_mesh;
4389-
importer_mesh.instantiate();
4390-
Ref<ArrayMesh> array_mesh = multi_mesh->get_mesh();
4391-
if (array_mesh.is_valid()) {
4392-
importer_mesh->set_blend_shape_mode(array_mesh->get_blend_shape_mode());
4393-
for (int32_t blend_i = 0; blend_i < array_mesh->get_blend_shape_count(); blend_i++) {
4394-
importer_mesh->add_blend_shape(array_mesh->get_blend_shape_name(blend_i));
4395-
}
4396-
}
4397-
for (int32_t surface_i = 0; surface_i < mesh->get_surface_count(); surface_i++) {
4398-
Ref<Material> mat = mesh->surface_get_material(surface_i);
4399-
String material_name;
4400-
if (mat.is_valid()) {
4401-
material_name = mat->get_name();
4402-
}
4403-
Array blend_arrays;
4404-
if (array_mesh.is_valid()) {
4405-
blend_arrays = array_mesh->surface_get_blend_shape_arrays(surface_i);
4406-
}
4407-
importer_mesh->add_surface(mesh->surface_get_primitive_type(surface_i), mesh->surface_get_arrays(surface_i),
4408-
blend_arrays, mesh->surface_get_lods(surface_i), mat, material_name, mesh->surface_get_format(surface_i));
4409-
}
4410-
gltf_mesh->set_mesh(importer_mesh);
4344+
gltf_mesh->set_mesh(ImporterMesh::from_mesh(mesh));
44114345
GLTFMeshIndex mesh_index = p_state->meshes.size();
44124346
p_state->meshes.push_back(gltf_mesh);
44134347
for (int32_t instance_i = 0; instance_i < multi_mesh->get_instance_count();

scene/resources/3d/importer_mesh.cpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ Mesh::BlendShapeMode ImporterMesh::get_blend_shape_mode() const {
6464
return blend_shape_mode;
6565
}
6666

67-
void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_name, const uint64_t p_flags) {
67+
void ImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes, const Dictionary &p_lods, const Ref<Material> &p_material, const String &p_surface_name, const uint64_t p_flags) {
6868
ERR_FAIL_COND(p_blend_shapes.size() != blend_shapes.size());
6969
ERR_FAIL_COND(p_arrays.size() != Mesh::ARRAY_MAX);
7070
Surface s;
7171
s.primitive = p_primitive;
7272
s.arrays = p_arrays;
73-
s.name = p_name;
73+
s.name = p_surface_name;
7474
s.flags = p_flags;
7575

7676
Vector<Vector3> vertex_array = p_arrays[Mesh::ARRAY_VERTEX];
@@ -627,6 +627,44 @@ Ref<ArrayMesh> ImporterMesh::get_mesh(const Ref<ArrayMesh> &p_base) {
627627
return mesh;
628628
}
629629

630+
Ref<ImporterMesh> ImporterMesh::from_mesh(const Ref<Mesh> &p_mesh) {
631+
Ref<ImporterMesh> importer_mesh;
632+
importer_mesh.instantiate();
633+
if (p_mesh.is_null()) {
634+
return importer_mesh;
635+
}
636+
Ref<ArrayMesh> array_mesh = p_mesh;
637+
// Convert blend shape mode and names if any.
638+
if (p_mesh->get_blend_shape_count() > 0) {
639+
ArrayMesh::BlendShapeMode shape_mode = ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED;
640+
if (array_mesh.is_valid()) {
641+
shape_mode = array_mesh->get_blend_shape_mode();
642+
}
643+
importer_mesh->set_blend_shape_mode(shape_mode);
644+
for (int morph_i = 0; morph_i < p_mesh->get_blend_shape_count(); morph_i++) {
645+
importer_mesh->add_blend_shape(p_mesh->get_blend_shape_name(morph_i));
646+
}
647+
}
648+
// Add surfaces one by one.
649+
for (int32_t surface_i = 0; surface_i < p_mesh->get_surface_count(); surface_i++) {
650+
Ref<Material> mat = p_mesh->surface_get_material(surface_i);
651+
String surface_name;
652+
if (array_mesh.is_valid()) {
653+
surface_name = array_mesh->surface_get_name(surface_i);
654+
}
655+
if (surface_name.is_empty() && mat.is_valid()) {
656+
surface_name = mat->get_name();
657+
}
658+
importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i), p_mesh->surface_get_arrays(surface_i),
659+
p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i),
660+
mat, surface_name, p_mesh->surface_get_format(surface_i));
661+
}
662+
// Merge metadata.
663+
importer_mesh->merge_meta_from(*p_mesh);
664+
importer_mesh->set_name(p_mesh->get_name());
665+
return importer_mesh;
666+
}
667+
630668
void ImporterMesh::clear() {
631669
surfaces.clear();
632670
blend_shapes.clear();
@@ -1255,6 +1293,7 @@ void ImporterMesh::_bind_methods() {
12551293

12561294
ClassDB::bind_method(D_METHOD("generate_lods", "normal_merge_angle", "normal_split_angle", "bone_transform_array"), &ImporterMesh::_generate_lods_bind);
12571295
ClassDB::bind_method(D_METHOD("get_mesh", "base_mesh"), &ImporterMesh::get_mesh, DEFVAL(Ref<ArrayMesh>()));
1296+
ClassDB::bind_static_method("ImporterMesh", D_METHOD("from_mesh", "mesh"), &ImporterMesh::from_mesh);
12581297
ClassDB::bind_method(D_METHOD("clear"), &ImporterMesh::clear);
12591298

12601299
ClassDB::bind_method(D_METHOD("_set_data", "data"), &ImporterMesh::_set_data);

scene/resources/3d/importer_mesh.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class ImporterMesh : public Resource {
9393

9494
static String validate_blend_shape_name(const String &p_name);
9595

96-
void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_name = String(), const uint64_t p_flags = 0);
96+
void add_surface(Mesh::PrimitiveType p_primitive, const Array &p_arrays, const TypedArray<Array> &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), const Ref<Material> &p_material = Ref<Material>(), const String &p_surface_name = String(), const uint64_t p_flags = 0);
9797
int get_surface_count() const;
9898

9999
void set_blend_shape_mode(Mesh::BlendShapeMode p_blend_shape_mode);
@@ -133,5 +133,6 @@ class ImporterMesh : public Resource {
133133

134134
bool has_mesh() const;
135135
Ref<ArrayMesh> get_mesh(const Ref<ArrayMesh> &p_base = Ref<ArrayMesh>());
136+
static Ref<ImporterMesh> from_mesh(const Ref<Mesh> &p_mesh);
136137
void clear();
137138
};

0 commit comments

Comments
 (0)