Android: проблемы с поворотом камеры в GLES 20

Я переместил свою камеру (mViewMatrix) в трехмерном пространстве на 15 ° на каждый угол x, y, z (со всеми углами 0 ° у меня нет проблем с поворотом камеры!)

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

Хорошо, теперь я хочу повернуть камеру вокруг оси X. Объекты в правом нижнем углу должны двигаться снизу вверх с правой стороны.

Но ... из-за измененных углов камеры 15 ° ... объекты перемещаются не только сверху вниз с правой стороны ... они также немного перемещаются справа налево.

Я думаю, мне нужно изменить вектор с:

Matrix.setRotateM(mViewMatrix, 0, 15, 0, 1, 0);

to:

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 дней, и я не знаю, как это исправить (я много тестировал).


person Kyle    schedule 24.01.2017    source источник


Ответы (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, поэтому вам нужно привести их к типу float, потому что функции класса Matrix принимают числа с плавающей запятой в качестве координат.

person Reaper    schedule 24.01.2017
comment
Спасибо большое, работает. Но как я могу повернуть угол крена? Я видел только наклон и рыскание - person Kyle; 24.01.2017
comment
@Kyle Вам нужно будет указать вектор (upX, upY, upZ) для Matrix.setLookAtM, чтобы сделать вашу камеру катящейся. Этот вектор указывает, куда направлена ​​ваша камера, т.е. е. если вы поднимете руку, это ваш вектор вверх. - person Reaper; 24.01.2017
comment
@ Reaper: хороший совет для вектора (upX, upY, upZ), чтобы повернуть камеру. У вас есть коды для преобразования угла крена в полезный вектор крена? - person Kyle; 24.01.2017
comment
@ Кайл Эмм ... нет, я не использую ролл. Хотя, думаю, с листом бумаги и немного времени я смогу это достать. - person Reaper; 24.01.2017
comment
Это работает: upX = (float) Math.cos (Math.toRadians (roll)); upY = (float) -Math.sin (Math.toRadians (ролл)); - person Kyle; 24.01.2017
comment
Любил это. (он не работает с переменными Up Vector: upX и upY) Я не знаю почему ... но я решил это. Теперь шатания больше нет, а также все углы всех объектов и камеры при вращении в любых направлениях работают нормально. Кажется, что я исправил и фиксатор кардана. После всех этих проблем я подумал об использовании 3D-движка ... но все эти 3D-движки очень ограничены и сложны. На устранение всех проблем потребовался 1 месяц. Итак, теперь я счастлив, что это работает. Спасибо еще раз. Android должен иметь полностью готовый к использованию 3D Engine, простой в использовании. Это сложный OpenGL - person Kyle; 26.01.2017

Вот весь рабочий код:

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);
person Kyle    schedule 24.01.2017