mirror of https://github.com/minetest/minetest.git
Refactor vertex loading
This commit is contained in:
parent
311a176cf0
commit
5aa9f8dcf4
|
@ -18,7 +18,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -133,8 +132,8 @@ std::vector<u16> CGLTFMeshFileLoader::MeshExtractor::getIndices(
|
||||||
const std::size_t meshIdx,
|
const std::size_t meshIdx,
|
||||||
const std::size_t primitiveIdx) const
|
const std::size_t primitiveIdx) const
|
||||||
{
|
{
|
||||||
auto accessorIdx = getIndicesAccessorIdx(meshIdx, primitiveIdx);
|
const auto accessorIdx = getIndicesAccessorIdx(meshIdx, primitiveIdx);
|
||||||
auto buf = getBuffer(meshIdx, primitiveIdx, accessorIdx);
|
const auto& buf = getBuffer(accessorIdx);
|
||||||
|
|
||||||
std::vector<u16> indices{};
|
std::vector<u16> indices{};
|
||||||
const auto count = getElemCount(accessorIdx);
|
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 meshIdx,
|
||||||
const std::size_t primitiveIdx) const
|
const std::size_t primitiveIdx) const
|
||||||
{
|
{
|
||||||
auto positionAccessorIdx = getPositionAccessorIdx(meshIdx, primitiveIdx);
|
const auto positionAccessorIdx = getPositionAccessorIdx(
|
||||||
auto vertexCount = getElemCount(positionAccessorIdx);
|
meshIdx, primitiveIdx);
|
||||||
std::vector<video::S3DVertex> vertices{};
|
std::vector<vertex_t> vertices{};
|
||||||
vertices.resize(vertexCount);
|
vertices.resize(getElemCount(positionAccessorIdx));
|
||||||
|
copyPositions(positionAccessorIdx, vertices);
|
||||||
|
|
||||||
Span<video::S3DVertex> outVertices {vertices.data(), vertexCount};
|
const auto normalAccessorIdx = getNormalAccessorIdx(
|
||||||
|
meshIdx, primitiveIdx);
|
||||||
copyPositions(outVertices, positionAccessorIdx);
|
if (normalAccessorIdx != static_cast<std::size_t>(-1)) {
|
||||||
|
copyNormals(normalAccessorIdx, vertices);
|
||||||
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 tCoordsField = m_model.meshes[meshIdx]
|
const auto tCoordAccessorIdx = getTCoordAccessorIdx(
|
||||||
.primitives[primitiveIdx].attributes.find("TEXCOORD_0");
|
meshIdx, primitiveIdx);
|
||||||
|
if (tCoordAccessorIdx != static_cast<std::size_t>(-1)) {
|
||||||
if (tCoordsField != m_model.meshes[meshIdx]
|
copyTCoords(tCoordAccessorIdx, vertices);
|
||||||
.primitives[primitiveIdx].attributes.end()) {
|
|
||||||
copyTCoords(outVertices, tCoordsField->second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vertices;
|
return vertices;
|
||||||
|
@ -224,53 +216,45 @@ core::vector3df CGLTFMeshFileLoader::MeshExtractor::readVec3DF(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGLTFMeshFileLoader::MeshExtractor::copyPositions(
|
void CGLTFMeshFileLoader::MeshExtractor::copyPositions(
|
||||||
const Span<video::S3DVertex> vertices,
|
const std::size_t accessorIdx,
|
||||||
const std::size_t accessorId) const
|
std::vector<vertex_t>& vertices) const
|
||||||
{
|
{
|
||||||
|
|
||||||
const auto& view = m_model.bufferViews[
|
const auto& buffer = getBuffer(accessorIdx);
|
||||||
m_model.accessors[accessorId].bufferView];
|
const auto count = getElemCount(accessorIdx);
|
||||||
const auto& buffer = m_model.buffers[view.buffer];
|
|
||||||
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 v = readVec3DF(BufferOffset(
|
const auto v = readVec3DF(BufferOffset(buffer,
|
||||||
buffer.data,
|
3 * sizeof(float) * i), getScale());
|
||||||
view.byteOffset + (3 * sizeof(float) * i)),
|
vertices[i].Pos = v;
|
||||||
getScale());
|
|
||||||
vertices.buffer[i].Pos = v;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGLTFMeshFileLoader::MeshExtractor::copyNormals(
|
void CGLTFMeshFileLoader::MeshExtractor::copyNormals(
|
||||||
const Span<video::S3DVertex> vertices,
|
const std::size_t accessorIdx,
|
||||||
const std::size_t accessorId) const
|
std::vector<vertex_t>& vertices) const
|
||||||
{
|
{
|
||||||
const auto& view = m_model.bufferViews[
|
const auto& buffer = getBuffer(accessorIdx);
|
||||||
m_model.accessors[accessorId].bufferView];
|
const auto count = getElemCount(accessorIdx);
|
||||||
const auto& buffer = m_model.buffers[view.buffer];
|
|
||||||
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,
|
||||||
view.byteOffset + 3 * sizeof(float) * i ));
|
3 * sizeof(float) * i));
|
||||||
vertices.buffer[i].Normal = n;
|
vertices[i].Normal = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGLTFMeshFileLoader::MeshExtractor::copyTCoords(
|
void CGLTFMeshFileLoader::MeshExtractor::copyTCoords(
|
||||||
const Span<video::S3DVertex> vertices,
|
const std::size_t accessorIdx,
|
||||||
const std::size_t accessorId) const
|
std::vector<vertex_t>& vertices) const
|
||||||
{
|
{
|
||||||
const auto& view = m_model.bufferViews[
|
const auto& buffer = getBuffer(accessorIdx);
|
||||||
m_model.accessors[accessorId].bufferView];
|
const auto count = getElemCount(accessorIdx);
|
||||||
const auto& buffer = m_model.buffers[view.buffer];
|
|
||||||
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 t = readVec2DF(BufferOffset(
|
const auto t = readVec2DF(BufferOffset(buffer,
|
||||||
buffer.data, view.byteOffset + 2 * sizeof(float) * i));
|
2 * sizeof(float) * i));
|
||||||
vertices.buffer[i].TCoords = t;
|
vertices[i].TCoords = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +274,6 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getElemCount(
|
||||||
}
|
}
|
||||||
|
|
||||||
CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer(
|
CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer(
|
||||||
const std::size_t meshIdx,
|
|
||||||
const std::size_t primitiveIdx,
|
|
||||||
const std::size_t accessorIdx) const
|
const std::size_t accessorIdx) const
|
||||||
{
|
{
|
||||||
const auto& accessor = m_model.accessors[accessorIdx];
|
const auto& accessor = m_model.accessors[accessorIdx];
|
||||||
|
@ -316,6 +298,36 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getPositionAccessorIdx(
|
||||||
.attributes.find("POSITION")->second;
|
.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,
|
bool CGLTFMeshFileLoader::tryParseGLTF(io::IReadFile* file,
|
||||||
tinygltf::Model& model)
|
tinygltf::Model& model)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,13 +32,6 @@ public:
|
||||||
IAnimatedMesh* createMesh(io::IReadFile* file) override;
|
IAnimatedMesh* createMesh(io::IReadFile* file) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
|
||||||
struct Span
|
|
||||||
{
|
|
||||||
T* buffer = nullptr;
|
|
||||||
std::size_t size = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BufferOffset
|
class BufferOffset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -57,6 +50,8 @@ private:
|
||||||
|
|
||||||
class MeshExtractor {
|
class MeshExtractor {
|
||||||
public:
|
public:
|
||||||
|
using vertex_t = video::S3DVertex;
|
||||||
|
|
||||||
MeshExtractor(const tinygltf::Model& model) noexcept;
|
MeshExtractor(const tinygltf::Model& model) noexcept;
|
||||||
|
|
||||||
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,
|
std::vector<u16> getIndices(const std::size_t meshIdx,
|
||||||
const std::size_t primitiveIdx) const;
|
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;
|
const std::size_t primitiveIdx) const;
|
||||||
|
|
||||||
std::size_t getMeshCount() const;
|
std::size_t getMeshCount() const;
|
||||||
|
@ -92,14 +87,14 @@ private:
|
||||||
const BufferOffset& readFrom,
|
const BufferOffset& readFrom,
|
||||||
const float scale = 1.0f);
|
const float scale = 1.0f);
|
||||||
|
|
||||||
void copyPositions(const Span<video::S3DVertex> vertices,
|
void copyPositions(const std::size_t accessorIdx,
|
||||||
const std::size_t accessorId) const;
|
std::vector<vertex_t>& vertices) const;
|
||||||
|
|
||||||
void copyNormals(const Span<video::S3DVertex> vertices,
|
void copyNormals(const std::size_t accessorIdx,
|
||||||
const std::size_t accessorId) const;
|
std::vector<vertex_t>& vertices) const;
|
||||||
|
|
||||||
void copyTCoords(const Span<video::S3DVertex> vertices,
|
void copyTCoords(const std::size_t accessorIdx,
|
||||||
const std::size_t accessorId) const;
|
std::vector<vertex_t>& vertices) const;
|
||||||
|
|
||||||
/* Get the scale factor from the glTF mesh information.
|
/* Get the scale factor from the glTF mesh information.
|
||||||
*
|
*
|
||||||
|
@ -109,15 +104,27 @@ private:
|
||||||
|
|
||||||
std::size_t getElemCount(const std::size_t accessorIdx) const;
|
std::size_t getElemCount(const std::size_t accessorIdx) const;
|
||||||
|
|
||||||
BufferOffset getBuffer(const std::size_t meshIdx,
|
BufferOffset getBuffer(const std::size_t accessorIdx) const;
|
||||||
const std::size_t primitiveIdx,
|
|
||||||
const std::size_t accessorIdx) const;
|
|
||||||
|
|
||||||
std::size_t getIndicesAccessorIdx(const std::size_t meshIdx,
|
std::size_t getIndicesAccessorIdx(const std::size_t meshIdx,
|
||||||
const std::size_t primitiveIdx) const;
|
const std::size_t primitiveIdx) const;
|
||||||
|
|
||||||
std::size_t getPositionAccessorIdx(const std::size_t meshIdx,
|
std::size_t getPositionAccessorIdx(const std::size_t meshIdx,
|
||||||
const std::size_t primitiveIdx) const;
|
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);
|
void loadPrimitives(const MeshExtractor& parser, SMesh* mesh);
|
||||||
|
|
Loading…
Reference in New Issue