2016-03-10 5 views
0

У меня есть игрок в форме сферы, которая может свободно перемещаться по направлениям x и z. Игрокам текущая скорость сохраняется в векторе, который добавляется к позиции игроков на каждом кадре:Вращение матрицы в направлении вектора?

m_position += m_speed; 

У меня также есть матрица поворота, что я хотел бы, чтобы повернуть в направлении, перемещение игрока в (представьте, как мяч будет вращаться, если он скатится на пол). Вот короткое видео, чтобы помочь визуализировать проблему: http://imgur.com/YrTG2al

Обратите внимание на видео, когда я начинаю двигаться вверх и вниз (Z) в противоположность не влево и вправо (X) ось вращения больше не соответствует движению игрока.

Код, используемый для получения результатов:

glm::vec3 UP = glm::vec3(0, 1, 0); 
float rollSpeed = fabs(m_Speed.x + m_Speed.z); 
if (rollSpeed > 0.0f) { 
    m_RotationMatrix = glm::rotate(m_RotationMatrix, rollSpeed, glm::cross(UP, glm::normalize(m_Speed))); 
} 

благодарных за помощью

+0

вращения необходимы две вещи: ось вращения и направление вращения. Когда вы говорите «вращать матрицу в направлении вектора», возможно, вы имеете в виду поворот с вектором в качестве оси вращения? – user463035818

+0

@ tobi303 Возможно, мой вопрос был не очень ясен. В основном я пытаюсь выяснить правильную ось, которую нужно использовать при вращении матрицы, учитывая текущую скорость игроков. – bapibopi

+0

Возможно, небольшой чертеж может помочь проиллюстрировать проблему – user463035818

ответ

1

Ваше rollSpeed вычисления неправильно - например, если признаки m_Speed.x и m_Speed.z скоростей различны, то они будут вычитать. Вы должны использовать норму скорости в плоскости:

float rollSpeed = sqrt(m_Speed.x * m_Speed.x + m_Speed.y * m_Speed.y); 

Чтобы быть более общим об этом, вы можете повторно использовать перекрестный продукт вместо этого. Таким образом, ваша математика, менее вероятно, чтобы выйти из синхронизации - что-то вроде:

glm::vec3 rollAxis = glm::cross(UP, m_speed); 
float rollSpeed = glm::length(rollAxis); 
m_RotationMatrix = glm::rotate(m_RotationMatrix, rollSpeed, rollAxis); 
+0

Вы правы в том, что rollSpeed ​​вычисляется неправильно, хотя я думаю, что проблема, показанная мной в видео, заключается в вычислении rollAxis (cross (UP, m_Speed)). Возможно, «вверх» должно меняться в зависимости от текущего вращения сферы. – bapibopi

+1

. Вы не сказали, как вы используете матрицу, но, возможно, вы используете ее неправильно, обновляя матрицу с неправильного конца или что-то сравнимое. Проверьте свои предположения о своих системах координат; например, вам может потребоваться использовать инверсию 'm_RotationMatrix' для поворота вашей сферы. – comingstorm

+0

Обратный матрицы. Вот как я использую матрицу вращения: 'glm :: mat4 model; model = glm :: translate (model, m_Position) * glm :: inverse (m_RotationMatrix); // set модельная форма в шейдере – bapibopi

-1

Если я правильно понял, вам нужен поворот матрицы, которая будет работать в любом направлении оси (х, у, г).

Я думаю, вы должны написать rotate() метод на ось (х, у, г), а также вы должны указать направление, на котором ось очков направления, вы должны написать direction.x или direction.y или direction.z и матрица вращения будет понять, где вектор направления является точкой.

+0

Если я правильно вас понимаю (что очень сложно, пожалуйста, уважайте капитализацию и полные слова), вы предлагаете написать if-предложение для каждого направления. Это именно то, что делает вышеприведенный код, используя кросс-продукт, просто более общим образом, работая с произвольными направлениями в плоскости xz. – BDL

+0

Нет, нет, кто сказал, что если требуется условие?!выше кода делает только то, что говорит автор, когда он меняет векторный код направления, не работает. Я думаю, что он должен быть более конкретным для каждого направления оси, для которого направлен вектор направления. Это мое мнение. –

+0

@BDL «Я пробовал следующее, которое работает до тех пор, пока вы не попытаетесь двигаться в другом направлении от того, в котором вы ранее перемещались. (От x до z или наоборот)» Цитата от автора сообщения. –

0

rollSpeed должен быть размером вектора скорости.

float rollSpeed = glm::length(m_Speed); 

Преобразование матрицы предполагает угол. Угол поворота будет зависеть от размера вашего шара. Но сказать, что это радиус r то угол (в радианах), вам нужно

angle = rollSpeed/r;