mirror of
https://github.com/minetest/irrlicht.git
synced 2025-02-22 22:00:26 +01:00
Refactor getIndices()
This commit is contained in:
parent
5f5dd7abfc
commit
ea22b642c1
@ -84,26 +84,22 @@ bool CGLTFMeshFileLoader::isALoadableFileExtension(
|
|||||||
|
|
||||||
IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
|
IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
|
||||||
{
|
{
|
||||||
tinygltf::Model model{};
|
tinygltf::Model model {};
|
||||||
|
|
||||||
if (file->getSize() == 0 || !tryParseGLTF(file, model)) {
|
if (file->getSize() == 0 || !tryParseGLTF(file, model)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the base mesh
|
ModelParser parser(std::move(model));
|
||||||
SMesh* mesh { new SMesh {} };
|
SMesh* baseMesh(new SMesh {});
|
||||||
|
|
||||||
// Iterate models
|
// Iterate models
|
||||||
for (std::size_t meshIndex = 0;
|
for (std::size_t meshIndex = 0;
|
||||||
meshIndex < model.meshes.size(); meshIndex++) {
|
meshIndex < parser.getMeshCount(); meshIndex++) {
|
||||||
// Iterate primitives
|
// Iterate primitives
|
||||||
for (std::size_t primitiveIndex = 0; primitiveIndex < model
|
for (std::size_t primitiveIndex = 0; primitiveIndex < parser.getPrimitiveCount(meshIndex); primitiveIndex++) {
|
||||||
.meshes[meshIndex].primitives.size(); primitiveIndex++) {
|
|
||||||
|
|
||||||
const auto positionAccessorId = model.meshes[meshIndex]
|
const auto positionAccessorId = model.meshes[meshIndex]
|
||||||
.primitives[primitiveIndex].attributes["POSITION"];
|
.primitives[primitiveIndex].attributes["POSITION"];
|
||||||
const auto indicesAccessorId = model.meshes[meshIndex]
|
|
||||||
.primitives[primitiveIndex].indices;
|
|
||||||
|
|
||||||
// Creates counts for preallocation
|
// Creates counts for preallocation
|
||||||
std::size_t vertexCount = model.accessors[positionAccessorId].count;
|
std::size_t vertexCount = model.accessors[positionAccessorId].count;
|
||||||
@ -113,34 +109,22 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
|
|||||||
auto* vertexBuffer = new video::S3DVertex[vertexCount]();
|
auto* vertexBuffer = new video::S3DVertex[vertexCount]();
|
||||||
// This is used to copy data into the vertexBuffer
|
// This is used to copy data into the vertexBuffer
|
||||||
Span<video::S3DVertex> verticesBuffer{vertexBuffer,vertexCount};
|
Span<video::S3DVertex> verticesBuffer{vertexBuffer,vertexCount};
|
||||||
// Create dynamic indices buffer so it's easier to work with.
|
auto indices = parser.getIndices(meshIndex, primitiveIndex);
|
||||||
// Preallocate needed resources to boost game startup speed
|
|
||||||
std::vector<u16> indicesBuffer(model.accessors[
|
|
||||||
indicesAccessorId].count);
|
|
||||||
|
|
||||||
ModelParser parser(std::move(model));
|
|
||||||
|
|
||||||
parser.getIndices(indicesAccessorId, indicesBuffer);
|
|
||||||
parser.getVertices(positionAccessorId,
|
parser.getVertices(positionAccessorId,
|
||||||
verticesBuffer,
|
verticesBuffer,
|
||||||
meshIndex,
|
meshIndex,
|
||||||
primitiveIndex);
|
primitiveIndex);
|
||||||
|
|
||||||
std::reverse(indicesBuffer.begin(),indicesBuffer.end());
|
SMeshBuffer* meshbuf(new SMeshBuffer {});
|
||||||
|
meshbuf->append(vertexBuffer, vertexCount,
|
||||||
// Create the mesh buffer
|
indices.data(), indices.size());
|
||||||
SMeshBuffer* meshbuf { new SMeshBuffer {} };
|
baseMesh->addMeshBuffer(meshbuf);
|
||||||
meshbuf->append(vertexBuffer, vertexCount, indicesBuffer.data(),
|
|
||||||
indicesBuffer.size());
|
|
||||||
|
|
||||||
mesh->addMeshBuffer(meshbuf);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the mesh animations
|
// Create the mesh animations
|
||||||
SAnimatedMesh* animatedMesh { new SAnimatedMesh {} };
|
SAnimatedMesh* animatedMesh { new SAnimatedMesh {} };
|
||||||
animatedMesh->addMesh(mesh);
|
animatedMesh->addMesh(baseMesh);
|
||||||
|
|
||||||
return animatedMesh;
|
return animatedMesh;
|
||||||
}
|
}
|
||||||
@ -157,21 +141,22 @@ CGLTFMeshFileLoader::ModelParser::ModelParser(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGLTFMeshFileLoader::ModelParser::getIndices(
|
std::vector<u16> CGLTFMeshFileLoader::ModelParser::getIndices(
|
||||||
const std::size_t accessorId,
|
std::size_t meshIdx,
|
||||||
std::vector<u16>& outIndices) const
|
std::size_t primitiveIdx) const
|
||||||
{
|
{
|
||||||
const auto& view = m_model.bufferViews[
|
auto accessorIdx = getIndicesAccessorIdx(meshIdx, primitiveIdx);
|
||||||
m_model.accessors[accessorId].bufferView];
|
auto buf = getBuffer(meshIdx, primitiveIdx, accessorIdx);
|
||||||
const auto& modelIndices = m_model.buffers[view.buffer];
|
|
||||||
|
|
||||||
auto buffOffset = BufferOffset(modelIndices.data, view.byteOffset);
|
std::vector<u16> indices{};
|
||||||
auto count = m_model.accessors[accessorId].count;
|
std::size_t count = getElemCount(accessorIdx);
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
for (std::size_t i = 0; i < count; i++) {
|
std::size_t elemIdx = count - i - 1;
|
||||||
outIndices[i] = readPrimitive<u16>(BufferOffset(
|
indices.push_back(readPrimitive<u16>(
|
||||||
buffOffset, i * sizeof(u16)));
|
BufferOffset(buf, elemIdx * sizeof(u16))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns a tuple of the current counts (current_vertex_index,
|
//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 <typename T>
|
template <typename T>
|
||||||
T CGLTFMeshFileLoader::ModelParser::readPrimitive(
|
T CGLTFMeshFileLoader::ModelParser::readPrimitive(
|
||||||
const BufferOffset& readFrom)
|
const BufferOffset& readFrom)
|
||||||
@ -262,7 +259,7 @@ void CGLTFMeshFileLoader::ModelParser::copyNormals(
|
|||||||
const auto count = m_model.accessors[accessorId].count;
|
const auto count = m_model.accessors[accessorId].count;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < count; i++) {
|
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 ));
|
view.byteOffset + 3 * sizeof(float) * i ));
|
||||||
vertices.buffer[i].Normal = n;
|
vertices.buffer[i].Normal = n;
|
||||||
}
|
}
|
||||||
@ -293,6 +290,31 @@ float CGLTFMeshFileLoader::ModelParser::getScale() const
|
|||||||
return 1.0f;
|
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,
|
bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file,
|
||||||
tinygltf::Model& model)
|
tinygltf::Model& model)
|
||||||
{
|
{
|
||||||
|
@ -60,14 +60,21 @@ private:
|
|||||||
|
|
||||||
ModelParser(const tinygltf::Model&& model);
|
ModelParser(const tinygltf::Model&& model);
|
||||||
|
|
||||||
void getIndices(const std::size_t accessorId,
|
/* Gets indices for the given mesh/primitive.
|
||||||
std::vector<u16>& outIndices) const;
|
*
|
||||||
|
* Values are return in Irrlicht winding order.
|
||||||
|
*/
|
||||||
|
std::vector<u16> getIndices(std::size_t meshIdx,
|
||||||
|
std::size_t primitiveIdx) const;
|
||||||
|
|
||||||
void getVertices(const std::size_t accessorId,
|
void getVertices(const std::size_t accessorId,
|
||||||
Span<video::S3DVertex>& outVertices,
|
Span<video::S3DVertex>& outVertices,
|
||||||
std::size_t meshIndex,
|
std::size_t meshIndex,
|
||||||
std::size_t primitiveIndex) const;
|
std::size_t primitiveIndex) const;
|
||||||
|
|
||||||
|
std::size_t getMeshCount() const;
|
||||||
|
std::size_t getPrimitiveCount(std::size_t meshIdx) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tinygltf::Model m_model;
|
tinygltf::Model m_model;
|
||||||
|
|
||||||
@ -91,6 +98,15 @@ private:
|
|||||||
const std::size_t accessorId) const;
|
const std::size_t accessorId) const;
|
||||||
|
|
||||||
float getScale() 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,
|
static bool tryParseGLTF(io::IReadFile* file,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user