|
|
//========= Copyright � 1996-2005, 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++) { CMapClass *pMapClass = (CUtlReference< CMapClass >)pSelection->Element( i ); CMapEntity *ent = dynamic_cast<CMapEntity*>( pMapClass );
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 ) { CMapClass *pMapClass = (CUtlReference< CMapClass >)selection.Element(pos); ent = dynamic_cast<CMapEntity*>( pMapClass );
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(); }
|