Вам просто нужно обновить направление, в котором смотрит ваша камера. Вам не нужно менять матрицу мира, метод openGL "gluLookAt ()" сделает это автоматически за кулисами.
Если у вас есть настройка класса камеры, просто создайте функцию для установки вектора направления вверх камеры, который вам потребуется для расчета на основе значения типа float / double (я полагаю) из компаса iPhone. Когда ваша камера обновится в позиции lookAt (), она должна изменить камеру, чтобы она смотрела в правильном месте.
Это не сильно отличается от того, что вы делаете, когда вращаете камеру в игре на основе FPS. Разница в том, что вы хотите вращать камеру вдоль оси X вместо оси Y.
Посмотрите, как класс камеры выполняет вращение для перемещения камеры влево или вправо с помощью клавиатуры, затем измените его, чтобы он работал, используя значения направления вашего компаса.
Вот некоторый C ++ код, который я написал, который может дать вам представление о том, как должен работать ваш класс камеры:
/* This reshapes the camera using the perspective projection */
void Camera::ReshapePerspectiveForPicking( void )
{
glMatrixMode(GL_PROJECTION);
// Sets the clipping volume
gluPerspective( m_FieldOfView, (float)m_width/(float)m_height, m_zNear, m_zFar );
gluLookAt( camPos.x, camPos.y, camPos.z,
camPos.x + camView.x, camPos.y + camView.y, camPos.z + camView.z,
0.0f, 1.0f, 0.0f );
glMatrixMode( GL_MODELVIEW );
}
Обратите внимание на строку выше (0.0f, 1.0f, 0.0f). Это вектор направления ВВЕРХ.
Это было статично для моей игры, потому что камера никогда не должна была смотреть вниз.
Вам просто нужно изменить этот вектор, создав новый вектор на ориентации компаса.
Метод, приведенный ниже, был просто альтернативным методом, который нам иногда требовался для обновления камеры, передавая ей специальный вектор. Вы, вероятно, можете игнорировать это, я просто включил его, чтобы вы могли поучиться у него.
/* This updates the camera to look at the changed camera position. This uses a passed in camPosition and camView GameMath::Vector */
void Camera::Update( GameMath::Vector camPos, GameMath::Vector camView )
{
glMatrixMode( GL_PROJECTION );
gluLookAt( camPos.x, camPos.y, camPos.z,
camPos.x + camView.x, camPos.y + camView.y, camPos.z + camView.z,
0.0f, 1.0f,0.0f );
}
Вот мой метод поворота камеры вдоль оси Y (помните, что вы хотите повернуть вдоль оси X ) - я бы переписал этот метод сейчас, потому что это своего рода уловка (я написал это) лет назад) но этого достаточно, чтобы показать вам, как это можно сделать.
void Camera::Rotate( void )
{
if ( m_rotateCamera == true )
{
// Keep the radians within 2 pi, roughly
float minimumRadiansRotate = 0.00;
float maximumRadiansRotate = 6.2831853072;
m_YRotateAngle = GameMath::Wrap( m_YRotateAngle, minimumRadiansRotate, maximumRadiansRotate );
m_YRotateAngle += m_rotateSpeed * m_rotateDirection; // Add to the camera's current angle value
camView.x = sin( m_YRotateAngle );
camView.z = -cos( m_YRotateAngle );
}
}
Немного сложно предоставить вам определенный кусок кода, который будет делать то, что вы хотите сделать, потому что ваш класс камеры, вероятно, отличается от моего, хотя это должно помочь вам понять, что нужно сделать.
Среда CoreLocation содержит биты кода, которые вам понадобятся для считывания значений с компаса, если вы еще не закодировали эту часть.
Удачи.