@ -3719,11 +3719,11 @@ static Model LoadGLTF(const char *fileName)
model . boneCount = ( int ) data - > nodes_count ;
model . bones = RL_CALLOC ( model . boneCount , sizeof ( BoneInfo ) ) ;
model . bindPose = RL_CALLOC ( model . boneCount , sizeof ( Transform ) ) ;
for ( unsigned int j = 0 ; j < data - > nodes_count ; j + + )
{
strcpy ( model . bones [ j ] . name , data - > nodes [ j ] . name = = 0 ? " ANIMJOINT " : data - > nodes [ j ] . name ) ;
model . bones [ j ] . parent = ( kt">int ) ( ( j ! = 0 & & data - > nodes [ j ] . parent ! = NULL ) ? data - > nodes [ j ] . parent - data - > nodes : mi">0 ) ;
model . bones [ j ] . parent = ( data - > nodes [ j ] . parent ! = NULL ) ? data - > nodes [ j ] . parent - data - > nodes : o">- 1 ;
}
for ( unsigned int i = 0 ; i < data - > nodes_count ; i + + )
@ -3739,22 +3739,41 @@ static Model LoadGLTF(const char *fileName)
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 ;
int root = currentBone - > parent ;
if ( root > = model . boneCount ) root = 0 ;
Transform * parentTransform = model . bindPose + root ;
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 ) ;
bool * completedBones = RL_CALLOC ( model . boneCount , sizeof ( bool ) ) ;
int numberCompletedBones = 0 ;
while ( numberCompletedBones < model . boneCount ) {
for ( int i = 0 ; i < model . boneCount ; i + + )
{
if ( completedBones [ i ] ) continue ;
if ( model . bones [ i ] . parent < 0 ) {
completedBones [ i ] = true ;
numberCompletedBones + + ;
continue ;
}
if ( ! completedBones [ model . bones [ i ] . parent ] ) continue ;
Transform * currentTransform = & model . bindPose [ i ] ;
BoneInfo * currentBone = & model . bones [ i ] ;
int root = currentBone - > parent ;
if ( root > = model . boneCount )
root = 0 ;
Transform * parentTransform = & model . bindPose [ root ] ;
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 ) ;
completedBones [ i ] = true ;
numberCompletedBones + + ;
}
}
RL_FREE ( completedBones ) ;
}
for ( int i = 0 ; i < model . materialCount - 1 ; i + + )
@ -3879,7 +3898,28 @@ static Model LoadGLTF(const char *fileName)
short * bones = RL_MALLOC ( sizeof ( short ) * acc - > count * 4 ) ;
LOAD_ACCESSOR ( short , 4 , acc , bones ) ;
for ( unsigned int a = 0 ; a < acc - > count * 4 ; a + + )
for ( unsigned int a = 0 ; a < acc - > count * 4 ; a + + )
{
cgltf_node * skinJoint = data - > skins - > joints [ bones [ a ] ] ;
for ( unsigned int k = 0 ; k < data - > nodes_count ; k + + )
{
if ( & ( data - > nodes [ k ] ) = = skinJoint )
{
model . meshes [ primitiveIndex ] . boneIds [ a ] = k ;
break ;
}
}
}
RL_FREE ( bones ) ;
}
else if ( acc - > component_type = = cgltf_component_type_r_8u )
{
model . meshes [ primitiveIndex ] . boneIds = RL_MALLOC ( sizeof ( int ) * acc - > count * 4 ) ;
unsigned char * bones = RL_MALLOC ( sizeof ( unsigned char ) * acc - > count * 4 ) ;
LOAD_ACCESSOR ( unsigned char , 4 , acc , bones ) ;
for ( unsigned int a = 0 ; a < acc - > count * 4 ; a + + )
{
cgltf_node * skinJoint = data - > skins - > joints [ bones [ a ] ] ;
@ -4009,6 +4049,9 @@ static ModelAnimation* LoadGLTFModelAnimations(const char *fileName, int *animCo
{
TRACELOG ( LOG_INFO , " MODEL: [%s] glTF animations (%s) count: %i " , fileName , ( data - > file_type = = 2 ) ? " glb " :
" gltf " , data - > animations_count ) ;
result = cgltf_load_buffers ( & options , data , fileName ) ;
if ( result ! = cgltf_result_success ) TRACELOG ( LOG_WARNING , " MODEL: [%s] unable to load glTF animations data " , fileName ) ;
animations = RL_MALLOC ( data - > animations_count * sizeof ( ModelAnimation ) ) ;
@ -4054,7 +4097,7 @@ static ModelAnimation* LoadGLTFModelAnimations(const char *fileName, int *animCo
for ( unsigned int j = 0 ; j < data - > nodes_count ; j + + )
{
strcpy ( output - > bones [ j ] . name , data - > nodes [ j ] . name = = 0 ? " ANIMJOINT " : data - > nodes [ j ] . name ) ;
output - > bones [ j ] . parent = j ! = mi">0 ? ( int ) ( data - > nodes [ j ] . parent - data - > nodes ) : mi">0 ;
output - > bones [ j ] . parent = p">( data - > nodes [ j ] . parent ! = nb">NULL ) ? ( int ) ( data - > nodes [ j ] . parent - data - > nodes ) : o">- 1 ;
}
/ / Allocate data for frames
@ -4099,11 +4142,11 @@ static ModelAnimation* LoadGLTFModelAnimations(const char *fileName, int *animCo
if ( frameTime < inputFrameTime )
{
shouldSkipFurtherTransformation = false ;
outputMin = j - 1 ;
outputMin = p">( j = = 0 ) ? 0 : j - 1 ;
outputMax = j ;
float previousInputTime = 0.0f ;
if ( GltfReadFloat ( sampler - > input , j - 1 , ( float * ) & previousInputTime , 1 ) )
if ( GltfReadFloat ( sampler - > input , outputMin , ( float * ) & previousInputTime , 1 ) )
{
lerpPercent = ( frameTime - previousInputTime ) / ( inputFrameTime - previousInputTime ) ;
}
@ -4163,16 +4206,32 @@ static ModelAnimation* LoadGLTFModelAnimations(const char *fileName, int *animCo
/ / Build frameposes
for ( int frame = 0 ; frame < output - > frameCount ; frame + + )
{
for ( int i = 0 ; i < output - > boneCount ; i + + )
{
if ( output - > bones [ i ] . parent > = 0 )
bool * completedBones = RL_CALLOC ( output - > boneCount , sizeof ( bool ) ) ;
int numberCompletedBones = 0 ;
while ( numberCompletedBones < output - > boneCount ) {
for ( int i = 0 ; i < output - > boneCount ; i + + )
{
if ( completedBones [ i ] ) continue ;
if ( output - > bones [ i ] . parent < 0 ) {
completedBones [ i ] = true ;
numberCompletedBones + + ;
continue ;
}
if ( ! completedBones [ output - > bones [ i ] . parent ] ) continue ;
output - > framePoses [ frame ] [ i ] . rotation = QuaternionMultiply ( output - > framePoses [ frame ] [ output - > bones [ i ] . parent ] . rotation , output - > framePoses [ frame ] [ i ] . rotation ) ;
output - > framePoses [ frame ] [ i ] . translation = Vector3RotateByQuaternion ( output - > framePoses [ frame ] [ i ] . translation , output - > framePoses [ frame ] [ output - > bones [ i ] . parent ] . rotation ) ;
output - > framePoses [ frame ] [ i ] . translation = Vector3Add ( output - > framePoses [ frame ] [ i ] . translation , output - > framePoses [ frame ] [ output - > bones [ i ] . parent ] . translation ) ;
output - > framePoses [ frame ] [ i ] . scale = Vector3Multiply ( output - > framePoses [ frame ] [ i ] . scale , output - > framePoses [ frame ] [ output - > bones [ i ] . parent ] . scale ) ;
completedBones [ i ] = true ;
numberCompletedBones + + ;
}
}
RL_FREE ( completedBones ) ;
}
}