Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

723 lines
21 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements a camera for the 3D view.
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <windows.h>
  8. #include <math.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include "Camera.h"
  12. #include "hammer_mathlib.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. //
  16. // Indices of camera axes.
  17. //
  18. #define CAMERA_RIGHT 0
  19. #define CAMERA_UP 1
  20. #define CAMERA_FORWARD 2
  21. #define CAMERA_ORIGIN 3
  22. #define MIN_PITCH -90.0f
  23. #define MAX_PITCH 90.0f
  24. static void DBG(char *fmt, ...)
  25. {
  26. char ach[128];
  27. va_list va;
  28. va_start(va, fmt);
  29. vsprintf(ach, fmt, va);
  30. va_end(va);
  31. OutputDebugString(ach);
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Purpose: Constructor.
  35. //-----------------------------------------------------------------------------
  36. CCamera::CCamera(void)
  37. {
  38. m_ViewPoint.Init();
  39. m_fPitch = 0.0;
  40. m_fRoll = 0.0;
  41. m_fYaw = 0.0;
  42. m_fHorizontalFOV = 90;
  43. m_fNearClip = 1.0;
  44. m_fFarClip = 5000;
  45. m_fZoom = 1.0f;
  46. m_bIsOrthographic = false;
  47. m_fScaleHorz = m_fScaleVert = 1;
  48. m_nViewWidth = m_nViewHeight = 100;
  49. BuildViewMatrix();
  50. BuildProjMatrix();
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Purpose: Destructor.
  54. //-----------------------------------------------------------------------------
  55. CCamera::~CCamera(void)
  56. {
  57. }
  58. void CCamera::SetViewPort( int width, int height )
  59. {
  60. if ( m_nViewWidth != width || m_nViewHeight != height )
  61. {
  62. m_nViewWidth = width;
  63. m_nViewHeight = height;
  64. BuildProjMatrix();
  65. }
  66. }
  67. void CCamera::GetViewPort( int &width, int &height )
  68. {
  69. width = m_nViewWidth;
  70. height = m_nViewHeight;
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose: Returns the current value of the camera's pitch.
  74. //-----------------------------------------------------------------------------
  75. float CCamera::GetPitch(void)
  76. {
  77. return(m_fPitch);
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Purpose: Returns the current value of the camera's roll.
  81. //-----------------------------------------------------------------------------
  82. float CCamera::GetRoll(void)
  83. {
  84. return(m_fRoll);
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose: Returns the current value of the camera's yaw.
  88. //-----------------------------------------------------------------------------
  89. float CCamera::GetYaw(void)
  90. {
  91. return(m_fYaw);
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Purpose: returns the camera angles
  95. // Output : returns the camera angles
  96. //-----------------------------------------------------------------------------
  97. QAngle CCamera::GetAngles()
  98. {
  99. return QAngle( m_fPitch, m_fYaw, m_fRoll );
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose: Moves the camera along the camera's right axis.
  103. // Input : fUnits - World units to move the camera.
  104. //-----------------------------------------------------------------------------
  105. void CCamera::MoveRight(float fUnits)
  106. {
  107. if (fUnits != 0)
  108. {
  109. m_ViewPoint[0] += m_ViewMatrix[CAMERA_RIGHT][0] * fUnits;
  110. m_ViewPoint[1] += m_ViewMatrix[CAMERA_RIGHT][1] * fUnits;
  111. m_ViewPoint[2] += m_ViewMatrix[CAMERA_RIGHT][2] * fUnits;
  112. BuildViewMatrix();
  113. }
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose: Moves the camera along the camera's up axis.
  117. // Input : fUnits - World units to move the camera.
  118. //-----------------------------------------------------------------------------
  119. void CCamera::MoveUp(float fUnits)
  120. {
  121. if (fUnits != 0)
  122. {
  123. m_ViewPoint[0] += m_ViewMatrix[CAMERA_UP][0] * fUnits;
  124. m_ViewPoint[1] += m_ViewMatrix[CAMERA_UP][1] * fUnits;
  125. m_ViewPoint[2] += m_ViewMatrix[CAMERA_UP][2] * fUnits;
  126. BuildViewMatrix();
  127. }
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose: Moves the camera along the camera's forward axis.
  131. // Input : fUnits - World units to move the camera.
  132. //-----------------------------------------------------------------------------
  133. void CCamera::MoveForward(float fUnits)
  134. {
  135. if (fUnits != 0)
  136. {
  137. m_ViewPoint[0] -= m_ViewMatrix[CAMERA_FORWARD][0] * fUnits;
  138. m_ViewPoint[1] -= m_ViewMatrix[CAMERA_FORWARD][1] * fUnits;
  139. m_ViewPoint[2] -= m_ViewMatrix[CAMERA_FORWARD][2] * fUnits;
  140. BuildViewMatrix();
  141. }
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose: Returns the camera's viewpoint.
  145. //-----------------------------------------------------------------------------
  146. void CCamera::GetViewPoint(Vector& ViewPoint) const
  147. {
  148. ViewPoint = m_ViewPoint;
  149. }
  150. //-----------------------------------------------------------------------------
  151. // Purpose: Returns a vector indicating the camera's forward axis.
  152. //-----------------------------------------------------------------------------
  153. void CCamera::GetViewForward(Vector& ViewForward) const
  154. {
  155. ViewForward[0] = -m_ViewMatrix[CAMERA_FORWARD][0];
  156. ViewForward[1] = -m_ViewMatrix[CAMERA_FORWARD][1];
  157. ViewForward[2] = -m_ViewMatrix[CAMERA_FORWARD][2];
  158. }
  159. //-----------------------------------------------------------------------------
  160. // Purpose: Returns a vector indicating the camera's up axis.
  161. //-----------------------------------------------------------------------------
  162. void CCamera::GetViewUp(Vector& ViewUp) const
  163. {
  164. ViewUp[0] = m_ViewMatrix[CAMERA_UP][0];
  165. ViewUp[1] = m_ViewMatrix[CAMERA_UP][1];
  166. ViewUp[2] = m_ViewMatrix[CAMERA_UP][2];
  167. }
  168. //-----------------------------------------------------------------------------
  169. // Purpose: Returns a vector indicating the camera's right axis.
  170. //-----------------------------------------------------------------------------
  171. void CCamera::GetViewRight(Vector& ViewRight) const
  172. {
  173. ViewRight[0] = m_ViewMatrix[CAMERA_RIGHT][0];
  174. ViewRight[1] = m_ViewMatrix[CAMERA_RIGHT][1];
  175. ViewRight[2] = m_ViewMatrix[CAMERA_RIGHT][2];
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Purpose: Returns the horizontal field of view in degrees.
  179. //-----------------------------------------------------------------------------
  180. float CCamera::GetFOV(void)
  181. {
  182. return(m_fHorizontalFOV);
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Purpose: Returns the distance from the camera to the near clipping plane in world units.
  186. //-----------------------------------------------------------------------------
  187. float CCamera::GetNearClip(void)
  188. {
  189. return(m_fNearClip);
  190. }
  191. //-----------------------------------------------------------------------------
  192. // Purpose: Returns the distance from the camera to the far clipping plane in world units.
  193. //-----------------------------------------------------------------------------
  194. float CCamera::GetFarClip(void)
  195. {
  196. return(m_fFarClip);
  197. }
  198. //-----------------------------------------------------------------------------
  199. // Purpose: Sets up fields of view & clip plane distances for the view frustum.
  200. // Input : fHorizontalFOV -
  201. // fVerticalFOV -
  202. // fNearClip -
  203. // fFarClip -
  204. //-----------------------------------------------------------------------------
  205. void CCamera::SetPerspective(float fHorizontalFOV, float fNearClip, float fFarClip)
  206. {
  207. m_bIsOrthographic = false;
  208. m_fHorizontalFOV = fHorizontalFOV;
  209. m_fNearClip = fNearClip;
  210. m_fFarClip = fFarClip;
  211. BuildProjMatrix();
  212. }
  213. void CCamera::SetOrthographic(float fZoom, float fNearClip, float fFarClip)
  214. {
  215. m_fZoom = fZoom;
  216. m_fNearClip = fNearClip;
  217. m_fFarClip = fFarClip;
  218. m_bIsOrthographic = true;
  219. BuildProjMatrix();
  220. }
  221. void CCamera::GetFrustumPlanes( Vector4D Planes[6] )
  222. {
  223. // TODO check for FrustumPlanesFromMatrix, maybe we can use that
  224. Vector ViewForward;
  225. GetViewForward(ViewForward);
  226. VMatrix CameraMatrix = m_ProjMatrix * m_ViewMatrix;
  227. //
  228. // Now the plane coefficients can be pulled directly out of the the camera
  229. // matrix as follows:
  230. //
  231. // Right : first_column - fourth_column
  232. // Left : -first_column - fourth_column
  233. // Top : second_column - fourth_column
  234. // Bottom: -second_column - fourth_column
  235. // Front : -third_column - fourth_column
  236. // Back : third_column + fourth_column
  237. //
  238. // dvs: My plane constants should be coming directly from the matrices,
  239. // but they aren't (for some reason). Instead I calculate the plane
  240. // constants myself. Sigh.
  241. //
  242. Planes[0][0] = CameraMatrix[0][0] - CameraMatrix[3][0];
  243. Planes[0][1] = CameraMatrix[0][1] - CameraMatrix[3][1];
  244. Planes[0][2] = CameraMatrix[0][2] - CameraMatrix[3][2];
  245. VectorNormalize(Planes[0].AsVector3D());
  246. Planes[0][3] = DotProduct(m_ViewPoint, Planes[0].AsVector3D());
  247. Planes[1][0] = -CameraMatrix[0][0] - CameraMatrix[3][0];
  248. Planes[1][1] = -CameraMatrix[0][1] - CameraMatrix[3][1];
  249. Planes[1][2] = -CameraMatrix[0][2] - CameraMatrix[3][2];
  250. VectorNormalize(Planes[1].AsVector3D());
  251. Planes[1][3] = DotProduct(m_ViewPoint, Planes[1].AsVector3D());
  252. Planes[2][0] = CameraMatrix[1][0] - CameraMatrix[3][0];
  253. Planes[2][1] = CameraMatrix[1][1] - CameraMatrix[3][1];
  254. Planes[2][2] = CameraMatrix[1][2] - CameraMatrix[3][2];
  255. VectorNormalize(Planes[2].AsVector3D());
  256. Planes[2][3] = DotProduct(m_ViewPoint, Planes[2].AsVector3D());
  257. Planes[3][0] = -CameraMatrix[1][0] - CameraMatrix[3][0];
  258. Planes[3][1] = -CameraMatrix[1][1] - CameraMatrix[3][1];
  259. Planes[3][2] = -CameraMatrix[1][2] - CameraMatrix[3][2];
  260. VectorNormalize(Planes[3].AsVector3D());
  261. Planes[3][3] = DotProduct(m_ViewPoint, Planes[3].AsVector3D());
  262. Planes[4][0] = -CameraMatrix[2][0] - CameraMatrix[3][0];
  263. Planes[4][1] = -CameraMatrix[2][1] - CameraMatrix[3][1];
  264. Planes[4][2] = -CameraMatrix[2][2] - CameraMatrix[3][2];
  265. VectorNormalize(Planes[4].AsVector3D());
  266. Planes[4][3] = DotProduct(m_ViewPoint + ViewForward * m_fNearClip, Planes[4].AsVector3D());
  267. Planes[5][0] = CameraMatrix[2][0] + CameraMatrix[3][0];
  268. Planes[5][1] = CameraMatrix[2][1] + CameraMatrix[3][1];
  269. Planes[5][2] = CameraMatrix[2][2] + CameraMatrix[3][2];
  270. VectorNormalize(Planes[5].AsVector3D());
  271. Planes[5][3] = DotProduct(m_ViewPoint + ViewForward * m_fFarClip, Planes[5].AsVector3D());
  272. }
  273. bool CCamera::IsOrthographic()
  274. {
  275. return m_bIsOrthographic;
  276. }
  277. void CCamera::BuildProjMatrix()
  278. {
  279. memset( &m_ProjMatrix,0,sizeof(m_ProjMatrix) );
  280. VMatrix &m = m_ProjMatrix;
  281. if ( m_bIsOrthographic )
  282. {
  283. // same as D3DXMatrixOrthoRH
  284. float w = (float)m_nViewWidth / m_fZoom;
  285. float h = (float)m_nViewHeight / m_fZoom;
  286. m[0][0] = 2/w;
  287. m[1][1] = 2/h;
  288. m[2][2] = 1/(m_fNearClip-m_fFarClip);
  289. m[2][3] = m_fNearClip/(m_fNearClip-m_fFarClip);
  290. m[3][3] = 1;
  291. }
  292. else
  293. {
  294. // same as D3DXMatrixPerspectiveRH
  295. float w = 2 * m_fNearClip * tan( m_fHorizontalFOV * M_PI / 360.0 );
  296. float h = ( w * float(m_nViewHeight) ) / float(m_nViewWidth);
  297. m[0][0] = 2*m_fNearClip/w;
  298. m[1][1] = 2*m_fNearClip/h;
  299. m[2][2] = m_fFarClip/(m_fNearClip-m_fFarClip);
  300. m[2][3] = (m_fNearClip*m_fFarClip)/(m_fNearClip-m_fFarClip);
  301. m[3][2] = -1;
  302. }
  303. m_ViewProjMatrix = m_ProjMatrix * m_ViewMatrix;
  304. m_ViewProjMatrix.InverseGeneral( m_InvViewProjMatrix );
  305. }
  306. //-----------------------------------------------------------------------------
  307. // Purpose: Sets the distance from the camera to the near clipping plane in world units.
  308. //-----------------------------------------------------------------------------
  309. void CCamera::SetNearClip(float fNearClip)
  310. {
  311. if ( m_fNearClip != fNearClip )
  312. {
  313. m_fNearClip = fNearClip;
  314. BuildProjMatrix();
  315. }
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Purpose: Sets the distance from the camera to the far clipping plane in world units.
  319. //-----------------------------------------------------------------------------
  320. void CCamera::SetFarClip(float fFarClip)
  321. {
  322. if ( m_fFarClip != fFarClip )
  323. {
  324. m_fFarClip = fFarClip;
  325. BuildProjMatrix();
  326. }
  327. }
  328. //-----------------------------------------------------------------------------
  329. // Purpose: Sets the pitch in degrees, from [MIN_PITCH..MAX_PITCH]
  330. //-----------------------------------------------------------------------------
  331. void CCamera::SetPitch(float fDegrees)
  332. {
  333. if (m_fPitch != fDegrees)
  334. {
  335. m_fPitch = fDegrees;
  336. if (m_fPitch > MAX_PITCH)
  337. {
  338. m_fPitch = MAX_PITCH;
  339. }
  340. else if (m_fPitch < MIN_PITCH)
  341. {
  342. m_fPitch = MIN_PITCH;
  343. }
  344. BuildViewMatrix();
  345. }
  346. }
  347. //-----------------------------------------------------------------------------
  348. // Purpose: Sets the roll in degrees, from [0..360)
  349. //-----------------------------------------------------------------------------
  350. void CCamera::SetRoll(float fDegrees)
  351. {
  352. while (fDegrees >= 360)
  353. {
  354. fDegrees -= 360;
  355. }
  356. while (fDegrees < 0)
  357. {
  358. fDegrees += 360;
  359. }
  360. if (m_fRoll != fDegrees)
  361. {
  362. m_fRoll = fDegrees;
  363. BuildViewMatrix();
  364. }
  365. }
  366. //-----------------------------------------------------------------------------
  367. // Purpose: Sets the yaw in degrees, from [0..360)
  368. //-----------------------------------------------------------------------------
  369. void CCamera::SetYaw(float fDegrees)
  370. {
  371. while (fDegrees >= 360)
  372. {
  373. fDegrees -= 360;
  374. }
  375. while (fDegrees < 0)
  376. {
  377. fDegrees += 360;
  378. }
  379. if (m_fYaw != fDegrees)
  380. {
  381. m_fYaw = fDegrees;
  382. BuildViewMatrix();
  383. }
  384. }
  385. //-----------------------------------------------------------------------------
  386. // Purpose: Sets the view point.
  387. //-----------------------------------------------------------------------------
  388. void CCamera::SetViewPoint(const Vector &ViewPoint)
  389. {
  390. if ( m_ViewPoint != ViewPoint )
  391. {
  392. m_ViewPoint = ViewPoint;
  393. BuildViewMatrix();
  394. }
  395. }
  396. //-----------------------------------------------------------------------------
  397. // Purpose: Sets the camera target, rebuilding the view matrix.
  398. // Input : ViewTarget - the point in world space that the camera should look at.
  399. //-----------------------------------------------------------------------------
  400. void CCamera::SetViewTarget(const Vector &ViewTarget)
  401. {
  402. Vector ViewOrigin;
  403. Vector ViewForward;
  404. GetViewPoint( ViewOrigin );
  405. VectorSubtract(ViewTarget, ViewOrigin, ViewForward);
  406. VectorNormalize(ViewForward);
  407. //
  408. // Ideally we could replace the math below with standard VectorAngles stuff, but Hammer
  409. // camera matrices use a different convention from QAngle (sadly).
  410. //
  411. float fYaw = RAD2DEG(atan2(ViewForward[0], ViewForward[1]));
  412. SetYaw(fYaw);
  413. float fPitch = -RAD2DEG(asin(ViewForward[2]));
  414. SetPitch(fPitch);
  415. }
  416. //-----------------------------------------------------------------------------
  417. // Purpose: Move the camera along a worldspace vector.
  418. //-----------------------------------------------------------------------------
  419. void CCamera::Move(Vector &vDelta)
  420. {
  421. m_ViewPoint += vDelta;
  422. BuildViewMatrix();
  423. }
  424. //-----------------------------------------------------------------------------
  425. // Purpose: Pitches the camera forward axis toward the camera's down axis a
  426. // given number of degrees.
  427. //-----------------------------------------------------------------------------
  428. void CCamera::Pitch(float fDegrees)
  429. {
  430. if (fDegrees != 0)
  431. {
  432. float fPitch = GetPitch();
  433. fPitch += fDegrees;
  434. SetPitch(fPitch);
  435. }
  436. }
  437. //-----------------------------------------------------------------------------
  438. // Purpose: Rolls the camera's right axis toward the camera's up axis a given
  439. // number of degrees.
  440. //-----------------------------------------------------------------------------
  441. void CCamera::Roll(float fDegrees)
  442. {
  443. if (fDegrees != 0)
  444. {
  445. float fRoll = GetRoll();
  446. fRoll += fDegrees;
  447. SetRoll(fRoll);
  448. }
  449. }
  450. //-----------------------------------------------------------------------------
  451. // Purpose: Yaws the camera's forward axis toward the camera's right axis a
  452. // given number of degrees.
  453. //-----------------------------------------------------------------------------
  454. void CCamera::Yaw(float fDegrees)
  455. {
  456. if (fDegrees != 0)
  457. {
  458. float fYaw = GetYaw();
  459. fYaw += fDegrees;
  460. SetYaw(fYaw);
  461. }
  462. }
  463. //-----------------------------------------------------------------------------
  464. // Purpose: Loads the given matrix with an identity matrix.
  465. // Input : Matrix - 4 x 4 matrix to be loaded with the identity matrix.
  466. //-----------------------------------------------------------------------------
  467. void CCamera::CameraIdentityMatrix(VMatrix& Matrix)
  468. {
  469. // This function produces a transform which transforms from
  470. // material system camera space to quake camera space
  471. // Camera right axis lies along the world X axis.
  472. Matrix[CAMERA_RIGHT][0] = 1;
  473. Matrix[CAMERA_RIGHT][1] = 0;
  474. Matrix[CAMERA_RIGHT][2] = 0;
  475. Matrix[CAMERA_RIGHT][3] = 0;
  476. // Camera up axis lies along the world Z axis.
  477. Matrix[CAMERA_UP][0] = 0;
  478. Matrix[CAMERA_UP][1] = 0;
  479. Matrix[CAMERA_UP][2] = 1;
  480. Matrix[CAMERA_UP][3] = 0;
  481. // Camera forward axis lies along the negative world Y axis.
  482. Matrix[CAMERA_FORWARD][0] = 0;
  483. Matrix[CAMERA_FORWARD][1] = -1;
  484. Matrix[CAMERA_FORWARD][2] = 0;
  485. Matrix[CAMERA_FORWARD][3] = 0;
  486. Matrix[CAMERA_ORIGIN][0] = 0;
  487. Matrix[CAMERA_ORIGIN][1] = 0;
  488. Matrix[CAMERA_ORIGIN][2] = 0;
  489. Matrix[CAMERA_ORIGIN][3] = 1;
  490. }
  491. //-----------------------------------------------------------------------------
  492. // Purpose: Generates a view matrix based on our current yaw, pitch, and roll.
  493. // The view matrix does not consider FOV or clip plane distances.
  494. //-----------------------------------------------------------------------------
  495. void CCamera::BuildViewMatrix()
  496. {
  497. // The camera transformation is produced by multiplying roll * yaw * pitch.
  498. // This will transform a point from world space into quake camera space,
  499. // which is exactly what we want for our view matrix. However, quake
  500. // camera space isn't the same as material system camera space, so
  501. // we're going to have to apply a transformation that goes from quake
  502. // camera space to material system camera space.
  503. CameraIdentityMatrix( m_ViewMatrix );
  504. RotateAroundAxis(m_ViewMatrix, m_fPitch, 0 );
  505. RotateAroundAxis(m_ViewMatrix, m_fRoll, 1);
  506. RotateAroundAxis(m_ViewMatrix, m_fYaw, 2);
  507. // Translate the viewpoint to the world origin.
  508. VMatrix TempMatrix;
  509. TempMatrix.Identity();
  510. TempMatrix.SetTranslation( -m_ViewPoint );
  511. m_ViewMatrix = m_ViewMatrix * TempMatrix;
  512. m_ViewProjMatrix = m_ProjMatrix * m_ViewMatrix;
  513. m_ViewProjMatrix.InverseGeneral( m_InvViewProjMatrix );
  514. }
  515. //-----------------------------------------------------------------------------
  516. // Purpose:
  517. // Input : Matrix -
  518. //-----------------------------------------------------------------------------
  519. void CCamera::GetViewMatrix(VMatrix& Matrix)
  520. {
  521. Matrix = m_ViewMatrix;
  522. }
  523. void CCamera::GetProjMatrix(VMatrix& Matrix)
  524. {
  525. Matrix = m_ProjMatrix;
  526. }
  527. //-----------------------------------------------------------------------------
  528. // Purpose: Sets the view matrix of the current projection
  529. // Output : Matrix - the matrix to store the current projection matrix
  530. //-----------------------------------------------------------------------------
  531. void CCamera::GetViewProjMatrix( VMatrix &Matrix )
  532. {
  533. Matrix = m_ViewProjMatrix;
  534. }
  535. //-----------------------------------------------------------------------------
  536. // Purpose: to set the zoom in the orthographic gl view
  537. // Input: fScale - the zoom scale
  538. //-----------------------------------------------------------------------------
  539. void CCamera::SetZoom( float fScale )
  540. {
  541. if ( m_fZoom != fScale )
  542. {
  543. m_fZoom = fScale;
  544. BuildProjMatrix();
  545. }
  546. }
  547. //-----------------------------------------------------------------------------
  548. // Purpose: to accumulate the zoom in the orthographic gl view
  549. // Input: fScale - the zoom scale
  550. //-----------------------------------------------------------------------------
  551. void CCamera::Zoom( float fScale )
  552. {
  553. m_fZoom += fScale;
  554. // don't zoom negative
  555. if( m_fZoom < 0.00001f )
  556. m_fZoom = 0.00001f;
  557. }
  558. //-----------------------------------------------------------------------------
  559. // Purpose: to get the zoom in the orthographic gl view
  560. // Output: return the zoom scale
  561. //-----------------------------------------------------------------------------
  562. float CCamera::GetZoom( void )
  563. {
  564. return m_fZoom;
  565. }
  566. void CCamera::WorldToView( const Vector& vWorld, Vector2D &vView )
  567. {
  568. Vector vView3D;
  569. Vector3DMultiplyPositionProjective( m_ViewProjMatrix, vWorld, vView3D );
  570. // NOTE: The negative sign on y is because wc wants to think about screen
  571. // coordinates in a different way than the material system
  572. vView.x = 0.5 * (vView3D.x + 1.0) * m_nViewWidth;
  573. vView.y = 0.5 * (-vView3D.y + 1.0) * m_nViewHeight;
  574. }
  575. void CCamera::ViewToWorld( const Vector2D &vView, Vector& vWorld)
  576. {
  577. Vector vView3D;
  578. vView3D.x = 2.0 * vView.x / m_nViewWidth - 1;
  579. vView3D.y = -2.0 * vView.y / m_nViewHeight + 1;
  580. vView3D.z = 0;
  581. Vector3DMultiplyPositionProjective( m_InvViewProjMatrix, vView3D, vWorld );
  582. }
  583. void CCamera::BuildRay( const Vector2D &vView, Vector& vStart, Vector& vEnd )
  584. {
  585. // Find the point they clicked on in world coordinates. It lies on the near
  586. // clipping plane.
  587. Vector vClickPoint;
  588. ViewToWorld(vView, vClickPoint );
  589. // Build a ray from the viewpoint through the point on the near clipping plane.
  590. Vector vRay = vClickPoint - m_ViewPoint;
  591. VectorNormalize( vRay );
  592. vStart = m_ViewPoint;
  593. vEnd = vStart + vRay * 99999;
  594. }