OpenGL/GLM — Расчет задач усеченной пирамиды

Я пытаюсь рассчитать свою усеченную пирамиду, чтобы выполнить несколько простых тестов ограничивающей рамки.

Вот моя функция:

void CFrustum::calculateFrustum(glm::mat4* mat)
{
    // Calculate the LEFT side
    m_Frustum[LEFT][A] = *glm::value_ptr(mat[0][3]) + *glm::value_ptr(mat[0][0]);
    m_Frustum[LEFT][B] = *glm::value_ptr(mat[1][3]) + *glm::value_ptr(mat[1][0]);
    m_Frustum[LEFT][C] = *glm::value_ptr(mat[2][3]) + *glm::value_ptr(mat[2][0]);
    m_Frustum[LEFT][D] = *glm::value_ptr(mat[3][3]) + *glm::value_ptr(mat[3][0]);

    // Calculate the RIGHT side
    m_Frustum[RIGHT][A] = *glm::value_ptr(mat[0][3]) - *glm::value_ptr(mat[0][0]);
    m_Frustum[RIGHT][B] = *glm::value_ptr(mat[1][3]) - *glm::value_ptr(mat[1][0]);
    m_Frustum[RIGHT][C] = *glm::value_ptr(mat[2][3]) - *glm::value_ptr(mat[2][0]);
    m_Frustum[RIGHT][D] = *glm::value_ptr(mat[3][3]) - *glm::value_ptr(mat[3][0]);

    // Calculate the TOP side
    m_Frustum[TOP][A] = *glm::value_ptr(mat[0][3]) - *glm::value_ptr(mat[0][1]);
    m_Frustum[TOP][B] = *glm::value_ptr(mat[1][3]) - *glm::value_ptr(mat[1][1]);
    m_Frustum[TOP][C] = *glm::value_ptr(mat[2][3]) - *glm::value_ptr(mat[2][1]);
    m_Frustum[TOP][D] = *glm::value_ptr(mat[3][3]) - *glm::value_ptr(mat[3][1]);

    // Calculate the BOTTOM side
    m_Frustum[BOTTOM][A] = *glm::value_ptr(mat[0][3]) + *glm::value_ptr(mat[0][1]);
    m_Frustum[BOTTOM][B] = *glm::value_ptr(mat[1][3]) + *glm::value_ptr(mat[1][1]);
    m_Frustum[BOTTOM][C] = *glm::value_ptr(mat[2][3]) + *glm::value_ptr(mat[2][1]);
    m_Frustum[BOTTOM][D] = *glm::value_ptr(mat[3][3]) + *glm::value_ptr(mat[3][1]);

    // Calculate the FRONT side
    m_Frustum[FRONT][A] = *glm::value_ptr(mat[0][3]) + *glm::value_ptr(mat[0][2]);
    m_Frustum[FRONT][B] = *glm::value_ptr(mat[1][3]) + *glm::value_ptr(mat[1][2]);
    m_Frustum[FRONT][C] = *glm::value_ptr(mat[2][3]) + *glm::value_ptr(mat[2][2]);
    m_Frustum[FRONT][D] = *glm::value_ptr(mat[3][3]) + *glm::value_ptr(mat[3][2]);

    // Calculate the BACK side
    m_Frustum[BACK][A] = *glm::value_ptr(mat[0][3]) - *glm::value_ptr(mat[0][2]);
    m_Frustum[BACK][B] = *glm::value_ptr(mat[1][3]) - *glm::value_ptr(mat[1][2]);
    m_Frustum[BACK][C] = *glm::value_ptr(mat[2][3]) - *glm::value_ptr(mat[2][2]);
    m_Frustum[BACK][D] = *glm::value_ptr(mat[3][3]) - *glm::value_ptr(mat[3][2]);

    // Normalize all the sides
    NormalizePlane(m_Frustum, LEFT);
    NormalizePlane(m_Frustum, RIGHT);
    NormalizePlane(m_Frustum, TOP);
    NormalizePlane(m_Frustum, BOTTOM);
    NormalizePlane(m_Frustum, FRONT);
    NormalizePlane(m_Frustum, BACK);
}

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

Я переключился с режима фиксированной функции на получение моих матриц следующим образом:

glGetFloatv( GL_PROJECTION_MATRIX, proj );

glGetFloatv( GL_MODELVIEW_MATRIX, modl );

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

Вот мое создание матрицы:

cameraMatrix = glm::lookAt(position, position+direction, up);
projectionMatrix = glm::perspective(50.0f, 4.0f / 3.0f, 0.1f, 1000.f);
viewMatrix = projectionMatrix * cameraMatrix;

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

Я уверен, что мой код box vs frustum правильный. Кто-нибудь видит ошибку в моем коде расчета или знает, что мне действительно нужно преобразовать вершины поля привязки?

Спасибо.


person Pladnius Brooks    schedule 03.08.2012    source источник


Ответы (2)


Если у вас есть ограничительная рамка в мировых координатах, вы должны передать свой viewMatrix для вычисления Frustum.

Передача viewMatrix в calculateFrustum сгенерирует плоскости в мировом пространстве.

Если вместо этого вы передадите проекционную матрицу для вычисления Frustum, вам придется применить cameraMatrix к ограничивающей рамке перед выполнением теста пересечения.

person brano    schedule 03.08.2012
comment
Итак, чтобы мы понимали терминологию, моя матрица обзора — это и перемещение камеры, и вращение, и проекционная матрица вместе взятые. Я прошел это и все еще, я, кажется, получаю ошибки. Кажется, какую бы матрицу я ему ни передал, он не анализирует ограничивающую рамку в мировом пространстве. - person Pladnius Brooks; 03.08.2012
comment
Мы согласны с терминологией. Согласно документу, который я отправил вам в предыдущем посте, он говорит следующее: если матрица равна сумме матриц проекции и представления модели, то алгоритм дает плоскости отсечения в пространстве модели (т. е. V*P=M, где V — матрица представления модели, а P — матрица проекции). В вашем случае M - это viewMatrix, и он должен работать. - person brano; 03.08.2012
comment
Хорошо. Спасибо. Я буду продолжать в том же духе. - person Pladnius Brooks; 03.08.2012

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

Это первая строка исправленного метода:

m_Frustum[LEFT][A] = (*mat)[0][3] + (*mat)[0][0];
person Bobinar    schedule 10.02.2016