Class to manage the scene object rendering queue.
Objects are grouped by material to minimize rendering state changes. The map from material to renderable object is wrapped in a class for ease of use.

This class includes the concept of 'queue groups' which allows the application adding the renderable to specifically schedule it so that it is included in a discrete group. Good for separating renderables into the main scene, backgrounds and overlays, and also could be used in the future for more complex multipass routines like stenciling.

        /// <summary>
        ///		Default constructor.
        /// </summary>
        /// <param name="parent">Render queue that owns this group.</param>
        /// <param name="splitPassesByLightingType">Split passes based on lighting stage?</param>
        /// <param name="splitNoShadowPasses"></param>
        public RenderQueueGroup(RenderQueue parent, bool splitPassesByLightingType,
                                bool splitNoShadowPasses, bool shadowCastersCannotBeReceivers)
        {
            // shadows enabled by default
            shadowsEnabled = true;

            this.splitPassesByLightingType      = splitPassesByLightingType;
            this.splitNoShadowPasses            = splitNoShadowPasses;
            this.shadowCastersCannotBeReceivers = shadowCastersCannotBeReceivers;
            this.parent = parent;
        }
        /// <summary>
        ///		Default constructor.
        /// </summary>
        /// <param name="parent">Render queue that owns this group.</param>
        /// <param name="splitPassesByLightingType">Split passes based on lighting stage?</param>
        /// <param name="splitNoShadowPasses"></param>
        public RenderQueueGroup(RenderQueue parent, bool splitPassesByLightingType,
                                bool splitNoShadowPasses, bool shadowCastersCannotBeReceivers)
        {
            // shadows enabled by default
            shadowsEnabled = true;

            this.splitPassesByLightingType = splitPassesByLightingType;
            this.splitNoShadowPasses = splitNoShadowPasses;
            this.shadowCastersCannotBeReceivers = shadowCastersCannotBeReceivers;
            this.parent = parent;
        }
Exemplo n.º 3
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 );
Exemplo n.º 4
0
		/// <summary>
		///    Internal method to put the contents onto the render queue.
		/// </summary>
		/// <param name="queue">Current render queue.</param>
		public virtual void UpdateRenderQueue( RenderQueue queue )
		{
			if ( isVisible )
			{
				queue.AddRenderable( this, (ushort)zOrder, RenderQueueGroupID.Overlay );
			}
		}
Exemplo n.º 5
0
		/// <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 )
		{

			int i;
			foreach ( MovableObject obj in objectList.Values )
			{
				obj.NotifyCurrentCamera( cam );

				if ( obj.IsVisible )
				{
					obj.UpdateRenderQueue( queue );
				}
			}
		}
		public void UpdateRenderQueue( RenderQueue queue, bool updateChildren )
		{
			if ( isVisible )
			{
				// call base class method
				base.UpdateRenderQueue( queue );

				if ( updateChildren )
				{
					foreach ( var child in this.children.Values )
					{
						child.UpdateRenderQueue( queue );
					}
				}
			}
		}
Exemplo n.º 7
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="queue"></param>
 public override void UpdateRenderQueue(RenderQueue queue)
 {
     // add ourself to the render queue
     queue.AddRenderable(this, RenderQueueGroup);
 }
Exemplo n.º 8
0
 public override void UpdateRenderQueue( RenderQueue queue )
 {
     /* not needed */
 }
        public override void UpdateRenderQueue(RenderQueue queue)
        {
            if (isVisible)
            {
                if (TerrainManager.Instance.DrawTerrain)
                {
                    if (renderOp.vertexData == null)
                    {
                        // the object is visible so we had better make sure it has vertex and index buffers
                        buildVertexData();
                    }

                    // put terrain in its own render queue for easier profiling
                    queue.AddRenderable(this, RenderQueue.DEFAULT_PRIORITY, RenderQueueGroupID.Main);
                }
            }
        }
Exemplo n.º 10
0
 public override void UpdateRenderQueue(RenderQueue queue)
 {
     // do nothing
 }
Exemplo n.º 11
0
		public override void UpdateRenderQueue( RenderQueue queue )
		{
			queue.AddRenderable( this );
		}
        public override void UpdateRenderQueue(RenderQueue queue, 
                                               List<Particle> currentParticles, 
                                               bool cullIndividually)
        {
            billboardSet.CullIndividual = cullIndividually;

            // Update billboard set geometry
            billboardSet.BeginBillboards();
            Billboard bb = new Billboard();
            foreach (Particle p in currentParticles) {
                bb.Position = p.Position;
                if (billboardSet.BillboardType == BillboardType.OrientedSelf ||
                    billboardSet.BillboardType == BillboardType.PerpendicularSelf)
                {
                    // Normalise direction vector
                    bb.Direction = p.Direction;
                    bb.Direction.Normalize();
                }
                bb.Color = p.Color;
                bb.rotationInRadians = p.rotationInRadians;
                bb.HasOwnDimensions = p.HasOwnDimensions;
                if (bb.HasOwnDimensions)
                {
                    bb.width = p.Width;
                    bb.height = p.Height;
                }
                billboardSet.InjectBillboard(bb);
            }

            billboardSet.EndBillboards();

            // Update the queue
            billboardSet.UpdateRenderQueue(queue);
        }
Exemplo n.º 13
0
        /// <summary>
        ///    Internal method to put the overlay contents onto the render queue.
        /// </summary>
        /// <param name="camera">Current camera being used in the render loop.</param>
        /// <param name="queue">Current render queue.</param>
        public void FindVisibleObjects(Camera camera, RenderQueue queue)
        {
            if(!isVisible) {
                return;
            }

            // add 3d elements
            rootNode.Position = camera.DerivedPosition;
            rootNode.Orientation = camera.DerivedOrientation;
            rootNode.Update(true, false);

            // set up the default queue group for the objects about to be added
            RenderQueueGroupID oldGroupID = queue.DefaultRenderGroup;
            queue.DefaultRenderGroup = RenderQueueGroupID.Overlay;
            rootNode.FindVisibleObjects(camera, queue, null, true, false);
            // reset the group
            queue.DefaultRenderGroup = oldGroupID;

            // add 2d elements
            for(int i = 0; i < elementList.Count; i++) {
                OverlayElementContainer container = (OverlayElementContainer)elementList[i];
                container.Update();
                container.UpdateRenderQueue(queue);
            }
        }
        /// <summary>
        ///		Internal method for queueing the visible overlays for rendering.
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="queue"></param>
        /// <param name="viewport"></param>
        internal void QueueOverlaysForRendering(Camera camera, RenderQueue queue, Viewport viewport)
        {
            // Flag for update pixel-based OverlayElements if viewport has changed dimensions
            if(lastViewportWidth != viewport.ActualWidth ||
                lastViewportHeight != viewport.ActualHeight) {

                viewportDimensionsChanged = true;
                lastViewportWidth = viewport.ActualWidth;
                lastViewportHeight = viewport.ActualHeight;
            }
            else {
                viewportDimensionsChanged = false;
            }

            // TODO: optimize this resource list to avoid the foreach
            foreach(Overlay overlay in resourceList.Values) {
                overlay.FindVisibleObjects(camera, queue);
            }
        }
Exemplo n.º 15
0
		/// <summary>
		///		Internal method for initializing the render queue.
		/// </summary>
		/// <remarks>
		///		Subclasses can use this to install their own <see cref="RenderQueue"/> implementation.
		/// </remarks>
		protected virtual void InitRenderQueue()
		{
			this.renderQueue = new RenderQueue();

			// init render queues that do not need shadows
			this.renderQueue.GetQueueGroup( RenderQueueGroupID.Background ).ShadowsEnabled = false;
			this.renderQueue.GetQueueGroup( RenderQueueGroupID.Overlay ).ShadowsEnabled = false;
			this.renderQueue.GetQueueGroup( RenderQueueGroupID.SkiesEarly ).ShadowsEnabled = false;
			this.renderQueue.GetQueueGroup( RenderQueueGroupID.SkiesLate ).ShadowsEnabled = false;
		}
 /// <summary>
 ///		An abstract method that causes the specified RenderQueue to update itself.  
 /// </summary>
 /// <remarks>This is an internal method used by the engine assembly only.</remarks>
 /// <param name="queue">The render queue that this object should be updated in.</param>
 public abstract void UpdateRenderQueue(RenderQueue queue);
Exemplo n.º 17
0
		public void UpdateRenderQueue( RenderQueue queue )
		{
			if ( IsRenderedAtCurrentLod )
			{
				queue.AddRenderable( this.mRend, this.mTerrain.RenderQueueGroupID );
			}
		}
Exemplo n.º 18
0
		/// <summary>
		///    Internal method to put the overlay contents onto the render queue.
		/// </summary>
		/// <param name="camera">Current camera being used in the render loop.</param>
		/// <param name="queue">Current render queue.</param>
		public void FindVisibleObjects( Camera camera, RenderQueue queue )
		{
			if ( OverlayManager.Instance.HasViewportChanged )
			{
				for ( var i = 0; i < this.elementList.Count; i++ )
				{
					var container = (OverlayElementContainer)this.elementList[ i ];
					container.NotifyViewport();
				}
			}

			if ( this.isVisible )
			{
				// update transform of elements
				if ( this.isTransformUpdated )
				{
					GetWorldTransforms( this.xform );
					for ( var i = 0; i < this.elementList.Count; i++ )
					{
						var container = (OverlayElementContainer)this.elementList[ i ];
						container.NotifyWorldTransforms( this.xform );
					}
					this.isTransformUpdated = false;
				}

				// add 3d elements
				this.rootNode.Position = camera.DerivedPosition;
				this.rootNode.Orientation = camera.DerivedOrientation;
				this.rootNode.Update( true, false );

				// set up the default queue group for the objects about to be added
				var oldGroupID = queue.DefaultRenderGroup;
				var oldPriority = queue.DefaultRenderablePriority;

				queue.DefaultRenderGroup = RenderQueueGroupID.Overlay;
				queue.DefaultRenderablePriority = (ushort)( ( this.zOrder*100 ) - 1 );
				this.rootNode.FindVisibleObjects( camera, queue, true, false );

				// reset the group
				queue.DefaultRenderGroup = oldGroupID;
				queue.DefaultRenderablePriority = oldPriority;

				// add 2d elements
				for ( var i = 0; i < this.elementList.Count; i++ )
				{
					var container = (OverlayElementContainer)this.elementList[ i ];
					container.Update();
					container.UpdateRenderQueue( queue );
				}
			}
		}
Exemplo n.º 19
0
			public override void UpdateRenderQueue( RenderQueue queue )
			{
				this.mParent.UpdateRenderQueue( queue );
			}
Exemplo n.º 20
0
        public override void UpdateRenderQueue(RenderQueue queue)
        {
            Debug.Assert(inBoundary);

            if (isVisible)
            {
                queue.AddRenderable(this);
            }
        }
Exemplo n.º 21
0
			public void AddRenderables( RenderQueue queue, RenderQueueGroupID group, float camSquaredDistance )
			{
				// Just pass this on to child buckets
				foreach ( var mbucket in this.materialBucketMap.Values )
				{
					mbucket.AddRenderables( queue, group, camSquaredDistance );
				}
			}
Exemplo n.º 22
0
		public override void UpdateRenderQueue( RenderQueue queue )
		{
			this.UpdateIndexBuffer();

			if ( this.indexData.indexCount > 0 )
			{
				queue.AddRenderable( this );
			}
		}
        /** 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 ) );
            }
        }
Exemplo n.º 24
0
		public override void UpdateRenderQueue( RenderQueue queue )
		{
			UpdateRenderQueue( queue, true );
		}
Exemplo n.º 25
0
		public override void UpdateRenderQueue( RenderQueue queue )
		{
			// Notify need to calculate light list when our sending to render queue
			this.mLightListDirty = true;

			//if ( !added )
			{
				queue.AddRenderable( this, renderQueueID );
				this.added = true;
			}
		}
Exemplo n.º 26
0
		public override void UpdateRenderQueue( RenderQueue queue )
		{
			// Do nothing
		}
Exemplo n.º 27
0
 public override void UpdateRenderQueue(RenderQueue queue)
 {
 }
Exemplo n.º 28
0
		/** 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;
					}
				}
			}
		}
Exemplo n.º 29
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 );
					}
				}
			}
		}
Exemplo n.º 30
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 );
					}
				}
			}
		}
Exemplo n.º 31
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 );

			}
		}
Exemplo n.º 32
0
		/// <summary>
		///
		/// </summary>
		/// <param name="queue"></param>
		public override void UpdateRenderQueue( RenderQueue queue )
		{
			// Manual LOD sub entities
			if ( this.meshLodIndex > 0 && this.mesh.IsLodManual )
			{
				Debug.Assert( this.meshLodIndex - 1 < this.lodEntityList.Count,
				              "No LOD EntityList - did you build the manual LODs after creating the entity?" );

				var lodEnt = this.lodEntityList[ this.meshLodIndex - 1 ];

				// index - 1 as we skip index 0 (original LOD)
				if ( HasSkeleton && lodEnt.HasSkeleton )
				{
					// Copy the animation state set to lod entity, we assume the lod
					// entity only has a subset animation states
					CopyAnimationStateSubset( lodEnt.animationState, this.animationState );
				}

				lodEnt.UpdateRenderQueue( queue );
				return;
			}

			// add all visible sub entities to the render queue
			foreach ( var se in this.subEntityList )
			{
				if ( se.IsVisible )
				{
					queue.AddRenderable( se, RenderQueue.DEFAULT_PRIORITY, renderQueueID );
				}
			}

			// Since we know we're going to be rendered, take this opportunity to
			// update the animation
			if ( HasSkeleton || this.mesh.HasVertexAnimation )
			{
				UpdateAnimation();

				// Update render queue with child objects (tag points)
				foreach ( var child in this.childObjectList.Values )
				{
					if ( child.IsVisible )
					{
						child.UpdateRenderQueue( queue );
					}
				}
			}
		}
Exemplo n.º 33
0
        public override void UpdateRenderQueue(RenderQueue queue)
        {
            if ( isVisible )
            {
                if (tile.Hilight)
                {
                    material = tile.HilightMaterial;
                }
                else
                {
                    material = normalMaterial;
                }

                if ( renderOp.vertexData == null )
                {
                    // the object is visible so we had better make sure it has vertex and index buffers
                    renderOp.vertexData = buildVertexData();
                    renderOp.indexData = IndexBufferManager.Instance.GetTileIndexBuffer(numSamples);
                }

                if ( WorldManager.Instance.DrawTiles )
                {
                    queue.AddRenderable( this );
                }

                if ( stitchRenderable == null )
                {
                    tile.Stitch();
                }

                if ( WorldManager.Instance.DrawStitches && ( stitchRenderable != null ) )
                {
                    queue.AddRenderable( stitchRenderable );
                }
            }
        }