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.
332 lines
8.8 KiB
332 lines
8.8 KiB
//========= 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(); |
|
} |
|
|
|
|