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.

660 lines
22 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef CAMERA_H
  9. #define CAMERA_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include <math.h>
  14. #include <float.h>
  15. // For vec_t, put this somewhere else?
  16. #include "tier0/basetypes.h"
  17. #include "mathlib/vector.h"
  18. #include "tier0/dbg.h"
  19. #include "mathlib/vector2d.h"
  20. #include "mathlib/math_pfns.h"
  21. #include "mathlib/vmatrix.h"
  22. #include "mathlib/ssemath.h"
  23. #include "datamap.h"
  24. #include "mathlib/aabb.h"
  25. #include "tier0/memalloc.h"
  26. // declarations for camera and frustum
  27. extern VMatrix g_matViewToCameraMatrix, g_matCameraToViewMatrix;
  28. struct ALIGN16 Camera_t
  29. {
  30. void Init( const Vector &origin, const QAngle &angles, float flNear, float flFar, float flFOV, float flAspect );
  31. void InitOrtho( const Vector &origin, const QAngle &angles, float flNear, float flFar, float flWidth, float flHeight );
  32. void InitViewParameters( const Vector &vOrigin, const QAngle &vAngles );
  33. void InitOrthoProjection( float flZNear, float flZFar, float flWidth, float flHeight );
  34. bool IsOrthographic() const;
  35. void InitPerspectiveProjection( float flZNear, float flZFar, float flFOVX, float flAspect );
  36. // generates 8 vertices of the frustum
  37. // vertex order is near plane (UL, UR, LL, LR), far plane (UL, UR, LL, LR)
  38. void ComputeGeometry( Vector *pVertsOut8 ) const;
  39. void ComputeGeometry( Vector *pVertsOut8, const Vector &vForward, const Vector &vLeft, const Vector &vUp ) const;
  40. inline bool operator ==( const Camera_t &other ) const;
  41. inline bool operator !=( const Camera_t &other ) const;
  42. Vector m_origin;
  43. QAngle m_angles;
  44. // FOV for X/width.
  45. // This should be set to -1 to get an ortho projection,
  46. // in which case it'll use m_flWidth and m_flHeight.
  47. float m_flFOVX;
  48. float m_flAspect; // For Perspective
  49. float m_flZNear;
  50. float m_flZFar;
  51. float m_flWidth; // For ortho.
  52. float m_flHeight;
  53. } ALIGN16_POST;
  54. inline void Camera_t::Init( const Vector &origin, const QAngle &angles, float flNear, float flFar, float flFOV, float flAspect )
  55. {
  56. InitViewParameters( origin, angles );
  57. InitPerspectiveProjection( flNear, flFar, flFOV, flAspect );
  58. m_flWidth = -1;
  59. m_flHeight = -1;
  60. }
  61. inline void Camera_t::InitOrtho( const Vector &origin, const QAngle &angles, float flNear, float flFar, float flWidth, float flHeight )
  62. {
  63. InitViewParameters( origin, angles );
  64. InitOrthoProjection( flNear, flFar, flWidth, flHeight );
  65. }
  66. inline void Camera_t::InitViewParameters( const Vector &vOrigin, const QAngle &vAngles )
  67. {
  68. m_origin = vOrigin;
  69. m_angles = vAngles;
  70. }
  71. inline void Camera_t::InitOrthoProjection( float flZNear, float flZFar, float flWidth, float flHeight )
  72. {
  73. m_flFOVX = -1;
  74. m_flZNear = flZNear;
  75. m_flZFar = flZFar;
  76. m_flWidth = flWidth;
  77. m_flHeight = flHeight;
  78. }
  79. inline bool Camera_t::IsOrthographic() const
  80. {
  81. return m_flFOVX == -1;
  82. }
  83. inline void Camera_t::InitPerspectiveProjection( float flZNear, float flZFar, float flFOVX, float flAspect )
  84. {
  85. m_flFOVX = flFOVX;
  86. m_flAspect = flAspect;
  87. m_flZNear = flZNear;
  88. m_flZFar = flZFar;
  89. }
  90. inline bool Camera_t::operator ==( const Camera_t &other ) const
  91. {
  92. return ( m_origin == other.m_origin ) &&
  93. ( m_angles == other.m_angles ) &&
  94. ( m_flFOVX == other.m_flFOVX ) &&
  95. ( m_flAspect == other.m_flAspect ) &&
  96. ( m_flZNear == other.m_flZNear ) &&
  97. ( m_flZFar == other.m_flZFar ) &&
  98. ( m_flWidth == other.m_flWidth ) &&
  99. ( m_flHeight == other.m_flHeight );
  100. }
  101. inline bool Camera_t::operator !=( const Camera_t &other ) const
  102. {
  103. return !( *this == other );
  104. }
  105. ///\name Functions to set up a VMatrix from various input view specifications
  106. //@{
  107. /// This maps the X/Y bounds into [-1,1] and flNear/flFar into [0,1]
  108. inline VMatrix OrthoMatrixRH( float x1, float y1, float x2, float y2, float flNear, float flFar )
  109. {
  110. float flDelta = flNear - flFar;
  111. float ix = 2.0f / ( x2 - x1 );
  112. float iy = 2.0f / ( y2 - y1 );
  113. VMatrix mRet(
  114. ix, 0, 0, 0,
  115. 0, iy, 0, 0,
  116. 0, 0, 1.0f / flDelta, flNear / flDelta,
  117. 0, 0, 0, 1 );
  118. return mRet;
  119. }
  120. inline VMatrix OrthoMatrixOffCenterRH( float x1, float y1, float x2, float y2, float flNear, float flFar )
  121. {
  122. float flDelta = flNear - flFar;
  123. float ix = 2.0f / ( x2 - x1 );
  124. float iy = 2.0f / ( y2 - y1 );
  125. VMatrix mRet(
  126. ix, 0, 0, -(ix * x1) - 1,
  127. 0, iy, 0, -(iy * y1) - 1,
  128. 0, 0, 1.0f / flDelta, flNear / flDelta,
  129. 0, 0, 0, 1 );
  130. return mRet;
  131. }
  132. /// This maps the X/Y bounds into [-1,1] and flNear/flFar into [0,1]
  133. /// This is left-handed for concatenation onto the viewproj matrix for app-tiling in source2
  134. inline VMatrix OrthoMatrixOffCenterLH( float x1, float y1, float x2, float y2, float flNear, float flFar )
  135. {
  136. float flDelta = flFar - flNear;
  137. float ix = 2.0f / ( x2 - x1 );
  138. float iy = 2.0f / ( y2 - y1 );
  139. VMatrix mRet(
  140. ix, 0, 0, 0,
  141. 0, iy, 0, 0,
  142. 0, 0, 1.0f / flDelta, 0,
  143. ( x1 + x2 )/( x1 - x2 ), ( y1 + y2 ) / ( y1 - y2 ), -flNear / flDelta, 1 );
  144. return mRet;
  145. }
  146. /// This is the hammer wireframe widget version that inverts depth and shifts the xy coordinates
  147. inline VMatrix OrthoMatrixHammerRH( float x1, float y1, float x2, float y2, float flNear, float flFar )
  148. {
  149. float flDelta = flNear - flFar;
  150. float ix = 2.0f / ( x2 - x1 );
  151. float iy = 2.0f / ( y2 - y1 );
  152. VMatrix mRet(
  153. ix, 0, 0, -(ix * x1) - 1,
  154. 0, iy, 0, -(iy * y1) - 1,
  155. 0, 0, 1.0f / flDelta, -flNear / flDelta,
  156. 0, 0, 0, 1 );
  157. return mRet;
  158. }
  159. /// helper to calculate an ortho matrix for a view region centered at 0 of specified width and height
  160. inline VMatrix OrthoMatrixRH( float flWidth, float flHeight, float flNear, float flFar )
  161. {
  162. return OrthoMatrixRH( -flWidth/2, -flHeight/2, flWidth/2, flHeight/2, flNear, flFar );
  163. }
  164. /// calculate a view matrix given an origin, forward vector, and up vector
  165. VMatrix ViewMatrixRH( Vector &vEye, Vector &vAt, Vector &vUp );
  166. /// calculate a VMatrix from a camera_t
  167. void ComputeViewMatrix( VMatrix *pWorldToView, const Camera_t& camera );
  168. /// calculate a matrix3x4_t corresponding to a camera_t
  169. void ComputeViewMatrix( matrix3x4_t *pWorldToView, const Camera_t& camera );
  170. void ComputeViewMatrix( matrix3x4_t *pWorldToView, matrix3x4_t *pWorldToCamera, const Camera_t &camera );
  171. void ComputeViewMatrix( matrix3x4_t *pWorldToView, matrix3x4_t *pCameraToWorld,
  172. Vector const &vecOrigin,
  173. Vector const &vecForward, Vector const &vecLeft, Vector const &vecUp );
  174. void ComputeViewMatrix( VMatrix *pViewMatrix, const Vector &origin, const QAngle &angles );
  175. void ComputeViewMatrix( VMatrix *pViewMatrix, const matrix3x4_t &matGameCustom );
  176. void ComputeProjectionMatrix( VMatrix *pCameraToProjection, const Camera_t& camera, int width, int height );
  177. void ComputeProjectionMatrix( VMatrix *pCameraToProjection, float flZNear, float flZFar, float flFOVX, float flAspectRatio );
  178. void ComputeProjectionMatrix( VMatrix *pCameraToProjection, float flZNear, float flZFar, float flFOVX, float flAspectRatio,
  179. float flClipSpaceBottomLeftX, float flClipSpaceBottomLeftY,
  180. float flClipSpaceTopRightX, float flClipSpaceTopRightY );
  181. //@}
  182. void CalcFarPlaneCameraRelativePoints( Vector *p4PointsOut, Vector &vForward, Vector &vUp, Vector &vLeft, float flFarPlane,
  183. float flFovX, float flFovY,
  184. float flClipSpaceBottomLeftX = -1.0f, float flClipSpaceBottomLeftY = -1.0f,
  185. float flClipSpaceTopRightX = 1.0f, float flClipSpaceTopRightY = 1.0f );
  186. /// transform a point from 3d to 2d, given screen width + height
  187. void ComputeScreenSpacePosition( Vector2D *pScreenPosition, const Vector &vecWorldPosition,
  188. const Camera_t &camera, int width, int height );
  189. // Functions to build frustum information given params
  190. void MatricesFromCamera( VMatrix &mWorldToView, VMatrix &mProjection, const Camera_t &camera,
  191. float flClipSpaceBottomLeftX = -1.0f, float flClipSpaceBottomLeftY = -1.0f,
  192. float flClipSpaceTopRightX = 1.0f, float flClipSpaceTopRightY = 1.0f );
  193. void FrustumFromViewProj( Frustum_t *pFrustum, const VMatrix &mViewProj, const Vector &origin, bool bD3DClippingRange = true );
  194. void FrustumFromMatrices( Frustum_t *pFrustum, const VMatrix &mWorldToView, const VMatrix &mProjection, const Vector &origin, bool bD3DClippingRange = true );
  195. // TODO: desired api.
  196. //void MatrixFromFrustum( VMatrix *pViewProj, const Frustum_t &frustum );
  197. VMatrix ViewProjFromVectors( const Vector &origin, float flNear, float flFar, float flFOV, float flAspect,
  198. Vector const &vecForward, Vector const &vecLeft, Vector const &vecUp );
  199. enum EBoxOverlapFlags
  200. {
  201. BOXCHECK_FLAGS_OVERLAPS_NEAR = 1,
  202. BOXCHECK_FLAGS_OVERLAPS_FAR = 2,
  203. };
  204. /// Class holding a camera, frustum planes, and transformation matrices, and methods to calculate
  205. /// them and keep them in sync.
  206. class CFrustum
  207. {
  208. public:
  209. CFrustum();
  210. ~CFrustum(){}
  211. //--------------------------------------------------------------------------------------------------
  212. // Camera fxns
  213. //--------------------------------------------------------------------------------------------------
  214. void InitCamera( const Camera_t &Other )
  215. {
  216. m_camera = Other;
  217. m_bDirty = true;
  218. }
  219. // For an off-center projection:
  220. // flClipSpaceXXXX coordinates are in clip space, where ( -1,-1 ) is the bottom left corner of the screen
  221. // and ( 1,1 ) is the top right corner of the screen.
  222. void InitCamera( const Vector &origin, const QAngle &angles, float flNear, float flFar, float flFOV, float flAspect,
  223. float flClipSpaceBottomLeftX = -1.0f, float flClipSpaceBottomLeftY = -1.0f, float flClipSpaceTopRightX = 1.0f, float flClipSpaceTopRightY = 1.0f )
  224. {
  225. m_camera.Init( origin, angles, flNear, flFar, flFOV, flAspect );
  226. m_flClipSpaceBottomLeftX = flClipSpaceBottomLeftX;
  227. m_flClipSpaceBottomLeftY = flClipSpaceBottomLeftY;
  228. m_flClipSpaceTopRightX = flClipSpaceTopRightX;
  229. m_flClipSpaceTopRightY = flClipSpaceTopRightY;
  230. m_bDirty = true;
  231. }
  232. void InitOrthoCamera( const Vector &origin, const QAngle &angles, float flNear, float flFar, float flWidth, float flHeight,
  233. float flClipSpaceBottomLeftX = -1.0f, float flClipSpaceBottomLeftY = -1.0f, float flClipSpaceTopRightX = 1.0f, float flClipSpaceTopRightY = 1.0f )
  234. {
  235. m_camera.InitOrtho( origin, angles, flNear, flFar, flWidth, flHeight );
  236. m_camera.m_flAspect = flWidth / flHeight;
  237. m_flClipSpaceBottomLeftX = flClipSpaceBottomLeftX;
  238. m_flClipSpaceBottomLeftY = flClipSpaceBottomLeftY;
  239. m_flClipSpaceTopRightX = flClipSpaceTopRightX;
  240. m_flClipSpaceTopRightY = flClipSpaceTopRightY;
  241. m_bDirty = true;
  242. }
  243. bool IsOrthographic() const { return m_camera.IsOrthographic(); }
  244. void SetCameraPosition( const Vector &origin );
  245. const Vector &GetCameraPosition() const { return m_camera.m_origin; }
  246. void SetCameraAngles( const QAngle &angles );
  247. const QAngle &GetCameraAngles() const { return m_camera.m_angles; }
  248. // Sets the distance from the camera to the near/far clipping plane in world units.
  249. void SetCameraNearFarPlanes( float flNear, float flFar );
  250. void GetCameraNearFarPlanes( float &flNear, float &flFar ) const { flNear = m_camera.m_flZNear; flFar = m_camera.m_flZFar; }
  251. // Sets the distance from the camera to the near clipping plane in world units.
  252. void SetCameraNearPlane( float flNear );
  253. float GetCameraNearPlane() const { return m_camera.m_flZNear; }
  254. // Sets the distance from the camera to the far clipping plane in world units.
  255. void SetCameraFarPlane( float flFar );
  256. float GetCameraFarPlane() const { return m_camera.m_flZFar; }
  257. // Set the field of view (in degrees)
  258. void SetCameraFOV( float flFOV );
  259. float GetCameraFOV() const { return m_camera.m_flFOVX; }
  260. void SetCameraWidthHeight( float flWidth, float flHeight );
  261. void GetCameraWidthHeight( float &width, float &height ) const { width = m_camera.m_flWidth; height = m_camera.m_flHeight; }
  262. void SetCameraWidth( float flWidth );
  263. float GetCameraWidth() const { return m_camera.m_flWidth; }
  264. void SetCameraHeight( float flHeight );
  265. float GetCameraHeight() const { return m_camera.m_flHeight; }
  266. void SetCameraAspect( float flAspect );
  267. float GetCameraAspect() const { return m_camera.m_flAspect; }
  268. /// Returns mask of BOXCHECK_FLAGS_xxx indicating the status of the box with respect to this
  269. /// frustum's near and far clip planes.
  270. int CheckBoxAgainstNearAndFarPlanes( const VectorAligned &minBounds, const VectorAligned &maxBounds ) const;
  271. /// given an AABB, return the values of the near and far plane which will enclose the box
  272. void GetNearAndFarPlanesAroundBox( float *pNear, float *pFar, AABB_t const &inBox, Vector &vOriginShift ) const;
  273. /// Compute the approximate size of a sphere. Rough calculation suitable for lod selection,
  274. /// etc. Result is in terms of approximate % coverage of the viewport, not taking clipping
  275. /// into account.
  276. float ComputeScreenSize( Vector vecOrigin, float flRadius ) const;
  277. /// Return the Sin of the FOV
  278. FORCEINLINE float SinFOV( void ) const { return sin( DEG2RAD( GetCameraFOV() ) ); }
  279. const Camera_t &GetCameraStruct() const { return m_camera; }
  280. //--------------------------------------------------------------------------------------------------
  281. // Frustum fxns
  282. //--------------------------------------------------------------------------------------------------
  283. void SetFrustumStruct( const Frustum_t &frustumStruct ) { m_frustumStruct = frustumStruct; }
  284. // Camera oriented directions
  285. const Vector &CameraForward() const { return m_forward; }
  286. const Vector &CameraLeft() const { return m_left; }
  287. const Vector &CameraUp() const { return m_up; }
  288. // View oriented directions i.e. view align matrix has been applied
  289. void ViewForward( Vector& vViewForward ) const;
  290. void ViewLeft( Vector& vViewLeft ) const;
  291. void ViewUp( Vector& vViewUp ) const;
  292. void SetView( VMatrix &mWorldToView ) { m_worldToView = mWorldToView.As3x4(); }
  293. const matrix3x4_t &GetView() const { return m_worldToView; }
  294. void SetProj( VMatrix &mProj ) { m_projection = mProj; }
  295. const VMatrix &GetProj() const { return m_projection; }
  296. const VMatrix &GetInvProj() const { return m_invProjection; }
  297. // The viewProj and invViewProj matrices are NOT transposed.
  298. void SetViewProj( VMatrix &viewProj ) { m_viewProj = viewProj; }
  299. const VMatrix &GetViewProj() const { return m_viewProj; }
  300. VMatrix GetViewProjTranspose() const { return m_viewProj.Transpose(); }
  301. void SetInvViewProj( VMatrix &invViewProj ) { m_invViewProj = invViewProj; }
  302. const VMatrix &GetInvViewProj() const { return m_invViewProj; }
  303. VMatrix GetInvViewProjTranspose() const { return m_invViewProj.Transpose(); }
  304. bool BoundingVolumeIntersectsFrustum( AABB_t const &box ) const;
  305. bool BoundingVolumeIntersectsFrustum( Vector const &mins, Vector const &maxes ) const;
  306. bool BoundingVolumeIntersectsFrustum( AABB_t const &box, Vector &vOriginShift ) const;
  307. /// Update the matrix and clip planes for this frustum to reflect the state of the embedded Camera_t
  308. void UpdateFrustumFromCamera();
  309. /// build a full frustum from rotation vectors plus camera vars
  310. void BuildFrustumFromVectors( const Vector &origin, float flNear, float flFar, float flFOV, float flAspect,
  311. Vector const &vecForward, Vector const &vecLeft, Vector const &vecUp );
  312. void BuildShadowFrustum( VMatrix &newWorldToView, VMatrix &newProj );
  313. void BuildFrustumFromParameters(
  314. const Vector &origin, const QAngle &angles,
  315. float flNear, float flFar, float flFOV, float flAspect,
  316. const VMatrix &worldToView, const VMatrix &viewToProj );
  317. /// calculate the projection of the 4 view-frustum corner rays onto a plane
  318. void CalcFarPlaneCameraRelativePoints( Vector *p4PointsOut, float flFarPlane,
  319. float flClipSpaceBottomLeftX = -1.0f, float flClipSpaceBottomLeftY = -1.0f,
  320. float flClipSpaceTopRightX = 1.0f, float flClipSpaceTopRightY = 1.0f ) const;
  321. /// concatenate the projection and view matrices, and also update the inverse view and
  322. /// projection matrices
  323. void CalcViewProj( );
  324. /// Transform a point from world space into camera space.
  325. Vector4D TransformPointToHomogenousViewCoordinates( Vector const &pnt ) const;
  326. void SetClipSpaceBounds( float flClipSpaceBottomLeftX, float flClipSpaceBottomLeftY, float flClipSpaceTopRightX, float flClipSpaceTopRightY );
  327. void GetClipSpaceBounds( float &flClipSpaceBottomLeftX, float &flClipSpaceBottomLeftY, float &flClipSpaceTopRightX, float &flClipSpaceTopRightY ) const
  328. {
  329. flClipSpaceBottomLeftX = m_flClipSpaceBottomLeftX;
  330. flClipSpaceBottomLeftY = m_flClipSpaceBottomLeftY;
  331. flClipSpaceTopRightX = m_flClipSpaceTopRightX;
  332. flClipSpaceTopRightY = m_flClipSpaceTopRightY;
  333. }
  334. // NOTE: Not tested with ortho projections
  335. void ComputeBounds( Vector *pMins, Vector *pMaxs ) const;
  336. void ComputeGeometry( Vector *pVertsOut8 ) const { m_camera.ComputeGeometry( pVertsOut8, m_forward, m_left, m_up ); }
  337. const Frustum_t &GetFrustumStruct() const { return m_frustumStruct; }
  338. //--------------------------------------------------------------------------------------------------
  339. void ViewToWorld( const Vector2D &vViewMinusOneToOne, Vector *pOutWorld );
  340. void BuildRay( const Vector2D &vViewMinusOneToOne, Vector *pOutRayStart, Vector *pOutRayDirection );
  341. protected:
  342. Camera_t m_camera; // NOTE: SIMD-aligned
  343. Frustum_t m_frustumStruct; // NOTE: SIMD-aligned
  344. // For off-center projection
  345. float m_flClipSpaceBottomLeftX;
  346. float m_flClipSpaceBottomLeftY;
  347. float m_flClipSpaceTopRightX;
  348. float m_flClipSpaceTopRightY;
  349. Vector m_forward;
  350. Vector m_left;
  351. Vector m_up;
  352. // Camera/view matrices. (The space order is: world->camera->view->projection->screenspace.)
  353. matrix3x4_t m_cameraToWorld; // camera->world (NOT view->world, and not the inverse of m_worldToView)
  354. matrix3x4_t m_worldToView; // world->view
  355. // Projection matrices.
  356. VMatrix m_projection; // view->proj
  357. VMatrix m_invProjection; // proj->view
  358. // Combined world->projection matrices.
  359. VMatrix m_viewProj; // world->proj
  360. VMatrix m_invViewProj; // proj->world
  361. bool m_bDirty;
  362. };
  363. inline CFrustum::CFrustum()
  364. {
  365. InitCamera( Vector( 0, 0, 0 ), QAngle( 0, 0, 0 ), 10, 100, 90, 1.0f );
  366. V_memset( &m_frustumStruct, 0, sizeof(Frustum_t) );
  367. m_forward.Init( 0, 0, 0 );
  368. m_left.Init( 0, 0, 0 );
  369. m_up.Init( 0, 0, 0 );
  370. V_memset( &m_cameraToWorld, 0, sizeof(matrix3x4_t) );
  371. V_memset( &m_worldToView, 0, sizeof(matrix3x4_t) );
  372. V_memset( &m_projection, 0, sizeof(VMatrix) );
  373. V_memset( &m_invProjection, 0, sizeof(VMatrix) );
  374. V_memset( &m_viewProj, 0, sizeof(VMatrix) );
  375. V_memset( &m_invViewProj, 0, sizeof(VMatrix) );
  376. m_bDirty = true;
  377. }
  378. inline void CFrustum::SetCameraPosition( const Vector &origin )
  379. {
  380. if ( m_camera.m_origin == origin )
  381. return;
  382. m_camera.m_origin = origin;
  383. Assert( origin.IsValid() && origin.IsReasonable() );
  384. m_bDirty = true;
  385. }
  386. inline void CFrustum::SetCameraAngles( const QAngle &angles )
  387. {
  388. if ( m_camera.m_angles == angles )
  389. return;
  390. m_camera.m_angles = angles;
  391. m_bDirty = true;
  392. }
  393. inline void CFrustum::SetCameraNearFarPlanes( float flNear, float flFar )
  394. {
  395. if ( ( m_camera.m_flZNear == flNear ) && ( m_camera.m_flZFar == flFar ) )
  396. return;
  397. m_camera.m_flZNear = flNear;
  398. m_camera.m_flZFar = flFar;
  399. m_bDirty = true;
  400. }
  401. inline void CFrustum::SetCameraNearPlane( float flNear )
  402. {
  403. if ( m_camera.m_flZNear == flNear )
  404. return;
  405. m_camera.m_flZNear = flNear;
  406. m_bDirty = true;
  407. }
  408. inline void CFrustum::SetCameraFarPlane( float flFar )
  409. {
  410. if ( m_camera.m_flZFar == flFar )
  411. return;
  412. m_camera.m_flZFar = flFar;
  413. m_bDirty = true;
  414. }
  415. /// Set the field of view (in degrees)
  416. inline void CFrustum::SetCameraFOV( float flFOV )
  417. {
  418. if ( m_camera.m_flFOVX == flFOV )
  419. return;
  420. m_camera.m_flFOVX = flFOV;
  421. m_bDirty = true;
  422. }
  423. inline void CFrustum::SetCameraWidthHeight( float flWidth, float flHeight )
  424. {
  425. if ( ( m_camera.m_flWidth == flWidth ) && ( m_camera.m_flHeight == flHeight ) )
  426. return;
  427. m_camera.m_flWidth = flWidth;
  428. m_camera.m_flHeight = flHeight;
  429. m_camera.m_flAspect = m_camera.m_flWidth / m_camera.m_flHeight;
  430. m_bDirty = true;
  431. }
  432. inline void CFrustum::SetCameraWidth( float flWidth )
  433. {
  434. if ( m_camera.m_flWidth == flWidth )
  435. return;
  436. m_camera.m_flWidth = flWidth;
  437. m_camera.m_flAspect = m_camera.m_flWidth / m_camera.m_flHeight;
  438. m_bDirty = true;
  439. }
  440. inline void CFrustum::SetCameraHeight( float flHeight )
  441. {
  442. if ( m_camera.m_flHeight == flHeight )
  443. return;
  444. m_camera.m_flHeight = flHeight;
  445. m_camera.m_flAspect = m_camera.m_flWidth / m_camera.m_flHeight;
  446. m_bDirty = true;
  447. }
  448. inline void CFrustum::SetCameraAspect( float flAspect )
  449. {
  450. if ( m_camera.m_flAspect == flAspect )
  451. return;
  452. m_camera.m_flAspect = flAspect;
  453. m_bDirty = true;
  454. }
  455. inline bool CFrustum::BoundingVolumeIntersectsFrustum( AABB_t const &box ) const
  456. {
  457. Vector vMins = box.m_vMinBounds - m_camera.m_origin;
  458. Vector vMaxs = box.m_vMaxBounds - m_camera.m_origin;
  459. return m_frustumStruct.Intersects( vMins, vMaxs );
  460. }
  461. inline bool CFrustum::BoundingVolumeIntersectsFrustum( Vector const &mins, Vector const &maxes ) const
  462. {
  463. Vector vMins = mins - m_camera.m_origin;
  464. Vector vMaxs = maxes - m_camera.m_origin;
  465. return m_frustumStruct.Intersects( vMins, vMaxs );
  466. }
  467. inline bool CFrustum::BoundingVolumeIntersectsFrustum( AABB_t const &box, Vector &vOriginShift ) const
  468. {
  469. Vector vMins = box.m_vMinBounds - m_camera.m_origin - vOriginShift;
  470. Vector vMaxs = box.m_vMaxBounds - m_camera.m_origin - vOriginShift;
  471. return m_frustumStruct.Intersects( vMins, vMaxs );
  472. }
  473. inline Vector4D CFrustum::TransformPointToHomogenousViewCoordinates( Vector const &pnt ) const
  474. {
  475. Vector4D v4Rslt;
  476. GetViewProj().V4Mul( Vector4D( pnt.x, pnt.y, pnt.z, 1.0 ), v4Rslt );
  477. return v4Rslt;
  478. }
  479. inline void CFrustum::ViewForward( Vector& vViewForward ) const
  480. {
  481. Vector vFrustumDir;
  482. MatrixGetRow( VMatrix( m_worldToView ), Z_AXIS, &vFrustumDir );
  483. VectorNormalize( vFrustumDir );
  484. vFrustumDir = -vFrustumDir;
  485. vViewForward = vFrustumDir;
  486. }
  487. inline void CFrustum::ViewLeft( Vector& vViewLeft ) const
  488. {
  489. Vector vFrustumDir;
  490. MatrixGetRow( VMatrix( m_worldToView ), X_AXIS, &vFrustumDir );
  491. VectorNormalize( vFrustumDir );
  492. vViewLeft = -vFrustumDir;
  493. }
  494. inline void CFrustum::ViewUp( Vector& vViewUp ) const
  495. {
  496. Vector vFrustumDir;
  497. MatrixGetRow( VMatrix( m_worldToView ), Y_AXIS, &vFrustumDir );
  498. VectorNormalize( vFrustumDir );
  499. vViewUp = vFrustumDir;
  500. }
  501. inline void CFrustum::SetClipSpaceBounds( float flClipSpaceBottomLeftX, float flClipSpaceBottomLeftY, float flClipSpaceTopRightX, float flClipSpaceTopRightY )
  502. {
  503. m_flClipSpaceBottomLeftX = flClipSpaceBottomLeftX;
  504. m_flClipSpaceBottomLeftY = flClipSpaceBottomLeftY;
  505. m_flClipSpaceTopRightX = flClipSpaceTopRightX;
  506. m_flClipSpaceTopRightY = flClipSpaceTopRightY;
  507. m_bDirty = true;
  508. }
  509. #endif // CAMERA_H