From 8ab7ca4b32952ee3328fadf02c3b25bb647c466c Mon Sep 17 00:00:00 2001 From: Joan Fons Date: Wed, 6 Oct 2021 11:53:53 +0200 Subject: [PATCH] Fix auto LOD generation for blendshapes. --- scene/resources/importer_mesh.cpp | 45 +++++++++++++++++-------------- scene/resources/importer_mesh.h | 1 + servers/rendering_server.cpp | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index af69b799cc3..2572c5de332 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -37,26 +37,34 @@ #include void ImporterMesh::Surface::split_normals(const LocalVector &p_indices, const LocalVector &p_normals) { - ERR_FAIL_COND(arrays.size() != RS::ARRAY_MAX); + _split_normals(arrays, p_indices, p_normals); - const PackedVector3Array &vertices = arrays[RS::ARRAY_VERTEX]; + for (BlendShape &blend_shape : blend_shape_data) { + _split_normals(blend_shape.arrays, p_indices, p_normals); + } +} + +void ImporterMesh::Surface::_split_normals(Array &r_arrays, const LocalVector &p_indices, const LocalVector &p_normals) { + ERR_FAIL_COND(r_arrays.size() != RS::ARRAY_MAX); + + const PackedVector3Array &vertices = r_arrays[RS::ARRAY_VERTEX]; int current_vertex_count = vertices.size(); int new_vertex_count = p_indices.size(); int final_vertex_count = current_vertex_count + new_vertex_count; const int *indices_ptr = p_indices.ptr(); - for (int i = 0; i < arrays.size(); i++) { + for (int i = 0; i < r_arrays.size(); i++) { if (i == RS::ARRAY_INDEX) { continue; } - if (arrays[i].get_type() == Variant::NIL) { + if (r_arrays[i].get_type() == Variant::NIL) { continue; } - switch (arrays[i].get_type()) { + switch (r_arrays[i].get_type()) { case Variant::PACKED_VECTOR3_ARRAY: { - PackedVector3Array data = arrays[i]; + PackedVector3Array data = r_arrays[i]; data.resize(final_vertex_count); Vector3 *data_ptr = data.ptrw(); if (i == RS::ARRAY_NORMAL) { @@ -67,55 +75,55 @@ void ImporterMesh::Surface::split_normals(const LocalVector &p_indices, con data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; } } - arrays[i] = data; + r_arrays[i] = data; } break; case Variant::PACKED_VECTOR2_ARRAY: { - PackedVector2Array data = arrays[i]; + PackedVector2Array data = r_arrays[i]; data.resize(final_vertex_count); Vector2 *data_ptr = data.ptrw(); for (int j = 0; j < new_vertex_count; j++) { data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; } - arrays[i] = data; + r_arrays[i] = data; } break; case Variant::PACKED_FLOAT32_ARRAY: { - PackedFloat32Array data = arrays[i]; + PackedFloat32Array data = r_arrays[i]; int elements = data.size() / current_vertex_count; data.resize(final_vertex_count * elements); float *data_ptr = data.ptrw(); for (int j = 0; j < new_vertex_count; j++) { memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(float) * elements); } - arrays[i] = data; + r_arrays[i] = data; } break; case Variant::PACKED_INT32_ARRAY: { - PackedInt32Array data = arrays[i]; + PackedInt32Array data = r_arrays[i]; int elements = data.size() / current_vertex_count; data.resize(final_vertex_count * elements); int32_t *data_ptr = data.ptrw(); for (int j = 0; j < new_vertex_count; j++) { memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(int32_t) * elements); } - arrays[i] = data; + r_arrays[i] = data; } break; case Variant::PACKED_BYTE_ARRAY: { - PackedByteArray data = arrays[i]; + PackedByteArray data = r_arrays[i]; int elements = data.size() / current_vertex_count; data.resize(final_vertex_count * elements); uint8_t *data_ptr = data.ptrw(); for (int j = 0; j < new_vertex_count; j++) { memcpy(&data_ptr[(current_vertex_count + j) * elements], &data_ptr[indices_ptr[j] * elements], sizeof(uint8_t) * elements); } - arrays[i] = data; + r_arrays[i] = data; } break; case Variant::PACKED_COLOR_ARRAY: { - PackedColorArray data = arrays[i]; + PackedColorArray data = r_arrays[i]; data.resize(final_vertex_count); Color *data_ptr = data.ptrw(); for (int j = 0; j < new_vertex_count; j++) { data_ptr[current_vertex_count + j] = data_ptr[indices_ptr[j]]; } - arrays[i] = data; + r_arrays[i] = data; } break; default: { ERR_FAIL_MSG("Unhandled array type."); @@ -261,9 +269,6 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) { continue; } - if (get_blend_shape_count()) { - continue; - } surfaces.write[i].lods.clear(); Vector vertices = surfaces[i].arrays[RS::ARRAY_VERTEX]; diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index 89909f17f0f..8576312a8a4 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -70,6 +70,7 @@ class ImporterMesh : public Resource { }; void split_normals(const LocalVector &p_indices, const LocalVector &p_normals); + static void _split_normals(Array &r_arrays, const LocalVector &p_indices, const LocalVector &p_normals); }; Vector surfaces; Vector blend_shapes; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 7e66ddbb0f5..b3efe840b6f 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -934,7 +934,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa } } - ERR_FAIL_COND_V_MSG((bsformat) != (format & (ARRAY_FORMAT_VERTEX | ARRAY_FORMAT_NORMAL | ARRAY_FORMAT_TANGENT)), ERR_INVALID_PARAMETER, "Blend shape format must match the main array format for Vertex, Normal and Tangent arrays."); + ERR_FAIL_COND_V_MSG((bsformat & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK) != (format & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK), ERR_INVALID_PARAMETER, "Blend shape format must match the main array format for Vertex, Normal and Tangent arrays."); } }