1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include "gltf_loader.h"
#include "spdlog/spdlog.h"
enum class SceneFileType {
GLTF,
GLB,
UNKNOWN,
};
bool load_gltf(const std::string_view path, iris::Scene &scene) {
tinygltf::Model model;
tinygltf::TinyGLTF loader;
std::string error;
std::string warning;
SceneFileType file_type = [&path] {
if (path.find_last_of(".") != std::string::npos) {
std::string_view extension = path.substr(path.find_last_of(".") + 1);
if (extension == "glb") {
return SceneFileType::GLB;
} else if (extension == "gltf") {
return SceneFileType::GLTF;
}
}
return SceneFileType::UNKNOWN;
}();
switch (file_type) {
case SceneFileType::GLTF:
if (!loader.LoadASCIIFromFile(&model, &error, &warning, path.data())) {
spdlog::error("Failed to load glTF file: {}", error);
return false;
}
break;
case SceneFileType::GLB:
if (!loader.LoadBinaryFromFile(&model, &error, &warning, path.data())) {
spdlog::error("Failed to load glTF file: {}", error);
return false;
}
break;
case SceneFileType::UNKNOWN:
spdlog::error("Unknown file type: {}", path);
return false;
}
spdlog::info("loaded glTF file {} has:\n"
"{} accessors\n"
"{} animations\n"
"{} buffers\n"
"{} bufferViews\n"
"{} materials\n"
"{} meshes\n"
"{} nodes\n"
"{} textures\n"
"{} images\n"
"{} skins\n"
"{} samplers\n"
"{} cameras\n"
"{} scenes\n"
"{} lights",
path,
model.accessors.size(),
model.animations.size(),
model.buffers.size(),
model.bufferViews.size(),
model.materials.size(),
model.meshes.size(),
model.nodes.size(),
model.textures.size(),
model.images.size(),
model.skins.size(),
model.samplers.size(),
model.cameras.size(),
model.scenes.size(),
model.lights.size());
for (const auto &mesh : model.meshes) {
iris::Mesh<float> iris_mesh;
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);
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);
}
scene.meshes.push_back(iris_mesh);
}
return true;
}
|