// (front)
BspNode * back; // subtree in negative halfspace
// (back)
BoundingBox box;
BspNode ( Polygon3D * poly ) : Plane ( *poly -> getPlane () )
{
facet = poly; front = NULL;
back = NULL;
}
bool visitlnorder ( BspNodeVisitork );
// front-to-back traversal bool visitPostorder ( BspNodeVisitork );
// back-to-front traversal
const BoundingBoxk getBoundingBox () const {
return box;
}
void setBoundingBox ( const BoundingBox& theBox )
{
box = theBox;
}
} ;
Данный класс выведен из класса Plane, поскольку каждый узел дерева соответствует плоскости разбиения. Поля front и back являются указателями на поддеревья, лежащие в положительном и отрицательном полупространствах соответственно. Поле facet указывает на грань, использованную для проведения разбиения.
Здесь методы visitlnorder и visitPostorder служат для обхода дерева в прямом и обратном nopxji,Ke(front-to-back и back-to-front). Для обхода дерева используется паттерн "Посетитель" [12], соответствующий класс посетителя выглядит следующим образом: Т3|
class BspNodeVisitor {
protected:
Vector3D pos;
public:
BspNodeVisitor ( const Vector3D& v) : pos ( v ) {} virtual -BspNodeVisitor () {}
const Vector3D& getPos () const {
return pos;
}
Пишем портальный рендерер (часть II)
virtual bool wantsNode ( const BspNode * node ) {
return true;
}
virtual bool visit ( BspNode * node ) = 0;
} ;
Метод visit обрабатывает очередной узел дерева и возвращает false для продолжения обхода дерева и true для его прекращения.
Обход дерева реализуется аналогично тому, как это представлено в гл. 2, и выглядит следующим образом: о
bool BspNode :: visitlnorder ( BspNodeVisitork visitor ) {
if ( (visitor.wantsNode ( this ) ) return true;
int cl = classify ( visitor.getPos () );
if ( cl == IN_FRONT ) {
if ( front != NULL )
if ( front -> visitlnorder ( visitor ) ) return true;
if ( visitor.visit ( this ) ) return true;