summaryrefslogtreecommitdiff
path: root/src/gltf_loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gltf_loader.cpp')
-rw-r--r--src/gltf_loader.cpp105
1 files changed, 96 insertions, 9 deletions
diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp
index 2b3818f..142b69f 100644
--- a/src/gltf_loader.cpp
+++ b/src/gltf_loader.cpp
@@ -1,5 +1,6 @@
#include "gltf_loader.h"
#include "spdlog/spdlog.h"
+#include <concepts>
enum class SceneFileType {
GLTF,
@@ -75,22 +76,108 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
model.lights.size());
for (const auto &mesh : model.meshes) {
- iris::Mesh<float> iris_mesh;
+ iris::Mesh iris_mesh {
+ .name = mesh.name,
+ .vertices = {},
+ .indices = {},
+ };
for (const auto &primitive : mesh.primitives) {
- const auto &position_accessor = model.accessors[primitive.attributes.at("POSITION")];
- const auto &position_buffer_view = model.bufferViews[position_accessor.bufferView];
- const auto &position_buffer = model.buffers[position_buffer_view.buffer];
- const auto &position_data = reinterpret_cast<const float *>(position_buffer.data.data() + position_buffer_view.byteOffset + position_accessor.byteOffset);
-
const auto &index_accessor = model.accessors[primitive.indices];
const auto &index_buffer_view = model.bufferViews[index_accessor.bufferView];
const auto &index_buffer = model.buffers[index_buffer_view.buffer];
- const auto &index_data = reinterpret_cast<const uint32_t *>(index_buffer.data.data() + index_buffer_view.byteOffset + index_accessor.byteOffset);
+ const uint8_t *index_data_ptr = index_buffer.data.data() + index_buffer_view.byteOffset + index_accessor.byteOffset;
+
+ auto extract_index = [&index_data_ptr]<typename T>() -> T requires std::integral<T> {
+ const T *index_data = reinterpret_cast<const T *>(index_data_ptr);
+ index_data_ptr += sizeof(T);
+ return *index_data;
+ };
+ switch (index_accessor.componentType) {
+ case TINYGLTF_COMPONENT_TYPE_BYTE:
+ for (size_t i = 0; i < index_accessor.count; i++) {
+ iris_mesh.indices.push_back(extract_index.operator()<int8_t>());
+ }
+ break;
+ case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
+ for (size_t i = 0; i < index_accessor.count; i++) {
+ iris_mesh.indices.push_back(extract_index.operator()<uint8_t>());
+ }
+ break;
+ case TINYGLTF_COMPONENT_TYPE_SHORT:
+ for (size_t i = 0; i < index_accessor.count; i++) {
+ iris_mesh.indices.push_back(extract_index.operator()<int16_t>());
+ }
+ break;
+ case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
+ for (size_t i = 0; i < index_accessor.count; i++) {
+ iris_mesh.indices.push_back(extract_index.operator()<uint16_t>());
+ }
+ break;
+ case TINYGLTF_COMPONENT_TYPE_INT:
+ for (size_t i = 0; i < index_accessor.count; i++) {
+ iris_mesh.indices.push_back(extract_index.operator()<int32_t>());
+ }
+ break;
+ case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
+ for (size_t i = 0; i < index_accessor.count; i++) {
+ iris_mesh.indices.push_back(extract_index.operator()<uint32_t>());
+ }
+ break;
+ default:
+ spdlog::error("Unsupported index component type: {}", index_accessor.componentType);
+ return false;
+ }
+
+ switch (primitive.mode) {
+ case TINYGLTF_MODE_TRIANGLES: {
+ // All float ?
+ for (const auto &[attrib_name, accessor_index] : primitive.attributes) {
+ const auto &accessor = model.accessors[accessor_index];
+ const auto &buffer_view = model.bufferViews[accessor.bufferView];
+ const auto &buffer = model.buffers[buffer_view.buffer];
+ const float *data = reinterpret_cast<const float *>(buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset);
- iris_mesh.vertices.insert(iris_mesh.vertices.end(), position_data, position_data + position_accessor.count * 3);
- iris_mesh.indices.insert(iris_mesh.indices.end(), index_data, index_data + index_accessor.count);
+ // TODO: support other types. Currently only float3 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Unsupported POSITION type: {}, {}", accessor.type, accessor.componentType);
+ return false;
+ }
+
+ // spdlog::info("attribute: {}, count: {}", attrib_name, accessor.count);
+ if (attrib_name == "POSITION") {
+ spdlog::info("loading POSITION, count {}", accessor.count);
+ for (size_t i = 0; i < accessor.count; i++) {
+ iris_mesh.vertices.push_back(data[i * 3 + 0]);
+ iris_mesh.vertices.push_back(data[i * 3 + 1]);
+ iris_mesh.vertices.push_back(data[i * 3 + 2]);
+ }
+ } else if (attrib_name == "NORMAL") {
+ spdlog::info("loading NORMAL, count {}", accessor.count);
+ for (size_t i = 0; i < accessor.count; i++) {
+ iris_mesh.vertices.push_back(data[i * 3 + 0]);
+ iris_mesh.vertices.push_back(data[i * 3 + 1]);
+ iris_mesh.vertices.push_back(data[i * 3 + 2]);
+ }
+ // TODO reorder normals correctly
+ } else if (attrib_name == "TEXCOORD_0") {
+ spdlog::info("loading TEXCOORD_0, count {}", accessor.count);
+ for (size_t i = 0; i < accessor.count; i++) {
+ iris_mesh.vertices.push_back(data[i * 2 + 0]);
+ iris_mesh.vertices.push_back(data[i * 2 + 1]);
+ }
+ } else {
+ spdlog::warn("Unsupported attribute: {}", attrib_name);
+ }
+ }
+ }
+ // TODO add support for other modes
+ default:
+ spdlog::error("Unsupported primitive mode: {}", primitive.mode);
+ return false;
+ }
}
scene.meshes.push_back(iris_mesh);
}
+
return true;
} \ No newline at end of file