Войти
OpenGL communityФорумВопросы по программированию

камера без ограничений

#0
12:08, 13 ноя. 2014

Добрый день уважаемые программисты)

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

Суть: простую камеру сделать очень легко, будет вращаться вниз вверх глядеть по сторонам и даже можно положить её на бок, это я реализовал легко и просто, но есть очень большое НО

1) в любой обычной игре, если смотреть вперед, то камера вращается по бокам нормально, если же смотреть вниз или вверх, то при поворотах мышки направо и налево камера начнет крутиться вокруг своей оси, необходимо же чтобы при повороте мышкой в бок, не зависимо от текущего положения камеры смотрели в бок

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

если использовать стандартный ОпенГЛ, то никакой комбинацией перестановок последовательности углов поворота не решить эту проблему.

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

уже почти неделю стою на месте.
Есть у кого нибудь готовый пример на любом языке?, желательно с пояснением, в крайнем случае без, сам разобраться попытаюсь)
заранее благодарю.


#1
12:15, 13 ноя. 2014

я так понял, нужна камера для леталки
научись работать с матрицами, OpenGL тут вообще не причем

#2
12:16, 13 ноя. 2014

reqyz
> если использовать стандартный ОпенГЛ, то никакой комбинацией перестановок
> последовательности углов поворота не решить эту проблему.

не используй стандартные функции - они там вообще халявно сделаны.
Или, на худой конец, обрати внимание сюда: http://www.gamedev.ru/code/forum/?id=168907&page=2

Твоя проблема в том, что преобразование, добавленное последним, вставляется в начало стека преобразований. Это происходит из-за умножения матриц преобразования на текущую матрицу не в том порядке, в каком нужно тебе (тебе последнее добавленное преобразование нужно добавить в конец стека преобразований, а не в начало).

#3
10:48, 14 ноя. 2014

Бери Up вектор всегда равным направлению вверх в мировых координатах. Если это у тебя ось Y тогда Up вектор буде (0, 1, 0).

я юзаю HandyMath lib
кусок моего гавнокода

void QCamera::RotateHorizontal(const float angle)
{
  horAngle += angle;
}

void QCamera::RotateVertical(const float angle)
{
  float resAngle = angle;
  if ( verAngle+angle > 89.9f )
    resAngle = 89.9f - verAngle;

  if ( verAngle+angle < -89.9 )
    resAngle = -89.9 - verAngle;

  verAngle += resAngle;
}

// вычисление матрицы перспективной проекции
void QPerspectiveCamera::Set()
{
  up = vec3(0,0,1); // у меня левая координатная система, вектор вверх 0Z
  fwd = vec3(0,1,0);
  lft = vec3(-1,0,0);

  fwd = rotate(radians(horAngle), up, fwd); // два поворота по горизонтали, сначала вращаем направление "вперед" вокруг вектора вверх
  lft = rotate(radians(horAngle), up, lft); // затем вращаем вектор "влево" вокруг вектора "вверх"
  fwd = rotate(radians(verAngle), lft, fwd); // и наконец вращаем вектор "вперед" вокруг вектора "влево", это наклон взгляда вниз вверх

  if( lookingAt )  pos = lookTo-(lookDistance*fwd);

  mPerspective(prj, radians(fov/aspect), aspect, znear, zfar);
  prj *= lookAtMat(pos, pos+fwd, up);
}
//Create perspective projection matrix (fov in degrees)
void mPerspective(float *m, float fovy, float aspect, float znear, float zfar)
{
  float f = 1/tanf(fovy/2);
  float A = (znear+zfar)/(znear-zfar);
  float B = 2*znear*zfar/(znear-zfar);

  m[0] = f/aspect;  m[4] = 0;  m[8] = 0;  m[12] = 0;

  m[1] = 0;      m[5] = f;  m[9] = 0;  m[13] = 0;

  m[2] = 0;      m[6] = 0;  m[10] = A;  m[14] = B;

  m[3] = 0;      m[7] = 0;  m[11] = -1;  m[15] = 0;
}

void mLookAt(float *m, const vec3& eye, const vec3& at, const vec3& up)
{
  vec3 zaxis = normalize(at-eye);
  vec3 xaxis = normalize(cross(up,zaxis));
  vec3 yaxis = cross(zaxis,xaxis);

  m[0] = xaxis[0];    m[4] = yaxis[0];      m[8] = zaxis[0];    m[12] = 0;

  m[1] = xaxis[1];    m[5] = yaxis[1];      m[9] = zaxis[1];    m[12] = 0;

  m[2] = xaxis[2];    m[6] = yaxis[2];      m[10]= zaxis[2];    m[12] = 0;

  m[3] = -dot(xaxis,eye);  m[7] = -dot(yaxis,eye);    m[11]= -dot(zaxis,eye);  m[12] = 1;
}

как видишь, вектор вверх у меня вообще не меняется.

#4
11:49, 14 ноя. 2014

RmzVoid
спасибо, изучу ваш код, правильно ли я понимаю, что он позволяет рассчитывать матрицу для замены в glMultMatrixf?

#5
12:24, 14 ноя. 2014

да, потом тупо делаешь

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(camera.prj);

перед рисованием

да и учти, что у меня координатная система не такая как обычно пишут в паперах

OpenGL communityФорумВопросы по программированию

Тема в архиве.