Как стать автором
Обновить

О реализации перемещения камеры в трехмерном мире (OpenGL)

Сегодня я расскажу о том как писать управление камерой используя свой мозг и некоторые знания в OpenGL.

Камера


Для начала стоит выяснить что есть камера.
Камера — это плоская область некоторой формы на которую проецируется трехмерный мир. Обычно это прямоугольник размеров экрана вашего монитора.

Подходы


Есть несколько подходов относительно того как следует делать камеру. Я расскажу о 2-х способах. Но следует договориться о некоторых правилах перемещения в мире. Эти правила возникают всякий раз когда вы используете функции библиотеки GLUT в своем приложении, а именно glTranslate[f,d](x,y,z) glRotate[f,d](angle,x,y,z).
glTranslate[f,d](x,y,z) — перемножает матрицу моделирования на некоторые коэффициенты, переносящие последующие объекты на x, y. z относительно предыдущей матрицы.

glRotate[f,d](angle,x,y,z) — также перемножает матрицу моделирования на коэффициенты, поворачивающие все последующие за этой командой объекты на угол angle (в градусах) относительно вектора (x, y, x).

При использовании данных команд возникает не очень хорошая ситуация.
Представим что в центре координат находиться человек, каждый его ход начинается с этой точки. Ходом назовем перемещение его в некоторую точку и поворот на некоторый угол. Задачей человека является сымитировать для наблюдателя свое движение по координатной сетке. Первым делом напрашивается вопрос: «В чем проблема то? Человек каждый раз перемещается в нужную точку и поворачивается на некоторый угол». Но в этом то и дело что не все так просто. Взгляните на картинку:
image
Видно, что если делать всегда переносы а потом повороты — то мы не сдвинемся с оси, а если делать поворот и перенос — то движение будет или по кругу или по спирали.

1-е решение

Будем запоминать координаты предыдущей точки. Каждая следующая точка — предыдущая точка плюс проекция отрезка (шага из старой точки в новую) на соответствующие оси.
В чем недостаток? Недостаток в основном заключается в том, что операции вычисления синуса или косинуса — довольно трудоемки. А в остальном все работает правильно.
2-е решение

Здесь будем запоминать модельную матрицу местоположения предыдущей точки. Это мне напоминает то, как происходит в мире — каждый шаг происходит из предыдущей точки, а не из начала координат. Что для этого нужно: нужно хранить в памяти отдельные преобразования и менять их по мере движения, не затрагивая внешние объекты. Это довольно сложно. Но если немного подумать — решаемо. Для этого в OpenGL были предусмотрены функции glLoadIdentity() glLoadMatrix(*array) glMultMatrix(*array).glPushMatrix() glPopMatrix().

glLoadIdentity() — обнуляет все наши переносы, перенося строительство последующих объектов в глобальный центр координат.

glLoadMatrix(*array) — заменят текущую матрицу на матрицу из массива 4х4.

glMultMatrix(*array) — умножаеттекущую матрицу на матрицу, содержащуюся в массиве array опять таки размерности 4х4 (следует заметить, что в массив 4х4 строкам соотв. столбцы матрицы).

glPushMatrix() — добавляет в стек текущую матрицу.
glPopMatrix() — изымает из стека верхнюю матрицу, таким образом мы возвращаемся к позиции до glPushMatrix().
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.