Noxilie
futurum est iam
В DirectX для операций с камерой существует специальная матрица - VIEW. Состоит она из трех векторов Right (право, оно же X), Up (вверх, оно же Y) и Look (взгляд, оно же Z) и, собственно, координат камеры, которые тоже в общем-то можно рассматривать как вектор, кому как нравится.


единичная view матрица типа D3DMATRIX
имет вид:
D3DMATRIX ourmatrix = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};

к элементам матрицы можно обратиться как ourmatrix.m[i][j]
где:
m[0][0] - x координата вектора Right
m[0][1] - y координата вектора Right
m[0][2] - z координата вектора Right

m[1][0] - x координата вектора Up
m[1][1] - y координата вектора Up
m[1][2] - z координата вектора Up

m[2][0] - x координата вектора Look
m[2][1] - y координата вектора Look
m[2][2] - z координата вектора Look

m[3][0] - отрицательное значение скалярного произведения координат камеры и вектора Right
m[3][1] - отрицательное значение скалярного произведения координат камеры и вектора Up
m[3][2] - отрицательное значение скалярного произведения координат камеры и вектора Look



векторная математика(для тех, кто забыл ;) )...
скалярное произведение двух векторов вычисляется по формуле:
x1*x2+y1*y2+z1*z2

векторное произведение (суть третий вектор, ортогональный двум предыдущим):
x3=y1*z2-z1*y2;
y3=z1*x2-x1*z2;
z3=x1*y2-y1*x2;
направление нового вектора зависит от порядка перемножения(!!!)

нормализация(приведение длины вектора к единичной):
x2=x1/длину вектора
y2=y1/длину вектора
z2=z1/длину вектора
где длина равна квадратному корню из суммы квадратов координат



Вращение:
Задача поворота камеры вокруг некоторой оси сводится к повороту двух векторов вокруг этой оси. Предположим, мы поворачиваем камеру вокруг оси Y (для нашей камеры её будет представлять вектор Up), банальный поворот влево/вправо. Итак, с вектором Up мы ничегошеньки не делаем, он у нас неподвижен, нам остается только пересчитать координаты векторов Look и Right, и вуаля, камера повернута :)

Новый вектор Look мы представим как сумму вектора right и старого look, выглядеть это будет так:
lx=rx*sn+lx*cs;
ly=ry*sn+ly*cs;
lz=rz*sn+lz*cs;

где:
lx, ly, lz - координаты look вектора
rx, ry, rz - координаты right вектора
sn и cs - синус и косинус угла поворота

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

Теперь осталось повернуть второй вектор, вектор Right. Это можно сделать выразив его, как сумму старого Right и старого look векторов, а можно как векторное произведение Up и нового Look. Выбор за вами. После чего, опять-таки, надо будет произвести нормализацию свеженайденного вектора.



Перемещение:
Конечно, рассматривать мир вращая камеру - здорово, но хотелось бы еще и перемещаться по этому миру,
ведь так?) Таки нет ничего проще!

Допустим, мы хотим пододвинуть камеру вперед. Для этого нужно пододвинуть позицию камеры по Look вектору. Т.е.:
cpx+=lx*points;
cpy+=ly*points;
cpz+=lz*points;

где:
сpx, cpy, cpz - координаты камеры
lx, ly, lz - координаты вектора Look
points - длина на которую перемещаем камеру



Вращение вокруг точки:
В большинстве современных rpg камеру можно отдалить от персонажа и полюбоваться своим альтер-эго с разных ракурсов. Как это сделать?

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

Выглядеть это будет так:
cpx=sx-radius*lx;
cpy=sy-radius*ly;
cpz=sz-radius*lz;

где:
cpx, cpy, cpz - координаты камеры
sx, sy, sz - координаты центра обзорной сферы
radius - радиус обзорной сферы
lx, ly, lz - координаты вектора Look

@темы: технологии, DirectX, C/C++