From d90b906d2649ee59f3adaa1e26e77db292f729d1 Mon Sep 17 00:00:00 2001 From: Josiah VanderZee Date: Sat, 12 Nov 2022 07:01:56 -0600 Subject: [PATCH] Test for texture coordinates on cube --- source/Irrlicht/CGLTFMeshFileLoader.cpp | 72 +++++++++++++++---- .../tests/testCGLTFMeshFileLoader.cpp | 14 +++- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/source/Irrlicht/CGLTFMeshFileLoader.cpp b/source/Irrlicht/CGLTFMeshFileLoader.cpp index ce5c4fd7..3b533363 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/CGLTFMeshFileLoader.cpp @@ -18,6 +18,13 @@ #include #include +template +struct Span +{ + T* buffer = nullptr; + std::size_t size = 0; +}; + class BufferOffset { public: @@ -63,7 +70,8 @@ static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) } template -static T readPrimitive(const BufferOffset& readFrom) { +static T readPrimitive(const BufferOffset& readFrom) +{ unsigned char d[sizeof(T)]{}; for (std::size_t i = 0; i < sizeof(T); ++i) { d[i] = readFrom.at(i); @@ -71,7 +79,16 @@ static T readPrimitive(const BufferOffset& readFrom) { return *reinterpret_cast(d); } -static core::vector3df readVector(const BufferOffset& readFrom, const float scale) { +static core::vector2df readVec2DF(const BufferOffset& readFrom) +{ + return core::vector2df( + readPrimitive(readFrom), + readPrimitive(BufferOffset(readFrom, sizeof(float)))); + +} + +static core::vector3df readVec3DF(const BufferOffset& readFrom, const float scale) +{ // glTF coordinates are right-handed, minetest ones are left-handed // 1 glTF coordinate is equivalent to 10 Irrlicht coordinates return core::vector3df( @@ -98,24 +115,55 @@ float getScale(const tinygltf::Model& model) return 1.0f; } -video::S3DVertex* getVertices(const tinygltf::Model& model, const std::size_t accessorId) +static void copyPositions(const tinygltf::Model& model, + const Span vertices, + const std::size_t accessorId) { const auto& view = model.bufferViews[ model.accessors[accessorId].bufferView]; const auto& buffer = model.buffers[view.buffer]; - - auto* vertices = new video::S3DVertex[model.accessors[accessorId].count]; - for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) { - const auto v = readVector(BufferOffset( - buffer.data, view.byteOffset + 3 * sizeof(float) * i), getScale(model)); - vertices[i] = {v, {0.0f, 0.0f, 0.0f}, {}, {0.0f, 0.0f}}; + const auto v = readVec3DF(BufferOffset( + buffer.data, view.byteOffset + 3 * sizeof(float) * i), + getScale(model)); + vertices.buffer[i].Pos = v; } - - return vertices; } -u16* getIndices(const tinygltf::Model& model, const std::size_t accessorId) +static void copyTCoords(const tinygltf::Model& model, + const Span vertices, + const std::size_t accessorId) +{ + const auto& view = model.bufferViews[ + model.accessors[accessorId].bufferView]; + const auto& buffer = model.buffers[view.buffer]; + for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) { + const auto t = readVec2DF(BufferOffset( + buffer.data, view.byteOffset + 2 * sizeof(float) * i)); + vertices.buffer[i].TCoords = t; + } +} + +static video::S3DVertex* getVertices(const tinygltf::Model& model, + const std::size_t accessorId) +{ + auto* vertexBuffer = new video::S3DVertex[ + model.accessors[accessorId].count]{}; + Span vertices{ + vertexBuffer, model.accessors[accessorId].count}; + copyPositions(model, vertices, accessorId); + + const auto tCoordsField + = model.meshes[0].primitives[0].attributes.find("TEXCOORD_0"); + if (tCoordsField != model.meshes[0].primitives[0].attributes.end()) { + copyTCoords(model, vertices, tCoordsField->second); + } + + return vertexBuffer; +} + +static u16* getIndices(const tinygltf::Model& model, + const std::size_t accessorId) { const auto& view = model.bufferViews[ model.accessors[accessorId].bufferView]; diff --git a/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp b/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp index 002cb10b..a0a14052 100644 --- a/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp @@ -84,8 +84,7 @@ TEST_CASE("blender cube") { CHECK(vertices[21].Pos == irr::core::vector3df{-10.0f, 10.0f, -10.0f}); } - SECTION("vertex indices are correct") - { + SECTION("vertex indices are correct") { REQUIRE(sm.getMesh()->getMeshBuffer(0)->getIndexCount() == 36); const auto* indices = reinterpret_cast( sm.getMesh()->getMeshBuffer(0)->getIndices()); @@ -93,6 +92,17 @@ TEST_CASE("blender cube") { CHECK(indices[1] == 3); CHECK(indices[2] == 9); } + + SECTION("texture coords are correct") { + REQUIRE(sm.getMesh()->getMeshBuffer(0)->getVertexCount() == 24); + const auto* vertices = reinterpret_cast( + sm.getMesh()->getMeshBuffer(0)->getVertices()); + CHECK(vertices[0].TCoords == irr::core::vector2df{0.375f, 1.0f}); + CHECK(vertices[1].TCoords == irr::core::vector2df{0.125f, 0.25f}); + CHECK(vertices[2].TCoords == irr::core::vector2df{0.375f, 0.0f}); + CHECK(vertices[3].TCoords == irr::core::vector2df{0.6250f, 1.0f}); + CHECK(vertices[6].TCoords == irr::core::vector2df{0.375f, 0.75f}); + } } TEST_CASE("mesh loader returns nullptr when given null file pointer") {