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.

334 lines
8.9 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <stdafx.h>
  8. #include "GlobalFunctions.h"
  9. #include "History.h"
  10. #include "MainFrm.h"
  11. #include "MapAnimator.h"
  12. #include "MapAnimationDlg.h"
  13. #include "MapClass.h"
  14. #include "MapDoc.h"
  15. #include "MapEntity.h"
  16. #include "MapWorld.h"
  17. #include "hammer.h"
  18. #include "Selection.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include <tier0/memdbgon.h>
  21. BEGIN_MESSAGE_MAP( CMapAnimationDlg, CHammerBar )
  22. //{{AFX_MSG_MAP( CMapAnimationDlg )
  23. ON_WM_HSCROLL()
  24. ON_BN_CLICKED(IDC_ANIMATIONPLAY, OnPlay)
  25. ON_BN_CLICKED(IDC_ANIMATIONCREATEKEYFRAME, OnCreateKeyFrame)
  26. ON_UPDATE_COMMAND_UI(IDC_ANIMATIONPLAY, UpdateControl)
  27. ON_UPDATE_COMMAND_UI(IDC_ANIMATIONCREATEKEYFRAME, UpdateControl)
  28. //}}AFX_MSG_MAP
  29. END_MESSAGE_MAP()
  30. //-----------------------------------------------------------------------------
  31. // Purpose: CMapAnimationDlg contructor
  32. //-----------------------------------------------------------------------------
  33. CMapAnimationDlg::CMapAnimationDlg()
  34. {
  35. m_flAnimationDuration = 5.0f;
  36. m_flAnimationStart = 0.0f;
  37. m_flAnimTime = 0.0f;
  38. m_bPlaying = false;
  39. }
  40. static const int ANIMSLIDER_NUMTICS = 100;
  41. //-----------------------------------------------------------------------------
  42. //-----------------------------------------------------------------------------
  43. bool CMapAnimationDlg::Create( CWnd *pParentWnd )
  44. {
  45. //
  46. // create a modeless dialog toolbar
  47. //
  48. if( !( CHammerBar::Create( pParentWnd, IDD, CBRS_RIGHT, IDCB_ANIMATIONBAR ) ) )
  49. {
  50. return false;
  51. }
  52. // to remain consistant with the other toolbars in the editor
  53. SetWindowText( _T( "Animation" ) );
  54. // set dialog bar style
  55. SetBarStyle( GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED );
  56. // enable docking
  57. EnableDocking( CBRS_ALIGN_ANY );
  58. //
  59. // initialize the dialog items
  60. //
  61. InitTimeSlider();
  62. m_Play.SubclassDlgItem( IDC_ANIMATIONPLAY, this );
  63. // show the dialog
  64. ShowWindow( SW_SHOW );
  65. m_bEnabled = false;
  66. // created successfully
  67. return true;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose: Called every frame, used to update animation time
  71. //-----------------------------------------------------------------------------
  72. void CMapAnimationDlg::RunFrame( void )
  73. {
  74. if ( m_bPlaying )
  75. {
  76. AdvanceAnimationTime();
  77. }
  78. }
  79. //-----------------------------------------------------------------------------
  80. //-----------------------------------------------------------------------------
  81. void CMapAnimationDlg::InitTimeSlider( void )
  82. {
  83. m_TimeSlider.SubclassDlgItem( IDC_TIMESLIDER, this );
  84. m_TimeSlider.SetRange( 0, ANIMSLIDER_NUMTICS );
  85. m_TimeSlider.SetTicFreq( ANIMSLIDER_NUMTICS / 4 );
  86. m_TimeSlider.SetPos( 0 );
  87. m_TimeSlider.EnableWindow( false );
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose: Sets Enable/Disable state for any controls
  91. // Input : *pCmdUI -
  92. //-----------------------------------------------------------------------------
  93. void CMapAnimationDlg::UpdateControl( CCmdUI *pCmdUI )
  94. {
  95. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  96. if ( !pDoc || !m_bEnabled )
  97. {
  98. pCmdUI->Enable( false );
  99. return;
  100. }
  101. else
  102. {
  103. pCmdUI->Enable( true );
  104. }
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: Communicates to the doc the current animation time
  108. // Input : time -
  109. //-----------------------------------------------------------------------------
  110. void CMapAnimationDlg::UpdateAnimationTime( void )
  111. {
  112. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  113. if( !pDoc )
  114. {
  115. return;
  116. }
  117. pDoc->SetAnimationTime( m_flAnimTime );
  118. }
  119. //-----------------------------------------------------------------------------
  120. //-----------------------------------------------------------------------------
  121. void CMapAnimationDlg::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar *pScrollBar )
  122. {
  123. // get the new time from the slider bar
  124. m_flAnimTime = ((float)m_TimeSlider.GetPos() / ANIMSLIDER_NUMTICS) * m_flAnimationDuration;
  125. // stop any playback
  126. PausePlayback();
  127. UpdateAnimationTime();
  128. CHammerBar::OnHScroll( nSBCode, nPos, pScrollBar );
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose: Moves the animation time forward with real time
  132. //-----------------------------------------------------------------------------
  133. void CMapAnimationDlg::OnPlay( void )
  134. {
  135. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  136. if ( !pDoc )
  137. {
  138. return;
  139. }
  140. // if we're not playing, start
  141. if ( !m_bPlaying )
  142. {
  143. m_flAnimationStart = pDoc->GetTime() - m_flAnimTime;
  144. m_bPlaying = true;
  145. // change the animation text
  146. SetDlgItemText( IDC_ANIMATIONPLAY, "Stop" );
  147. UpdateAnimationTime();
  148. }
  149. else
  150. {
  151. PausePlayback();
  152. }
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Purpose: pauses the animation playback at the current time
  156. //-----------------------------------------------------------------------------
  157. void CMapAnimationDlg::PausePlayback( void )
  158. {
  159. m_bPlaying = false;
  160. SetDlgItemText( IDC_ANIMATIONPLAY, "Play" );
  161. }
  162. //-----------------------------------------------------------------------------
  163. // Purpose: Creates a new keyframe in the cycle at the current time in the animation
  164. //-----------------------------------------------------------------------------
  165. void CMapAnimationDlg::OnCreateKeyFrame( void )
  166. {
  167. // stop any playback
  168. PausePlayback();
  169. GetHistory()->MarkUndoPosition( NULL, "New Keyframe" );
  170. // get the animating object
  171. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  172. const CMapObjectList *pSelection = pDoc->GetSelection()->GetList();
  173. for (int i = 0; i < pSelection->Count(); i++)
  174. {
  175. CMapClass *pMapClass = (CUtlReference< CMapClass >)pSelection->Element( i );
  176. CMapEntity *ent = dynamic_cast<CMapEntity*>( pMapClass );
  177. if ( ent && ent->IsAnimationController() )
  178. {
  179. // tell the animating object to create a new keyframe
  180. CMapAnimator *anim = ent->GetChildOfType( (CMapAnimator*)NULL );
  181. if ( anim )
  182. {
  183. CMapEntity *pNewEntity = anim->CreateNewKeyFrame( m_flAnimTime );
  184. CMapDoc::GetActiveMapDoc()->AddObjectToWorld( pNewEntity );
  185. GetHistory()->KeepNew( pNewEntity );
  186. // change the selection and then update the view
  187. CMapDoc::GetActiveMapDoc()->SelectObject(pNewEntity, scClear|scSaveChanges );
  188. break;
  189. }
  190. }
  191. }
  192. ResetTimeSlider();
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose: moves the current animation time forward, if currently playing
  196. //-----------------------------------------------------------------------------
  197. void CMapAnimationDlg::AdvanceAnimationTime( void )
  198. {
  199. if ( !m_bPlaying )
  200. return;
  201. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  202. if ( !pDoc )
  203. {
  204. return;
  205. }
  206. // make sure the animation is long enough to play
  207. if ( m_flAnimationDuration <= 0.01 )
  208. {
  209. ResetTimeSlider();
  210. return;
  211. }
  212. // calculate the new position along the time slider
  213. m_flAnimTime = pDoc->GetTime() - m_flAnimationStart;
  214. // check to see if we've hit the end of the animation
  215. if ( m_flAnimTime >= m_flAnimationDuration )
  216. {
  217. ResetTimeSlider();
  218. return;
  219. }
  220. // set the new animtion time
  221. m_TimeSlider.SetPos( (m_flAnimTime / m_flAnimationDuration) * ANIMSLIDER_NUMTICS );
  222. UpdateAnimationTime();
  223. }
  224. //-----------------------------------------------------------------------------
  225. // Purpose: Resets the slider bar and all times
  226. //-----------------------------------------------------------------------------
  227. void CMapAnimationDlg::ResetTimeSlider( void )
  228. {
  229. PausePlayback();
  230. m_flAnimTime = 0.0f;
  231. m_flAnimationStart = 0.0f;
  232. m_TimeSlider.SetPos( 0 );
  233. UpdateAnimationTime();
  234. }
  235. //-----------------------------------------------------------------------------
  236. // Purpose: Called whenever the selection changes, so the slider bar can update
  237. // with the selected keyframe info
  238. // Input : &selection -
  239. //-----------------------------------------------------------------------------
  240. void CMapAnimationDlg::SelectionChanged( CMapObjectList &selection )
  241. {
  242. // reset the slider
  243. ResetTimeSlider();
  244. m_bEnabled = false;
  245. // loop through the selection looking for potential animating objects
  246. CMapEntity *ent = NULL;
  247. FOR_EACH_OBJ( selection, pos )
  248. {
  249. CMapClass *pMapClass = (CUtlReference< CMapClass >)selection.Element(pos);
  250. ent = dynamic_cast<CMapEntity*>( pMapClass );
  251. if ( ent )
  252. {
  253. if ( ent->IsAnimationController() && ent->GetChildOfType((CMapAnimator*)NULL) )
  254. {
  255. m_bEnabled = true;
  256. break;
  257. }
  258. }
  259. }
  260. // find out our enabled state
  261. if ( !m_bEnabled )
  262. {
  263. m_TimeSlider.EnableWindow( false );
  264. return;
  265. }
  266. m_TimeSlider.EnableWindow( true );
  267. // set up the slider from the selection
  268. CMapAnimator *anim = ent->GetChildOfType( (CMapAnimator*)NULL );
  269. Assert( anim != NULL );
  270. m_flAnimationDuration = anim->GetRemainingTime();
  271. }