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.

205 lines
4.4 KiB

  1. //========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "matsys_controls/manipulator.h"
  8. #include "materialsystem/imaterialsystem.h"
  9. #include "vgui/IVGui.h"
  10. #include "vgui/IInput.h"
  11. #include "vgui/ISystem.h"
  12. #include "vgui/MouseCode.h"
  13. #include "mathlib/vector.h"
  14. #include "mathlib/vmatrix.h"
  15. #include "mathlib/mathlib.h"
  16. #include <float.h>
  17. // NOTE: This has to be the last file included!
  18. #include "tier0/memdbgon.h"
  19. using namespace vgui;
  20. //-----------------------------------------------------------------------------
  21. // local helper functions
  22. //-----------------------------------------------------------------------------
  23. static float UpdateTime( float &flLastTime )
  24. {
  25. float flTime = vgui::system()->GetFrameTime();
  26. float dt = flTime - flLastTime;
  27. flLastTime = flTime;
  28. return dt;
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Base class for manipulators which operate on transforms
  32. //-----------------------------------------------------------------------------
  33. CTransformManipulator::CTransformManipulator( matrix3x4_t *pTransform ) :
  34. m_pTransform( pTransform )
  35. {
  36. }
  37. void CTransformManipulator::SetTransform( matrix3x4_t *pTransform )
  38. {
  39. m_pTransform = pTransform;
  40. }
  41. matrix3x4_t *CTransformManipulator::GetTransform( void )
  42. {
  43. return m_pTransform;
  44. }
  45. //-----------------------------------------------------------------------------
  46. // CPotteryWheelManip - nendo-style camera manipulator
  47. //-----------------------------------------------------------------------------
  48. CPotteryWheelManip::CPotteryWheelManip( matrix3x4_t *pTransform ) :
  49. CTransformManipulator( pTransform ),
  50. m_lastx( -1 ), m_lasty( -1 ),
  51. m_zoom( 100.0f ), m_altitude( 0.0f ), m_azimuth( 0.0f ),
  52. m_prevZoom( 100.0f ), m_prevAltitude( 0.0f ), m_prevAzimuth( 0.0f ),
  53. m_flLastMouseTime( 0.0f ), m_flLastTickTime( 0.0f ),
  54. m_flSpin( 0.0f ), m_bSpin( false )
  55. {
  56. }
  57. void CPotteryWheelManip::OnBeginManipulation( void )
  58. {
  59. m_prevZoom = m_zoom;
  60. m_prevAltitude = m_altitude;
  61. m_prevAzimuth = m_azimuth;
  62. m_flLastMouseTime = m_flLastTickTime = vgui::system()->GetFrameTime();
  63. m_flSpin = 0.0f;
  64. m_bSpin = false;
  65. }
  66. // Sets the zoom level
  67. void CPotteryWheelManip::SetZoom( float flZoom )
  68. {
  69. m_prevZoom = m_zoom = flZoom;
  70. }
  71. void CPotteryWheelManip::OnAcceptManipulation( void )
  72. {
  73. m_flSpin = 0.0f;
  74. m_bSpin = false;
  75. }
  76. void CPotteryWheelManip::OnCancelManipulation( void )
  77. {
  78. m_zoom = m_prevZoom;
  79. m_altitude = m_prevAltitude;
  80. m_azimuth = m_prevAzimuth;
  81. m_flSpin = 0.0f;
  82. m_bSpin = false;
  83. UpdateTransform();
  84. }
  85. void CPotteryWheelManip::OnTick( void )
  86. {
  87. float dt = UpdateTime( m_flLastTickTime );
  88. if ( m_bSpin )
  89. {
  90. m_azimuth += dt * m_flSpin;
  91. UpdateTransform();
  92. }
  93. }
  94. void CPotteryWheelManip::OnCursorMoved( int x, int y )
  95. {
  96. float dt = UpdateTime( m_flLastMouseTime );
  97. if ( m_bSpin )
  98. {
  99. m_lastx = x;
  100. m_lasty = y;
  101. return;
  102. }
  103. if ( input()->IsMouseDown( MOUSE_MIDDLE ) )
  104. {
  105. int dy = y - m_lasty;
  106. int dx = x - m_lastx;
  107. if ( abs( dx ) < 2 * abs( dy ) )
  108. {
  109. UpdateZoom( 0.2f * dy );
  110. }
  111. else
  112. {
  113. m_flSpin = (dt != 0.0f) ? 0.002f * dx / dt : 0.0f;
  114. m_azimuth += 0.002f * dx;
  115. }
  116. }
  117. else
  118. {
  119. m_azimuth += 0.002f * ( x - m_lastx );
  120. m_altitude -= 0.002f * ( y - m_lasty );
  121. m_altitude = MAX( -M_PI/2, MIN( M_PI/2, m_altitude ) );
  122. }
  123. m_lastx = x;
  124. m_lasty = y;
  125. UpdateTransform();
  126. }
  127. void CPotteryWheelManip::OnMousePressed( vgui::MouseCode code, int x, int y )
  128. {
  129. UpdateTime( m_flLastMouseTime );
  130. m_lastx = x;
  131. m_lasty = y;
  132. m_bSpin = false;
  133. m_flSpin = 0.0f;
  134. }
  135. void CPotteryWheelManip::OnMouseReleased( vgui::MouseCode code, int x, int y )
  136. {
  137. UpdateTime( m_flLastMouseTime );
  138. if ( code == MOUSE_MIDDLE )
  139. {
  140. m_bSpin = ( fabs( m_flSpin ) > 1.0f );
  141. }
  142. m_lastx = x;
  143. m_lasty = y;
  144. }
  145. void CPotteryWheelManip::OnMouseWheeled( int delta )
  146. {
  147. UpdateTime( m_flLastMouseTime );
  148. UpdateZoom( -10.0f * delta );
  149. UpdateTransform();
  150. }
  151. void CPotteryWheelManip::UpdateTransform()
  152. {
  153. if ( !m_pTransform )
  154. return;
  155. float y = m_zoom * sin( m_altitude );
  156. float xz = m_zoom * cos( m_altitude );
  157. float x = xz * sin( m_azimuth );
  158. float z = xz * cos( m_azimuth );
  159. Vector position(x, y, z);
  160. AngleMatrix( RadianEuler( -m_altitude, m_azimuth, 0 ), position, *m_pTransform );
  161. }
  162. void CPotteryWheelManip::UpdateZoom( float delta )
  163. {
  164. m_zoom *= pow( 1.01f, delta );
  165. }