I'm trying to parse the bvh data to my skeleton I already developed with OpenGL. There is one thing regarding data parsing I got curious about though.
Bvh data has two parts, which are HIERARCHY and MOTION. HIERARCHY specifies the tree structure and the OFFSET data, which is used to infer the length of the parent bone. MOTION specifies the position of the root bone and the joint configurations of every bone.
I already made my model with the bones that were mentioned in HIERARCHY. I made my model under the same tree structure mentioned in HIERARCHY as well. (Of course the length between the bones is arbitrarily set by me since the model is made before parsing the file data. So the modeled bone's length is actually a bit different from the OFFSET data.)
Since I already made the model that I want to be animated, does that mean I can ignore the HIERARCHY(=OFFSET) part, and just read the MOTION data part for obtaining each joint's joint configuration?
I feel like this is a really obvious question, but something just feels wrong because that just means I can ignore the first half(HIERARCHY) of the file, and just make a parser for the second half of it.
Is there any detail that I am possibly missing from the first half of the file? Any help would be appreciated. Thanks in advance!
BVH HIERARCHY
contains initial pose of the skeleton (without any MOTION
data). So the OFFSET
actually define the initial orientation of each bone too. If you ignore it you will lose sync between BVH and your mesh. What you need to do is:
- parse whole
HIERARCHY
structure
for each bone compute transform with scale that aligns your mesh to BVH initial position
this is not as easy as it sounds as you got two endpoints for each bone in BVH. But for correct position of mesh is that not enough as its missing the rotation around bone axis. Scale is simple ratio between BVH bone and mesh bone size.
What you need is to construct 4x4 homogenuous matrices. Here some ideas on how:
- Understanding 4x4 homogenous transform
- How to find rotation matrix between two vectors in THREE.js
- Problem superimposing and aligning 3D triangles
parse whole MOTION
data
for each frame
compute transform matrices of reach bone and apply it on your mesh (together with the initial position matrices).
I strongly suggest parse/play BVH without any mesh using just lines. And move to the next level only if it is working correctly. Because depending on used notations matrix multiplication order and coordinate systems you might have corrupted output. Which would give you hard time debugging the stuff on top of it.
Beware the rotations must be done in defined order and without any offset !!!
[edit1]
Here some small BVH example:
HIERARCHY
ROOT Hips
{
OFFSET 0.00 0.00 0.00
CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
JOINT Chest
{
OFFSET 0.00 5.21 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT Neck
{
OFFSET 0.00 18.65 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT Head
{
OFFSET 0.00 5.45 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
End Site
{
OFFSET 0.00 3.87 0.00
}
}
}
JOINT LeftCollar
{
OFFSET 1.12 16.23 1.87
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT LeftUpArm
{
OFFSET 5.54 0.00 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT LeftLowArm
{
OFFSET 0.00 -11.96 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT LeftHand
{
OFFSET 0.00 -9.93 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
End Site
{
OFFSET 0.00 -7.00 0.00
}
}
}
}
}
JOINT RightCollar
{
OFFSET -1.12 16.23 1.87
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT RightUpArm
{
OFFSET -6.07 0.00 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT RightLowArm
{
OFFSET 0.00 -11.82 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT RightHand
{
OFFSET 0.00 -10.65 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
End Site
{
OFFSET 0.00 -7.00 0.00
}
}
}
}
}
}
JOINT LeftUpLeg
{
OFFSET 3.91 0.00 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT LeftLowLeg
{
OFFSET 0.00 -18.34 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT LeftFoot
{
OFFSET 0.00 -17.37 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
End Site
{
OFFSET 0.00 -3.46 0.00
}
}
}
}
JOINT RightUpLeg
{
OFFSET -3.91 0.00 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT RightLowLeg
{
OFFSET 0.00 -17.63 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
JOINT RightFoot
{
OFFSET 0.00 -17.14 0.00
CHANNELS 3 Zrotation Xrotation Yrotation
End Site
{
OFFSET 0.00 -3.75 0.00
}
}
}
}
}
MOTION
Frames: 2
Frame Time: 0.033333
8.03 35.01 88.36 -3.41 14.78 -164.35 13.09 40.30 -24.60 7.88 43.80 0.00 -3.61 -41.45 5.82 10.08 0.00 10.21 97.95 -23.53 -2.14 -101.86 -80.77 -98.91 0.69 0.03 0.00 -14.04 0.00 -10.50 -85.52 -13.72 -102.93 61.91 -61.18 65.18 -1.57 0.69 0.02 15.00 22.78 -5.92 14.93 49.99 6.60 0.00 -1.14 0.00 -16.58 -10.51 -3.11 15.38 52.66 -21.80 0.00 -23.95 0.00
7.81 35.10 86.47 -3.78 12.94 -166.97 12.64 42.57 -22.34 7.67 43.61 0.00 -4.23 -41.41 4.89 19.10 0.00 4.16 93.12 -9.69 -9.43 132.67 -81.86 136.80 0.70 0.37 0.00 -8.62 0.00 -21.82 -87.31 -27.57 -100.09 56.17 -61.56 58.72 -1.63 0.95 0.03 13.16 15.44 -3.56 7.97 59.29 4.97 0.00 1.64 0.00 -17.18 -10.02 -3.08 13.56 53.38 -18.07 0.00 -25.93 0.00
And here preview:
on the left is skelet without applying MOTION
data (pure offsets) as you can see its not axis aligned (but its not far from it) the bones are not in the same plane and are rotated a bit. But you need to take into account that the initial configuration and pose can be anything.
On the right is preview with applied first frame transforms from MOTION
data.