From 659c6faa05d0bf33d05f549b37258735196e7c16 Mon Sep 17 00:00:00 2001 From: Hristo Stamenov Date: Sat, 19 Jun 2021 15:21:07 +0300 Subject: [PATCH] Refactored the new names and structure of extracted functions. --- src/models.c | 504 ++++++++++++++++++++++++++------------------------- 1 file changed, 254 insertions(+), 250 deletions(-) diff --git a/src/models.c b/src/models.c index ec594ce16..cebdd794e 100644 --- a/src/models.c +++ b/src/models.c @@ -118,10 +118,13 @@ static ModelAnimation *LoadIQMModelAnimations(const char *fileName, int *animCou static Model LoadGLTF(const char *fileName); // Load GLTF mesh data static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount); // Load GLTF animation data static void LoadGLTFModelIndices(Model *model, cgltf_accessor *indexAccessor, int primitiveIndex); -static void BindGLTFPrimitiveToBones(Model *model, const cgltf_data *data, int primitiveIndex); static void LoadGLTFBoneAttribute(Model *model, cgltf_accessor *jointsAccessor, const cgltf_data *data, int primitiveIndex); static void LoadGLTFMaterial(Model *model, const char *fileName, const cgltf_data *data); +static void LoadGLTFMesh(cgltf_data *data, cgltf_mesh* mesh, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char* fileName); +static void LoadGLTFNode(cgltf_data *data, cgltf_node* node, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char* fileName); static void InitGLTFBones(Model *model, const cgltf_data *data); +static void BindGLTFPrimitiveToBones(Model *model, const cgltf_data *data, int primitiveIndex); +static void GetGLTFPrimitiveCount(cgltf_node* node, int* outCount); #endif //---------------------------------------------------------------------------------- @@ -4158,253 +4161,6 @@ static bool GLTFReadValue(cgltf_accessor* acc, unsigned int index, void *variabl return true; } -static void ProcessGLTFMesh(cgltf_data *data, cgltf_mesh* mesh, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char* fileName) -{ - for (unsigned int p = 0; p < mesh->primitives_count; p++) - { - for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++) - { - if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_position) - { - cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; - outModel->meshes[(*primitiveIndex)].vertexCount = (int)acc->count; - int bufferSize = outModel->meshes[(*primitiveIndex)].vertexCount*3*sizeof(float); - outModel->meshes[(*primitiveIndex)].vertices = RL_MALLOC(bufferSize); - outModel->meshes[(*primitiveIndex)].animVertices = RL_MALLOC(bufferSize); - - if (acc->component_type == cgltf_component_type_r_32f) - { - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].vertices + (a*3), 3, sizeof(float)); - } - } - else if (acc->component_type == cgltf_component_type_r_32u) - { - int readValue[3]; - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, readValue, 3, sizeof(int)); - outModel->meshes[(*primitiveIndex)].vertices[(a*3) + 0] = (float)readValue[0]; - outModel->meshes[(*primitiveIndex)].vertices[(a*3) + 1] = (float)readValue[1]; - outModel->meshes[(*primitiveIndex)].vertices[(a*3) + 2] = (float)readValue[2]; - } - } - else - { - // TODO: Support normalized unsigned byte/unsigned short vertices - TRACELOG(LOG_WARNING, "MODEL: [%s] glTF vertices must be float or int", fileName); - } - - for (unsigned int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++) - { - Vector3 vertex = { - outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 0)], - outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 1)], - outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 2)], - }; - - vertex = Vector3Transform(vertex, currentTransform); - - outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 0)] = vertex.x; - outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 1)] = vertex.y; - outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 2)] = vertex.z; - } - - memcpy(outModel->meshes[(*primitiveIndex)].animVertices, outModel->meshes[(*primitiveIndex)].vertices, bufferSize); - } - else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) - { - cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; - - int bufferSize = (int)(acc->count*3*sizeof(float)); - outModel->meshes[(*primitiveIndex)].normals = RL_MALLOC(bufferSize); - outModel->meshes[(*primitiveIndex)].animNormals = RL_MALLOC(bufferSize); - - if (acc->component_type == cgltf_component_type_r_32f) - { - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].normals + (a*3), 3, sizeof(float)); - } - } - else if (acc->component_type == cgltf_component_type_r_32u) - { - int readValue[3]; - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, readValue, 3, sizeof(int)); - outModel->meshes[(*primitiveIndex)].normals[(a*3) + 0] = (float)readValue[0]; - outModel->meshes[(*primitiveIndex)].normals[(a*3) + 1] = (float)readValue[1]; - outModel->meshes[(*primitiveIndex)].normals[(a*3) + 2] = (float)readValue[2]; - } - } - else - { - // TODO: Support normalized unsigned byte/unsigned short normals - TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName); - } - - for (unsigned int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++) - { - Vector3 normal = { - outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 0)], - outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 1)], - outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 2)], - }; - - normal = Vector3Transform(normal, currentTransform); - - outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 0)] = normal.x; - outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 1)] = normal.y; - outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 2)] = normal.z; - } - - memcpy(outModel->meshes[(*primitiveIndex)].animNormals, outModel->meshes[(*primitiveIndex)].normals, bufferSize); - } - else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) - { - cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; - - if (acc->component_type == cgltf_component_type_r_32f) - { - outModel->meshes[(*primitiveIndex)].texcoords = RL_MALLOC(acc->count*2*sizeof(float)); - - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].texcoords + (a*2), 2, sizeof(float)); - } - } - else - { - // TODO: Support normalized unsigned byte/unsigned short texture coordinates - TRACELOG(LOG_WARNING, "MODEL: [%s] glTF texture coordinates must be float", fileName); - } - } - else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_joints) - { - cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; - LoadGLTFBoneAttribute(outModel, acc, data, *primitiveIndex); - } - else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_weights) - { - cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; - - outModel->meshes[(*primitiveIndex)].boneWeights = RL_MALLOC(acc->count*4*sizeof(float)); - - if (acc->component_type == cgltf_component_type_r_32f) - { - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].boneWeights + (a*4), 4, sizeof(float)); - } - } - else if (acc->component_type == cgltf_component_type_r_32u) - { - unsigned int readValue[4]; - for (unsigned int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned int)); - outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 0] = (float)readValue[0]; - outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 1] = (float)readValue[1]; - outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 2] = (float)readValue[2]; - outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 3] = (float)readValue[3]; - } - } - else - { - // TODO: Support normalized unsigned byte/unsigned short weights - TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName); - } - } - else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_color) - { - cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; - outModel->meshes[(*primitiveIndex)].colors = RL_MALLOC(acc->count*4*sizeof(unsigned char)); - - if (acc->component_type == cgltf_component_type_r_8u) - { - for (int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].colors + (a*4), 4, sizeof(unsigned char)); - } - } - if (acc->component_type == cgltf_component_type_r_16u) - { - TRACELOG(LOG_WARNING, "MODEL: [%s] converting glTF colors to unsigned char", fileName); - for (int a = 0; a < acc->count; a++) - { - unsigned short readValue[4]; - for (int a = 0; a < acc->count; a++) - { - GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned short)); - // 257 = 65535/255 - outModel->meshes[(*primitiveIndex)].colors[(a*4) + 0] = (unsigned char)(readValue[0]/257); - outModel->meshes[(*primitiveIndex)].colors[(a*4) + 1] = (unsigned char)(readValue[1]/257); - outModel->meshes[(*primitiveIndex)].colors[(a*4) + 2] = (unsigned char)(readValue[2]/257); - outModel->meshes[(*primitiveIndex)].colors[(a*4) + 3] = (unsigned char)(readValue[3]/257); - } - } - } - else - { - TRACELOG(LOG_WARNING, "MODEL: [%s] glTF colors must be uchar or ushort", fileName); - } - } - } - - cgltf_accessor *acc = mesh->primitives[p].indices; - LoadGLTFModelIndices(outModel, acc, *primitiveIndex); - - if (mesh->primitives[p].material) - { - // Compute the offset - outModel->meshMaterial[(*primitiveIndex)] = (int)(mesh->primitives[p].material - data->materials); - } - else - { - outModel->meshMaterial[(*primitiveIndex)] = outModel->materialCount - 1; - } - - BindGLTFPrimitiveToBones(outModel, data, *primitiveIndex); - - (*primitiveIndex) = (*primitiveIndex) + 1; - } -} - -static void ProcessGLTFNode(cgltf_data *data, cgltf_node* node, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char* fileName) -{ - Matrix nodeTransform = { node->matrix[0], node->matrix[4], node->matrix[8], node->matrix[12], - node->matrix[1], node->matrix[5], node->matrix[9], node->matrix[13], - node->matrix[2], node->matrix[6], node->matrix[10], node->matrix[14], - node->matrix[3], node->matrix[7], node->matrix[11], node->matrix[15] }; - - currentTransform = MatrixMultiply(nodeTransform, currentTransform); - - if(node->mesh != NULL) - { - ProcessGLTFMesh(data, node->mesh, outModel, currentTransform, primitiveIndex, fileName); - } - - for(unsigned int i = 0; i < node->children_count; i++) - { - ProcessGLTFNode(data, node->children[i], outModel, currentTransform, primitiveIndex, fileName); - } -} - -static void GetPrimitiveCount(cgltf_node* node, int* outCount) -{ - if(node->mesh != NULL) - { - *outCount += node->mesh->primitives_count; - } - - for(unsigned int i = 0; i < node->children_count; i++) - { - GetPrimitiveCount(node->children[i], outCount); - } -} - // LoadGLTF loads in model data from given filename, supporting both .gltf and .glb static Model LoadGLTF(const char *fileName) { @@ -4453,7 +4209,7 @@ static Model LoadGLTF(const char *fileName) int primitivesCount = 0; for (unsigned int i = 0; i < data->scene->nodes_count; i++) { - GetPrimitiveCount(data->scene->nodes[i], &primitivesCount); + GetGLTFPrimitiveCount(data->scene->nodes[i], &primitivesCount); } // Process glTF data and map to model @@ -4473,7 +4229,7 @@ static Model LoadGLTF(const char *fileName) for(unsigned int i = 0; i < data->scene->nodes_count; i++) { Matrix staticTransform = MatrixIdentity(); - ProcessGLTFNode(data, data->scene->nodes[i], &model, staticTransform, &primitiveIndex, fileName); + LoadGLTFNode(data, data->scene->nodes[i], &model, staticTransform, &primitiveIndex, fileName); } cgltf_free(data); @@ -4985,4 +4741,252 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo return animations; } +void LoadGLTFMesh(cgltf_data* data, cgltf_mesh* mesh, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char* fileName) +{ + for (unsigned int p = 0; p < mesh->primitives_count; p++) + { + for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++) + { + if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_position) + { + cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; + outModel->meshes[(*primitiveIndex)].vertexCount = (int)acc->count; + int bufferSize = outModel->meshes[(*primitiveIndex)].vertexCount*3*sizeof(float); + outModel->meshes[(*primitiveIndex)].vertices = RL_MALLOC(bufferSize); + outModel->meshes[(*primitiveIndex)].animVertices = RL_MALLOC(bufferSize); + + if (acc->component_type == cgltf_component_type_r_32f) + { + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].vertices + (a*3), 3, sizeof(float)); + } + } + else if (acc->component_type == cgltf_component_type_r_32u) + { + int readValue[3]; + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, readValue, 3, sizeof(int)); + outModel->meshes[(*primitiveIndex)].vertices[(a*3) + 0] = (float)readValue[0]; + outModel->meshes[(*primitiveIndex)].vertices[(a*3) + 1] = (float)readValue[1]; + outModel->meshes[(*primitiveIndex)].vertices[(a*3) + 2] = (float)readValue[2]; + } + } + else + { + // TODO: Support normalized unsigned byte/unsigned short vertices + TRACELOG(LOG_WARNING, "MODEL: [%s] glTF vertices must be float or int", fileName); + } + + for (unsigned int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++) + { + Vector3 vertex = { + outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 0)], + outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 1)], + outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 2)], + }; + + vertex = Vector3Transform(vertex, currentTransform); + + outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 0)] = vertex.x; + outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 1)] = vertex.y; + outModel->meshes[(*primitiveIndex)].vertices[(v * 3 + 2)] = vertex.z; + } + + memcpy(outModel->meshes[(*primitiveIndex)].animVertices, outModel->meshes[(*primitiveIndex)].vertices, bufferSize); + } + else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) + { + cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; + + int bufferSize = (int)(acc->count*3*sizeof(float)); + outModel->meshes[(*primitiveIndex)].normals = RL_MALLOC(bufferSize); + outModel->meshes[(*primitiveIndex)].animNormals = RL_MALLOC(bufferSize); + + if (acc->component_type == cgltf_component_type_r_32f) + { + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].normals + (a*3), 3, sizeof(float)); + } + } + else if (acc->component_type == cgltf_component_type_r_32u) + { + int readValue[3]; + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, readValue, 3, sizeof(int)); + outModel->meshes[(*primitiveIndex)].normals[(a*3) + 0] = (float)readValue[0]; + outModel->meshes[(*primitiveIndex)].normals[(a*3) + 1] = (float)readValue[1]; + outModel->meshes[(*primitiveIndex)].normals[(a*3) + 2] = (float)readValue[2]; + } + } + else + { + // TODO: Support normalized unsigned byte/unsigned short normals + TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName); + } + + for (unsigned int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++) + { + Vector3 normal = { + outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 0)], + outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 1)], + outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 2)], + }; + + normal = Vector3Transform(normal, currentTransform); + + outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 0)] = normal.x; + outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 1)] = normal.y; + outModel->meshes[(*primitiveIndex)].normals[(v * 3 + 2)] = normal.z; + } + + memcpy(outModel->meshes[(*primitiveIndex)].animNormals, outModel->meshes[(*primitiveIndex)].normals, bufferSize); + } + else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) + { + cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; + + if (acc->component_type == cgltf_component_type_r_32f) + { + outModel->meshes[(*primitiveIndex)].texcoords = RL_MALLOC(acc->count*2*sizeof(float)); + + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].texcoords + (a*2), 2, sizeof(float)); + } + } + else + { + // TODO: Support normalized unsigned byte/unsigned short texture coordinates + TRACELOG(LOG_WARNING, "MODEL: [%s] glTF texture coordinates must be float", fileName); + } + } + else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_joints) + { + cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; + LoadGLTFBoneAttribute(outModel, acc, data, *primitiveIndex); + } + else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_weights) + { + cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; + + outModel->meshes[(*primitiveIndex)].boneWeights = RL_MALLOC(acc->count*4*sizeof(float)); + + if (acc->component_type == cgltf_component_type_r_32f) + { + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].boneWeights + (a*4), 4, sizeof(float)); + } + } + else if (acc->component_type == cgltf_component_type_r_32u) + { + unsigned int readValue[4]; + for (unsigned int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned int)); + outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 0] = (float)readValue[0]; + outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 1] = (float)readValue[1]; + outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 2] = (float)readValue[2]; + outModel->meshes[(*primitiveIndex)].boneWeights[(a*4) + 3] = (float)readValue[3]; + } + } + else + { + // TODO: Support normalized unsigned byte/unsigned short weights + TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName); + } + } + else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_color) + { + cgltf_accessor *acc = mesh->primitives[p].attributes[j].data; + outModel->meshes[(*primitiveIndex)].colors = RL_MALLOC(acc->count*4*sizeof(unsigned char)); + + if (acc->component_type == cgltf_component_type_r_8u) + { + for (int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, outModel->meshes[(*primitiveIndex)].colors + (a*4), 4, sizeof(unsigned char)); + } + } + if (acc->component_type == cgltf_component_type_r_16u) + { + TRACELOG(LOG_WARNING, "MODEL: [%s] converting glTF colors to unsigned char", fileName); + for (int a = 0; a < acc->count; a++) + { + unsigned short readValue[4]; + for (int a = 0; a < acc->count; a++) + { + GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned short)); + // 257 = 65535/255 + outModel->meshes[(*primitiveIndex)].colors[(a*4) + 0] = (unsigned char)(readValue[0]/257); + outModel->meshes[(*primitiveIndex)].colors[(a*4) + 1] = (unsigned char)(readValue[1]/257); + outModel->meshes[(*primitiveIndex)].colors[(a*4) + 2] = (unsigned char)(readValue[2]/257); + outModel->meshes[(*primitiveIndex)].colors[(a*4) + 3] = (unsigned char)(readValue[3]/257); + } + } + } + else + { + TRACELOG(LOG_WARNING, "MODEL: [%s] glTF colors must be uchar or ushort", fileName); + } + } + } + + cgltf_accessor *acc = mesh->primitives[p].indices; + LoadGLTFModelIndices(outModel, acc, *primitiveIndex); + + if (mesh->primitives[p].material) + { + // Compute the offset + outModel->meshMaterial[(*primitiveIndex)] = (int)(mesh->primitives[p].material - data->materials); + } + else + { + outModel->meshMaterial[(*primitiveIndex)] = outModel->materialCount - 1; + } + + BindGLTFPrimitiveToBones(outModel, data, *primitiveIndex); + + (*primitiveIndex) = (*primitiveIndex) + 1; + } +} + +void LoadGLTFNode(cgltf_data* data, cgltf_node* node, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char* fileName) +{ + Matrix nodeTransform = { node->matrix[0], node->matrix[4], node->matrix[8], node->matrix[12], + node->matrix[1], node->matrix[5], node->matrix[9], node->matrix[13], + node->matrix[2], node->matrix[6], node->matrix[10], node->matrix[14], + node->matrix[3], node->matrix[7], node->matrix[11], node->matrix[15] }; + + currentTransform = MatrixMultiply(nodeTransform, currentTransform); + + if(node->mesh != NULL) + { + LoadGLTFMesh(data, node->mesh, outModel, currentTransform, primitiveIndex, fileName); + } + + for(unsigned int i = 0; i < node->children_count; i++) + { + LoadGLTFNode(data, node->children[i], outModel, currentTransform, primitiveIndex, fileName); + } +} + +static void GetGLTFPrimitiveCount(cgltf_node* node, int* outCount) +{ + if(node->mesh != NULL) + { + *outCount += node->mesh->primitives_count; + } + + for(unsigned int i = 0; i < node->children_count; i++) + { + GetGLTFPrimitiveCount(node->children[i], outCount); + } +} + + #endif