From f8f10248b4a7d6ab67939a1c3b520248896428d3 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Fri, 1 Dec 2023 17:10:01 -0500 Subject: [PATCH] Package glTF spec docs with comments * git --CRUSH And try to make this line the same Now undo my gitignore nonsense Hail mary Move these functions to the top More documentation Add some serious documentation Move this to the top Readability & documentation Add some documentation Add spec documentation Make this more more complex to make it less complex Move this up & document Make this more readable for me Document and make this more readable Move this out of the way and document it Update CGLTFMeshFileLoader.cpp Documentation Document Update CGLTFMeshFileLoader.cpp Document Move entry point to bottom Part 5 Part 4 Part 3 Part 2 Allman -> OTBS (readability for me) Consolidate Remove unneeded function These files are annoying * fix #1 * fix 2 * indentation * Remove redundant function * Remove redundant function * add trailing new line * Stop an interesting build error with a template * Code reduction * Document bytestride * Add more detail to chain hierarchy * Dump this huge vscode thing in here for no reason * Document 3 more functions * Document copyTcoords * Dump in (incorrect) scale documentation for node * Add a readable description * Fix incorrect getScale * Add update based on context of function * Add documentation, fix another one * Document another * Document another * And document another * Document this nice function * Bolt in some future use documentation * Add highlighting for IDE * Just shovel on more docs to this * 2 more comments * I think that's all of them * Add some wild west debuggin * And then update this comment * Bolt on isAccessorNormalized() * Bolt in an absolute hack job to test * Now clean this mess up and give josiah ref material * Fix Josiah's request for scale * Fix josiah request * Fix josiah request .vscode Fix indentation Fix indentation Fix indentation * Unfix getScale() again --- include/vector3d.h | 1 - source/Irrlicht/CGLTFMeshFileLoader.cpp | 140 +++++++++++++++++++++--- source/Irrlicht/CGLTFMeshFileLoader.h | 6 +- 3 files changed, 128 insertions(+), 19 deletions(-) diff --git a/include/vector3d.h b/include/vector3d.h index 72a41f66..a69f17e1 100644 --- a/include/vector3d.h +++ b/include/vector3d.h @@ -7,7 +7,6 @@ #include "irrMath.h" #include -#include namespace irr { diff --git a/source/Irrlicht/CGLTFMeshFileLoader.cpp b/source/Irrlicht/CGLTFMeshFileLoader.cpp index 8bec5de2..899d95b4 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/CGLTFMeshFileLoader.cpp @@ -34,19 +34,6 @@ * of the vertex indices. */ -// A helper function to disable tinygltf embedded image loading -static bool dummyImageLoader(tinygltf::Image *a, - const int b, std::string *c, - std::string *d, - int e, - int f, - const unsigned char * g, - int h, - void *userPointer) -{ - return false; -}; - namespace irr { namespace scene { @@ -67,6 +54,9 @@ CGLTFMeshFileLoader::BufferOffset::BufferOffset( { } +/** + * Get a raw unsigned char (ubyte) from a buffer offset. +*/ unsigned char CGLTFMeshFileLoader::BufferOffset::at( const std::size_t fromOffset) const { @@ -77,12 +67,18 @@ CGLTFMeshFileLoader::CGLTFMeshFileLoader() noexcept { } +/** + * The most basic portion of the code base. This tells irllicht if this file has a .gltf extension. +*/ bool CGLTFMeshFileLoader::isALoadableFileExtension( const io::path& filename) const { return core::hasFileExtension(filename, "gltf"); } +/** + * Entry point into loading a GLTF model. +*/ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) { tinygltf::Model model {}; @@ -101,6 +97,12 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) return animatedMesh; } + +/** + * Load up the rawest form of the model. The vertex positions and indices. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes + * If material is undefined, then a default material MUST be used. +*/ void CGLTFMeshFileLoader::loadPrimitives( const MeshExtractor& parser, SMesh* mesh) @@ -130,6 +132,9 @@ CGLTFMeshFileLoader::MeshExtractor::MeshExtractor( { } +/** + * Extracts GLTF mesh indices into the irrlicht model. +*/ std::vector CGLTFMeshFileLoader::MeshExtractor::getIndices( const std::size_t meshIdx, const std::size_t primitiveIdx) const @@ -148,6 +153,9 @@ std::vector CGLTFMeshFileLoader::MeshExtractor::getIndices( return indices; } +/** + * Create a vector of video::S3DVertex (model data) from a mesh & primitive index. +*/ std::vector CGLTFMeshFileLoader::MeshExtractor::getVertices( const std::size_t meshIdx, const std::size_t primitiveIdx) const @@ -173,18 +181,30 @@ std::vector CGLTFMeshFileLoader::MeshExtractor::getVertices( return vertices; } +/** + * Get the amount of meshes that a model contains. +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getMeshCount() const { return m_model.meshes.size(); } +/** + * Get the amount of primitives that a mesh in a model contains. +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getPrimitiveCount( const std::size_t meshIdx) const { return m_model.meshes[meshIdx].primitives.size(); } - +/** + * Templated buffer reader. Based on type width. + * This is specifically used to build upon to read more complex data types. + * It is also used raw to read arrays directly. + * Basically we're using the width of the type to infer + * how big of a gap we have from the beginning of the buffer. +*/ template T CGLTFMeshFileLoader::MeshExtractor::readPrimitive( const BufferOffset& readFrom) @@ -198,6 +218,10 @@ T CGLTFMeshFileLoader::MeshExtractor::readPrimitive( return dest; } +/** + * Read a vector2df from a buffer at an offset. + * @return vec2 core::Vector2df +*/ core::vector2df CGLTFMeshFileLoader::MeshExtractor::readVec2DF( const CGLTFMeshFileLoader::BufferOffset& readFrom) { @@ -206,9 +230,13 @@ core::vector2df CGLTFMeshFileLoader::MeshExtractor::readVec2DF( } +/** + * Read a vector3df from a buffer at an offset. + * @return vec3 core::Vector3df +*/ core::vector3df CGLTFMeshFileLoader::MeshExtractor::readVec3DF( const BufferOffset& readFrom, - const float scale) + const float scale = 1.0f) { return core::vector3df( scale * readPrimitive(readFrom), @@ -217,6 +245,10 @@ core::vector3df CGLTFMeshFileLoader::MeshExtractor::readVec3DF( sizeof(float)))); } +/** + * Streams vertex positions raw data into usable buffer via reference. + * Buffer: ref Vector +*/ void CGLTFMeshFileLoader::MeshExtractor::copyPositions( const std::size_t accessorIdx, std::vector& vertices) const @@ -233,6 +265,10 @@ void CGLTFMeshFileLoader::MeshExtractor::copyPositions( } } +/** + * Streams normals raw data into usable buffer via reference. + * Buffer: ref Vector +*/ void CGLTFMeshFileLoader::MeshExtractor::copyNormals( const std::size_t accessorIdx, std::vector& vertices) const @@ -247,10 +283,15 @@ void CGLTFMeshFileLoader::MeshExtractor::copyNormals( } } +/** + * Streams texture coordinate raw data into usable buffer via reference. + * Buffer: ref Vector +*/ void CGLTFMeshFileLoader::MeshExtractor::copyTCoords( const std::size_t accessorIdx, std::vector& vertices) const { + const auto& buffer = getBuffer(accessorIdx); const auto count = getElemCount(accessorIdx); @@ -261,6 +302,13 @@ void CGLTFMeshFileLoader::MeshExtractor::copyTCoords( } } +/** + * Gets the scale of a model's node via a reference Vector3df. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-node + * Type: number[3] (tinygltf: vector) + * Required: NO + * @returns: core::vector2df +*/ float CGLTFMeshFileLoader::MeshExtractor::getScale() const { if (m_model.nodes[0].scale.size() > 0) { @@ -270,12 +318,25 @@ float CGLTFMeshFileLoader::MeshExtractor::getScale() const return 1.0f; } +/** + * The number of elements referenced by this accessor, not to be confused with the number of bytes or number of components. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_accessor_count + * Type: Integer + * Required: YES +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getElemCount( const std::size_t accessorIdx) const { return m_model.accessors[accessorIdx].count; } +/** + * The stride, in bytes, between vertex attributes. + * When this is not defined, data is tightly packed. + * When two or more accessors use the same buffer view, this field MUST be defined. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_bufferview_bytestride + * Required: NO +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getByteStride( const std::size_t accessorIdx) const { @@ -284,6 +345,24 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getByteStride( return accessor.ByteStride(view); } +/** + * Specifies whether integer data values are normalized (true) to [0, 1] (for unsigned types) + * or to [-1, 1] (for signed types) when they are accessed. This property MUST NOT be set to + * true for accessors with FLOAT or UNSIGNED_INT component type. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_accessor_normalized + * Required: NO +*/ +bool CGLTFMeshFileLoader::MeshExtractor::isAccessorNormalized( + const std::size_t accessorIdx) const +{ + const auto& accessor = m_model.accessors[accessorIdx]; + return accessor.normalized; +} + +/** + * Walk through the complex chain of the model to extract the required buffer. + * Accessor -> BufferView -> Buffer +*/ CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer( const std::size_t accessorIdx) const { @@ -294,6 +373,14 @@ CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer( return BufferOffset(buffer.data, view.byteOffset); } +/** + * The index of the accessor that contains the vertex indices. + * When this is undefined, the primitive defines non-indexed geometry. + * When defined, the accessor MUST have SCALAR type and an unsigned integer component type. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_mesh_primitive_indices + * Type: Integer + * Required: NO +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getIndicesAccessorIdx( const std::size_t meshIdx, const std::size_t primitiveIdx) const @@ -301,6 +388,12 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getIndicesAccessorIdx( return m_model.meshes[meshIdx].primitives[primitiveIdx].indices; } +/** + * The index of the accessor that contains the POSITIONs. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview + * Type: VEC3 (Float) + * ! Required: YES (Appears so, needs another pair of eyes to research.) +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getPositionAccessorIdx( const std::size_t meshIdx, const std::size_t primitiveIdx) const @@ -309,6 +402,12 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getPositionAccessorIdx( .attributes.find("POSITION")->second; } +/** + * The index of the accessor that contains the NORMALs. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview + * Type: VEC3 (Float) + * ! Required: NO (Appears to not be, needs another pair of eyes to research.) +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getNormalAccessorIdx( const std::size_t meshIdx, const std::size_t primitiveIdx) const @@ -324,6 +423,12 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getNormalAccessorIdx( } } +/** + * The index of the accessor that contains the NORMALs. + * Documentation: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview + * Type: VEC3 (Float) + * ! Required: YES (Appears so, needs another pair of eyes to research.) +*/ std::size_t CGLTFMeshFileLoader::MeshExtractor::getTCoordAccessorIdx( const std::size_t meshIdx, const std::size_t primitiveIdx) const @@ -339,13 +444,16 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getTCoordAccessorIdx( } } +/** + * This is where the actual model's GLTF file is loaded and parsed by tinygltf. +*/ bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) { tinygltf::TinyGLTF loader {}; // Stop embedded textures from making model fail to load - loader.SetImageLoader(dummyImageLoader, nullptr); + loader.SetImageLoader(nullptr, nullptr); std::string err {}; std::string warn {}; diff --git a/source/Irrlicht/CGLTFMeshFileLoader.h b/source/Irrlicht/CGLTFMeshFileLoader.h index 2f141168..3e03ce1d 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.h +++ b/source/Irrlicht/CGLTFMeshFileLoader.h @@ -85,7 +85,7 @@ private: */ static core::vector3df readVec3DF( const BufferOffset& readFrom, - const float scale = 1.0f); + const float scale); void copyPositions(const std::size_t accessorIdx, std::vector& vertices) const; @@ -98,7 +98,7 @@ private: /* Get the scale factor from the glTF mesh information. * - * Returns 1.0f if no scale factor is present. + * Returns vec3(1.0, 1.0, 1.0) if no scale factor is present. */ float getScale() const; @@ -106,6 +106,8 @@ private: 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::size_t getIndicesAccessorIdx(const std::size_t meshIdx,