[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         }

 

你可能感兴趣的:(Camera)