utility 2026.1.9
A comprehensive C++ utilities library tailored for the development of modern desktop and extended reality (XR) applications.
Loading...
Searching...
No Matches
model.cpp
1/*
2** ETIB PROJECT, 2026
3** xider
4** File description:
5** model
6*/
7
8#include <utility/graphic/model.hpp>
9
10namespace utility::graphic
11{
12 Model::Model(std::shared_ptr<utility::File> modelAsset, const PoseF &pose,
13 uint32_t materialID)
14 : Renderable(pose, Color32Bit())
15 , _materialID(materialID)
16 {
17 std::string extension =
18 modelAsset->path().substr(modelAsset->path().find_last_of(".") + 1);
19
20 if (extension == "obj") {
21 loadOBJ(modelAsset);
22 _type = ModelType::OBJ;
23 } else if (extension == "fbx") {
24 getLogger().warning()
25 << "FBX loading not implemented yet. Skipping model loading.";
26 // loadFBX(modelAsset); // Not implemented yet
27 _type = ModelType::FBX;
28 } else if (extension == "gltf" || extension == "glb") {
29 getLogger().warning()
30 << "GLTF loading not implemented yet. Skipping model loading.";
31 // loadGLTF(modelAsset); // Not implemented yet
32 _type = ModelType::GLTF;
33 } else {
34 throw std::runtime_error("Unsupported model format: " + extension);
35 }
36 }
37
38 Model::Model(std::shared_ptr<utility::File> modelAsset, ModelType modelType,
39 const PoseF &pose, uint32_t materialID)
40 : Renderable(pose, Color32Bit())
41 , _materialID(materialID)
42 {
43 _type = modelType;
44
45 switch (modelType) {
46 case ModelType::OBJ:
47 loadOBJ(modelAsset);
48 break;
49 case ModelType::FBX:
50 getLogger().warning() << "FBX loading not implemented yet. "
51 "Skipping model loading.";
52 // loadFBX(modelAsset); // Not implemented yet
53 break;
54 case ModelType::GLTF:
55 getLogger().warning() << "GLTF loading not implemented yet. "
56 "Skipping model loading.";
57 // loadGLTF(modelAsset); // Not implemented yet
58 break;
59 default:
60 throw std::runtime_error("Unsupported model type");
61 }
62 }
63
65 // Public methods //
67
69 {
70 return _type;
71 }
72
77
78 uint32_t Model::getMaterialID(void) const
79 {
80 return _materialID;
81 }
82
84 // Protected methods //
86
87 void Model::loadOBJ(std::shared_ptr<utility::File> modelAsset)
88 {
89 std::vector<VertexF> vertices;
90 std::vector<uint32_t> indices;
91
92 // Bounding box calculation
93 float minX = std::numeric_limits<float>::max();
94 float minY = std::numeric_limits<float>::max();
95 float minZ = std::numeric_limits<float>::max();
96 float maxX = std::numeric_limits<float>::lowest();
97 float maxY = std::numeric_limits<float>::lowest();
98 float maxZ = std::numeric_limits<float>::lowest();
99
100 tinyobj::attrib_t attrib;
101 std::vector<tinyobj::shape_t> shapes;
102 std::vector<tinyobj::material_t> materials;
103 std::string warn;
104 std::string err;
105 std::istringstream input(modelAsset->content());
106
107 bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
108 &input, nullptr, true);
109
110 if (!ret) {
111 throw std::runtime_error("Failed to load/parse .obj. " + err);
112 }
113 for (const auto &shape: shapes) {
114 for (const auto &index: shape.mesh.indices) {
115 if (index.vertex_index < 0) {
116 continue;
117 }
118
119 const size_t vertexBase =
120 static_cast<size_t>(index.vertex_index) * 3;
121 if (vertexBase + 2 >= attrib.vertices.size()) {
122 continue;
123 }
124
125 // Vertices are kept in local (object) space: the world
126 // transform is supplied per instance through the model matrix
127 // (see utility::graphic::poseToMatrix).
130 attrib.vertices[vertexBase + 0],
131 attrib.vertices[vertexBase + 1],
132 attrib.vertices[vertexBase + 2]));
133
134 if (index.texcoord_index >= 0) {
135 const size_t texcoordBase =
136 static_cast<size_t>(index.texcoord_index) * 2;
137 if (texcoordBase + 1 < attrib.texcoords.size()) {
138 vertex.setTextureCoordinates(utility::math::Vector2F(
139 { attrib.texcoords[texcoordBase + 0],
140 attrib.texcoords[texcoordBase + 1] }));
141 }
142 }
143
144 if (index.normal_index >= 0) {
145 const size_t normalBase =
146 static_cast<size_t>(index.normal_index) * 3;
147 if (normalBase + 2 < attrib.normals.size()) {
148 vertex.setNormal(utility::math::Vector3F(
149 { attrib.normals[normalBase + 0],
150 attrib.normals[normalBase + 1],
151 attrib.normals[normalBase + 2] }));
152 }
153 }
154
155 vertex.setColor(
156 utility::graphic::Color32Bit(255, 255, 255, 255));
157
158 if (vertices.size() >= static_cast<size_t>(
159 std::numeric_limits<uint32_t>::max())) {
160 throw std::runtime_error(
161 "Too many vertices for uint32_t indices");
162 }
163
164 minX = std::min(minX, attrib.vertices[vertexBase + 0]);
165 minY = std::min(minY, attrib.vertices[vertexBase + 1]);
166 minZ = std::min(minZ, attrib.vertices[vertexBase + 2]);
167 maxX = std::max(maxX, attrib.vertices[vertexBase + 0]);
168 maxY = std::max(maxY, attrib.vertices[vertexBase + 1]);
169 maxZ = std::max(maxZ, attrib.vertices[vertexBase + 2]);
170
171 const uint32_t newIndex =
172 static_cast<uint32_t>(vertices.size());
173 vertices.push_back(vertex);
174 indices.push_back(newIndex);
175 }
176 }
177
178 _meshes.clear();
179 if (!vertices.empty() && !indices.empty()) {
180 _meshes.push_back(std::make_shared<Mesh>(vertices, indices));
181 }
182 _boundingBox = SizeF(maxX - minX, maxY - minY, maxZ - minZ);
183 }
184} // namespace utility::graphic
ModelType
The ModelType enum represents the different types of 3D models that can be loaded and rendered in the...
Definition model.hpp:52
utility::graphic::SizeF _boundingBox
The bounding box of the model.
Definition model.hpp:144
void loadOBJ(std::shared_ptr< utility::File > modelAsset)
Loads a model from a given File containing the model data.
Definition model.cpp:87
utility::graphic::SizeF computeBoundingSize(void)
Computes the bounding size of the model.
Definition model.cpp:73
uint32_t _materialID
The material associated with the model.
Definition model.hpp:146
ModelType type() const
Get the type of the model.
Definition model.cpp:68
uint32_t getMaterialID(void) const
Get the material ID associated with the model.
Definition model.cpp:78
Model(std::shared_ptr< utility::File > modelAsset, const PoseF &pose, uint32_t materialID)
Constructs a Model object from a given File containing the model data.
Definition model.cpp:12
ModelType _type
The type of the model (e.g., OBJ, FBX, GLTF)
Definition model.hpp:142
Position in 3D space represented as a vector of three PositionComponentType components (x,...
Definition position.hpp:53
The Renderable class represents an object that can be rendered in the graphics application.
std::vector< std::shared_ptr< Mesh > > _meshes
Meshes associated with this renderable object.
Vertex type containing common mesh attributes.
Definition vertex.hpp:38
void setPosition(const Position< VectorComponent > &position)
Set vertex position.
Definition vertex.hpp:87
LoggerType & getLogger(void)
Get the internal logger.
Definition loggable.hpp:98
3D vector class inheriting from glm::vec3.
Definition vector.hpp:83