Beispiel #1
0
		private void WalkOctree( PCZCamera camera,
									ref List<PCZSceneNode> visibleNodeList,
									RenderQueue queue,
									Octree octant,
									VisibleObjectsBoundsInfo visibleBounds,
									bool foundvisible,
									bool onlyShadowCasters,
									bool displayNodes,
									bool showBoundingBoxes )
		{

			//return immediately if nothing is in the node.
			if ( octant.NunodeList == 0 )
				return;

			Visibility v = Visibility.None;

			if ( foundvisible )
			{
				v = Visibility.Full;
			}

			else if ( octant == rootOctree )
			{
				v = Visibility.Partial;
			}

			else
			{
				AxisAlignedBox box = octant.Box;

				v = camera.GetVisibility( box );
			}


			// if the octant is visible, or if it's the root node...
			if ( v != Visibility.None )
			{
				//Add stuff to be rendered;

				bool vis = true;

				foreach ( PCZSceneNode sn in octant.NodeList.Values )
				{
					// if the scene node is already visible, then we can skip it
					if ( sn.LastVisibleFrame != mLastVisibleFrame ||
						sn.LastVisibleFromCamera != camera )
					{
						// if this octree is partially visible, manually cull all
						// scene nodes attached directly to this level.
						if ( v == Visibility.Partial )
						{
							vis = camera.IsObjectVisible( sn.WorldAABB );
						}
						if ( vis )
						{
							// add the node to the render queue
							sn.AddToRenderQueue( camera, queue, onlyShadowCasters, visibleBounds );
							// add it to the list of visible nodes
							visibleNodeList.Add( sn );
							// if we are displaying nodes, add the node renderable to the queue
							if ( displayNodes )
							{
								queue.AddRenderable( sn.GetDebugRenderable() );
							}
							// if the scene manager or the node wants the bounding box shown, add it to the queue
							if ( sn.ShowBoundingBox || showBoundingBoxes )
							{
								sn.AddBoundingBoxToQueue( queue );
							}
							// flag the node as being visible this frame
							sn.LastVisibleFrame = mLastVisibleFrame;
							sn.LastVisibleFromCamera = camera;
						}
					}
				}

				Octree child;
				bool childfoundvisible = ( v == Visibility.Full );
				if ( ( child = octant.Children[ 0, 0, 0 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 1, 0, 0 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 0, 1, 0 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 1, 1, 0 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 0, 0, 1 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 1, 0, 1 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 0, 1, 1 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

				if ( ( child = octant.Children[ 1, 1, 1 ] ) != null )
					WalkOctree( camera, ref visibleNodeList, queue, child, visibleBounds, childfoundvisible,
							   onlyShadowCasters, displayNodes, showBoundingBoxes );

			}
		}
 /// <summary>
 ///		Overloaded method.
 /// </summary>
 /// <param name="camera"></param>
 /// <param name="queue"></param>
 public virtual void FindVisibleObjects(Camera camera, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds)
 {
     // call overloaded method
     FindVisibleObjects(camera, queue, visibleBounds, true, false, false);
 }
        /** 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 ) );
            }
        }
Beispiel #4
0
		public override void FindVisibleNodes( PCZCamera camera, ref List<PCZSceneNode> visibleNodeList, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters, bool displayNodes, bool showBoundingBoxes )
		{
			//return immediately if nothing is in the zone.
			if ( mHomeNodeList.Count == 0 &&
				mVisitorNodeList.Count == 0 &&
				mPortals.Count == 0 )
				return;

			// Else, the zone is automatically assumed to be visible since either
			// it is the camera the zone is in, or it was reached because
			// a connecting portal was deemed visible to the camera.

			// enable sky if called to do so for this zone
			if ( mHasSky )
			{
				// enable sky
				mPCZSM.EnableSky( true );
			}

			// Recursively find visible nodes in the zone
			WalkOctree( camera,
					   ref visibleNodeList,
					   queue,
					   rootOctree,
					   visibleBounds,
					   false,
					   onlyShadowCasters,
					   displayNodes,
					   showBoundingBoxes );

			// find visible portals in the zone and recurse into them
			bool vis;
			foreach ( Portal portal in mPortals )
			{
				// for portal, check visibility using world bounding sphere & direction
				FrustumPlane pl = FrustumPlane.None;
				vis = camera.IsObjectVisible( portal, out pl );
				if ( vis )
				{
					// portal is visible. Add the portal as extra culling planes to camera
					int planes_added = camera.AddPortalCullingPlanes( portal );
					// tell target zone it's visible this frame
					portal.getTargetZone().LastVisibleFrame = mLastVisibleFrame;
					portal.getTargetZone().LastVisibleFromCamera = camera;
					// recurse into the connected zone
					portal.getTargetZone().FindVisibleNodes( camera,
															  ref visibleNodeList,
															  queue,
															  visibleBounds,
															  onlyShadowCasters,
															  displayNodes,
															  showBoundingBoxes );
					if ( planes_added > 0 )
					{
						// Then remove the extra culling planes added before going to the next portal in this zone.
						camera.RemovePortalCullingPlanes( portal );
					}
				}
			}
		}
 /// <summary>
 ///		Overloaded method.
 /// </summary>
 /// <param name="camera"></param>
 /// <param name="queue"></param>
 public virtual void FindVisibleObjects(Camera camera, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds)
 {
     // call overloaded method
     FindVisibleObjects(camera, queue, visibleBounds, true, false, false);
 }
        public override void FindVisibleObjects(Camera cam,  VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters)
        {
            GetRenderQueue().Clear();
            boxList.Clear();
            visible.Clear();

            if(cullCamera) {
                Camera c = cameraList["CullCamera"];

                if(c != null) {
                    cameraInProgress = cameraList["CullCamera"];
                }
            }

            numObjects = 0;

            //walk the octree, adding all visible Octreenodes nodes to the render queue.
            WalkOctree((OctreeCamera)cam, GetRenderQueue(), octree, visibleBounds, onlyShadowCasters, false);

            // Show the octree boxes & cull camera if required
            if(this.ShowBoundingBoxes || cullCamera) {
                if(this.ShowBoundingBoxes) {
                    for(int i = 0; i < boxList.Count; i++) {
                        WireBoundingBox box = (WireBoundingBox)boxList[i];

                        GetRenderQueue().AddRenderable(box);
                    }
                }

                if(cullCamera) {
                    OctreeCamera c = (OctreeCamera)GetCamera("CullCamera");

                    if(c != null) {
                        GetRenderQueue().AddRenderable(c);
                    }
                }
            }
        }
        /// <summary>
        ///     Adds all the attached scenenodes to the render queue.
        /// </summary>
        /// <param name="cam"></param>
        /// <param name="queue"></param>
		public void AddToRenderQueue(Camera cam, RenderQueue queue, bool onlyShadowCasters,
                                     VisibleObjectsBoundsInfo visibleBounds) {
			
            // int i;
            foreach (MovableObject obj in objectList.Values) {
                obj.NotifyCurrentCamera(cam);
			
                if(obj.IsVisible && (!onlyShadowCasters || obj.CastShadows)) {
                    obj.UpdateRenderQueue(queue);
                    if (visibleBounds != null)
                        visibleBounds.Merge(obj.GetWorldBoundingBox(true),
                                            obj.GetWorldBoundingSphere(true),
                                            cam);
                }
            }
        }
Beispiel #8
0
		/** Find and add visible objects to the render queue.
		@remarks
		Starts with objects in the zone and proceeds through visible portals
		This is a recursive call (the main call should be to _findVisibleObjects)
		*/

		public abstract void FindVisibleNodes( PCZCamera camera, ref List<PCZSceneNode> visibleNodeList, RenderQueue queue,
		                                       VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters,
		                                       bool displayNodes, bool showBoundingBoxes );
 /// <summary>
 ///		Internal method which parses the scene to find visible objects to render.
 /// </summary>
 /// <remarks>
 ///		If you're implementing a custom scene manager, this is the most important method to
 ///		override since it's here you can apply your custom world partitioning scheme. Once you
 ///		have added the appropriate objects to the render queue, you can let the default
 ///		SceneManager objects RenderVisibleObjects handle the actual rendering of the objects
 ///		you pick.
 ///		<p/>
 ///		Any visible objects will be added to a rendering queue, which is indexed by material in order
 ///		to ensure objects with the same material are rendered together to minimise render state changes.
 /// </remarks>
 /// <param name="camera"></param>
 public virtual void FindVisibleObjects(Camera camera, VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters)
 {
     // ask the root node to iterate through and find visible objects in the scene
     rootSceneNode.FindVisibleObjects(camera, GetRenderQueue(), visibleBounds, true, displayNodes, onlyShadowCasters);
 }
Beispiel #10
0
		/** Adds the attached objects of this PCZSceneNode into the queue. */
		public void AddToRenderQueue( Camera cam, RenderQueue queue, bool onlyShadowCasters, VisibleObjectsBoundsInfo visibleBounds )
		{
			foreach ( KeyValuePair<string, MovableObject> pair in objectsByName )
			{
				pair.Value.NotifyCurrentCamera( cam );

				if ( pair.Value.IsVisible && ( !onlyShadowCasters || pair.Value.CastShadows ) )
				{
					pair.Value.UpdateRenderQueue( queue );

					if ( !visibleBounds.aabb.IsNull )
					{
						visibleBounds.Merge( pair.Value.GetWorldBoundingBox( true ), pair.Value.GetWorldBoundingSphere( true ), cam );
					}
				}
			}
		}
        /// <summary>
        ///		Creates a camera to be managed by this scene manager.
        /// </summary>
        /// <remarks>
        ///		This camera can be added to the scene at a later time using
        ///		the AttachObject method of the SceneNode class.
        ///	 </remarks>
        ///	 <param name="name"></param>
        /// <returns></returns>
        public virtual Camera CreateCamera(string name)
        {
            if (cameraList.ContainsKey(name)) {
                throw new AxiomException(string.Format("A camera with the name '{0}' already exists in the scene.", name));
            }

            // create the camera and add it to our local list
            Camera camera = new Camera(name, this);
            cameraList[name] = camera;

            // create visible bounds aabb map entry
            camVisibleObjectsMap[camera] = new VisibleObjectsBoundsInfo();

            return camera;
        }
        /// <summary>
        ///		Internal method which locates any visible objects attached to this node and adds them to the passed in queue.
        /// </summary>
        /// <param name="camera">Active camera.</param>
        /// <param name="queue">Queue to which these objects should be added.</param>
        /// <param name="includeChildren">If true, cascades down to all children.</param>
        /// <param name="displayNodes">Renders the local axes for the node.</param>
        /// <param name="onlyShadowCasters"></param>
        public virtual void FindVisibleObjects(Camera camera, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds, bool includeChildren, bool displayNodes, bool onlyShadowCasters)
        {
            // if we aren't visible, then quit now
            // TODO: Make sure sphere is calculated properly for all objects, then switch to cull using that
            if(!camera.IsObjectVisible(worldAABB))
                return;

            // add visible objects to the render queue
            //objectListMeter.Enter();
            foreach (MovableObject obj in objectList.Values) {
                // tell attached object about current camera in case it wants to know
                //notifyCameraMeter.Enter();
                obj.NotifyCurrentCamera(camera);
                //notifyCameraMeter.Exit();

                // if this object is visible, add it to the render queue
                if(obj.IsVisible &&
                    (!onlyShadowCasters || obj.CastShadows)) {
                    //updateQueueMeter.Enter();
                    obj.UpdateRenderQueue(queue);
                    //updateQueueMeter.Exit();

                    // update visible boundaries aab
                    if (visibleBounds != null)
                        visibleBounds.Merge(obj.GetWorldBoundingBox(true),
                                            obj.GetWorldBoundingSphere(true),
                                            camera);
                }
            }
            //objectListMeter.Exit();

            //childListMeter.Enter();
            if(includeChildren) {
                // ask all child nodes to update the render queue with visible objects
                foreach (SceneNode childNode in childNodes.Values) {
                    if(childNode.Visible)
                        childNode.FindVisibleObjects(camera, queue, visibleBounds, includeChildren, displayNodes, onlyShadowCasters);
                }
            }
            //childListMeter.Exit();

            // if we wanna display nodes themself..
            if(displayNodes) {
                // hey, lets just add ourself right to the render queue
                queue.AddRenderable(this);
            }

            // do we wanna show our beautiful bounding box?
            // do it if either we want it, or the SceneManager dictates it
            if(showBoundingBox || creator.ShowBoundingBoxes) {
                AddBoundingBoxToQueue(queue);
            }
        }
 /// <summary>
 ///		Overloaded method.
 /// </summary>
 /// <param name="camera"></param>
 /// <param name="queue"></param>
 /// <param name="includeChildren"></param>
 /// <param name="displayNodes"></param>
 public virtual void FindVisibleObjects(Camera camera, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds, bool includeChildren, bool displayNodes)
 {
     // call overloaded method
     FindVisibleObjects(camera, queue, visibleBounds, includeChildren, displayNodes, false);
 }
 /// <summary>
 ///		Overloaded method.
 /// </summary>
 /// <param name="camera"></param>
 /// <param name="queue"></param>
 /// <param name="includeChildren"></param>
 /// <param name="displayNodes"></param>
 public virtual void FindVisibleObjects(Camera camera, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds, bool includeChildren, bool displayNodes)
 {
     // call overloaded method
     FindVisibleObjects(camera, queue, visibleBounds, includeChildren, displayNodes, false);
 }
Beispiel #15
0
		// main visibility determination & render queue filling routine
		// over-ridden from base/default scene manager.  This is *the*
		// main call.
		public void FindVisibleObjects( Camera cam, VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters )
		{
			// clear the render queue
			renderQueue.Clear();
			// clear the list of visible nodes
			this.visibleNodes.Clear();

			// turn off sky
			EnableSky( false );

			// remove all extra culling planes
			( (PCZCamera)cam ).RemoveAllExtraCullingPlanes();

			// increment the visibility frame counter
			//mFrameCount++;
			this.frameCount = Root.Instance.CurrentFrameCount;

			// update the camera
			( (PCZCamera)cam ).Update();

			// get the home zone of the camera
			PCZone cameraHomeZone = ( (PCZSceneNode)( cam.ParentSceneNode ) ).HomeZone;

			// walk the zones, starting from the camera home zone,
			// adding all visible scene nodes to the mVisibles list
			cameraHomeZone.LastVisibleFrame = this.frameCount;
			cameraHomeZone.FindVisibleNodes( (PCZCamera)cam, ref this.visibleNodes, renderQueue, visibleBounds, onlyShadowCasters,
			                                 displayNodes, showBoundingBoxes );
		}
        /// <summary>
        ///		Internal method which locates any visible objects attached to this node and adds them to the passed in queue.
        /// </summary>
        /// <param name="camera">Active camera.</param>
        /// <param name="queue">Queue to which these objects should be added.</param>
        /// <param name="includeChildren">If true, cascades down to all children.</param>
        /// <param name="displayNodes">Renders the local axes for the node.</param>
        /// <param name="onlyShadowCasters"></param>
        public virtual void FindVisibleObjects(Camera camera, RenderQueue queue, VisibleObjectsBoundsInfo visibleBounds, bool includeChildren, bool displayNodes, bool onlyShadowCasters)
        {
            // if we aren't visible, then quit now
            // TODO: Make sure sphere is calculated properly for all objects, then switch to cull using that
            if (!camera.IsObjectVisible(worldAABB))
            {
                return;
            }

            // add visible objects to the render queue
            //objectListMeter.Enter();
            foreach (MovableObject obj in objectList.Values)
            {
                // tell attached object about current camera in case it wants to know
                //notifyCameraMeter.Enter();
                obj.NotifyCurrentCamera(camera);
                //notifyCameraMeter.Exit();

                // if this object is visible, add it to the render queue
                if (obj.IsVisible &&
                    (!onlyShadowCasters || obj.CastShadows))
                {
                    //updateQueueMeter.Enter();
                    obj.UpdateRenderQueue(queue);
                    //updateQueueMeter.Exit();

                    // update visible boundaries aab
                    if (visibleBounds != null)
                    {
                        visibleBounds.Merge(obj.GetWorldBoundingBox(true),
                                            obj.GetWorldBoundingSphere(true),
                                            camera);
                    }
                }
            }
            //objectListMeter.Exit();

            //childListMeter.Enter();
            if (includeChildren)
            {
                // ask all child nodes to update the render queue with visible objects
                foreach (SceneNode childNode in childNodes.Values)
                {
                    if (childNode.Visible)
                    {
                        childNode.FindVisibleObjects(camera, queue, visibleBounds, includeChildren, displayNodes, onlyShadowCasters);
                    }
                }
            }
            //childListMeter.Exit();

            // if we wanna display nodes themself..
            if (displayNodes)
            {
                // hey, lets just add ourself right to the render queue
                queue.AddRenderable(this);
            }

            // do we wanna show our beautiful bounding box?
            // do it if either we want it, or the SceneManager dictates it
            if (showBoundingBox || creator.ShowBoundingBoxes)
            {
                AddBoundingBoxToQueue(queue);
            }
        }
 public override Camera CreateCamera(string name)
 {
     Camera cam = new OctreeCamera(name, this);
     cameraList.Add(name, cam);
     // create visible bounds aabb map entry
     camVisibleObjectsMap[cam] = new VisibleObjectsBoundsInfo();
     return cam;
 }
Beispiel #18
0
		/*
		// Recursively walk the zones, adding all visible SceneNodes to the list of visible nodes.
		*/
		public override void FindVisibleNodes( PCZCamera camera,
									  ref List<PCZSceneNode> visibleNodeList,
									  RenderQueue queue,
									  VisibleObjectsBoundsInfo visibleBounds,
									  bool onlyShadowCasters,
									  bool displayNodes,
									  bool showBoundingBoxes )
		{

			//return immediately if nothing is in the zone.
			if ( mHomeNodeList.Count == 0 &&
				mVisitorNodeList.Count == 0 &&
				mPortals.Count == 0 )
				return;

			// Else, the zone is automatically assumed to be visible since either
			// it is the camera the zone is in, or it was reached because
			// a connecting portal was deemed visible to the camera.

			// enable sky if called to do so for this zone
			if ( HasSky )
			{
				// enable sky
				mPCZSM.EnableSky( true );
			}

			// find visible nodes at home in the zone
			bool vis;

			foreach ( PCZSceneNode pczsn in mHomeNodeList )
			{
				//PCZSceneNode pczsn = *it;
				// if the scene node is already visible, then we can skip it
				if ( pczsn.LastVisibleFrame != mLastVisibleFrame ||
					pczsn.LastVisibleFromCamera != camera )
				{
					FrustumPlane fPlane;
					// for a scene node, check visibility using AABB
					vis = camera.IsObjectVisible( pczsn.WorldAABB, out fPlane );
					if ( vis )
					{
						// add it to the list of visible nodes
						visibleNodeList.Add( pczsn );
						// add the node to the render queue
						pczsn.AddToRenderQueue( camera, queue, onlyShadowCasters, visibleBounds );
						// if we are displaying nodes, add the node renderable to the queue
						if ( displayNodes )
						{
							queue.AddRenderable( pczsn.GetDebugRenderable() );
						}
						// if the scene manager or the node wants the bounding box shown, add it to the queue
						if ( pczsn.ShowBoundingBox || showBoundingBoxes )
						{
							pczsn.AddBoundingBoxToQueue( queue );
						}
						// flag the node as being visible this frame
						pczsn.LastVisibleFrame = mLastVisibleFrame;
						pczsn.LastVisibleFromCamera = camera;
					}
				}
			}
			// find visible visitor nodes

			foreach ( PCZSceneNode pczsn in mVisitorNodeList )
			{
				// if the scene node is already visible, then we can skip it
				if ( pczsn.LastVisibleFrame != mLastVisibleFrame ||
					pczsn.LastVisibleFromCamera != camera )
				{
					FrustumPlane fPlane;
					// for a scene node, check visibility using AABB
					vis = camera.IsObjectVisible( pczsn.WorldAABB, out fPlane );
					if ( vis )
					{
						// add it to the list of visible nodes
						visibleNodeList.Add( pczsn );
						// add the node to the render queue
						pczsn.AddToRenderQueue( camera, queue, onlyShadowCasters, visibleBounds );
						// if we are displaying nodes, add the node renderable to the queue
						if ( displayNodes )
						{
							queue.AddRenderable( pczsn.GetDebugRenderable() );
						}
						// if the scene manager or the node wants the bounding box shown, add it to the queue
						if ( pczsn.ShowBoundingBox || showBoundingBoxes )
						{
							pczsn.AddBoundingBoxToQueue( queue );
						}
						// flag the node as being visible this frame
						pczsn.LastVisibleFrame = mLastVisibleFrame;
						pczsn.LastVisibleFromCamera = camera;
					}
				}
			}

			// find visible portals in the zone and recurse into them
			foreach ( Portal portal in mPortals )
			{
				FrustumPlane fPlane;
				// for portal, check visibility using world bounding sphere & direction
				vis = camera.IsObjectVisible( portal, out fPlane );
				if ( vis )
				{
					// portal is visible. Add the portal as extra culling planes to camera
					int planes_added = camera.AddPortalCullingPlanes( portal );
					// tell target zone it's visible this frame
					portal.getTargetZone().LastVisibleFrame = mLastVisibleFrame;
					portal.getTargetZone().LastVisibleFromCamera = camera;
					// recurse into the connected zone
					portal.getTargetZone().FindVisibleNodes( camera,
															  ref visibleNodeList,
															  queue,
															  visibleBounds,
															  onlyShadowCasters,
															  displayNodes,
															  showBoundingBoxes );
					if ( planes_added > 0 )
					{
						// Then remove the extra culling planes added before going to the next portal in this zone.
						camera.RemovePortalCullingPlanes( portal );
					}
				}
			}
		}
 /// <summary>
 /// 
 /// </summary>
 /// <param name="camera"></param>
 public override void FindVisibleObjects(Camera camera,  VisibleObjectsBoundsInfo visibleBounds, bool onlyShadowCasters)
 {
     base.FindVisibleObjects (camera, visibleBounds, onlyShadowCasters);
 }