Refactored the new names and structure of extracted functions.
This commit is contained in:
parent
3501c86b33
commit
659c6faa05
504
src/models.c
504
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user