A viewpoint from which the scene will be rendered.
The engine renders scenes from a camera viewpoint into a buffer of some sort, normally a window or a texture (a subclass of RenderTarget). the engine cameras support both perspective projection (the default, meaning objects get smaller the further away they are) and orthographic projection (blueprint-style, no decrease in size with distance). Each camera carries with it a style of rendering, e.g. full textured, flat shaded, wireframe), field of view, rendering distances etc, allowing you to use the engine to create complex multi-window views if required. In addition, more than one camera can point at a single render target if required, each rendering to a subset of the target, allowing split screen and picture-in-picture views.

Cameras maintain their own aspect ratios, field of view, and frustrum, and project co-ordinates into a space measured from -1 to 1 in x and y, and 0 to 1 in z. At render time, the camera will be rendering to a Viewport which will translate these parametric co-ordinates into real screen co-ordinates. Obviously it is advisable that the viewport has the same aspect ratio as the camera to avoid distortion (unless you want it!).

Note that a Camera can be attached to a SceneNode, using the method SceneNode.AttachObject. If this is done the Camera will combine it's own position/orientation settings with it's parent SceneNode. This is useful for implementing more complex Camera / object relationships i.e. having a camera attached to a world object.

Inheritance: Frustum
Example #1
0
        public void OnLoad()
        {
            var dir = Directory.GetCurrentDirectory();
            ResourceGroupManager.Instance.AddResourceLocation(dir, "Folder");
            //MaterialManager.Instance.Initialize();

            _scene = _root.CreateSceneManager("DefaultSceneManager", "SLSharpInstance");
            _scene.ClearScene();

            Bindings.Axiom.SLSharp.Init();
            Shader.DebugMode = true;

            //Shader.DebugMode = true;

            _clipmap = new Clipmap(_scene);
            RecalcHeight();

            _camera = _scene.CreateCamera("MainCamera");
            _camera.Position = new Vector3(0, 0, 5);
            _camera.LookAt(Vector3.Zero);
            _camera.Near = 0.001f;
            _camera.Far = 20.0f;
            _camera.AutoAspectRatio = true;

            var vp = _window.AddViewport(_camera);
            vp.BackgroundColor = ColorEx.CornflowerBlue;
        }
 public CameraComponent()
 {
     camera = null;
     acceleration = Vector3.Zero;
     velocity = Vector3.Zero;
     rotation = Vector3.Zero;
 }
Example #3
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="camera"></param>
		public override void NotifyCurrentCamera( Camera camera )
		{
			base.NotifyCurrentCamera( camera );


			///Fake orientation toward camera
			Vector3 zVec = ParentNode.DerivedPosition - camera.DerivedPosition;
			zVec.Normalize();

			Vector3 fixedAxis = camera.DerivedOrientation*Vector3.UnitY;

			Vector3 xVec = fixedAxis.Cross( zVec );
			xVec.Normalize();

			Vector3 yVec = zVec.Cross( xVec );
			yVec.Normalize();

			Quaternion oriQuat = Quaternion.FromAxes( xVec, yVec, zVec );

			this.fakeOrientation = oriQuat.ToRotationMatrix();

			Quaternion q = ParentNode.DerivedOrientation.UnitInverse*oriQuat;
			Matrix3 tempMat = q.ToRotationMatrix();

			Matrix4 rotMat = Matrix4.Identity;
			rotMat = tempMat;
			rotMat.Translation = new Vector3( 0.5f, 0.5f, 0.5f );

			this.unit.TextureMatrix = rotMat;
		}
        protected override void CreateCamera()
        {
            base.CreateCamera();

            camera2 = scene.CreateCamera("Camera2");
            camera2.Far = 300;
            camera2.Near = 1;
        }
        /// 
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public override float GetSquaredViewDepth(Camera camera)
        {
            // get the parent entitie's parent node
            Node node = this.ParentNode;

            Debug.Assert(node != null);

            return node.GetSquaredViewDepth(camera);
        }
		public void Merge( AxisAlignedBox boxBounds, Sphere sphereBounds, Camera cam, bool receiver )
		{
			aabb.Merge( boxBounds );
			if ( receiver )
				receiverAabb.Merge( boxBounds );
			Real camDistToCenter = ( cam.DerivedPosition - sphereBounds.Center ).Length;
			minDistance = System.Math.Min( minDistance, System.Math.Max( (Real)0, camDistToCenter - sphereBounds.Radius ) );
			maxDistance = System.Math.Max( maxDistance, camDistToCenter + sphereBounds.Radius );
		}
Example #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cam"></param>
        /// <param name="section"></param>
        public override void NotifyCamera(Camera cam, PagedWorldSection section)
        {
            Grid2DPageStrategyData stratData = (Grid2DPageStrategyData)section.StrategyData;

            Vector3 pos = cam.DerivedPosition;
            Vector2 gridpos = Vector2.Zero;
            stratData.ConvetWorldToGridSpace(pos, ref gridpos);
            int row = 0, col = 0;
            stratData.DetermineGridLocation(gridpos, ref row, ref col);

            float loadRadius = stratData.LoadRadiusInCells;
            float holdRadius = stratData.HoldRadiusInCells;
            //scan the whole hold range
            float frowmin = (float)row - holdRadius;
            float frowmax = (float)row + holdRadius;
            float fcolmin = (float)col - holdRadius;
            float fcolmax = (float)col + holdRadius;

            int clampRowAt = stratData.CellCountVert - 1;
            int clampColAt = stratData.CellCountHorz - 1;

            //round UP max, round DOWN min
            int rowmin = frowmin < 0 ? 0 : (int)System.Math.Floor(frowmin);
            int rowmax = frowmax > clampRowAt ? clampRowAt : (int)System.Math.Ceiling(frowmax);
            int colmin = fcolmin < 0 ? 0 : (int)System.Math.Floor(fcolmin);
            int colmax = fcolmax > clampColAt ? clampColAt : (int)System.Math.Ceiling(fcolmax);
            // the inner, active load range
            frowmin = (float)row - loadRadius;
            frowmax = (float)row + loadRadius;
            fcolmin = (float)col - loadRadius;
            fcolmax = (float)col + loadRadius;
            //round UP max, round DOWN min
            int loadrowmin = frowmin < 0 ? 0 : (int)System.Math.Floor(frowmin);
            int loadrowmax = frowmax > clampRowAt ? clampRowAt : (int)System.Math.Ceiling(frowmax);
            int loadcolmin = fcolmin < 0 ? 0 : (int)System.Math.Floor(fcolmin);
            int loadcolmax = fcolmax > clampColAt ? clampColAt : (int)System.Math.Ceiling(fcolmax);

            for (int r = rowmin; r <= rowmax; ++r)
            {
                for (int c = colmin; c <= colmax; ++c)
                {
                    PageID pageID = stratData.CalculatePageID(r, c);
                    if (r >= loadrowmin && r <= loadrowmax && c >= loadcolmin && c <= loadcolmax)
                    {
                        // int the 'load' range, request it
                        section.LoadPage(pageID);
                    }
                    else
                    {
                        // int the outer 'hold' range, keep it but don't actively load.
                        section.HoldPage(pageID);
                    }
                    // other paged will by inference be marked for unloading
                }
            }
        }
Example #8
0
		/// <summary>
		/// Returns the camera-relative squared depth of this renderable.
		/// </summary>
		/// <param name="camera"></param>
		/// <returns></returns>
		public override Real GetSquaredViewDepth( Camera camera )
		{
			Vector3 min, max, mid, dist;

			min = box.Minimum;
			max = box.Maximum;
			mid = ( ( min - max )*0.5 ) + min;
			dist = camera.DerivedPosition - mid;

			return dist.LengthSquared;
		}
Example #9
0
        public virtual void CreateCamera()
        {
            // create a camera and initialize its position
            camera = scene.CreateCamera("MainCamera");
            camera.Position = new Vector3(0, 0, 500);
            camera.LookAt(new Vector3(0, 0, -300));

            // set the near clipping plane to be very close
            camera.Near = 5;

            camera.AutoAspectRatio = true;
        }
Example #10
0
 public override void NotifyCurrentCamera(Axiom.Core.Camera cam)
 {
     if (((Camera)(cam)).IsObjectVisible(this.worldAABB))
     {
         isVisible = true;
     }
     else
     {
         isVisible = false;
         return;
     }
 }
Example #11
0
        /// <summary>
        /// Internal method for updating the scene graph ie the tree of SceneNode instances managed by this class.
        /// </summary>
        /// <param name="cam"></param>
        /// <remarks>
        ///	This must be done before issuing objects to the rendering pipeline, since derived transformations from
        ///	parent nodes are not updated until required. This SceneManager is a basic implementation which simply
        ///	updates all nodes from the root. This ensures the scene is up to date but requires all the nodes
        ///	to be updated even if they are not visible. Subclasses could trim this such that only potentially visible
        ///	nodes are updated.
        /// </remarks>
        protected override void UpdateSceneGraph(Axiom.Core.Camera cam)
        {
            // entry into here could come before SetWorldGeometry
            // got called which could be disasterous
            // so check for init

            if (worldGeomIsSetup)
            {
                pageManager.Update((Camera)cam);
                renderableManager.ResetVisibles();
            }

            // Call the default
            base.UpdateSceneGraph(cam);
        }
Example #12
0
		public void OnLoad()
		{
			//ResourceGroupManager.Instance.AddResourceLocation("media", "Folder", true);

			_root.SceneManager = _sceneManager = _root.CreateSceneManager(SceneType.ExteriorClose);
			_sceneManager.ClearScene();

			_camera = _sceneManager.CreateCamera("MainCamera");

			_camera.Position = new Vector3(0, 0, 500);
			_camera.LookAt(new Vector3(0, 0, -300));
			_camera.Near = 5;
			_camera.AutoAspectRatio = true;
			_camera.FieldOfView = 0.70f;
			_viewport = _renderWindow.AddViewport(_camera, 0, 0, 1.0f, 1.0f, 100);
			_viewport.BackgroundColor = ColorEx.Black; ;

			_light = _sceneManager.CreateLight("light1");
			_light.Type = LightType.Directional;
			_light.Position = new Vector3(0, 150, 300);
			_light.Diffuse = ColorEx.Blue;
			_light.Specular = ColorEx.Blue;
			//_light.Direction = new Vector3(0, 0, -300);
			_sceneManager.AmbientLight = ColorEx.White;// new ColorEx(0.2f, 0.2f, 0.2f);

			ResourceGroupManager.Instance.InitializeAllResourceGroups();


			_inputReader = PlatformManager.Instance.CreateInputReader();
			_inputReader.Initialize(_renderWindow, true, true, false, false);

			_inputReader.UseKeyboardEvents = true;
			_inputReader.UseMouseEvents = false;

			//_renderItems.Add(new BasicCube());
			_renderItems.Add(new CubeBrowser());
			foreach (var i in _renderItems)
			{
				i.Initialise(_root);
			}
		}
Example #13
0
        /// <summary>
        /// Internal method for updating the scene graph ie the tree of SceneNode instances managed by this class.
        /// </summary>
        /// <param name="cam"></param>
        /// <remarks>
        ///	This must be done before issuing objects to the rendering pipeline, since derived transformations from
        ///	parent nodes are not updated until required. This SceneManager is a basic implementation which simply
        ///	updates all nodes from the root. This ensures the scene is up to date but requires all the nodes
        ///	to be updated even if they are not visible. Subclasses could trim this such that only potentially visible
        ///	nodes are updated.
        /// </remarks>
        protected override void UpdateSceneGraph(Axiom.Core.Camera cam)
        {
            if (illuminationStage == IlluminationRenderStage.None)
            {
                // Notify the TerrainManager of the camera location.  If a page or tile boundary is crossed
                // this will result in a bunch of shuffling of heightMap data.
                // After the object bounding boxes have been update below, we need to call
                // the TerrainManager again to perform LOD adjustments on all visible tiles,
                // and queue the non-visible ones.
                TerrainManager.Instance.UpdateCamera(cam);
            }

            // call the base SceneManager to update the transforms and world bounds of all the
            // objects in the scene graph.
            base.UpdateSceneGraph(cam);

            if (illuminationStage == IlluminationRenderStage.None)
            {
                TerrainManager.Instance.LatePerFrameProcessing(cam);
            }
        }
Example #14
0
		/// <summary>
		///		Internal method for locating a list of shadow casters which
		///		could be affecting the frustum for a given light.
		/// </summary>
		/// <remarks>
		///		Custom scene managers are encouraged to override this method to add optimizations,
		///		and to add their own custom shadow casters (perhaps for world geometry)
		/// </remarks>
		/// <param name="light"></param>
		/// <param name="camera"></param>
		protected virtual IList FindShadowCastersForLight( Light light, Camera camera )
		{
			this.shadowCasterList.Clear();

			if ( light.Type == LightType.Directional )
			{
				// Basic AABB query encompassing the frustum and the extrusion of it
				AxisAlignedBox aabb = new AxisAlignedBox();
				Vector3[] corners = camera.WorldSpaceCorners;
				Vector3 min, max;
				Vector3 extrude = light.DerivedDirection * -this.shadowDirLightExtrudeDist;
				// do first corner
				min = max = corners[ 0 ];
				min.Floor( corners[ 0 ] + extrude );
				max.Ceil( corners[ 0 ] + extrude );
				for ( int c = 1; c < 8; ++c )
				{
					min.Floor( corners[ c ] );
					max.Ceil( corners[ c ] );
					min.Floor( corners[ c ] + extrude );
					max.Ceil( corners[ c ] + extrude );
				}
				aabb.SetExtents( min, max );

				if ( this.shadowCasterAABBQuery == null )
				{
					this.shadowCasterAABBQuery = this.CreateAABBRegionQuery( aabb );
				}
				else
				{
					this.shadowCasterAABBQuery.Box = aabb;
				}
				// Execute, use callback
				this.shadowCasterQueryListener.Prepare( false,
														light.GetFrustumClipVolumes( camera ),
														light,
														camera,
														this.shadowCasterList,
														light.ShadowFarDistanceSquared );
				this.shadowCasterAABBQuery.Execute( this.shadowCasterQueryListener );
			}
			else
			{
				Sphere s = new Sphere( light.DerivedPosition, light.AttenuationRange );

				// eliminate early if camera cannot see light sphere
				if ( camera.IsObjectVisible( s ) )
				{
					// create or init a sphere region query
					if ( this.shadowCasterSphereQuery == null )
					{
						this.shadowCasterSphereQuery = this.CreateSphereRegionQuery( s );
					}
					else
					{
						this.shadowCasterSphereQuery.Sphere = s;
					}

					// check if the light is within view of the camera
					bool lightInFrustum = camera.IsObjectVisible( light.DerivedPosition );

					PlaneBoundedVolumeList volumeList = null;

					// Only worth building an external volume list if
					// light is outside the frustum
					if ( !lightInFrustum )
					{
						volumeList = light.GetFrustumClipVolumes( camera );
					}

					// prepare the query and execute using the callback
					this.shadowCasterQueryListener.Prepare(
						lightInFrustum,
						volumeList,
						light,
						camera,
						this.shadowCasterList,
						light.ShadowFarDistanceSquared );

					this.shadowCasterSphereQuery.Execute( this.shadowCasterQueryListener );
				}
			}

			return this.shadowCasterList;
		}
Example #15
0
		/// <summary>
		///		Internal method for locating a list of lights which could be affecting the frustum.
		/// </summary>
		/// <remarks>
		///		Custom scene managers are encouraged to override this method to make use of their
		///		scene partitioning scheme to more efficiently locate lights, and to eliminate lights
		///		which may be occluded by word geometry.
		/// </remarks>
		/// <param name="camera">Camera to find lights within it's view.</param>
		protected virtual void FindLightsAffectingFrustum( Camera camera )
		{
			// Basic iteration for this scene manager
			this.lightsAffectingFrustum.Clear();

			MovableObjectCollection lightList = this.GetMovableObjectCollection( LightFactory.TypeName );

			// sphere to use for testing
			Sphere sphere = new Sphere();

			foreach ( Light light in lightList.Values )
			{
				if ( light.IsVisible )
				{
					if ( light.Type == LightType.Directional )
					{
						// Always visible
						this.lightsAffectingFrustum.Add( light );
					}
					else
					{
						// treating spotlight as point for simplicity
						// Just see if the lights attenuation range is within the frustum
						sphere.Center = light.DerivedPosition;
						sphere.Radius = light.AttenuationRange;

						if ( camera.IsObjectVisible( sphere ) )
						{
							this.lightsAffectingFrustum.Add( light );
						}
					}
				}
			}

			// notify light dirty, so all movable objects will re-populate
			// their light list next time
			NotifyLightsDirty();
		}
Example #16
0
		/** called when the scene manager creates a camera because
			some zone managers (like TerrainZone) need the camera info.
		*/
		public override void NotifyCameraCreated( Camera c )
		{
		}
Example #17
0
		public void DestroyCamera( Camera camera )
		{
			cameraList.Remove( camera.Name );
			this.targetRenderSystem.NotifyCameraRemoved( camera );

			if ( !camera.IsDisposed )
				camera.Dispose();
		}
Example #18
0
		/// <summary>
		///		Internal method for updating the scene graph ie the tree of SceneNode instances managed by this class.
		/// </summary>
		/// <remarks>
		///		This must be done before issuing objects to the rendering pipeline, since derived transformations from
		///		parent nodes are not updated until required. This SceneManager is a basic implementation which simply
		///		updates all nodes from the root. This ensures the scene is up to date but requires all the nodes
		///		to be updated even if they are not visible. Subclasses could trim this such that only potentially visible
		///		nodes are updated.
		/// </remarks>
		/// <param name="camera"></param>
		protected internal virtual void UpdateSceneGraph( Camera camera )
		{
			// Process queued needUpdate calls
			Node.ProcessQueuedUpdates();

			// Cascade down the graph updating transforms & world bounds
			// In this implementation, just update from the root
			// Smarter SceneManager subclasses may choose to update only
			// certain scene graph branches based on space partioning info.
			this.rootSceneNode.Update( true, false );
		}
Example #19
0
		/// <summary>
		///		Removes the specified camera from the scene.
		/// </summary>
		/// <remarks>
		///		This method removes a previously added camera from the scene.
		/// </remarks>
		/// <param name="camera">Reference to the camera to remove.</param>
		public virtual void RemoveCamera( Camera camera )
		{
			cameraList.Remove( camera.Name );

			// notify all render targets
			this.targetRenderSystem.NotifyCameraRemoved( camera );
		}
Example #20
0
        public override void NotifyCurrentCamera(Axiom.Core.Camera cam)
        {
            if (inUse == false || isLoaded == false)
            {
                return;
            }

            if (((Camera)(cam)).IsObjectVisible(this.worldAABB))
            {
                inFrustum = true;
                isVisible = true;
            }
            else
            {
                inFrustum = false;
                isVisible = false;
                return;
            }

            /* set*/
#if _VisibilityCheck
            //Check if the renderable need to be rendered based on the Cone normal approach
            //TODO: use the cone aperture not a fixed value
            if (Options.Instance.Lit == true)
            {
                mustRender = (bool)(cam.Direction.Dot(coneNormal) < Options.Instance.VisibilityAngle);
            }
#endif

            float d = (parentNode.DerivedPosition - cam.DerivedPosition).LengthSquared;
            // Now adjust it by the camera bias
            d = d * cam.LodBias;
            // Material LOD

            //TODO:: Axiom Doesn't Support Material LOD yet.
            //if ( this.material.getNumLodLevels() > 1 )
            //	materialLODIndex = m_pMaterial->getLodIndexSquaredDepth(d);

            // Check if we need to decrease the LOD
            float factor    = Options.Instance.LOD_Factor;
            float curr_lod  = factor * (1 + RenderLevel);
            bool  changeLOD = false;
            if (d < curr_lod)
            {
                if (RenderLevel != 0)
                {
                    RenderLevel--;
                    curr_lod -= factor;
                    changeLOD = true;
                }
            }
            else if (RenderLevel < Options.Instance.MaxRenderLevel && d >= (curr_lod * 2))
            {
                curr_lod += factor;
                RenderLevel++;
                changeLOD = true;
            }

            //**************
            //RenderLevel = Options.Instance.MaxRenderLevel;
            //changeLOD = true;
            //**************

            if (changeLOD || this.renderOp.indexData == null)
            {
                Update();
                for (long i = 0; i < 4; i++)
                {
                    if (neighbors[i] != null && neighbors[i].IsLoaded)
                    {
                        neighbors[i].Update();
                    }
                }
            }
            if (this.needReload)
            {
                Load();
            }
        }
Example #21
0
        /** Updates the level of detail to be used for rendering this PagingLandScapeRenderable based on the passed in Camera
         */
        public override void NotifyCurrentCamera(Axiom.Core.Camera cam)
        {
            PagingLandscape.Camera plsmcam = (PagingLandscape.Camera)(cam);
            this.isVisible = (init && loaded && plsmcam.GetVisibility(tileSceneNode.WorldAABB));
//			this.isVisible = (init && loaded );
        }
Example #22
0
		/// <summary>
		///		Internal method for rendering all the objects for a given light into the stencil buffer.
		/// </summary>
		/// <param name="light">The light source.</param>
		/// <param name="camera">The camera being viewed from.</param>
		protected virtual void RenderShadowVolumesToStencil( Light light, Camera camera )
		{
			// get the shadow caster list
			IList casters = this.FindShadowCastersForLight( light, camera );
			if ( casters.Count == 0 )
			{
				// No casters, just do nothing
				return;
			}

			// Set up scissor test (point & spot lights only)
			bool scissored = false;
			if ( light.Type != LightType.Directional &&
				 this.targetRenderSystem.Capabilities.HasCapability( Capabilities.ScissorTest ) )
			{
				// Project the sphere onto the camera
				float left, right, top, bottom;
				Sphere sphere = new Sphere( light.DerivedPosition, light.AttenuationRange );
				if ( camera.ProjectSphere( sphere, out left, out top, out right, out bottom ) )
				{
					scissored = true;
					// Turn normalised device coordinates into pixels
					int iLeft, iTop, iWidth, iHeight;
					this.currentViewport.GetActualDimensions( out iLeft, out iTop, out iWidth, out iHeight );
					int szLeft, szRight, szTop, szBottom;

					szLeft = (int)( iLeft + ( ( left + 1 ) * 0.5f * iWidth ) );
					szRight = (int)( iLeft + ( ( right + 1 ) * 0.5f * iWidth ) );
					szTop = (int)( iTop + ( ( -top + 1 ) * 0.5f * iHeight ) );
					szBottom = (int)( iTop + ( ( -bottom + 1 ) * 0.5f * iHeight ) );

					this.targetRenderSystem.SetScissorTest( true, szLeft, szTop, szRight, szBottom );
				}
			}

			this.targetRenderSystem.UnbindGpuProgram( GpuProgramType.Fragment );

			// Can we do a 2-sided stencil?
			bool stencil2sided = false;

			if ( this.targetRenderSystem.Capabilities.HasCapability( Capabilities.TwoSidedStencil ) &&
				 this.targetRenderSystem.Capabilities.HasCapability( Capabilities.StencilWrap ) )
			{
				// enable
				stencil2sided = true;
			}

			// Do we have access to vertex programs?
			bool extrudeInSoftware = true;

			bool finiteExtrude = !this.shadowUseInfiniteFarPlane ||
								 !this.targetRenderSystem.Capabilities.HasCapability(
									  Capabilities.InfiniteFarPlane );

			if ( this.targetRenderSystem.Capabilities.HasCapability( Capabilities.VertexPrograms ) )
			{
				extrudeInSoftware = false;
				this.EnableHardwareShadowExtrusion( light, finiteExtrude );
			}
			else
			{
				this.targetRenderSystem.UnbindGpuProgram( GpuProgramType.Vertex );
			}

			// Add light to internal list for use in render call
			tmpLightList.Clear();
			tmpLightList.Add( light );

			// Turn off color writing and depth writing
			this.targetRenderSystem.SetColorBufferWriteEnabled( false, false, false, false );
			this.targetRenderSystem.DepthBufferWriteEnabled = false;
			this.targetRenderSystem.StencilCheckEnabled = true;
			this.targetRenderSystem.DepthBufferFunction = CompareFunction.Less;

			// Calculate extrusion distance
			float extrudeDistance = 0;
			if ( light.Type == LightType.Directional )
			{
				extrudeDistance = this.shadowDirLightExtrudeDist;
			}

			// get the near clip volume
			PlaneBoundedVolume nearClipVol = light.GetNearClipVolume( camera );

			// Determine whether zfail is required
			// We need to use zfail for ALL objects if we find a single object which
			// requires it
			bool zfailAlgo = false;

			this.CheckShadowCasters( casters,
									 nearClipVol,
									 light,
									 extrudeInSoftware,
									 finiteExtrude,
									 zfailAlgo,
									 camera,
									 extrudeDistance,
									 stencil2sided,
									 tmpLightList );
			// revert colour write state
			this.targetRenderSystem.SetColorBufferWriteEnabled( true, true, true, true );
			// revert depth state
			this.targetRenderSystem.SetDepthBufferParams();

			this.targetRenderSystem.StencilCheckEnabled = false;

			this.targetRenderSystem.UnbindGpuProgram( GpuProgramType.Vertex );

			if ( scissored )
			{
				// disable scissor test
				this.targetRenderSystem.SetScissorTest( false );
			}
		}
Example #23
0
		private void CheckShadowCasters( IList casters,
										 PlaneBoundedVolume nearClipVol,
										 Light light,
										 bool extrudeInSoftware,
										 bool finiteExtrude,
										 bool zfailAlgo,
										 Camera camera,
										 float extrudeDistance,
										 bool stencil2sided,
										 LightList tmpLightList )
		{
			int flags;
			for ( int i = 0; i < casters.Count; i++ )
			{
				ShadowCaster caster = (ShadowCaster)casters[ i ];

				if ( nearClipVol.Intersects( caster.GetWorldBoundingBox() ) )
				{
					// We have a zfail case, we must use zfail for all objects
					zfailAlgo = true;

					break;
				}
			}

			for ( int ci = 0; ci < casters.Count; ci++ )
			{
				ShadowCaster caster = (ShadowCaster)casters[ ci ];
				flags = 0;

				if ( light.Type != LightType.Directional )
				{
					extrudeDistance = caster.GetPointExtrusionDistance( light );
				}

				if ( !extrudeInSoftware && !finiteExtrude )
				{
					// hardware extrusion, to infinity (and beyond!)
					flags |= (int)ShadowRenderableFlags.ExtrudeToInfinity;
				}

				if ( zfailAlgo )
				{
					// We need to include the light and / or dark cap
					// But only if they will be visible
					if ( camera.IsObjectVisible( caster.GetLightCapBounds() ) )
					{
						flags |= (int)ShadowRenderableFlags.IncludeLightCap;
					}
				}

				// Dark cap (no dark cap for directional lights using
				// hardware extrusion to infinity)
				if ( !( ( flags & (int)ShadowRenderableFlags.ExtrudeToInfinity ) != 0 &&
						light.Type == LightType.Directional ) &&
					 camera.IsObjectVisible( caster.GetDarkCapBounds( light, extrudeDistance ) ) )
				{
					flags |= (int)ShadowRenderableFlags.IncludeDarkCap;
				}

				// get shadow renderables
				IEnumerator renderables = caster.GetShadowVolumeRenderableEnumerator(
					this.shadowTechnique, light, this.shadowIndexBuffer, extrudeInSoftware, extrudeDistance, flags );

				// If using one-sided stencil, render the first pass of all shadow
				// renderables before all the second passes
				for ( int i = 0; i < ( stencil2sided ? 1 : 2 ); i++ )
				{
					if ( i == 1 )
					{
						renderables = caster.GetLastShadowVolumeRenderableEnumerator();
					}

					while ( renderables.MoveNext() )
					{
						ShadowRenderable sr = (ShadowRenderable)renderables.Current;

						// omit hidden renderables
						if ( sr.IsVisible )
						{
							// render volume, including dark and (maybe) light caps
							this.RenderSingleShadowVolumeToStencil( sr,
																	zfailAlgo,
																	stencil2sided,
																	tmpLightList,
																	( i > 0 ) );

							// optionally render separate light cap
							if ( sr.IsLightCapSeperate
								 && ( ( flags & (int)ShadowRenderableFlags.IncludeLightCap ) ) > 0 )
							{
								// must always fail depth check
								this.targetRenderSystem.DepthBufferFunction = CompareFunction.AlwaysFail;

								Debug.Assert( sr.LightCapRenderable != null,
											  "Shadow renderable is missing a separate light cap renderable!" );

								this.RenderSingleShadowVolumeToStencil( sr.LightCapRenderable,
																		zfailAlgo,
																		stencil2sided,
																		tmpLightList,
																		( i > 0 ) );
								// reset depth function
                                this.targetRenderSystem.DepthBufferFunction = CompareFunction.Less;
							}
						}
					}
				}
			}
		}
Example #24
0
		/// <summary>
		///		Internal method for queueing the sky objects with the params as
		///		previously set through SetSkyBox, SetSkyPlane and SetSkyDome.
		/// </summary>
		/// <param name="camera"></param>
		internal virtual void QueueSkiesForRendering( Camera camera )
		{
			// translate the skybox by cam position
			if ( this.skyPlaneNode != null )
			{
				this.skyPlaneNode.Position = camera.DerivedPosition;
			}

			if ( this.skyBoxNode != null )
			{
				this.skyBoxNode.Position = camera.DerivedPosition;
			}

			if ( this.skyDomeNode != null )
			{
				this.skyDomeNode.Position = camera.DerivedPosition;
			}

			RenderQueueGroupID qid;

			// if the skyplane is enabled, queue up the single plane
			if ( this.isSkyPlaneEnabled )
			{
				qid = this.isSkyPlaneDrawnFirst ? RenderQueueGroupID.SkiesEarly : RenderQueueGroupID.SkiesLate;
				this.GetRenderQueue().AddRenderable( this.skyPlaneEntity.GetSubEntity( 0 ), 1, qid );
			}

			// if the skybox is enabled, queue up all the planes
			if ( this.isSkyBoxEnabled )
			{
				qid = this.isSkyBoxDrawnFirst ? RenderQueueGroupID.SkiesEarly : RenderQueueGroupID.SkiesLate;

				for ( int plane = 0; plane < 6; plane++ )
				{
					this.GetRenderQueue().AddRenderable( this.skyBoxEntities[ plane ].GetSubEntity( 0 ), 1, qid );
				}
			}

			// if the skydome is enabled, queue up all the planes
			if ( this.isSkyDomeEnabled )
			{
				qid = this.isSkyDomeDrawnFirst ? RenderQueueGroupID.SkiesEarly : RenderQueueGroupID.SkiesLate;

				for ( int plane = 0; plane < 5; ++plane )
				{
					this.GetRenderQueue().AddRenderable( this.skyDomeEntities[ plane ].GetSubEntity( 0 ), 1, qid );
				}
			}
		}
Example #25
0
		/// <summary>
		///		Prompts the class to send its contents to the renderer.
		/// </summary>
		/// <remarks>
		///		This method prompts the scene manager to send the
		///		contents of the scene it manages to the rendering
		///		pipeline, possibly preceded by some sorting, culling
		///		or other scene management tasks. Note that this method is not normally called
		///		directly by the user application; it is called automatically
		///		by the engine's rendering loop.
		/// </remarks>
		/// <param name="camera">Pointer to a camera from whose viewpoint the scene is to be rendered.</param>
		/// <param name="viewport">The target viewport</param>
		/// <param name="showOverlays">Whether or not any overlay objects should be rendered</param>
		protected internal void RenderScene( Camera camera, Viewport viewport, bool showOverlays )
		{
			// let the engine know this is the current scene manager
			Root.Instance.SceneManager = this;

			if ( this.IsShadowTechniqueInUse )
			{
				// initialize shadow volume materials
				this.InitShadowVolumeMaterials();
			}

			// Perform a quick pre-check to see whether we should override far distance
			// When using stencil volumes we have to use infinite far distance
			// to prevent dark caps getting clipped
			if ( this.IsShadowTechniqueStencilBased &&
				 camera.Far != 0 &&
				 this.targetRenderSystem.Capabilities.HasCapability( Capabilities.InfiniteFarPlane ) &&
				 this.shadowUseInfiniteFarPlane )
			{
				// infinite far distance
				camera.Far = 0.0f;
			}

			this.cameraInProgress = camera;
			this.hasCameraChanged = true;

			// Update the scene, only do this once per frame
			ulong thisFrameNumber = Root.Instance.CurrentFrameCount;
			if ( thisFrameNumber != this.lastFrameNumber )
			{
				// Update animations
				this.ApplySceneAnimations();
				// Update controllers
				ControllerManager.Instance.UpdateAll();
				this.lastFrameNumber = thisFrameNumber;
			}

			// Update scene graph for this camera (can happen multiple times per frame)
			this.UpdateSceneGraph( camera );

			// Auto-track nodes
			foreach ( SceneNode sn in autoTrackingSceneNodes.Values )
			{
				sn.AutoTrack();
			}

			// ask the camera to auto track if it has a target
			camera.AutoTrack();

			// Are we using any shadows at all?
			if ( this.IsShadowTechniqueInUse && this.illuminationStage != IlluminationRenderStage.RenderToTexture &&
				 viewport.ShowShadows && this.findVisibleObjects )
			{
				// Locate any lights which could be affecting the frustum
				this.FindLightsAffectingFrustum( camera );

				if ( this.IsShadowTechniqueTextureBased )
				{
					// *******
					// WARNING
					// *******
					// This call will result in re-entrant calls to this method
					// therefore anything which comes before this is NOT
					// guaranteed persistent. Make sure that anything which
					// MUST be specific to this camera / target is done
					// AFTER THIS POINT
					this.PrepareShadowTextures( camera, viewport );
					// reset the cameras because of the re-entrant call
					this.cameraInProgress = camera;
					this.hasCameraChanged = true;
				}
			}

			// Invert vertex winding?
			this.targetRenderSystem.InvertVertexWinding = camera.IsReflected;

			// Tell params about viewport
			this.autoParamDataSource.Viewport = viewport;
			// Set the viewport
			this.SetViewport( viewport );

			// set the current camera for use in the auto GPU program params
			this.autoParamDataSource.Camera = camera;

			// Set autoparams for finite dir light extrusion
			this.autoParamDataSource.SetShadowDirLightExtrusionDistance( this.shadowDirLightExtrudeDist );

			// sets the current ambient light color for use in auto GPU program params
			this.autoParamDataSource.AmbientLight = this.ambientColor;
			// Tell rendersystem
			this.targetRenderSystem.AmbientLight = this.ambientColor;

			// Tell params about render target
			this.autoParamDataSource.RenderTarget = viewport.Target;

			// set fog params
			float fogScale = 1f;
			if ( this.fogMode == FogMode.None )
			{
				fogScale = 0f;
			}
			this.autoParamDataSource.FogParams = new Vector4( this.fogStart, this.fogEnd, fogScale, 0 );

			// set the time in the auto param data source
			//autoParamDataSource.Time = ((float)Root.Instance.Timer.Milliseconds) / 1000f;

			// Set camera window clipping planes (if any)
			if ( this.targetRenderSystem.Capabilities.HasCapability( Capabilities.UserClipPlanes ) )
			{
				// TODO: Add ClipPlanes to RenderSystem.cs
				if ( camera.IsWindowSet )
				{
				    targetRenderSystem.ResetClipPlanes();
					IList<Plane> planeList = camera.WindowPlanes;
					for ( ushort i = 0; i < 4; ++i )
					{
					    targetRenderSystem.AddClipPlane( planeList[ i ] );

						//this.targetRenderSystem.EnableClipPlane( i, true );
						//this.targetRenderSystem.SetClipPlane( i, planeList[ i ] );
					}
				}
				// this disables any user-set clipplanes... this should be done manually
				//else
				//{
				//    for (ushort i = 0; i < 4; ++i)
				//    {
				//        targetRenderSystem.EnableClipPlane(i, false);
				//    }
				//}
			}

			// Prepare render queue for receiving new objects
			this.PrepareRenderQueue();

			// Parse the scene and tag visibles
			if ( this.findVisibleObjects )
			{
				if ( this.PreFindVisibleObjects != null )
					PreFindVisibleObjects( this, this.illuminationStage, viewport );
				this.FindVisibleObjects( camera, this.illuminationStage == IlluminationRenderStage.RenderToTexture );
				if ( this.PostFindVisibleObjects != null )
					PostFindVisibleObjects( this, this.illuminationStage, viewport );
			}

			// Add overlays, if viewport deems it
			if ( viewport.ShowOverlays && this.illuminationStage != IlluminationRenderStage.RenderToTexture )
			{
				// Queue overlays for rendering
				OverlayManager.Instance.QueueOverlaysForRendering( camera, this.GetRenderQueue(), viewport );
			}

			// queue overlays and skyboxes for rendering
			if ( viewport.ShowSkies && this.findVisibleObjects &&
				 this.illuminationStage != IlluminationRenderStage.RenderToTexture )
			{
				this.QueueSkiesForRendering( camera );
			}

			// begin frame geometry count
			this.targetRenderSystem.BeginGeometryCount();

			// clear the device if need be
			if ( viewport.ClearEveryFrame )
			{
				this.targetRenderSystem.ClearFrameBuffer( viewport.ClearBuffers, viewport.BackgroundColor );
			}

			// being a frame of animation
			this.targetRenderSystem.BeginFrame();

			// use the camera's current scene detail level
			this.targetRenderSystem.PolygonMode = camera.PolygonMode;

			// Set initial camera state
			this.targetRenderSystem.ProjectionMatrix = camera.ProjectionMatrixRS;
			this.targetRenderSystem.ViewMatrix = camera.ViewMatrix;

			// render all visible objects
			this.RenderVisibleObjects();

			// end the current frame
			this.targetRenderSystem.EndFrame();

			// Notify camera of the number of rendered faces
			camera.NotifyRenderedFaces( this.targetRenderSystem.FaceCount );

			// Notify camera of the number of rendered batches
			camera.NotifyRenderedBatches( this.targetRenderSystem.BatchCount );
		}
Example #26
0
		/// <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 ( this.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 );
			this.cameraList.Add( camera );

			return camera;
		}
Example #27
0
		/// <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>
		public virtual void FindVisibleObjects( Camera camera, bool onlyShadowCasters )
		{
			// ask the root node to iterate through and find visible objects in the scene
			this.rootSceneNode.FindVisibleObjects( camera,
												   this.GetRenderQueue(),
												   true,
												   this.displayNodes,
												   onlyShadowCasters );
		}
Example #28
0
		public override void NotifyCurrentCamera( Camera camera )
		{
			if ( parentNode != null )
			{
				// Get mesh lod strategy
				var meshStrategy = this.mesh.LodStrategy;
				// Get the appropriate lod value
				Real lodValue = meshStrategy.GetValue( this, camera );
				// Bias the lod value
				var biasedMeshLodValue = lodValue*this.meshLodFactorTransformed;

				// Get the index at this biased depth
				var newMeshLodIndex = this.mesh.GetLodIndex( biasedMeshLodValue );

				// Apply maximum detail restriction (remember lower = higher detail)
				this.meshLodIndex = (int)Utility.Max( this.maxMeshLodIndex, this.meshLodIndex );

				// Apply minimum detail restriction (remember higher = lower detail)
				this.meshLodIndex = (int)Utility.Min( this.minMeshLodIndex, this.meshLodIndex );

				// Construct event object
				EntityMeshLodChangedEvent evt;
				evt.Entity = this;
				evt.Camera = camera;
				evt.LodValue = biasedMeshLodValue;
				evt.PreviousLodIndex = this.meshLodIndex;
				evt.NewLodIndex = newMeshLodIndex;

				// Notify lod event listeners
				//camera.SceneManager.NotifyEntityMeshLodChanged( evt );

				// Change lod index
				this.meshLodIndex = evt.NewLodIndex;

				// Now do material LOD
				lodValue *= this.materialLodFactorTransformed;

				// apply the material LOD to all sub entities
				foreach ( var subEntity in this.subEntityList )
				{
					// Get sub-entity material
					var material = subEntity.Material;

					// Get material lod strategy
					var materialStrategy = material.LodStrategy;

					// Recalculate lod value if strategies do not match
					Real biasedMaterialLodValue;
					if ( meshStrategy == materialStrategy )
					{
						biasedMaterialLodValue = lodValue;
					}
					else
					{
						biasedMaterialLodValue = materialStrategy.GetValue( this, camera )*
						                         materialStrategy.TransformBias( this.materialLodFactor );
					}

					// Get the index at this biased depth
					var idx = material.GetLodIndex( biasedMaterialLodValue );
					// Apply maximum detail restriction (remember lower = higher detail)
					idx = (int)Utility.Max( this.maxMaterialLodIndex, idx );
					// Apply minimum detail restriction (remember higher = lower detail)
					idx = (int)Utility.Min( this.minMaterialLodIndex, idx );

					// Construct event object
					EntityMaterialLodChangedEvent materialLodEvent;
					materialLodEvent.SubEntity = subEntity;
					materialLodEvent.Camera = camera;
					materialLodEvent.LodValue = biasedMaterialLodValue;
					materialLodEvent.PreviousLodIndex = subEntity.MaterialLodIndex;
					materialLodEvent.NewLodIndex = idx;

					// Notify lod event listeners
					//camera.SceneManager.NotifyEntityMaterialLodChanged( materialLodEvent );

					// Change lod index
					subEntity.MaterialLodIndex = materialLodEvent.NewLodIndex;

					// Also invalidate any camera distance cache
					//subEntity.InvalidateCameraCache();
				}
			}

			// Notify child objects (tag points)
			foreach ( var child in this.childObjectList.Values )
			{
				child.NotifyCurrentCamera( camera );
			}
		}
Example #29
0
		/// <summary>
		/// Internal method for preparing shadow textures ready for use in a regular render
		/// </summary>
		/// <param name="camera"></param>
		/// <param name="viewPort"></param>
		protected internal virtual void PrepareShadowTextures( Camera camera, Viewport viewPort )
		{
			// Set the illumination stage, prevents recursive calls
			IlluminationRenderStage savedStage = this.illuminationStage;
			this.illuminationStage = IlluminationRenderStage.RenderToTexture;

			// Determine far shadow distance
			float shadowDist = this.shadowFarDistance;
			if ( shadowDist == 0.0f )
			{
				// need a shadow distance, make one up
				shadowDist = camera.Near * 300;
			}
			// set fogging to hide the shadow edge
			float shadowOffset = shadowDist * this.shadowTextureOffset;
			// Precalculate fading info
			float shadowEnd = shadowDist + shadowOffset;
			float fadeStart = shadowEnd * this.shadowTextureFadeStart;
			float fadeEnd = shadowEnd * this.shadowTextureFadeEnd;
			// Additive lighting should not use fogging, since it will overbrighten; use border clamp
			if ( !this.IsShadowTechniqueAdditive )
			{
				this.shadowReceiverPass.SetFog( true,
												FogMode.Linear,
												ColorEx.White,
												0,
												fadeStart,
												fadeEnd );
				// if we have a custom receiver material, then give it the fog params too
				if ( this.shadowTextureCustomReceiverPass != null )
				{
					this.shadowTextureCustomReceiverPass.SetFog( true,
																 FogMode.Linear,
																 ColorEx.White,
																 0,
																 fadeStart,
																 fadeEnd );
				}
			}
			else
			{
				// disable fogging explicitly
				this.shadowReceiverPass.SetFog( true, FogMode.None );
				// if we have a custom receiver material, then give it the fog params too
				if ( this.shadowTextureCustomReceiverPass != null )
				{
					this.shadowTextureCustomReceiverPass.SetFog( true, FogMode.None );
				}
			}

			// Iterate over the lights we've found, max out at the limit of light textures
			int sti = 0;
			foreach ( Light light in this.lightsAffectingFrustum )
			{
				// Check limit reached
				if ( sti == this.shadowTextures.Count )
					break;

				// Skip non-shadowing lights
				if ( !light.CastShadows )
				{
					continue;
				}

				Texture shadowTex = this.shadowTextures[ sti ];
				RenderTarget shadowRTT = shadowTex.GetBuffer().GetRenderTarget();
				Viewport shadowView = shadowRTT.GetViewport( 0 );
				Camera texCam = this.shadowTextureCameras[ sti ];

				// rebind camera, incase another SM in use which has switched to its cam
				shadowView.Camera = texCam;

				// Associate main view camera as LOD camera
				texCam.LodCamera = camera;

				//Vector3 dir;

				// set base
				if ( light.Type == LightType.Point )
					texCam.Direction = light.DerivedDirection;
				if ( light.Type == LightType.Directional )
					texCam.Position = light.DerivedPosition;

				// Use the material scheme of the main viewport
				// This is required to pick up the correct shadow_caster_material and similar properties.
				shadowView.MaterialScheme = viewPort.MaterialScheme;

				if ( light.CustomShadowCameraSetup == null )
				{
					_defaultShadowCameraSetup.GetShadowCamera( this, camera, viewPort, light, texCam, sti );
				}
				else
				{
					light.CustomShadowCameraSetup.GetShadowCamera( this, camera, viewPort, light, texCam, sti );
				}

				shadowView.BackgroundColor = ColorEx.White;

				// Fire shadow caster update, callee can alter camera settings
				// fireShadowTexturesPreCaster(light, texCam);

				// Update target
				shadowRTT.Update();

				++sti;
			}
			// Set the illumination stage, prevents recursive calls
			this.illuminationStage = savedStage;

			//fireShadowTexturesUpdated( std::min(mLightsAffectingFrustum.size(), mShadowTextures.size()));
		}
 public override float GetSquaredViewDepth(Axiom.Core.Camera camera)
 {
     // Use squared length to avoid square root
     return((this.ParentNode.DerivedPosition - camera.DerivedPosition).LengthSquared);
 }
Example #31
0
			/// <summary>
			///		Prepare the listener for use with a set of parameters.
			/// </summary>
			/// <param name="lightInFrustum"></param>
			/// <param name="lightClipVolumes"></param>
			/// <param name="light"></param>
			/// <param name="camera"></param>
			/// <param name="shadowCasterList"></param>
			/// <param name="farDistSquared"></param>
			public void Prepare( bool lightInFrustum,
								 PlaneBoundedVolumeList lightClipVolumes,
								 Light light,
								 Camera camera,
								 List<ShadowCaster> shadowCasterList,
								 float farDistSquared )
			{
				this.casterList = shadowCasterList;
				this.isLightInFrustum = lightInFrustum;
				this.lightClipVolumeList = lightClipVolumes;
				this.camera = camera;
				this.light = light;
				this.farDistSquared = farDistSquared;
			}
Example #32
0
		/// <summary>
		///		Walks the BSP tree looking for the node which the camera is in, and tags any geometry
		///		which is in a visible leaf for later processing.
		/// </summary>
		protected BspNode WalkTree( Camera camera, bool onlyShadowCasters )
		{
			if ( this.level == null )
			{
				return null;
			}

			// Locate the leaf node where the camera is located
			BspNode cameraNode = this.level.FindLeaf( camera.DerivedPosition );

			this.matFaceGroupMap.Clear();
			this.faceGroupChecked.Clear();

			// Scan through all the other leaf nodes looking for visibles
			int i = this.level.NumNodes - this.level.LeafStart;
			int p = this.level.LeafStart;
			BspNode node;

			while ( i-- > 0 )
			{
				node = this.level.Nodes[ p ];

				if ( this.level.IsLeafVisible( cameraNode, node ) )
				{
					// Visible according to PVS, check bounding box against frustum
					//if ( camera.IsObjectVisible( node.BoundingBox ) )
					{
						ProcessVisibleLeaf( node, camera, onlyShadowCasters );

						if ( this.showNodeAABs )
						{
							AddBoundingBox( node.BoundingBox, true );
						}
					}
				}

				p++;
			}

			return cameraNode;
		}
Example #33
0
		public override Real GetSquaredViewDepth( Camera camera )
		{
			return 0;
		}
Example #34
0
		/// <summary>
		///		Tags geometry in the leaf specified for later rendering.
		/// </summary>
		protected void ProcessVisibleLeaf( BspNode leaf, Camera camera, bool onlyShadowCasters )
		{
			// Skip world geometry if we're only supposed to process shadow casters
			// World is pre-lit
			if ( !onlyShadowCasters )
			{
				// Parse the leaf node's faces, add face groups to material map
				int numGroups = leaf.NumFaceGroups;
				int idx = leaf.FaceGroupStart;

				while ( numGroups-- > 0 )
				{
					int realIndex = this.level.LeafFaceGroups[ idx++ ];

					// Is it already checked ?
					if ( this.faceGroupChecked.ContainsKey( realIndex ) && this.faceGroupChecked[ realIndex ] == true )
					{
						continue;
					}

					this.faceGroupChecked[ realIndex ] = true;

					BspStaticFaceGroup faceGroup = this.level.FaceGroups[ realIndex ];

					// Get Material reference by handle
					Material mat = GetMaterial( faceGroup.materialHandle );

					// Check normal (manual culling)
					ManualCullingMode cullMode = mat.GetTechnique( 0 ).GetPass( 0 ).ManualCullingMode;

					if ( cullMode != ManualCullingMode.None )
					{
						float dist = faceGroup.plane.GetDistance( camera.DerivedPosition );

						if ( ( ( dist < 0 ) && ( cullMode == ManualCullingMode.Back ) ) ||
						     ( ( dist > 0 ) && ( cullMode == ManualCullingMode.Front ) ) )
						{
							continue;
						}
					}

					// Try to insert, will find existing if already there
					this.matFaceGroupMap.Add( mat, faceGroup );
				}
			}

			// Add movables to render queue, provided it hasn't been seen already.
			foreach ( MovableObject obj in leaf.Objects.Values )
			{
				if ( !this.objectsForRendering.ContainsKey( obj.Name ) )
				{
					if ( obj.IsVisible && ( !onlyShadowCasters || obj.CastShadows ) &&
					     camera.IsObjectVisible( obj.GetWorldBoundingBox() ) )
					{
						obj.NotifyCurrentCamera( camera );
						obj.UpdateRenderQueue( renderQueue );
						// Check if the bounding box should be shown.
						var node = (SceneNode)obj.ParentNode;
						if ( node.ShowBoundingBox || showBoundingBoxes )
						{
							node.AddBoundingBoxToQueue( renderQueue );
						}
						this.objectsForRendering.Add( obj );
					}
				}
			}
		}
        protected void CreateCamera()
        {
            camera = scene.CreateCamera("PlayerCam");

            ResetCameraPosition();

            camera.Near = 1 * oneMeter;
            camera.Far = 10000 * oneMeter;

            camera.AspectRatio = (float)window.Width / window.Height;
        }
Example #36
0
		/** called when the scene manager creates a camera in order to store the first camera created as the primary
			one, for determining error metrics and the 'home' terrain page.
		*/
		public abstract void NotifyCameraCreated( Camera c );