Перевод не влияет на матрицу вращения или дает странные результаты - PullRequest
0 голосов
/ 24 января 2020

Я работаю над приложением OpenGL в C, и я решил создать свои собственные математические функции и структуры. Сначала кажется, что все работает нормально. Мне удалось перевести геометрию, повернуть ее вокруг ее собственного происхождения (локально), но когда дело дошло до реализации поворота всей сцены, чтобы имитировать движение камеры, я столкнулся с некоторыми проблемами. В этом случае я хочу вращать материал не вокруг его центра, а вокруг камеры, поэтому я перемещаю всю сцену, поэтому камера опирается на начало системы координат, а затем выполняю вращение. К сожалению, вращение все еще происходит локально. Я думаю, что есть проблема с умножением матриц, но я не уверен.

void mat4_mul(umat4* m1, umat4* m2, umat4* res) {
    res->col0[0] = m1->col0[0] * m2->col0[0] + m1->col1[0] * m2->col0[1] + m1->col2[0] * m2->col0[2] + m1->col3[0] * m2->col0[3];
    res->col1[0] = m1->col0[0] * m2->col1[0] + m1->col1[0] * m2->col1[1] + m1->col2[0] * m2->col1[2] + m1->col3[0] * m2->col1[3];
    res->col2[0] = m1->col0[0] * m2->col2[0] + m1->col1[0] * m2->col2[1] + m1->col2[0] * m2->col2[2] + m1->col3[0] * m2->col2[3];
    res->col3[0] = m1->col0[0] * m2->col3[0] + m1->col1[0] * m2->col3[1] + m1->col2[0] * m2->col3[2] + m1->col3[0] * m2->col3[3];

    res->col0[1] = m1->col0[1] * m2->col0[0] + m1->col1[1] * m2->col0[1] + m1->col2[1] * m2->col0[2] + m1->col3[1] * m2->col0[3];
    res->col1[1] = m1->col0[1] * m2->col1[0] + m1->col1[1] * m2->col1[1] + m1->col2[1] * m2->col1[2] + m1->col3[1] * m2->col1[3];
    res->col2[1] = m1->col0[1] * m2->col2[0] + m1->col1[1] * m2->col2[1] + m1->col2[1] * m2->col2[2] + m1->col3[1] * m2->col2[3];
    res->col3[1] = m1->col0[1] * m2->col3[0] + m1->col1[1] * m2->col3[1] + m1->col2[1] * m2->col3[2] + m1->col3[1] * m2->col3[3];

    res->col0[2] = m1->col0[2] * m2->col0[0] + m1->col1[2] * m2->col0[1] + m1->col2[2] * m2->col0[2] + m1->col3[2] * m2->col0[3];
    res->col1[2] = m1->col0[2] * m2->col1[0] + m1->col1[2] * m2->col1[1] + m1->col2[2] * m2->col1[2] + m1->col3[2] * m2->col1[3];
    res->col2[2] = m1->col0[2] * m2->col2[0] + m1->col1[2] * m2->col2[1] + m1->col2[2] * m2->col2[2] + m1->col3[2] * m2->col2[3];
    res->col3[2] = m1->col0[2] * m2->col3[0] + m1->col1[2] * m2->col3[1] + m1->col2[2] * m2->col3[2] + m1->col3[2] * m2->col3[3];

    res->col0[3] = m1->col0[3] * m2->col0[0] + m1->col1[3] * m2->col0[1] + m1->col2[3] * m2->col0[2] + m1->col3[3] * m2->col0[3];
    res->col1[3] = m1->col0[3] * m2->col1[0] + m1->col1[3] * m2->col1[1] + m1->col2[3] * m2->col1[2] + m1->col3[3] * m2->col1[3];
    res->col2[3] = m1->col0[3] * m2->col2[0] + m1->col1[3] * m2->col2[1] + m1->col2[3] * m2->col2[2] + m1->col3[3] * m2->col2[3];
    res->col3[3] = m1->col0[3] * m2->col3[0] + m1->col1[3] * m2->col3[1] + m1->col2[3] * m2->col3[2] + m1->col3[3] * m2->col3[3];
}

Матрицы в моем коде и в OpenGL являются основными столбцами.

umat3 rotation_matrix(uvec3 rotation) {
    umat3 x;
    umat3 y;
    umat3 z;

    mat3_setidentity(&x);
    mat3_setidentity(&y);
    mat3_setidentity(&z);

    float torad = DEG_TO_RAD;
    float cos = cosf(rotation.x * torad);
    float sin = sinf(rotation.x * torad);

    x.col1[1] = cos;
    x.col2[1] = -sin;
    x.col2[2] = cos;
    x.col1[2] = sin;

    cos = cosf(rotation.y * torad);
    sin = sinf(rotation.y * torad);

    y.col0[0] = cos;
    y.col0[2] = -sin;
    y.col2[0] = sin;
    y.col2[2] = cos;

    cos = cosf(rotation.z * torad);
    sin = sinf(rotation.z * torad);

    z.col0[0] = cos;
    z.col1[0] = -sin;
    z.col1[1] = cos;
    z.col0[1] = sin;

    mat3_mul(&x, &y);
    mat3_mul(&x, &z);

    return x;
}

Матрица вращения - это вращение 3x3, которое затем помещается в единичную матрицу 4x4

RRR0 RRR0 RRR0 0001

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...