summaryrefslogtreecommitdiff
path: root/hammer/mapanimationdlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hammer/mapanimationdlg.cpp')
-rw-r--r--hammer/mapanimationdlg.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/hammer/mapanimationdlg.cpp b/hammer/mapanimationdlg.cpp
new file mode 100644
index 0000000..613b2cb
--- /dev/null
+++ b/hammer/mapanimationdlg.cpp
@@ -0,0 +1,332 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include <stdafx.h>
+#include "GlobalFunctions.h"
+#include "History.h"
+#include "MainFrm.h"
+#include "MapAnimator.h"
+#include "MapAnimationDlg.h"
+#include "MapClass.h"
+#include "MapDoc.h"
+#include "MapEntity.h"
+#include "MapWorld.h"
+#include "hammer.h"
+#include "Selection.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include <tier0/memdbgon.h>
+
+
+BEGIN_MESSAGE_MAP( CMapAnimationDlg, CHammerBar )
+ //{{AFX_MSG_MAP( CMapAnimationDlg )
+ ON_WM_HSCROLL()
+ ON_BN_CLICKED(IDC_ANIMATIONPLAY, OnPlay)
+ ON_BN_CLICKED(IDC_ANIMATIONCREATEKEYFRAME, OnCreateKeyFrame)
+ ON_UPDATE_COMMAND_UI(IDC_ANIMATIONPLAY, UpdateControl)
+ ON_UPDATE_COMMAND_UI(IDC_ANIMATIONCREATEKEYFRAME, UpdateControl)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+//-----------------------------------------------------------------------------
+// Purpose: CMapAnimationDlg contructor
+//-----------------------------------------------------------------------------
+CMapAnimationDlg::CMapAnimationDlg()
+{
+ m_flAnimationDuration = 5.0f;
+ m_flAnimationStart = 0.0f;
+ m_flAnimTime = 0.0f;
+ m_bPlaying = false;
+}
+
+
+static const int ANIMSLIDER_NUMTICS = 100;
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+bool CMapAnimationDlg::Create( CWnd *pParentWnd )
+{
+ //
+ // create a modeless dialog toolbar
+ //
+ if( !( CHammerBar::Create( pParentWnd, IDD, CBRS_RIGHT, IDCB_ANIMATIONBAR ) ) )
+ {
+ return false;
+ }
+
+ // to remain consistant with the other toolbars in the editor
+ SetWindowText( _T( "Animation" ) );
+
+ // set dialog bar style
+ SetBarStyle( GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED );
+
+ // enable docking
+ EnableDocking( CBRS_ALIGN_ANY );
+
+ //
+ // initialize the dialog items
+ //
+ InitTimeSlider();
+
+ m_Play.SubclassDlgItem( IDC_ANIMATIONPLAY, this );
+
+ // show the dialog
+ ShowWindow( SW_SHOW );
+
+ m_bEnabled = false;
+
+ // created successfully
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Called every frame, used to update animation time
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::RunFrame( void )
+{
+ if ( m_bPlaying )
+ {
+ AdvanceAnimationTime();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::InitTimeSlider( void )
+{
+ m_TimeSlider.SubclassDlgItem( IDC_TIMESLIDER, this );
+ m_TimeSlider.SetRange( 0, ANIMSLIDER_NUMTICS );
+ m_TimeSlider.SetTicFreq( ANIMSLIDER_NUMTICS / 4 );
+ m_TimeSlider.SetPos( 0 );
+
+ m_TimeSlider.EnableWindow( false );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Sets Enable/Disable state for any controls
+// Input : *pCmdUI -
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::UpdateControl( CCmdUI *pCmdUI )
+{
+ CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
+ if ( !pDoc || !m_bEnabled )
+ {
+ pCmdUI->Enable( false );
+ return;
+ }
+ else
+ {
+ pCmdUI->Enable( true );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Communicates to the doc the current animation time
+// Input : time -
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::UpdateAnimationTime( void )
+{
+ CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
+ if( !pDoc )
+ {
+ return;
+ }
+
+ pDoc->SetAnimationTime( m_flAnimTime );
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar *pScrollBar )
+{
+ // get the new time from the slider bar
+ m_flAnimTime = ((float)m_TimeSlider.GetPos() / ANIMSLIDER_NUMTICS) * m_flAnimationDuration;
+
+ // stop any playback
+ PausePlayback();
+
+ UpdateAnimationTime();
+ CHammerBar::OnHScroll( nSBCode, nPos, pScrollBar );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Moves the animation time forward with real time
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::OnPlay( void )
+{
+ CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
+ if ( !pDoc )
+ {
+ return;
+ }
+
+ // if we're not playing, start
+ if ( !m_bPlaying )
+ {
+ m_flAnimationStart = pDoc->GetTime() - m_flAnimTime;
+ m_bPlaying = true;
+
+ // change the animation text
+ SetDlgItemText( IDC_ANIMATIONPLAY, "Stop" );
+
+ UpdateAnimationTime();
+ }
+ else
+ {
+ PausePlayback();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: pauses the animation playback at the current time
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::PausePlayback( void )
+{
+ m_bPlaying = false;
+ SetDlgItemText( IDC_ANIMATIONPLAY, "Play" );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Creates a new keyframe in the cycle at the current time in the animation
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::OnCreateKeyFrame( void )
+{
+ // stop any playback
+ PausePlayback();
+
+ GetHistory()->MarkUndoPosition( NULL, "New Keyframe" );
+
+ // get the animating object
+ CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
+
+ const CMapObjectList *pSelection = pDoc->GetSelection()->GetList();
+
+ for (int i = 0; i < pSelection->Count(); i++)
+ {
+ CMapEntity *ent = dynamic_cast<CMapEntity*>( pSelection->Element( i ) );
+
+ if ( ent && ent->IsAnimationController() )
+ {
+ // tell the animating object to create a new keyframe
+ CMapAnimator *anim = ent->GetChildOfType( (CMapAnimator*)NULL );
+ if ( anim )
+ {
+ CMapEntity *pNewEntity = anim->CreateNewKeyFrame( m_flAnimTime );
+
+ CMapDoc::GetActiveMapDoc()->AddObjectToWorld( pNewEntity );
+ GetHistory()->KeepNew( pNewEntity );
+
+ // change the selection and then update the view
+ CMapDoc::GetActiveMapDoc()->SelectObject(pNewEntity, scClear|scSaveChanges );
+
+ break;
+ }
+ }
+ }
+
+ ResetTimeSlider();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: moves the current animation time forward, if currently playing
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::AdvanceAnimationTime( void )
+{
+ if ( !m_bPlaying )
+ return;
+
+ CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
+ if ( !pDoc )
+ {
+ return;
+ }
+
+ // make sure the animation is long enough to play
+ if ( m_flAnimationDuration <= 0.01 )
+ {
+ ResetTimeSlider();
+ return;
+ }
+
+ // calculate the new position along the time slider
+ m_flAnimTime = pDoc->GetTime() - m_flAnimationStart;
+
+ // check to see if we've hit the end of the animation
+ if ( m_flAnimTime >= m_flAnimationDuration )
+ {
+ ResetTimeSlider();
+ return;
+ }
+
+ // set the new animtion time
+ m_TimeSlider.SetPos( (m_flAnimTime / m_flAnimationDuration) * ANIMSLIDER_NUMTICS );
+
+ UpdateAnimationTime();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Resets the slider bar and all times
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::ResetTimeSlider( void )
+{
+ PausePlayback();
+ m_flAnimTime = 0.0f;
+ m_flAnimationStart = 0.0f;
+ m_TimeSlider.SetPos( 0 );
+ UpdateAnimationTime();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Called whenever the selection changes, so the slider bar can update
+// with the selected keyframe info
+// Input : &selection -
+//-----------------------------------------------------------------------------
+void CMapAnimationDlg::SelectionChanged( CMapObjectList &selection )
+{
+ // reset the slider
+ ResetTimeSlider();
+ m_bEnabled = false;
+
+ // loop through the selection looking for potential animating objects
+ CMapEntity *ent = NULL;
+
+ FOR_EACH_OBJ( selection, pos )
+ {
+ ent = dynamic_cast<CMapEntity*>( selection.Element(pos) );
+
+ if ( ent )
+ {
+ if ( ent->IsAnimationController() && ent->GetChildOfType((CMapAnimator*)NULL) )
+ {
+ m_bEnabled = true;
+ break;
+ }
+ }
+ }
+
+ // find out our enabled state
+ if ( !m_bEnabled )
+ {
+ m_TimeSlider.EnableWindow( false );
+ return;
+ }
+
+ m_TimeSlider.EnableWindow( true );
+
+ // set up the slider from the selection
+ CMapAnimator *anim = ent->GetChildOfType( (CMapAnimator*)NULL );
+ Assert( anim != NULL );
+
+ m_flAnimationDuration = anim->GetRemainingTime();
+}
+