如何将 bvh 文件解析为 OpenGL 制作的骨架模型?
How to parse a bvh file to a skeleton model made in OpenGL?
我正在尝试将 bvh 数据解析为我已经使用 OpenGL 开发的骨架。关于数据解析,有一件事我很好奇。
Bvh数据有两部分,分别是HIERARCHY和MOTION。 HIERARCHY 指定树结构和 OFFSET 数据,用于推断父骨骼的长度。 MOTION 指定根骨骼的位置和每个骨骼的关节配置。
我已经用 HIERARCHY 中提到的骨骼制作了我的模型。我也在 HIERARCHY 中提到的相同树结构下制作了我的模型。 (当然骨骼之间的长度是我随意设置的,因为模型是在解析文件数据之前制作的。所以模型骨骼的长度实际上与OFFSET数据有点不同。)
既然我已经制作了要动画的模型,那是否意味着我可以忽略HIERARCHY(=OFFSET)部分,而只读取MOTION数据部分以获得每个关节的关节配置?
我觉得这是一个非常明显的问题,但感觉有些不对劲,因为这只是意味着我可以忽略文件的前半部分 (HIERARCHY),而只为后半部分创建一个解析器。
文件的前半部分是否有我可能遗漏的任何细节?
BVH HIERARCHY
包含骨架的初始姿势(没有任何 MOTION
数据)。所以 OFFSET
实际上也定义了每个骨骼的初始方向。如果你忽略它,你将失去 BVH 和你的网格之间的同步。您需要做的是:
- 解析整个
HIERARCHY
结构
每个骨骼计算变换的比例使您的网格与 BVH 初始位置对齐
这并不像听起来那么容易,因为您在 BVH 中为每个骨骼设置了两个端点。但是对于网格的正确位置来说还不够,因为它缺少围绕骨骼轴的旋转。比例是 BVH 骨骼和网格骨骼大小之间的简单比率。
你需要的是构建 4x4 齐次矩阵。这里有一些关于如何做的想法:
- How to find rotation matrix between two vectors in THREE.js
- Problem superimposing and aligning 3D triangles
解析整个MOTION
数据
每帧
计算到达骨骼的变换矩阵并将其应用于您的网格(连同初始位置矩阵)。
我强烈建议 parse/play BVH 没有任何网格,只使用线条。并且只有在它正常工作时才能进入下一个级别。因为根据使用的符号矩阵乘法顺序和坐标系,您可能会损坏输出。这会让你很难调试它上面的东西。
注意旋转必须按照定义的顺序进行并且没有任何偏移!!!
[edit1]
这里有一些 BVH 的小例子:
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
此处预览:
左边是没有应用 MOTION
数据(纯偏移)的骨架,因为你可以看到它没有轴对齐(但离它不远)骨骼不在同一平面上并且旋转了一个少量。但是你需要考虑到初始配置和姿势可以是任何东西。
右侧是应用 MOTION
数据的第一帧变换后的预览。
另见:
我正在尝试将 bvh 数据解析为我已经使用 OpenGL 开发的骨架。关于数据解析,有一件事我很好奇。
Bvh数据有两部分,分别是HIERARCHY和MOTION。 HIERARCHY 指定树结构和 OFFSET 数据,用于推断父骨骼的长度。 MOTION 指定根骨骼的位置和每个骨骼的关节配置。
我已经用 HIERARCHY 中提到的骨骼制作了我的模型。我也在 HIERARCHY 中提到的相同树结构下制作了我的模型。 (当然骨骼之间的长度是我随意设置的,因为模型是在解析文件数据之前制作的。所以模型骨骼的长度实际上与OFFSET数据有点不同。)
既然我已经制作了要动画的模型,那是否意味着我可以忽略HIERARCHY(=OFFSET)部分,而只读取MOTION数据部分以获得每个关节的关节配置?
我觉得这是一个非常明显的问题,但感觉有些不对劲,因为这只是意味着我可以忽略文件的前半部分 (HIERARCHY),而只为后半部分创建一个解析器。
文件的前半部分是否有我可能遗漏的任何细节?
BVH HIERARCHY
包含骨架的初始姿势(没有任何 MOTION
数据)。所以 OFFSET
实际上也定义了每个骨骼的初始方向。如果你忽略它,你将失去 BVH 和你的网格之间的同步。您需要做的是:
- 解析整个
HIERARCHY
结构 每个骨骼计算变换的比例使您的网格与 BVH 初始位置对齐
这并不像听起来那么容易,因为您在 BVH 中为每个骨骼设置了两个端点。但是对于网格的正确位置来说还不够,因为它缺少围绕骨骼轴的旋转。比例是 BVH 骨骼和网格骨骼大小之间的简单比率。
你需要的是构建 4x4 齐次矩阵。这里有一些关于如何做的想法:
- How to find rotation matrix between two vectors in THREE.js
- Problem superimposing and aligning 3D triangles
解析整个
MOTION
数据每帧
计算到达骨骼的变换矩阵并将其应用于您的网格(连同初始位置矩阵)。
我强烈建议 parse/play BVH 没有任何网格,只使用线条。并且只有在它正常工作时才能进入下一个级别。因为根据使用的符号矩阵乘法顺序和坐标系,您可能会损坏输出。这会让你很难调试它上面的东西。
注意旋转必须按照定义的顺序进行并且没有任何偏移!!!
[edit1]
这里有一些 BVH 的小例子:
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
此处预览:
左边是没有应用 MOTION
数据(纯偏移)的骨架,因为你可以看到它没有轴对齐(但离它不远)骨骼不在同一平面上并且旋转了一个少量。但是你需要考虑到初始配置和姿势可以是任何东西。
右侧是应用 MOTION
数据的第一帧变换后的预览。
另见: