簡體   English   中英

將 BVH animation 的根繞 Y 軸旋轉一個角度

[英]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*qZQuaternion.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的值。

Quaternion.eulerAngles

圍繞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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM