Подобие авиасимулятора - как описать камеру ручками?
Задача: имеется некий ландшафт и объект (самолет) над ним. Требуется вывести на экран вид с камеры, находящейся не накотором расстоянии за самолетом. При этом самолетом, ессно, можно управлять... Как лучше описать эту камеру и какие матрицы преобразований понадобяться?
OpenGL, DirectX не используем, все ручками :)
Углы наклона камеры пока без внимания...
Пробовал сделать по-простому - стандартное перспективное преобразование, координаты камеры = координатам самолета - оффсет по z... (перед этим перенос камеры в (0,0,z)) но что-то не то получается...
Понимаю, что все должно быть элементарно и просто я где-то конкретно туплю, но сообразить не могу...
Кто может подсказать?
Ну... нужно делать все правильно, тогда наверняка получится.
PS. Может, телепаты подскажут что-нибудь поконкретнее.
PPS. Ты бы хоть написал, как вводишь систему координат.
Я и сам знаю, что нужно делать правильно, только как это "правильно"? Ибо почти все статьи, которые есть, описывают данную задачу именно с позиций либо OpenGL, либо DX.
Я вроде не просил за меня код писать, а всего лишь помочь алгоритмом, описанием, статейкой...
Ссылку на статью не помню, но саму статью видел где-то здесь.
Ты приводишь некоторое выражение, судя по всему, для координат: (0,0,z), но правильно оно или нет, я не знаю, т.к. не знаю, как именно ты вводишь эту систему координат.
Как говорится, "телепаты в отпуске", и нечего здесь обижаться.
В принципе все необходимое есть в учебнике Беклемишева Аналитическая геометрия и линейная алгебра.
Применительно к компьютерной графике могу поекомендовать Шикина и Борескова Компьютерная графика.
Ты приводишь некоторое выражение, судя по всему, для координат: (0,0,z), но правильно оно или нет, я не знаю, т.к. не знаю, как именно ты вводишь эту систему координат.
А чего здесь непонятного? Все объекты описаны в мировой системе координат. Ось X смотрит вправо, Y - вверх, Z - на наблюдателя...
А сама методика работы с камерой, и алгоритмы преобразований, по-моему, в принципе, не зависят от того, левая или правая СК принята... В матрицах, да будут отличия.
Применительно к компьютерной графике могу поекомендовать Шикина и Борескова Компьютерная графика.
Ничего о задании камер в Шикине нет. Разве что, пара строчек в главе про OpenGL....
зы. да и не обижаюсь я, не на что :)
Насчет Шикина и Борескова, если в тексте не встречается слово "камера", это не значит, что она не подразумевается. Любая проекция осуществляется в системе отсчета, связанной с камерой.
Идея была такая:
1) Ставим камеру по координатам самолета, по y и z - некоторые смещения (чтобы как бы камера получилась чуть выше и чуть позади)
2) Из данной точки строим перспективную проекцию
а) делаем перенос в положение стандартной камеры (0,0,z)
б) собственно проекция
3) Отображаем на экран...
Вроде бы все должно быть правильно... Или я ошибаюсь где-то?
Вообще-то для начала камеру нужно будет повернуть. Применяем для векторов положения и цели камеры те же преобразования, что и для самолёта - всего и делов. Автор, в каком смысле не получается? Не туда смотрит, не движется, ... ?
В общем-то, сам так и делал... С поворотами, как раз, проблем у меня не было, то что, вектора камеры надо изменять соответственно преобразованиям, применимым к самолету, это понятно...
Теперь проблема несколько другая... Сделал через Lookat() (точнее через матрицу, которую lookat строит).. вроде бы все нормально... вот только никак не могу сообразить, как выбирать вектора положения камеры и прицела камеры (eye и target)... я взял положение камеры - чуть выше и чуть за самолетом, а target - чуть впереди и чуть ниже (но пробовал и ровно по координатам самолета выставлять)... в итоге выходит - при движении самолета вдоль z - он постепенно ухоит с экрана (снизу вверх)... не могу сообразить, как правильно эти вектора задать, чтобы он оставался приблизительно в центре экрана всегда.... ведь вроде бы target должен это определять...
создается странное впечатление: ты пишешь "я сделал <1>, получил <2>", но, судя по <2>, ты только хотел сделать <1>, а на самом деле сделал <3>.
Когда о том, что ты сделал НА САМОМ ДЕЛЕ, приходится только догадываться, советовать что-то очень сложно.
Итак.
Все объекты сцены описаны в виде полигональных моделей и лежат в соответствующем массиве структур. структура имеет поля для хранения координа как в мировых координатах, так и в системе координат камеры:
int a,b,c;
Vector norm;
double lintensity;
int colorr;
int colorg;
int colorb;
}polygon_type;
typedef struct{ //вершина
Vector wcs;
Vector ccs;
Vector norm;
double LIguro;
bool flag;
}vertex_type;
typedef struct // камера
{
double x; // положение камеры
double y;
double z;
Vector target;
Vector up; // по-умолчанию (0,1,0)
} viewport;
После задания векторов камеры вызывается
{
Vector camera1 = Vector(camera.x, camera.y, camera.z);
Vector f = Normalize(camera.target - camera1);
Vector up = Normalize(camera.up);
Vector s = f ^ up;
Vector u = s ^ f;
Matrix lookat(1);
lookat.x [0][0] = s.x;
lookat.x [0][1] = s.y;
lookat.x [0][2] = s.z;
lookat.x [1][0] = u.x;
lookat.x [1][1] = u.y;
lookat.x [1][2] = u.z;
lookat.x [2][0] = -f.x;
lookat.x [2][1] = -f.y;
lookat.x [2][2] = -f.z;
return lookat;
}
Полученная матрица применятся ко всем объектам сцены (к вершинам полигонов):
{
for (int i=0; i<objects_qty; i++)
for (int j=0; j<object.vertices_qty; j++)
{
object.vertex[j].ccs = m * object.vertex[j].wcs;
if (object.vertex[j].ccs.x > 0 && object.vertex[j].ccs.x < resX &&
object.vertex[j].ccs.y > 0 && object.vertex[j].ccs.y < resY)
object.vertex[j].flag = true;
else object.vertex[j].flag = false;
}
v = lobject.coord; // это для источника света
lobject.coordccs = v;
}
2 Der Meister
Да, самолет движеться вдоль z
Не понял, что ты имеешь в виду... Я применяю построенную матрицу ко всем объектам сцены... и все... Что значит "применить преобразование к положению камеры и ее целям в отдельности"???
У тебя их не может быть менее трех: для ландшафта (возможно, единичная), для самолета и для камеры.
У тебя их не может быть менее трех: для ландшафта (возможно, единичная), для самолета и для камеры.
Почему???
Если все объекты описаны в одной (мировой) СК, то для построения их координат в СК наблюдателя (т.е. камеры), почему для разных объектов должны быть разные матрицы??? Я всегда считал что матрица должна быть одна, и зависеть она должна от положения камеры и направления ее "взгляда"
По-моему, с точки зрения математики, все объекты равноценны, да и представить их все можно вообще в виде одного массива вершин...
И почему для ландшафта единичная - она же ничего не изменяет?
Объясни, я не понял, о чем ты хотел сказать...
Конечно, любой объект можно описать сразу в мировой системе координат. Но тогда при перемещении самолета надо будет переприсваивать значения координат всех его вершин на каждом шаге.
Естественно, никто так не делает: координаты всех вершин самолета записываются относительно системы отсчета, связанной с самолетом, а затем для всего самолета в целом высчитывается матрица и она применяется ко всем вершинам самолета.
Конечно, любой объект можно описать сразу в мировой системе координат. Но тогда при перемещении самолета надо будет переприсваивать значения координат всех его вершин на каждом шаге.
Естественно, никто так не делает: координаты всех вершин самолета записываются относительно системы отсчета, связанной с самолетом, а затем для всего самолета в целом высчитывается матрица и она применяется ко всем вершинам самолета.
У меня все объекты (самолет в т.ч.) описаны сразу в МСК... А поскольку вершин самолета относительно немного, изменение их на каждом шаге особых затрат не вызывает...
Поэтому в моем случае, матрица все-таки одна для всех будет....
Поэтому в моем случае, матрица все-таки одна для всех будет....
Да нее, хреновая идея. Фишка матриц в том, что все базовые преобразования, не меняющие структуру объекта (трансформации) компактно размещаются в одном месте и обрабатываются универсально. Гемор с прямым изменением векторов положения вершин начинается тогда, когда визуализируемый объект подразумевает наличие подобъектов, движение которых происходит в локальной системе координат родительского объекта.
Такой эффект мог бы иметь место, если сначала построить матрицу с использованием look-at constraint, а затем начать её двигать. Поскольку локальная ось z для камеры проходила бы уже вдоль направления взгяда и, в описанном тобой случае, не совпадала бы с мировой, постольку камера постепенно уходила бы вниз. Проверить легко: если цель для камеры задать чуть-чуть пониже, твой саломёт начнёт взмывать ещё быстрее. Посмотри внимательнее код: wcs, ccs... Хрен его знает, мож ты тупо буквой ошибся и при перемещении берутся значения не из того вектора, а объекты начинают двигаться уже и не в мировой системе координат