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.

1191 lines
33 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "matsys_controls/potterywheelpanel.h"
  7. #include "matsys_controls/manipulator.h"
  8. #include "vgui/ISystem.h"
  9. #include "vgui/Cursor.h"
  10. #include "vgui/IVGui.h"
  11. #include "vgui/ISurface.h"
  12. #include "vgui/IInput.h"
  13. #include "VGuiMatSurface/IMatSystemSurface.h"
  14. #include "dmxloader/dmxelement.h"
  15. #include "vgui_controls/Frame.h"
  16. #include "convar.h"
  17. #include "tier0/dbg.h"
  18. #include "matsys_controls/matsyscontrols.h"
  19. #include "materialsystem/imaterial.h"
  20. #include "materialsystem/imaterialsystem.h"
  21. #include "istudiorender.h"
  22. #include "materialsystem/imaterialsystemhardwareconfig.h"
  23. #include "tier2/renderutils.h"
  24. #include "tier1/keyvalues.h"
  25. #include "materialsystem/imesh.h"
  26. #include "shaderapi/ishaderapi.h"
  27. #include "view_shared.h"
  28. #include "ivrenderview.h"
  29. #include "game/client/irendercaptureconfiguration.h"
  30. // memdbgon must be the last include file in a .cpp file!!!
  31. #include "tier0/memdbgon.h"
  32. using namespace vgui;
  33. //-----------------------------------------------------------------------------
  34. // Translation manipulator
  35. //-----------------------------------------------------------------------------
  36. class CTranslationManipulator : public CTransformManipulator
  37. {
  38. public:
  39. CTranslationManipulator( matrix3x4_t *pTransform );
  40. // Methods of IManipulator
  41. virtual void OnMousePressed( vgui::MouseCode code, int x, int y );
  42. virtual void OnCursorMoved( int x, int y );
  43. protected:
  44. int m_lastx, m_lasty;
  45. };
  46. CTranslationManipulator::CTranslationManipulator( matrix3x4_t *pTransform ) : CTransformManipulator( pTransform )
  47. {
  48. m_lastx = m_lasty = 0;
  49. }
  50. void CTranslationManipulator::OnMousePressed( vgui::MouseCode code, int x, int y )
  51. {
  52. m_lasty = y;
  53. m_lastx = x;
  54. }
  55. void CTranslationManipulator::OnCursorMoved( int x, int y )
  56. {
  57. if ( !m_pTransform )
  58. return;
  59. Vector vPosition;
  60. QAngle quakeEuler;
  61. MatrixAngles( *m_pTransform, quakeEuler, vPosition );
  62. Vector forward, right, up;
  63. AngleVectors( quakeEuler, &forward, &right, &up );
  64. int dy = y - m_lasty;
  65. int dx = x - m_lastx;
  66. right *= -0.2f * dx;
  67. up *= 0.2f * dy;
  68. vPosition += up + right;
  69. m_lastx = x;
  70. m_lasty = y;
  71. PositionMatrix( vPosition, *m_pTransform );
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Zoom manipulator
  75. //-----------------------------------------------------------------------------
  76. class CZoomManipulator : public CBaseManipulator
  77. {
  78. public:
  79. CZoomManipulator( float *pDistance );
  80. // Methods of IManipulator
  81. virtual void OnMousePressed( vgui::MouseCode code, int x, int y );
  82. virtual void OnCursorMoved( int x, int y );
  83. protected:
  84. int m_lasty;
  85. float *m_pDistance;
  86. };
  87. CZoomManipulator::CZoomManipulator( float *pDistance )
  88. {
  89. m_lasty = 0;
  90. m_pDistance = pDistance;
  91. }
  92. void CZoomManipulator::OnMousePressed( vgui::MouseCode code, int x, int y )
  93. {
  94. m_lasty = y;
  95. }
  96. void CZoomManipulator::OnCursorMoved( int x, int y )
  97. {
  98. float delta = 0.2f * ( y - m_lasty );
  99. m_lasty = y;
  100. *m_pDistance *= pow( 1.01f, delta );
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Rotation manipulator
  104. //-----------------------------------------------------------------------------
  105. class CRotationManipulator : public CTransformManipulator
  106. {
  107. public:
  108. CRotationManipulator( matrix3x4_t *pTransform );
  109. // Inherited from IManipulator
  110. virtual void OnMousePressed( vgui::MouseCode code, int x, int y );
  111. virtual void OnCursorMoved( int x, int y );
  112. virtual void UpdateTransform();
  113. void SetDefaultValues();
  114. private:
  115. int m_lastx, m_lasty;
  116. float m_altitude, m_azimuth;
  117. };
  118. CRotationManipulator::CRotationManipulator( matrix3x4_t *pTransform ) : CTransformManipulator( pTransform )
  119. {
  120. SetDefaultValues();
  121. }
  122. void CRotationManipulator::SetDefaultValues()
  123. {
  124. m_lastx = m_lasty = 0;
  125. m_altitude = M_PI/6;
  126. m_azimuth = -3*M_PI/4;
  127. UpdateTransform();
  128. }
  129. void CRotationManipulator::OnMousePressed( vgui::MouseCode code, int x, int y )
  130. {
  131. m_lasty = y;
  132. m_lastx = x;
  133. }
  134. void CRotationManipulator::OnCursorMoved( int x, int y )
  135. {
  136. m_azimuth += 0.002f * ( m_lastx - x );
  137. m_altitude -= 0.002f * ( m_lasty - y );
  138. m_altitude = MAX( -M_PI/2, MIN( M_PI/2, m_altitude ) );
  139. m_lastx = x;
  140. m_lasty = y;
  141. UpdateTransform();
  142. }
  143. void CRotationManipulator::UpdateTransform()
  144. {
  145. if ( !m_pTransform )
  146. return;
  147. QAngle angles( RAD2DEG( m_altitude ), RAD2DEG( m_azimuth ), 0 );
  148. Vector vecPosition;
  149. MatrixGetColumn( *m_pTransform, 3, vecPosition );
  150. AngleMatrix( angles, vecPosition, *m_pTransform );
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Constructor, destructor
  154. //-----------------------------------------------------------------------------
  155. CPotteryWheelPanel::CPotteryWheelPanel( vgui::Panel *pParent, const char *pName ) :
  156. BaseClass( pParent, pName ),
  157. m_pCameraRotate( NULL ),
  158. m_pCameraTranslate( NULL ),
  159. m_pCameraZoom( NULL ),
  160. m_pLightManip( NULL ),
  161. m_pCurrentManip( NULL ),
  162. m_nCaptureMouseCode( vgui::MouseCode( -1 ) ),
  163. m_xoffset( 0 ), m_yoffset( 0 ),
  164. m_bParentMouseNotify( false )
  165. {
  166. m_bHasLightProbe = false;
  167. m_bSetupRenderStateDelayed = false;
  168. m_bRender3DSupersampled = false;
  169. m_bInRender3dForRenderCapture = false;
  170. m_pvRenderingWithFlashlightConfiguration = NULL;
  171. SetPaintBackgroundEnabled( false );
  172. SetPaintBorderEnabled( false );
  173. m_ClearColor.SetColor( 76, 88, 68, 255 );
  174. m_GridColor.SetColor( 255, 255, 255, 255 );
  175. SetIdentityMatrix( m_CameraPivot );
  176. CreateDefaultLights();
  177. m_nManipStartX = m_nManipStartY = 0;
  178. m_vecCameraOffset.Init( 100.0f, 0.0f, 0.0f );
  179. m_Camera.Init( Vector( 0, 0, 0 ), QAngle( 0, 0, 0 ), 3.0f, 16384.0f * 1.73205080757f, 30.0f, 1.0f );
  180. m_pCameraRotate = new CRotationManipulator( &m_CameraPivot );
  181. m_pCameraRotate->SetDefaultValues();
  182. m_pCameraTranslate = new CTranslationManipulator( &m_CameraPivot );
  183. m_pCameraZoom = new CZoomManipulator( &m_vecCameraOffset.x );
  184. SetKeyBoardInputEnabled( true );
  185. UpdateCameraTransform();
  186. // Used to poll input
  187. vgui::ivgui()->AddTickSignal( GetVPanel() );
  188. }
  189. CPotteryWheelPanel::~CPotteryWheelPanel()
  190. {
  191. delete m_pCameraRotate;
  192. delete m_pCameraZoom;
  193. delete m_pCameraTranslate;
  194. DestroyLights();
  195. }
  196. void CPotteryWheelPanel::CreateDefaultLights()
  197. {
  198. memset( &m_LightingState, 0, sizeof(MaterialLightingState_t) );
  199. for ( int i = 0; i < 6; ++i )
  200. {
  201. m_LightingState.m_vecAmbientCube[i].Init( 0.4f, 0.4f, 0.4f );
  202. }
  203. SetIdentityMatrix( m_LightToWorld[0] );
  204. m_LightingState.m_pLocalLightDesc[0].m_Type = MATERIAL_LIGHT_DIRECTIONAL;
  205. m_LightingState.m_pLocalLightDesc[0].m_Color.Init( 1.0f, 1.0f, 1.0f );
  206. m_LightingState.m_pLocalLightDesc[0].m_Direction.Init( 0.0f, 0.0f, -1.0f );
  207. m_LightingState.m_pLocalLightDesc[0].m_Range=0.0;
  208. m_LightingState.m_pLocalLightDesc[0].m_Attenuation0 = 1.0;
  209. m_LightingState.m_pLocalLightDesc[0].m_Attenuation1 = 0;
  210. m_LightingState.m_pLocalLightDesc[0].m_Attenuation2 = 0;
  211. m_LightingState.m_pLocalLightDesc[0].RecalculateDerivedValues();
  212. m_LightingState.m_nLocalLightCount = 1;
  213. m_pLightManip = new CPotteryWheelManip( &m_LightToWorld[0] );
  214. }
  215. void CPotteryWheelPanel::UpdateDirectionalLight( int idx, const Color& color, const Vector& direction )
  216. {
  217. if ( idx >= 0 && idx < m_LightingState.m_nLocalLightCount )
  218. {
  219. // Update the existing light
  220. SetIdentityMatrix( m_LightToWorld[idx] );
  221. m_LightingState.m_pLocalLightDesc[idx].m_Type = MATERIAL_LIGHT_DIRECTIONAL;
  222. m_LightingState.m_pLocalLightDesc[idx].m_Color.Init( color.r() / 255.0f, color.g() / 255.0f, color.b() / 255.0f );
  223. m_LightingState.m_pLocalLightDesc[idx].m_Direction.Init( direction.x, direction.y, direction.z );
  224. m_LightingState.m_pLocalLightDesc[idx].m_Range=0.0;
  225. m_LightingState.m_pLocalLightDesc[idx].m_Attenuation0 = 1.0;
  226. m_LightingState.m_pLocalLightDesc[idx].m_Attenuation1 = 0;
  227. m_LightingState.m_pLocalLightDesc[idx].m_Attenuation2 = 0;
  228. m_LightingState.m_pLocalLightDesc[idx].RecalculateDerivedValues();
  229. }
  230. else
  231. {
  232. AddDirectionalLight( color, direction );
  233. }
  234. }
  235. void CPotteryWheelPanel::ClearDirectionalLights()
  236. {
  237. m_LightingState.m_nLocalLightCount = 0;
  238. }
  239. void CPotteryWheelPanel::AddDirectionalLight( const Color& color, const Vector& direction )
  240. {
  241. if ( m_LightingState.m_nLocalLightCount < MATERIAL_MAX_LIGHT_COUNT )
  242. {
  243. SetIdentityMatrix( m_LightToWorld[m_LightingState.m_nLocalLightCount] );
  244. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Type = MATERIAL_LIGHT_DIRECTIONAL;
  245. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Color.Init( color.r() / 255.0f, color.g() / 255.0f, color.b() / 255.0f );
  246. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Direction.Init( direction.x, direction.y, direction.z );
  247. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Range=0.0;
  248. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Attenuation0 = 1.0;
  249. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Attenuation1 = 0;
  250. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].m_Attenuation2 = 0;
  251. m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount].RecalculateDerivedValues();
  252. m_LightingState.m_nLocalLightCount++;
  253. }
  254. }
  255. void CPotteryWheelPanel::SetLightAmbient( const Vector& ambient )
  256. {
  257. for ( int i = 0; i < 6; ++i )
  258. {
  259. m_LightingState.m_vecAmbientCube[i].Init( ambient.x, ambient.y, ambient.z );
  260. }
  261. }
  262. void CPotteryWheelPanel::DestroyLights()
  263. {
  264. if ( m_pLightManip )
  265. {
  266. delete m_pLightManip;
  267. m_pLightManip = NULL;
  268. }
  269. m_LightingState.m_nLocalLightCount = 0;
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Sets the background color
  273. //-----------------------------------------------------------------------------
  274. void CPotteryWheelPanel::SetBackgroundColor( int r, int g, int b )
  275. {
  276. m_ClearColor.SetColor( r, g, b, 255 );
  277. }
  278. void CPotteryWheelPanel::SetBackgroundColor( const Color& c )
  279. {
  280. m_ClearColor = c;
  281. }
  282. const Color& CPotteryWheelPanel::GetBackgroundColor() const
  283. {
  284. return m_ClearColor;
  285. }
  286. void CPotteryWheelPanel::SetGridColor( int r, int g, int b )
  287. {
  288. m_GridColor.SetColor( r, g, b, 255 );
  289. }
  290. //-----------------------------------------------------------------------------
  291. // Light probe
  292. //-----------------------------------------------------------------------------
  293. void CPotteryWheelPanel::SetLightProbe( CDmxElement *pLightProbe )
  294. {
  295. m_LightProbeBackground.Shutdown();
  296. m_LightProbeHDRBackground.Shutdown();
  297. m_LightProbeCubemap.Shutdown();
  298. m_LightProbeHDRCubemap.Shutdown();
  299. DestroyLights();
  300. m_bHasLightProbe = ( pLightProbe != NULL );
  301. if ( !m_bHasLightProbe )
  302. {
  303. CreateDefaultLights();
  304. return;
  305. }
  306. const char *pCubemap = pLightProbe->GetValueString( "cubemap" );
  307. m_LightProbeCubemap.Init( pCubemap, TEXTURE_GROUP_OTHER );
  308. const char *pCubemapHDR = pLightProbe->HasAttribute( "cubemapHdr" ) ? pLightProbe->GetValueString( "cubemapHdr" ) : pCubemap;
  309. m_LightProbeHDRCubemap.Init( pCubemapHDR, TEXTURE_GROUP_OTHER );
  310. KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  311. pVMTKeyValues->SetInt( "$ignorez", 1 );
  312. pVMTKeyValues->SetString( "$envmap", pCubemap );
  313. pVMTKeyValues->SetInt( "$no_fullbright", 1 );
  314. pVMTKeyValues->SetInt( "$nocull", 1 );
  315. m_LightProbeBackground.Init( "SPWP_LightProbeBackground", pVMTKeyValues );
  316. m_LightProbeBackground->Refresh();
  317. pVMTKeyValues = new KeyValues( "UnlitGeneric" );
  318. pVMTKeyValues->SetInt( "$ignorez", 1 );
  319. pVMTKeyValues->SetString( "$envmap", pCubemapHDR );
  320. pVMTKeyValues->SetInt( "$no_fullbright", 1 );
  321. pVMTKeyValues->SetInt( "$nocull", 1 );
  322. m_LightProbeHDRBackground.Init( "SPWP_LightProbeBackground_HDR", pVMTKeyValues );
  323. m_LightProbeHDRBackground->Refresh();
  324. const CUtlVector< Vector >& ambientCube = pLightProbe->GetArray<Vector>( "ambientCube" );
  325. if ( ambientCube.Count() == 6 )
  326. {
  327. for ( int i = 0; i < 6; ++i )
  328. {
  329. m_LightingState.m_vecAmbientCube[i].Init( ambientCube[i].x, ambientCube[i].y, ambientCube[i].z );
  330. }
  331. }
  332. const CUtlVector< CDmxElement* >& localLights = pLightProbe->GetArray< CDmxElement* >( "localLights" );
  333. int nLightCount = localLights.Count();
  334. for ( int i = 0; i < nLightCount; ++i )
  335. {
  336. if ( m_LightingState.m_nLocalLightCount == MATERIAL_MAX_LIGHT_COUNT )
  337. break;
  338. LightDesc_t *pDesc = &m_LightingState.m_pLocalLightDesc[m_LightingState.m_nLocalLightCount];
  339. CDmxElement *pLocalLight = localLights[ i ];
  340. const char *pType = pLocalLight->GetValueString( "name" );
  341. const Vector& vecColor = pLocalLight->GetValue<Vector>( "color" );
  342. if ( !Q_stricmp( pType, "directional" ) )
  343. {
  344. pDesc->InitDirectional( pLocalLight->GetValue<Vector>( "direction" ), vecColor );
  345. ++m_LightingState.m_nLocalLightCount;
  346. continue;
  347. }
  348. if ( !Q_stricmp( pType, "point" ) )
  349. {
  350. const Vector& vecAtten = pLocalLight->GetValue<Vector>( "attenuation" );
  351. pDesc->InitPoint( pLocalLight->GetValue<Vector>( "origin" ), vecColor );
  352. pDesc->m_Attenuation0 = vecAtten.x;
  353. pDesc->m_Attenuation1 = vecAtten.y;
  354. pDesc->m_Attenuation2 = vecAtten.z;
  355. pDesc->m_Range = pLocalLight->GetValue<float>( "maxDistance" );
  356. pDesc->RecalculateDerivedValues();
  357. ++m_LightingState.m_nLocalLightCount;
  358. continue;
  359. }
  360. if ( !Q_stricmp( pType, "spot" ) )
  361. {
  362. const Vector& vecAtten = pLocalLight->GetValue<Vector>( "attenuation" );
  363. pDesc->InitSpot( pLocalLight->GetValue<Vector>( "origin" ), vecColor, vec3_origin,
  364. 0.5f * RAD2DEG ( pLocalLight->GetValue<float>( "theta" ) ),
  365. 0.5f * RAD2DEG ( pLocalLight->GetValue<float>( "phi" ) ) );
  366. pDesc->m_Direction = pLocalLight->GetValue<Vector>( "direction" );
  367. pDesc->m_Attenuation0 = vecAtten.x;
  368. pDesc->m_Attenuation1 = vecAtten.y;
  369. pDesc->m_Attenuation2 = vecAtten.z;
  370. pDesc->m_Range = pLocalLight->GetValue<float>( "maxDistance" );
  371. pDesc->m_Falloff = pLocalLight->GetValue<float>( "exponent" );
  372. pDesc->RecalculateDerivedValues();
  373. ++m_LightingState.m_nLocalLightCount;
  374. continue;
  375. }
  376. }
  377. if ( nLightCount > 0 )
  378. {
  379. m_pLightManip = new CPotteryWheelManip( &m_LightToWorld[0] );
  380. }
  381. }
  382. bool CPotteryWheelPanel::HasLightProbe() const
  383. {
  384. return m_bHasLightProbe;
  385. }
  386. ITexture *CPotteryWheelPanel::GetLightProbeCubemap( bool bHDR )
  387. {
  388. if ( !m_bHasLightProbe )
  389. return NULL;
  390. return bHDR ? m_LightProbeHDRCubemap : m_LightProbeCubemap;
  391. }
  392. //-----------------------------------------------------------------------------
  393. // Purpose:
  394. //-----------------------------------------------------------------------------
  395. int CPotteryWheelPanel::GetCameraFOV( void )
  396. {
  397. return m_Camera.m_flFOVX;
  398. }
  399. //-----------------------------------------------------------------------------
  400. // Purpose:
  401. //-----------------------------------------------------------------------------
  402. void CPotteryWheelPanel::SetCameraFOV( float flFOV )
  403. {
  404. m_Camera.m_flFOVX = flFOV;
  405. }
  406. //-----------------------------------------------------------------------------
  407. // Purpose:
  408. //-----------------------------------------------------------------------------
  409. void CPotteryWheelPanel::SetCameraOffset( const Vector &vecOffset )
  410. {
  411. m_vecCameraOffset = vecOffset;
  412. }
  413. //-----------------------------------------------------------------------------
  414. // Purpose:
  415. //-----------------------------------------------------------------------------
  416. void CPotteryWheelPanel::GetCameraOffset( Vector &vecOffset )
  417. {
  418. vecOffset = m_vecCameraOffset;
  419. }
  420. //-----------------------------------------------------------------------------
  421. // Purpose:
  422. //-----------------------------------------------------------------------------
  423. void CPotteryWheelPanel::SetCameraPositionAndAngles( const Vector &vecPos, const QAngle &angDir )
  424. {
  425. m_Camera.m_origin = vecPos;
  426. m_Camera.m_angles = angDir;
  427. }
  428. //-----------------------------------------------------------------------------
  429. // Purpose:
  430. //-----------------------------------------------------------------------------
  431. void CPotteryWheelPanel::GetCameraPositionAndAngles( Vector &vecPos, QAngle &angDir )
  432. {
  433. MatrixAngles( m_CameraPivot, angDir, vecPos );
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Purpose:
  437. //-----------------------------------------------------------------------------
  438. void CPotteryWheelPanel::ResetCameraPivot( void )
  439. {
  440. SetIdentityMatrix( m_CameraPivot );
  441. }
  442. //-----------------------------------------------------------------------------
  443. // Purpose:
  444. //-----------------------------------------------------------------------------
  445. void CPotteryWheelPanel::ResetView( void )
  446. {
  447. SetIdentityMatrix( m_CameraPivot );
  448. m_vecCameraOffset.Init( 100.0f, 0.0f, 0.0f );
  449. m_pCameraRotate->SetDefaultValues();
  450. UpdateCameraTransform();
  451. }
  452. //-----------------------------------------------------------------------------
  453. // Sets the camera to look at the the thing we're spinning around
  454. //-----------------------------------------------------------------------------
  455. void CPotteryWheelPanel::LookAt( float flRadius )
  456. {
  457. // Compute the distance to the camera for the object based on its
  458. // radius and fov.
  459. // since tan( fov/2 ) = f/d
  460. // cos( fov/2 ) = r / r' where r = sphere radius, r' = perp distance from sphere center to max extent of camera
  461. // d/f = r'/d' where d' is distance of camera to sphere
  462. // d' = r' / tan( fov/2 ) * r' = r / ( cos (fov/2) * tan( fov/2 ) ) = r / sin( fov/2 )
  463. float flFOVx = m_Camera.m_flFOVX;
  464. // Compute fov/2 in radians
  465. flFOVx *= M_PI / 360.0f;
  466. // Compute an effective fov based on the aspect ratio
  467. // if the height is smaller than the width
  468. int w, h;
  469. GetSize( w, h );
  470. if ( h < w )
  471. {
  472. flFOVx = atan( h * tan( flFOVx ) / w );
  473. }
  474. m_vecCameraOffset.x = -( flRadius / sin( flFOVx ) );
  475. UpdateCameraTransform();
  476. }
  477. void CPotteryWheelPanel::LookAt( const Vector &vecCenter, float flRadius )
  478. {
  479. MatrixSetColumn( vecCenter, 3, m_CameraPivot );
  480. LookAt( flRadius );
  481. }
  482. //-----------------------------------------------------------------------------
  483. // Sets up render state in the material system for rendering
  484. //-----------------------------------------------------------------------------
  485. void CPotteryWheelPanel::SetupRenderState( int nDisplayWidth, int nDisplayHeight )
  486. {
  487. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  488. VMatrix view, projection;
  489. ComputeViewMatrix( &view, m_Camera );
  490. ComputeProjectionMatrix( &projection, m_Camera, nDisplayWidth, nDisplayHeight );
  491. pRenderContext->MatrixMode( MATERIAL_MODEL );
  492. pRenderContext->LoadIdentity( );
  493. pRenderContext->MatrixMode( MATERIAL_VIEW );
  494. pRenderContext->LoadMatrix( view );
  495. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  496. pRenderContext->LoadMatrix( projection );
  497. // Transform light based on manipulator
  498. MaterialLightingState_t state = m_LightingState;
  499. for ( int i = 0; i < state.m_nLocalLightCount; ++i )
  500. {
  501. const LightDesc_t &srcDesc = m_LightingState.m_pLocalLightDesc[ i ];
  502. LightDesc_t &destDesc = state.m_pLocalLightDesc[ i ];
  503. VectorTransform( srcDesc.m_Position, m_LightToWorld[i], destDesc.m_Position );
  504. VectorRotate( srcDesc.m_Direction, m_LightToWorld[i], destDesc.m_Direction );
  505. VectorNormalize( destDesc.m_Direction );
  506. }
  507. pRenderContext->SetLightingState( state );
  508. // FIXME: Remove this! This should automatically happen in DrawModel
  509. // in studiorender.
  510. if ( !g_pStudioRender )
  511. return;
  512. VMatrix worldToCamera;
  513. MatrixInverseTR( view, worldToCamera );
  514. Vector vecOrigin, vecRight, vecUp, vecForward;
  515. MatrixGetColumn( worldToCamera, 0, &vecRight );
  516. MatrixGetColumn( worldToCamera, 1, &vecUp );
  517. MatrixGetColumn( worldToCamera, 2, &vecForward );
  518. MatrixGetColumn( worldToCamera, 3, &vecOrigin );
  519. g_pStudioRender->SetViewState( vecOrigin, vecRight, vecUp, vecForward );
  520. g_pStudioRender->SetLocalLights( state.m_nLocalLightCount, state.m_pLocalLightDesc );
  521. g_pStudioRender->SetAmbientLightColors( state.m_vecAmbientCube );
  522. }
  523. //-----------------------------------------------------------------------------
  524. // Compute the camera world position
  525. //-----------------------------------------------------------------------------
  526. void CPotteryWheelPanel::UpdateCameraTransform( )
  527. {
  528. // Set up the render state for the camera + light
  529. matrix3x4_t offset, worldToCamera;
  530. SetIdentityMatrix( offset );
  531. MatrixSetColumn( m_vecCameraOffset, 3, offset );
  532. ConcatTransforms( m_CameraPivot, offset, worldToCamera );
  533. MatrixAngles( worldToCamera, m_Camera.m_angles, m_Camera.m_origin );
  534. }
  535. void CPotteryWheelPanel::ComputeCameraTransform( matrix3x4_t *pWorldToCamera )
  536. {
  537. AngleMatrix( m_Camera.m_angles, m_Camera.m_origin, *pWorldToCamera );
  538. }
  539. //-----------------------------------------------------------------------------
  540. // Computes the position in the panel of a particular 3D point
  541. //-----------------------------------------------------------------------------
  542. void CPotteryWheelPanel::ComputePanelPosition( const Vector &vecPosition, Vector2D *pPanelPos )
  543. {
  544. int w, h;
  545. GetSize( w, h );
  546. matrix3x4_t worldToCamera;
  547. ComputeCameraTransform( &worldToCamera );
  548. MatrixAngles( worldToCamera, m_Camera.m_angles, m_Camera.m_origin );
  549. ComputeScreenSpacePosition( pPanelPos, vecPosition, m_Camera, w, h );
  550. }
  551. IMaterial * CPotteryWheelPanel::GetWireframeMaterial()
  552. {
  553. if ( !m_Wireframe.IsValid() )
  554. {
  555. KeyValues *pMaterialKeys = new KeyValues( "Wireframe", "$model", "1" );
  556. pMaterialKeys->SetString( "$vertexcolor", "1" );
  557. m_Wireframe.Init( "potterywheelpanelwireframe", pMaterialKeys );
  558. }
  559. return m_Wireframe;
  560. }
  561. //-----------------------------------------------------------------------------
  562. // Utility method to draw a grid at the 'ground'
  563. //-----------------------------------------------------------------------------
  564. void CPotteryWheelPanel::DrawGrid()
  565. {
  566. matrix3x4_t transform;
  567. CMatRenderContextPtr pRenderContext( MaterialSystem() );
  568. pRenderContext->MatrixMode( MATERIAL_MODEL );
  569. pRenderContext->LoadIdentity( );
  570. pRenderContext->Bind( GetWireframeMaterial() );
  571. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  572. int nGridDim = 10;
  573. CMeshBuilder meshBuilder;
  574. meshBuilder.Begin( pMesh, MATERIAL_LINES, 2 * nGridDim + 2 );
  575. float bounds = 100.0f;
  576. float delta = 2 * bounds / nGridDim;
  577. for ( int i = 0; i < nGridDim + 1; ++i )
  578. {
  579. float xy = -bounds + delta * i;
  580. meshBuilder.Position3f( xy, -bounds, 0 );
  581. meshBuilder.Color4ub( m_GridColor.r(), m_GridColor.g(), m_GridColor.b(), m_GridColor.a());
  582. meshBuilder.AdvanceVertex();
  583. meshBuilder.Position3f( xy, bounds, 0 );
  584. meshBuilder.Color4ub( m_GridColor.r(), m_GridColor.g(), m_GridColor.b(), m_GridColor.a());
  585. meshBuilder.AdvanceVertex();
  586. meshBuilder.Position3f( -bounds, xy, 0 );
  587. meshBuilder.Color4ub( m_GridColor.r(), m_GridColor.g(), m_GridColor.b(), m_GridColor.a());
  588. meshBuilder.AdvanceVertex();
  589. meshBuilder.Position3f( bounds, xy, 0 );
  590. meshBuilder.Color4ub( m_GridColor.r(), m_GridColor.g(), m_GridColor.b(), m_GridColor.a());
  591. meshBuilder.AdvanceVertex();
  592. }
  593. meshBuilder.End();
  594. pMesh->Draw();
  595. }
  596. //-----------------------------------------------------------------------------
  597. // paint it!
  598. //-----------------------------------------------------------------------------
  599. void CPotteryWheelPanel::Paint()
  600. {
  601. int iWidth, iHeight;
  602. GetSize( iWidth, iHeight );
  603. int screenw, screenh;
  604. vgui::surface()->GetScreenSize( screenw, screenh );
  605. int windowposx = 0, windowposy = 0;
  606. GetPos( windowposx, windowposy );
  607. int windowposright = windowposx + iWidth;
  608. int windowposbottom = windowposy + iHeight;
  609. if ( windowposright >= screenw )
  610. {
  611. iWidth -= ( windowposright - screenw );
  612. }
  613. if ( windowposbottom >= screenh )
  614. {
  615. iHeight -= ( windowposbottom - screenh );
  616. }
  617. int startx = 0, starty = 0;
  618. if( windowposx < 0 )
  619. {
  620. startx = -windowposx;
  621. iWidth -= startx;
  622. }
  623. if ( windowposy < 0 )
  624. {
  625. starty = -windowposy;
  626. iHeight -= starty;
  627. }
  628. if( iWidth < 0 || iHeight < 0 )
  629. {
  630. return;
  631. }
  632. if ( GetRenderingWithFlashlightConfiguration() )
  633. {
  634. RenderCapture();
  635. }
  636. int w, h;
  637. GetSize( w, h );
  638. vgui::MatSystemSurface()->Begin3DPaint( 0, 0, w, h, m_bRender3DSupersampled );
  639. if ( m_pCurrentManip )
  640. {
  641. m_pCurrentManip->SetViewportSize( iWidth, iHeight );
  642. }
  643. // Set up the render state for the camera + light
  644. m_nRenderWidth = iWidth;
  645. m_nRenderHeight = iHeight;
  646. if ( !m_bSetupRenderStateDelayed )
  647. SetupRenderState( iWidth, iHeight );
  648. CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
  649. PIXEVENT( pRenderContext, "CPotteryWheelPanel::Paint" );
  650. if ( m_bUseParentBG && GetParent() )
  651. {
  652. Color bgCol = GetParent()->GetBgColor();
  653. pRenderContext->ClearColor4ub( bgCol.r(), bgCol.g(), bgCol.b(), bgCol.a() );
  654. }
  655. else
  656. {
  657. pRenderContext->ClearColor4ub( m_ClearColor.r(), m_ClearColor.g(), m_ClearColor.b(), m_ClearColor.a() );
  658. }
  659. pRenderContext->ClearBuffers( true, true );
  660. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  661. if ( HasLightProbe() )
  662. {
  663. IMaterial *pMaterial = ( vgui::MaterialSystemHardwareConfig()->GetHDRType() == HDR_TYPE_NONE ) ?
  664. m_LightProbeBackground : m_LightProbeHDRBackground;
  665. RenderBox( m_Camera.m_origin, vec3_angle, Vector( -100, -100, -100 ), Vector( 100, 100, 100 ),
  666. Color( 255, 255, 255, 255 ), pMaterial, true );
  667. }
  668. OnPaint3D();
  669. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  670. vgui::MatSystemSurface()->End3DPaint( );
  671. }
  672. void CPotteryWheelPanel::EnableRenderingWithFlashlight( void *pvConfiguration )
  673. {
  674. m_pvRenderingWithFlashlightConfiguration = pvConfiguration;
  675. }
  676. void CPotteryWheelPanel::RenderCapture()
  677. {
  678. if ( !GetRenderingWithFlashlightConfiguration() )
  679. return;
  680. CRenderCaptureConfigurationState *pCfg = reinterpret_cast< CRenderCaptureConfigurationState * >( GetRenderingWithFlashlightConfiguration() );
  681. m_nRenderWidth = pCfg->m_pFlashlightDepthTexture->GetActualWidth();
  682. m_nRenderHeight = pCfg->m_pFlashlightDepthTexture->GetActualHeight();
  683. if ( !m_bSetupRenderStateDelayed )
  684. SetupRenderState( m_nRenderWidth, m_nRenderHeight );
  685. CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
  686. PIXEVENT( pRenderContext, "CPotteryWheelPanel::RenderCapture" );
  687. CViewSetup view2d;
  688. view2d.x = 0;
  689. view2d.y = 0;
  690. view2d.width = m_nRenderWidth;
  691. view2d.height = m_nRenderHeight;
  692. pCfg->m_pIVRenderView->Push3DView( pRenderContext, view2d, VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH, pCfg->m_pDummyColorBufferTexture, NULL, pCfg->m_pFlashlightDepthTexture );
  693. pRenderContext->ClearColor4ub( 0, 0, 0, 0 );
  694. pRenderContext->ClearBuffers( true, true, false );
  695. m_bInRender3dForRenderCapture = true;
  696. pRenderContext->CullMode(MATERIAL_CULLMODE_CW);
  697. g_pStudioRender->ForcedMaterialOverride( NULL, OVERRIDE_DEPTH_WRITE );
  698. // Don't draw the 3D scene w/ stencil
  699. ShaderStencilState_t state;
  700. pRenderContext->SetStencilState( state );
  701. OnPaint3D();
  702. g_pStudioRender->ForcedMaterialOverride( NULL );
  703. pRenderContext->CullMode(MATERIAL_CULLMODE_CCW);
  704. m_bInRender3dForRenderCapture = false;
  705. pCfg->m_pIVRenderView->PopView( pRenderContext, NULL );
  706. pRenderContext->Flush();
  707. }
  708. //-----------------------------------------------------------------------------
  709. // called when we're ticked...
  710. //-----------------------------------------------------------------------------
  711. void CPotteryWheelPanel::OnTick()
  712. {
  713. BaseClass::OnTick();
  714. if ( m_pCurrentManip )
  715. {
  716. m_pCurrentManip->OnTick();
  717. UpdateCameraTransform();
  718. }
  719. }
  720. //-----------------------------------------------------------------------------
  721. // input
  722. //-----------------------------------------------------------------------------
  723. void CPotteryWheelPanel::OnKeyCodePressed(KeyCode code)
  724. {
  725. if ( m_pCurrentManip )
  726. {
  727. switch( code )
  728. {
  729. case KEY_RSHIFT:
  730. case KEY_LSHIFT:
  731. // start translate mode
  732. AcceptManipulation( false );
  733. EnterManipulationMode( CAMERA_TRANSLATE, false );
  734. break;
  735. case KEY_RCONTROL:
  736. case KEY_LCONTROL:
  737. // start light mode
  738. AcceptManipulation( false );
  739. EnterManipulationMode( LIGHT_MODE, false );
  740. break;
  741. }
  742. }
  743. BaseClass::OnKeyCodePressed( code );
  744. }
  745. //-----------------------------------------------------------------------------
  746. // Set whether the parent panel should be notified of mouse actions
  747. //-----------------------------------------------------------------------------
  748. void CPotteryWheelPanel::SetParentMouseNotify( bool bParentMouseNotify )
  749. {
  750. m_bParentMouseNotify = bParentMouseNotify;
  751. }
  752. //-----------------------------------------------------------------------------
  753. // Purpose: soaks up any remaining messages
  754. //-----------------------------------------------------------------------------
  755. void CPotteryWheelPanel::OnKeyCodeReleased(KeyCode code)
  756. {
  757. if ( m_pCurrentManip )
  758. {
  759. switch( code )
  760. {
  761. case KEY_RSHIFT:
  762. case KEY_LSHIFT:
  763. case KEY_RCONTROL:
  764. case KEY_LCONTROL:
  765. {
  766. // stop manipulation mode
  767. AcceptManipulation( false );
  768. switch ( m_nCaptureMouseCode )
  769. {
  770. default:
  771. case MOUSE_LEFT:
  772. EnterManipulationMode( CAMERA_ROTATE, false );
  773. break;
  774. case MOUSE_MIDDLE:
  775. EnterManipulationMode( CAMERA_TRANSLATE, false );
  776. break;
  777. case MOUSE_RIGHT:
  778. EnterManipulationMode( CAMERA_ZOOM, false );
  779. break;
  780. }
  781. }
  782. break;
  783. }
  784. }
  785. BaseClass::OnKeyCodeReleased( code );
  786. }
  787. void CPotteryWheelPanel::OnMouseDoublePressed( vgui::MouseCode code )
  788. {
  789. BaseClass::OnMouseDoublePressed( code );
  790. if( m_bParentMouseNotify && GetParent() )
  791. {
  792. GetParent()->OnMouseDoublePressed(code);
  793. }
  794. }
  795. void CPotteryWheelPanel::OnMousePressed( vgui::MouseCode code )
  796. {
  797. if ( m_pCurrentManip )
  798. return;
  799. RequestFocus();
  800. if ( input()->IsKeyDown( KEY_RSHIFT ) || input()->IsKeyDown( KEY_LSHIFT ) )
  801. {
  802. EnterManipulationMode( CAMERA_TRANSLATE, true, code );
  803. }
  804. else if ( input()->IsKeyDown( KEY_RCONTROL ) || input()->IsKeyDown( KEY_LCONTROL ) )
  805. {
  806. EnterManipulationMode( LIGHT_MODE, true, code );
  807. }
  808. else
  809. {
  810. switch ( code )
  811. {
  812. case MOUSE_LEFT:
  813. EnterManipulationMode( CAMERA_ROTATE, true, code );
  814. break;
  815. case MOUSE_MIDDLE:
  816. EnterManipulationMode( CAMERA_TRANSLATE, true, code );
  817. break;
  818. case MOUSE_RIGHT:
  819. EnterManipulationMode( CAMERA_ZOOM, true, code );
  820. break;
  821. }
  822. }
  823. BaseClass::OnMousePressed( code );
  824. if( m_bParentMouseNotify && GetParent() )
  825. {
  826. GetParent()->OnMousePressed(code);
  827. }
  828. }
  829. void CPotteryWheelPanel::OnMouseReleased( vgui::MouseCode code )
  830. {
  831. int x, y;
  832. input()->GetCursorPos( x, y );
  833. ScreenToLocal( x, y );
  834. AcceptManipulation();
  835. BaseClass::OnMouseReleased( code );
  836. if( m_bParentMouseNotify && GetParent() )
  837. {
  838. GetParent()->OnMouseReleased(code);
  839. }
  840. }
  841. void CPotteryWheelPanel::OnCursorMoved( int x, int y )
  842. {
  843. if ( m_pCurrentManip )
  844. {
  845. if ( WarpMouse( x, y ) )
  846. {
  847. m_pCurrentManip->OnCursorMoved( x, y );
  848. }
  849. }
  850. BaseClass::OnCursorMoved( x, y );
  851. if( m_bParentMouseNotify && GetParent() )
  852. {
  853. GetParent()->OnCursorMoved(x,y);
  854. }
  855. }
  856. void CPotteryWheelPanel::OnMouseWheeled( int delta )
  857. {
  858. if ( m_pCurrentManip )
  859. {
  860. m_pCurrentManip->OnMouseWheeled( delta );
  861. }
  862. BaseClass::OnMouseWheeled( delta );
  863. if( m_bParentMouseNotify && GetParent() )
  864. {
  865. GetParent()->OnMouseWheeled(delta);
  866. }
  867. }
  868. void CPotteryWheelPanel::EnterManipulationMode( ManipulationMode_t manipMode, bool bMouseCapture, vgui::MouseCode mouseCode /* = -1 */ )
  869. {
  870. switch ( manipMode )
  871. {
  872. case CAMERA_ROTATE:
  873. m_pCurrentManip = m_pCameraRotate;
  874. break;
  875. case CAMERA_TRANSLATE:
  876. m_pCurrentManip = m_pCameraTranslate;
  877. break;
  878. case CAMERA_ZOOM:
  879. m_pCurrentManip = m_pCameraZoom;
  880. break;
  881. case LIGHT_MODE:
  882. m_pCurrentManip = m_pLightManip;
  883. break;
  884. }
  885. if ( !m_pCurrentManip )
  886. return;
  887. m_pCurrentManip->OnBeginManipulation();
  888. m_xoffset = m_yoffset = 0;
  889. // Warp the mouse to the center of the screen
  890. int width, height;
  891. GetSize( width, height );
  892. int x = width / 2;
  893. int y = height / 2;
  894. if ( bMouseCapture )
  895. {
  896. input()->GetCursorPos( m_nManipStartX, m_nManipStartY );
  897. EnableMouseCapture( true, mouseCode );
  898. int xpos = x;
  899. int ypos = y;
  900. LocalToScreen( xpos, ypos );
  901. input()->SetCursorPos( xpos, ypos );
  902. }
  903. m_pCurrentManip->OnMousePressed( mouseCode, x, y );
  904. }
  905. void CPotteryWheelPanel::AcceptManipulation( bool bReleaseMouseCapture )
  906. {
  907. if ( m_pCurrentManip )
  908. {
  909. m_pCurrentManip->OnAcceptManipulation();
  910. if ( bReleaseMouseCapture )
  911. {
  912. EnableMouseCapture( false );
  913. input()->SetCursorPos( m_nManipStartX, m_nManipStartY );
  914. }
  915. m_pCurrentManip = NULL;
  916. }
  917. }
  918. void CPotteryWheelPanel::CancelManipulation()
  919. {
  920. if ( m_pCurrentManip )
  921. {
  922. m_pCurrentManip->OnCancelManipulation();
  923. EnableMouseCapture( false );
  924. input()->SetCursorPos( m_nManipStartX, m_nManipStartY );
  925. m_pCurrentManip = NULL;
  926. }
  927. }
  928. void CPotteryWheelPanel::OnMouseCaptureLost()
  929. {
  930. SetCursor( vgui::dc_arrow );
  931. m_nCaptureMouseCode = vgui::MouseCode( -1 );
  932. }
  933. void CPotteryWheelPanel::EnableMouseCapture( bool enable, vgui::MouseCode mouseCode /* = -1 */ )
  934. {
  935. if ( enable )
  936. {
  937. m_nCaptureMouseCode = mouseCode;
  938. SetCursor( vgui::dc_none );
  939. input()->SetMouseCaptureEx( GetVPanel(), m_nCaptureMouseCode );
  940. }
  941. else
  942. {
  943. m_nCaptureMouseCode = vgui::MouseCode( -1 );
  944. input()->SetMouseCapture( NULL );
  945. SetCursor( vgui::dc_arrow );
  946. }
  947. }
  948. bool CPotteryWheelPanel::WarpMouse( int &x, int &y )
  949. {
  950. // Re-force capture if it was lost...
  951. if ( input()->GetMouseCapture() != GetVPanel() )
  952. {
  953. input()->GetCursorPos( m_nManipStartX, m_nManipStartY );
  954. EnableMouseCapture( true, m_nCaptureMouseCode );
  955. }
  956. int width, height;
  957. GetSize( width, height );
  958. int centerx = width / 2;
  959. int centery = height / 2;
  960. // skip this event
  961. if ( x == centerx && y == centery )
  962. return false;
  963. int xpos = centerx;
  964. int ypos = centery;
  965. LocalToScreen( xpos, ypos );
  966. input()->SetCursorPos( xpos, ypos );
  967. int dx = x - centerx;
  968. int dy = y - centery;
  969. x += m_xoffset;
  970. y += m_yoffset;
  971. m_xoffset += dx;
  972. m_yoffset += dy;
  973. return true;
  974. }