2010-08-03 3 views
0

Я настоящий нуб, который только начал изучать 3d-программирование, и мне очень сложно узнать о повороте в 3D-пространстве. Моя проблема в том, что я не могу понять, как вращать объект, используя его локальные координаты.Проблемы с вращением OpenGL-OpenTK

У меня есть базовый класс для 3D-объектов, и для начала я хочу реализовать функции, которые будут вращать объект на определенной оси с помощью x градусов. До сих пор у меня есть следующее:

public void RollDeg(float angle) 
    { 
     this.rotation = Matrix4.Mult(rotation, 
      Matrix4.CreateRotationX(MyMath.Conversions.DegToRad(angle))); 
    } 

    public void PitchDeg(float angle) 
    { 
     this.rotation = Matrix4.Mult(rotation, 
      Matrix4.CreateRotationY(MyMath.Conversions.DegToRad(angle))); 
    } 

    public void YawDeg(float angle) 
    { 
     this.rotation = Matrix4.Mult(rotation, 
      Matrix4.CreateRotationZ(MyMath.Conversions.DegToRad(angle))); 
    } 

«вращение» - это матрица 4x4, которая начинается как единичная матрица. Каждый раз, когда я хочу катить/шагать/рычать объект, я вызываю одну из вышеперечисленных функций.

Для рисования я использую другую функцию, которая подталкивает матрицу к стеклу ModelView, умножает ее на матрицы преобразования, вращения и масштабирования объекта (в этом порядке) и начинает рисовать вершины. Конечно, я вытащил матрицу из стека.

проблема заключается в том, что функции, указанные выше, вращают объект на оси GLOBAL, а не на LOCAL, даже если, по моему мнению, каждый раз, когда вы поворачиваете объект, локальная система меняет свою ось, а затем, когда новое вращение применяется поверх других, для новой используется локальная ось.

Я читал разные учебники о математике за ней и о том, как вращать объекты, но я не мог найти один, который мог бы мне помочь.

Если у кого есть время, я был бы очень признателен, если бы он мог помочь мне понять, КАК вращаться вокруг локальной оси и, возможно, даже более важно, что я сделал не так в моей текущей реализации.

+0

Это просто [Gimbal lock] (http://en.wikipedia.org/wiki/Gimbal_lock)? [Quaternions] (http://en.wikipedia.org/wiki/Quaternion) намного веселее :) – sje397

+0

@ sje377: nop, а не Gimbal. Каждое вращение делается глобально, вот в чем проблема, я не говорю о перекрывающейся оси. @ Calvin1602: Я знаю, и это то, что меня больше всего раздражает: я не могу понять, что мне не хватает. не использовал отладчик. Возможно, я должен опубликовать/прикрепить весь класс? может ли проблема быть скрыта где-то в другом месте? – cantrem

+0

Извините, неверный комментарий, см. Ответ. Но замечание об отладчике все еще держится: используйте его – Calvin1602

ответ

1

Если вы хотите выполнить свои преобразования в следующем порядке: перевод -> вращение -> масштаб (что имеет смысл, это то, что требуется обычно), вам нужно умножить свои матрицы в обратном порядке.

В правой системе координат (т. Е. Используется один openGL), умножение матрицы должно выполняться справа налево. Вот почему:

ModelViewTransform = Transform * View * Model // < - вы начинаете с модели, не так ли? так это так

Обратите внимание, что в directX они используют левую систему координат. У него есть свои недостатки, но это более интуитивно.

+0

oook, так: есть средний, есть глупый, есть очень глупый, есть глупость, есть и я: Мне пришлось увидеть правую систему координат для в тысячный раз (спасибо calvin), чтобы подумать об изменении порядка умножения матриц вращения. проблема заключалась в том, что я умножил «old * new» вместо «new * old». и я имел эту надоедливую проблему с преобразованиями RTS и решил ее, даже с порядком x/y/z и решил ее. я просто не могу перестать удивлять себя: | Еще раз спасибо! – cantrem

Смежные вопросы