Skip to content

Commit dca566a

Browse files
committed
Fix more importer edge cases
Also fixed subdivider to generate normals at subdivision level 0.
1 parent b1a8cba commit dca566a

File tree

3 files changed

+44
-29
lines changed

3 files changed

+44
-29
lines changed

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
![Version](https://img.shields.io/badge/version-Godot%204-informational) ![License](https://img.shields.io/github/license/tefusion/godot-subdiv)
1+
![Version](https://img.shields.io/badge/Godot-v4.0%20(beta%203)-informational) ![License](https://img.shields.io/github/license/tefusion/godot-subdiv)
22
# Godot Subdiv
33

44
| ![UV Subdivision](UVSubdivision.gif) | ![Skinning subdivision](SkinningSubdivision.gif) |
@@ -55,9 +55,6 @@ In Blender you can go in Edit Mode and go Select->Select All by Trait->Faces by
5555
- [Godot3 module for opensubdiv](https://github.com/godot-extended-libraries/godot-fire/tree/feature/3.2/opensubdiv-next) by fire that was referenced for subdivision implementation
5656
- [Template used](https://github.com/nathanfranke/gdextension), includes the used github workflow and was easy to setup
5757

58-
## Last tested Godot version
59-
60-
Godot 4 Beta 3
6158
## License
6259

6360
[MIT](LICENSE)

src/import/topology_data_importer.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@ void TopologyDataImporter::_bind_methods() {
3030
}
3131

3232
TopologyDataImporter::SurfaceVertexArrays::SurfaceVertexArrays(const Array &p_mesh_arrays) {
33+
ERR_FAIL_COND(p_mesh_arrays.size() != Mesh::ARRAY_MAX);
34+
3335
vertex_array = p_mesh_arrays[Mesh::ARRAY_VERTEX];
34-
if (p_mesh_arrays[Mesh::ARRAY_NORMAL].get_type() == Variant::PACKED_VECTOR3_ARRAY) {
36+
if (p_mesh_arrays[Mesh::ARRAY_NORMAL].get_type() == Variant::PACKED_VECTOR3_ARRAY)
3537
normal_array = p_mesh_arrays[Mesh::ARRAY_NORMAL];
36-
}
37-
index_array = p_mesh_arrays[Mesh::ARRAY_INDEX];
38-
if (p_mesh_arrays[Mesh::ARRAY_TEX_UV].get_type() == Variant::PACKED_VECTOR2_ARRAY) {
38+
39+
if (p_mesh_arrays[Mesh::ARRAY_INDEX].get_type() == Variant::PACKED_INT32_ARRAY)
40+
index_array = p_mesh_arrays[Mesh::ARRAY_INDEX];
41+
42+
if (p_mesh_arrays[Mesh::ARRAY_TEX_UV].get_type() == Variant::PACKED_VECTOR2_ARRAY)
3943
uv_array = p_mesh_arrays[Mesh::ARRAY_TEX_UV];
40-
}
44+
4145
if (p_mesh_arrays[Mesh::ARRAY_BONES].get_type() == Variant::PACKED_INT32_ARRAY)
4246
bones_array = p_mesh_arrays[Mesh::ARRAY_BONES];
4347

@@ -51,12 +55,14 @@ void TopologyDataImporter::convert_importer_meshinstance_to_subdiv(Object *impor
5155
ERR_FAIL_COND_MSG(importer_mesh.is_null(), "Mesh is null");
5256

5357
//handle cases that don't need to generate TopologyDataMesh
54-
if (import_mode == ImportMode::IMPORTER_MESH && subdiv_level == 0) {
55-
return;
56-
}
57-
if (import_mode == ImportMode::ARRAY_MESH && subdiv_level == 0) {
58-
_replace_importer_mesh_instance_with_mesh_instance(importer_mesh_instance);
59-
return;
58+
if (subdiv_level == 0) {
59+
if (import_mode == ImportMode::IMPORTER_MESH) {
60+
return;
61+
}
62+
if (import_mode == ImportMode::ARRAY_MESH) {
63+
_replace_importer_mesh_instance_with_mesh_instance(importer_mesh_instance);
64+
return;
65+
}
6066
}
6167

6268
Ref<TopologyDataMesh> topology_data_mesh;
@@ -66,8 +72,22 @@ void TopologyDataImporter::convert_importer_meshinstance_to_subdiv(Object *impor
6672
for (int surface_index = 0; surface_index < importer_mesh->get_surface_count(); surface_index++) {
6773
//convert actual mesh data to quad
6874
Array p_arrays = importer_mesh->get_surface_arrays(surface_index);
69-
SurfaceVertexArrays surface = SurfaceVertexArrays(p_arrays);
7075
int32_t format = generate_fake_format(p_arrays); //importermesh surface_get_format just returns flags
76+
77+
// generate_fake_format returns 0 if size != ARRAY_MAX
78+
if (format == 0 || !(format & Mesh::ARRAY_FORMAT_VERTEX)) {
79+
continue;
80+
} else if (!(format & Mesh::ARRAY_FORMAT_INDEX)) {
81+
//generate index array, p_arrays also used by blend_shapes so generating here
82+
const PackedVector3Array &vertex_array = p_arrays[Mesh::ARRAY_VERTEX];
83+
PackedInt32Array simple_index_array;
84+
for (int i = 0; i < vertex_array.size(); i++) {
85+
simple_index_array.push_back(i);
86+
}
87+
p_arrays[Mesh::ARRAY_INDEX] = simple_index_array;
88+
format |= Mesh::ARRAY_FORMAT_INDEX;
89+
}
90+
7191
Array surface_arrays;
7292
TopologyDataMesh::TopologyType topology_type = _generate_topology_surface_arrays(SurfaceVertexArrays(p_arrays), format, surface_arrays);
7393

@@ -336,10 +356,9 @@ Array TopologyDataImporter::_generate_packed_blend_shapes(const Array &tri_blend
336356

337357
int32_t TopologyDataImporter::generate_fake_format(const Array &arrays) const {
338358
ERR_FAIL_COND_V(arrays.size() != Mesh::ARRAY_MAX, 0);
339-
int32_t format = 0;
359+
ERR_FAIL_COND_V(arrays[Mesh::ARRAY_VERTEX].get_type() != Variant::PACKED_VECTOR3_ARRAY, 0);
360+
int32_t format = Mesh::ARRAY_FORMAT_VERTEX;
340361

341-
if (arrays[Mesh::ARRAY_VERTEX].get_type() == Variant::PACKED_VECTOR3_ARRAY)
342-
format |= Mesh::ARRAY_FORMAT_VERTEX;
343362
if (arrays[Mesh::ARRAY_NORMAL].get_type() == Variant::PACKED_VECTOR3_ARRAY)
344363
format |= Mesh::ARRAY_FORMAT_NORMAL;
345364
if (arrays[Mesh::ARRAY_TANGENT].get_type() == Variant::PACKED_FLOAT32_ARRAY)

src/subdivision/subdivider.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,18 +262,17 @@ void Subdivider::subdivide(const Array &p_arrays, int p_level, int32_t p_format,
262262
const bool use_bones = (p_format & Mesh::ARRAY_FORMAT_BONES) && (p_format & Mesh::ARRAY_FORMAT_WEIGHTS);
263263

264264
topology_data = TopologyData(p_arrays, p_format, _get_vertices_per_face_count());
265-
if (p_level == 0) {
266-
return;
265+
//if p_level not 0 subdivide mesh and store in topology_data again
266+
if (p_level != 0) {
267+
Far::TopologyRefiner *refiner = _create_topology_refiner(p_level, p_format);
268+
ERR_FAIL_COND_MSG(!refiner, "Refiner couldn't be created, numVertsPerFace array likely lost.");
269+
_create_subdivision_vertices(refiner, p_level, p_format);
270+
_create_subdivision_faces(refiner, p_level, p_format);
271+
//free memory
272+
273+
delete refiner;
267274
}
268275

269-
Far::TopologyRefiner *refiner = _create_topology_refiner(p_level, p_format);
270-
ERR_FAIL_COND_MSG(!refiner, "Refiner couldn't be created, numVertsPerFace array likely lost.");
271-
_create_subdivision_vertices(refiner, p_level, p_format);
272-
_create_subdivision_faces(refiner, p_level, p_format);
273-
//free memory
274-
275-
delete refiner;
276-
277276
if (calculate_normals) {
278277
topology_data.normal_array = _calculate_smooth_normals(topology_data.vertex_array, topology_data.index_array);
279278
}

0 commit comments

Comments
 (0)