How to calculate futur positions in world coordinates of each bones for a given animation

Hi,

I exported a model from Blender that I initially imported from mixamo.
I used the GLTFLoader to import it to my three.js scene.

The animation is just a running action. It works well, but I would like to make the character run through a certain distance. For example, n times the actual action.

I believe that I have to create new clips with the right keyframe tracks values and times but I don’t understand the values to do the right math.
Indeed, for each part of the body, I have the keyframes for the position, quaternion, and scale like that

“mixamorigHips.position”
“mixamorigHips.quaternion”
“mixamorigHips.scale”

“mixamorigSpine.position”
“mixamorigSpine.quaternion”
“mixamorigSpine.scale”

“mixamorigSpine1.position”
“mixamorigSpine1.quaternion”
“mixamorigSpine1.scale”

and so on…

I tried to understand the values by adding an arrowHelper at each time with (x,y,z) that I have from .position keyFrameTracks and then apply
the quaternion that I have from .quaternion keyFrameTracks but I have weird results.

I don’t take into account the .scale par as the values are always 1

Repo : GitHub - kasra0/threejs-animation

Could you please explain to me how to achieve what i want ?
Is it the right way of doing it ?

Thanks

I don’t understand the values of the keyframes,

mixamorigNeck.position

T X Y Z
0.033 0.000 15.033 0.793
0.067 0.000 15.033 0.793
0.100 0.000 15.032 0.793
0.133 0.000 15.033 0.793
0.167 0.000 15.033 0.793
0.200 0.000 15.032 0.793
0.233 0.000 15.033 0.793
0.267 0.000 15.033 0.793
0.300 0.000 15.033 0.793
0.333 0.000 15.033 0.793
0.367 0.000 15.032 0.793
0.400 0.000 15.032 0.793
0.433 0.000 15.033 0.793
0.467 0.000 15.033 0.793
0.500 0.000 15.033 0.793
0.533 0.000 15.032 0.793
0.567 0.000 15.033 0.793
0.600 0.000 15.032 0.793

mixamorigHead.position

T X Y Z
0.033 0.000 10.322 3.142
0.067 0.000 10.322 3.142
0.100 0.000 10.322 3.142
0.133 0.000 10.322 3.142
0.167 0.000 10.322 3.142
0.200 0.000 10.322 3.142
0.233 0.000 10.322 3.142
0.267 0.000 10.322 3.142
0.300 0.000 10.322 3.142
0.333 0.000 10.322 3.142
0.367 0.000 10.322 3.142
0.400 0.000 10.322 3.142
0.433 0.000 10.322 3.142
0.467 0.000 10.322 3.142
0.500 -0.000 10.322 3.142
0.533 0.000 10.322 3.142
0.567 0.000 10.322 3.142
0.600 0.000 10.322 3.142

mixamorigHips.position

T X Y Z
0.033 0.499 0.014 -89.754
0.067 0.284 22.579 -90.694
0.100 -0.076 43.528 -92.902
0.133 -0.316 63.690 -94.193
0.167 -0.442 83.187 -94.123
0.200 -0.433 102.799 -92.909
0.233 -0.244 122.130 -92.117
0.267 0.106 140.115 -90.748
0.300 0.211 161.983 -89.834
0.333 0.532 185.136 -90.239
0.367 1.027 207.264 -92.144
0.400 1.063 227.858 -93.944
0.433 0.996 248.332 -94.701
0.467 0.896 268.675 -93.863
0.500 0.866 288.691 -92.782
0.533 0.678 308.870 -91.577
0.567 0.594 328.728 -90.377
0.600 0.510 351.425 -89.771

how these values should be interpreted?
why the Y-Neck > Y-Head ?

thanks

The values represent represent coordinates in local space. When 3D objects are organized in a hierarchy (which is the case for skeletons), a direct comparison of such coordinates is meaningless.

If you are looking for values in world space, you have to transform the data into the respective coordinate system. You can get the position in world space via Object3D.localToWorld(). There is also a method for quaternions.

Hi,
thanks for your help !

I iterated over all the bones’ character, called localToWorld on each bone
and get the world position and put a little sphere as shown below.

Now i would like to calculate the futur positions of each keyPoints.
The hips are in RED and the Spine in Yellow

For the hips, i took the values of the “mixamorigHips.position” keyFrameTrack and apply .applyMatrix4(parent.matrix) ( parent.matrix is the character local matrix)
and i have the right result ( green dot ).

here is the begining of the bones’ hierarchy

character Object3D p: [0.000,0.000,0.000] q: [0.707,0.000,0.000,0.707]
.-mixamorigHips Bone p: [0.499,0.014,-89.754] q: [-0.650,-0.068,0.018,0.757]
…-mixamorigSpine Bone p: [0.000,9.923,-1.227] q: [0.081,0.088,0.042,0.992]
…-mixamorigSpine1 Bone p: [-0.000,11.645,-1.422] q: [-0.008,0.011,-0.003,1.000]

For the Spine i don’t know how to calculate it, could you please give me a numerical example?
thanks

I got the result that I want like so :

the important concept ( thanks to Mugen87 to put me in the right direction )
is to take into account the hierarchical set of interconnected bones of the skeleton
and apply the transformation recursively

the formula is :

const childPositionInLocalCoordinate = childRelativePositionInLocalCoordinate
.applyQuaternion(parentQuaternionInLocalCoordinate)
.add(parentRelativePositionInLocalCoordinate)

example: Calculation of the future position of the Spine1 at keyframe 1 of the animation “sprint-style50-speed70”

with hierarchical structure = Hips > Spine > Spine1

frame: 1 of sprint-style50-speed70 at mixamorigSpine :
[-0.000, 11.645, -1.422].applyQuaternion([0.037,0.119,0.027,0.992]) + [0.000 , 9.923 , -1.227] = [-0.865, 21.615, -1.680]

  • [-0.000, 11.645, -1.422] = Spine1PositionInLocalCoordinate
  • [0.037,0.119,0.027,0.992] = SpineQuaternionInLocalCoordinate
  • [0.000 , 9.923 , -1.227] = SpinePositionInLocalCoordinate

the same logic applies again a the Hips level …

frame: 1 of sprint-style50-speed70 at mixamorigHips

[-0.865, 21.615, -1.680].applyQuaternion([[-0.649,-0.054,0.024,0.759]]) + [0.284 , 22.579, -90.694] = [0.339 , 24.222, -112.329]

and then we have to apply the local transform matrix of the character on the final point :

const x = new THREE.Vector3(0.339 , 24.222, -112.329)

and finally the futur position of the Spine1 at frame 1 in the “sprint-style50-speed70” animation equal x.applyMatrix4(character.matrix)

some graphical examples of futur positions of bones ( all frames ) of “sprint-style50-speed70”

  • mixamorigSpine1_character
  • mixamorigRightShoulder_character
  • mixamorigLeftFoot_character
  • mixamorigLeftForeArm_character

thanks,
Kasra