自己根据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. }

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

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

[3D]第一人称相机类Camera的更多相关文章

  1. 关于Unity中FPS第一人称射击类游戏制作(专题十)

    当前Unity最新版本5.6.3f1,我使用的是5.5.1f1 场景搭建 1: 导入人物模型, 手持一把枪;2: 导入碎片模型;3: 创建一个平面;4: 创建一个障碍物;5: 导入人物模型;6: 配置 ...

  2. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引 代码工程地址: https://g ...

  3. 【转】265行JavaScript代码的第一人称3D H5游戏Demo

    译文:http://blog.jobbole.com/70956/ 原文:http://www.playfuljs.com/a-first-person-engine-in-265-lines/ 这是 ...

  4. android Camera相机类

    Camera相机类相关的几个流程方法 Camera.open(cameraId) 打开相机 camera.setDisplayOrientation(0) 设置相机水平方向 mCamera.setPr ...

  5. Opengl绘制我们的小屋(二)第一人称漫游

    这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像 ...

  6. 【Unity】2.8 相机(Camera)

    分类:Unity.C#.VS2015 创建日期:2016-03-31 一.简介 Unity的相机用来向玩家呈现游戏世界.你在场景中始终至少有一个相机,但也可以有多个.多个相机可以带给您双人分屏效果或创 ...

  7. unity3d学习笔记(一) 第一人称视角实现和倒计时实现

    unity3d学习笔记(一) 第一人称视角实现和倒计时实现 1. 第一人称视角 (1)让mainCamera和player(视角对象)同步在一起 因为我们的player是生成的,所以不能把mainCa ...

  8. D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建

    说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...

  9. 基于HTML5及WebGL开发的2D3D第一人称漫游进行碰撞检测

    为了实现一个基于HTML5的场景小游戏,我采用了HT for Web来实现,短短200行代码,我就能实现用“第一人称”来操作前进后退上下左右,并且实现了碰撞检测. 先来看下实现的效果:http://h ...

随机推荐

  1. JavaScript 取对象的值时用点和中括号的区别

    用点的时候 点后面是对象的真实属性名称, 用中括号的时候 中括号里面是变量或者字符串

  2. [转]wcout输出中文却不显示出来

    准备使用UNICODE来写个控制台测试程序发现,cout无法输出UNICODE的中文字符.查找C++标准看到,其提供了wcin.wcout.wcerr.wclog用于处理wchar_t字符的输入输出. ...

  3. iOS 注冊本地通知(推送)

    注:按Home键让App进入后台执行时.方可查看通知. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithO ...

  4. quick-cocos2d-x游戏开发【10】——触摸捕获事件 cc.NODE_TOUCH_CAPTURE_EVENT

    假设看过sample中touch的代码,你会发现演示样例中有一个cc.NODE_TOUCH_CAPTURE_EVENT事件.它和cc.NODE_TOUCH_EVENT触摸事件一样,是引擎级别的事件,我 ...

  5. swift - UIButton 的用法

    1,按钮的创建 (1)按钮有下面四种类型: contactAdd:前面带“+”图标按钮,默认文字颜色为蓝色,有触摸时的高亮效果 detailDisclosure:前面带“!”图标按钮,默认文字颜色为蓝 ...

  6. abs()

    abs() 用于返回一个数值的绝对值 In [1]: abs(10) Out[1]: 10 In [2]: abs(-10) Out[2]: 10 In [3]: abs(-10.9) Out[3]: ...

  7. 批量执行命令:fabric

    Fabric 可以通过 SSH 在多台客户端主机上批量执行任务,是基于 paramiko 封装开发的,paramiko 更底层一些,安装方法如下: [root@localhost ~]$ yum in ...

  8. Python 使用正则表达式匹配URL网址

    使用正则表达式匹配以 .com 或 .cn 为域名后缀的URL地址 In [1]: import re In [2]: str = "http://www.baidu.com/" ...

  9. 第四篇:GPU 并行编程的存储系统架构

    前言 在用 CUDA 对 GPU 进行并行编程的过程中,除了需要对线程架构要有深刻的认识外,也需要对存储系统架构有深入的了解. 这两个部分是 GPU 编程中最为基础,也是最为重要的部分,需要花时间去理 ...

  10. m2014-architecture-imgserver->Lighttpd +mod_mem_cache的效果简直太好了

    公司的图片服务器一直以来负载都比较高,原因是图片比较分散而且比较小.经常把iowait搞的特别的高.但是只有一台机器也法用squid,经测试squid和apache在同一台机器效果会很糟糕的.因为sq ...