Масштабировать, вращать, переводить w. матрицы в openGL ES 2.0

Я работаю с OpenGL ES 2.0 и пытаюсь создать свой класс объектов с некоторыми методами для их поворота/перевода/масштабирования.

Я просто устанавливаю свой объект в 0,0,0 и затем перемещаю его в нужное место на экране. Ниже приведены мои методы перемещения его отдельно. После этого я запускаю buildObjectModelMatrix, чтобы передать все матрицы в одну objectMatrix, чтобы я мог взять вершины и умножить их на мою modelMatrix/objectMatrix, а затем визуализировать их.

Что я считаю правильным, я должен умножить свои матрицы в следующем порядке:

[масштаб]x[поворот]x[перевод]

->

[temp]x[перевод]

->

[объектная матрица]

Я нашла литературу. Может быть, я получу его через несколько минут, если я буду, я обновлю его.

Начало Android 3D

https://gamedev.stackexchange.com/questions/16719/what-is-the-correct-order-to-multiply-scale-rotation-and-translation-matrices-f

  setIdentityM(scaleMatrix, 0);
  setIdentityM(translateMatrix, 0);
  setIdentityM(rotateMatrix, 0);
public void translate(float x, float y, float z) {
    translateM(translateMatrix, 0, x, y, z);
    buildObjectModelMatrix();
}

public void rotate(float angle, float x, float y, float z) {
    rotateM(rotateMatrix, 0, angle, x, y, z);
    buildObjectModelMatrix();
}

public void scale(float x, float y,float z) {
    scaleM(scaleMatrix, 0, x, y, z);
    buildObjectModelMatrix();
}

private void buildObjectModelMatrix() {
    multiplyMM(tempM, 0, scaleMatrix, 0, rotateMatrix, 0);
    multiplyMM(objectMatrix, 0, tempM, 0, translateMatrix, 0);
}

РЕШЕНО: Проблема во всем этом заключается в том, что если вы масштабируете перед перемещением, вы получаете разницу в расстоянии, которое вы переводите! правильный код для умножения ваших матриц должен быть (поправьте меня, если я ошибаюсь)

    private void buildObjectModelMatrix() {
    multiplyMM(tempM, 0, translateMatrix, 0, rotateMatrix, 0);
    multiplyMM(objectMatrix, 0, tempM, 0, scaleMatrix, 0);
}

с этим вы сначала переводите и вращаете. После этого вы можете масштабировать объект.

Протестировано с несколькими объектами... надеюсь, это помогло :)


person LordSmith    schedule 29.09.2014    source источник


Ответы (1)


Вы знаете, что это самая распространенная проблема большинства людей, когда они начинают работать с матричными операциями. Умножение матриц работает так, как если бы вы смотрели на объект от первого лица, получая некоторые команды: например, если вы начали с (0,0,0), обращенного к положительной оси X, а up было бы положительной осью Y, тогда перевод (a,0,0) будет означать «идти вперед», переводить (0,0,a) будет означать "идти налево", поворот (a, 0, 1, 0) будет означать "повернуть налево"...

Итак, если в вашем случае вы масштабируете на 3 единиц, поворачиваете на 90 градусов, а затем переводите на (2,0,0), то происходит то, что вы сначала увеличиваете себя на 3, затем поворачиваете на 90 градусов, так что теперь вы сталкиваетесь с положительным Z, все еще довольно большим. Затем вы продвигаетесь вперед на 2 единиц измерения в вашей собственной системе координат, что означает, что вы фактически перейдете к (0,0,2*3). Таким образом, вы окажетесь на (0,0,6), глядя в сторону положительной оси Z.

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

Вы должны знать, что, несмотря на то, что такой вид матрицы является нормальным, когда вы начинаете с 3D-сцены, вы должны попытаться как можно скорее перейти на лучшую систему. В основном я использую структуру/класс объекта, который содержит 3 вектора: position, forward и up (это очень похоже на использование glLookAt, но не совсем то же самое). Таким образом, имея эти 3 вектора, вы можете просто установить определенное положение или поворот, используя тригонометрию или ваши матричные инструменты, умножив векторы на матрицы вместо матриц на матрицы. Или вы можете работать с ними внутренне (от первого лица), где, например, «идти вперед» будет выполняться как position = position + position*forward*scale, поворот налево будет вращать вектор forward вокруг вектора up. В любом случае, я надеюсь, что смогу понять, как манипулировать этими тремя векторами, чтобы получить желаемый эффект... Итак, что вам нужно сделать, чтобы восстановить матрицу из этих трех векторов, нужно сгенерировать другой вектор right, который является перекрестным произведением up и forward, а затем Матрица модели состоит из:

right.x,    right.y,    right.z, .0
up.x,       up.y,       up.z, .0
forward.x,  forward.y,  forward.z,  .0
position.x, position.y, position.z, 1.0

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

Я надеюсь, что это поможет вам лучше понять...

person Matic Oblak    schedule 01.10.2014