⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.cs

📁 Game Engine Desing Direct X and C#.rar
💻 CS
字号:
using System;
using System.Collections;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace GameEngine
{
	/// <summary>
	/// Summary description for Camera.
	/// </summary>
	public class Camera
	{
		#region	// Cull State enumeration
		/// <summary>
		/// Each member of this enumeration is one possible culling result
		/// </summary>
		
		public enum CullState
		{
			/// <summary>
			/// The rectangle is completely within the viewing Frustum
			/// </summary>
			AllInside,	
			/// <summary>
			/// The rectangle is completely outside the viewing Frustum
			/// </summary>
			AllOutside,		
			/// <summary>
			/// The rectangle is partially within the viewing Frustum
			/// </summary>
			PartiallyIn,		
		}
	#endregion

		#region Attributes
		private Object3D  m_AttachedObject = null;
		private Object3D  m_LookAtObject = null;
		private Vector3   m_Offset;
		private Attitude  m_Attitude;
		private Matrix    m_matProj;
		private Matrix    m_matView;
		private float     m_X = 1.0f;
		private float     m_Y = 1.0f;
		private float     m_Z = 1.0f;
		private Vector3[] vecFrustum;    // corners of the view frustum
		private Plane[]   planeFrustum;    // planes of the view frustum
		private Vector3   m_Eye;
		private Vector3   m_LookAt;
		private string    m_name = "default";
		private float     m_fFOV = (float)Math.PI/4.0f;
		private float     m_fAspect = 1.33f;
		private float     m_fNearPlane = 1.0f;
		private float     m_fFarPlane = 800.0f;
		private ArrayList m_VisibleObjects = null;
		#endregion

		#region Properties
		public ArrayList VisibleObjects { get { return m_VisibleObjects; } }
		public float Heading { get { return (float)(m_Attitude.Heading*180.0/Math.PI); } }
		public float Pitch { get { return (float)(m_Attitude.Pitch*180.0/Math.PI); } }
		public string Name { get { return m_name; } }
		public float X { get { return m_X; } }
		public float Y { get { return m_Y; } }
		public float Z { get { return m_Z; } }
		public Matrix View { get { return m_matView; } }
		public Vector3 EyeVector { get { return m_Eye; } }
		public Vector3 LookAtVector { get { return m_LookAt; } }
		public float FieldOfView 
		{
			set 
			{ 
				m_fFOV = value;
				m_matProj = Matrix.PerspectiveFovLH( m_fFOV, m_fAspect, 
					m_fNearPlane, m_fFarPlane );
			} 
		}
		public float AspectRatio 
		{
			set 
			{ 
				m_fAspect = value;
				m_matProj = Matrix.PerspectiveFovLH( m_fFOV, m_fAspect, 
					m_fNearPlane, m_fFarPlane );
			} 
		}
		public float NearClipPlane 
		{
			set 
			{ 
				m_fNearPlane = value;
				m_matProj = Matrix.PerspectiveFovLH( m_fFOV, m_fAspect, 
					m_fNearPlane, m_fFarPlane );
			} 
		}
		public float FarClipPlane 
		{
			set 
			{ 
				m_fFarPlane = value;
				m_matProj = Matrix.PerspectiveFovLH( m_fFOV, m_fAspect, 
					m_fNearPlane, m_fFarPlane );
			} 
		}

		#endregion

		public Camera()
		{
			m_VisibleObjects = new ArrayList();
			m_matView = Matrix.Identity;
			m_Offset = new Vector3(0.0f, 0.0f, 0.0f);
			vecFrustum = new Vector3[8];    // corners of the view frustum
			planeFrustum = new Plane[6];    // planes of the view frustum
			m_matProj = Matrix.PerspectiveFovLH( m_fFOV, m_fAspect, 
				m_fNearPlane, m_fFarPlane );
		}

		public Camera(string name)
		{
			m_VisibleObjects = new ArrayList();
			m_matView = Matrix.Identity;
			m_Offset = new Vector3(0.0f, 0.0f, 0.0f);;
			vecFrustum = new Vector3[8];    // corners of the view frustum
			planeFrustum = new Plane[6];    // planes of the view frustum
			m_fFOV = (float)Math.PI/4.0f;
			m_fAspect = 1.0f;
			m_fNearPlane = .10f;
			m_fFarPlane = 800.0f;
			m_matProj = Matrix.PerspectiveFovLH( m_fFOV, m_fAspect, 
				m_fNearPlane, m_fFarPlane );
			m_name = name;
		}

		public void AdjustHeading( float deltaHeading )
		{
			m_Attitude.Heading += (deltaHeading * (float)Math.PI / 180.0f);

			if ( m_Attitude.Heading > (2.0f * Math.PI) )
			{
				m_Attitude.Heading -= (float)(2.0f * Math.PI);
			}

			if ( m_Attitude.Heading < 0.0f )
			{
				m_Attitude.Heading += (float)(2.0f * Math.PI);
			}

		}

		public void AdjustPitch( float deltaPitch )
		{
			m_Attitude.Pitch += (deltaPitch * (float)Math.PI / 180.0f);

			if ( m_Attitude.Pitch > (0.5f * Math.PI) )
			{
				m_Attitude.Pitch = (float)(0.5f * Math.PI);
			}

			if ( m_Attitude.Pitch < (-0.5f * Math.PI) )
			{
				m_Attitude.Pitch = (float)(-0.5f * Math.PI);
			}

		}

		public void MoveCamera( float x, float y, float z )
		{
			float ty;
			m_X += x * (float)Math.Cos(m_Attitude.Heading) + z * (float)Math.Sin(m_Attitude.Heading);
			m_Y += y;
			m_Z += z * (float)Math.Cos(m_Attitude.Heading) + x * (float)Math.Sin(m_Attitude.Heading);
			try
			{
				ty = CGameEngine.Ground.HeightOfTerrain(new Vector3(m_X, m_Y, m_Z));
			}
			catch {ty=0;}
			m_Y = ty + 1.0f;
		}

		public CullState CheckFrustum( Vector3 pos, float radius )
		{

			float distance;
			int count = 0;

			for( int iPlane = 0; iPlane < 4; iPlane++ )  // don't check against top and bottom
			{
				distance = planeFrustum[iPlane].Dot( pos );
				if( distance <= -radius )
				{
					return CullState.AllOutside;
				}
				if ( distance > radius ) count++;
			}

			if ( count == 4 ) return CullState.AllInside;

			return CullState.PartiallyIn;
		}

		public CullState CheckFrustum( Object3D obj )
		{

			float distance = 0.0f;
			int count = 0;

			for( int iPlane = 0; iPlane < 4; iPlane++ )  // don't check against top and bottom
			{
				distance = planeFrustum[iPlane].Dot( obj.Position );
				if( distance <= -obj.Radius )
				{
					return CullState.AllOutside;
				}
				if ( distance > obj.Radius ) count++;
			}

			if ( count == 4 ) return CullState.AllInside;

			return CullState.PartiallyIn;
		}

		public float GetDistance( Object3D obj )
		{
			return planeFrustum[3].Dot( obj.Position ) + m_fNearPlane;
		}

		public void Attach( Object3D parent, Vector3 offset )
		{
			m_AttachedObject = parent;
			m_Offset = offset;
		}

		public void LookAt( Object3D obj )
		{
			m_LookAtObject = obj;
		}

		public void Render()
		{
			Vector3 Up = new Vector3(0.0f, 1.0f, 0.0f);
			if ( m_AttachedObject != null ) 
			{
				if ( m_LookAtObject != null )
				{
					m_LookAt = m_LookAtObject.Position;
				}
				else
				{
					m_LookAt = m_AttachedObject.Position;
					m_LookAt.X += (float)Math.Sin(m_Attitude.Heading)*10.0f;
					m_LookAt.Y += (float)Math.Sin(m_Attitude.Pitch)*10.0f;
					m_LookAt.Z += (float)Math.Cos(m_Attitude.Heading)*10.0f;
				}
				Matrix transpose = Matrix.Identity;

				m_Attitude.Heading = Attitude.Aepc(m_AttachedObject.Heading);
				m_Attitude.Pitch = m_AttachedObject.Pitch;
				m_Attitude.Roll = 0.0f;
				transpose.RotateYawPitchRoll(m_Attitude.Heading,
					m_Attitude.Pitch,m_Attitude.Roll);

				m_Eye = m_AttachedObject.Position + 
					Vector3.TransformCoordinate(m_Offset, transpose);
			}
			else 
			{
				m_Eye = new Vector3( m_X, m_Y, m_Z);
				if ( m_LookAtObject != null )
				{
					m_LookAt = m_LookAtObject.Position;
				}
				else
				{
					m_LookAt = m_Eye;
					m_LookAt.X += (float)Math.Sin(m_Attitude.Heading)*10.0f;
					m_LookAt.Y += (float)Math.Sin(m_Attitude.Pitch)*10.0f;
					m_LookAt.Z += (float)Math.Cos(m_Attitude.Heading)*10.0f;
				}
			}
			// Set the app view matrix for normal viewing
			m_matView = Matrix.LookAtLH(m_Eye, m_LookAt, Up);

			CGameEngine.Device3D.Transform.View = m_matView;

			CGameEngine.Device3D.Transform.Projection = m_matProj;

			Matrix mat = Matrix.Multiply(m_matView, m_matProj);
			mat.Invert();

			vecFrustum[0] = new Vector3(-1.0f, -1.0f,  0.0f); // xyz
			vecFrustum[1] = new Vector3( 1.0f, -1.0f,  0.0f); // Xyz
			vecFrustum[2] = new Vector3(-1.0f,  1.0f,  0.0f); // xYz
			vecFrustum[3] = new Vector3( 1.0f,  1.0f,  0.0f); // XYz
			vecFrustum[4] = new Vector3(-1.0f, -1.0f,  1.0f); // xyZ
			vecFrustum[5] = new Vector3( 1.0f, -1.0f,  1.0f); // XyZ
			vecFrustum[6] = new Vector3(-1.0f,  1.0f,  1.0f); // xYZ
			vecFrustum[7] = new Vector3( 1.0f,  1.0f,  1.0f); // XYZ

			for( int i = 0; i < 8; i++ )
				vecFrustum[i] = Vector3.TransformCoordinate(vecFrustum[i],mat);

			planeFrustum[0] = Plane.FromPoints(vecFrustum[7],
				vecFrustum[3],vecFrustum[5]); // Right
			planeFrustum[1] = Plane.FromPoints(vecFrustum[2], 
				vecFrustum[6],vecFrustum[4]); // Left
			planeFrustum[2] = Plane.FromPoints(vecFrustum[6], 
				vecFrustum[7],vecFrustum[5]); // Far
			planeFrustum[3] = Plane.FromPoints(vecFrustum[0], 
				vecFrustum[1],vecFrustum[2]); // Near
			planeFrustum[4] = Plane.FromPoints(vecFrustum[2], 
				vecFrustum[3],vecFrustum[6]); // Top
			planeFrustum[5] = Plane.FromPoints(vecFrustum[1], 
				vecFrustum[0],vecFrustum[4]); // Bottom
		}

		public void Reset()
		{
			m_VisibleObjects.Clear();
		}

		public void AddVisibleObject( Object3D obj )
		{
			if ( ! (obj is TerrainQuad) )
			{
				m_VisibleObjects.Add( obj );
			}
		}

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -