Fix indices, inverted models, & multiple models failing to load

Fix embedded textures causing a model not to load

Add todo

Add another todo

Push current (broken) prototyping

Fix missing bracket

Make a single array object work

Convert hard array into dynamic vector

Simplify semantics

Remove "new"

Add blocker for vscode environment changes

Disable non-dynamic prototyping

Add comment

Add more informative debug & disable it

Add additional items to gitignore

Add debug info for scalar value

Output even more debug info

Make textures render correctly

Insert the indices properly

Update .gitignore

Disable y flip

Make a reusable vertex buffer :)

Disallow embedded textures

More disable

Set up implementation for contiguous model

Add a note

More automation & framework

Final framework before stepping into function overhaul

Hold track of current_index

Integrate iterators

More integration

Rename, it's going to need 2 counters

Correctly offset the count to the right

Sync normals with positions

Time to use a tuple

Set up other counters

Do return value

Do input passing

Make (somewhat) working contiguous model

Add getter for translation data

Add debug info for future utilization

Update .gitignore

More debug

Update .gitignore

Update .gitignore

Remove all debug info & clean up

Delete this thing

Automate everything & put it into spec

Spaces into tabs

Remove array include as build test

Fix the gitignore
This commit is contained in:
jordan4ibanez 2023-01-27 20:45:02 -05:00
parent b47858cf80
commit 2d4f1ce35e

View File

@ -10,6 +10,8 @@
#include "SColor.h" #include "SColor.h"
#include "SMesh.h" #include "SMesh.h"
#include "vector3d.h" #include "vector3d.h"
#include <vector>
#include <tuple>
#define TINYGLTF_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION
#include <tiny_gltf.h> #include <tiny_gltf.h>
@ -52,6 +54,13 @@ private:
std::size_t m_offset; std::size_t m_offset;
}; };
// A helper function to disable tinygltf embedded image loading
bool turn_off_textures_hack(tinygltf::Image *a, const int b, std::string *c,
std::string *d, int e, int f, const unsigned char * g,int h, void *user_pointer)
{
return false;
};
namespace irr namespace irr
{ {
@ -61,13 +70,22 @@ namespace scene
static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model) static bool tryParseGLTF(io::IReadFile* file, tinygltf::Model& model)
{ {
tinygltf::TinyGLTF loader {}; tinygltf::TinyGLTF loader {};
// Stop embedded textures from making model fail to load
void *the_void = 0;
loader.SetImageLoader(turn_off_textures_hack, the_void);
std::string err {}; std::string err {};
std::string warn {}; std::string warn {};
auto buf = std::make_unique<char[]>(file->getSize()); auto buf = std::make_unique<char[]>(file->getSize());
file->read(buf.get(), file->getSize()); file->read(buf.get(), file->getSize());
return loader.LoadASCIIFromString(
&model, &err, &warn, buf.get(), file->getSize(), "", 1); if (err != "" || warn != "") {
return false;
}
return loader.LoadASCIIFromString(&model, &err, &warn, buf.get(), file->getSize(), "", 1);
} }
template <class T> template <class T>
@ -84,9 +102,7 @@ static T readPrimitive(const BufferOffset& readFrom)
static core::vector2df readVec2DF(const BufferOffset& readFrom) static core::vector2df readVec2DF(const BufferOffset& readFrom)
{ {
return core::vector2df( return core::vector2df( readPrimitive<float>(readFrom), readPrimitive<float>( BufferOffset( readFrom, sizeof(float) ) ) );
readPrimitive<float>(readFrom),
readPrimitive<float>(BufferOffset(readFrom, sizeof(float))));
} }
@ -101,16 +117,6 @@ static core::vector3df readVec3DF(const BufferOffset& readFrom,
-scale * readPrimitive<float>(BufferOffset(readFrom, 2 * sizeof(float)))); -scale * readPrimitive<float>(BufferOffset(readFrom, 2 * sizeof(float))));
} }
static u16* readIndices(const BufferOffset& readFrom, const std::size_t count)
{
auto* indices = new u16[count]{};
for (std::size_t i = 0; i < count; ++i) {
indices[i] = readPrimitive<u16>(BufferOffset(readFrom, i * sizeof(u16)));
}
return indices;
}
float getScale(const tinygltf::Model& model) float getScale(const tinygltf::Model& model)
{ {
if (model.nodes[0].scale.size() > 0) { if (model.nodes[0].scale.size() > 0) {
@ -119,82 +125,82 @@ float getScale(const tinygltf::Model& model)
return 1.0f; return 1.0f;
} }
static void copyPositions(const tinygltf::Model& model,
const Span<video::S3DVertex> vertices,
const std::size_t accessorId)
static void copyPositions(const tinygltf::Model& model, const Span<video::S3DVertex> vertices, const std::size_t accessorId)
{ {
const auto& view = model.bufferViews[
model.accessors[accessorId].bufferView]; const auto& view = model.bufferViews[ model.accessors[accessorId].bufferView];
const auto& buffer = model.buffers[view.buffer]; const auto& buffer = model.buffers[view.buffer];
for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) { const auto count = model.accessors[accessorId].count;
const auto v = readVec3DF(BufferOffset(
buffer.data, view.byteOffset + 3 * sizeof(float) * i), float scale = getScale(model);
getScale(model));
for (std::size_t i = 0; i < count; i++) {
const auto v = readVec3DF(BufferOffset( buffer.data, view.byteOffset + (3 * sizeof(float) * i)), scale);
vertices.buffer[i].Pos = v; vertices.buffer[i].Pos = v;
} }
} }
static void copyNormals(const tinygltf::Model& model, static void copyNormals(const tinygltf::Model& model, const Span<video::S3DVertex> vertices, const std::size_t accessorId)
const Span<video::S3DVertex> vertices,
const std::size_t accessorId)
{ {
const auto& view = model.bufferViews[ const auto& view = model.bufferViews[model.accessors[accessorId].bufferView];
model.accessors[accessorId].bufferView];
const auto& buffer = model.buffers[view.buffer]; const auto& buffer = model.buffers[view.buffer];
for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) { const auto count = model.accessors[accessorId].count;
const auto n = readVec3DF(BufferOffset(
buffer.data, view.byteOffset + 3 * sizeof(float) * i)); 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; vertices.buffer[i].Normal = n;
} }
} }
static void copyTCoords(const tinygltf::Model& model, static void copyTCoords(const tinygltf::Model& model, const Span<video::S3DVertex> vertices, const std::size_t accessorId)
const Span<video::S3DVertex> vertices,
const std::size_t accessorId)
{ {
const auto& view = model.bufferViews[ const auto& view = model.bufferViews[ model.accessors[accessorId].bufferView ];
model.accessors[accessorId].bufferView];
const auto& buffer = model.buffers[view.buffer]; const auto& buffer = model.buffers[view.buffer];
for (std::size_t i = 0; i < model.accessors[accessorId].count; ++i) { const auto count = model.accessors[accessorId].count;
const auto t = readVec2DF(BufferOffset(
buffer.data, view.byteOffset + 2 * sizeof(float) * i)); 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; vertices.buffer[i].TCoords = t;
} }
} }
static video::S3DVertex* getVertices(const tinygltf::Model& model, static void getIndices(const tinygltf::Model& model, const std::size_t accessorId, std::vector<u16> *indicesBuffer)
const std::size_t accessorId)
{ {
auto* vertexBuffer = new video::S3DVertex[ const auto& view = model.bufferViews[model.accessors[accessorId].bufferView];
model.accessors[accessorId].count]{}; const auto& modelIndices = model.buffers[view.buffer];
Span<video::S3DVertex> vertices{
vertexBuffer, model.accessors[accessorId].count};
copyPositions(model, vertices, accessorId);
const auto normalsField auto bufferobject = BufferOffset(modelIndices.data, view.byteOffset);
= model.meshes[0].primitives[0].attributes.find("NORMAL"); auto count = model.accessors[accessorId].count;
if (normalsField != model.meshes[0].primitives[0].attributes.end()) {
copyNormals(model, vertices, normalsField->second); for (std::size_t i = 0; i < count; i++) {
auto current = readPrimitive<u16>(BufferOffset(bufferobject, i * sizeof(u16)));
// Inverse the order of indices
indicesBuffer->insert(indicesBuffer->begin(), current);
}
} }
const auto tCoordsField // Returns a tuple of the current counts (current_vertex_index, current_normals_index, current_tcoords_index)
= model.meshes[0].primitives[0].attributes.find("TEXCOORD_0"); static void getVertices
if (tCoordsField != model.meshes[0].primitives[0].attributes.end()) { ( const tinygltf::Model& model, const std::size_t accessorId, Span<video::S3DVertex> *verticesBuffer,
copyTCoords(model, vertices, tCoordsField->second); std::size_t mesh_index, std::size_t primitive_index )
}
return vertexBuffer;
}
static u16* getIndices(const tinygltf::Model& model,
const std::size_t accessorId)
{ {
const auto& view = model.bufferViews[ copyPositions(model, *verticesBuffer, accessorId);
model.accessors[accessorId].bufferView];
const auto& indicesBuffer = model.buffers[view.buffer]; const auto normalsField = model.meshes[mesh_index].primitives[primitive_index].attributes.find("NORMAL");
return readIndices(
BufferOffset(indicesBuffer.data, view.byteOffset), if (normalsField != model.meshes[mesh_index].primitives[primitive_index].attributes.end()) {
model.accessors[accessorId].count); copyNormals(model, *verticesBuffer, normalsField->second);
}
const auto tCoordsField = model.meshes[mesh_index].primitives[primitive_index].attributes.find("TEXCOORD_0");
if (tCoordsField != model.meshes[mesh_index].primitives[primitive_index].attributes.end()) {
copyTCoords(model, *verticesBuffer, tCoordsField->second);
}
} }
CGLTFMeshFileLoader::CGLTFMeshFileLoader() CGLTFMeshFileLoader::CGLTFMeshFileLoader()
@ -215,22 +221,41 @@ IAnimatedMesh* CGLTFMeshFileLoader::createMesh(io::IReadFile* file)
return nullptr; return nullptr;
} }
const auto indicesAccessorId = // Create the base mesh
model.meshes[0].primitives[0].indices;
const auto positionAccessorId =
model.meshes[0].primitives[0].attributes["POSITION"];
auto* indices = getIndices(model, indicesAccessorId);
auto* vertices = getVertices(model, positionAccessorId);
SMeshBuffer* meshbuf { new SMeshBuffer {} };
meshbuf->append(vertices, model.accessors[positionAccessorId].count,
indices, model.accessors[indicesAccessorId].count);
SMesh* mesh { new SMesh {} }; SMesh* mesh { new SMesh {} };
// Iterate models
for (std::size_t mesh_index = 0; mesh_index < model.meshes.size(); mesh_index++) {
// Iterate primitives
for (std::size_t primitive_index = 0; primitive_index < model.meshes[mesh_index].primitives.size(); primitive_index++) {
const auto positionAccessorId = model.meshes[mesh_index].primitives[primitive_index].attributes["POSITION"];
const auto indicesAccessorId = model.meshes[mesh_index].primitives[primitive_index].indices;
// Creates counts for preallocation
std::size_t vertices_count = model.accessors[positionAccessorId].count;
// We must count to create containers for the data
// Create new buffer for vertices, positions, and normals. Will loop through this soon
auto* vertexBuffer = new video::S3DVertex[vertices_count]{};
// This is used to copy data into the vertexBuffer
Span<video::S3DVertex> verticesBuffer{ vertexBuffer, vertices_count };
// Create dynamic indices buffer so it's easier to work with
std::vector<u16> indicesBuffer;
getIndices(model, indicesAccessorId, &indicesBuffer);
getVertices(model, positionAccessorId, &verticesBuffer, mesh_index, primitive_index);
// Create the mesh buffer
SMeshBuffer* meshbuf { new SMeshBuffer {} };
meshbuf->append(vertexBuffer, vertices_count, indicesBuffer.data(), indicesBuffer.size());
mesh->addMeshBuffer(meshbuf); mesh->addMeshBuffer(meshbuf);
}
}
// Create the mesh animations
SAnimatedMesh* animatedMesh { new SAnimatedMesh {} }; SAnimatedMesh* animatedMesh { new SAnimatedMesh {} };
animatedMesh->addMesh(mesh); animatedMesh->addMesh(mesh);