Android: проблемы с поворотом камеры в GLES 20
Я переместил свою камеру (mViewMatrix) в трехмерное пространство, на 15° к каждому углу x,y,z (при всех углах 0° у меня нет проблем с вращением камеры!)
Все объекты в трехмерном пространстве в порядке (показано в правой нижней части экрана).
Хорошо, теперь я хочу повернуть камеру вокруг оси X. Объекты в правом нижнем углу должны перемещаться снизу вверх с правой стороны.
Но... из-за изменения угла обзора камеры в 15°... объекты движутся не только вниз с правой стороны... они также немного двигаются справа налево.
Я думаю, что я должен изменить вектор с:
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
чтобы:
Matrix.setRotateM(mViewMatrix, 0, 15, cameraVector.x, cameraVector.y, cameraVector.z);
... или что-то.
Это то, что я сделал (я знаю, что должен использовать матрицу поворота, но здесь я разместил простой код, только для удобства чтения):
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.translateM(mViewMatrix, 0, 0, 0, -8);
Matrix.setRotateM(mViewMatrix, 0, 15 + angle, 1, 0, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);
Matrix.setRotateM(mViewMatrix, 0, 15, 0, 0, 1);
Было бы хорошо, если бы кто-то мог опубликовать работающий простой демонстрационный код, потому что я пробовал 5 дней, и я не знаю, как это исправить (я много тестировал).
2 ответа
На самом деле вы не можете вращать камеру в OpenGL. Вместо этого вы должны перемещать / вращать объекты вокруг. Вам необходимо применить матрицы модель / вид / проекция к каждому визуализируемому объекту. Вам не нужно вычислять их все самостоятельно, вы можете использовать android.graphics.matrix. Вы использовали это в своем коде, но с неправильным методом. Чтобы повернуть камеру, вы должны использовать метод.
Matrix.setLookAtM(float rm[], int rmOffset, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
Тем не менее, вам необходимо указать координаты точки, в которой ваша камера должна быть центрирована. К счастью, найти координаты такой точки легко, вам просто нужно немного тригонометрии и 3 строки кода:
centerX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );
centerY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );
centerZ =eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );
Math.cos (двойной угол) и Math.sin(двойной угол) принимают углы в радианах, поэтому вы должны преобразовать их в радианы, используя Math.toRadians (двойной угол). Эти функции возвращают значения типа double, поэтому вам нужно привести их к плавающему типу, потому что функции класса Matrix принимают значения с плавающей точкой в качестве координат.
Вот весь рабочий код:
float pitch = 0;
float yaw = 90;
float roll = -90;
lookX = eyeX + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.cos( Math.toRadians( yaw ) );
lookY = eyeY - ( float ) Math.sin( Math.toRadians( pitch ) );
lookZ = eyeZ + ( float ) Math.cos( Math.toRadians( pitch ) ) * ( float ) Math.sin( Math.toRadians( yaw ) );
upX = (float) Math.cos(Math.toRadians( roll ));
upY = (float) -Math.sin(Math.toRadians( roll ));
Matrix.setIdentityM(mViewMatrix, 0);
Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);