#ifndef __C_GLTF_MESH_FILE_LOADER_INCLUDED__ #define __C_GLTF_MESH_FILE_LOADER_INCLUDED__ #include "ISkinnedMesh.h" #include "IMeshLoader.h" #include "IReadFile.h" #include "irrTypes.h" #include "path.h" #include "S3DVertex.h" #include "vector2d.h" #include "vector3d.h" #include #include #include namespace irr { namespace scene { class CGLTFMeshFileLoader : public IMeshLoader { public: CGLTFMeshFileLoader() noexcept; bool isALoadableFileExtension(const io::path& filename) const override; IAnimatedMesh* createMesh(io::IReadFile* file) override; private: class BufferOffset { public: BufferOffset(const std::vector& buf, const std::size_t offset); BufferOffset(const BufferOffset& other, const std::size_t fromOffset); unsigned char at(const std::size_t fromOffset) const; private: const std::vector& m_buf; std::size_t m_offset; int m_filesize; }; class MeshExtractor { public: using vertex_t = video::S3DVertex; MeshExtractor(const tiniergltf::GlTF &model, ISkinnedMesh *mesh) noexcept : m_gltf_model(model), m_irr_model(mesh) {}; MeshExtractor(const tiniergltf::GlTF &&model, ISkinnedMesh *mesh) noexcept : m_gltf_model(model), m_irr_model(mesh) {}; /* Gets indices for the given mesh/primitive. * * Values are return in Irrlicht winding order. */ std::optional> getIndices(const std::size_t meshIdx, const std::size_t primitiveIdx) const; std::optional> getVertices(std::size_t meshIdx, const std::size_t primitiveIdx) const; std::size_t getMeshCount() const; std::size_t getPrimitiveCount(const std::size_t meshIdx) const; void loadNodes() const; private: const tiniergltf::GlTF m_gltf_model; ISkinnedMesh *m_irr_model; template static T readPrimitive(const BufferOffset& readFrom); static core::vector2df readVec2DF( const BufferOffset& readFrom); /* Read a vec3df from a buffer with transformations applied. * * Values are returned in Irrlicht coordinates. */ static core::vector3df readVec3DF( const BufferOffset& readFrom, const core::vector3df scale); void copyPositions(const std::size_t accessorIdx, std::vector& vertices) const; void copyNormals(const std::size_t accessorIdx, std::vector& vertices) const; void copyTCoords(const std::size_t accessorIdx, std::vector& vertices) const; std::size_t getElemCount(const std::size_t accessorIdx) const; std::size_t getByteStride(const std::size_t accessorIdx) const; bool isAccessorNormalized(const std::size_t accessorIdx) const; BufferOffset getBuffer(const std::size_t accessorIdx) const; std::optional getIndicesAccessorIdx(const std::size_t meshIdx, const std::size_t primitiveIdx) const; std::optional getPositionAccessorIdx(const std::size_t meshIdx, const std::size_t primitiveIdx) const; /* Get the accessor id of the normals of a primitive. */ std::optional getNormalAccessorIdx(const std::size_t meshIdx, const std::size_t primitiveIdx) const; /* Get the accessor id for the tcoords of a primitive. */ std::optional getTCoordAccessorIdx(const std::size_t meshIdx, const std::size_t primitiveIdx) const; void loadMesh( std::size_t meshIdx, ISkinnedMesh::SJoint *parentJoint) const; void loadNode( const std::size_t nodeIdx, ISkinnedMesh::SJoint *parentJoint) const; }; std::optional tryParseGLTF(io::IReadFile* file); }; } // namespace scene } // namespace irr #endif // __C_GLTF_MESH_FILE_LOADER_INCLUDED__