From ea22b642c152d7cf95d369880964a8ded18463ad Mon Sep 17 00:00:00 2001 From: JosiahWI Date: Wed, 17 May 2023 16:47:02 -0500 Subject: [PATCH] Refactor getIndices() --- source/Irrlicht/CGLTFMeshFileLoader.cpp | 132 ++++++++++++++---------- source/Irrlicht/CGLTFMeshFileLoader.h | 20 +++- 2 files changed, 95 insertions(+), 57 deletions(-) diff --git a/source/Irrlicht/CGLTFMeshFileLoader.cpp b/source/Irrlicht/CGLTFMeshFileLoader.cpp index af1d12fb..510ae76f 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.cpp +++ b/source/Irrlicht/CGLTFMeshFileLoader.cpp @@ -84,63 +84,47 @@ bool CGLTFMeshFileLoader::isALoadableFileExtension( IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file) { - tinygltf::Model model{}; + tinygltf::Model model {}; if (file->getSize() == 0 || !tryParseGLTF(file, model)) { return nullptr; } - // Create the base mesh - SMesh* mesh { new SMesh {} }; + ModelParser parser(std::move(model)); + SMesh* baseMesh(new SMesh {}); // Iterate models for (std::size_t meshIndex = 0; - meshIndex < model.meshes.size(); meshIndex++) { - // Iterate primitives - for (std::size_t primitiveIndex = 0; primitiveIndex < model - .meshes[meshIndex].primitives.size(); primitiveIndex++) { + meshIndex < parser.getMeshCount(); meshIndex++) { + // Iterate primitives + for (std::size_t primitiveIndex = 0; primitiveIndex < parser.getPrimitiveCount(meshIndex); primitiveIndex++) { + const auto positionAccessorId = model.meshes[meshIndex] + .primitives[primitiveIndex].attributes["POSITION"]; - const auto positionAccessorId = model.meshes[meshIndex] - .primitives[primitiveIndex].attributes["POSITION"]; - const auto indicesAccessorId = model.meshes[meshIndex] - .primitives[primitiveIndex].indices; + // Creates counts for preallocation + std::size_t vertexCount = model.accessors[positionAccessorId].count; - // Creates counts for preallocation - std::size_t vertexCount = model.accessors[positionAccessorId].count; + // We must count to create containers for the data + // Create new buffer for vertices, positions, and normals + auto* vertexBuffer = new video::S3DVertex[vertexCount](); + // This is used to copy data into the vertexBuffer + Span verticesBuffer{vertexBuffer,vertexCount}; + auto indices = parser.getIndices(meshIndex, primitiveIndex); + parser.getVertices(positionAccessorId, + verticesBuffer, + meshIndex, + primitiveIndex); - // We must count to create containers for the data - // Create new buffer for vertices, positions, and normals - auto* vertexBuffer = new video::S3DVertex[vertexCount](); - // This is used to copy data into the vertexBuffer - Span verticesBuffer{vertexBuffer,vertexCount}; - // Create dynamic indices buffer so it's easier to work with. - // Preallocate needed resources to boost game startup speed - std::vector indicesBuffer(model.accessors[ - indicesAccessorId].count); - - ModelParser parser(std::move(model)); - - parser.getIndices(indicesAccessorId, indicesBuffer); - parser.getVertices(positionAccessorId, - verticesBuffer, - meshIndex, - primitiveIndex); - - std::reverse(indicesBuffer.begin(),indicesBuffer.end()); - - // Create the mesh buffer - SMeshBuffer* meshbuf { new SMeshBuffer {} }; - meshbuf->append(vertexBuffer, vertexCount, indicesBuffer.data(), - indicesBuffer.size()); - - mesh->addMeshBuffer(meshbuf); - - } + SMeshBuffer* meshbuf(new SMeshBuffer {}); + meshbuf->append(vertexBuffer, vertexCount, + indices.data(), indices.size()); + baseMesh->addMeshBuffer(meshbuf); + } } // Create the mesh animations SAnimatedMesh* animatedMesh { new SAnimatedMesh {} }; - animatedMesh->addMesh(mesh); + animatedMesh->addMesh(baseMesh); return animatedMesh; } @@ -157,21 +141,22 @@ CGLTFMeshFileLoader::ModelParser::ModelParser( { } -void CGLTFMeshFileLoader::ModelParser::getIndices( - const std::size_t accessorId, - std::vector& outIndices) const +std::vector CGLTFMeshFileLoader::ModelParser::getIndices( + std::size_t meshIdx, + std::size_t primitiveIdx) const { - const auto& view = m_model.bufferViews[ - m_model.accessors[accessorId].bufferView]; - const auto& modelIndices = m_model.buffers[view.buffer]; + auto accessorIdx = getIndicesAccessorIdx(meshIdx, primitiveIdx); + auto buf = getBuffer(meshIdx, primitiveIdx, accessorIdx); - auto buffOffset = BufferOffset(modelIndices.data, view.byteOffset); - auto count = m_model.accessors[accessorId].count; - - for (std::size_t i = 0; i < count; i++) { - outIndices[i] = readPrimitive(BufferOffset( - buffOffset, i * sizeof(u16))); + std::vector indices{}; + std::size_t count = getElemCount(accessorIdx); + for (std::size_t i = 0; i < count; ++i) { + std::size_t elemIdx = count - i - 1; + indices.push_back(readPrimitive( + BufferOffset(buf, elemIdx * sizeof(u16)))); } + + return indices; } //Returns a tuple of the current counts (current_vertex_index, @@ -201,6 +186,18 @@ void CGLTFMeshFileLoader::ModelParser::getVertices( } } +std::size_t CGLTFMeshFileLoader::ModelParser::getMeshCount() const +{ + return m_model.meshes.size(); +} + +std::size_t CGLTFMeshFileLoader::ModelParser::getPrimitiveCount( + std::size_t meshIdx) const +{ + return m_model.meshes[meshIdx].primitives.size(); +} + + template T CGLTFMeshFileLoader::ModelParser::readPrimitive( const BufferOffset& readFrom) @@ -262,7 +259,7 @@ void CGLTFMeshFileLoader::ModelParser::copyNormals( const auto count = m_model.accessors[accessorId].count; for (std::size_t i = 0; i < count; i++) { - const auto n = readVec3DF(BufferOffset( buffer.data, + const auto n = readVec3DF(BufferOffset(buffer.data, view.byteOffset + 3 * sizeof(float) * i )); vertices.buffer[i].Normal = n; } @@ -293,6 +290,31 @@ float CGLTFMeshFileLoader::ModelParser::getScale() const return 1.0f; } +std::size_t CGLTFMeshFileLoader::ModelParser::getElemCount( + std::size_t accessorIdx) const +{ + return m_model.accessors[accessorIdx].count; +} + +CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::ModelParser::getBuffer( + std::size_t meshIdx, + std::size_t primitiveIdx, + std::size_t accessorIdx) const +{ + const auto& accessor = m_model.accessors[accessorIdx]; + const auto& view = m_model.bufferViews[accessor.bufferView]; + const auto& buffer = m_model.buffers[view.buffer]; + + return BufferOffset(buffer.data, view.byteOffset); +} + +std::size_t CGLTFMeshFileLoader::ModelParser::getIndicesAccessorIdx( + std::size_t meshIdx, + std::size_t primitiveIdx) const +{ + return m_model.meshes[meshIdx].primitives[primitiveIdx].indices; +} + bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) { diff --git a/source/Irrlicht/CGLTFMeshFileLoader.h b/source/Irrlicht/CGLTFMeshFileLoader.h index 968a7603..e071f9b6 100644 --- a/source/Irrlicht/CGLTFMeshFileLoader.h +++ b/source/Irrlicht/CGLTFMeshFileLoader.h @@ -60,14 +60,21 @@ private: ModelParser(const tinygltf::Model&& model); - void getIndices(const std::size_t accessorId, - std::vector& outIndices) const; + /* Gets indices for the given mesh/primitive. + * + * Values are return in Irrlicht winding order. + */ + std::vector getIndices(std::size_t meshIdx, + std::size_t primitiveIdx) const; void getVertices(const std::size_t accessorId, Span& outVertices, std::size_t meshIndex, std::size_t primitiveIndex) const; + std::size_t getMeshCount() const; + std::size_t getPrimitiveCount(std::size_t meshIdx) const; + private: tinygltf::Model m_model; @@ -91,6 +98,15 @@ private: const std::size_t accessorId) const; float getScale() const; + + std::size_t getElemCount(std::size_t accessorIdx) const; + + BufferOffset getBuffer(std::size_t meshIdx, + std::size_t primitiveIdx, + std::size_t accessorIdx) const; + + std::size_t getIndicesAccessorIdx(std::size_t meshIdx, + std::size_t primitiveIdx) const; }; static bool tryParseGLTF(io::IReadFile* file,