From ac7bac9a3a4569c36e375211f3c3f6c5652d1de9 Mon Sep 17 00:00:00 2001 From: JosiahWI Date: Sun, 6 Nov 2022 07:55:09 -0600 Subject: [PATCH] Load vertex coordinates from glTF buffer --- source/Irrlicht/CGLTFMeshFileLoader.cpp | 60 ++++++++++++++++--- source/Irrlicht/CGLTFMeshFileLoader.h | 1 - .../tests/testCGLTFMeshFileLoader.cpp | 4 +- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/source/Irrlicht/CGLTFMeshFileLoader.cpp b/source/Irrlicht/CGLTFMeshFileLoader.cpp index 81f4fd8a1..540c80a0c 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/CGLTFMeshFileLoader.cpp @@ -9,10 +9,12 @@ #include "SAnimatedMesh.h" #include "SColor.h" #include "SMesh.h" +#include "vector3d.h" #define TINYGLTF_IMPLEMENTATION #include +#include #include #include @@ -22,6 +24,33 @@ namespace irr namespace scene { +class BufferOffset +{ +public: + BufferOffset(const std::vector& buf, + const std::size_t offset) noexcept + : m_buf(buf), m_offset(offset) + { + } + + unsigned char at(const std::size_t fromOffset) const + { + return m_buf.at(m_offset + fromOffset); + } + +private: + const std::vector& m_buf; + std::size_t m_offset; +}; + +static constexpr float readFloat(const BufferOffset& readFrom) { + unsigned char d[4]{}; + for (int i = 0; i < 4; ++i) { + d[i] = readFrom.at(i); + } + return *reinterpret_cast(d); +} + CGLTFMeshFileLoader::CGLTFMeshFileLoader() { } @@ -34,18 +63,35 @@ bool CGLTFMeshFileLoader::isALoadableFileExtension( IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) { - if (file->getSize() == 0 || !tryParseGLTF(file)) { + tinygltf::Model model{}; + + if (file->getSize() == 0 || !tryParseGLTF(file, model)) { return nullptr; } + const auto& view = model.bufferViews[model.accessors[1].bufferView]; + const auto& buffer = model.buffers[view.buffer]; + const core::vector3df v1( + -readFloat(BufferOffset(buffer.data, view.byteOffset)), + readFloat(BufferOffset(buffer.data, view.byteOffset + 4)), + readFloat(BufferOffset(buffer.data, view.byteOffset + 8))); + const core::vector3df v2( + -readFloat(BufferOffset(buffer.data, view.byteOffset + 12)), + readFloat(BufferOffset(buffer.data, view.byteOffset + 16)), + readFloat(BufferOffset(buffer.data, view.byteOffset + 20))); + const core::vector3df v3( + -readFloat(BufferOffset(buffer.data, view.byteOffset + 24)), + readFloat(BufferOffset(buffer.data, view.byteOffset + 28)), + readFloat(BufferOffset(buffer.data, view.byteOffset + 32))); + // sorry Bjarne SMeshBuffer* meshbuf { new SMeshBuffer {} }; const video::S3DVertex* vertices { new video::S3DVertex[3] { - {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 0.0f}}, - {{0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {}, {1.0f, 0.0f}}, - {{-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {}, {0.0f, 1.0f}} } }; - const u16* indices { new u16[3] {0, 1, 2} }; + {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); SMesh* mesh { new SMesh {} }; @@ -57,9 +103,9 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) return animatedMesh; } -bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file) const +bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file, + tinygltf::Model& model) const { - tinygltf::Model model {}; tinygltf::TinyGLTF loader {}; std::string err {}; std::string warn {}; diff --git a/source/Irrlicht/CGLTFMeshFileLoader.h b/source/Irrlicht/CGLTFMeshFileLoader.h index 76f464df3..383015ccc 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.h +++ b/source/Irrlicht/CGLTFMeshFileLoader.h @@ -30,4 +30,3 @@ private: } // namespace irr #endif // __C_GLTF_MESH_FILE_LOADER_INCLUDED__ - diff --git a/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp b/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp index c717ac5a2..413623e8a 100644 --- a/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/tests/testCGLTFMeshFileLoader.cpp @@ -56,8 +56,8 @@ TEST_CASE("minimal triangle has correct vertices") { 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 {0.0f, 1.0f, 0.0f}); - CHECK(vertices[2].Pos == irr::core::vector3df {-1.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}); } TEST_CASE("mesh loader returns nullptr when given null file pointer") {