Столкновение точка - плоскость без функций glutLookAt*

Как я понял, рекомендуется использовать glTranslate / glRotate в пользу glutLootAt. Я не собираюсь искать причины, выходящие за рамки очевидного режима вычисления HW против SW, а просто пойду с волной. Тем не менее, это вызывает у меня некоторые головные боли, так как я точно не знаю, как эффективно остановить пробивание камеры через стены. Меня интересуют только пересечения в точечной плоскости, а не AABB или что-то еще.

Таким образом, использование glTranslates и glRotates означает, что точка зрения остается неподвижной (на уровне (0,0,0) для простоты), в то время как мир вращается вокруг нее. Для меня это означает, что для проверки любых точек пересечения мне нужно пересчитать координаты мировых вершин (что не требовалось при подходе glutLookAt) для каждого движения камеры. Поскольку невозможно получить необходимые новые координаты из земли графического процессора, их необходимо вычислять в земле процессора вручную. За каждое движение камеры...:(

Кажется, есть необходимость сохранить текущие повороты в стороне от каждой из 3 осей и одинаковые для трансляций. В моей программе не используется масштабирование. Мои вопросы:

1 - ошибочны ли приведенные выше рассуждения? Как? 2 - если нет, то должен быть способ избежать таких пересчетов. На мой взгляд (и, глядя на http://www.glprogramming.com/red/appendixf.html), нужно одно матричное умножение для переводов и другое для вращения (только в сторону от необходимой оси y). Однако необходимость вычислять так много сложений / умножений, особенно синус / косинус, наверняка убьет FPS. Будут тысячи или даже десятки тысяч вершин для вычисления. Каждый кадр... вся математика... После вычисления новых координат мира все кажется очень простым - просто посмотрите, есть ли какая-либо плоскость, которая сменила знак 'd' (из уравнения плоскостей ax + by + cz + d = 0). Если это так, используйте легкий метод перекрестных продуктов, чтобы проверить, находится ли точка внутри пространства внутри каждого "движущегося" треугольника этой плоскости.

Спасибо

редактировать: я нашел о glGet, и я думаю, что это путь, но я не знаю, как правильно его использовать:

    // Retains the current modelview matrix
//glPushMatrix();
glGetFloatv(GL_MODELVIEW_MATRIX, m_vt16CurrentMatrixVerts);
//glPopMatrix();

m_vt16CurrentMatrixVerts - это число с плавающей точкой [16], которое заполняется значениями 0.f или 8.67453e-13 или чем-то подобным. Где я облажался?

1 ответ

Решение

GluLookAt - очень удобная функция без потери производительности. Нет никаких оснований не использовать его, и, прежде всего, нет никаких соображений по этому поводу. Как заявил Mk12, glRotatef также выполняется на процессоре. Часть графического процессора: gl_Position = ProjectionMatrix x ViewMatrix x ModelMatrix x VertexPosition.

"Использование glTranslates и glRotates означает, что точка обзора остается неподвижной" -> то же самое для gluLookAt

"at (0,0,0) для простоты" -> не для простоты, это факт. Тем не менее, это (0,0,0) находится в системе координат камеры. Это имеет смысл: относительно камеры камера находится в начале координат...

Теперь, если вы хотите, чтобы камера не проходила сквозь стены, обычным способом является отслеживание луча от камеры. Я подозреваю, что это то, о чем вы говорите ("проверить наличие точек пересечения"). Но нет необходимости делать это в пространстве камеры. Вы можете сделать это в мировом пространстве. Вот сравнение:

  • Отслеживание лучей в пространстве камеры: луч всегда начинается с (0,0,0) и идет до (0,0,-1). Геометрия должна быть преобразована из Пространства Модели в Пространство Мира, а затем в Пространство Камеры, что вас раздражает
  • Трассировка лучей в мировом пространстве: луч начинается с положения камеры (в мировом пространстве) и переходит в (eyeCenter - eyePos).normalize(). Геометрия должна быть преобразована из Модельного пространства в Мировое пространство.

Обратите внимание, что не существует третьего варианта (Трассировка лучей в пространстве модели), который позволил бы избежать преобразования геометрии из пространства модели в пространство мира. Тем не менее, у вас есть пара обходных путей:

  • Во-первых, мир вашей игры, вероятно, все еще остается неизменным: матрица модели, вероятно, всегда идентична. Таким образом, преобразование его геометрии из Модели в Пространство Мира равносильно тому, чтобы вообще ничего не делать.
  • Во-вторых, для всех других объектов вы можете использовать противоположный подход. Вместо того, чтобы преобразовать всю геометрию в одном направлении, измените только луч в обратном направлении: возьмите матрицу вашей модели, переверните ее, и вы получите матрицу, которая перемещается из мирового пространства в пространство модели. Умножьте источник и направление вашего луча на эту матрицу: ваш луч теперь находится в модельном пространстве. Пересекаются нормальным способом. Готово.

Обратите внимание, что все, что я сказал, это стандартные методы. Нет хаков или других странных вещей, только математика:)

Другие вопросы по тегам