Fixed model loading with bones.

Also updated license info on the model.
This commit is contained in:
Hristo Stamenov 2021-01-27 11:50:43 +02:00
parent 0ae068506c
commit 3452c9fcb0
4 changed files with 70 additions and 12 deletions

View File

@ -39,7 +39,7 @@ int main(void)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type
Model model = LoadModel("resources/models/rigged_figure.glb"); // Load the animated model mesh and
Model model = LoadModel("resources/rigged_figure/rigged_figure.glb"); // Load the animated model mesh and
// basic data
// Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
// SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture
@ -48,7 +48,7 @@ int main(void)
// Load animation data
int animsCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/models/rigged_figure.glb", &animsCount);
ModelAnimation *anims = LoadModelAnimations("resources/rigged_figure/rigged_figure.glb", &animsCount);
int animFrameCounter = 0;
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode
@ -92,7 +92,7 @@ int main(void)
EndMode3D();
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON);
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY);
DrawText("(cc4) Rigged Figure by @Cesium", screenWidth - 200, screenHeight - 20, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------

View File

@ -0,0 +1,6 @@
Rigged Figure model has been created by Cesium (https://cesium.com/cesiumjs/),
and licensed as Creative Commons Attribution 4.0 International License.
It was donated to GLTF sample models for testing (https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/RiggedFigure)
Check for details: http://creativecommons.org/licenses/by/4.0/

View File

@ -3781,7 +3781,8 @@ static Model LoadGLTF(const char *fileName)
int primitivesCount = 0;
for (unsigned int i = 0; i < data->meshes_count; i++) primitivesCount += (int)data->meshes[i].primitives_count;
for (unsigned int i = 0; i < data->meshes_count; i++)
primitivesCount += (int)data->meshes[i].primitives_count;
// Process glTF data and map to model
model.meshCount = primitivesCount;
@ -3793,7 +3794,8 @@ static Model LoadGLTF(const char *fileName)
model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo));
model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform));
for (int i = 0; i < model.meshCount; i++) model.meshes[i].vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
for (int i = 0; i < model.meshCount; i++)
model.meshes[i].vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
for (unsigned int j = 0; j < data->nodes_count; j++)
{
@ -3801,6 +3803,52 @@ static Model LoadGLTF(const char *fileName)
model.bones[j].parent = j != 0 ? data->nodes[j].parent - data->nodes : 0;
}
for (unsigned int i = 0; i < data->nodes_count; i++)
{
if(data->nodes[i].has_translation)
{
memcpy(&model.bindPose[i].translation, data->nodes[i].translation, 3 * sizeof(float));
}
else
{
model.bindPose[i].translation = Vector3Zero();
}
if(data->nodes[i].has_rotation)
{
memcpy(&model.bindPose[i].rotation, data->nodes[i].rotation, 4 * sizeof(float));
}
else
{
model.bindPose[i].rotation = QuaternionIdentity();
}
model.bindPose[i].rotation = QuaternionNormalize(model.bindPose[i].rotation);
if(data->nodes[i].has_scale)
{
memcpy(&model.bindPose[i].scale, data->nodes[i].scale, 3 * sizeof(float));
}
else
{
model.bindPose[i].scale = Vector3One();
}
}
for (int i = 0; i < model.boneCount; i++)
{
Transform* currentTransform = model.bindPose + i;
BoneInfo* currentBone = model.bones + i;
Transform* parentTransform = model.bindPose + currentBone->parent;
if (currentBone->parent >= 0)
{
currentTransform->rotation = QuaternionMultiply(parentTransform->rotation, currentTransform->rotation);
currentTransform->translation = Vector3RotateByQuaternion(currentTransform->translation, parentTransform->rotation);
currentTransform->translation = Vector3Add(currentTransform->translation, parentTransform->translation);
currentTransform->scale = Vector3Multiply(parentTransform->scale, parentTransform->scale);
}
}
for (int i = 0; i < model.materialCount - 1; i++)
{
model.materials[i] = LoadMaterialDefault();
@ -3881,18 +3929,22 @@ static Model LoadGLTF(const char *fileName)
{
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].vertexCount = (int)acc->count;
model.meshes[primitiveIndex].vertices = RL_MALLOC(model.meshes[primitiveIndex].vertexCount*3*sizeof(float));
model.meshes[primitiveIndex].animVertices = RL_MALLOC(model.meshes[primitiveIndex].vertexCount*3*sizeof(float));
int bufferSize = model.meshes[primitiveIndex].vertexCount * 3 * sizeof(float);
model.meshes[primitiveIndex].vertices = RL_MALLOC(bufferSize);
model.meshes[primitiveIndex].animVertices = RL_MALLOC(bufferSize);
LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].vertices)
LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].vertices);
memcpy(model.meshes[primitiveIndex].animVertices, model.meshes[primitiveIndex].vertices, bufferSize);
}
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal)
{
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].normals = RL_MALLOC(acc->count*3*sizeof(float));
model.meshes[primitiveIndex].animNormals = RL_MALLOC(acc->count*3*sizeof(float));
int bufferSize = acc->count*3*sizeof(float);
model.meshes[primitiveIndex].normals = RL_MALLOC(bufferSize);
model.meshes[primitiveIndex].animNormals = RL_MALLOC(bufferSize);
LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].normals)
LOAD_ACCESSOR(float, 3, acc, model.meshes[primitiveIndex].normals);
memcpy(model.meshes[primitiveIndex].animNormals, model.meshes[primitiveIndex].normals, bufferSize);
}
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord)
{