Visual Computing Library  devel
Loading...
Searching...
No Matches
load.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_IO_MESH_GLTF_LOAD_H
24#define VCL_IO_MESH_GLTF_LOAD_H
25
26#include <vclib/io/file_info.h>
27#include <vclib/io/mesh/settings.h>
28
29#include "detail/info.h"
30#include "detail/load_mesh.h"
31
32namespace vcl {
33
34namespace detail {
35
36template<Matrix44Concept MatrixType, LoggerConcept LogType>
37void loadGltfMeshesWhileTraversingNodes(
38 const tinygltf::Model& model,
39 auto& currentMeshIt,
40 auto& currentInfoIt,
41 MatrixType currentMatrix,
42 uint currentNode,
43 const LoadSettings& settings,
44 LogType& log)
45{
46 currentMatrix =
47 currentMatrix * gltfCurrentNodeMatrix<MatrixType>(model, currentNode);
48
49 if (model.nodes[currentNode].mesh >= 0) {
50 int meshid = model.nodes[currentNode].mesh;
51 gltfLoadMesh(
52 *currentMeshIt,
53 *currentInfoIt,
54 model.meshes[meshid],
55 model,
56 currentMatrix,
57 settings,
58 log);
59
60 ++currentMeshIt;
61 ++currentInfoIt;
62 }
63 // for each child
64 for (int c : model.nodes[currentNode].children) {
65 if (c >= 0) { // if it is valid
66 // visit child
67 loadGltfMeshesWhileTraversingNodes(
68 model,
69 currentMeshIt,
70 currentInfoIt,
71 currentMatrix,
72 c,
73 settings,
74 log);
75 }
76 }
77}
78
79template<MeshConcept MeshType, LoggerConcept LogType>
80void loadGltf(
81 tinygltf::Model& model,
82 std::vector<MeshType>& meshes,
83 std::vector<MeshInfo>& infos,
84 const LoadSettings& settings = LoadSettings(),
85 LogType& log = nullLogger)
86{
87 using ScalarType = MeshType::ScalarType;
88
89 using Matrix44m = std::conditional_t<
90 HasTransformMatrix<MeshType>,
91 typename MeshType::TransformMatrixType,
92 Matrix44<ScalarType>>;
93
94 uint nMeshes = gltfNumberMeshes(model);
95
96 Matrix44m identityMatrix = Matrix44m::Identity();
97
98 meshes.resize(nMeshes);
99 infos.resize(nMeshes);
100
101 log.startProgress("Reading meshes", nMeshes);
102
103 auto mit = meshes.begin();
104 auto iit = infos.begin();
105
106 for (unsigned int s = 0; s < model.scenes.size(); ++s) {
107 const tinygltf::Scene& scene = model.scenes[s];
108 for (unsigned int n = 0; n < scene.nodes.size(); ++n) {
109 loadGltfMeshesWhileTraversingNodes(
110 model, mit, iit, identityMatrix, scene.nodes[n], settings, log);
111
112 log.progress(s * scene.nodes.size() + n);
113 }
114 }
115
116 log.endProgress();
117}
118
119} // namespace detail
120
121template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
122void loadGltf(
123 std::vector<MeshType>& m,
124 const std::string& filename,
125 std::vector<MeshInfo>& loadedInfo,
126 const LoadSettings& settings = LoadSettings(),
127 LogType& log = nullLogger)
128{
129 tinygltf::TinyGLTF loader;
130 tinygltf::Model model;
131
132 std::string err;
133 std::string warn;
134
135 // Determine the file format from the filename extension
136 std::string ext = toLower(FileInfo::extension(filename));
137
138 bool ret = false;
139
140 if (ext == ".gltf") {
141 ret = loader.LoadASCIIFromFile(&model, &err, &warn, filename);
142 }
143 else if (ext == ".glb") {
144 ret = loader.LoadBinaryFromFile(&model, &err, &warn, filename);
145 }
146 else {
147 throw UnknownFileFormatException(ext);
148 }
149
150 if (!ret) {
151 throw CannotOpenFileException(
152 "Failed to load glTF file: " + filename + "\n" + err);
153 }
154
155 if (!warn.empty()) {
156 log.log(
157 "Warnings while loading glTF file: " + warn,
158 LogType::LogLevel::WARNING_LOG);
159 }
160
161 detail::loadGltf(model, m, loadedInfo, settings, log);
162}
163
164template<MeshConcept MeshType, LoggerConcept LogType = NullLogger>
165void loadGltf(
166 MeshType& m,
167 const std::string& filename,
168 MeshInfo& loadedInfo,
169 const LoadSettings& settings = LoadSettings(),
170 LogType& log = nullLogger)
171{
172 std::vector<MeshType> meshes;
173 std::vector<MeshInfo> infos;
174 loadGltf(meshes, filename, infos, settings, log);
175
176 m = std::move(meshes.front());
177 loadedInfo = std::move(infos.front());
178 for (std::size_t i = 1; i < meshes.size(); ++i) {
179 m.append(std::move(meshes[i]));
180 // todo manage infos
181 }
182}
183
184} // namespace vcl
185
186#endif // VCL_IO_MESH_GLTF_LOAD_H
static std::string extension(const std::string &filename)
Get the extension of a file.
Definition file_info.h:260
NullLogger nullLogger
The nullLogger object is an object of type NullLogger that is used as default argument in the functio...
Definition null_logger.h:123