summaryrefslogtreecommitdiff
path: root/src/gltf_loader.cpp
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2024-10-04 22:43:11 -0700
committerChuyan Zhang <me@zcy.moe>2024-10-04 22:43:11 -0700
commit1866dd531dffc4084dfaf261591bc7ac2a376d67 (patch)
tree55e6cbe7b54fc24fb80463f337a86089ef8b9bc3 /src/gltf_loader.cpp
parentd116dfacb8dc50ad9fb98d67d084d901ae95e456 (diff)
downloadiris-1866dd531dffc4084dfaf261591bc7ac2a376d67.tar.gz
iris-1866dd531dffc4084dfaf261591bc7ac2a376d67.zip
add basic gltf loader
Diffstat (limited to 'src/gltf_loader.cpp')
-rw-r--r--src/gltf_loader.cpp67
1 files changed, 49 insertions, 18 deletions
diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp
index 142b69f..bf64740 100644
--- a/src/gltf_loader.cpp
+++ b/src/gltf_loader.cpp
@@ -1,6 +1,6 @@
#include "gltf_loader.h"
#include "spdlog/spdlog.h"
-#include <concepts>
+#include <cstdint>
enum class SceneFileType {
GLTF,
@@ -79,6 +79,8 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
iris::Mesh iris_mesh {
.name = mesh.name,
.vertices = {},
+ .normals = {},
+ .texcoords = {},
.indices = {},
};
for (const auto &primitive : mesh.primitives) {
@@ -87,7 +89,7 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
const auto &index_buffer = model.buffers[index_buffer_view.buffer];
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> {
+ auto extract = [&index_data_ptr]<typename T>() -> T {
const T *index_data = reinterpret_cast<const T *>(index_data_ptr);
index_data_ptr += sizeof(T);
return *index_data;
@@ -95,32 +97,32 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
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>());
+ iris_mesh.indices.push_back(extract.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>());
+ iris_mesh.indices.push_back(extract.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>());
+ iris_mesh.indices.push_back(extract.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>());
+ iris_mesh.indices.push_back(extract.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>());
+ iris_mesh.indices.push_back(extract.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>());
+ iris_mesh.indices.push_back(extract.operator()<uint32_t>());
}
break;
default:
@@ -135,7 +137,12 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
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);
+ const uint8_t *data = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
+ auto extract_data = [&data]<typename T>() -> T {
+ const T *typed_data = reinterpret_cast<const T *>(data);
+ data += sizeof(T);
+ return *typed_data;
+ };
// TODO: support other types. Currently only float3 is supported
if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
@@ -146,24 +153,20 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
// spdlog::info("attribute: {}, count: {}", attrib_name, accessor.count);
if (attrib_name == "POSITION") {
spdlog::info("loading POSITION, count {}", accessor.count);
+ 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++) {
- 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]);
+ iris_mesh.vertices.push_back(extract_data.operator()<glm::vec3>());
}
} 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]);
+ iris_mesh.normals.push_back(extract_data.operator()<glm::vec3>());
}
- // 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]);
+ iris_mesh.texcoords.push_back(extract_data.operator()<glm::vec2>());
}
} else {
spdlog::warn("Unsupported attribute: {}", attrib_name);
@@ -179,5 +182,33 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
scene.meshes.push_back(iris_mesh);
}
+ // TODO load materials and textures
+
+ for (const tinygltf::Camera &camera : model.cameras) {
+ iris::Camera iris_camera {
+ .position = glm::vec3(0.0f),
+ .direction = glm::vec3(0.0f),
+ .up = glm::vec3(0.0f, 1.0f, 0.0f),
+ };
+ spdlog::info("Camera: {}, type: {}", camera.name, camera.type);
+ if (camera.type == "perspective") {
+ const auto &perspective = camera.perspective;
+ iris_camera.intrinsic_tag = iris::Camera::Tag::Perspective;
+ iris_camera.intrinsic.perspective.fovx = 2 * glm::atan(glm::tan(perspective.yfov / 2) * perspective.aspectRatio);
+ iris_camera.intrinsic.perspective.fovy = perspective.yfov;
+ iris_camera.intrinsic.perspective.aspect = perspective.aspectRatio;
+ iris_camera.intrinsic.perspective.znear = perspective.znear;
+ iris_camera.intrinsic.perspective.zfar = perspective.zfar;
+ } else {
+ const auto &orthographic = camera.orthographic;
+ iris_camera.intrinsic_tag = iris::Camera::Tag::Orthographic;
+ iris_camera.intrinsic.orthographic.xmag = orthographic.xmag;
+ iris_camera.intrinsic.orthographic.ymag = orthographic.ymag;
+ iris_camera.intrinsic.orthographic.znear = orthographic.znear;
+ iris_camera.intrinsic.orthographic.zfar = orthographic.zfar;
+ }
+ scene.camera = iris_camera;
+ }
+
return true;
} \ No newline at end of file