mirror of
https://github.com/raysan5/raylib.git
synced 2025-09-30 06:58:31 +00:00
REVIEWED: [rmodels] LoadGLFT()
, avoid loading attributes already loaded, issue a warning. FIX: #4996
This commit is contained in:
375
src/rmodels.c
375
src/rmodels.c
@@ -5488,14 +5488,16 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
// Other possible materials not supported by raylib pipeline:
|
// Other possible materials not supported by raylib pipeline:
|
||||||
// has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen
|
// has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen
|
||||||
}
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Visit each node in the hierarchy and process any mesh linked from it
|
// Load meshes data
|
||||||
// Each primitive within a glTF node becomes a Raylib Mesh
|
//
|
||||||
// The local-to-world transform of each node is used to transform the
|
// NOTE: Visit each node in the hierarchy and process any mesh linked from it
|
||||||
// points/normals/tangents of the created Mesh(es)
|
// - Each primitive within a glTF node becomes a raylib Mesh
|
||||||
// Any glTF mesh linked from more than one Node (i.e. instancing)
|
// - The local-to-world transform of each node is used to transform the points/normals/tangents of the created Mesh(es)
|
||||||
// is turned into multiple Mesh's, as each Node will have its own transform applied
|
// - Any glTF mesh linked from more than one Node (i.e. instancing) is turned into multiple Mesh's, as each Node will have its own transform applied
|
||||||
// NOTE: The code below disregards the scenes defined in the file, all nodes are used
|
//
|
||||||
|
// WARNING: The code below disregards the scenes defined in the file, all nodes are used
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
int meshIndex = 0;
|
int meshIndex = 0;
|
||||||
for (unsigned int i = 0; i < data->nodes_count; i++)
|
for (unsigned int i = 0; i < data->nodes_count; i++)
|
||||||
@@ -5503,8 +5505,7 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
cgltf_node *node = &(data->nodes[i]);
|
cgltf_node *node = &(data->nodes[i]);
|
||||||
|
|
||||||
cgltf_mesh *mesh = node->mesh;
|
cgltf_mesh *mesh = node->mesh;
|
||||||
if (!mesh)
|
if (!mesh) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
cgltf_float worldTransform[16];
|
cgltf_float worldTransform[16];
|
||||||
cgltf_node_transform_world(node, worldTransform);
|
cgltf_node_transform_world(node, worldTransform);
|
||||||
@@ -5536,74 +5537,86 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
|
|
||||||
// WARNING: SPECS: POSITION accessor MUST have its min and max properties defined
|
// WARNING: SPECS: POSITION accessor MUST have its min and max properties defined
|
||||||
|
|
||||||
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
if (model.meshes[meshIndex].vertices != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Init raylib mesh vertices to copy glTF attribute data
|
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
||||||
model.meshes[meshIndex].vertexCount = (int)attribute->count;
|
|
||||||
model.meshes[meshIndex].vertices = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
|
|
||||||
|
|
||||||
// Load 3 components of float data type into mesh.vertices
|
|
||||||
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices)
|
|
||||||
|
|
||||||
// Transform the vertices
|
|
||||||
float *vertices = model.meshes[meshIndex].vertices;
|
|
||||||
for (unsigned int k = 0; k < attribute->count; k++)
|
|
||||||
{
|
{
|
||||||
Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
|
// Init raylib mesh vertices to copy glTF attribute data
|
||||||
vertices[3*k] = vt.x;
|
model.meshes[meshIndex].vertexCount = (int)attribute->count;
|
||||||
vertices[3*k+1] = vt.y;
|
model.meshes[meshIndex].vertices = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
|
||||||
vertices[3*k+2] = vt.z;
|
|
||||||
|
// Load 3 components of float data type into mesh.vertices
|
||||||
|
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices)
|
||||||
|
|
||||||
|
// Transform the vertices
|
||||||
|
float *vertices = model.meshes[meshIndex].vertices;
|
||||||
|
for (unsigned int k = 0; k < attribute->count; k++)
|
||||||
|
{
|
||||||
|
Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
|
||||||
|
vertices[3*k] = vt.x;
|
||||||
|
vertices[3*k+1] = vt.y;
|
||||||
|
vertices[3*k+2] = vt.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName);
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName);
|
|
||||||
}
|
}
|
||||||
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float
|
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float
|
||||||
{
|
{
|
||||||
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
|
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
|
||||||
|
|
||||||
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
if (model.meshes[meshIndex].normals != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Normals attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Init raylib mesh normals to copy glTF attribute data
|
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
||||||
model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
|
|
||||||
|
|
||||||
// Load 3 components of float data type into mesh.normals
|
|
||||||
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals)
|
|
||||||
|
|
||||||
// Transform the normals
|
|
||||||
float *normals = model.meshes[meshIndex].normals;
|
|
||||||
for (unsigned int k = 0; k < attribute->count; k++)
|
|
||||||
{
|
{
|
||||||
Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
|
// Init raylib mesh normals to copy glTF attribute data
|
||||||
normals[3*k] = nt.x;
|
model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
|
||||||
normals[3*k+1] = nt.y;
|
|
||||||
normals[3*k+2] = nt.z;
|
// Load 3 components of float data type into mesh.normals
|
||||||
|
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals)
|
||||||
|
|
||||||
|
// Transform the normals
|
||||||
|
float *normals = model.meshes[meshIndex].normals;
|
||||||
|
for (unsigned int k = 0; k < attribute->count; k++)
|
||||||
|
{
|
||||||
|
Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
|
||||||
|
normals[3*k] = nt.x;
|
||||||
|
normals[3*k+1] = nt.y;
|
||||||
|
normals[3*k+2] = nt.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Normals attribute data format not supported, use vec3 float", fileName);
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName);
|
|
||||||
}
|
}
|
||||||
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec4, float, w is tangent basis sign
|
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec4, float, w is tangent basis sign
|
||||||
{
|
{
|
||||||
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
|
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
|
||||||
|
|
||||||
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
|
if (model.meshes[meshIndex].tangents != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Tangents attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Init raylib mesh tangent to copy glTF attribute data
|
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
|
||||||
model.meshes[meshIndex].tangents = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
|
|
||||||
|
|
||||||
// Load 4 components of float data type into mesh.tangents
|
|
||||||
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents)
|
|
||||||
|
|
||||||
// Transform the tangents
|
|
||||||
float *tangents = model.meshes[meshIndex].tangents;
|
|
||||||
for (unsigned int k = 0; k < attribute->count; k++)
|
|
||||||
{
|
{
|
||||||
Vector3 tt = Vector3Transform((Vector3){ tangents[4*k], tangents[4*k+1], tangents[4*k+2] }, worldMatrix);
|
// Init raylib mesh tangent to copy glTF attribute data
|
||||||
tangents[4*k] = tt.x;
|
model.meshes[meshIndex].tangents = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
|
||||||
tangents[4*k+1] = tt.y;
|
|
||||||
tangents[4*k+2] = tt.z;
|
// Load 4 components of float data type into mesh.tangents
|
||||||
|
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents)
|
||||||
|
|
||||||
|
// Transform the tangents
|
||||||
|
float *tangents = model.meshes[meshIndex].tangents;
|
||||||
|
for (unsigned int k = 0; k < attribute->count; k++)
|
||||||
|
{
|
||||||
|
Vector3 tt = Vector3Transform((Vector3){ tangents[4*k], tangents[4*k+1], tangents[4*k+2] }, worldMatrix);
|
||||||
|
tangents[4*k] = tt.x;
|
||||||
|
tangents[4*k+1] = tt.y;
|
||||||
|
tangents[4*k+2] = tt.z;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangents attribute data format not supported, use vec4 float", fileName);
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName);
|
|
||||||
}
|
}
|
||||||
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n
|
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n
|
||||||
{
|
{
|
||||||
@@ -5669,114 +5682,118 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
|
|
||||||
// WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range
|
// WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range
|
||||||
|
|
||||||
if (attribute->type == cgltf_type_vec3) // RGB
|
if (model.meshes[meshIndex].colors != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Colors attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (attribute->component_type == cgltf_component_type_r_8u)
|
if (attribute->type == cgltf_type_vec3) // RGB
|
||||||
{
|
{
|
||||||
// Init raylib mesh color to copy glTF attribute data
|
if (attribute->component_type == cgltf_component_type_r_8u)
|
||||||
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
|
||||||
|
|
||||||
// Load data into a temp buffer to be converted to raylib data type
|
|
||||||
unsigned char *temp = (unsigned char *)RL_MALLOC(attribute->count*3*sizeof(unsigned char));
|
|
||||||
LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp);
|
|
||||||
|
|
||||||
// Convert data to raylib color data type (4 bytes)
|
|
||||||
for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
|
|
||||||
{
|
{
|
||||||
model.meshes[meshIndex].colors[c] = temp[k];
|
// Init raylib mesh color to copy glTF attribute data
|
||||||
model.meshes[meshIndex].colors[c + 1] = temp[k + 1];
|
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
||||||
model.meshes[meshIndex].colors[c + 2] = temp[k + 2];
|
|
||||||
model.meshes[meshIndex].colors[c + 3] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
RL_FREE(temp);
|
// Load data into a temp buffer to be converted to raylib data type
|
||||||
|
unsigned char *temp = (unsigned char *)RL_MALLOC(attribute->count*3*sizeof(unsigned char));
|
||||||
|
LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp);
|
||||||
|
|
||||||
|
// Convert data to raylib color data type (4 bytes)
|
||||||
|
for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
|
||||||
|
{
|
||||||
|
model.meshes[meshIndex].colors[c] = temp[k];
|
||||||
|
model.meshes[meshIndex].colors[c + 1] = temp[k + 1];
|
||||||
|
model.meshes[meshIndex].colors[c + 2] = temp[k + 2];
|
||||||
|
model.meshes[meshIndex].colors[c + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
RL_FREE(temp);
|
||||||
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_16u)
|
||||||
|
{
|
||||||
|
// Init raylib mesh color to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
||||||
|
|
||||||
|
// Load data into a temp buffer to be converted to raylib data type
|
||||||
|
unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*3*sizeof(unsigned short));
|
||||||
|
LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp);
|
||||||
|
|
||||||
|
// Convert data to raylib color data type (4 bytes)
|
||||||
|
for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
|
||||||
|
{
|
||||||
|
model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[k]/65535.0f)*255.0f);
|
||||||
|
model.meshes[meshIndex].colors[c + 1] = (unsigned char)(((float)temp[k + 1]/65535.0f)*255.0f);
|
||||||
|
model.meshes[meshIndex].colors[c + 2] = (unsigned char)(((float)temp[k + 2]/65535.0f)*255.0f);
|
||||||
|
model.meshes[meshIndex].colors[c + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
RL_FREE(temp);
|
||||||
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_32f)
|
||||||
|
{
|
||||||
|
// Init raylib mesh color to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
||||||
|
|
||||||
|
// Load data into a temp buffer to be converted to raylib data type
|
||||||
|
float *temp = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
|
||||||
|
LOAD_ATTRIBUTE(attribute, 3, float, temp);
|
||||||
|
|
||||||
|
// Convert data to raylib color data type (4 bytes)
|
||||||
|
for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
|
||||||
|
{
|
||||||
|
model.meshes[meshIndex].colors[c] = (unsigned char)(temp[k]*255.0f);
|
||||||
|
model.meshes[meshIndex].colors[c + 1] = (unsigned char)(temp[k + 1]*255.0f);
|
||||||
|
model.meshes[meshIndex].colors[c + 2] = (unsigned char)(temp[k + 2]*255.0f);
|
||||||
|
model.meshes[meshIndex].colors[c + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
RL_FREE(temp);
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
||||||
}
|
}
|
||||||
else if (attribute->component_type == cgltf_component_type_r_16u)
|
else if (attribute->type == cgltf_type_vec4) // RGBA
|
||||||
{
|
{
|
||||||
// Init raylib mesh color to copy glTF attribute data
|
if (attribute->component_type == cgltf_component_type_r_8u)
|
||||||
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
|
||||||
|
|
||||||
// Load data into a temp buffer to be converted to raylib data type
|
|
||||||
unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*3*sizeof(unsigned short));
|
|
||||||
LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp);
|
|
||||||
|
|
||||||
// Convert data to raylib color data type (4 bytes)
|
|
||||||
for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
|
|
||||||
{
|
{
|
||||||
model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[k]/65535.0f)*255.0f);
|
// Init raylib mesh color to copy glTF attribute data
|
||||||
model.meshes[meshIndex].colors[c + 1] = (unsigned char)(((float)temp[k + 1]/65535.0f)*255.0f);
|
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
||||||
model.meshes[meshIndex].colors[c + 2] = (unsigned char)(((float)temp[k + 2]/65535.0f)*255.0f);
|
|
||||||
model.meshes[meshIndex].colors[c + 3] = 255;
|
// Load 4 components of unsigned char data type into mesh.colors
|
||||||
|
LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors)
|
||||||
}
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_16u)
|
||||||
RL_FREE(temp);
|
|
||||||
}
|
|
||||||
else if (attribute->component_type == cgltf_component_type_r_32f)
|
|
||||||
{
|
|
||||||
// Init raylib mesh color to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
|
||||||
|
|
||||||
// Load data into a temp buffer to be converted to raylib data type
|
|
||||||
float *temp = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
|
|
||||||
LOAD_ATTRIBUTE(attribute, 3, float, temp);
|
|
||||||
|
|
||||||
// Convert data to raylib color data type (4 bytes)
|
|
||||||
for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
|
|
||||||
{
|
{
|
||||||
model.meshes[meshIndex].colors[c] = (unsigned char)(temp[k]*255.0f);
|
// Init raylib mesh color to copy glTF attribute data
|
||||||
model.meshes[meshIndex].colors[c + 1] = (unsigned char)(temp[k + 1]*255.0f);
|
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
||||||
model.meshes[meshIndex].colors[c + 2] = (unsigned char)(temp[k + 2]*255.0f);
|
|
||||||
model.meshes[meshIndex].colors[c + 3] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
RL_FREE(temp);
|
// Load data into a temp buffer to be converted to raylib data type
|
||||||
|
unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*4*sizeof(unsigned short));
|
||||||
|
LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp);
|
||||||
|
|
||||||
|
// Convert data to raylib color data type (4 bytes)
|
||||||
|
for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[c]/65535.0f)*255.0f);
|
||||||
|
|
||||||
|
RL_FREE(temp);
|
||||||
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_32f)
|
||||||
|
{
|
||||||
|
// Init raylib mesh color to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
||||||
|
|
||||||
|
// Load data into a temp buffer to be converted to raylib data type
|
||||||
|
float *temp = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
|
||||||
|
LOAD_ATTRIBUTE(attribute, 4, float, temp);
|
||||||
|
|
||||||
|
// Convert data to raylib color data type (4 bytes), we expect the color data normalized
|
||||||
|
for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f);
|
||||||
|
|
||||||
|
RL_FREE(temp);
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
||||||
}
|
}
|
||||||
else if (attribute->type == cgltf_type_vec4) // RGBA
|
|
||||||
{
|
|
||||||
if (attribute->component_type == cgltf_component_type_r_8u)
|
|
||||||
{
|
|
||||||
// Init raylib mesh color to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
|
||||||
|
|
||||||
// Load 4 components of unsigned char data type into mesh.colors
|
|
||||||
LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors)
|
|
||||||
}
|
|
||||||
else if (attribute->component_type == cgltf_component_type_r_16u)
|
|
||||||
{
|
|
||||||
// Init raylib mesh color to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
|
||||||
|
|
||||||
// Load data into a temp buffer to be converted to raylib data type
|
|
||||||
unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*4*sizeof(unsigned short));
|
|
||||||
LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp);
|
|
||||||
|
|
||||||
// Convert data to raylib color data type (4 bytes)
|
|
||||||
for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[c]/65535.0f)*255.0f);
|
|
||||||
|
|
||||||
RL_FREE(temp);
|
|
||||||
}
|
|
||||||
else if (attribute->component_type == cgltf_component_type_r_32f)
|
|
||||||
{
|
|
||||||
// Init raylib mesh color to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
|
|
||||||
|
|
||||||
// Load data into a temp buffer to be converted to raylib data type
|
|
||||||
float *temp = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
|
|
||||||
LOAD_ATTRIBUTE(attribute, 4, float, temp);
|
|
||||||
|
|
||||||
// Convert data to raylib color data type (4 bytes), we expect the color data normalized
|
|
||||||
for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f);
|
|
||||||
|
|
||||||
RL_FREE(temp);
|
|
||||||
}
|
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
|
||||||
}
|
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Attributes related to animations are processed separately
|
// NOTE: Attributes related to animations data are processed after mesh data loading
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load primitive indices data (if provided)
|
// Load primitive indices data (if provided)
|
||||||
@@ -5786,32 +5803,33 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
|
|
||||||
model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
|
model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
|
||||||
|
|
||||||
if (attribute->component_type == cgltf_component_type_r_16u)
|
if (model.meshes[meshIndex].indices != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Indices attribute data already loaded", fileName);
|
||||||
{
|
|
||||||
// Init raylib mesh indices to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
|
|
||||||
|
|
||||||
// Load unsigned short data type into mesh.indices
|
|
||||||
LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
|
|
||||||
}
|
|
||||||
else if (attribute->component_type == cgltf_component_type_r_8u)
|
|
||||||
{
|
|
||||||
// Init raylib mesh indices to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
|
|
||||||
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (attribute->component_type == cgltf_component_type_r_32u)
|
|
||||||
{
|
|
||||||
// Init raylib mesh indices to copy glTF attribute data
|
|
||||||
model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
|
|
||||||
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short);
|
|
||||||
|
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
|
if (attribute->component_type == cgltf_component_type_r_16u)
|
||||||
|
{
|
||||||
|
// Init raylib mesh indices to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
|
||||||
|
|
||||||
|
// Load unsigned short data type into mesh.indices
|
||||||
|
LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
|
||||||
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_8u)
|
||||||
|
{
|
||||||
|
// Init raylib mesh indices to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
|
||||||
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_32u)
|
||||||
|
{
|
||||||
|
// Init raylib mesh indices to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
|
||||||
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short);
|
||||||
|
|
||||||
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh
|
else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh
|
||||||
@@ -5834,8 +5852,9 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
meshIndex++; // Move to next mesh
|
meshIndex++; // Move to next mesh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Load glTF meshes animation data
|
// Load animation data
|
||||||
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins
|
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins
|
||||||
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
|
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
|
||||||
//
|
//
|
||||||
@@ -5863,10 +5882,8 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
};
|
};
|
||||||
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale));
|
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (data->skins_count > 1)
|
if (data->skins_count > 1) TRACELOG(LOG_WARNING, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
|
||||||
{
|
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meshIndex = 0;
|
meshIndex = 0;
|
||||||
@@ -5875,8 +5892,7 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
cgltf_node *node = &(data->nodes[i]);
|
cgltf_node *node = &(data->nodes[i]);
|
||||||
|
|
||||||
cgltf_mesh *mesh = node->mesh;
|
cgltf_mesh *mesh = node->mesh;
|
||||||
if (!mesh)
|
if (!mesh) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
for (unsigned int p = 0; p < mesh->primitives_count; p++)
|
for (unsigned int p = 0; p < mesh->primitives_count; p++)
|
||||||
{
|
{
|
||||||
@@ -6039,6 +6055,7 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
meshIndex++; // Move to next mesh
|
meshIndex++; // Move to next mesh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Free all cgltf loaded data
|
// Free all cgltf loaded data
|
||||||
cgltf_free(data);
|
cgltf_free(data);
|
||||||
|
Reference in New Issue
Block a user