Load data from a .obj file.
55 {
57
58 bool isFind = false;
59 std::string filePath;
60 int index = 0;
61 for (auto& it : ResourceSystem::GetSearchFolder())
62 {
65 {
66 isFind = true;
67 break;
68 }
69 index++;
70 }
71 if (!isFind) return false;
72
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
184
185 return true;
186 }
#define SPICES_PROFILE_ZONE
static bool FileLibrary_Exists(const char *path)
Determine whether the given string is existing a file.
static bool WriteSASSET(int folderIndex, const std::string &fileName, const MeshPack *outMeshPack)
Write the read data to the sasset file.
static void GenerateMeshLodClusterHierarchy(MeshPack *meshPack)
Generate Mesh Lod Resources.
const std::string defaultOBJMeshPath
Const variable: OBJ Mesh File Path.