/** 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, bool foundVisible ) { Queue<WalkQueueObject> q = new Queue<WalkQueueObject>(); WalkQueueObject temp = new WalkQueueObject( octant, foundVisible ); q.Enqueue( temp ); while ( q.Count > 0 ) { temp = q.Dequeue(); //return immediately if nothing is in the node. if ( temp.Octant.NumNodes == 0 ) { continue; } Visibility v = Visibility.None; if ( temp.FoundVisible ) { v = Visibility.Full; } else if ( temp.Octant == octree ) { v = Visibility.Partial; } else { AxisAlignedBox box = temp.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 ) { boxList.Add( temp.Octant.WireBoundingBox ); } bool vis = true; foreach ( OctreeNode node in temp.Octant.NodeList.Values ) { // 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 ); visible.Add( node ); if ( DisplayNodes ) { GetRenderQueue().AddRenderable( node.GetDebugRenderable() ); } // check if the scene manager or this node wants the bounding box shown. if ( node.ShowBoundingBox || this.ShowBoundingBoxes ) { node.AddBoundingBoxToQueue( queue ); } } } if ( temp.Octant.Children[ 0, 0, 0 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 0, 0, 0 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 0, 0, 0 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 1, 0, 0 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 1, 0, 0 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 1, 0, 0 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 0, 1, 0 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 0, 1, 0 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 0, 1, 0 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 1, 1, 0 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 1, 1, 0 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 1, 1, 0 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 0, 0, 1 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 0, 0, 1 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 0, 0, 1 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 1, 0, 1 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 1, 0, 1 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 1, 0, 1 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 0, 1, 1 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 0, 1, 1 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 0, 1, 1 ], ( v == Visibility.Full ) ); //continue; } if ( temp.Octant.Children[ 1, 1, 1 ] != null ) { q.Enqueue( new WalkQueueObject( temp.Octant.Children[ 1, 1, 1 ], v == Visibility.Full ) ); //WalkOctree( camera, queue, octant.Children[ 1, 1, 1 ], ( v == Visibility.Full ) ); //continue; } } } }
/** 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 ) ); } }
/** 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, bool foundVisible) { var q = new Queue <WalkQueueObject>(); var temp = new WalkQueueObject(octant, foundVisible); q.Enqueue(temp); while (q.Count > 0) { temp = q.Dequeue(); //return immediately if nothing is in the node. if (temp.Octant.NumNodes == 0) { continue; } Visibility v = Visibility.None; if (temp.FoundVisible) { v = Visibility.Full; } else if (temp.Octant == this.octree) { v = Visibility.Partial; } else { AxisAlignedBox box = temp.Octant.CullBounds; v = camera.GetVisibility(box); } // if the octant is visible, or if it's the root node... if (v != Visibility.None) { if (ShowBoundingBoxes) { this.boxList.Add(temp.Octant.WireBoundingBox); } bool vis = true; foreach (OctreeNode node in temp.Octant.NodeList.Values) { // 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) { this.numObjects++; node.AddToRenderQueue(camera, queue); this.visible.Add(node); if (DisplayNodes) { GetRenderQueue().AddRenderable(node.GetDebugRenderable()); } // check if the scene manager or this node wants the bounding box shown. if (node.ShowBoundingBox || ShowBoundingBoxes) { node.AddBoundingBoxToQueue(queue); } } } if (temp.Octant.Children[0, 0, 0] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[0, 0, 0], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 0, 0, 0 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[1, 0, 0] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[1, 0, 0], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 1, 0, 0 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[0, 1, 0] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[0, 1, 0], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 0, 1, 0 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[1, 1, 0] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[1, 1, 0], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 1, 1, 0 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[0, 0, 1] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[0, 0, 1], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 0, 0, 1 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[1, 0, 1] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[1, 0, 1], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 1, 0, 1 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[0, 1, 1] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[0, 1, 1], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 0, 1, 1 ], ( v == Visibility.Full ) ); //continue; } if (temp.Octant.Children[1, 1, 1] != null) { q.Enqueue(new WalkQueueObject(temp.Octant.Children[1, 1, 1], v == Visibility.Full)); //WalkOctree( camera, queue, octant.Children[ 1, 1, 1 ], ( v == Visibility.Full ) ); //continue; } } } }