|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeclip.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datamodel/dmehandle.h"
#include "movieobjects/dmetimeframe.h"
#include "movieobjects/dmebookmark.h"
#include "movieobjects/dmesound.h"
#include "movieobjects/dmechannel.h"
#include "movieobjects/dmecamera.h"
#include "movieobjects/dmelight.h"
#include "movieobjects/dmedag.h"
#include "movieobjects/dmeinput.h"
#include "movieobjects/dmeoperator.h"
#include "movieobjects/dmematerial.h"
#include "movieobjects/dmetrack.h"
#include "movieobjects/dmetrackgroup.h"
#include "movieobjects/dmematerialoverlayfxclip.h"
#include "movieobjects/dmeanimationset.h"
#include "movieobjects_interfaces.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imesh.h"
#include "tier3/tier3.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// String to clip type + back
//-----------------------------------------------------------------------------
static const char *s_pClipTypeNames[DMECLIP_TYPE_COUNT] = { "Channel", "Audio", "Effects", "Film", };
DmeClipType_t ClipTypeFromString( const char *pName ) { for ( DmeClipType_t i = DMECLIP_FIRST; i <= DMECLIP_LAST; ++i ) { if ( !Q_stricmp( pName, s_pClipTypeNames[i] ) ) return i; } return DMECLIP_UNKNOWN; }
const char *ClipTypeToString( DmeClipType_t type ) { if ( type >= DMECLIP_FIRST && type <= DMECLIP_LAST ) return s_pClipTypeNames[ type ]; return "Unknown"; }
//-----------------------------------------------------------------------------
// CDmeClip - common base class for filmclips, soundclips, and channelclips
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeClip, CDmeClip );
void CDmeClip::OnConstruction() { m_TimeFrame.InitAndCreate( this, "timeFrame" ); m_ClipColor.InitAndSet( this, "color", Color( 0, 0, 0, 0 ) ); m_ClipText.Init( this, "text" ); m_bMute.Init( this, "mute" ); m_TrackGroups.Init( this, "trackGroups", FATTRIB_MUSTCOPY | FATTRIB_HAS_ARRAY_CALLBACK ); }
void CDmeClip::OnDestruction() { }
//-----------------------------------------------------------------------------
// Inherited from IDmElement
//-----------------------------------------------------------------------------
void CDmeClip::OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) { BaseClass::OnAttributeArrayElementAdded( pAttribute, nFirstElem, nLastElem ); if ( pAttribute == m_TrackGroups.GetAttribute() ) { for ( int i = nFirstElem; i <= nLastElem; ++i ) { CDmeTrackGroup *pTrackGroup = m_TrackGroups[ i ]; if ( pTrackGroup ) { pTrackGroup->SetOwnerClip( this ); } } return; } }
void CDmeClip::OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) { BaseClass::OnAttributeArrayElementRemoved( pAttribute, nFirstElem, nLastElem ); if ( pAttribute == m_TrackGroups.GetAttribute() ) { for ( int i = nFirstElem; i <= nLastElem; ++i ) { CDmeTrackGroup *pTrackGroup = m_TrackGroups[ i ]; if ( pTrackGroup ) { pTrackGroup->SetOwnerClip( NULL ); } } return; } }
//-----------------------------------------------------------------------------
// Clip color
//-----------------------------------------------------------------------------
void CDmeClip::SetClipColor( const Color& clr ) { m_ClipColor.Set( clr ); }
Color CDmeClip::GetClipColor() const { return m_ClipColor.Get(); }
//-----------------------------------------------------------------------------
// Clip text
//-----------------------------------------------------------------------------
void CDmeClip::SetClipText( const char *pText ) { m_ClipText = pText; }
const char* CDmeClip::GetClipText() const { return m_ClipText; }
//-----------------------------------------------------------------------------
// Returns the time frame
//-----------------------------------------------------------------------------
CDmeTimeFrame *CDmeClip::GetTimeFrame() const { return m_TimeFrame.GetElement(); }
DmeTime_t CDmeClip::ToChildMediaTime( DmeTime_t t, bool bClamp ) const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->ToChildMediaTime( t, bClamp ) : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::FromChildMediaTime( DmeTime_t t, bool bClamp ) const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->FromChildMediaTime( t, bClamp ) : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::ToChildMediaDuration( DmeTime_t dt ) const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->ToChildMediaDuration( dt ) : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::FromChildMediaDuration( DmeTime_t dt ) const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->FromChildMediaDuration( dt ) : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::GetTimeOffset() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetTimeOffset() : DmeTime_t( 0 ); }
float CDmeClip::GetTimeScale() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetTimeScale() : 0.0f; }
DmeTime_t CDmeClip::GetStartTime() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetStartTime() : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::GetEndTime() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetStartTime() + tf->GetDuration() : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::GetDuration() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetDuration() : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::GetStartInChildMediaTime() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetStartInChildMediaTime() : DmeTime_t( 0 ); }
DmeTime_t CDmeClip::GetEndInChildMediaTime() const { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); return tf ? tf->GetEndInChildMediaTime() : DmeTime_t( 0 ); }
void CDmeClip::SetTimeOffset( DmeTime_t t ) { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); if ( tf ) { tf->SetTimeOffset( t ); } }
void CDmeClip::SetTimeScale( float s ) { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); if ( tf ) { tf->SetTimeScale( s ); } }
void CDmeClip::SetStartTime( DmeTime_t t ) { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); if ( tf ) { tf->SetStartTime( t ); } }
void CDmeClip::SetDuration( DmeTime_t t ) { CDmeTimeFrame *tf = m_TimeFrame.GetElement(); if ( tf ) { tf->SetDuration( t ); } }
//-----------------------------------------------------------------------------
// Track iteration
//-----------------------------------------------------------------------------
const CUtlVector< DmElementHandle_t > &CDmeClip::GetTrackGroups( ) const { return m_TrackGroups.Get(); }
int CDmeClip::GetTrackGroupCount( ) const { // Make sure no invalid clip types have snuck in
return m_TrackGroups.Count(); }
CDmeTrackGroup *CDmeClip::GetTrackGroup( int nIndex ) const { if ( ( nIndex >= 0 ) && ( nIndex < m_TrackGroups.Count() ) ) return m_TrackGroups[ nIndex ]; return NULL; } //-----------------------------------------------------------------------------
// Is a track group valid to add?
//-----------------------------------------------------------------------------
bool CDmeClip::IsTrackGroupValid( CDmeTrackGroup *pTrackGroup ) { // FIXME: If track groups have allowed types, we can check for validity
for ( DmeClipType_t i = DMECLIP_FIRST; i <= DMECLIP_LAST; ++i ) { if ( !IsSubClipTypeAllowed( i ) && pTrackGroup->IsSubClipTypeAllowed( i ) ) return false; }
return true; }
//-----------------------------------------------------------------------------
// Track group addition/removal
//-----------------------------------------------------------------------------
void CDmeClip::AddTrackGroup( CDmeTrackGroup *pTrackGroup ) { if ( !IsTrackGroupValid( pTrackGroup ) ) return;
// FIXME: Should check if track with same name already exists???
if ( GetTrackGroupIndex( pTrackGroup ) < 0 ) { m_TrackGroups.AddToTail( pTrackGroup ); } }
void CDmeClip::AddTrackGroupBefore( CDmeTrackGroup *pTrackGroup, CDmeTrackGroup *pBefore ) { if ( !IsTrackGroupValid( pTrackGroup ) ) return;
// FIXME: Should check if track with same name already exists???
if ( GetTrackGroupIndex( pTrackGroup ) < 0 ) { int nBeforeIndex = pBefore ? GetTrackGroupIndex( pBefore ) : GetTrackGroupCount(); if ( nBeforeIndex >= 0 ) { m_TrackGroups.InsertBefore( nBeforeIndex, pTrackGroup ); } } }
CDmeTrackGroup *CDmeClip::AddTrackGroup( const char *pTrackGroupName ) { CDmeTrackGroup *pTrackGroup = CreateElement< CDmeTrackGroup >( pTrackGroupName, GetFileId() ); pTrackGroup->SetMinimized( false ); m_TrackGroups.AddToTail( pTrackGroup ); return pTrackGroup; }
void CDmeClip::RemoveTrackGroup( int nIndex ) { Assert( nIndex >= 0 && nIndex < m_TrackGroups.Count() );
m_TrackGroups.Remove( nIndex ); }
void CDmeClip::RemoveTrackGroup( CDmeTrackGroup *pTrackGroup ) { int i = GetTrackGroupIndex( pTrackGroup ); if ( i < 0 ) return;
m_TrackGroups.Remove( i ); }
void CDmeClip::RemoveTrackGroup( const char *pTrackGroupName ) { if ( !pTrackGroupName ) { pTrackGroupName = DMETRACKGROUP_DEFAULT_NAME; }
int c = m_TrackGroups.Count(); for ( int i = c; --i >= 0; ) { if ( !Q_strcmp( m_TrackGroups[i]->GetName(), pTrackGroupName ) ) { m_TrackGroups.Remove( i ); return; } } }
//-----------------------------------------------------------------------------
// Swap track groups
//-----------------------------------------------------------------------------
void CDmeClip::SwapOrder( CDmeTrackGroup *pTrackGroup1, CDmeTrackGroup *pTrackGroup2 ) { if ( pTrackGroup1 == pTrackGroup2 ) return; if ( pTrackGroup1->IsFilmTrackGroup() || pTrackGroup2->IsFilmTrackGroup() ) return;
int nIndex1 = -1, nIndex2 = -1; int c = m_TrackGroups.Count(); for ( int i = c; --i >= 0; ) { if ( m_TrackGroups[i] == pTrackGroup1 ) { nIndex1 = i; } if ( m_TrackGroups[i] == pTrackGroup2 ) { nIndex2 = i; } } if ( ( nIndex1 < 0 ) || ( nIndex2 < 0 ) ) return;
m_TrackGroups.Swap( nIndex1, nIndex2 ); }
//-----------------------------------------------------------------------------
// Track group finding
//-----------------------------------------------------------------------------
CDmeTrackGroup *CDmeClip::FindTrackGroup( const char *pTrackGroupName ) const { if ( !pTrackGroupName ) { pTrackGroupName = DMETRACKGROUP_DEFAULT_NAME; }
int c = m_TrackGroups.Count(); for ( int i = 0 ; i < c; ++i ) { CDmeTrackGroup *pTrackGroup = m_TrackGroups[i]; if ( !pTrackGroup ) continue;
if ( !Q_strcmp( pTrackGroup->GetName(), pTrackGroupName ) ) return pTrackGroup; } return NULL; }
int CDmeClip::GetTrackGroupIndex( CDmeTrackGroup *pTrackGroup ) const { int nTrackGroups = m_TrackGroups.Count(); for ( int i = 0 ; i < nTrackGroups; ++i ) { if ( pTrackGroup == m_TrackGroups[i] ) return i; } return -1; }
//-----------------------------------------------------------------------------
// Find or create a track group
//-----------------------------------------------------------------------------
CDmeTrackGroup *CDmeClip::FindOrAddTrackGroup( const char *pTrackGroupName ) { CDmeTrackGroup *pTrackGroup = FindTrackGroup( pTrackGroupName ); if ( !pTrackGroup ) { pTrackGroup = AddTrackGroup( pTrackGroupName ); } return pTrackGroup; }
//-----------------------------------------------------------------------------
// Finding clips in track groups
//-----------------------------------------------------------------------------
CDmeTrack *CDmeClip::FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup /*= NULL*/ ) const { // DmeClipType_t type = pClip->GetClipType();
int c = m_TrackGroups.Count(); for ( int i = 0 ; i < c; ++i ) { // FIXME: If trackgroups have valid types, can early out here
CDmeTrack *pTrack = m_TrackGroups[i]->FindTrackForClip( pClip ); if ( pTrack ) { if ( ppTrackGroup ) { *ppTrackGroup = m_TrackGroups[i]; } return pTrack; } }
return NULL; }
bool CDmeClip::FindMultiTrackGroupForClip( CDmeClip *pClip, int *pTrackGroupIndex, int *pTrackIndex, int *pClipIndex ) const { int nTrackGroups = m_TrackGroups.Count(); for ( int gi = 0 ; gi < nTrackGroups; ++gi ) { CDmeTrackGroup *pTrackGroup = m_TrackGroups[ gi ]; if ( !pTrackGroup ) continue;
if ( !pTrackGroup->FindTrackForClip( pClip, pTrackIndex, pClipIndex ) ) continue;
if ( pTrackGroupIndex ) { *pTrackGroupIndex = gi; } return true; }
return false; }
//-----------------------------------------------------------------------------
// Finding clips in tracks by time
//-----------------------------------------------------------------------------
void CDmeClip::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const { if ( clipType == DMECLIP_FILM ) return;
int gc = GetTrackGroupCount(); for ( int i = 0; i < gc; ++i ) { CDmeTrackGroup *pTrackGroup = GetTrackGroup( i ); if ( !pTrackGroup ) continue;
pTrackGroup->FindClipsAtTime( clipType, time, flags, clips ); } }
void CDmeClip::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const { if ( clipType == DMECLIP_FILM ) return;
int gc = GetTrackGroupCount(); for ( int i = 0; i < gc; ++i ) { CDmeTrackGroup *pTrackGroup = GetTrackGroup( i ); if ( !pTrackGroup ) continue;
pTrackGroup->FindClipsWithinTime( clipType, startTime, endTime, flags, clips ); } }
//-----------------------------------------------------------------------------
// Build a list of all referring clips
//-----------------------------------------------------------------------------
static int BuildReferringClipList( CDmeClip *pClip, CDmeClip** ppParents, int nMaxCount ) { int nCount = 0;
DmAttributeReferenceIterator_t it, it2, it3; for ( it = g_pDataModel->FirstAttributeReferencingElement( pClip->GetHandle() ); it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; it = g_pDataModel->NextAttributeReferencingElement( it ) ) { CDmAttribute *pAttribute = g_pDataModel->GetAttribute( it ); const char *pName = pAttribute->GetName(); CDmElement *pElement = pAttribute->GetOwner(); CDmeTrack *pTrack = CastElement< CDmeTrack >( pElement ); if ( !pTrack ) continue;
for ( it2 = g_pDataModel->FirstAttributeReferencingElement( pTrack->GetHandle() ); it2 != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; it2 = g_pDataModel->NextAttributeReferencingElement( it2 ) ) { pAttribute = g_pDataModel->GetAttribute( it2 ); pName = pAttribute->GetName(); pElement = pAttribute->GetOwner(); CDmeTrackGroup *pTrackGroup = CastElement< CDmeTrackGroup >( pElement ); if ( !pTrackGroup ) continue;
for ( it3 = g_pDataModel->FirstAttributeReferencingElement( pTrackGroup->GetHandle() ); it3 != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; it3 = g_pDataModel->NextAttributeReferencingElement( it3 ) ) { pAttribute = g_pDataModel->GetAttribute( it3 ); pName = pAttribute->GetName(); pElement = pAttribute->GetOwner(); CDmeClip *pParent = CastElement< CDmeClip >( pElement ); if ( !pParent ) continue;
Assert( nCount < nMaxCount ); if ( nCount >= nMaxCount ) return nCount; ppParents[nCount++] = pParent; } } } return nCount; }
//-----------------------------------------------------------------------------
// Clip stack
//-----------------------------------------------------------------------------
static bool BuildClipStack_R( DmeClipStack_t* pStack, CDmeClip *pMovie, CDmeClip *pShot, CDmeClip *pCurrent ) { // Add this clip to the stack
int nIndex = pStack->AddToHead( CDmeHandle< CDmeClip >( pCurrent ) );
// Is this clip the shot? We don't need to look for it any more.
if ( pCurrent == pShot ) { pShot = NULL; }
// Is this clip the movie? We succeeded if we already found the shot!
if ( pCurrent == pMovie ) { if ( !pShot ) return true; } else { // NOTE: This algorithm assumes a clip can never appear twice under another clip
// at a single level of hierarchy.
CDmeClip* ppParents[1024]; int nCount = BuildReferringClipList( pCurrent, ppParents, 1024 ); for ( int i = 0; i < nCount; ++i ) { // Can we find a path to the root through the shot? We succeeded!
if ( BuildClipStack_R( pStack, pMovie, pShot, ppParents[i] ) ) return true; } }
// This clip didn't work out for us. Remove it.
pStack->Remove( nIndex );
return false; }
bool CDmeClip::BuildClipStack( DmeClipStack_t* pStack, CDmeClip *pMovie, CDmeClip *pShot ) { // Walk through each shot in the movie and look for the subClip, if don't find it recurse into each shot
return BuildClipStack_R( pStack, pMovie, pShot, this ); }
DmeTime_t CDmeClip::ToChildMediaTime( const DmeClipStack_t& stack, DmeTime_t globalTime, bool bClamp /* = true */ ) { DmeTime_t time = globalTime;
int nClips = stack.Count(); for ( int i = 0; i < nClips; ++i ) { time = stack[ i ]->ToChildMediaTime( time, bClamp ); }
return time; }
DmeTime_t CDmeClip::FromChildMediaTime( const DmeClipStack_t& stack, DmeTime_t localTime, bool bClamp /* = true */ ) { DmeTime_t time = localTime;
int nClips = stack.Count(); for ( int i = nClips-1; i >= 0; --i ) { time = stack[ i ]->FromChildMediaTime( time, bClamp ); }
return time; }
DmeTime_t CDmeClip::ToChildMediaDuration( const DmeClipStack_t& stack, DmeTime_t globalDuration ) { DmeTime_t duration = globalDuration;
int nClips = stack.Count(); for ( int i = 0; i < nClips; ++i ) { duration = stack[ i ]->ToChildMediaDuration( duration ); }
return duration; }
DmeTime_t CDmeClip::FromChildMediaDuration( const DmeClipStack_t& stack, DmeTime_t localDuration ) { DmeTime_t duration = localDuration;
int nClips = stack.Count(); for ( int i = nClips-1; i >= 0; --i ) { duration = stack[ i ]->FromChildMediaDuration( duration ); }
return duration; }
void CDmeClip::ToChildMediaTime( DmeLog_TimeSelection_t ¶ms, const DmeClipStack_t& stack ) { for ( int i = 0; i < TS_TIME_COUNT; ++i ) { params.m_nTimes[i] = ToChildMediaTime( stack, params.m_nTimes[i], false ); } }
//-----------------------------------------------------------------------------
//
// CDmeSoundClip - timeframe view into a dmesound
//
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSoundClip, CDmeSoundClip );
void CDmeSoundClip::OnConstruction() { m_Sound.Init( this, "sound" ); m_bShowWave.InitAndSet( this, "showwave", false ); }
void CDmeSoundClip::OnDestruction() { }
void CDmeSoundClip::SetShowWave( bool state ) { m_bShowWave = state; }
bool CDmeSoundClip::ShouldShowWave( ) const { return m_bShowWave; }
//-----------------------------------------------------------------------------
// CDmeChannelsClip - timeframe view into a set of channels
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeChannelsClip, CDmeChannelsClip );
void CDmeChannelsClip::OnConstruction() { m_Channels.Init( this, "channels" ); }
void CDmeChannelsClip::OnDestruction() { }
CDmeChannel *CDmeChannelsClip::CreatePassThruConnection( char const *passThruName, CDmElement *pFrom, char const *pFromAttribute, CDmElement *pTo, char const *pToAttribute, int index /*= 0*/ ) { CDmeChannel *helper = CreateElement< CDmeChannel >( passThruName, GetFileId() ); Assert( helper );
helper->SetMode( CM_PASS ); helper->SetInput( pFrom, pFromAttribute ); helper->SetOutput( pTo, pToAttribute, index );
m_Channels.AddToTail( helper );
return helper; }
void CDmeChannelsClip::RemoveChannel( CDmeChannel *pChannel ) { int nCount = m_Channels.Count(); for ( int i = 0; i < nCount; ++i ) { if ( pChannel == m_Channels[i] ) { m_Channels.Remove( i ); break; } } }
//-----------------------------------------------------------------------------
// CDmeFXClip - timeframe view into an effect
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFXClip, CDmeFXClip );
void CDmeFXClip::OnConstruction() { }
void CDmeFXClip::OnDestruction() { }
//-----------------------------------------------------------------------------
// Global list of FX clip types
//-----------------------------------------------------------------------------
const char *CDmeFXClip::s_pFXClipTypes[MAX_FXCLIP_TYPES]; const char *CDmeFXClip::s_pFXClipDescriptions[MAX_FXCLIP_TYPES]; int CDmeFXClip::s_nFXClipTypeCount = 0;
void CDmeFXClip::InstallFXClipType( const char *pElementType, const char *pDescription ) { s_pFXClipTypes[s_nFXClipTypeCount] = pElementType; s_pFXClipDescriptions[s_nFXClipTypeCount] = pDescription; ++s_nFXClipTypeCount; }
int CDmeFXClip::FXClipTypeCount() { return s_nFXClipTypeCount; }
const char *CDmeFXClip::FXClipType( int nIndex ) { Assert( s_nFXClipTypeCount > nIndex ); return s_pFXClipTypes[nIndex]; }
const char *CDmeFXClip::FXClipDescription( int nIndex ) { Assert( s_nFXClipTypeCount > nIndex ); return s_pFXClipDescriptions[nIndex]; }
//-----------------------------------------------------------------------------
// CDmeFilmClip - hierarchical clip (movie, sequence or shot) w/ scene info
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeFilmClip, CDmeFilmClip );
void CDmeFilmClip::OnConstruction() { m_MaterialOverlayEffect.Init( this, "materialOverlay" );
m_MapName.Init( this, "mapname" ); m_Camera.Init( this, "camera" ); m_MonitorCameras.Init( this, "monitorCameras" ); m_nActiveMonitor.InitAndSet( this, "activeMonitor", -1 ); m_Lights.Init( this, "lights" ); m_Scene.Init( this, "scene" ); m_AVIFile.Init( this, "aviFile" ); m_fadeInDuration .InitAndSet( this, "fadeIn", 0 ); m_fadeOutDuration.InitAndSet( this, "fadeOut", 0 );
m_Inputs.Init( this, "inputs" ); m_Operators.Init( this, "operators" ); m_bIsUsingCachedVersion.Init( this, "useAviFile" ); m_AnimationSets.Init( this, "animationSets" ); m_Bookmarks.Init( this, "bookmarks" ); m_FilmTrackGroup.Init( this, "subClipTrackGroup", FATTRIB_HAS_CALLBACK | FATTRIB_HAS_PRE_CALLBACK ); m_Volume.InitAndSet( this, "volume", 1.0);
m_pCachedVersion = NULL; m_bIsUsingCachedVersion = false; m_bReloadCachedVersion = false; }
void CDmeFilmClip::OnDestruction() { if ( g_pVideo != NULL && m_pCachedVersion != NULL ) { g_pVideo->DestroyVideoMaterial( m_pCachedVersion ); m_pCachedVersion = NULL; } }
//-----------------------------------------------------------------------------
// Returns the special film track group
//-----------------------------------------------------------------------------
CDmeTrackGroup *CDmeFilmClip::GetFilmTrackGroup() const { return m_FilmTrackGroup; }
//-----------------------------------------------------------------------------
// Returns the special film track
//-----------------------------------------------------------------------------
CDmeTrack *CDmeFilmClip::GetFilmTrack() const { CDmeTrackGroup *pTrackGroup = m_FilmTrackGroup.GetElement(); if ( pTrackGroup ) return pTrackGroup->GetFilmTrack(); return NULL; }
CDmeTrackGroup *CDmeFilmClip::FindOrCreateFilmTrackGroup() { if ( !m_FilmTrackGroup ) { m_FilmTrackGroup = CreateElement< CDmeTrackGroup >( "subClipTrackGroup", GetFileId() ); m_FilmTrackGroup->SetMinimized( false ); m_FilmTrackGroup->SetMaxTrackCount( 1 ); m_FilmTrackGroup->SetOwnerClip( this ); } return m_FilmTrackGroup; }
CDmeTrack *CDmeFilmClip::FindOrCreateFilmTrack() { CDmeTrackGroup *pTrackGroup = FindOrCreateFilmTrackGroup(); CDmeTrack *pTrack = pTrackGroup->GetFilmTrack(); return pTrack ? pTrack : m_FilmTrackGroup->CreateFilmTrack(); }
//-----------------------------------------------------------------------------
// Finding clips in track groups
//-----------------------------------------------------------------------------
CDmeTrack *CDmeFilmClip::FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup /*= NULL*/ ) const { if ( m_FilmTrackGroup.GetElement() ) { CDmeTrack *pTrack = m_FilmTrackGroup->FindTrackForClip( pClip ); if ( pTrack ) { if ( ppTrackGroup ) { *ppTrackGroup = m_FilmTrackGroup; } return pTrack; } }
return CDmeClip::FindTrackForClip( pClip, ppTrackGroup ); }
//-----------------------------------------------------------------------------
// Finding clips in tracks by time
//-----------------------------------------------------------------------------
void CDmeFilmClip::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const { if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) ) { if ( m_FilmTrackGroup ) { m_FilmTrackGroup->FindClipsAtTime( clipType, time, flags, clips ); } }
CDmeClip::FindClipsAtTime( clipType, time, flags, clips ); }
void CDmeFilmClip::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const { if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) ) { if ( m_FilmTrackGroup ) { m_FilmTrackGroup->FindClipsWithinTime( clipType, startTime, endTime, flags, clips ); } }
CDmeClip::FindClipsWithinTime( clipType, startTime, endTime, flags, clips ); }
//-----------------------------------------------------------------------------
// Volume
//-----------------------------------------------------------------------------
void CDmeFilmClip::SetVolume( float state ) { m_Volume = state; } float CDmeFilmClip::GetVolume() const { return m_Volume.Get(); }
//-----------------------------------------------------------------------------
// mapname helper methods
//-----------------------------------------------------------------------------
const char *CDmeFilmClip::GetMapName() { return m_MapName.Get(); }
void CDmeFilmClip::SetMapName( const char *pMapName ) { m_MapName.Set( pMapName ); }
//-----------------------------------------------------------------------------
// Attribute changed
//-----------------------------------------------------------------------------
void CDmeFilmClip::PreAttributeChanged( CDmAttribute *pAttribute ) { BaseClass::PreAttributeChanged( pAttribute ); if ( pAttribute == m_FilmTrackGroup.GetAttribute() ) { if ( m_FilmTrackGroup.GetElement() ) { m_FilmTrackGroup->SetOwnerClip( NULL ); } return; } }
void CDmeFilmClip::OnAttributeChanged( CDmAttribute *pAttribute ) { BaseClass::OnAttributeChanged( pAttribute ); if ( pAttribute == m_FilmTrackGroup.GetAttribute() ) { if ( m_FilmTrackGroup.GetElement() ) { m_FilmTrackGroup->SetMaxTrackCount( 1 ); m_FilmTrackGroup->SetOwnerClip( this ); } } else if ( pAttribute->GetOwner() == m_TimeFrame.GetElement() ) { InvokeOnAttributeChangedOnReferrers( GetHandle(), pAttribute ); } }
void CDmeFilmClip::OnElementUnserialized( ) { BaseClass::OnElementUnserialized();
CDmeTrackGroup *pFilmTrackGroup = m_FilmTrackGroup.GetElement(); if ( pFilmTrackGroup ) { pFilmTrackGroup->SetMaxTrackCount( 1 ); if ( pFilmTrackGroup->GetTrackCount() == 0 ) { pFilmTrackGroup->CreateFilmTrack(); } }
// this conversion code went in on 10/31/2005
// I'm hoping we don't care about any files that old - if we ever hit this, we should move this code into an unserialization converter
Assert( !HasAttribute( "overlay" ) && !HasAttribute( "overlayalpha" ) ); if ( HasAttribute( "overlay" ) || HasAttribute( "overlayalpha" ) ) { Warning( "CDmeFilmClip %s is an old version that has overlay and/or overlayalpha attributes!\n", GetName() );
// Backward compat conversion
// If this is an older file with an overlay attribute, strip it out into materialoverlay
CDmAttribute *pOverlayAttribute = GetAttribute( "overlay" ); if ( !pOverlayAttribute ) goto cleanUp;
const char *pName = pOverlayAttribute->GetValueString(); if ( !pName || !pName[0] ) goto cleanUp;
// If we don't yet have a material overlay, create one
if ( m_MaterialOverlayEffect.GetElement() == NULL ) { m_MaterialOverlayEffect = CreateElement<CDmeMaterialOverlayFXClip>( "materialOverlay", GetFileId() ); }
m_MaterialOverlayEffect->SetOverlayEffect( pName );
// If this is an older file with an overlayalpha attribute, strip it out into materialoverlay
CDmAttribute *pOverlayAlphaAttribute = GetAttribute( "overlayalpha" ); if ( pOverlayAlphaAttribute ) { float alpha = pOverlayAlphaAttribute->GetValue<float>(); m_MaterialOverlayEffect->SetAlpha( alpha ); }
cleanUp: // Always strip out the old overlay attribute
RemoveAttribute( "overlay" ); RemoveAttribute( "overlayalpha" ); } }
//-----------------------------------------------------------------------------
// Resolve
//-----------------------------------------------------------------------------
void CDmeFilmClip::Resolve() { BaseClass::Resolve(); if ( m_AVIFile.IsDirty() ) { m_bReloadCachedVersion = true; m_AVIFile.GetAttribute()->RemoveFlag( FATTRIB_DIRTY ); } }
//-----------------------------------------------------------------------------
// Helper for overlays
//-----------------------------------------------------------------------------
void CDmeFilmClip::SetOverlay( const char *pMaterialName ) { if ( pMaterialName && pMaterialName[0] ) { if ( !m_MaterialOverlayEffect.GetElement() ) { m_MaterialOverlayEffect = CreateElement<CDmeMaterialOverlayFXClip>( "materialOverlay", GetFileId() ); }
m_MaterialOverlayEffect->SetOverlayEffect( pMaterialName ); } else { m_MaterialOverlayEffect.Set( NULL ); } }
IMaterial *CDmeFilmClip::GetOverlayMaterial() { return m_MaterialOverlayEffect.GetElement() ? m_MaterialOverlayEffect->GetMaterial() : NULL; }
float CDmeFilmClip::GetOverlayAlpha() { return m_MaterialOverlayEffect.GetElement() ? m_MaterialOverlayEffect->GetAlpha() : 0.0f; }
void CDmeFilmClip::SetOverlayAlpha( float alpha ) { if ( m_MaterialOverlayEffect.GetElement() ) { m_MaterialOverlayEffect->SetAlpha( alpha ); } }
bool CDmeFilmClip::HasOpaqueOverlay( void ) { if ( m_MaterialOverlayEffect->GetMaterial()->IsTranslucent() || ( m_MaterialOverlayEffect->GetAlpha() < 1.0f ) ) { return false; }
return true; }
void CDmeFilmClip::DrawOverlay( DmeTime_t time, Rect_t ¤tRect, Rect_t &totalRect ) { if ( m_MaterialOverlayEffect.GetElement() ) { m_MaterialOverlayEffect->ApplyEffect( ToChildMediaTime( time ), currentRect, totalRect, NULL ); }
DmeTime_t fadeIn( m_fadeInDuration ); DmeTime_t fadeOut( m_fadeOutDuration );
float fade = 1.0f; if ( time < GetStartTime() + fadeIn ) { fade = ( time - GetStartTime() ) / fadeIn; } if ( time > GetEndTime() - fadeOut ) { fade = min( fade, ( GetEndTime() - time ) / fadeOut ); } if ( fade < 1.0f ) { if ( !m_FadeMaterial.IsValid() ) { m_FadeMaterial.Init( "engine\\singlecolor.vmt", NULL, false ); }
float r, g, b; m_FadeMaterial->GetColorModulation( &r, &g, &b ); float a = m_FadeMaterial->GetAlphaModulation();
m_FadeMaterial->ColorModulate( 0.0f, 0.0f, 0.0f ); m_FadeMaterial->AlphaModulate( 1.0f - fade );
CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Bind( m_FadeMaterial );
float w = currentRect.width; float h = currentRect.height;
IMesh *pMesh = pRenderContext->GetDynamicMesh(); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f ); meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, h, 0.0f ); meshBuilder.AdvanceVertex();
meshBuilder.Position3f( w, 0.0f, 0.0f ); meshBuilder.AdvanceVertex();
meshBuilder.Position3f( w, h, 0.0f ); meshBuilder.AdvanceVertex();
meshBuilder.End(); pMesh->Draw();
m_FadeMaterial->ColorModulate( r, g, b ); m_FadeMaterial->AlphaModulate( a ); } }
//-----------------------------------------------------------------------------
// AVI tape out
//-----------------------------------------------------------------------------
void CDmeFilmClip::UseCachedVersion( bool bUseCachedVersion ) { m_bIsUsingCachedVersion = bUseCachedVersion; }
bool CDmeFilmClip::IsUsingCachedVersion() const { return m_bIsUsingCachedVersion; }
IVideoMaterial *CDmeFilmClip::GetCachedVideoMaterial() { if ( m_bReloadCachedVersion ) { if ( g_pVideo ) { if ( m_pCachedVersion != NULL ) { g_pVideo->DestroyVideoMaterial( m_pCachedVersion ); m_pCachedVersion = NULL; } if ( m_AVIFile[0] ) { m_pCachedVersion = g_pVideo->CreateVideoMaterial( m_AVIFile, m_AVIFile, "MOD" ); } } m_bReloadCachedVersion = false; } return m_pCachedVersion; } void CDmeFilmClip::SetCachedAVI( const char *pAVIFile ) { m_AVIFile = pAVIFile; m_bReloadCachedVersion = true; }
//-----------------------------------------------------------------------------
// Camera helper methods
//-----------------------------------------------------------------------------
CDmeCamera *CDmeFilmClip::GetCamera() { return m_Camera; }
void CDmeFilmClip::SetCamera( CDmeCamera *pCamera ) { m_Camera = pCamera; }
//-----------------------------------------------------------------------------
// Returns the monitor camera associated with the clip (for now, only 1 supported)
//-----------------------------------------------------------------------------
CDmeCamera *CDmeFilmClip::GetMonitorCamera() { if ( m_nActiveMonitor < 0 ) return NULL; return m_MonitorCameras[ m_nActiveMonitor ]; }
void CDmeFilmClip::AddMonitorCamera( CDmeCamera *pCamera ) { m_MonitorCameras.AddToTail( pCamera ); }
int CDmeFilmClip::FindMonitorCamera( CDmeCamera *pCamera ) { return m_MonitorCameras.Find( pCamera->GetHandle() ); }
void CDmeFilmClip::RemoveMonitorCamera( CDmeCamera *pCamera ) { int i = m_MonitorCameras.Find( pCamera->GetHandle() ); if ( i >= 0 ) { if ( m_nActiveMonitor == i ) { m_nActiveMonitor = -1; } m_MonitorCameras.FastRemove( i ); } }
void CDmeFilmClip::SelectMonitorCamera( CDmeCamera *pCamera ) { m_nActiveMonitor = pCamera ? m_MonitorCameras.Find( pCamera->GetHandle() ) : -1; }
//-----------------------------------------------------------------------------
// Light helper methods
//-----------------------------------------------------------------------------
int CDmeFilmClip::GetLightCount() { return m_Lights.Count(); }
CDmeLight *CDmeFilmClip::GetLight( int nIndex ) { if ( ( nIndex < 0 ) || ( nIndex >= m_Lights.Count() ) ) return NULL;
return m_Lights[ nIndex ]; }
void CDmeFilmClip::AddLight( CDmeLight *pLight ) { m_Lights.AddToTail( pLight ); }
//-----------------------------------------------------------------------------
// Scene / Dag helper methods
//-----------------------------------------------------------------------------
CDmeDag *CDmeFilmClip::GetScene() { return m_Scene.GetElement(); }
void CDmeFilmClip::SetScene( CDmeDag *pDag ) { m_Scene.Set( pDag ); }
//-----------------------------------------------------------------------------
// helper for inputs and operators
//-----------------------------------------------------------------------------
int CDmeFilmClip::GetInputCount() { return m_Inputs.Count(); }
CDmeInput *CDmeFilmClip::GetInput( int nIndex ) { if ( nIndex < 0 || nIndex >= m_Inputs.Count() ) return NULL;
return m_Inputs[ nIndex ]; }
void CDmeFilmClip::AddInput( CDmeInput *pInput ) { m_Inputs.AddToTail( pInput ); }
void CDmeFilmClip::RemoveAllInputs() { m_Inputs.RemoveAll(); }
void CDmeFilmClip::AddOperator( CDmeOperator *pOperator ) { m_Operators.AddToTail( pOperator ); }
void CDmeFilmClip::CollectOperators( CUtlVector< DmElementHandle_t > &operators ) { int numInputs = m_Inputs.Count(); for ( int i = 0; i < numInputs; ++i ) { operators.AddToTail( m_Inputs[ i ]->GetHandle() ); }
int numOperators = m_Operators.Count(); for ( int i = 0; i < numOperators; ++i ) { operators.AddToTail( m_Operators[ i ]->GetHandle() ); } }
int CDmeFilmClip::GetAnimationSetCount() { // yes, this is nasty perf-wise, but since we only have a dozen or so animation sets,
// and we're about to rewrite the entire structure of animation sets vs. clips vs. scene
// it's not worth polluting the leaf code just to save a couple cycles short term
int nCount = 0;
int nElements = m_AnimationSets.Count(); for ( int i = 0; i < nElements; ++i ) { CDmElement *pElement = m_AnimationSets.Get( i ); if ( !pElement ) continue;
CDmeAnimationSet *pAnimSet = CastElement< CDmeAnimationSet >( pElement ); if ( pAnimSet ) { ++nCount; } else { const CDmAttribute *pChildren = pElement->GetAttribute( "children", AT_ELEMENT_ARRAY ); if ( !pChildren ) continue;
CDmrElementArrayConst< CDmElement > array( pChildren ); nCount += array.Count(); } }
return nCount; }
CDmeAnimationSet *CDmeFilmClip::GetAnimationSet( int idx ) { // yes, this is nasty perf-wise, but since we only have a dozen or so animation sets,
// and we're about to rewrite the entire structure of animation sets vs. clips vs. scene
// it's not worth polluting the leaf code just to save a couple cycles short term
int nElements = m_AnimationSets.Count(); for ( int i = 0; i < nElements; ++i ) { CDmElement *pElement = m_AnimationSets.Get( i ); if ( !pElement ) continue;
CDmeAnimationSet *pAnimSet = CastElement< CDmeAnimationSet >( pElement ); if ( pAnimSet ) { if ( idx == 0 ) return pAnimSet; --idx; } else { const CDmAttribute *pChildren = pElement->GetAttribute( "children", AT_ELEMENT_ARRAY ); if ( !pChildren ) continue;
CDmrElementArrayConst< CDmElement > array( pChildren ); int nChildren = array.Count();
if ( idx < nChildren ) return CastElement< CDmeAnimationSet >( array[ idx ] ); idx -= nChildren; } }
return NULL; }
void CDmeFilmClip::AddAnimationSet( CDmeAnimationSet *element ) { m_AnimationSets.AddToTail( element ); }
void CDmeFilmClip::RemoveAllAnimationSets() { m_AnimationSets.RemoveAll(); }
CDmaElementArray< CDmElement > &CDmeFilmClip::GetAnimationSets() { return m_AnimationSets; }
const CDmaElementArray< CDmElement > &CDmeFilmClip::GetAnimationSets() const { return m_AnimationSets; }
const CDmaElementArray< CDmeBookmark > &CDmeFilmClip::GetBookmarks() const { return m_Bookmarks; }
CDmaElementArray< CDmeBookmark > &CDmeFilmClip::GetBookmarks() { return m_Bookmarks; }
//-----------------------------------------------------------------------------
// Used to move clips in non-film track groups with film clips
// Call BuildClipAssociations before modifying the film track,
// then UpdateAssociatedClips after modifying it.
//-----------------------------------------------------------------------------
void CDmeFilmClip::BuildClipAssociations( CUtlVector< ClipAssociation_t > &association, bool bHandleGaps ) { association.RemoveAll();
CDmeTrack *pFilmTrack = GetFilmTrack(); if ( !pFilmTrack ) return;
int c = pFilmTrack->GetClipCount(); int gc = GetTrackGroupCount(); if ( c == 0 || gc == 0 ) return;
DmeTime_t clipStartTime = GetStartInChildMediaTime(); DmeTime_t clipEndTime = GetEndInChildMediaTime();
// These slugs will be removed in UpdateAssociatedClips
if ( bHandleGaps ) { pFilmTrack->FillAllGapsWithSlugs( "__tempSlug__", clipStartTime, clipEndTime ); }
for ( int i = 0; i < gc; ++i ) { CDmeTrackGroup *pTrackGroup = GetTrackGroup( i ); int tc = pTrackGroup->GetTrackCount(); for ( int j = 0; j < tc; ++j ) { CDmeTrack *pTrack = pTrackGroup->GetTrack( j ); if ( !pTrack->IsSynched() ) continue;
// Only have visible tracks now
int cc = pTrack->GetClipCount(); association.EnsureCapacity( association.Count() + cc ); for ( int k = 0; k < cc; ++k ) { CDmeClip *pClip = pTrack->GetClip( k ); CDmeClip *pFilmClip = pFilmTrack->FindFilmClipAtTime( pClip->GetStartTime() ); int nIndex = association.AddToTail(); association[nIndex].m_hClip = pClip; association[nIndex].m_hAssociation = pFilmClip; if ( pFilmClip ) { association[nIndex].m_offset = pClip->GetStartTime() - pFilmClip->GetStartTime(); association[nIndex].m_nType = ClipAssociation_t::HAS_CLIP; continue; }
// Handle edge cases
if ( pClip->GetStartTime() <= clipStartTime ) { association[nIndex].m_offset = pClip->GetStartTime() - clipStartTime; association[nIndex].m_nType = ClipAssociation_t::BEFORE_START; continue; }
if ( pClip->GetStartTime() >= clipEndTime ) { association[nIndex].m_offset = pClip->GetStartTime() - clipEndTime; association[nIndex].m_nType = ClipAssociation_t::AFTER_END; continue; }
association[nIndex].m_offset = DmeTime_t( 0 ); association[nIndex].m_nType = ClipAssociation_t::NO_MOVEMENT; } } } }
//-----------------------------------------------------------------------------
// Rolls associated clips so they remain in the same relative time
//-----------------------------------------------------------------------------
void CDmeFilmClip::RollAssociatedClips( CDmeClip *pClip, CUtlVector< ClipAssociation_t > &association, DmeTime_t dt ) { int c = association.Count(); for ( int i = 0; i < c; ++i ) { if ( association[i].m_nType != ClipAssociation_t::HAS_CLIP ) continue;
if ( association[i].m_hAssociation.Get() != pClip ) continue; DmeTime_t newStartTime = association[i].m_hClip->GetStartTime() - dt; association[i].m_hClip->SetStartTime( newStartTime ); } }
//-----------------------------------------------------------------------------
// Rolls associated clips so they remain in the same relative time
//-----------------------------------------------------------------------------
void CDmeFilmClip::ScaleAssociatedClips( CDmeClip *pClip, CUtlVector< ClipAssociation_t > &association, float ratio, DmeTime_t oldOffset ) { int c = association.Count(); for ( int i = 0; i < c; ++i ) { if ( association[i].m_nType != ClipAssociation_t::HAS_CLIP ) continue;
if ( association[i].m_hAssociation.Get() != pClip ) continue;
DmeTime_t clipStartTime = pClip->GetStartTime(); DmeTime_t oldStartTime = association[i].m_hClip->GetStartTime(); DmeTime_t newStartTime = ( oldStartTime - clipStartTime + oldOffset ) / ratio + clipStartTime - pClip->GetTimeOffset(); association[i].m_hClip->SetStartTime( newStartTime ); } }
void CDmeFilmClip::UpdateAssociatedClips( CUtlVector< ClipAssociation_t > &association ) { int i;
CDmeTrack *pFilmTrack = GetFilmTrack(); if ( !pFilmTrack ) return;
int c = association.Count(); if ( c > 0 ) { DmeTime_t clipStartTime = GetStartInChildMediaTime(); DmeTime_t clipEndTime = GetEndInChildMediaTime();
for ( i = 0; i < c; ++i ) { ClipAssociation_t &curr = association[i]; if ( !curr.m_hClip.Get() ) continue;
switch( curr.m_nType ) { case ClipAssociation_t::HAS_CLIP: if ( curr.m_hAssociation.Get() ) { curr.m_hClip->SetStartTime( curr.m_hAssociation->GetStartTime() + curr.m_offset ); } break;
case ClipAssociation_t::BEFORE_START: curr.m_hClip->SetStartTime( clipStartTime + curr.m_offset ); break;
case ClipAssociation_t::AFTER_END: curr.m_hClip->SetStartTime( clipEndTime + curr.m_offset ); break; } } }
c = pFilmTrack->GetClipCount(); for ( i = c; --i >= 0; ) { CDmeClip *pClip = pFilmTrack->GetClip(i); if ( !Q_strcmp( pClip->GetName(), "__tempSlug__" ) ) { pFilmTrack->RemoveClip( i ); } } }
//-----------------------------------------------------------------------------
// Creates a slug clip
//-----------------------------------------------------------------------------
CDmeFilmClip *CreateSlugClip( const char *pClipName, DmeTime_t startTime, DmeTime_t endTime, DmFileId_t fileid ) { CDmeFilmClip *pSlugClip = CreateElement<CDmeFilmClip>( pClipName, fileid ); pSlugClip->GetTimeFrame()->SetName( "timeframe" ); pSlugClip->SetStartTime( startTime ); pSlugClip->SetDuration( endTime - startTime ); pSlugClip->SetTimeOffset( DmeTime_t( 0 ) ); pSlugClip->SetTimeScale( 1.0f ); pSlugClip->SetClipColor( Color( 0, 0, 0, 128 ) ); pSlugClip->SetOverlay( "vgui/black" ); return pSlugClip; }
//-----------------------------------------------------------------------------
// helper methods
//-----------------------------------------------------------------------------
CDmeTrack *GetParentTrack( CDmeClip *pClip ) { DmAttributeReferenceIterator_t hAttr = g_pDataModel->FirstAttributeReferencingElement( pClip->GetHandle() ); for ( ; hAttr != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; hAttr = g_pDataModel->NextAttributeReferencingElement( hAttr ) ) { CDmAttribute *pAttr = g_pDataModel->GetAttribute( hAttr ); if ( !pAttr ) continue;
CDmeTrack *pTrack = CastElement< CDmeTrack >( pAttr->GetOwner() ); if ( pTrack ) return pTrack; } return NULL; }
//-----------------------------------------------------------------------------
// Finds a channel in a channel or film clip targetting a particular element
//-----------------------------------------------------------------------------
CDmeChannel *FindChannelTargetingElement( CDmeChannelsClip *pChannelsClip, CDmElement *pElement, const char *pAttributeName ) { int nChannels = pChannelsClip->m_Channels.Count(); for ( int i = 0; i < nChannels; ++i ) { CDmeChannel *pChannel = pChannelsClip->m_Channels[ i ]; CDmElement *toElement = pChannel->GetToElement(); if ( toElement != pElement ) continue;
if ( pAttributeName && ( Q_stricmp( pChannel->GetToAttribute()->GetName(), pAttributeName ) != 0 ) ) continue;
return pChannel; }
return NULL; }
CDmeChannel *FindChannelTargetingElement( CDmeFilmClip *pClip, CDmElement *pElement, const char *pAttributeName, CDmeChannelsClip **ppChannelsClip, CDmeTrack **ppTrack, CDmeTrackGroup **ppTrackGroup ) { int gc = pClip->GetTrackGroupCount(); for ( int i = 0; i < gc; ++i ) { CDmeTrackGroup *pTrackGroup = pClip->GetTrackGroup( i ); DMETRACKGROUP_FOREACH_CLIP_TYPE_START( CDmeChannelsClip, pTrackGroup, pTrack, pChannelsClip )
CDmeChannel *pChannel = FindChannelTargetingElement( pChannelsClip, pElement, pAttributeName ); if ( !pChannel ) continue;
if ( ppChannelsClip ) { *ppChannelsClip = pChannelsClip; } if ( ppTrack ) { *ppTrack = pTrack; } if ( ppTrackGroup ) { *ppTrackGroup = pTrackGroup; } return pChannel;
DMETRACKGROUP_FOREACH_CLIP_TYPE_END() }
return NULL; }
|