Refactor vertex loading

This commit is contained in:
JosiahWI 2023-05-18 07:33:04 -05:00 committed by Josiah VanderZee
parent 0896aae906
commit 53c92b0b1d
2 changed files with 90 additions and 71 deletions

View File

@ -18,7 +18,6 @@
#include <cstring>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
@ -133,8 +132,8 @@ std::vector<u16> 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<u16> indices{};
const auto count = getElemCount(accessorIdx);
@ -151,29 +150,22 @@ std::vector<video::S3DVertex> 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<video::S3DVertex> vertices{};
vertices.resize(vertexCount);
const auto positionAccessorIdx = getPositionAccessorIdx(
meshIdx, primitiveIdx);
std::vector<vertex_t> vertices{};
vertices.resize(getElemCount(positionAccessorIdx));
copyPositions(positionAccessorIdx, vertices);
Span<video::S3DVertex> 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<std::size_t>(-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<std::size_t>(-1)) {
copyTCoords(tCoordAccessorIdx, vertices);
}
return vertices;
@ -224,53 +216,45 @@ core::vector3df CGLTFMeshFileLoader::MeshExtractor::readVec3DF(
}
void CGLTFMeshFileLoader::MeshExtractor::copyPositions(
const Span<video::S3DVertex> vertices,
const std::size_t accessorId) const
const std::size_t accessorIdx,
std::vector<vertex_t>& 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<video::S3DVertex> vertices,
const std::size_t accessorId) const
const std::size_t accessorIdx,
std::vector<vertex_t>& 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<video::S3DVertex> vertices,
const std::size_t accessorId) const
const std::size_t accessorIdx,
std::vector<vertex_t>& 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)
{

View File

@ -32,13 +32,6 @@ public:
IAnimatedMesh* createMesh(io::IReadFile* file) override;
private:
template <typename T>
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<u16> getIndices(const std::size_t meshIdx,
const std::size_t primitiveIdx) const;
std::vector<video::S3DVertex> getVertices(std::size_t meshIdx,
std::vector<vertex_t> 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<video::S3DVertex> vertices,
const std::size_t accessorId) const;
void copyPositions(const std::size_t accessorIdx,
std::vector<vertex_t>& vertices) const;
void copyNormals(const Span<video::S3DVertex> vertices,
const std::size_t accessorId) const;
void copyNormals(const std::size_t accessorIdx,
std::vector<vertex_t>& vertices) const;
void copyTCoords(const Span<video::S3DVertex> vertices,
const std::size_t accessorId) const;
void copyTCoords(const std::size_t accessorIdx,
std::vector<vertex_t>& 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);