diff options
Diffstat (limited to 'hammer/mapanimationdlg.cpp')
| -rw-r--r-- | hammer/mapanimationdlg.cpp | 332 |
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(); +} + |