[C ++] {DirectX 9}
TL; DR: Как мне преобразовать число с плавающей точкой, представляющее локальное вращение по оси X, в глобальный рыскание / тангаж / крен с использованием матриц?
Поэтому я пишу небольшую игру, в которой игрок представлен в виде топора. Вид игрока вращается горизонтально (вокруг оси Y) при движении мыши. [Вот] это скриншот, чтобы получить лучшую идею.
Поэтому я пытаюсь оживить топор, качающийся взад и вперед при удерживании мыши. В данный момент я сохраняю глобальную позицию и вращение игрока в классе Player как переменные (m_x, m_y, m_z, m_rotationX, m_rotationY, m_rotationZ).
Когда я рисую объект, я преобразую все эти координаты в глобальное пространство, чтобы создать мировую матрицу. Так что да, это глобальные координаты. m_rotationY изменяется в зависимости от движения мыши.
Это означает, что если я увеличиваю m_rotationX (т.е. на значение sin некоторого приращения анимации), объект поворачивается ГЛОБАЛЬНО, что означает, что если я смотрю влево или вправо, топор качается по экрану, а не от него.
Мой вопрос: какие матричные преобразования мне нужно будет сделать, чтобы преобразовать некоторые «локальные» значения вращения x в «глобальные» значения вращения x, y и z.
if(m_attacking)
{
m_attackAnimation += 0.1f;
float rotationAmount = sin(m_attackAnimation) * 0.1;
// How do I figure out m_rotationX, m_rotationY and m_rotationZ
// from rotationAmount here? :c
}
До сих пор я думал о том, чтобы создать X-матрицу вращения, а затем преобразовать какой-то вектор с использованием этого, но все мои эксперименты с этим были довольно неудачными.
Спасибо за ваше время: D
РЕДАКТИРОВАТЬ:
Больше диаграмм!
Это то, что происходит, когда я делаю m_rotationX = rotationAmount;
РЕДАКТИРОВАТЬ 2:
Итак, основываясь на ответе Федерико, я настроил следующий код:
// Get the local "right" vector
D3DXVECTOR3 right(1, 0, 0);
D3DXMATRIX rotationY;
D3DXMatrixRotationY(&rotationY, m_rotationY);
D3DXVec3TransformCoord(&right, &right, &rotationY);
// Calculate the theta value we want to rotate by
m_attackAnimation += 0.1f;
float rotationAmount = sin(m_attackAnimation) * 0.1;
//Cross product
D3DXVECTOR3 axis;
D3DXVECTOR3 up(0, 1, 0);
D3DXVec3Cross(&axis, &right, &up);
//Rotation matrix
D3DXMATRIX matrix;
D3DXMatrixRotationAxis(&matrix, &axis, rotationAmount);
Это ДОЛЖНО дать мне матрицу вращения, представляющую локальное вращение по оси X. Тем не менее, я, наверное, неправильно понял.
Независимо от того, как я могу вернуть это обратно в глобальные переменные вращения X, вращение Y и вращение Z
*Редактировать 3: *
Это моя попытка извлечь углы поворота из матрицы. К сожалению, результат полностью выключен. Топор просто исчезает из вида, и персонаж перемещается случайным образом.
float rotY = acosf(matrix._11);
float rotX = asinf(matrix._13 / sin(rotY));
float rotZ = acosf(matrix._21 / sin(rotX));
m_rotationX += rotX;
m_rotationY += rotY;
m_rotationZ += rotZ;
Математически это кажется мне правильным. Не уверен, куда идти отсюда.
Думаю, я просто попытаюсь реализовать это, используя только матрицы, как предложил Фредерико.
Если я понял, что вы пытаетесь сделать, это создаст матрицу, которая будет вращаться вокруг произвольной оси, в вашем случае ось — это перекрестное произведение между направлением и вектором вверх, то есть осью, направленной вправо (или влево). , зависит от системы координат и заказа продукта). Перекрестное произведение всегда возвращает вектор, перпендикулярный двум другим.
//Cross product
D3DXVECTOR3 axis;
D3DXVec3Cross(&axis, &direction, &up);
//Rotation matrix
D3DXMATRIX matrix;
D3DXMatrixRotationAxis(&matrix, &axis, rotationAmount);
Полученная матрица должна быть вашей матрицей вращения.
Посмотри на http://en.wikipedia.org/wiki/Euler_angles в разделе «Матрица вращения XYZ», если вы хотите вернуть углы поворота назад, но я предлагаю вам использовать встроенную матрицу и векторную операцию, заданную directx, для сохранения вашей позиции и поворота.
Это позволит вам легко вращать, переводить и масштабировать позиции и направления, используя матрицы, не заботясь о математике при каждой операции, и не вызывая блокировку gimabl (http://en.wikipedia.org/wiki/Gimbal_lock). Посмотри на http://msdn.microsoft.com/en-us/library/windows/desktop/bb205164(v=vs.85).aspx для математических операций directx или поиска других руководств действительно легко научиться справляться с ними.
Если вы хотите получить некоторую информацию по определенной математике или другим темам, связанным с игрой, я предлагаю вам прочитать «Архитектура игрового движка» Джейсона Грегори
Других решений пока нет …