Как использовать ориентацию компаса Android для наведения камеры opengl? - PullRequest
3 голосов
/ 11 марта 2011

Я использую libgdx для разработки базовой 3d-игры для Android, и мне трудно правильно ориентировать камеру с учетом трех углов поворота, полученных от компаса (азимут - вращение вокруг Z, вращение - вращение вокруг Y, наклон - вращение о Х). У меня был небольшой успех в следующем коде: я могу правильно нацелить виртуальную камеру вниз по оси Z и по оси X, как я и ожидал. (Углы в градусах [-180,180])

camera.direction.x = 0;
camera.direction.y = 0;
camera.direction.z = 1;
camera.up.x = -1;
camera.up.y = 0;
camera.up.z = 0;

camera.rotate(azimuth,0,0,1);
camera.rotate(roll,0,1,0);
camera.rotate(pitch,1,0,0);

У меня тоже был некоторый успех с этим, но он не ориентирует вектор роста камеры. (В этой версии углы были преобразованы в радианы)

float x,y,z;
roll = (float) (roll + Math.PI/2.0);
x = (float) (Math.cos(azimuth) * Math.cos(roll));
y = (float) (Math.sin(azimuth) * Math.cos(roll));
z = (float) (Math.sin(roll));
Vector3 lookat = new Vector3(x,y,z);
camera.lookAt(lookat.x, lookat.y, lookat.z);

Может ли кто-нибудь пролить свет на то, как правильно ориентировать виртуальную камеру под этими тремя углами?

Кроме того, я пытаюсь перевести телефон в горизонтальный режим, чтобы верхняя часть телефона была слева, а нижняя - справа. Следовательно, направление камеры по умолчанию (все повороты равны 0, верх телефона направлен на север) - это камера, направленная к земле (положительное Z) с направленным вверх востоком (отрицательное X).

1 Ответ

3 голосов
/ 24 марта 2011

Кодируя некоторое время другие вещи, я в конечном итоге достиг точки, где я пытался разделить рендеринг, симуляцию и ввод.Из-за этого я пришел к следующему решению, которое работает для меня.Я не проверял это строго, но он, кажется, делает то, что я хочу (игнорируя поворот камеры) .

В андроидной части программы мне нужно было установить ориентацию на альбомнуюрежим:

<activity android:name=".MySuperAwesomeApplication"
              android:label="@string/app_name"
              android:screenOrientation="landscape">
              >

Я создал класс игрока для хранения рыскания, тангажа, крена и позиции

public class Player {
    public final Vector3 position = new Vector3(0,1.5f,0);    
    /** Angle left or right of the vertical */
    public float yaw = 0.0f;
    /** Angle above or below the horizon */
    public float pitch = 0.0f;
    /** Angle about the direction as defined by yaw and pitch */
    public float roll = 0.0f;
}

А затем, когда я обновляю игрока на основе ввода, я делаю следующее:

player.yaw = -Gdx.input.getAzimuth();
player.pitch = -Gdx.input.getRoll()-90;
player.roll = -Gdx.input.getPitch();

Обратите внимание, что высота тона отображается на input.roll, а карты - на input.pitch.Не уверен, почему, но это работает для меня.Наконец обновите камеру:

camera.direction.x = 0;
camera.direction.y = 0;
camera.direction.z = 1;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 0;
camera.update();

// The world up vector is <0,1,0>
camera.rotate(player.yaw,0,1,0);
Vector3 pivot = camera.direction.cpy().crs(camera.up);
camera.rotate(player.pitch, pivot.x,pivot.y,pivot.z);
camera.rotate(player.roll, camera.direction.x, camera.direction.y, camera.direction.z);
camera.translate(player.position.x, player.position.y, player.position.z);
camera.update();

РЕДАКТИРОВАТЬ: добавлен рулон камеры к коду.Для меня и моего Droid 2, по-видимому, у рулона есть только значения в [-90,90], так что если вы поворачиваете на -90 или 90, значения начинают изменяться обратно к 0.

...