Сообщение от Кирпи4
Окей, раскрываю
У меня есть меш за стеной, и, допустим, баундинг бокс в виде куба.
Нужно сделать так, чтобы меш хайдился, если баундинг бокс полностью загорожен. EntityVisible - вообще убило меня, так как он проверяет на видимость ЦЕНТР ентити - бред...
|
юзать порталы и\или антипорталы (оклудеры).
порталы, грубо говоря, это полигоны описывающие проемы в стенах.
их можно построить в дерево.
т.е. определить какие порталы видны из другого и запилить иерархию.
это можно сделать либо вручную в редакторе, либо автоматически, примерно так ( как вариант ):
берем каждый портал
определяем какие порталы находятся с одной стороны, а какие с другой, и так-же делим геометрию сцены
для каждой стороны
"рисуем" геометрию в буфер глубины
"рисуем" другие порталы в буфер без записи, но с тестом и определяем виден он или нет
добавляем видимые порталы, соответственно стороне, в две ветки текущего портала
и т.д.
для "рисовать", я бы набросал софтварный растеризатор простейший, от него впринципе требуется только 32 битное значение глубины интерполировать, так что там все просто. ( это можно например оформить в тулзу, которая будет хавать сцену, а высирать построеную иерархию как файлик )
от каждого портала можно построить фрустум, т.е.
берем по паре вершин от полигона портала (по его ребрам)
строим пару векторов от камеры до этих вершин
векторно перемножаем, нормализовываем и получаем нормаль плоскости
скалярное прозведение этой нормали с вектором "камера-центр координат" даст четвертую компоненту плоскости.
в результате получишь несколько плоскостей которые и будут фрустумом
соответственно как происходит кулинг сцены:
пробегаем по порталам по иерархии видимости
режем полигон портала фрустумом ( ибо он можнт быть виден только частично, и чтобы правильный фрустум через него построить, нужно определить видимую часть этого портала )
строим новый фрустум из урезанного полигона
насчет "режем полигон"
можно заюзать например алгоритм сазерленда-ходжмана
суть его примерно такова:
проходим по полигону, через его ребра
с помощью двух скалярных произведений пары вершин ребра и плоскости, которой этот полигон режется, определяем три ситуации:
1 оба произведения отрицательны - обе вершины находятся с отсеченной стороны плоскости
2 одно из произведений положительно - одна вершина с одной стороны плоскости, другая - с другой, значит ребро пересекает плоскость - один вертекс ( который с положительным произведением ) помещаем в результирующий полигон, а второй вертекс - точка пересечения ребра с плоскостью, ее находим и тоже в результируюй полигон
3 оба произведения положительны - обе вершины с отсекаемой стороны плоскости, добавляем обе в результирующий полигон
в результате получится полигон, урезанный плоскостью
для обрезки по фрустуму - просто режем полигон последовательно всеми плоскостями фрустума.
исходный фрустум - фрустум камеры, проходя по иерархии порталов ты этот фрустум через ихние полигоны колбасишь, и по ходу проверяешь вхождение обьектов в этот фрустум.
по хорошему надо строить например какое-нить октарное дерево, делить геометрию сцены между узлами этого дерева, и порталы соответственно тоже, чтобы не колбасить лишнего.
антипорталами может выступать любая геометрия. Принцип тот же самый - строим через окклудер фрустум, и все что в него входит уже наоборот - скрывается. Если геометрия окклудера сложная ( т.е. не просто полигон, а например куб ), то сначала надо определить силуэтные вершины ( минимальные\максимальные по проекции на плоскость камеры ), и по ним уже построить фрустум так-же, как описал выше для портала.
ЗЫ
извиняюсь за этот поток сознания
писал в спешке, попзжа подробнее опишу, если надо конечно.