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.

499 lines
16 KiB

  1. //======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ======
  2. //
  3. // A class representing a camera
  4. //
  5. //===============================================================================
  6. #include "movieobjects/dmecamera.h"
  7. #include "tier0/dbg.h"
  8. #include "datamodel/dmelementfactoryhelper.h"
  9. #include "mathlib/vector.h"
  10. #include "movieobjects/dmetransform.h"
  11. #include "materialsystem/imaterialsystem.h"
  12. #include "movieobjects_interfaces.h"
  13. #include "tier2/tier2.h"
  14. // FIXME: REMOVE
  15. #include "istudiorender.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. //-----------------------------------------------------------------------------
  19. // Expose this class to the scene database
  20. //-----------------------------------------------------------------------------
  21. IMPLEMENT_ELEMENT_FACTORY( DmeCamera, CDmeCamera );
  22. //-----------------------------------------------------------------------------
  23. // Purpose:
  24. //-----------------------------------------------------------------------------
  25. void CDmeCamera::OnConstruction()
  26. {
  27. m_flFieldOfView.InitAndSet( this, "fieldOfView", 30.0f );
  28. // FIXME: This currently matches the client DLL for HL2
  29. // but we probably need a way of getting this state from the client DLL
  30. m_zNear.InitAndSet( this, "znear", 3.0f );
  31. m_zFar.InitAndSet( this, "zfar", 16384.0f * 1.73205080757f );
  32. m_flFocalDistance.InitAndSet( this, "focalDistance", 72.0f);
  33. m_flZeroParallaxDistance.InitAndSet( this, "zeroParallaxDistance", 75.0f );
  34. m_flEyeSeparation.InitAndSet( this, "eyeSeparation", 0.75f );
  35. m_flAperture.InitAndSet( this, "aperture", 0.2f);
  36. m_shutterSpeed.InitAndSet( this, "shutterSpeed", DmeTime_t( 0.5f / 24.0f ) );
  37. m_flToneMapScale.InitAndSet( this, "toneMapScale", 1.0f );
  38. m_flAOBias.InitAndSet( this, "SSAOBias", 0.0005f );
  39. m_flAOStrength.InitAndSet( this, "SSAOStrength", 1.0f );
  40. m_flAORadius.InitAndSet( this, "SSAORadius", 15.0f );
  41. m_flBloomScale.InitAndSet( this, "bloomScale", 0.28f );
  42. m_nDoFQuality.InitAndSet( this, "depthOfFieldQuality", 0 );
  43. m_nMotionBlurQuality.InitAndSet( this, "motionBlurQuality", 0 );
  44. m_flBloomWidth.InitAndSet( this, "bloomWidth", 9.0f );
  45. m_bOrtho.InitAndSet( this, "ortho", false );
  46. // Ortho
  47. m_nAxis.InitAndSet( this, "axis", 0 );
  48. m_bWasBehindFrustum.InitAndSet( this, "behindfrustum", false );
  49. m_flDistance.InitAndSet( this, "distance", 32.0f );
  50. for ( int i = 0; i < AXIS_COUNT; ++i )
  51. {
  52. char sz[ 32 ];
  53. Q_snprintf( sz, sizeof( sz ), "scale%d", i );
  54. m_flScale[ i ].InitAndSet( this, sz, 1.0f );
  55. Q_snprintf( sz, sizeof( sz ), "lookat%d", i );
  56. m_vecLookAt[ i ].Init( this, sz );
  57. }
  58. m_vecAxis.Init();
  59. m_vecOrigin.Init();
  60. m_angRotation.Init();
  61. SetIdentityMatrix( m_Transform );
  62. }
  63. void CDmeCamera::OnDestruction()
  64. {
  65. }
  66. //-----------------------------------------------------------------------------
  67. // Loads the material system view matrix based on the transform
  68. //-----------------------------------------------------------------------------
  69. void CDmeCamera::LoadViewMatrix( bool bUseEngineCoordinateSystem )
  70. {
  71. if ( !g_pMaterialSystem )
  72. return;
  73. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  74. VMatrix view;
  75. GetViewMatrix( view, bUseEngineCoordinateSystem );
  76. pRenderContext->MatrixMode( MATERIAL_VIEW );
  77. pRenderContext->LoadMatrix( view );
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Loads the material system projection matrix based on the fov, etc.
  81. //-----------------------------------------------------------------------------
  82. void CDmeCamera::LoadProjectionMatrix( int nDisplayWidth, int nDisplayHeight )
  83. {
  84. if ( !g_pMaterialSystem )
  85. return;
  86. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  87. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  88. VMatrix proj;
  89. GetProjectionMatrix( proj, nDisplayWidth, nDisplayHeight );
  90. pRenderContext->LoadMatrix( proj );
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Sets up studiorender camera state
  94. //-----------------------------------------------------------------------------
  95. void CDmeCamera::LoadStudioRenderCameraState()
  96. {
  97. // FIXME: Remove this! This should automatically happen in DrawModel
  98. // in studiorender.
  99. if ( !g_pStudioRender )
  100. return;
  101. matrix3x4_t transform;
  102. GetTransform()->GetTransform( transform );
  103. Vector vecOrigin, vecRight, vecUp, vecForward;
  104. MatrixGetColumn( transform, 0, vecRight );
  105. MatrixGetColumn( transform, 1, vecUp );
  106. MatrixGetColumn( transform, 2, vecForward );
  107. MatrixGetColumn( transform, 3, vecOrigin );
  108. g_pStudioRender->SetViewState( vecOrigin, vecRight, vecUp, vecForward );
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Returns the x FOV (the full angle)
  112. //-----------------------------------------------------------------------------
  113. float CDmeCamera::GetFOVx() const
  114. {
  115. return m_flFieldOfView;
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Returns the near Z in inches
  119. //-----------------------------------------------------------------------------
  120. float CDmeCamera::GetNearZ() const
  121. {
  122. return m_zNear;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Sets the near Z in inches
  126. //-----------------------------------------------------------------------------
  127. void CDmeCamera::SetNearZ( float zNear )
  128. {
  129. m_zNear = zNear;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Returns the far Z in inches
  133. //-----------------------------------------------------------------------------
  134. float CDmeCamera::GetFarZ() const
  135. {
  136. return m_zFar;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Sets the far Z in inches
  140. //-----------------------------------------------------------------------------
  141. void CDmeCamera::SetFarZ( float zFar )
  142. {
  143. m_zFar = zFar;
  144. }
  145. void CDmeCamera::SetFOVx( float fov )
  146. {
  147. m_flFieldOfView = fov;
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Returns the focal distance in inches
  151. //-----------------------------------------------------------------------------
  152. float CDmeCamera::GetFocalDistance() const
  153. {
  154. return m_flFocalDistance;
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Sets the focal distance in inches
  158. //-----------------------------------------------------------------------------
  159. void CDmeCamera::SetFocalDistance( const float &flFocalDistance )
  160. {
  161. m_flFocalDistance = flFocalDistance;
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Returns the zero-parallax distance in inches
  165. //-----------------------------------------------------------------------------
  166. float CDmeCamera::GetZeroParallaxDistance() const
  167. {
  168. return m_flZeroParallaxDistance;
  169. }
  170. //-----------------------------------------------------------------------------
  171. // Sets the zero-parallax distance in inches
  172. //-----------------------------------------------------------------------------
  173. void CDmeCamera::SetZeroParallaxDistance( const float &flZeroParallaxDistance )
  174. {
  175. m_flZeroParallaxDistance = flZeroParallaxDistance;
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Returns the eye separation distance in inches
  179. //-----------------------------------------------------------------------------
  180. float CDmeCamera::GetEyeSeparation() const
  181. {
  182. return m_flEyeSeparation;
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Sets the eye separation distance in inches
  186. //-----------------------------------------------------------------------------
  187. void CDmeCamera::SetEyeSeparation( const float &flEyeSeparation )
  188. {
  189. m_flEyeSeparation = flEyeSeparation;
  190. }
  191. //-----------------------------------------------------------------------------
  192. // Returns the camera aperture in inches
  193. //-----------------------------------------------------------------------------
  194. float CDmeCamera::GetAperture() const
  195. {
  196. return m_flAperture;
  197. }
  198. //-----------------------------------------------------------------------------
  199. // Returns the camera aperture in inches
  200. //-----------------------------------------------------------------------------
  201. DmeTime_t CDmeCamera::GetShutterSpeed() const
  202. {
  203. return m_shutterSpeed;
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Returns the tone map scale
  207. //-----------------------------------------------------------------------------
  208. float CDmeCamera::GetToneMapScale() const
  209. {
  210. return m_flToneMapScale;
  211. }
  212. //-----------------------------------------------------------------------------
  213. // Returns the camera's Ambient occlusion bias
  214. //-----------------------------------------------------------------------------
  215. float CDmeCamera::GetAOBias() const
  216. {
  217. return m_flAOBias;
  218. }
  219. //-----------------------------------------------------------------------------
  220. // Returns the camera's Ambient occlusion strength
  221. //-----------------------------------------------------------------------------
  222. float CDmeCamera::GetAOStrength() const
  223. {
  224. return m_flAOStrength;
  225. }
  226. //-----------------------------------------------------------------------------
  227. // Returns the camera's Ambient occlusion radius
  228. //-----------------------------------------------------------------------------
  229. float CDmeCamera::GetAORadius() const
  230. {
  231. return m_flAORadius;
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Returns the bloom scale
  235. //-----------------------------------------------------------------------------
  236. float CDmeCamera::GetBloomScale() const
  237. {
  238. return m_flBloomScale;
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Returns the bloom width
  242. //-----------------------------------------------------------------------------
  243. float CDmeCamera::GetBloomWidth() const
  244. {
  245. return m_flBloomWidth;
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Returns the number of Depth of Field samples
  249. //-----------------------------------------------------------------------------
  250. int CDmeCamera::GetDepthOfFieldQuality() const
  251. {
  252. return m_nDoFQuality;
  253. }
  254. //-----------------------------------------------------------------------------
  255. // Returns the number of Motion Blur samples
  256. //-----------------------------------------------------------------------------
  257. int CDmeCamera::GetMotionBlurQuality() const
  258. {
  259. return m_nMotionBlurQuality;
  260. }
  261. //-----------------------------------------------------------------------------
  262. // Returns the view direction
  263. //-----------------------------------------------------------------------------
  264. void CDmeCamera::GetViewDirection( Vector *pDirection )
  265. {
  266. matrix3x4_t transform;
  267. GetTransform()->GetTransform( transform );
  268. MatrixGetColumn( transform, 2, *pDirection );
  269. // We look down the -z axis
  270. *pDirection *= -1.0f;
  271. }
  272. //-----------------------------------------------------------------------------
  273. // Sets up render state in the material system for rendering
  274. //-----------------------------------------------------------------------------
  275. void CDmeCamera::SetupRenderState( int nDisplayWidth, int nDisplayHeight, bool bUseEngineCoordinateSystem /* = false */ )
  276. {
  277. LoadViewMatrix( bUseEngineCoordinateSystem );
  278. LoadProjectionMatrix( nDisplayWidth, nDisplayHeight );
  279. LoadStudioRenderCameraState( );
  280. }
  281. //-----------------------------------------------------------------------------
  282. // accessors for generated matrices
  283. //-----------------------------------------------------------------------------
  284. void CDmeCamera::GetViewMatrix( VMatrix &view, bool bUseEngineCoordinateSystem /* = false */ )
  285. {
  286. matrix3x4_t transform, invTransform;
  287. CDmeTransform *pTransform = GetTransform();
  288. pTransform->GetTransform( transform );
  289. if ( bUseEngineCoordinateSystem )
  290. {
  291. VMatrix matRotate( transform );
  292. VMatrix matRotateZ;
  293. MatrixBuildRotationAboutAxis( matRotateZ, Vector(0,0,1), -90 );
  294. MatrixMultiply( matRotate, matRotateZ, matRotate );
  295. VMatrix matRotateX;
  296. MatrixBuildRotationAboutAxis( matRotateX, Vector(1,0,0), 90 );
  297. MatrixMultiply( matRotate, matRotateX, matRotate );
  298. transform = matRotate.As3x4();
  299. }
  300. MatrixInvert( transform, invTransform );
  301. view.Init( invTransform );
  302. }
  303. void CDmeCamera::GetProjectionMatrix( VMatrix &proj, int width, int height )
  304. {
  305. float flFOV = m_flFieldOfView.Get();
  306. float flZNear = m_zNear.Get();
  307. float flZFar = m_zFar.Get();
  308. float flApsectRatio = (float)width / (float)height;
  309. // MatrixBuildPerspective( proj, flFOV, flFOV * flApsectRatio, flZNear, flZFar );
  310. #if 1
  311. float halfWidth = tan( flFOV * M_PI / 360.0 );
  312. float halfHeight = halfWidth / flApsectRatio;
  313. #else
  314. float halfHeight = tan( flFOV * M_PI / 360.0 );
  315. float halfWidth = flApsectRatio * halfHeight;
  316. #endif
  317. memset( proj.Base(), 0, sizeof( proj ) );
  318. proj[0][0] = 1.0f / halfWidth;
  319. proj[1][1] = 1.0f / halfHeight;
  320. proj[2][2] = flZFar / ( flZNear - flZFar );
  321. proj[3][2] = -1.0f;
  322. proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
  323. }
  324. void CDmeCamera::GetViewProjectionInverse( VMatrix &viewprojinv, int width, int height )
  325. {
  326. VMatrix view, proj;
  327. GetViewMatrix( view );
  328. GetProjectionMatrix( proj, width, height );
  329. VMatrix viewproj;
  330. MatrixMultiply( proj, view, viewproj );
  331. bool success = MatrixInverseGeneral( viewproj, viewprojinv );
  332. if ( !success )
  333. {
  334. Assert( 0 );
  335. MatrixInverseTR( viewproj, viewprojinv );
  336. }
  337. }
  338. //-----------------------------------------------------------------------------
  339. // Computes the screen space position given a screen size
  340. //-----------------------------------------------------------------------------
  341. void CDmeCamera::ComputeScreenSpacePosition( const Vector &vecWorldPosition, int width, int height, Vector2D *pScreenPosition )
  342. {
  343. VMatrix view, proj, viewproj;
  344. GetViewMatrix( view );
  345. GetProjectionMatrix( proj, width, height );
  346. MatrixMultiply( proj, view, viewproj );
  347. Vector vecScreenPos;
  348. Vector3DMultiplyPositionProjective( viewproj, vecWorldPosition, vecScreenPos );
  349. pScreenPosition->x = ( vecScreenPos.x + 1.0f ) * width / 2.0f;
  350. pScreenPosition->y = ( -vecScreenPos.y + 1.0f ) * height / 2.0f;
  351. }
  352. const matrix3x4_t &CDmeCamera::GetOrthoTransform() const
  353. {
  354. return m_Transform;
  355. }
  356. const Vector &CDmeCamera::GetOrthoAbsOrigin() const
  357. {
  358. return m_vecOrigin;
  359. }
  360. const QAngle &CDmeCamera::GetOrthoAbsAngles() const
  361. {
  362. return m_angRotation;
  363. }
  364. void CDmeCamera::OrthoUpdate()
  365. {
  366. m_vecAxis.Init( 0, 0, 0 );
  367. switch ( m_nAxis )
  368. {
  369. default:
  370. Assert( 0 );
  371. case AXIS_X:
  372. m_vecAxis[ 1 ] = 1;
  373. break;
  374. case AXIS_Y:
  375. m_vecAxis[ 2 ] = -1;
  376. break;
  377. case AXIS_Z:
  378. m_vecAxis[ 0 ] = 1;
  379. break;
  380. case AXIS_X_NEG:
  381. m_vecAxis[ 1 ] = -1;
  382. break;
  383. case AXIS_Y_NEG:
  384. m_vecAxis[ 2 ] = 1;
  385. break;
  386. case AXIS_Z_NEG:
  387. m_vecAxis[ 0 ] = -1;
  388. break;
  389. }
  390. m_vecOrigin = m_vecLookAt[ m_nAxis ].Get() - m_flDistance * m_vecAxis;
  391. Assert( m_vecOrigin.IsValid() );
  392. VectorAngles( m_vecAxis,m_angRotation );
  393. AngleMatrix( m_angRotation, m_vecOrigin, m_Transform );
  394. }
  395. void CDmeCamera::FromCamera( CDmeCamera *pCamera )
  396. {
  397. m_bOrtho = pCamera->m_bOrtho;
  398. matrix3x4_t mat;
  399. pCamera->GetAbsTransform( mat );
  400. MatrixCopy( mat, m_Transform );
  401. m_flFieldOfView = pCamera->GetFOVx();
  402. for ( int i = 0; i < AXIS_COUNT; ++i )
  403. {
  404. m_vecLookAt[ i ] =pCamera->m_vecLookAt[ i ];
  405. m_flScale[ i ] = pCamera->m_flScale[ i ];
  406. }
  407. m_flDistance = pCamera->m_flDistance;
  408. m_nAxis = pCamera->m_nAxis;
  409. m_bWasBehindFrustum = pCamera->m_bWasBehindFrustum;
  410. if ( m_bOrtho )
  411. {
  412. OrthoUpdate();
  413. }
  414. }
  415. void CDmeCamera::ToCamera( CDmeCamera *pCamera )
  416. {
  417. pCamera->m_bOrtho = m_bOrtho;
  418. pCamera->SetFOVx( m_flFieldOfView );
  419. pCamera->SetAbsTransform( m_Transform );
  420. for ( int i = 0; i < AXIS_COUNT; ++i )
  421. {
  422. pCamera->m_vecLookAt[ i ] = m_vecLookAt[ i ];
  423. pCamera->m_flScale[ i ] = m_flScale[ i ];
  424. }
  425. pCamera->m_flDistance = m_flDistance;
  426. pCamera->m_nAxis = m_nAxis;
  427. pCamera->m_bWasBehindFrustum = m_bWasBehindFrustum;
  428. if ( m_bOrtho )
  429. {
  430. pCamera->OrthoUpdate();
  431. }
  432. }