cNodeTreeMesh::SortNode是一个递归函数,它计算节点3D空间中多边形的数量,并决定节点是否需要分裂为4个或8个子节点(根据树类型)。当节点适当的分裂之后,SortNode函数建立一个多边形列表包含于节点3D空间。
这个函数储存节点的坐标和开始分裂的节点:
void cNodeTreeMesh::SortNode(sNode *Node, / float XPos, float YPos, float ZPos, / float Size) { unsigned long i, Num; float XOff, YOff, ZOff; // Error checking if(Node == NULL || m_PolygonList == NULL) return; // 储存节点坐标、大小 Node->XPos = XPos; Node->YPos = (m_TreeType==QUADTREE)?0.0f:YPos; Node->ZPos = ZPos; Node->Size = Size; // 查看在节点中是否含有多边形 if(!(Num = CountPolygons(XPos, YPos, ZPos, Size))) return; // Split node if size > maximum and too many polygons if(Size > m_MaxSize && Num > m_MaxPolygons) { for(i=0;i<(unsigned long)((m_TreeType==QUADTREE)?4:8);i++) { XOff = (((i % 2) < 1) ? -1.0f : 1.0f) * (Size / 4.0f); ZOff = (((i % 4) < 2) ? -1.0f : 1.0f) * (Size / 4.0f); YOff = (((i % 8) < 4) ? -1.0f : 1.0f) * (Size / 4.0f); // See if any polygons in new node bounding box if(CountPolygons(XPos+XOff,YPos+YOff,ZPos+ZOff, / Size/2.0f)) { Node->Nodes[i] = new sNode(); // Create new child node // Sort the polygons with the new child node SortNode(Node->Nodes[i],XPos+XOff,YPos+YOff, / ZPos+ZOff,Size/2.0f); } } return; } |
直到现在,所有多边形都在节点的盒子中被数。如果有太多的多边形并且节点的盒子太大,那么这个节点就要分裂。随后的节点分裂都是执行相同的处理。现在,不管怎样,空节点被跳过处理,包含多边形的节点又被使用SortNode函数(递归)。
// 为多边形列表指针分配空间 Node->NumPolygons = Num; Node->PolygonList = new sPolygon[Num]; // Scan through polygon list, storing pointers and // assigning them. Num = 0; for(i=0;i<m_NumPolygons;i++) { // Add polygon to node list if contained in 3-D space. if(IsPolygonContained(&m_PolygonList[i], / XPos, YPos, ZPos, Size) == TRUE) Node->PolygonList[Num++] = &m_PolygonList[i]; } } |
这最后的一点代码分配一个指针数组,他指向sPolygon数组。当要渲染时,指向数组的指针被用于返回每个多边形的信息,过扩顶点数据和纹理组。这些被绘的多边形被加入到恰当的纹理组的顶点缓冲,使用的是AddNode函数。