[3D]第一人称相机类Camera

自己根据C++ D3D的源码改写一个相机类(第一人称)。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using Microsoft.DirectX;
  6 using Microsoft.DirectX.PrivateImplementationDetails;
  7 using Microsoft.DirectX.Direct3D;
  8 
  9 namespace AppScene
 10 {
 11     public enum CameraType { LANDOBJECT, AIRCRAFT };
 12     public class Camera
 13     {
 14         CameraType mCameraType;
 15         Vector3 mPosition; //相机位置
 16         Vector3 mLook;//LookVector  
 17         Vector3 mUp;// UpVector  
 18         Vector3 mRight;// RightVector  
 19         Vector3 ViewFrustum;// 平面截投体  
 20 
 21         protected Viewport mViewPort;//视口大小
 22         protected Matrix m_ProjectionMatrix; //上一次渲染采用的投影变换矩阵 Projection matrix used in last render.
 23         protected Matrix m_ViewMatrix; //上一次渲染采用的观察矩阵 View matrix used in last render.
 24         protected Matrix m_WorldMatrix = Matrix.Identity;//世界变换矩阵
 25         public Camera()
 26         {
 27             mCameraType = CameraType.AIRCRAFT;
 28             mPosition = new Vector3(0.0f, 0.0f, -50.0f);//注意默认位置,现在对了。
 29             mRight = new Vector3(0.0f, 1.0f, 0.0f);
 30             mUp = new Vector3(0.0f, 1.0f, 0.0f);
 31             mLook = new Vector3(0.0f, 0.0f, 10.0f);
 32         }
 33         public Camera(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 upVector)
 34         {
 35             mCameraType = CameraType.AIRCRAFT;
 36             mPosition = new Vector3(0.0f, 0.0f, -100.0f);
 37             mRight = new Vector3(1.0f, 0.0f, 0.0f);
 38             mUp = new Vector3(0.0f, 1.0f, 0.0f);
 39             mLook = new Vector3(0.0f, 0.0f, 0.0f);
 40         }
 41         public void setCameraType(CameraType cameraType)
 42         {
 43             mCameraType = cameraType;
 44         }
 45         //前后移动
 46         public void walk(float units)
 47         {
 48             // move only on xz plane for land object
 49             if (mCameraType == CameraType.LANDOBJECT)
 50                 mPosition += new Vector3(mLook.X, 0.0f, mLook.Z) * units;
 51 
 52             if (mCameraType == CameraType.AIRCRAFT)
 53                 mPosition += mLook * units;
 54         }
 55         //左右移动,扫射
 56         public void strafe(float units)
 57         {
 58             // move only on xz plane for land object
 59             if (mCameraType == CameraType.LANDOBJECT)
 60                 mPosition += new Vector3(mRight.X, 0.0f, mRight.Z) * units;
 61 
 62             if (mCameraType == CameraType.AIRCRAFT)
 63                 mPosition += mRight * units;
 64         }
 65         //上下移动
 66         public void fly(float units)
 67         {
 68             // move only on y-axis for land object
 69             if (mCameraType == CameraType.LANDOBJECT)
 70                 mPosition.Y += units;
 71 
 72             if (mCameraType == CameraType.AIRCRAFT)
 73                 mPosition += mUp * units;
 74         }
 75 
 76         // 倾斜角 
 77         public void Pitch(float angle)
 78         {
 79             Matrix T = Matrix.Identity;
 80             //D3DXMatrixRotationAxis(&T, &_right, angle);
 81             T.RotateAxis(mRight, angle);
 82             // rotate _up and _look around _right vector
 83             mUp.TransformCoordinate(T);
 84             mLook.TransformCoordinate(T);
 85             //D3DXVec3TransformCoord(&_up, &_up, &T);
 86             //D3DXVec3TransformCoord(&_look, &_look, &T);
 87         }
 88         //俯仰角
 89         public void Roll(float angle)
 90         {
 91             // only roll for aircraft type
 92             if (mCameraType == CameraType.AIRCRAFT)
 93             {
 94                 Matrix T = Matrix.Identity;
 95                 T.RotateAxis(mLook, angle);
 96 
 97                 // rotate _up and _right around _look vector
 98                 mRight.TransformCoordinate(T);
 99                 mUp.TransformCoordinate(T);
100             }
101         }
102         // 航偏角
103         public void Yaw(float angle)
104         {
105             Matrix T = Matrix.Identity;
106 
107             // rotate around world y (0, 1, 0) always for land object
108             if (mCameraType == CameraType.LANDOBJECT)
109                 T.RotateY(angle);
110             // rotate around own up vector for aircraft
111             if (mCameraType == CameraType.AIRCRAFT)
112                 T.RotateAxis(mUp, angle);
113 
114             // rotate _right and _look around _up or y-axis
115             mRight.TransformCoordinate(T);
116             mLook.TransformCoordinate(T);
117         }
118         public void SetPosition(Vector3 position)// 设置相机世界坐标  
119         {
120             mPosition = position;
121         }
122         //更新相机状态
123         public Matrix UpdateCamera()
124         {
125             Matrix mViewMatrix = Matrix.Identity;
126             // Keep camera's axes orthogonal to eachother
127             //D3DXVec3Normalize(&_look, &_look);
128             mLook.Normalize();
129             //D3DXVec3Cross(&, &_look, &_right);
130             // _up = Vector3.Cross(_look, _right);
131             //D3DXVec3Normalize(&_up, &_up);
132             mUp.Normalize();
133             //D3DXVec3Cross(&_right, &_up, &_look);
134             mRight = Vector3.Cross(mUp, mLook);
135             //D3DXVec3Normalize(&_right, &_right);
136             mRight.Normalize();
137             // Build the view matrix:
138             //float x = -D3DXVec3Dot(&_right, &_pos);
139             //float y = -D3DXVec3Dot(&_up, &_pos);
140             //float z = -D3DXVec3Dot(&_look, &_pos);
141             float x = -Vector3.Dot(mRight, mPosition);
142             float y = -Vector3.Dot(mUp, mPosition);
143             float z = -Vector3.Dot(mLook, mPosition);
144 
145             mViewMatrix.M11 = mRight.X; mViewMatrix.M12 = mUp.X; mViewMatrix.M13 = mLook.X; mViewMatrix.M14 = 0.0f;
146             mViewMatrix.M21 = mRight.Y; mViewMatrix.M22 = mUp.Y; mViewMatrix.M23 = mLook.Y; mViewMatrix.M24 = 0.0f;
147             mViewMatrix.M31 = mRight.Z; mViewMatrix.M32 = mUp.Z; mViewMatrix.M33 = mLook.Z; mViewMatrix.M34 = 0.0f;
148             mViewMatrix.M41 = x; mViewMatrix.M42 = y; mViewMatrix.M43 = z; mViewMatrix.M44 = 1.0f;
149             return mViewMatrix;
150         }
151 
152         public void Update(Microsoft.DirectX.Direct3D.Device m_Device3d)
153         {
154             Matrix V = UpdateCamera();
155             m_Device3d.SetTransform(TransformType.View, V);
156         }
157         //视口大小
158         public Viewport Viewport
159         {
160             get
161             {
162                 return mViewPort;
163             }
164         }
165         //观察变换矩阵
166         public Matrix ViewMatrix
167         {
168             get
169             {
170                 return m_ViewMatrix;
171             }
172         }
173         //投影变换矩阵
174         public Matrix ProjectionMatrix
175         {
176             get
177             {
178                 return m_ProjectionMatrix;
179             }
180         }
181         //世界变换矩阵
182         public Matrix WorldMatrix
183         {
184             get
185             {
186                 return m_WorldMatrix;
187             }
188         }
189         /// <summary>
190         /// UnProject和Project之前需要调用该方法
191         /// </summary>
192         /// <param name="m_Device3d"></param>
193         public void ComputeMatrix(Device m_Device3d)
194         {
195             m_WorldMatrix = m_Device3d.GetTransform(TransformType.World);
196             m_ProjectionMatrix = m_Device3d.GetTransform(TransformType.Projection);
197             m_ViewMatrix = m_Device3d.GetTransform(TransformType.View);
198             mViewPort = m_Device3d.Viewport;
199         }
200         /// <summary>
201         /// Projects a point from world to screen coordinates.
202         /// 计算指定世界坐标的屏幕坐标
203         /// </summary>
204         /// <param name="point">Point in world space</param>
205         /// <returns>Point in screen space</returns>
206         public Vector3 Project(Vector3 point)
207         {
208             point.Project(mViewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix);
209             return point;
210         }
211 
212         internal Vector3 UnProject(Vector3 v1)
213         {
214             v1.Unproject(mViewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix);
215             return v1;
216         }
217     }
218 }
View Code

增加一个围绕某条射线旋转的方法:

 1  //
 2         public void RotateRay(float angle, Vector3 vOrigin, Vector3 vAxis)
 3         {
 4             // 计算新的焦点
 5             Vector3 vView = mLook - vOrigin;
 6             Matrix temp = Matrix.RotationAxis(vAxis, angle);
 7             vView.TransformCoordinate(temp);
 8             //vView.RotateAxis(angle, vAxis);
 9             mLook = vOrigin + vView;
10 
11             // 计算新的视点
12             vView = mPosition - vOrigin;
13            // Matrix temp2 = Matrix.RotationAxis(vAxis, angle);
14             vView.TransformCoordinate(temp);
15             //vView.RotateAxis(angle, vAxis);
16             mPosition = vOrigin + vView;
17 
18             mUp.TransformCoordinate(temp);
19           //  m_strafe.RotateAxis(angle, vAxis);
20         }
原文地址:https://www.cnblogs.com/yhlx125/p/3317377.html