utility 2026.2.0
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
87
88 std::string Model::getMaterialName() const
89 {
90 return "default_material"; // Placeholder: Replace with actual material name retrieval logic if available
91 }
92
94 // Protected methods //
96
97 void Model::loadOBJ(std::shared_ptr<utility::File> modelAsset)
98 {
99 std::vector<VertexF> vertices;
100 std::vector<uint32_t> indices;
101
102 // Bounding box calculation
103 float minX = std::numeric_limits<float>::max();
104 float minY = std::numeric_limits<float>::max();
105 float minZ = std::numeric_limits<float>::max();
106 float maxX = std::numeric_limits<float>::lowest();
107 float maxY = std::numeric_limits<float>::lowest();
108 float maxZ = std::numeric_limits<float>::lowest();
109
110 tinyobj::attrib_t attrib;
111 std::vector<tinyobj::shape_t> shapes;
112 std::vector<tinyobj::material_t> materials;
113 std::string warn;
114 std::string err;
115 std::istringstream input(modelAsset->content());
116
117 bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
118 &input, nullptr, true);
119
120 if (!ret) {
121 throw std::runtime_error("Failed to load/parse .obj. " + err);
122 }
123 for (const auto &shape: shapes) {
124 for (const auto &index: shape.mesh.indices) {
125 if (index.vertex_index < 0) {
126 continue;
127 }
128
129 const size_t vertexBase =
130 static_cast<size_t>(index.vertex_index) * 3;
131 if (vertexBase + 2 >= attrib.vertices.size()) {
132 continue;
133 }
134
135 // Vertices are kept in local (object) space: the world
136 // transform is supplied per instance through the model matrix
137 // (see utility::graphic::poseToMatrix).
140 attrib.vertices[vertexBase + 0],
141 attrib.vertices[vertexBase + 1],
142 attrib.vertices[vertexBase + 2]));
143
144 if (index.texcoord_index >= 0) {
145 const size_t texcoordBase =
146 static_cast<size_t>(index.texcoord_index) * 2;
147 if (texcoordBase + 1 < attrib.texcoords.size()) {
148 vertex.setTextureCoordinates(utility::math::Vector2F(
149 { attrib.texcoords[texcoordBase + 0],
150 attrib.texcoords[texcoordBase + 1] }));
151 }
152 }
153
154 if (index.normal_index >= 0) {
155 const size_t normalBase =
156 static_cast<size_t>(index.normal_index) * 3;
157 if (normalBase + 2 < attrib.normals.size()) {
158 vertex.setNormal(utility::math::Vector3F(
159 { attrib.normals[normalBase + 0],
160 attrib.normals[normalBase + 1],
161 attrib.normals[normalBase + 2] }));
162 }
163 }
164
165 vertex.setColor(
166 utility::graphic::Color32Bit(255, 255, 255, 255));
167
168 if (vertices.size() >= static_cast<size_t>(
169 std::numeric_limits<uint32_t>::max())) {
170 throw std::runtime_error(
171 "Too many vertices for uint32_t indices");
172 }
173
174 minX = std::min(minX, attrib.vertices[vertexBase + 0]);
175 minY = std::min(minY, attrib.vertices[vertexBase + 1]);
176 minZ = std::min(minZ, attrib.vertices[vertexBase + 2]);
177 maxX = std::max(maxX, attrib.vertices[vertexBase + 0]);
178 maxY = std::max(maxY, attrib.vertices[vertexBase + 1]);
179 maxZ = std::max(maxZ, attrib.vertices[vertexBase + 2]);
180
181 const uint32_t newIndex =
182 static_cast<uint32_t>(vertices.size());
183 vertices.push_back(vertex);
184 indices.push_back(newIndex);
185 }
186 }
187
188 _meshes.clear();
189 if (!vertices.empty() && !indices.empty()) {
190 _meshes.push_back(std::make_shared<Mesh>(vertices, indices));
191 }
192 _boundingBox = SizeF(maxX - minX, maxY - minY, maxZ - minZ);
193 }
194} // 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:158
void loadOBJ(std::shared_ptr< utility::File > modelAsset)
Loads a model from a given File containing the model data.
Definition model.cpp:97
utility::graphic::SizeF computeBoundingSize(void)
Computes the bounding size of the model.
Definition model.cpp:73
std::string getMaterialName() const override
Get the material name.
Definition model.cpp:88
RenderableType getRenderableType() const override
Get the Renderable Type object.
Definition model.cpp:83
uint32_t _materialID
The material associated with the model.
Definition model.hpp:160
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
ModelType _type
The type of the model (e.g., OBJ, FBX, GLTF)
Definition model.hpp:156
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