га
void Quake2Level :: buildClusterTable ( const Vector3D&
pos )
{
Quake2BspLeaf * leaf = findLeaf ( pos );
Глава П. Пишем рендерер уровней Quake II
if ( leaf == NULL I I leaf -> cluster >= numClusters ) return;
long of fs = file -> getPvsOffset ( leaf -> cluster ) ,-unsigned char * pvs = offs + (unsigned char *)
file -> vis;
for ( int i = 0, cl = 0; cl < numClusters; i++ ) if ( pvs [i] == 0 ) // RLE'd zeros
cl += 8 * pvs [++i];
else
for ( unsigned char bit = 1; bit != 0; bit *= 2, cl++ )
if ( pvs [i] & bit )
clusterTable [cl] = frameNo,-
}
Для определения листа дерева, соответствующего текущему положению камеры, служит MSTOnfindLeaf.
Quake2BspLeaf * Quake2Level :: findLeaf ( const Vector3D&
pos ) const
{
int index = file -> hulls [0].headNode;
while ( index >= 0 ) {
Quake2BspNode * node. = &file -> nodes [index]; Quake2BspPlane * plane = &file -> planes [node ->
plane];
if ( (plane -> normal & pos) >= plane -> dist ) index = node -> frontChild;
else
index = node -> backChild;
}
index = -(index +1); // -index
if ( index < 0 II index >= file -> numLeaves ) return NULL;
return &file -> leaves [index];
Этот метод просто обходит дерево, начиная с корня выбирая каждый раз то поддерево, в котором находится камера, до тех пор, пока не дойдет до листа.
В результате работы метода buildCluster Table в массив clusterTable на место, соответствующее кластеру, записывается номер текущего кадра (frameNo) в том случае, если этот лист является потенциально видимым в данном кадре.
Для более точного отсечения невидимых граней по списку потенциально видимых кластеров строится список потенциально видимых граней. Для этого для каждого листа дерева проверяется, попал ли соответствующий кластер в список видимых кластеров (clusterTable [leaf->cluster] == frameNo), и если да, то в случае попадания данного листа в область видимости камеры все грани этого листа записываются в список видимых граней (vis-Polys).