[英]Rotate the root of a BVH animation around Y axis by an angle
即使您不熟悉 BVH 文件格式,也許您可以幫助我了解如何組合兩個旋轉。
我只是從 BVH 文件中獲取根的旋轉(復制 x、y、z 值),根的通道設置如下:
CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
我想將根旋轉一定程度,可以是 0 到 360,圍繞 y 軸 (0,1,0)。 這種旋轉適用於某些幀。 然而,在大多數幀中,根旋轉得很奇怪(就像發生了萬向節鎖定)。
這是我使用的代碼。 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
與Quaternion.Euler(rotationFromBvh)
具有完全相同的 euler x,y,z 結果
// [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 文件 ok。
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();
}
我說您有充分的理由按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);
從物理上講,四元數乘法意味着從右向左旋轉。
q1 * q2 表示旋轉 q2 然后 q1
所以如果你想一個接一個地應用旋轉,把它放在左邊。
在你的情況下,它應該是:
Quaternion qAfter = YawRotationQuaternion * qBefore;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.