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.cpp78
1 files changed, 64 insertions, 14 deletions
diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp
index bf64740..684fa7f 100644
--- a/src/gltf_loader.cpp
+++ b/src/gltf_loader.cpp
@@ -1,4 +1,5 @@
#include "gltf_loader.h"
+#include "render_assets.h"
#include "spdlog/spdlog.h"
#include <cstdint>
@@ -75,15 +76,26 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
model.scenes.size(),
model.lights.size());
+
for (const auto &mesh : model.meshes) {
- iris::Mesh iris_mesh {
- .name = mesh.name,
- .vertices = {},
- .normals = {},
- .texcoords = {},
- .indices = {},
- };
+ auto mesh_primitive_counter = 0u;
+ const std::string mesh_name = mesh.name == "" ? "mesh" : mesh.name;
+
+ // TODO: A Mesh in glTF can have multiple primitives, each with its own set of attributes
+ // But our current abstract doesn't support multiple primitives within a mesh, so we load
+ // each primitive as a separate mesh instead. This is a temporary solution and should be fixed.
for (const auto &primitive : mesh.primitives) {
+ std::string name = mesh_name + "_" + std::to_string(mesh_primitive_counter++);
+ spdlog::info("loading mesh primitive: {}", name);
+ iris::Mesh iris_mesh {
+ .name = mesh.name,
+ .vertices = {},
+ .normals = {},
+ .texcoords = {},
+ .indices = {},
+ .material_index = primitive.material,
+ };
+
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];
@@ -144,15 +156,14 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
return *typed_data;
};
- // 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);
+ // TODO: support other types. Currently only float3 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
iris_mesh.p_min = glm::vec3(accessor.minValues[0], accessor.minValues[1], accessor.minValues[2]);
iris_mesh.p_max = glm::vec3(accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2]);
for (size_t i = 0; i < accessor.count; i++) {
@@ -160,26 +171,65 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
}
} else if (attrib_name == "NORMAL") {
spdlog::info("loading NORMAL, count {}", 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("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
for (size_t i = 0; i < accessor.count; i++) {
iris_mesh.normals.push_back(extract_data.operator()<glm::vec3>());
}
} else if (attrib_name == "TEXCOORD_0") {
spdlog::info("loading TEXCOORD_0, count {}", accessor.count);
+ // TODO: support other types. Currently only float2 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC2 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
for (size_t i = 0; i < accessor.count; i++) {
iris_mesh.texcoords.push_back(extract_data.operator()<glm::vec2>());
}
+ } else if (attrib_name == "TANGENT") {
+ spdlog::info("loading TANGENT, count {}", accessor.count);
+ // TODO: support other types. Currently only float4 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC4 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
+ for (size_t i = 0; i < accessor.count; i++) {
+ iris_mesh.tangents.push_back(extract_data.operator()<glm::vec4>());
+ }
} else {
spdlog::warn("Unsupported attribute: {}", attrib_name);
}
}
+ break;
}
// TODO add support for other modes
default:
spdlog::error("Unsupported primitive mode: {}", primitive.mode);
return false;
}
+ scene.meshes.push_back(iris_mesh);
}
- scene.meshes.push_back(iris_mesh);
+ }
+
+ for (const tinygltf::Material &material : model.materials) {
+ const std::string material_name = material.name == "" ? "material" : material.name;
+ const auto &pbr = material.pbrMetallicRoughness;
+ iris::Material iris_material {
+ .name = material_name,
+ .base_color = glm::vec4(
+ pbr.baseColorFactor[0],
+ pbr.baseColorFactor[1],
+ pbr.baseColorFactor[2],
+ pbr.baseColorFactor[3]),
+ .metallic = float(pbr.metallicFactor),
+ .roughness = float(pbr.roughnessFactor),
+ };
+
+ // TODO: load texture information, skip for now
+ spdlog::info("Material: {}", material_name);
}
// TODO load materials and textures