/** Walks through the octree, adding any visible objects to the render queue.
@remarks
If any octant in the octree if completely within the the view frustum,
all subchildren are automatically added with no visibility tests.
*/
public void WalkOctree(OctreeCamera camera, RenderQueue queue, Octree octant,
VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters, bool foundVisible) {
//return immediately if nothing is in the node.
if(octant.NumNodes == 0) {
return;
}
Visibility v = Visibility.None;
if(foundVisible) {
v = Visibility.Full;
}
else if(octant == octree) {
v = Visibility.Partial;
}
else {
AxisAlignedBox box = octant.CullBounds;
v = camera.GetVisibility(box);
}
// if the octant is visible, or if it's the root node...
if(v != Visibility.None) {
if(this.ShowBoundingBoxes) {
// TODO: Implement Octree.WireBoundingBox
//boxList.Add(octant.WireBoundingBox);
}
bool vis = true;
for(int i = 0; i < octant.NodeList.Count; i++) {
OctreeNode node = (OctreeNode)octant.NodeList[i];
// if this octree is partially visible, manually cull all
// scene nodes attached directly to this level.
if(v == Visibility.Partial) {
vis = camera.IsObjectVisible(node.WorldAABB);
}
if(vis) {
numObjects++;
node.AddToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds);
visible.Add(node);
if(DisplayNodes) {
GetRenderQueue().AddRenderable(node);
}
// check if the scene manager or this node wants the bounding box shown.
if(node.ShowBoundingBox || this.ShowBoundingBoxes) {
node.AddBoundingBoxToQueue(queue);
}
}
}
if(octant.Children[0,0,0] != null ) WalkOctree(camera, queue, octant.Children[0,0,0], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[1,0,0] != null ) WalkOctree(camera, queue, octant.Children[1,0,0], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[0,1,0] != null ) WalkOctree(camera, queue, octant.Children[0,1,0], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[1,1,0] != null ) WalkOctree(camera, queue, octant.Children[1,1,0], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[0,0,1] != null ) WalkOctree(camera, queue, octant.Children[0,0,1], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[1,0,1] != null ) WalkOctree(camera, queue, octant.Children[1,0,1], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[0,1,1] != null ) WalkOctree(camera, queue, octant.Children[0,1,1], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
if(octant.Children[1,1,1] != null ) WalkOctree(camera, queue, octant.Children[1,1,1], visibleBounds, onlyShadowCasters, ( v == Visibility.Full ) );
}
}