Реализация страфе - OpenGL - Камера - PullRequest
4 голосов
/ 25 мая 2011

Я создал класс камеры.Моя мышь может вращаться на 360 градусов и двигаться вверх и вниз.Как я и предполагал, как и во всех играх.Также можно двигаться вперед и назад, как во всех играх.Но я не знаю, как реализовать перемещение влево и вправо.

Я делаю следующее:

Это вызывается каждый кадр:

gluLookAt(_posX , _posY , _posZ,
          _viewX, _viewY, _viewZ,
          _upX,   _upY,   _upZ );

Мой ходfunction
Не работает:

void Camera::moveLeft() 
{

    float rot= (_viewY / 180 * PI);
    _moveX -= float(cos(rot)) * 0.5;
    _moveZ -= float(sin(rot)) * 0.5;
}

Работает
движется вперед по сцене:

void Camera::moveForward() 
{

    float viewX = _viewX - _posX;
    float viewY = _viewY - _posY;
    float viewZ = _viewZ - _posZ;

    _posX += viewX * speed
    _posY += viewY * speed;
    _posZ += viewZ * speed;

    _viewX += viewX * speed;
    _viewY += viewY * speed;
    _viewZ += viewZ * speed;

}

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

Есть идеи, как это решить?

Спасибо

@ edit

Поэтому я удалил оператор glTranslated и изменил свою функцию moveLeft следующим образом:

void Camera::moveLeft(){</p> <pre><code>float x = ((_viewY * _upZ) - (_viewZ * _upY)); float y = ((_viewZ * _upX) - (_viewX * _upZ)); float z = ((_viewX * _upY) - (_viewY * _upX)); float magnitude = sqrt( (x * x) + (y * y) + (z * z) ); x /= magnitude; y /= magnitude; z /= magnitude; _posX -= x; _posY -= y; _posZ -= z;

}

Я явно что-то делаюнеправильно, потому что движения влево и вправо "лучше", но все же не то, что вы ожидаете.

1 Ответ

6 голосов
/ 25 мая 2011

Чтобы получить вектор, который указывает под углом 90 градусов к плоскости, содержащей ваши векторы вверх и просмотра, вам нужно сделать перекрестное произведение: http://en.wikipedia.org/wiki/Cross_product. Для этой функции в любой приличной библиотеке векторной математики будет иметься функция.

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

Обратите внимание, что это не сработает, если вектор вашего взгляда будет точно в том же направлении, что и вектор вверх.

Редактировать: Исходя из вашего отредактированного вопроса, я думаю, вам нужно сделать это:

Вам нужно получить вектор направления вида и использовать его вместо вектора вида в перекрестном произведении, а затем добавить к обеим позициям и вектору вида:

void Camera::moveLeft() 
{

    float viewX = _viewX - _posX;
    float viewY = _viewY - _posY;
    float viewZ = _viewZ - _posZ;

    float x = ((viewY * _upZ) - (viewZ * _upY));
    float y = ((viewZ * _upX) - (viewX * _upZ));
    float z = ((viewX * _upY) - (viewY * _upX));

    float magnitude = sqrt( (x * x) + (y * y) + (z * z) );

    x /= magnitude;
    y /= magnitude;
    z /= magnitude;

    _posX -= x;
    _posY -= y;
    _posZ -= z;

    _viewX -= x;
    _viewY -= y;
    _viewZ -= z;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...