|
|
@ -5226,17 +5226,19 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
***********************************************************************************************/ |
|
|
|
|
|
|
|
// Macro to simplify attributes loading code |
|
|
|
#define LOAD_ATTRIBUTE(accesor, numComp, dataType, dstPtr) \ |
|
|
|
#define LOAD_ATTRIBUTE(accesor, numComp, srcType, dstPtr) LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, srcType) |
|
|
|
|
|
|
|
#define LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, dstType) \ |
|
|
|
{ \ |
|
|
|
int n = 0; \ |
|
|
|
dataType *buffer = (dataType *)accesor->buffer_view->buffer->data + accesor->buffer_view->offset/sizeof(dataType) + accesor->offset/sizeof(dataType); \ |
|
|
|
srcType *buffer = (srcType *)accesor->buffer_view->buffer->data + accesor->buffer_view->offset/sizeof(srcType) + accesor->offset/sizeof(srcType); \ |
|
|
|
for (unsigned int k = 0; k < accesor->count; k++) \ |
|
|
|
{\ |
|
|
|
for (int l = 0; l < numComp; l++) \ |
|
|
|
{\ |
|
|
|
dstPtr[numComp*k + l] = buffer[n + l];\ |
|
|
|
dstPtr[numComp*k + l] = p">(dstType)buffer[n + l];\ |
|
|
|
}\ |
|
|
|
n += (int)(accesor->stride/sizeof(dataType));\ |
|
|
|
n += (int)(accesor->stride/sizeof(srcType));\ |
|
|
|
}\ |
|
|
|
} |
|
|
|
|
|
|
@ -5697,23 +5699,25 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
// 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 = 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 = RL_MALLOC(attribute->count*sizeof(unsigned short)); |
|
|
|
|
|
|
|
// Load data into a temp buffer to be converted to raylib data type |
|
|
|
unsigned int *temp = RL_MALLOC(attribute->count*sizeof(unsigned int)); |
|
|
|
LOAD_ATTRIBUTE(attribute, 1, unsigned int, temp); |
|
|
|
|
|
|
|
// Convert data to raylib indices data type (unsigned short) |
|
|
|
for (unsigned int d = 0; d < attribute->count; d++) model.meshes[meshIndex].indices[d] = (unsigned short)temp[d]; |
|
|
|
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); |
|
|
|
|
|
|
|
RL_FREE(temp); |
|
|
|
} |
|
|
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", 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 |
|
|
|
|
|
|
@ -5745,7 +5749,7 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
// - Only supports linear interpolation (default method in Blender when checked "Always Sample Animations" when exporting a GLTF file) |
|
|
|
// - Only supports translation/rotation/scale animation channel.path, weights not considered (i.e. morph targets) |
|
|
|
//---------------------------------------------------------------------------------------------------- |
|
|
|
if (data->skins_count == 1) |
|
|
|
if (data->skins_count > 0) |
|
|
|
{ |
|
|
|
cgltf_skin skin = data->skins[0]; |
|
|
|
model.bones = LoadBoneInfoGLTF(skin, &model.boneCount); |
|
|
@ -5765,9 +5769,9 @@ static Model LoadGLTF(const char *fileName) |
|
|
|
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale)); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (data->skins_count > 1) |
|
|
|
if (data->skins_count > 1) |
|
|
|
{ |
|
|
|
TRACELOG(LOG_ERROR, "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; |
|
|
@ -6088,7 +6092,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo |
|
|
|
|
|
|
|
if (result == cgltf_result_success) |
|
|
|
{ |
|
|
|
if (data->skins_count == 1) |
|
|
|
if (data->skins_count > 0) |
|
|
|
{ |
|
|
|
cgltf_skin skin = data->skins[0]; |
|
|
|
*animCount = (int)data->animations_count; |
|
|
@ -6223,7 +6227,11 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo |
|
|
|
RL_FREE(boneChannels); |
|
|
|
} |
|
|
|
} |
|
|
|
else TRACELOG(LOG_ERROR, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count); |
|
|
|
|
|
|
|
if (data->skins_count > 1) |
|
|
|
{ |
|
|
|
TRACELOG(LOG_WARNING, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count); |
|
|
|
} |
|
|
|
|
|
|
|
cgltf_free(data); |
|
|
|
} |
|
|
|