Skip to content

Commit 44b1baa

Browse files
committed
[Data/GltfLoad] Tangents are computed if not loaded
1 parent a570dba commit 44b1baa

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

src/RaZ/Data/GltfLoad.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void loadVertices(const fastgltf::Primitive& primitive,
4141
const std::vector<fastgltf::Buffer>& buffers,
4242
const std::vector<fastgltf::BufferView>& bufferViews,
4343
const std::vector<fastgltf::Accessor>& accessors,
44-
std::vector<Vertex>& vertices) {
44+
Submesh& submesh) {
4545
Logger::debug("[GltfLoad] Loading vertices...");
4646

4747
const auto positionIt = primitive.findAttribute("POSITION");
@@ -54,6 +54,7 @@ void loadVertices(const fastgltf::Primitive& primitive,
5454
if (!positionAccessor.bufferViewIndex.has_value())
5555
return;
5656

57+
std::vector<Vertex>& vertices = submesh.getVertices();
5758
vertices.resize(positionAccessor.count);
5859

5960
loadVertexData<float>(positionAccessor, buffers, bufferViews, vertices, [] (Vertex& vert, const float* data) {
@@ -79,6 +80,8 @@ void loadVertices(const fastgltf::Primitive& primitive,
7980
}}
8081
}};
8182

83+
bool hasLoadedTangents = false;
84+
8285
for (auto&& [attribName, callback] : attributes) {
8386
const auto attribIter = primitive.findAttribute(attribName);
8487

@@ -87,10 +90,17 @@ void loadVertices(const fastgltf::Primitive& primitive,
8790

8891
const fastgltf::Accessor& attribAccessor = accessors[attribIter->second];
8992

90-
if (attribAccessor.bufferViewIndex.has_value())
93+
if (attribAccessor.bufferViewIndex.has_value()) {
9194
loadVertexData(attribAccessor, buffers, bufferViews, vertices, callback);
95+
96+
if (attribName == "TANGENT")
97+
hasLoadedTangents = true;
98+
}
9299
}
93100

101+
if (!hasLoadedTangents)
102+
submesh.computeTangents();
103+
94104
Logger::debug("[GltfLoad] Loaded vertices");
95105
}
96106

@@ -117,19 +127,21 @@ void loadIndices(const fastgltf::Accessor& indicesAccessor,
117127
const std::size_t dataStride = indicesView.byteStride.value_or(dataSize);
118128

119129
for (std::size_t i = 0; i < indices.size(); ++i) {
130+
const uint8_t* const indexData = indicesData + i * dataStride;
131+
120132
// The indices must be of an unsigned integer type, but its size is unspecified
121133
// See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_indices
122134
switch (dataSize) {
123135
case 1:
124-
indices[i] = *reinterpret_cast<const uint8_t*>(indicesData + i * dataStride);
136+
indices[i] = *indexData;
125137
break;
126138

127139
case 2:
128-
indices[i] = *reinterpret_cast<const uint16_t*>(indicesData + i * dataStride);
140+
indices[i] = *reinterpret_cast<const uint16_t*>(indexData);
129141
break;
130142

131143
case 4:
132-
indices[i] = *reinterpret_cast<const uint32_t*>(indicesData + i * dataStride);
144+
indices[i] = *reinterpret_cast<const uint32_t*>(indexData);
133145
break;
134146

135147
default:
@@ -157,8 +169,9 @@ std::pair<Mesh, MeshRenderer> loadMeshes(const std::vector<fastgltf::Mesh>& mesh
157169
Submesh& submesh = loadedMesh.addSubmesh();
158170
SubmeshRenderer& submeshRenderer = loadedMeshRenderer.addSubmeshRenderer();
159171

160-
loadVertices(primitive, buffers, bufferViews, accessors, submesh.getVertices());
172+
// Indices must be loaded first as they are needed to compute the tangents if necessary
161173
loadIndices(accessors[*primitive.indicesAccessor], buffers, bufferViews, submesh.getTriangleIndices());
174+
loadVertices(primitive, buffers, bufferViews, accessors, submesh);
162175

163176
submeshRenderer.load(submesh, (primitive.type == fastgltf::PrimitiveType::Triangles ? RenderMode::TRIANGLE : RenderMode::POINT));
164177
submeshRenderer.setMaterialIndex(primitive.materialIndex.value_or(0));

tests/src/RaZ/Data/GltfFormat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ TEST_CASE("GltfFormat load GLB textured") {
261261
CHECK(mesh.getSubmeshes()[0].getVertices()[0] == Raz::Vertex{ Raz::Vec3f(-0.5f, -0.5f, 0.5f), Raz::Vec2f(0.f, 0.f), Raz::Axis::Z, Raz::Vec3f(0.f) });
262262
CHECK(mesh.getSubmeshes()[0].getVertices()[1] == Raz::Vertex{ Raz::Vec3f(0.5f, -0.5f, 0.5f), Raz::Vec2f(0.f, 0.f), Raz::Axis::Z, Raz::Vec3f(0.f) });
263263
CHECK(mesh.getSubmeshes()[0].getVertices()[12] == Raz::Vertex{ Raz::Vec3f(0.5f, -0.5f, 0.5f), Raz::Vec2f(0.f, 0.f), -Raz::Axis::Y, Raz::Vec3f(0.f) });
264-
CHECK(mesh.getSubmeshes()[0].getVertices()[23] == Raz::Vertex{ Raz::Vec3f(0.5f, 0.5f, -0.5f), Raz::Vec2f(1.f, 1.f), -Raz::Axis::Z, Raz::Vec3f(0.f) });
264+
CHECK(mesh.getSubmeshes()[0].getVertices()[23] == Raz::Vertex{ Raz::Vec3f(0.5f, 0.5f, -0.5f), Raz::Vec2f(1.f, 1.f), -Raz::Axis::Z, Raz::Axis::X });
265265

266266
REQUIRE(meshRenderer.getSubmeshRenderers().size() == 1);
267267
CHECK(meshRenderer.getSubmeshRenderers()[0].getRenderMode() == Raz::RenderMode::TRIANGLE);

0 commit comments

Comments
 (0)