Skip to content

Commit

Permalink
[Data/GltfLoad] Texcoords are normalized
Browse files Browse the repository at this point in the history
- They can be outside the [0; 1] range, and are wrapped according to the REPEAT mode
  • Loading branch information
Razakhel committed Dec 24, 2023
1 parent ee7fce4 commit 2a55602
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
21 changes: 16 additions & 5 deletions src/RaZ/Data/GltfLoad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,23 @@ void loadVertices(const fastgltf::Primitive& primitive,
vert.position = Vec3f(data[0], data[1], data[2]);
});

// The tangent's input W component (data[3]) is either 1 or -1 and represents the handedness
// See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview
constexpr std::array<std::pair<std::string_view, void (*)(Vertex&, const float*)>, 3> attributes = {{
{ "TEXCOORD_0", [] (Vertex& vert, const float* data) { vert.texcoords = Vec2f(data[0], data[1]); } },
{ "NORMAL", [] (Vertex& vert, const float* data) { vert.normal = Vec3f(data[0], data[1], data[2]); } },
{ "TANGENT", [] (Vertex& vert, const float* data) { vert.tangent = Vec3f(data[0], data[1], data[2]) * data[3]; } }
{ "TEXCOORD_0", [] (Vertex& vert, const float* data) {
// The texcoords can be outside the [0; 1] range; they're normalized according to the REPEAT mode. This may be subject to change
// See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_wrapping
vert.texcoords = Vec2f(data[0], data[1]);

for (float& elt : vert.texcoords.getData()) {
if (elt < -1.f || elt > 1.f) elt = std::fmod(elt, 1.f);
if (elt < 0.f) elt += 1.f;
}
}},
{ "NORMAL", [] (Vertex& vert, const float* data) { vert.normal = Vec3f(data[0], data[1], data[2]); } },
{ "TANGENT", [] (Vertex& vert, const float* data) {
// The tangent's input W component (data[3]) is either 1 or -1 and represents the handedness
// See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview
vert.tangent = Vec3f(data[0], data[1], data[2]) * data[3];
}}
}};

for (auto&& [attribName, callback] : attributes) {
Expand Down
8 changes: 4 additions & 4 deletions tests/src/RaZ/Data/GltfFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ TEST_CASE("GltfFormat load glTF") {
CHECK(mesh.getSubmeshes()[1].getTriangleIndexCount() == 36);
CHECK(mesh.recoverTriangleCount() == 24); // 72 / 3

CHECK(mesh.getSubmeshes()[0].getVertices()[0] == Raz::Vertex{ Raz::Vec3f(1.f, -1.f, 1.f), Raz::Vec2f(0.f, 0.f), -Raz::Axis::Y, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[1] == Raz::Vertex{ Raz::Vec3f(-1.f, -1.f, -1.f), Raz::Vec2f(-1.f, 1.f), -Raz::Axis::Y, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[17] == Raz::Vertex{ Raz::Vec3f(1.f, 1.f, -0.9999989f), Raz::Vec2f(0.f, 1.f), -Raz::Axis::Z, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[35] == Raz::Vertex{ Raz::Vec3f(-1.f, 1.f, -1.f), Raz::Vec2f(-1.f, 1.f), -Raz::Axis::Z, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[0] == Raz::Vertex{ Raz::Vec3f(1.f, -1.f, 1.f), Raz::Vec2f(0.f, 0.f), -Raz::Axis::Y, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[1] == Raz::Vertex{ Raz::Vec3f(-1.f, -1.f, -1.f), Raz::Vec2f(0.f, 1.f), -Raz::Axis::Y, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[17] == Raz::Vertex{ Raz::Vec3f(1.f, 1.f, -0.9999989f), Raz::Vec2f(0.f, 1.f), -Raz::Axis::Z, -Raz::Axis::X });
CHECK(mesh.getSubmeshes()[0].getVertices()[35] == Raz::Vertex{ Raz::Vec3f(-1.f, 1.f, -1.f), Raz::Vec2f(0.f, 1.f), -Raz::Axis::Z, -Raz::Axis::X });

REQUIRE(meshRenderer.getSubmeshRenderers().size() == 2);
CHECK(meshRenderer.getSubmeshRenderers()[0].getRenderMode() == Raz::RenderMode::TRIANGLE);
Expand Down

0 comments on commit 2a55602

Please sign in to comment.