SpiecsEngine
 
Loading...
Searching...
No Matches
MeshLoader.cpp
Go to the documentation of this file.
1/**
2* @file MeshLoader.cpp.
3* @brief The MeshLoader Class Implementation.
4* @author Spices.
5*/
6
7#include "Pchheader.h"
8#include "MeshLoader.h"
9#include "Resources/Mesh/MeshPack.h"
10#include "Core/Library/FileLibrary.h"
11#include "Core/Library/StringLibrary.h"
12#include "Systems/ResourceSystem.h"
13#include "Resources/Mesh/MeshProcessor.h"
14
15#include "tiny_obj_loader.h"
16
17namespace Spices {
18
19 /**
20 * @brief Const variable: Bin Mesh File Path.
21 */
22 const std::string defaultBinMeshPath = "Meshes/bin/";
23
24 /**
25 * @brief Const variable: OBJ Mesh File Path.
26 */
27 const std::string defaultOBJMeshPath = "Meshes/src/obj/";
28
29 /**
30 * @brief Const variable: FBX Mesh File Path.
31 */
32 const std::string defaultFBXMeshPath = "Meshes/src/fbx/";
33
34 /**
35 * @brief Const variable: Mesh File Confirm header staer.
36 */
37 constexpr char MeshLoaderSignStart[100] = "#ItisSpicesMeshSign: DataStart";
38
39 /**
40 * @brief Const variable: Mesh File Confirm header over.
41 */
42 constexpr char MeshLoaderSignOver[100] = "#ItisSpicesMeshSign: DateOver";
43
44 bool MeshLoader::Load(const std::string& fileName, MeshPack* outMeshPack)
45 {
47
48 if ( LoadFromSASSET(fileName, outMeshPack)) return true;
49 else if ( LoadFromOBJ( fileName, outMeshPack)) return true;
50 else if ( LoadFromFBX( fileName, outMeshPack)) return true;
51 else return false;
52 }
53
54 bool MeshLoader::LoadFromOBJ(const std::string& fileName, MeshPack* outMeshPack)
55 {
57
58 bool isFind = false;
59 std::string filePath;
60 int index = 0;
61 for (auto& it : ResourceSystem::GetSearchFolder())
62 {
63 filePath = it + defaultOBJMeshPath + fileName + ".obj";
64 if (FileLibrary::FileLibrary_Exists(filePath.c_str()))
65 {
66 isFind = true;
67 break;
68 }
69 index++;
70 }
71 if (!isFind) return false;
72
73 if (!FileLibrary::FileLibrary_Exists(filePath.c_str())) {
74 return false;
75 }
76
77 tinyobj::attrib_t attrib;
78 std::vector<tinyobj::shape_t> shapes;
79 std::vector<tinyobj::material_t> materials;
80 std::string warn, err;
81
82 if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filePath.c_str()))
83 {
84 return false;
85 }
86
87 outMeshPack->m_MeshResource.positions.attributes->resize(attrib.vertices.size() / 3);
88 for (uint32_t i = 0; i < attrib.vertices.size() / 3; i++)
89 {
90 (*outMeshPack->m_MeshResource.positions.attributes)[i].x = attrib.vertices[3 * i + 0];
91 (*outMeshPack->m_MeshResource.positions.attributes)[i].y = attrib.vertices[3 * i + 1];
92 (*outMeshPack->m_MeshResource.positions.attributes)[i].z = -attrib.vertices[3 * i + 2];
93 }
94 if (attrib.vertices.empty())
95 {
96 outMeshPack->m_MeshResource.positions.attributes->resize(1);
97
98 (*outMeshPack->m_MeshResource.positions.attributes)[0].x = 0.0f;
99 (*outMeshPack->m_MeshResource.positions.attributes)[0].y = 0.0f;
100 (*outMeshPack->m_MeshResource.positions.attributes)[0].z = 0.0f;
101 }
102
103 outMeshPack->m_MeshResource.normals.attributes->resize(attrib.normals.size() / 3);
104 for (uint32_t i = 0; i < attrib.normals.size() / 3; i++)
105 {
106 (*outMeshPack->m_MeshResource.normals.attributes)[i].x = attrib.normals[3 * i + 0];
107 (*outMeshPack->m_MeshResource.normals.attributes)[i].y = attrib.normals[3 * i + 1];
108 (*outMeshPack->m_MeshResource.normals.attributes)[i].z = -attrib.normals[3 * i + 2];
109 }
110 if (attrib.normals.empty())
111 {
112 outMeshPack->m_MeshResource.normals.attributes->resize(1);
113
114 (*outMeshPack->m_MeshResource.normals.attributes)[0].x = 0.0f;
115 (*outMeshPack->m_MeshResource.normals.attributes)[0].y = 1.0f;
116 (*outMeshPack->m_MeshResource.normals.attributes)[0].z = 0.0f;
117 }
118
119 outMeshPack->m_MeshResource.colors.attributes->resize(attrib.colors.size() / 3);
120 for (uint32_t i = 0; i < attrib.colors.size() / 3; i++)
121 {
122 (*outMeshPack->m_MeshResource.colors.attributes)[i].x = attrib.colors[3 * i + 0];
123 (*outMeshPack->m_MeshResource.colors.attributes)[i].y = attrib.colors[3 * i + 1];
124 (*outMeshPack->m_MeshResource.colors.attributes)[i].z = attrib.colors[3 * i + 2];
125 }
126 if (attrib.colors.empty())
127 {
128 outMeshPack->m_MeshResource.colors.attributes->resize(1);
129
130 (*outMeshPack->m_MeshResource.colors.attributes)[0].x = 1.0f;
131 (*outMeshPack->m_MeshResource.colors.attributes)[0].y = 1.0f;
132 (*outMeshPack->m_MeshResource.colors.attributes)[0].z = 1.0f;
133 }
134
135 outMeshPack->m_MeshResource.texCoords.attributes->resize(attrib.texcoords.size() / 2);
136 for (uint32_t i = 0; i < attrib.texcoords.size() / 2; i++)
137 {
138 (*outMeshPack->m_MeshResource.texCoords.attributes)[i].x = attrib.texcoords[2 * i + 0];
139 (*outMeshPack->m_MeshResource.texCoords.attributes)[i].y = 1.0f - attrib.texcoords[2 * i + 1];
140 }
141 if (attrib.texcoords.empty())
142 {
143 outMeshPack->m_MeshResource.texCoords.attributes->resize(1);
144
145 (*outMeshPack->m_MeshResource.texCoords.attributes)[0].x = 0.0f;
146 (*outMeshPack->m_MeshResource.texCoords.attributes)[0].y = 0.0f;
147 }
148
149 std::unordered_map<glm::uvec4, uint32_t> verticesMap;
150 for (const auto& shape : shapes)
151 {
152 uint32_t start = outMeshPack->m_MeshResource.primitiveVertices.attributes->size();
153 outMeshPack->m_MeshResource.primitiveVertices.attributes->resize(start + shape.mesh.indices.size() / 3);
154
155 for (uint32_t i = 0; i < shape.mesh.indices.size() / 3; i++)
156 {
157 std::array<glm::uvec4, 3> vertexArray{};
158 for (uint32_t j = 0; j < 3; j++)
159 {
160 const auto& ind = shape.mesh.indices[3 * i + j];
161
162 vertexArray[j] = glm::uvec4(
163 ind.vertex_index == -1 ? 0 : ind.vertex_index,
164 ind.normal_index == -1 ? 0 : ind.normal_index,
165 ind.vertex_index == -1 ? 0 : ind.vertex_index,
166 ind.texcoord_index == -1 ? 0 : ind.texcoord_index
167 );
168
169 if (verticesMap.count(vertexArray[j]) == 0)
170 {
171 verticesMap[vertexArray[j]] = static_cast<uint32_t>(outMeshPack->m_MeshResource.vertices.attributes->size());
172 outMeshPack->m_MeshResource.vertices.attributes->push_back(vertexArray[j]);
173 }
174 }
175
176 (*outMeshPack->m_MeshResource.primitiveVertices.attributes)[start + i].x = verticesMap[vertexArray[0]];
177 (*outMeshPack->m_MeshResource.primitiveVertices.attributes)[start + i].y = verticesMap[vertexArray[1]];
178 (*outMeshPack->m_MeshResource.primitiveVertices.attributes)[start + i].z = verticesMap[vertexArray[2]];
179 }
180 }
181
183 WriteSASSET(index, fileName, outMeshPack);
184
185 return true;
186 }
187
188 bool MeshLoader::LoadFromFBX(const std::string& fileName, MeshPack* outMeshPack)
189 {
191
192 bool isFind = false;
193 std::string filePath;
194 for (auto& it : ResourceSystem::GetSearchFolder())
195 {
196 filePath = it + defaultFBXMeshPath + fileName + ".fbx";
197 if (FileLibrary::FileLibrary_Exists(filePath.c_str()))
198 {
199 isFind = true;
200 break;
201 }
202 }
203 if (!isFind) return false;
204
205 // TODO:
206 return false;
207 }
208
209 bool MeshLoader::LoadFromSASSET(const std::string& fileName, const MeshPack* outMeshPack)
210 {
212
213 bool isFind = false;
214 std::string filePath;
215 for (auto& it : ResourceSystem::GetSearchFolder())
216 {
217 filePath = it + defaultBinMeshPath + fileName + ".sasset";
218 if (FileLibrary::FileLibrary_Exists(filePath.c_str()))
219 {
220 isFind = true;
221 break;
222 }
223 }
224 if (!isFind) return false;
225
226 if (!FileLibrary::FileLibrary_Exists(filePath.c_str())) {
227 return false;
228 }
229
230 FileHandle f;
232
233 uint64_t readed = 0;
234
235 char startSign[100];
236 FileLibrary::FileLibrary_Read(&f, sizeof(char) * 100, &startSign, &readed);
237
239 {
241 return false;
242 }
243
244 uint32_t positionsCount = 0;
245 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &positionsCount, &readed);
246 outMeshPack->m_MeshResource.positions.attributes->resize(positionsCount);
247
248 uint32_t normalsCount = 0;
249 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &normalsCount, &readed);
250 outMeshPack->m_MeshResource.normals.attributes->resize(normalsCount);
251
252 uint32_t colorsCount = 0;
253 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &colorsCount, &readed);
254 outMeshPack->m_MeshResource.colors.attributes->resize(colorsCount);
255
256 uint32_t texCoordsCount = 0;
257 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &texCoordsCount, &readed);
258 outMeshPack->m_MeshResource.texCoords.attributes->resize(texCoordsCount);
259
260 uint32_t verticesCount = 0;
261 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &verticesCount, &readed);
262 outMeshPack->m_MeshResource.vertices.attributes->resize(verticesCount);
263
264 uint32_t primitivePointsCount = 0;
265 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &primitivePointsCount, &readed);
266 outMeshPack->m_MeshResource.primitivePoints.attributes->resize(primitivePointsCount);
267
268 uint32_t primitiveVerticesCount = 0;
269 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &primitiveVerticesCount, &readed);
270 outMeshPack->m_MeshResource.primitiveVertices.attributes->resize(primitiveVerticesCount);
271
272 uint32_t primitiveLocationsCount = 0;
273 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &primitiveLocationsCount, &readed);
274 outMeshPack->m_MeshResource.primitiveLocations.attributes->resize(primitiveLocationsCount);
275
276 uint32_t meshletsCount = 0;
277 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &meshletsCount, &readed);
278 outMeshPack->m_MeshResource.meshlets.attributes->resize(meshletsCount);
279
280 uint32_t lodsCount = 0;
281 FileLibrary::FileLibrary_Read(&f, sizeof(uint32_t), &lodsCount, &readed);
282 outMeshPack->m_MeshResource.lods.attributes->resize(lodsCount);
283
284 FileLibrary::FileLibrary_Read(&f, sizeof(glm::vec3) * positionsCount , outMeshPack->m_MeshResource.positions.attributes ->data(), &readed);
285 FileLibrary::FileLibrary_Read(&f, sizeof(glm::vec3) * normalsCount , outMeshPack->m_MeshResource.normals.attributes ->data(), &readed);
286 FileLibrary::FileLibrary_Read(&f, sizeof(glm::vec3) * colorsCount , outMeshPack->m_MeshResource.colors.attributes ->data(), &readed);
287 FileLibrary::FileLibrary_Read(&f, sizeof(glm::vec2) * texCoordsCount , outMeshPack->m_MeshResource.texCoords.attributes ->data(), &readed);
288 FileLibrary::FileLibrary_Read(&f, sizeof(glm::uvec4) * verticesCount , outMeshPack->m_MeshResource.vertices.attributes ->data(), &readed);
289 FileLibrary::FileLibrary_Read(&f, sizeof(glm::uvec3) * primitivePointsCount , outMeshPack->m_MeshResource.primitivePoints.attributes ->data(), &readed);
290 FileLibrary::FileLibrary_Read(&f, sizeof(glm::uvec3) * primitiveVerticesCount , outMeshPack->m_MeshResource.primitiveVertices.attributes ->data(), &readed);
291 FileLibrary::FileLibrary_Read(&f, sizeof(glm::uvec3) * primitiveLocationsCount , outMeshPack->m_MeshResource.primitiveLocations.attributes ->data(), &readed);
292 FileLibrary::FileLibrary_Read(&f, sizeof(Meshlet) * meshletsCount , outMeshPack->m_MeshResource.meshlets.attributes ->data(), &readed);
293 FileLibrary::FileLibrary_Read(&f, sizeof(Lod) * lodsCount , outMeshPack->m_MeshResource.lods.attributes ->data(), &readed);
294
295 char overSign[100];
296 FileLibrary::FileLibrary_Read(&f, sizeof(char) * 100, &overSign, &readed);
297
299 {
301 return false;
302 }
303
305
306 return true;
307 }
308
309 bool MeshLoader::WriteSASSET(int folderIndex, const std::string& fileName, const MeshPack* outMeshPack)
310 {
312
313 std::string filePath = ResourceSystem::GetSearchFolder()[folderIndex] + defaultBinMeshPath + fileName + ".sasset";
314
315 if (FileLibrary::FileLibrary_Exists(filePath.c_str())) {
316 return false;
317 }
318
319 FileHandle f;
321
322 uint64_t written = 0;
323
324 FileLibrary::FileLibrary_Write(&f, sizeof(char) * 100, &MeshLoaderSignStart, &written);
325
326 const uint32_t positionsCount = (uint32_t)outMeshPack->m_MeshResource.positions.attributes->size();
327 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &positionsCount, &written);
328
329 const uint32_t normalsCount = (uint32_t)outMeshPack->m_MeshResource.normals.attributes->size();
330 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &normalsCount, &written);
331
332 const uint32_t colorsCount = (uint32_t)outMeshPack->m_MeshResource.colors.attributes->size();
333 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &colorsCount, &written);
334
335 const uint32_t texCoordsCount = (uint32_t)outMeshPack->m_MeshResource.texCoords.attributes->size();
336 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &texCoordsCount, &written);
337
338 const uint32_t verticesCount = (uint32_t)outMeshPack->m_MeshResource.vertices.attributes->size();
339 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &verticesCount, &written);
340
341 const uint32_t primitivePointsCount = (uint32_t)outMeshPack->m_MeshResource.primitivePoints.attributes->size();
342 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &primitivePointsCount, &written);
343
344 const uint32_t primitiveVerticesCount = (uint32_t)outMeshPack->m_MeshResource.primitiveVertices.attributes->size();
345 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &primitiveVerticesCount, &written);
346
347 const uint32_t primitiveLocationsCount = (uint32_t)outMeshPack->m_MeshResource.primitiveLocations.attributes->size();
348 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &primitiveLocationsCount, &written);
349
350 const uint32_t meshletsCount = (uint32_t)outMeshPack->m_MeshResource.meshlets.attributes->size();
351 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &meshletsCount, &written);
352
353 const uint32_t lodsCount = (uint32_t)outMeshPack->m_MeshResource.lods.attributes->size();
354 FileLibrary::FileLibrary_Write(&f, sizeof(uint32_t), &lodsCount, &written);
355
356 FileLibrary::FileLibrary_Write(&f, sizeof(glm::vec3) * positionsCount , outMeshPack->m_MeshResource.positions.attributes ->data(), &written);
357 FileLibrary::FileLibrary_Write(&f, sizeof(glm::vec3) * normalsCount , outMeshPack->m_MeshResource.normals.attributes ->data(), &written);
358 FileLibrary::FileLibrary_Write(&f, sizeof(glm::vec3) * colorsCount , outMeshPack->m_MeshResource.colors.attributes ->data(), &written);
359 FileLibrary::FileLibrary_Write(&f, sizeof(glm::vec2) * texCoordsCount , outMeshPack->m_MeshResource.texCoords.attributes ->data(), &written);
360 FileLibrary::FileLibrary_Write(&f, sizeof(glm::uvec4) * verticesCount , outMeshPack->m_MeshResource.vertices.attributes ->data(), &written);
361 FileLibrary::FileLibrary_Write(&f, sizeof(glm::uvec3) * primitivePointsCount , outMeshPack->m_MeshResource.primitivePoints.attributes ->data(), &written);
362 FileLibrary::FileLibrary_Write(&f, sizeof(glm::uvec3) * primitiveVerticesCount , outMeshPack->m_MeshResource.primitiveVertices.attributes ->data(), &written);
363 FileLibrary::FileLibrary_Write(&f, sizeof(glm::uvec3) * primitiveLocationsCount , outMeshPack->m_MeshResource.primitiveLocations.attributes ->data(), &written);
364 FileLibrary::FileLibrary_Write(&f, sizeof(Meshlet) * meshletsCount , outMeshPack->m_MeshResource.meshlets.attributes ->data(), &written);
365 FileLibrary::FileLibrary_Write(&f, sizeof(Lod) * lodsCount , outMeshPack->m_MeshResource.lods.attributes ->data(), &written);
366
367 FileLibrary::FileLibrary_Write(&f, sizeof(char) * 100, &MeshLoaderSignOver, &written);
368
370
371 return true;
372 }
373}
#define SPICES_PROFILE_ZONE
static bool FileLibrary_Read(const FileHandle *handle, uint64_t data_size, void *out_data, uint64_t *out_bytes_read)
Read Specific size of data form the current file handle pointer, and move pointer the same size.
static bool FileLibrary_Write(const FileHandle *handle, uint64_t data_size, const void *data, uint64_t *out_bytes_written)
Write given data to the file handle pointer.
static bool FileLibrary_Open(const char *path, FileModes mode, bool binary, FileHandle *out_handle)
Open the file using given string.
static void FileLibrary_Close(FileHandle *handle)
Close the file by the file handle.
static bool FileLibrary_Exists(const char *path)
Determine whether the given string is existing a file.
File Static Function Library.
Definition FileLibrary.h:49
static bool Load(const std::string &fileName, MeshPack *outMeshPack)
Public called API, it is entrance.
static bool WriteSASSET(int folderIndex, const std::string &fileName, const MeshPack *outMeshPack)
Write the read data to the sasset file.
static bool LoadFromSASSET(const std::string &fileName, const MeshPack *outMeshPack)
Load data from a .sasset file.
static bool LoadFromFBX(const std::string &fileName, MeshPack *outMeshPack)
Load data from a .fbx file.
static bool LoadFromOBJ(const std::string &fileName, MeshPack *outMeshPack)
Load data from a .obj file.
MeshLoader Class. This class only defines static function for load data from mesh file.
Definition MeshLoader.h:48
MeshPack Class. This class defines some basic behaves and variables. This class need to be inherited ...
Definition MeshPack.h:156
static void GenerateMeshLodClusterHierarchy(MeshPack *meshPack)
Generate Mesh Lod Resources.
Class for provide functions of process Meshpack.
static bool StringsEqual(const char *str0, const char *str1)
Determine if the strings given are equal. Platform Specific.
String Static Function Library.
const std::string defaultFBXMeshPath
Const variable: FBX Mesh File Path.
constexpr char MeshLoaderSignOver[100]
Const variable: Mesh File Confirm header over.
constexpr char MeshLoaderSignStart[100]
Const variable: Mesh File Confirm header staer.
const std::string defaultBinMeshPath
Const variable: Bin Mesh File Path.
const std::string defaultOBJMeshPath
Const variable: OBJ Mesh File Path.
@ FILE_MODE_READ
model : read
Definition FileLibrary.h:37
@ FILE_MODE_WRITE
model : write
Definition FileLibrary.h:42
This Struct is FILE* handle pointer Wrapper.
Definition FileLibrary.h:15
Lod Data.
Definition MeshPack.h:28
Meshlet Class. This class defines what Meshlet data.
Definition Vertex.h:58