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 Model LoadGLTF(const char *fileName); // Load GLTF mesh data
|
||||||
static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount); // Load GLTF animation 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 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 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 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 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
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -4158,253 +4161,6 @@ static bool GLTFReadValue(cgltf_accessor* acc, unsigned int index, void *variabl
|
||||||
return true;
|
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
|
// LoadGLTF loads in model data from given filename, supporting both .gltf and .glb
|
||||||
static Model LoadGLTF(const char *fileName)
|
static Model LoadGLTF(const char *fileName)
|
||||||
{
|
{
|
||||||
|
|
@ -4453,7 +4209,7 @@ static Model LoadGLTF(const char *fileName)
|
||||||
int primitivesCount = 0;
|
int primitivesCount = 0;
|
||||||
for (unsigned int i = 0; i < data->scene->nodes_count; i++)
|
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
|
// 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++)
|
for(unsigned int i = 0; i < data->scene->nodes_count; i++)
|
||||||
{
|
{
|
||||||
Matrix staticTransform = MatrixIdentity();
|
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);
|
cgltf_free(data);
|
||||||
|
|
@ -4985,4 +4741,252 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
|
||||||
return animations;
|
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
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user