即使您不熟悉BVH文件格式,也许您也可以帮助我组合两个旋转方式。
我只是从BVH文件中获取根的旋转(复制x,y,z值),如下所示设置根的通道:
CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
我想绕y轴(0,1,0)将根旋转一定程度,可以是0到360。此旋转在某些帧上有效。但是,在大多数帧中,根部旋转得很奇怪(就像发生了万向节锁定一样)。
这是我使用的代码。 Unity中的C#。我只想正确地应用根的绕y轴的旋转。
当绕y轴旋转0度时,我可以确认代码工作正常(正确的BVH动画)。因此,错误必须是这两个旋转(qBefore和YawRotationQuaternion)的组合。
private Vector3 getFinalRootRotation(Vector3 rotationFromBvh, float angle)
{
// [INITIALIZE]: Convert Euler to Quaternion for each axis.
Quaternion qX = Quaternion.AngleAxis(rotationFromBvh.x, Vector3.right);
Quaternion qY = Quaternion.AngleAxis(rotationFromBvh.y, Vector3.up);
Quaternion qZ = Quaternion.AngleAxis(rotationFromBvh.z, Vector3.forward);
Quaternion qBefore = qY * qX * qZ; // Multiply them in the correct order.
// Order in BVH file is ZXY.
qY*qX*qZ
与欧拉x,y,z结果相同与Quaternion.Euler(rotationFromBvh)
// [CREATE ROTATION AROUND Y]: Get the quaternion of rotating around y axis.
Quaternion YawRotationQuaternion = Quaternion.AngleAxis(angle, Vector3.up);
// [APPLY ROTATION AROUND Y]
Quaternion qAfter = qBefore * YawRotationQuaternion;
// [RETURN IN XYZ FORM]
return qAfter.eulerAngles;
}
我的目标是创建一个具有新根旋转的新BVH。这是我在文件中写入新旋转的代码的一部分。此代码已经过测试,可以创建BVH文件。
private string CreateMLine(Vector3 rootPosition, Vector3 rootRotation, List<Vector3> rotations)
{
StringBuilder s = new StringBuilder();
// Apply root's translation and rotation.
s.Append(rootPosition.x + " " + rootPosition.y + " " + rootPosition.z + " ");
s.Append(rootRotation.z + " " + rootRotation.x + " " + rootRotation.y + " ");
for(int i=1; i<rotations.Count; i++) // start at 1 ==> skip rotation of the root.
{
s.Append(rotations[i].z + " " + rotations[i].x + " " + rotations[i].y + " ");
}
s.Append("\n");
return s.ToString();
}
答案 0 :(得分:0)
我说您有充分的理由按Zrotation Xrotation Yrotation
的顺序获得BVH的值。
围绕z轴旋转euler.z度,围绕x轴旋转euler.x度和围绕y轴旋转euler.y度的旋转(按此顺序)。
所以我认为错误在于
Quaternion qBefore = qY * qX * qZ;
使用错误的顺序。
它应该是
Quaternion qBefore = qZ * qX * qY;
我建议改用Quaternion.Euler
返回围绕z轴旋转z度,围绕x轴旋转x度和围绕y轴旋转y度的旋转。
Quaternion qBefore = Quaternion.Euler(rotationFromBvh.x, rotationFromBvh.y, rotationFromBvh.z);