From 1b9d3ca5023a2b9f88f1cc9ce8fa0daee12b2f99 Mon Sep 17 00:00:00 2001 From: Josiah VanderZee Date: Thu, 10 Nov 2022 13:58:28 -0600 Subject: [PATCH] Test for correct vertex indices --- source/Irrlicht/CGLTFMeshFileLoader.cpp | 111 +++++++++++------- source/Irrlicht/CGLTFMeshFileLoader.h | 3 - .../tests/testCGLTFMeshFileLoader.cpp | 25 ++-- 3 files changed, 87 insertions(+), 52 deletions(-) diff --git a/source/Irrlicht/CGLTFMeshFileLoader.cpp b/source/Irrlicht/CGLTFMeshFileLoader.cpp index 3ebd117c..e3cc27ca 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/CGLTFMeshFileLoader.cpp @@ -18,12 +18,6 @@ #include #include -namespace irr -{ - -namespace scene -{ - class BufferOffset { public: @@ -50,20 +44,77 @@ private: std::size_t m_offset; }; -static float readFloat(const BufferOffset& readFrom) { - unsigned char d[4]{}; - for (int i = 0; i < 4; ++i) { +namespace irr +{ + +namespace scene +{ + +static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) +{ + tinygltf::TinyGLTF loader {}; + std::string err {}; + std::string warn {}; + + auto buf = std::make_unique(file->getSize()); + file->read(buf.get(), file->getSize()); + return loader.LoadASCIIFromString( + &model, &err, &warn, buf.get(), file->getSize(), "", 1); +} + +template +static T readPrimative(const BufferOffset& readFrom) { + unsigned char d[sizeof(T)]{}; + for (std::size_t i = 0; i < sizeof(T); ++i) { d[i] = readFrom.at(i); } - return *reinterpret_cast(d); + return *reinterpret_cast(d); } static core::vector3df readVector(const BufferOffset& readFrom) { // glTF coordinates are right-handed, minetest ones are left-handed + // 1 glTF coordinate is equivalent to 10 Irrlicht coordinates return core::vector3df( - -readFloat(readFrom), - readFloat(BufferOffset(readFrom, sizeof(float))), - readFloat(BufferOffset(readFrom, 2 * sizeof(float)))); + -1.0 * readPrimative(readFrom), + 1.0 * readPrimative(BufferOffset(readFrom, sizeof(float))), + 1.0 * readPrimative(BufferOffset(readFrom, 2 * sizeof(float)))); +} + +static u16* readIndices(const BufferOffset& readFrom, const std::size_t count) +{ + auto* indices = new u16[count]{}; + for (std::size_t i = 0; i < count; ++i) { + indices[i] = readPrimative(BufferOffset(readFrom, i * sizeof(u16))); + } + return indices; +} + +video::S3DVertex* getVertices(const tinygltf::Model& model, const std::size_t accessorId) +{ + const auto& view = model.bufferViews[ + model.accessors[accessorId].bufferView]; + const auto& buffer = model.buffers[view.buffer]; + const auto v1 = readVector(BufferOffset( + buffer.data, view.byteOffset)); + const auto v2 = readVector(BufferOffset( + buffer.data, view.byteOffset + (3 * sizeof(float)))); + const auto v3 = readVector(BufferOffset( + buffer.data, view.byteOffset + (6 * sizeof(float)))); + + return (new video::S3DVertex[3] { + {v1, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 0.0f}}, + {v2, {0.0f, 0.0f, 1.0f}, {}, {1.0f, 0.0f}}, + {v3, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 1.0f}} } ); +} + +u16* getIndices(const tinygltf::Model& model, const std::size_t accessorId) +{ + const auto& indicesView = model.bufferViews[ + model.accessors[accessorId].bufferView]; + const auto& indicesBuffer = model.buffers[indicesView.buffer]; + return readIndices( + BufferOffset(indicesBuffer.data, indicesView.byteOffset), + model.accessors[0].count); } CGLTFMeshFileLoader::CGLTFMeshFileLoader() @@ -84,24 +135,13 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) return nullptr; } - const auto& view = model.bufferViews[model.accessors[1].bufferView]; - const auto& buffer = model.buffers[view.buffer]; - const auto v1 = readVector(BufferOffset( - buffer.data, view.byteOffset)); - const auto v2 = readVector(BufferOffset( - buffer.data, view.byteOffset + (3 * sizeof(float)))); - const auto v3 = readVector(BufferOffset( - buffer.data, view.byteOffset + (6 * sizeof(float)))); + auto* indices = getIndices(model, 0); + auto* vertices = getVertices(model, 1); - // sorry Bjarne SMeshBuffer* meshbuf { new SMeshBuffer {} }; - const video::S3DVertex* vertices { new video::S3DVertex[3] { - {v1, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 0.0f}}, - {v2, {0.0f, 0.0f, 1.0f}, {}, {1.0f, 0.0f}}, - {v3, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 1.0f}} } }; - const u16* indices { new u16[3] {0, 2, 1} }; - meshbuf->append(vertices, 3, indices, 3); + meshbuf->append(vertices, model.accessors[1].count, + indices, model.accessors[0].count); SMesh* mesh { new SMesh {} }; mesh->addMeshBuffer(meshbuf); @@ -112,20 +152,7 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) return animatedMesh; } -bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file, - tinygltf::Model& model) const -{ - tinygltf::TinyGLTF loader {}; - std::string err {}; - std::string warn {}; - - auto buf = std::make_unique(file->getSize()); - file->read(buf.get(), file->getSize()); - return loader.LoadASCIIFromString( - &model, &err, &warn, buf.get(), file->getSize(), "", 1); -} +} // namespace scene } // namespace irr -} // namespace scene - diff --git a/source/Irrlicht/CGLTFMeshFileLoader.h b/source/Irrlicht/CGLTFMeshFileLoader.h index 766efe67..35ad3532 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.h +++ b/source/Irrlicht/CGLTFMeshFileLoader.h @@ -22,9 +22,6 @@ public: bool isALoadableFileExtension(const io::path& filename) const override; IAnimatedMesh* createMesh(io::IReadFile* file) override; - -private: - bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) const; }; } // namespace scene diff --git a/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp b/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp index 413623e8..4bccfaa5 100644 --- a/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp @@ -45,19 +45,30 @@ TEST_CASE("load empty gltf file") { CHECK(sm.getMesh() == nullptr); } -TEST_CASE("minimal triangle has correct vertices") { +TEST_CASE("minimal triangle") { ScopedMesh sm { "source/Irrlicht/tests/assets/minimal_triangle.gltf" }; auto* mesh = sm.getMesh(); REQUIRE(mesh != nullptr); REQUIRE(mesh->getMeshBufferCount() == 1); auto* meshbuf = mesh->getMeshBuffer(0); - REQUIRE(meshbuf->getVertexCount() == 3); - auto* vertices = reinterpret_cast( - meshbuf->getVertices()); - CHECK(vertices[0].Pos == irr::core::vector3df {0.0f, 0.0f, 0.0f}); - CHECK(vertices[1].Pos == irr::core::vector3df {-1.0f, 0.0f, 0.0f}); - CHECK(vertices[2].Pos == irr::core::vector3df {0.0f, 1.0f, 0.0f}); + + SECTION("vertex coordinates are correct") { + REQUIRE(meshbuf->getVertexCount() == 3); + auto* vertices = reinterpret_cast( + meshbuf->getVertices()); + CHECK(vertices[0].Pos == irr::core::vector3df {0.0f, 0.0f, 0.0f}); + CHECK(vertices[1].Pos == irr::core::vector3df {-1.0f, 0.0f, 0.0f}); + CHECK(vertices[2].Pos == irr::core::vector3df {0.0f, 1.0f, 0.0f}); + } + + SECTION("vertex indices are correct") { + REQUIRE(meshbuf->getIndexCount() == 3); + auto* indices = reinterpret_cast(meshbuf->getIndices()); + CHECK(indices[0] == 0); + CHECK(indices[1] == 1); + CHECK(indices[2] == 2); + } } TEST_CASE("mesh loader returns nullptr when given null file pointer") {