Гшва 2. Удаление невидимых поверхностей

Так, портал В в антитень не попадает и поэтому сразу же может быть отброшен. С другой стороны, портал А частично попадает в антитень и поэтому через него может быть видна лежащая за ним комната.

Следующим шагом будет определение видимости за порталом А. Для этого портал А сначала обрезается по границе антитени, и комната, лежащая за ним, становится новым generatorLeaf. После этого описанная процедура применяется снова.

Обратите внимание, что на рис. 2.32 вместо портала Л используется обрезанный на предыдущем шаге портал А'.

В результате мы получаем рекурсивную процедуру определения видимости. Она может быть выражена при помощи следующего фрагмента псевдокода:

def buildPvs (leaf, pvs): pvs = [leaf]
for srcPortal in leaf.portals: dstLeaf = srcPortal.leafs [0]
if dstLeaf == leaf:
dstLeaf = srcPortal.leafs [1]
for dstPortal in dstLeaf.portals:
if dstPortal.plane != srcPortal.plane: recursePvs ( leaf, srcPortal, dstLeaf, dstPortal, pvs )

Функция recursePvs служит для рекурсивного обхода цепочки комнат и порталов. В ходе ее работы по очереди выбирается genLeaf п проверяются все его порталы.

W
def recursePvs ( srcLeaf, srcPortal, dstLeaf, dstPortal, pvs ): genLeaf = dstPortal.leafs [0]
if genLeaf == dstLeaf:
genPortal = dstPortal.leafs [1]
pvs.insert ( genLeaf )
for genPortal in genLeaf.portals:
if dstPortal.plane == genPortal.plane: continue
clippedPortal = clipPortalToAntiPenumbrae ( srcPortal,
dstPortal, genPortal )
if clippedPorta.isEmpty: continue
recursePvs ( srcLeaf, srcPortal, clippedPortal, genLeaf, pvs )

Удаление невидимых поверхностей

Процедура clipPortalToAntiPenumbrae служит для отсечения портала по антитени, построенной по двум другим порталам.

def clipPortalToAntiPenumbrae ( srcPortal, dstPortal, portal ): planes = []
addClipPlanes ( srcPortla, dstPortal, planes ) addClipPlanes ( dstPortal, srcPortal, planes )
for plane in planes:
loc = plane.classify ( portal ) sloe = plane.classify ( srcPortal )

⇐ Предыдущая| |Следующая ⇒