@@ -141,102 +141,131 @@ Now, let's modify our `loadModel()` function to use tinygltf instead of tinyobjl
141141
142142[,c{pp}]
143143----
144- void loadModel() {
144+ void loadModel()
145+ {
145146 // Use tinygltf to load the model instead of tinyobjloader
146- tinygltf::Model model;
147+ tinygltf::Model model;
147148 tinygltf::TinyGLTF loader;
148- std::string err;
149- std::string warn;
149+ std::string err;
150+ std::string warn;
150151
151- bool ret = loader.LoadASCIIFromFile (&model, &err, &warn, MODEL_PATH);
152+ bool ret = loader.LoadBinaryFromFile (&model, &err, &warn, MODEL_PATH);
152153
153- if (!warn.empty()) {
154+ if (!warn.empty())
155+ {
154156 std::cout << "glTF warning: " << warn << std::endl;
155157 }
156158
157- if (!err.empty()) {
159+ if (!err.empty())
160+ {
158161 std::cout << "glTF error: " << err << std::endl;
159162 }
160163
161- if (!ret) {
164+ if (!ret)
165+ {
162166 throw std::runtime_error("Failed to load glTF model");
163167 }
164168
165- // Process all meshes in the model
166- std::unordered_map<Vertex, uint32_t> uniqueVertices{} ;
169+ vertices.clear();
170+ indices.clear() ;
167171
168- for (const auto& mesh : model.meshes) {
169- for (const auto& primitive : mesh.primitives) {
172+ // Process all meshes in the model
173+ for (const auto &mesh : model.meshes)
174+ {
175+ for (const auto &primitive : mesh.primitives)
176+ {
170177 // Get indices
171- const tinygltf::Accessor& indexAccessor = model.accessors[primitive.indices];
172- const tinygltf::BufferView& indexBufferView = model.bufferViews[indexAccessor.bufferView];
173- const tinygltf::Buffer& indexBuffer = model.buffers[indexBufferView.buffer];
178+ const tinygltf::Accessor & indexAccessor = model.accessors[primitive.indices];
179+ const tinygltf::BufferView & indexBufferView = model.bufferViews[indexAccessor.bufferView];
180+ const tinygltf::Buffer & indexBuffer = model.buffers[indexBufferView.buffer];
174181
175182 // Get vertex positions
176- const tinygltf::Accessor& posAccessor = model.accessors[primitive.attributes.at("POSITION")];
177- const tinygltf::BufferView& posBufferView = model.bufferViews[posAccessor.bufferView];
178- const tinygltf::Buffer& posBuffer = model.buffers[posBufferView.buffer];
183+ const tinygltf::Accessor & posAccessor = model.accessors[primitive.attributes.at("POSITION")];
184+ const tinygltf::BufferView & posBufferView = model.bufferViews[posAccessor.bufferView];
185+ const tinygltf::Buffer & posBuffer = model.buffers[posBufferView.buffer];
179186
180187 // Get texture coordinates if available
181- bool hasTexCoords = primitive.attributes.find("TEXCOORD_0") != primitive.attributes.end();
182- const tinygltf::Accessor* texCoordAccessor = nullptr;
183- const tinygltf::BufferView* texCoordBufferView = nullptr;
184- const tinygltf::Buffer* texCoordBuffer = nullptr;
185-
186- if (hasTexCoords) {
187- texCoordAccessor = &model.accessors[primitive.attributes.at("TEXCOORD_0")];
188+ bool hasTexCoords = primitive.attributes.find("TEXCOORD_0") != primitive.attributes.end();
189+ const tinygltf::Accessor *texCoordAccessor = nullptr;
190+ const tinygltf::BufferView *texCoordBufferView = nullptr;
191+ const tinygltf::Buffer *texCoordBuffer = nullptr;
192+
193+ if (hasTexCoords)
194+ {
195+ texCoordAccessor = &model.accessors[primitive.attributes.at("TEXCOORD_0")];
188196 texCoordBufferView = &model.bufferViews[texCoordAccessor->bufferView];
189- texCoordBuffer = &model.buffers[texCoordBufferView->buffer];
197+ texCoordBuffer = &model.buffers[texCoordBufferView->buffer];
190198 }
191199
192- // Process vertices
193- for (size_t i = 0; i < posAccessor.count; i++) {
200+ uint32_t baseVertex = static_cast<uint32_t>(vertices.size());
201+
202+ for (size_t i = 0; i < posAccessor.count; i++)
203+ {
194204 Vertex vertex{};
195205
196- // Get position
197- const float* pos = reinterpret_cast<const float*>(&posBuffer.data[posBufferView.byteOffset + posAccessor.byteOffset + i * 12]);
198- vertex.pos = {pos[0], pos[1], pos[2]};
206+ const float *pos = reinterpret_cast<const float *>(&posBuffer.data[posBufferView.byteOffset + posAccessor.byteOffset + i * 12]);
207+ // glTF uses a right-handed coordinate system with Y-up
208+ // Vulkan uses a right-handed coordinate system with Y-down
209+ // We need to flip the Y coordinate
210+ vertex.pos = {pos[0], -pos[1], pos[2]};
199211
200- // Get texture coordinates if available
201- if (hasTexCoords) {
202- const float* texCoord = reinterpret_cast<const float*>(&texCoordBuffer->data[texCoordBufferView->byteOffset + texCoordAccessor->byteOffset + i * 8]);
203- vertex.texCoord = {texCoord[0], 1.0f - texCoord[1]};
204- } else {
212+ if (hasTexCoords)
213+ {
214+ const float *texCoord = reinterpret_cast<const float *>(&texCoordBuffer->data[texCoordBufferView->byteOffset + texCoordAccessor->byteOffset + i * 8]);
215+ vertex.texCoord = {texCoord[0], texCoord[1]};
216+ }
217+ else
218+ {
205219 vertex.texCoord = {0.0f, 0.0f};
206220 }
207221
208- // Set default color
209222 vertex.color = {1.0f, 1.0f, 1.0f};
210223
211- // Add vertex if unique
212- if (!uniqueVertices.contains(vertex)) {
213- uniqueVertices[vertex] = static_cast<uint32_t>(vertices.size());
214- vertices.push_back(vertex);
215- }
224+ vertices.push_back(vertex);
225+ }
226+
227+ const unsigned char *indexData = &indexBuffer.data[indexBufferView.byteOffset + indexAccessor.byteOffset];
228+ size_t indexCount = indexAccessor.count;
229+ size_t indexStride = 0;
230+
231+ // Determine index stride based on component type
232+ if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
233+ {
234+ indexStride = sizeof(uint16_t);
235+ }
236+ else if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
237+ {
238+ indexStride = sizeof(uint32_t);
239+ }
240+ else if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
241+ {
242+ indexStride = sizeof(uint8_t);
216243 }
244+ else
245+ {
246+ throw std::runtime_error("Unsupported index component type");
247+ }
248+
249+ indices.reserve(indices.size() + indexCount);
217250
218- // Process indices
219- const unsigned char* indexData = &indexBuffer.data[indexBufferView.byteOffset + indexAccessor.byteOffset];
251+ for (size_t i = 0; i < indexCount; i++)
252+ {
253+ uint32_t index = 0;
220254
221- // Handle different index component types
222- if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
223- const uint16_t* indices16 = reinterpret_cast<const uint16_t*>(indexData);
224- for (size_t i = 0; i < indexAccessor.count; i++) {
225- Vertex vertex = vertices[indices16[i]];
226- indices.push_back(uniqueVertices[vertex]);
255+ if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
256+ {
257+ index = *reinterpret_cast<const uint16_t *>(indexData + i * indexStride);
227258 }
228- } else if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) {
229- const uint32_t* indices32 = reinterpret_cast<const uint32_t*>(indexData);
230- for (size_t i = 0; i < indexAccessor.count; i++) {
231- Vertex vertex = vertices[indices32[i]];
232- indices.push_back(uniqueVertices[vertex]);
259+ else if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
260+ {
261+ index = *reinterpret_cast<const uint32_t *>(indexData + i * indexStride);
233262 }
234- } else if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
235- const uint8_t* indices8 = reinterpret_cast<const uint8_t*>(indexData);
236- for (size_t i = 0; i < indexAccessor.count; i++) {
237- Vertex vertex = vertices[indices8[i]];
238- indices.push_back(uniqueVertices[vertex]);
263+ else if (indexAccessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
264+ {
265+ index = *reinterpret_cast<const uint8_t *>(indexData + i * indexStride);
239266 }
267+
268+ indices.push_back(baseVertex + index);
240269 }
241270 }
242271 }
0 commit comments