Team Fortress 2 Source Code as on 22/4/2020
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.

714 lines
20 KiB

  1. //========= Copyright 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(PRINTF_FORMAT_STRING const 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: Pitches the camera forward axis toward the camera's down axis a
  418. // given number of degrees.
  419. //-----------------------------------------------------------------------------
  420. void CCamera::Pitch(float fDegrees)
  421. {
  422. if (fDegrees != 0)
  423. {
  424. float fPitch = GetPitch();
  425. fPitch += fDegrees;
  426. SetPitch(fPitch);
  427. }
  428. }
  429. //-----------------------------------------------------------------------------
  430. // Purpose: Rolls the camera's right axis toward the camera's up axis a given
  431. // number of degrees.
  432. //-----------------------------------------------------------------------------
  433. void CCamera::Roll(float fDegrees)
  434. {
  435. if (fDegrees != 0)
  436. {
  437. float fRoll = GetRoll();
  438. fRoll += fDegrees;
  439. SetRoll(fRoll);
  440. }
  441. }
  442. //-----------------------------------------------------------------------------
  443. // Purpose: Yaws the camera's forward axis toward the camera's right axis a
  444. // given number of degrees.
  445. //-----------------------------------------------------------------------------
  446. void CCamera::Yaw(float fDegrees)
  447. {
  448. if (fDegrees != 0)
  449. {
  450. float fYaw = GetYaw();
  451. fYaw += fDegrees;
  452. SetYaw(fYaw);
  453. }
  454. }
  455. //-----------------------------------------------------------------------------
  456. // Purpose: Loads the given matrix with an identity matrix.
  457. // Input : Matrix - 4 x 4 matrix to be loaded with the identity matrix.
  458. //-----------------------------------------------------------------------------
  459. void CCamera::CameraIdentityMatrix(VMatrix& Matrix)
  460. {
  461. // This function produces a transform which transforms from
  462. // material system camera space to quake camera space
  463. // Camera right axis lies along the world X axis.
  464. Matrix[CAMERA_RIGHT][0] = 1;
  465. Matrix[CAMERA_RIGHT][1] = 0;
  466. Matrix[CAMERA_RIGHT][2] = 0;
  467. Matrix[CAMERA_RIGHT][3] = 0;
  468. // Camera up axis lies along the world Z axis.
  469. Matrix[CAMERA_UP][0] = 0;
  470. Matrix[CAMERA_UP][1] = 0;
  471. Matrix[CAMERA_UP][2] = 1;
  472. Matrix[CAMERA_UP][3] = 0;
  473. // Camera forward axis lies along the negative world Y axis.
  474. Matrix[CAMERA_FORWARD][0] = 0;
  475. Matrix[CAMERA_FORWARD][1] = -1;
  476. Matrix[CAMERA_FORWARD][2] = 0;
  477. Matrix[CAMERA_FORWARD][3] = 0;
  478. Matrix[CAMERA_ORIGIN][0] = 0;
  479. Matrix[CAMERA_ORIGIN][1] = 0;
  480. Matrix[CAMERA_ORIGIN][2] = 0;
  481. Matrix[CAMERA_ORIGIN][3] = 1;
  482. }
  483. //-----------------------------------------------------------------------------
  484. // Purpose: Generates a view matrix based on our current yaw, pitch, and roll.
  485. // The view matrix does not consider FOV or clip plane distances.
  486. //-----------------------------------------------------------------------------
  487. void CCamera::BuildViewMatrix()
  488. {
  489. // The camera transformation is produced by multiplying roll * yaw * pitch.
  490. // This will transform a point from world space into quake camera space,
  491. // which is exactly what we want for our view matrix. However, quake
  492. // camera space isn't the same as material system camera space, so
  493. // we're going to have to apply a transformation that goes from quake
  494. // camera space to material system camera space.
  495. CameraIdentityMatrix( m_ViewMatrix );
  496. RotateAroundAxis(m_ViewMatrix, m_fPitch, 0 );
  497. RotateAroundAxis(m_ViewMatrix, m_fRoll, 1);
  498. RotateAroundAxis(m_ViewMatrix, m_fYaw, 2);
  499. // Translate the viewpoint to the world origin.
  500. VMatrix TempMatrix;
  501. TempMatrix.Identity();
  502. TempMatrix.SetTranslation( -m_ViewPoint );
  503. m_ViewMatrix = m_ViewMatrix * TempMatrix;
  504. m_ViewProjMatrix = m_ProjMatrix * m_ViewMatrix;
  505. m_ViewProjMatrix.InverseGeneral( m_InvViewProjMatrix );
  506. }
  507. //-----------------------------------------------------------------------------
  508. // Purpose:
  509. // Input : Matrix -
  510. //-----------------------------------------------------------------------------
  511. void CCamera::GetViewMatrix(VMatrix& Matrix)
  512. {
  513. Matrix = m_ViewMatrix;
  514. }
  515. void CCamera::GetProjMatrix(VMatrix& Matrix)
  516. {
  517. Matrix = m_ProjMatrix;
  518. }
  519. //-----------------------------------------------------------------------------
  520. // Purpose: Sets the view matrix of the current projection
  521. // Output : Matrix - the matrix to store the current projection matrix
  522. //-----------------------------------------------------------------------------
  523. void CCamera::GetViewProjMatrix( VMatrix &Matrix )
  524. {
  525. Matrix = m_ViewProjMatrix;
  526. }
  527. //-----------------------------------------------------------------------------
  528. // Purpose: to set the zoom in the orthographic gl view
  529. // Input: fScale - the zoom scale
  530. //-----------------------------------------------------------------------------
  531. void CCamera::SetZoom( float fScale )
  532. {
  533. if ( m_fZoom != fScale )
  534. {
  535. m_fZoom = fScale;
  536. BuildProjMatrix();
  537. }
  538. }
  539. //-----------------------------------------------------------------------------
  540. // Purpose: to accumulate the zoom in the orthographic gl view
  541. // Input: fScale - the zoom scale
  542. //-----------------------------------------------------------------------------
  543. void CCamera::Zoom( float fScale )
  544. {
  545. m_fZoom += fScale;
  546. // don't zoom negative
  547. if( m_fZoom < 0.00001f )
  548. m_fZoom = 0.00001f;
  549. }
  550. //-----------------------------------------------------------------------------
  551. // Purpose: to get the zoom in the orthographic gl view
  552. // Output: return the zoom scale
  553. //-----------------------------------------------------------------------------
  554. float CCamera::GetZoom( void )
  555. {
  556. return m_fZoom;
  557. }
  558. void CCamera::WorldToView( const Vector& vWorld, Vector2D &vView )
  559. {
  560. Vector vView3D;
  561. Vector3DMultiplyPositionProjective( m_ViewProjMatrix, vWorld, vView3D );
  562. // NOTE: The negative sign on y is because wc wants to think about screen
  563. // coordinates in a different way than the material system
  564. vView.x = 0.5 * (vView3D.x + 1.0) * m_nViewWidth;
  565. vView.y = 0.5 * (-vView3D.y + 1.0) * m_nViewHeight;
  566. }
  567. void CCamera::ViewToWorld( const Vector2D &vView, Vector& vWorld)
  568. {
  569. Vector vView3D;
  570. vView3D.x = 2.0 * vView.x / m_nViewWidth - 1;
  571. vView3D.y = -2.0 * vView.y / m_nViewHeight + 1;
  572. vView3D.z = 0;
  573. Vector3DMultiplyPositionProjective( m_InvViewProjMatrix, vView3D, vWorld );
  574. }
  575. void CCamera::BuildRay( const Vector2D &vView, Vector& vStart, Vector& vEnd )
  576. {
  577. // Find the point they clicked on in world coordinates. It lies on the near
  578. // clipping plane.
  579. Vector vClickPoint;
  580. ViewToWorld(vView, vClickPoint );
  581. // Build a ray from the viewpoint through the point on the near clipping plane.
  582. Vector vRay = vClickPoint - m_ViewPoint;
  583. VectorNormalize( vRay );
  584. vStart = m_ViewPoint;
  585. vEnd = vStart + vRay * 99999;
  586. }