Повернуть корень анимации BVH вокруг оси Y на угол - PullRequest
0 голосов
/ 11 февраля 2019

Даже если вы не знакомы с форматом файла BVH, возможно, вы могли бы помочь мне с тем, как объединить два поворота.

Я просто беру поворот корня (копируя x, y,z значения) из файла BVH, что каналы корня, как установлено так:

CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation

И я хочу повернуть корень на несколько градусов может быть от 0 до 360, вокругось у (0,1,0).Это вращение работает в некоторых кадрах.Тем не менее, в большинстве фреймов корень поворачивается странным образом (это похоже на блокировку карданного подвеса).

Это код, который я использую.C # в Unity.Я просто хочу правильно применить поворот корня вокруг оси y.

Я могу подтвердить, что код работает нормально (правильная анимация BVH) при добавлении вращения на 0 градусов вокруг оси y.Таким образом, ошибка должна быть в комбинации этих двух вращений (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 результаты as 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();
}

1 Ответ

0 голосов
/ 11 февраля 2019

Я бы сказал, что вы получаете значения BVH в порядке Zrotation Xrotation Yrotation по уважительной причине.

От Quaternion.eulerAngles :

Вращение, которое вращает euler.z градусов вокруг оси z, euler.x градусов вокруг оси x и euler.y градусов вокруг оси y (в таком порядке) .

Так что я думаю, что ошибка заключается в

Quaternion qBefore = qY * qX * qZ;

, который использует неправильный порядок.


скорее это должно быть

Quaternion qBefore = qZ * qX * qY;

Я бы посоветовал использовать Quaternion.Euler вместо

Возвращает поворот, который поворачивает z градусов вокруг оси z, x градусов вокруг оси x,и у градусов вокруг оси у.

Quaternion qBefore = Quaternion.Euler(rotationFromBvh.x, rotationFromBvh.y, rotationFromBvh.z);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...