|
5 | 5 |
|
6 | 6 | #include "GLTF.hpp" |
7 | 7 |
|
| 8 | +#include <iostream> |
8 | 9 | #include <numbers> |
9 | 10 |
|
| 11 | +constexpr bool hasValidNormals(Mesh& mesh, Face& face) |
| 12 | +{ |
| 13 | + const std::size_t size = mesh.normals.size(); |
| 14 | + |
| 15 | + if (face.n1 >= size) return false; |
| 16 | + if (face.n2 >= size) return false; |
| 17 | + if (face.n3 >= size) return false; |
| 18 | + return true; |
| 19 | +} |
| 20 | + |
10 | 21 | struct Quaternion |
11 | 22 | { |
12 | 23 | float x; |
@@ -169,9 +180,19 @@ std::size_t GLTFExporter::buildPrimitiveNormal(Mesh& mesh, std::vector<Face> fac |
169 | 180 |
|
170 | 181 | for (auto& face : faces) |
171 | 182 | { |
172 | | - data.push_back(mesh.normals[face.n1]); |
173 | | - data.push_back(mesh.normals[face.n2]); |
174 | | - data.push_back(mesh.normals[face.n3]); |
| 183 | + if (hasValidNormals(mesh, face)) |
| 184 | + { |
| 185 | + data.push_back(mesh.normals[face.n1]); |
| 186 | + data.push_back(mesh.normals[face.n2]); |
| 187 | + data.push_back(mesh.normals[face.n3]); |
| 188 | + } |
| 189 | + else |
| 190 | + { |
| 191 | + data.push_back({ 0.0f, 1.0f, 0.0f }); |
| 192 | + data.push_back({ 0.0f, 1.0f, 0.0f }); |
| 193 | + data.push_back({ 0.0f, 1.0f, 0.0f }); |
| 194 | + std::cout << "Source model contains invalid normal data, using empty fallback values." << std::endl; |
| 195 | + } |
175 | 196 | } |
176 | 197 |
|
177 | 198 | return buildAccessor(data, TINYGLTF_COMPONENT_TYPE_FLOAT, TINYGLTF_TYPE_VEC3, TINYGLTF_TARGET_ARRAY_BUFFER); |
@@ -373,7 +394,7 @@ int32_t GLTFExporter::buildMaterial(MaterialMode mode) |
373 | 394 |
|
374 | 395 | void GLTFExporter::buildAnimations() |
375 | 396 | { |
376 | | - int i = 0; |
| 397 | + int i = 0; |
377 | 398 | for (auto& raw : mmd.anims->anims) |
378 | 399 | { |
379 | 400 | Animation data(raw); |
|
0 commit comments