mirror of
https://github.com/raysan5/raylib.git
synced 2025-09-30 15:08:32 +00:00
REVIEWED: [rmodels] LoadGLFT()
, avoid loading attributes already loaded, issue a warning. FIX: #4996
This commit is contained in:
@@ -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,6 +5537,9 @@ 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 (model.meshes[meshIndex].vertices != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
||||||
{
|
{
|
||||||
// Init raylib mesh vertices to copy glTF attribute data
|
// Init raylib mesh vertices to copy glTF attribute data
|
||||||
@@ -5557,10 +5561,14 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
}
|
}
|
||||||
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 (model.meshes[meshIndex].normals != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Normals attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
|
||||||
{
|
{
|
||||||
// Init raylib mesh normals to copy glTF attribute data
|
// Init raylib mesh normals to copy glTF attribute data
|
||||||
@@ -5579,12 +5587,16 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
normals[3*k+2] = nt.z;
|
normals[3*k+2] = nt.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName);
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Normals 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 (model.meshes[meshIndex].tangents != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Tangents attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
|
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
|
||||||
{
|
{
|
||||||
// Init raylib mesh tangent to copy glTF attribute data
|
// Init raylib mesh tangent to copy glTF attribute data
|
||||||
@@ -5603,7 +5615,8 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
tangents[4*k+2] = tt.z;
|
tangents[4*k+2] = tt.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName);
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangents 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,6 +5682,9 @@ 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 (model.meshes[meshIndex].colors != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Colors attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
if (attribute->type == cgltf_type_vec3) // RGB
|
if (attribute->type == cgltf_type_vec3) // RGB
|
||||||
{
|
{
|
||||||
if (attribute->component_type == cgltf_component_type_r_8u)
|
if (attribute->component_type == cgltf_component_type_r_8u)
|
||||||
@@ -5775,8 +5791,9 @@ static Model LoadGLTF(const char *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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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,6 +5803,9 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
|
|
||||||
model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
|
model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
|
||||||
|
|
||||||
|
if (model.meshes[meshIndex].indices != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Indices attribute data already loaded", fileName);
|
||||||
|
else
|
||||||
|
{
|
||||||
if (attribute->component_type == cgltf_component_type_r_16u)
|
if (attribute->component_type == cgltf_component_type_r_16u)
|
||||||
{
|
{
|
||||||
// Init raylib mesh indices to copy glTF attribute data
|
// Init raylib mesh indices to copy glTF attribute data
|
||||||
@@ -5809,9 +5829,7 @@ static Model LoadGLTF(const char *fileName)
|
|||||||
|
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
|
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);
|
||||||
{
|
|
||||||
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