Camera.cpp
上传用户:cxh8989
上传日期:2021-01-22
资源大小:2544k
文件大小:6k
源码类别:

射击游戏

开发平台:

Visual C++

  1. //========================================================
  2. /**
  3. *  @file      Camera.cpp
  4. *
  5. *  项目描述: Quake室内场景实例
  6. *  文件描述:  摄像机类  
  7. *  适用平台: Windows98/2000/NT/XP
  8. *  
  9. *  作者:     WWBOSS
  10. *  电子邮件:  wwboss123@gmail.com
  11. *  创建日期: 2006-08-06
  12. *  修改日期: 2007-09-01
  13. *
  14. */     
  15. //========================================================
  16. #include "main.h"
  17. #include "Camera.h"
  18. #include "Quake3Bsp.h"
  19. extern CVector3 g_vVelocity;
  20. #define kSpeed 200.0f
  21. double g_FrameInterval = 0.0f;
  22. extern CQuake3BSP g_Level;
  23. /** 计算FPS */
  24. void CalculateFrameRate()
  25. {
  26. static double framesPerSecond   = 0.0f;
  27.     static double lastTime = 0.0f;
  28. static char strFrameRate[50] = {0};
  29. static double frameTime = 0.0f;
  30.     double currentTime = timeGetTime() * 0.001f;
  31.   g_FrameInterval = currentTime - frameTime + 0.005f;
  32. frameTime = currentTime;
  33.     ++framesPerSecond;
  34.    if( currentTime - lastTime > 1.0f )
  35.     {
  36.     lastTime = currentTime;
  37. sprintf(strFrameRate, "Quake室内场景实例 FPS: %d", int(framesPerSecond));
  38. SetWindowText(g_hWnd, strFrameRate);  /**< 设置标题 */
  39. framesPerSecond = 0;
  40.     }
  41. }
  42. /** 计算叉积 */
  43. CVector3 Cross(CVector3 vVector1, CVector3 vVector2)
  44. {
  45. CVector3 vNormal;
  46. vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
  47. vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
  48. vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));
  49. return vNormal;  
  50. }
  51. /** 计算向量的模 */
  52. float Magnitude(CVector3 vNormal)
  53. {
  54. return (float)sqrt( (vNormal.x * vNormal.x) + 
  55. (vNormal.y * vNormal.y) + 
  56. (vNormal.z * vNormal.z) );
  57. }
  58. /** 单位化向量 */
  59. CVector3 Normalize(CVector3 vVector)
  60. {
  61. float magnitude = Magnitude(vVector);
  62. vVector = vVector / magnitude;
  63. return vVector;
  64. }
  65. CCamera::CCamera()
  66. {
  67. CVector3 vZero = CVector3(0.0, 0.0, 0.0);
  68. CVector3 vView = CVector3(0.0, 1.0, 0.5);
  69. CVector3 vUp   = CVector3(0.0, 0.0, 1.0);
  70. m_vPosition = vZero;
  71. m_vView = vView;
  72. m_vUpVector = vUp;
  73. }
  74. void CCamera::PositionCamera(float positionX, float positionY, float positionZ,
  75.         float viewX,     float viewY,     float viewZ,
  76.  float upVectorX, float upVectorY, float upVectorZ)
  77. {
  78. CVector3 vPosition = CVector3(positionX, positionY, positionZ);
  79. CVector3 vView = CVector3(viewX, viewY, viewZ);
  80. CVector3 vUpVector = CVector3(upVectorX, upVectorY, upVectorZ);
  81. m_vPosition = vPosition;
  82. m_vView     = vView;
  83. m_vUpVector = vUpVector;
  84. }
  85. void CCamera::SetViewByMouse()
  86. {
  87. POINT mousePos;
  88. int middleX = SCREEN_WIDTH  >> 1;
  89. int middleY = SCREEN_HEIGHT >> 1;
  90. float angleY = 0.0f;
  91. float angleZ = 0.0f;
  92. static float currentRotX = 0.0f;
  93. GetCursorPos(&mousePos);
  94. if( (mousePos.x == middleX) && (mousePos.y == middleY) ) return;
  95. SetCursorPos(middleX, middleY);
  96. angleY = (float)( (middleX - mousePos.x) ) / 500.0f;
  97. angleZ = (float)( (middleY - mousePos.y) ) / 500.0f;
  98. currentRotX -= angleZ;  
  99. CVector3 vAxis = Cross(m_vView - m_vPosition, m_vUpVector);
  100. vAxis = Normalize(vAxis);
  101. RotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
  102. RotateView(angleY, 0, 1, 0);
  103. }
  104. void CCamera::RotateView(float angle, float x, float y, float z)
  105. {
  106. CVector3 vNewView;
  107. CVector3 vView = m_vView - m_vPosition;
  108. float cosTheta = (float)cos(angle);
  109. float sinTheta = (float)sin(angle);
  110. vNewView.x  = (cosTheta + (1 - cosTheta) * x * x) * vView.x;
  111. vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta) * vView.y;
  112. vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta) * vView.z;
  113. vNewView.y  = ((1 - cosTheta) * x * y + z * sinTheta) * vView.x;
  114. vNewView.y += (cosTheta + (1 - cosTheta) * y * y) * vView.y;
  115. vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta) * vView.z;
  116. vNewView.z  = ((1 - cosTheta) * x * z - y * sinTheta) * vView.x;
  117. vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta) * vView.y;
  118. vNewView.z += (cosTheta + (1 - cosTheta) * z * z) * vView.z;
  119. m_vView = m_vPosition + vNewView;
  120. }
  121. void CCamera::StrafeCamera(float speed)
  122. {
  123. m_vPosition.x += m_vStrafe.x * speed;
  124. m_vPosition.z += m_vStrafe.z * speed;
  125. m_vView.x += m_vStrafe.x * speed;
  126. m_vView.z += m_vStrafe.z * speed;
  127. }
  128. void CCamera::MoveCamera(float speed)
  129. {
  130. CVector3 vVector = m_vView - m_vPosition;
  131. vVector = Normalize(vVector);
  132. m_vPosition.x += vVector.x * speed;
  133. m_vPosition.z += vVector.z * speed;
  134. m_vView.x += vVector.x * speed;
  135. m_vView.z += vVector.z * speed;
  136. }
  137. void CCamera::CheckForMovement()
  138. {
  139. float speed = (float)(kSpeed * g_FrameInterval);
  140. CVector3 vOldPosition = Position();
  141. CVector3 vOldView = View();
  142. bool bMovedBack = false;
  143. g_vVelocity.y -= (float)(kGravity * g_FrameInterval);
  144. m_vPosition = m_vPosition + g_vVelocity;
  145. if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80) 
  146. {
  147. MoveCamera(speed);
  148. }
  149. if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80) 
  150. {
  151. MoveCamera(-speed);
  152. bMovedBack = true;
  153. }
  154. if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80) 
  155. {
  156. StrafeCamera(-speed);
  157. }
  158. if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80)
  159. {
  160. StrafeCamera(speed);
  161. }
  162. CVector3 vCurrentPosition = Position();
  163. CVector3 vNewPosition = g_Level.TraceBox(vOldPosition, vCurrentPosition,
  164.                                      CVector3(-20, -50, -20), CVector3(20, 50, 20));
  165. if(g_Level.Collided() && bMovedBack)
  166. {
  167. if(vNewPosition.x == vOldPosition.x || vNewPosition.z == vOldPosition.z)
  168. m_vView = vOldView;
  169. }
  170. m_vPosition = vNewPosition;
  171. if(!g_Level.IsOnGround())
  172. m_vView = m_vView + g_vVelocity;
  173. else
  174. {
  175.    if(g_vVelocity.y < 0)
  176. g_vVelocity.y = 0;
  177. }
  178. }
  179. /** 更新摄像机 */
  180. void CCamera::Update() 
  181. {
  182. CVector3 vCross = Cross(m_vView - m_vPosition, m_vUpVector);
  183. m_vStrafe = Normalize(vCross);
  184. SetViewByMouse();
  185. CheckForMovement();
  186. CalculateFrameRate();
  187. }
  188. void CCamera::Look()
  189. {
  190. gluLookAt(m_vPosition.x, m_vPosition.y, m_vPosition.z,
  191.   m_vView.x,  m_vView.y,     m_vView.z,
  192.   m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
  193. }