Показать сообщение отдельно
Старый 27.09.2012, 07:32   #5
Platon
Знающий
 
Регистрация: 04.08.2006
Адрес: Россия
Сообщений: 297
Написано 39 полезных сообщений
(для 70 пользователей)
Ответ: Скрытие объектов за стенами

Сообщение от Кирпи4 Посмотреть сообщение
Окей, раскрываю
У меня есть меш за стеной, и, допустим, баундинг бокс в виде куба.
Нужно сделать так, чтобы меш хайдился, если баундинг бокс полностью загорожен. EntityVisible - вообще убило меня, так как он проверяет на видимость ЦЕНТР ентити - бред...
юзать порталы и\или антипорталы (оклудеры).

порталы, грубо говоря, это полигоны описывающие проемы в стенах.

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

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

соответственно как происходит кулинг сцены:
пробегаем по порталам по иерархии видимости
режем полигон портала фрустумом ( ибо он можнт быть виден только частично, и чтобы правильный фрустум через него построить, нужно определить видимую часть этого портала )
строим новый фрустум из урезанного полигона

насчет "режем полигон"
можно заюзать например алгоритм сазерленда-ходжмана
суть его примерно такова:
проходим по полигону, через его ребра
с помощью двух скалярных произведений пары вершин ребра и плоскости, которой этот полигон режется, определяем три ситуации:
1 оба произведения отрицательны - обе вершины находятся с отсеченной стороны плоскости
2 одно из произведений положительно - одна вершина с одной стороны плоскости, другая - с другой, значит ребро пересекает плоскость - один вертекс ( который с положительным произведением ) помещаем в результирующий полигон, а второй вертекс - точка пересечения ребра с плоскостью, ее находим и тоже в результируюй полигон
3 оба произведения положительны - обе вершины с отсекаемой стороны плоскости, добавляем обе в результирующий полигон
в результате получится полигон, урезанный плоскостью
для обрезки по фрустуму - просто режем полигон последовательно всеми плоскостями фрустума.

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

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

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

ЗЫ
извиняюсь за этот поток сознания писал в спешке, попзжа подробнее опишу, если надо конечно.
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо Platon за это полезное сообщение:
Dzirt (27.09.2012), HolyDel (27.09.2012), Mr_F_ (28.09.2012), Черный крыс (28.09.2012)