diff --git a/source/Irrlicht/CGLTFMeshFileLoader.cpp b/source/Irrlicht/CGLTFMeshFileLoader.cpp index 13d387a1..1a5d02fc 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/CGLTFMeshFileLoader.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -133,8 +132,8 @@ std::vector CGLTFMeshFileLoader::MeshExtractor::getIndices( const std::size_t meshIdx, const std::size_t primitiveIdx) const { - auto accessorIdx = getIndicesAccessorIdx(meshIdx, primitiveIdx); - auto buf = getBuffer(meshIdx, primitiveIdx, accessorIdx); + const auto accessorIdx = getIndicesAccessorIdx(meshIdx, primitiveIdx); + const auto& buf = getBuffer(accessorIdx); std::vector indices{}; const auto count = getElemCount(accessorIdx); @@ -151,29 +150,22 @@ std::vector CGLTFMeshFileLoader::MeshExtractor::getVertices( const std::size_t meshIdx, const std::size_t primitiveIdx) const { - auto positionAccessorIdx = getPositionAccessorIdx(meshIdx, primitiveIdx); - auto vertexCount = getElemCount(positionAccessorIdx); - std::vector vertices{}; - vertices.resize(vertexCount); + const auto positionAccessorIdx = getPositionAccessorIdx( + meshIdx, primitiveIdx); + std::vector vertices{}; + vertices.resize(getElemCount(positionAccessorIdx)); + copyPositions(positionAccessorIdx, vertices); - Span outVertices {vertices.data(), vertexCount}; - - copyPositions(outVertices, positionAccessorIdx); - - const auto normalsField = m_model.meshes[meshIdx] - .primitives[primitiveIdx].attributes.find("NORMAL"); - - if (normalsField != m_model.meshes[meshIdx] - .primitives[primitiveIdx].attributes.end()) { - copyNormals(outVertices, normalsField->second); + const auto normalAccessorIdx = getNormalAccessorIdx( + meshIdx, primitiveIdx); + if (normalAccessorIdx != static_cast(-1)) { + copyNormals(normalAccessorIdx, vertices); } - const auto tCoordsField = m_model.meshes[meshIdx] - .primitives[primitiveIdx].attributes.find("TEXCOORD_0"); - - if (tCoordsField != m_model.meshes[meshIdx] - .primitives[primitiveIdx].attributes.end()) { - copyTCoords(outVertices, tCoordsField->second); + const auto tCoordAccessorIdx = getTCoordAccessorIdx( + meshIdx, primitiveIdx); + if (tCoordAccessorIdx != static_cast(-1)) { + copyTCoords(tCoordAccessorIdx, vertices); } return vertices; @@ -224,53 +216,45 @@ core::vector3df CGLTFMeshFileLoader::MeshExtractor::readVec3DF( } void CGLTFMeshFileLoader::MeshExtractor::copyPositions( - const Span vertices, - const std::size_t accessorId) const + const std::size_t accessorIdx, + std::vector& vertices) const { - const auto& view = m_model.bufferViews[ - m_model.accessors[accessorId].bufferView]; - const auto& buffer = m_model.buffers[view.buffer]; - const auto count = m_model.accessors[accessorId].count; + const auto& buffer = getBuffer(accessorIdx); + const auto count = getElemCount(accessorIdx); for (std::size_t i = 0; i < count; i++) { - const auto v = readVec3DF(BufferOffset( - buffer.data, - view.byteOffset + (3 * sizeof(float) * i)), - getScale()); - vertices.buffer[i].Pos = v; + const auto v = readVec3DF(BufferOffset(buffer, + 3 * sizeof(float) * i), getScale()); + vertices[i].Pos = v; } } void CGLTFMeshFileLoader::MeshExtractor::copyNormals( - const Span vertices, - const std::size_t accessorId) const + const std::size_t accessorIdx, + std::vector& vertices) const { - const auto& view = m_model.bufferViews[ - m_model.accessors[accessorId].bufferView]; - const auto& buffer = m_model.buffers[view.buffer]; - const auto count = m_model.accessors[accessorId].count; + const auto& buffer = getBuffer(accessorIdx); + const auto count = getElemCount(accessorIdx); for (std::size_t i = 0; i < count; i++) { - const auto n = readVec3DF(BufferOffset(buffer.data, - view.byteOffset + 3 * sizeof(float) * i )); - vertices.buffer[i].Normal = n; + const auto n = readVec3DF(BufferOffset(buffer, + 3 * sizeof(float) * i)); + vertices[i].Normal = n; } } void CGLTFMeshFileLoader::MeshExtractor::copyTCoords( - const Span vertices, - const std::size_t accessorId) const + const std::size_t accessorIdx, + std::vector& vertices) const { - const auto& view = m_model.bufferViews[ - m_model.accessors[accessorId].bufferView]; - const auto& buffer = m_model.buffers[view.buffer]; - const auto count = m_model.accessors[accessorId].count; + const auto& buffer = getBuffer(accessorIdx); + const auto count = getElemCount(accessorIdx); for (std::size_t i = 0; i < count; ++i) { - const auto t = readVec2DF(BufferOffset( - buffer.data, view.byteOffset + 2 * sizeof(float) * i)); - vertices.buffer[i].TCoords = t; + const auto t = readVec2DF(BufferOffset(buffer, + 2 * sizeof(float) * i)); + vertices[i].TCoords = t; } } @@ -290,8 +274,6 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getElemCount( } CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer( - const std::size_t meshIdx, - const std::size_t primitiveIdx, const std::size_t accessorIdx) const { const auto& accessor = m_model.accessors[accessorIdx]; @@ -316,6 +298,36 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getPositionAccessorIdx( .attributes.find("POSITION")->second; } +std::size_t CGLTFMeshFileLoader::MeshExtractor::getNormalAccessorIdx( + const std::size_t meshIdx, + const std::size_t primitiveIdx) const +{ + const auto& attributes = m_model.meshes[meshIdx] + .primitives[primitiveIdx].attributes; + const auto result = attributes.find("NORMAL"); + + if (result == attributes.end()) { + return -1; + } else { + return result->second; + } +} + +std::size_t CGLTFMeshFileLoader::MeshExtractor::getTCoordAccessorIdx( + const std::size_t meshIdx, + const std::size_t primitiveIdx) const +{ + const auto& attributes = m_model.meshes[meshIdx] + .primitives[primitiveIdx].attributes; + const auto result = attributes.find("TEXCOORD_0"); + + if (result == attributes.end()) { + return -1; + } else { + return result->second; + } +} + bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) { diff --git a/source/Irrlicht/CGLTFMeshFileLoader.h b/source/Irrlicht/CGLTFMeshFileLoader.h index 0d862a6f..18f0cc59 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.h +++ b/source/Irrlicht/CGLTFMeshFileLoader.h @@ -32,13 +32,6 @@ public: IAnimatedMesh* createMesh(io::IReadFile* file) override; private: - template - struct Span - { - T* buffer = nullptr; - std::size_t size = 0; - }; - class BufferOffset { public: @@ -57,6 +50,8 @@ private: class MeshExtractor { public: + using vertex_t = video::S3DVertex; + MeshExtractor(const tinygltf::Model& model) noexcept; MeshExtractor(const tinygltf::Model&& model) noexcept; @@ -68,7 +63,7 @@ private: std::vector getIndices(const std::size_t meshIdx, const std::size_t primitiveIdx) const; - std::vector getVertices(std::size_t meshIdx, + std::vector getVertices(std::size_t meshIdx, const std::size_t primitiveIdx) const; std::size_t getMeshCount() const; @@ -92,14 +87,14 @@ private: const BufferOffset& readFrom, const float scale = 1.0f); - void copyPositions(const Span vertices, - const std::size_t accessorId) const; + void copyPositions(const std::size_t accessorIdx, + std::vector& vertices) const; - void copyNormals(const Span vertices, - const std::size_t accessorId) const; + void copyNormals(const std::size_t accessorIdx, + std::vector& vertices) const; - void copyTCoords(const Span vertices, - const std::size_t accessorId) const; + void copyTCoords(const std::size_t accessorIdx, + std::vector& vertices) const; /* Get the scale factor from the glTF mesh information. * @@ -109,15 +104,27 @@ private: std::size_t getElemCount(const std::size_t accessorIdx) const; - BufferOffset getBuffer(const std::size_t meshIdx, - const std::size_t primitiveIdx, - const std::size_t accessorIdx) const; + BufferOffset getBuffer(const std::size_t accessorIdx) const; std::size_t getIndicesAccessorIdx(const std::size_t meshIdx, const std::size_t primitiveIdx) const; std::size_t getPositionAccessorIdx(const std::size_t meshIdx, const std::size_t primitiveIdx) const; + + /* Get the accessor id of the normals of a primitive. + * + * -1 is returned if none are present. + */ + std::size_t getNormalAccessorIdx(const std::size_t meshIdx, + const std::size_t primitiveIdx) const; + + /* Get the accessor id for the tcoords of a primitive. + * + * -1 is returned if none are present. + */ + std::size_t getTCoordAccessorIdx(const std::size_t meshIdx, + const std::size_t primitiveIdx) const; }; void loadPrimitives(const MeshExtractor& parser, SMesh* mesh);