ПРОБЛЕМА ПЕРЕКТОРЫ
-
27-10-2019 - |
Вопрос
Я пытаюсь внедрить Frustum, отбрасывая в мою игру OpenGL 2D. Единственным видом геометрических объектов в моей игре на данный момент являются прямоугольники, поэтому я подумал, что это будет довольно легко, но я получаю неожиданные результаты. Я установил симметричную прогрессную проекцию с углом поля обзора 45 градусов, а также в ближайших и дальних плоскостях-0,01 и 50 соответственно. Вектор глаз всегда параллелен оси Z, камера может перемещаться только по осям x и y.
Моя идея состояла в том, чтобы получить прямоугольную область мира, которое в настоящее время видно для камеры на Z-координате прямоугольника, который я пытаюсь отбрасывать. Поскольку камера смотрит на центр rustum, я рассчитываю расстояние до краев этой видимой прямоугольной области следующим образом:
GLfloat maxDistance = givenRectangle.z * tanf(0.5 * (fovAngle * M_PI/180) );
Затем я добавляю и преодолеваю это расстояние к координатам x и y камеры, чтобы получить максимальный и минимальный видимый x и y, а затем проверяю заданный прямоугольник, чтобы увидеть, находится ли он между этими значениями.
Мой вопрос заключается в том, нахожусь ли я здесь на правильном пути, и почему приведенная выше формула возвращает абсурдно небольшое значение (что-то*10^-37), когда у меня есть объект при z = 5, что должно быть явно видно с камерой в (( 0,0,0)?
Решение
Взяв проблему сверху, я проверил вашу формулу - см. Эскиз, чтобы подтвердить, что я правильно вас понял.
Учитывая, что мы знаем A и Z и хотим решить для X, я впервые написал:
tan (a) = x/z
перестановка, я получаю:
X = z tan (a)
Поскольку z = 5 и a = 22,5 градусов ...
X = 5* tan (22,5 градуса)
X = 2,07106781
Таким образом, кажется, что у вас правильная математика, но ваш код неправильный - возможно, ваша функция загара ожидает степеней, а не радианами, или Fovangle не было установлено? Я думаю, что вам нужно отлаживать и проверить каждое значение.
Возвращаясь к более широкой проблеме выяснения того, что делает и не лежит внутри вашего Frustum, вы можете обнаружить, что вы можете использовать другой тест, чтобы ответить на один и тот же вопрос более элегантно. Многие графические кодеры используют тест «сторона плоскости». Учтите, что ваш просмотр Frustum представляет собой объем пространства, ограниченный набором из 6 плоскостей (4 для боковых сторон вашего просмотра, плоскость с почти отсеиванием и плоскость дальнего отсечения).
Учитывая точку на плоскости и норму для плоскости, вы можете легко рассчитать уравнение плоскости, которое, в свою очередь, делает тривиальным проверить, находится ли данная точка «внутри» (в направлении нормального) данной плоскости. Анкет Относитесь через все 6 плоскостей, и вы быстро пранизуете данную точку в том или иной или выходите из своего объема просмотра.
Действительно отличная вещь в этом тесте заключается в том, как легко вы можете повторно использовать его: любой простой выпуклый многоугольник, который вы хотите провести тесты (например, прямоугольник), можно описать как набор плоскостей, позволяя вам повторно использовать свой Тест "Инсайдер или снаружи". Очень общий.