Counter Strike : Global Offensive Source Code
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.

2277 lines
61 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmeclip.h"
  7. #include "tier0/dbg.h"
  8. #include "datamodel/dmelementfactoryhelper.h"
  9. #include "datamodel/dmehandle.h"
  10. #include "movieobjects/dmetimeframe.h"
  11. #include "movieobjects/dmebookmark.h"
  12. #include "movieobjects/dmesound.h"
  13. #include "movieobjects/dmechannel.h"
  14. #include "movieobjects/dmecamera.h"
  15. #include "movieobjects/dmedag.h"
  16. #include "movieobjects/dmeinput.h"
  17. #include "movieobjects/dmeoperator.h"
  18. #include "movieobjects/dmematerial.h"
  19. #include "movieobjects/dmetrack.h"
  20. #include "movieobjects/dmetrackgroup.h"
  21. #include "movieobjects/dmematerialoverlayfxclip.h"
  22. #include "movieobjects/dmeanimationset.h"
  23. #include "movieobjects_interfaces.h"
  24. #include "materialsystem/imaterialsystem.h"
  25. #include "materialsystem/imaterial.h"
  26. #include "materialsystem/imesh.h"
  27. #include "tier3/tier3.h"
  28. // memdbgon must be the last include file in a .cpp file!!!
  29. #include "tier0/memdbgon.h"
  30. //-----------------------------------------------------------------------------
  31. // String to clip type + back
  32. //-----------------------------------------------------------------------------
  33. static const char *s_pClipTypeNames[DMECLIP_TYPE_COUNT] =
  34. {
  35. "Channel",
  36. "Audio",
  37. "Effects",
  38. "Film",
  39. };
  40. DmeClipType_t ClipTypeFromString( const char *pName )
  41. {
  42. for ( DmeClipType_t i = DMECLIP_FIRST; i <= DMECLIP_LAST; ++i )
  43. {
  44. if ( !Q_stricmp( pName, s_pClipTypeNames[i] ) )
  45. return i;
  46. }
  47. return DMECLIP_UNKNOWN;
  48. }
  49. const char *ClipTypeToString( DmeClipType_t type )
  50. {
  51. if ( type >= DMECLIP_FIRST && type <= DMECLIP_LAST )
  52. return s_pClipTypeNames[ type ];
  53. return "Unknown";
  54. }
  55. //-----------------------------------------------------------------------------
  56. // CDmeClip - common base class for filmclips, soundclips, and channelclips
  57. //-----------------------------------------------------------------------------
  58. IMPLEMENT_ELEMENT_FACTORY( DmeClip, CDmeClip );
  59. void CDmeClip::OnConstruction()
  60. {
  61. m_TimeFrame.InitAndCreate( this, "timeFrame" );
  62. m_ClipColor.InitAndSet( this, "color", Color( 0, 0, 0, 0 ) );
  63. m_ClipText.Init( this, "text" );
  64. m_bMute.Init( this, "mute" );
  65. m_TrackGroups.Init( this, "trackGroups", FATTRIB_MUSTCOPY );
  66. m_flDisplayScale.InitAndSet( this, "displayScale", 1.0f );
  67. }
  68. void CDmeClip::OnDestruction()
  69. {
  70. }
  71. //-----------------------------------------------------------------------------
  72. // Clip color
  73. //-----------------------------------------------------------------------------
  74. void CDmeClip::SetClipColor( const Color& clr )
  75. {
  76. m_ClipColor.Set( clr );
  77. }
  78. Color CDmeClip::GetClipColor() const
  79. {
  80. return m_ClipColor.Get();
  81. }
  82. //-----------------------------------------------------------------------------
  83. // Clip text
  84. //-----------------------------------------------------------------------------
  85. void CDmeClip::SetClipText( const char *pText )
  86. {
  87. m_ClipText = pText;
  88. }
  89. const char* CDmeClip::GetClipText() const
  90. {
  91. return m_ClipText;
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Returns the time frame
  95. //-----------------------------------------------------------------------------
  96. CDmeTimeFrame *CDmeClip::GetTimeFrame() const
  97. {
  98. return m_TimeFrame.GetElement();
  99. }
  100. DmeTime_t CDmeClip::ToChildMediaTime( DmeTime_t t, bool bClamp ) const
  101. {
  102. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  103. return tf ? tf->ToChildMediaTime( t, bClamp ) : DmeTime_t( 0 );
  104. }
  105. DmeTime_t CDmeClip::FromChildMediaTime( DmeTime_t t, bool bClamp ) const
  106. {
  107. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  108. return tf ? tf->FromChildMediaTime( t, bClamp ) : DmeTime_t( 0 );
  109. }
  110. DmeTime_t CDmeClip::ToChildMediaDuration( DmeTime_t dt ) const
  111. {
  112. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  113. return tf ? tf->ToChildMediaDuration( dt ) : DmeTime_t( 0 );
  114. }
  115. DmeTime_t CDmeClip::FromChildMediaDuration( DmeTime_t dt ) const
  116. {
  117. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  118. return tf ? tf->FromChildMediaDuration( dt ) : DmeTime_t( 0 );
  119. }
  120. DmeTime_t CDmeClip::GetTimeOffset() const
  121. {
  122. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  123. return tf ? tf->GetTimeOffset() : DmeTime_t( 0 );
  124. }
  125. float CDmeClip::GetTimeScale() const
  126. {
  127. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  128. return tf ? tf->GetTimeScale() : 0.0f;
  129. }
  130. DmeTime_t CDmeClip::GetStartTime() const
  131. {
  132. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  133. return tf ? tf->GetStartTime() : DmeTime_t( 0 );
  134. }
  135. DmeTime_t CDmeClip::GetEndTime() const
  136. {
  137. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  138. return tf ? tf->GetStartTime() + tf->GetDuration() : DmeTime_t( 0 );
  139. }
  140. DmeTime_t CDmeClip::GetDuration() const
  141. {
  142. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  143. return tf ? tf->GetDuration() : DmeTime_t( 0 );
  144. }
  145. DmeTime_t CDmeClip::GetStartInChildMediaTime() const
  146. {
  147. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  148. return tf ? tf->GetStartInChildMediaTime() : DmeTime_t( 0 );
  149. }
  150. DmeTime_t CDmeClip::GetEndInChildMediaTime() const
  151. {
  152. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  153. return tf ? tf->GetEndInChildMediaTime() : DmeTime_t( 0 );
  154. }
  155. void CDmeClip::SetTimeOffset( DmeTime_t t )
  156. {
  157. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  158. if ( tf )
  159. {
  160. tf->SetTimeOffset( t );
  161. }
  162. }
  163. void CDmeClip::SetTimeScale( float s )
  164. {
  165. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  166. if ( tf )
  167. {
  168. tf->SetTimeScale( s );
  169. }
  170. }
  171. void CDmeClip::SetStartTime( DmeTime_t t )
  172. {
  173. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  174. if ( tf )
  175. {
  176. tf->SetStartTime( t );
  177. }
  178. }
  179. void CDmeClip::SetDuration( DmeTime_t t )
  180. {
  181. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  182. if ( tf )
  183. {
  184. tf->SetDuration( t );
  185. }
  186. }
  187. void CDmeClip::BakeTimeScale( float scale /*= 1.0f*/ )
  188. {
  189. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  190. Assert( tf );
  191. if ( !tf )
  192. return;
  193. float flNewScale = tf->GetTimeScale();
  194. tf->SetTimeScale( 1.0f );
  195. if ( scale != 1.0f )
  196. {
  197. tf->SetStartTime ( tf->GetStartTime () / scale );
  198. tf->SetDuration ( tf->GetDuration () / scale );
  199. tf->SetTimeOffset( tf->GetTimeOffset() / scale );
  200. flNewScale *= scale;
  201. }
  202. int nTrackGroups = m_TrackGroups.Count();
  203. for ( int gi = 0; gi < nTrackGroups; ++gi )
  204. {
  205. CDmeTrackGroup *pTrackGroup = m_TrackGroups[ gi ];
  206. if ( !pTrackGroup )
  207. continue;
  208. int nTracks = pTrackGroup->GetTrackCount();
  209. for ( int ti = 0; ti < nTracks; ++ti )
  210. {
  211. CDmeTrack *pTrack = pTrackGroup->GetTrack( ti );
  212. if ( !pTrack )
  213. continue;
  214. int nClips = pTrack->GetClipCount();
  215. for ( int ci = 0; ci < nClips; ++ci )
  216. {
  217. CDmeClip *pClip = pTrack->GetClip( ci );
  218. if ( !pClip )
  219. continue;
  220. pClip->BakeTimeScale( flNewScale );
  221. }
  222. }
  223. }
  224. }
  225. //-----------------------------------------------------------------------------
  226. // Track iteration
  227. //-----------------------------------------------------------------------------
  228. const CUtlVector< DmElementHandle_t > &CDmeClip::GetTrackGroups( ) const
  229. {
  230. return m_TrackGroups.Get();
  231. }
  232. int CDmeClip::GetTrackGroupCount( ) const
  233. {
  234. // Make sure no invalid clip types have snuck in
  235. return m_TrackGroups.Count();
  236. }
  237. CDmeTrackGroup *CDmeClip::GetTrackGroup( int nIndex ) const
  238. {
  239. if ( ( nIndex >= 0 ) && ( nIndex < m_TrackGroups.Count() ) )
  240. return m_TrackGroups[ nIndex ];
  241. return NULL;
  242. }
  243. //-----------------------------------------------------------------------------
  244. // Is a track group valid to add?
  245. //-----------------------------------------------------------------------------
  246. bool CDmeClip::IsTrackGroupValid( CDmeTrackGroup *pTrackGroup )
  247. {
  248. // FIXME: If track groups have allowed types, we can check for validity
  249. for ( DmeClipType_t i = DMECLIP_FIRST; i <= DMECLIP_LAST; ++i )
  250. {
  251. if ( !IsSubClipTypeAllowed( i ) && pTrackGroup->IsSubClipTypeAllowed( i ) )
  252. return false;
  253. }
  254. return true;
  255. }
  256. //-----------------------------------------------------------------------------
  257. // Track group addition/removal
  258. //-----------------------------------------------------------------------------
  259. void CDmeClip::AddTrackGroup( CDmeTrackGroup *pTrackGroup )
  260. {
  261. if ( !IsTrackGroupValid( pTrackGroup ) )
  262. return;
  263. // FIXME: Should check if track with same name already exists???
  264. if ( GetTrackGroupIndex( pTrackGroup ) < 0 )
  265. {
  266. m_TrackGroups.AddToTail( pTrackGroup );
  267. }
  268. }
  269. void CDmeClip::AddTrackGroupBefore( CDmeTrackGroup *pTrackGroup, CDmeTrackGroup *pBefore )
  270. {
  271. if ( !IsTrackGroupValid( pTrackGroup ) )
  272. return;
  273. // FIXME: Should check if track with same name already exists???
  274. if ( GetTrackGroupIndex( pTrackGroup ) < 0 )
  275. {
  276. int nBeforeIndex = pBefore ? GetTrackGroupIndex( pBefore ) : GetTrackGroupCount();
  277. if ( nBeforeIndex >= 0 )
  278. {
  279. m_TrackGroups.InsertBefore( nBeforeIndex, pTrackGroup );
  280. }
  281. }
  282. }
  283. CDmeTrackGroup *CDmeClip::AddTrackGroup( const char *pTrackGroupName )
  284. {
  285. CDmeTrackGroup *pTrackGroup = CreateElement< CDmeTrackGroup >( pTrackGroupName, GetFileId() );
  286. pTrackGroup->SetMinimized( false );
  287. m_TrackGroups.AddToTail( pTrackGroup );
  288. return pTrackGroup;
  289. }
  290. void CDmeClip::RemoveTrackGroup( int nIndex )
  291. {
  292. Assert( nIndex >= 0 && nIndex < m_TrackGroups.Count() );
  293. m_TrackGroups.Remove( nIndex );
  294. }
  295. void CDmeClip::RemoveTrackGroup( CDmeTrackGroup *pTrackGroup )
  296. {
  297. int i = GetTrackGroupIndex( pTrackGroup );
  298. if ( i < 0 )
  299. return;
  300. m_TrackGroups.Remove( i );
  301. }
  302. void CDmeClip::RemoveTrackGroup( const char *pTrackGroupName )
  303. {
  304. if ( !pTrackGroupName )
  305. {
  306. pTrackGroupName = DMETRACKGROUP_DEFAULT_NAME;
  307. }
  308. int c = m_TrackGroups.Count();
  309. for ( int i = c; --i >= 0; )
  310. {
  311. if ( !Q_strcmp( m_TrackGroups[i]->GetName(), pTrackGroupName ) )
  312. {
  313. m_TrackGroups.Remove( i );
  314. return;
  315. }
  316. }
  317. }
  318. //-----------------------------------------------------------------------------
  319. // Swap track groups
  320. //-----------------------------------------------------------------------------
  321. void CDmeClip::SwapOrder( CDmeTrackGroup *pTrackGroup1, CDmeTrackGroup *pTrackGroup2 )
  322. {
  323. if ( pTrackGroup1 == pTrackGroup2 )
  324. return;
  325. if ( pTrackGroup1->IsFilmTrackGroup() || pTrackGroup2->IsFilmTrackGroup() )
  326. return;
  327. int nIndex1 = -1, nIndex2 = -1;
  328. int c = m_TrackGroups.Count();
  329. for ( int i = c; --i >= 0; )
  330. {
  331. if ( m_TrackGroups[i] == pTrackGroup1 )
  332. {
  333. nIndex1 = i;
  334. }
  335. if ( m_TrackGroups[i] == pTrackGroup2 )
  336. {
  337. nIndex2 = i;
  338. }
  339. }
  340. if ( ( nIndex1 < 0 ) || ( nIndex2 < 0 ) )
  341. return;
  342. m_TrackGroups.Swap( nIndex1, nIndex2 );
  343. }
  344. //-----------------------------------------------------------------------------
  345. // Track group finding
  346. //-----------------------------------------------------------------------------
  347. CDmeTrackGroup *CDmeClip::FindTrackGroup( const char *pTrackGroupName ) const
  348. {
  349. if ( !pTrackGroupName )
  350. {
  351. pTrackGroupName = DMETRACKGROUP_DEFAULT_NAME;
  352. }
  353. int c = m_TrackGroups.Count();
  354. for ( int i = 0 ; i < c; ++i )
  355. {
  356. CDmeTrackGroup *pTrackGroup = m_TrackGroups[i];
  357. if ( !pTrackGroup )
  358. continue;
  359. if ( !Q_strcmp( pTrackGroup->GetName(), pTrackGroupName ) )
  360. return pTrackGroup;
  361. }
  362. return NULL;
  363. }
  364. int CDmeClip::GetTrackGroupIndex( CDmeTrackGroup *pTrackGroup ) const
  365. {
  366. int nTrackGroups = m_TrackGroups.Count();
  367. for ( int i = 0 ; i < nTrackGroups; ++i )
  368. {
  369. if ( pTrackGroup == m_TrackGroups[i] )
  370. return i;
  371. }
  372. return -1;
  373. }
  374. //-----------------------------------------------------------------------------
  375. // Find or create a track group
  376. //-----------------------------------------------------------------------------
  377. CDmeTrackGroup *CDmeClip::FindOrAddTrackGroup( const char *pTrackGroupName )
  378. {
  379. CDmeTrackGroup *pTrackGroup = FindTrackGroup( pTrackGroupName );
  380. if ( !pTrackGroup )
  381. {
  382. pTrackGroup = AddTrackGroup( pTrackGroupName );
  383. }
  384. return pTrackGroup;
  385. }
  386. //-----------------------------------------------------------------------------
  387. // Finding clips in track groups
  388. //-----------------------------------------------------------------------------
  389. CDmeTrack *CDmeClip::FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup /*= NULL*/ ) const
  390. {
  391. // DmeClipType_t type = pClip->GetClipType();
  392. int c = m_TrackGroups.Count();
  393. for ( int i = 0 ; i < c; ++i )
  394. {
  395. // FIXME: If trackgroups have valid types, can early out here
  396. CDmeTrack *pTrack = m_TrackGroups[i]->FindTrackForClip( pClip );
  397. if ( pTrack )
  398. {
  399. if ( ppTrackGroup )
  400. {
  401. *ppTrackGroup = m_TrackGroups[i];
  402. }
  403. return pTrack;
  404. }
  405. }
  406. return NULL;
  407. }
  408. bool CDmeClip::FindMultiTrackGroupForClip( CDmeClip *pClip, int *pTrackGroupIndex, int *pTrackIndex, int *pClipIndex ) const
  409. {
  410. int nTrackGroups = m_TrackGroups.Count();
  411. for ( int gi = 0 ; gi < nTrackGroups; ++gi )
  412. {
  413. CDmeTrackGroup *pTrackGroup = m_TrackGroups[ gi ];
  414. if ( !pTrackGroup )
  415. continue;
  416. if ( !pTrackGroup->FindTrackForClip( pClip, pTrackIndex, pClipIndex ) )
  417. continue;
  418. if ( pTrackGroupIndex )
  419. {
  420. *pTrackGroupIndex = gi;
  421. }
  422. return true;
  423. }
  424. return false;
  425. }
  426. //-----------------------------------------------------------------------------
  427. // Finding clips in tracks by time
  428. //-----------------------------------------------------------------------------
  429. void CDmeClip::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  430. {
  431. if ( clipType == DMECLIP_FILM )
  432. return;
  433. int gc = GetTrackGroupCount();
  434. for ( int i = 0; i < gc; ++i )
  435. {
  436. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  437. if ( !pTrackGroup )
  438. continue;
  439. pTrackGroup->FindClipsAtTime( clipType, time, flags, clips );
  440. }
  441. }
  442. void CDmeClip::FindClipsIntersectingTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  443. {
  444. if ( clipType == DMECLIP_FILM )
  445. return;
  446. int gc = GetTrackGroupCount();
  447. for ( int i = 0; i < gc; ++i )
  448. {
  449. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  450. if ( !pTrackGroup )
  451. continue;
  452. pTrackGroup->FindClipsIntersectingTime( clipType, startTime, endTime, flags, clips );
  453. }
  454. }
  455. void CDmeClip::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  456. {
  457. if ( clipType == DMECLIP_FILM )
  458. return;
  459. int gc = GetTrackGroupCount();
  460. for ( int i = 0; i < gc; ++i )
  461. {
  462. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  463. if ( !pTrackGroup )
  464. continue;
  465. pTrackGroup->FindClipsWithinTime( clipType, startTime, endTime, flags, clips );
  466. }
  467. }
  468. //-----------------------------------------------------------------------------
  469. // Build a list of all referring clips
  470. //-----------------------------------------------------------------------------
  471. static int BuildReferringClipList( const CDmeClip *pClip, CDmeClip** ppParents, int nMaxCount )
  472. {
  473. int nCount = 0;
  474. DmAttributeReferenceIterator_t it, it2, it3;
  475. for ( it = g_pDataModel->FirstAttributeReferencingElement( pClip->GetHandle() );
  476. it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  477. it = g_pDataModel->NextAttributeReferencingElement( it ) )
  478. {
  479. CDmAttribute *pAttribute = g_pDataModel->GetAttribute( it );
  480. const char *pName = pAttribute->GetName();
  481. CDmElement *pElement = pAttribute->GetOwner();
  482. CDmeTrack *pTrack = CastElement< CDmeTrack >( pElement );
  483. if ( !pTrack )
  484. continue;
  485. for ( it2 = g_pDataModel->FirstAttributeReferencingElement( pTrack->GetHandle() );
  486. it2 != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  487. it2 = g_pDataModel->NextAttributeReferencingElement( it2 ) )
  488. {
  489. pAttribute = g_pDataModel->GetAttribute( it2 );
  490. pName = pAttribute->GetName();
  491. pElement = pAttribute->GetOwner();
  492. CDmeTrackGroup *pTrackGroup = CastElement< CDmeTrackGroup >( pElement );
  493. if ( !pTrackGroup )
  494. continue;
  495. for ( it3 = g_pDataModel->FirstAttributeReferencingElement( pTrackGroup->GetHandle() );
  496. it3 != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  497. it3 = g_pDataModel->NextAttributeReferencingElement( it3 ) )
  498. {
  499. pAttribute = g_pDataModel->GetAttribute( it3 );
  500. pName = pAttribute->GetName();
  501. pElement = pAttribute->GetOwner();
  502. CDmeClip *pParent = CastElement< CDmeClip >( pElement );
  503. if ( !pParent )
  504. continue;
  505. Assert( nCount < nMaxCount );
  506. if ( nCount >= nMaxCount )
  507. return nCount;
  508. ppParents[nCount++] = pParent;
  509. }
  510. }
  511. }
  512. return nCount;
  513. }
  514. bool CDmeClip::BuildClipStack( DmeClipStack_t* pStack, const CDmeClip *pMovie, CDmeClip *pShot /*=NULL*/ )
  515. {
  516. // Walk through each shot in the movie and look for the subClip, if don't find it recurse into each shot
  517. return pStack->BuildClipStack( pMovie, pShot, this );
  518. }
  519. //-----------------------------------------------------------------------------
  520. // Clip stack
  521. //-----------------------------------------------------------------------------
  522. bool DmeClipStack_t::BuildClipStack_R( const CDmeClip *pMovie, const CDmeClip *pShot, const CDmeClip *pCurrent )
  523. {
  524. // Add this clip to the stack
  525. int nIndex = AddClipToHead( pCurrent );
  526. // Is this clip the shot? We don't need to look for it any more.
  527. if ( pCurrent == pShot )
  528. {
  529. pShot = NULL;
  530. }
  531. // Is this clip the movie? We succeeded if we already found the shot!
  532. if ( pCurrent == pMovie )
  533. {
  534. if ( !pShot )
  535. return true;
  536. }
  537. else
  538. {
  539. // NOTE: This algorithm assumes a clip can never appear twice under another clip
  540. // at a single level of hierarchy.
  541. CDmeClip* ppParents[1024];
  542. int nCount = BuildReferringClipList( pCurrent, ppParents, 1024 );
  543. for ( int i = 0; i < nCount; ++i )
  544. {
  545. // Can we find a path to the root through the shot? We succeeded!
  546. if ( BuildClipStack_R( pMovie, pShot, ppParents[i] ) )
  547. return true;
  548. }
  549. }
  550. // This clip didn't work out for us. Remove it.
  551. RemoveClip( nIndex );
  552. return false;
  553. }
  554. bool DmeClipStack_t::BuildClipStack( const CDmeClip *pMovie, const CDmeClip *pShot, const CDmeClip *pClip )
  555. {
  556. // Walk through each shot in the movie and look for the subClip, if don't find it recurse into each shot
  557. RemoveAll();
  558. return BuildClipStack_R( pMovie, pShot, pClip );
  559. }
  560. int DmeClipStack_t::FindClip( const CDmeClip *pClip ) const
  561. {
  562. if ( !pClip )
  563. return m_clips.InvalidIndex();
  564. return m_clips.Find( pClip->GetHandle() );
  565. }
  566. int DmeClipStack_t::AddClipToHead( const CDmeClip *pClip )
  567. {
  568. if ( !pClip )
  569. return m_clips.InvalidIndex();
  570. m_bOptimized = false;
  571. return m_clips.AddToHead( pClip->GetHandle() );
  572. }
  573. int DmeClipStack_t::AddClipToTail( const CDmeClip *pClip )
  574. {
  575. if ( !pClip )
  576. return m_clips.InvalidIndex();
  577. m_bOptimized = false;
  578. return m_clips.AddToTail( pClip->GetHandle() );
  579. }
  580. //#define TEST_CLIP_STACK_OPTIMIZER
  581. void DmeClipStack_t::Optimize() const
  582. {
  583. m_bOptimized = true;
  584. int nClips = m_clips.Count();
  585. if ( nClips == 0 )
  586. {
  587. m_tStart = m_tOffset = DMETIME_MINTIME + DMETIME_MAXTIME / 2; // HACK
  588. m_tDuration = DMETIME_MAXTIME;
  589. m_flScale = 1.0f;
  590. return;
  591. }
  592. // 0 = global, n-1 = local
  593. #ifdef TEST_CLIP_STACK_OPTIMIZER
  594. DmeTime_t tOptimizedClamped0 = DMETIME_ZERO;
  595. DmeTime_t tTimeFrameClamped0 = DMETIME_ZERO;
  596. DmeTime_t tOptimizedUnclamped0 = DMETIME_ZERO;
  597. DmeTime_t tTimeFrameUnclamped0 = DMETIME_ZERO;
  598. DmeTime_t tOptimizedClamped1 = DmeTime_t( 10000 );
  599. DmeTime_t tTimeFrameClamped1 = DmeTime_t( 10000 );
  600. DmeTime_t tOptimizedUnclamped1 = DmeTime_t( 10000 );
  601. DmeTime_t tTimeFrameUnclamped1 = DmeTime_t( 10000 );
  602. #endif
  603. const CDmeClip *pClip = m_clips[ nClips - 1 ];
  604. m_tStart = pClip->GetStartTime();
  605. m_tOffset = pClip->GetTimeOffset();
  606. m_tDuration = pClip->GetDuration();
  607. m_flScale = pClip->GetTimeScale();
  608. #ifdef TEST_CLIP_STACK_OPTIMIZER
  609. tOptimizedClamped0 = FromChildMediaTime( DMETIME_ZERO, true );
  610. tTimeFrameClamped0 = pClip->FromChildMediaTime( tTimeFrameClamped0, true );
  611. Assert( tOptimizedClamped0 == tTimeFrameClamped0 );
  612. tOptimizedUnclamped0 = FromChildMediaTime( DMETIME_ZERO, false );
  613. tTimeFrameUnclamped0 = pClip->FromChildMediaTime( tTimeFrameUnclamped0, false );
  614. Assert( tOptimizedUnclamped0 == tTimeFrameUnclamped0 );
  615. tOptimizedClamped1 = FromChildMediaTime( DmeTime_t( 10000 ), true );
  616. tTimeFrameClamped1 = pClip->FromChildMediaTime( tTimeFrameClamped1, true );
  617. Assert( tOptimizedClamped1 == tTimeFrameClamped1 );
  618. tOptimizedUnclamped1 = FromChildMediaTime( DmeTime_t( 10000 ), false );
  619. tTimeFrameUnclamped1 = pClip->FromChildMediaTime( tTimeFrameUnclamped1, false );
  620. Assert( tOptimizedUnclamped1 == tTimeFrameUnclamped1 );
  621. #endif
  622. for ( int i = nClips - 2; i > 0; --i )
  623. {
  624. const CDmeClip *pClip = m_clips[ i ];
  625. #ifdef TEST_CLIP_STACK_OPTIMIZER
  626. DmeTime_t tOldStart = m_tStart;
  627. DmeTime_t tOldOffset = m_tOffset;
  628. DmeTime_t tOldDuration = m_tDuration;
  629. float flOldScale = m_flScale;
  630. DmeTime_t tClipStart = pClip->GetStartTime();
  631. DmeTime_t tClipOffset = pClip->GetTimeOffset();
  632. DmeTime_t tClipDuration = pClip->GetDuration();
  633. float flClipSCale = pClip->GetTimeScale();
  634. #endif
  635. DmeTime_t tChildStartInParentTime = pClip->FromChildMediaTime( m_tStart, false );
  636. DmeTime_t tChildOffsetInParentTime = pClip->FromChildMediaDuration( m_tOffset );
  637. DmeTime_t tChildDurationInParentTime = pClip->FromChildMediaDuration( m_tDuration );
  638. DmeTime_t tChildEndInParentTime = tChildStartInParentTime + tChildDurationInParentTime;
  639. m_flScale = pClip->GetTimeScale() * m_flScale;
  640. m_tStart = MAX( tChildStartInParentTime, pClip->GetStartTime() );
  641. DmeTime_t tDiff = tChildStartInParentTime - m_tStart;
  642. m_tOffset = tChildOffsetInParentTime - tDiff;
  643. DmeTime_t tEnd = MIN( tChildEndInParentTime, pClip->GetEndTime() );
  644. m_tDuration = MAX( DMETIME_ZERO, tEnd - m_tStart );
  645. #ifdef TEST_CLIP_STACK_OPTIMIZER
  646. tOptimizedClamped0 = FromChildMediaTime( DMETIME_ZERO, true );
  647. tTimeFrameClamped0 = pClip->FromChildMediaTime( tTimeFrameClamped0, true );
  648. Assert( tOptimizedClamped0 == tTimeFrameClamped0 );
  649. tOptimizedUnclamped0 = FromChildMediaTime( DMETIME_ZERO, false );
  650. tTimeFrameUnclamped0 = pClip->FromChildMediaTime( tTimeFrameUnclamped0, false );
  651. Assert( tOptimizedUnclamped0 == tTimeFrameUnclamped0 );
  652. tOptimizedClamped1 = FromChildMediaTime( DmeTime_t( 10000 ), true );
  653. tTimeFrameClamped1 = pClip->FromChildMediaTime( tTimeFrameClamped1, true );
  654. Assert( tOptimizedClamped1 == tTimeFrameClamped1 );
  655. tOptimizedUnclamped1 = FromChildMediaTime( DmeTime_t( 10000 ), false );
  656. tTimeFrameUnclamped1 = pClip->FromChildMediaTime( tTimeFrameUnclamped1, false );
  657. Assert( tOptimizedUnclamped1 == tTimeFrameUnclamped1 );
  658. #endif
  659. }
  660. }
  661. DmeTime_t DmeClipStack_t::ToChildMediaTime( DmeTime_t t, bool bClamp /*=true*/ ) const
  662. {
  663. if ( !m_bOptimized )
  664. {
  665. Optimize();
  666. }
  667. t -= m_tStart;
  668. if ( bClamp )
  669. {
  670. t.Clamp( DMETIME_ZERO, m_tDuration );
  671. }
  672. return ( t + m_tOffset ) * m_flScale;
  673. }
  674. DmeTime_t DmeClipStack_t::FromChildMediaTime( DmeTime_t t, bool bClamp /*=true*/ ) const
  675. {
  676. if ( !m_bOptimized )
  677. {
  678. Optimize();
  679. }
  680. t = t / m_flScale - m_tOffset;
  681. if ( bClamp )
  682. {
  683. t.Clamp( DMETIME_ZERO, m_tDuration );
  684. }
  685. return t + m_tStart;
  686. }
  687. DmeTime_t DmeClipStack_t::ToChildMediaDuration( DmeTime_t t ) const
  688. {
  689. if ( !m_bOptimized )
  690. {
  691. Optimize();
  692. }
  693. return t * m_flScale;
  694. }
  695. DmeTime_t DmeClipStack_t::FromChildMediaDuration( DmeTime_t t ) const
  696. {
  697. if ( !m_bOptimized )
  698. {
  699. Optimize();
  700. }
  701. return t / m_flScale;
  702. }
  703. void DmeClipStack_t::ToChildMediaTime( TimeSelection_t &params ) const
  704. {
  705. for ( int i = 0; i < TS_TIME_COUNT; ++i )
  706. {
  707. params.m_Times[i] = ToChildMediaTime( params.m_Times[i], false );
  708. }
  709. }
  710. //-----------------------------------------------------------------------------
  711. //
  712. // CDmeSoundClip - timeframe view into a dmesound
  713. //
  714. //-----------------------------------------------------------------------------
  715. IMPLEMENT_ELEMENT_FACTORY( DmeSoundClip, CDmeSoundClip );
  716. void CDmeSoundClip::OnConstruction()
  717. {
  718. m_Sound.Init( this, "sound" );
  719. m_bShowWave.InitAndSet( this, "showwave", false );
  720. m_fadeInDuration .InitAndSet( this, "fadeIn", DMETIME_ZERO );
  721. m_fadeOutDuration.InitAndSet( this, "fadeOut", DMETIME_ZERO );
  722. }
  723. void CDmeSoundClip::OnDestruction()
  724. {
  725. }
  726. void CDmeSoundClip::SetShowWave( bool state )
  727. {
  728. m_bShowWave = state;
  729. }
  730. bool CDmeSoundClip::ShouldShowWave( ) const
  731. {
  732. return m_bShowWave;
  733. }
  734. float CDmeSoundClip::GetVolumeFade( DmeTime_t tParent )
  735. {
  736. float fade = 1.0f;
  737. if ( tParent < GetStartTime() + m_fadeInDuration )
  738. {
  739. fade = ( tParent - GetStartTime() ) / m_fadeInDuration;
  740. }
  741. if ( tParent > GetEndTime() - m_fadeOutDuration )
  742. {
  743. fade = MIN( fade, ( GetEndTime() - tParent ) / m_fadeOutDuration );
  744. }
  745. return fade;
  746. }
  747. void CDmeSoundClip::BakeTimeScale( float scale /*= 1.0f*/ )
  748. {
  749. float flNewScale = scale * GetTimeScale();
  750. float flInvScale = 1.0f / flNewScale;
  751. m_fadeInDuration *= flInvScale;
  752. m_fadeOutDuration *= flInvScale;
  753. BaseClass::BakeTimeScale( scale );
  754. }
  755. //-----------------------------------------------------------------------------
  756. // CDmeChannelsClip - timeframe view into a set of channels
  757. //-----------------------------------------------------------------------------
  758. IMPLEMENT_ELEMENT_FACTORY( DmeChannelsClip, CDmeChannelsClip );
  759. void CDmeChannelsClip::OnConstruction()
  760. {
  761. m_Channels.Init( this, "channels" );
  762. }
  763. void CDmeChannelsClip::OnDestruction()
  764. {
  765. }
  766. bool IsParticleSystemChannelsClip( CDmeChannelsClip *pChannelsClip )
  767. {
  768. int nChannels = pChannelsClip->m_Channels.Count();
  769. for ( int i = 0; i < nChannels; ++i )
  770. {
  771. CDmeChannel *pChannel = pChannelsClip->m_Channels[ i ];
  772. if ( !pChannel )
  773. continue;
  774. CDmElement *pToElement = pChannel->GetToElement();
  775. if ( !pToElement )
  776. continue;
  777. if ( !V_stricmp( pToElement->GetTypeString(), "DmeGameParticleSystem" ) )
  778. return true;
  779. CDmeTransform *pTransform = CastElement< CDmeTransform >( pToElement );
  780. if ( !pTransform )
  781. continue;
  782. CUtlVector< CDmeDag* > dags;
  783. FindAncestorsReferencingElement( pTransform, dags );
  784. int nDags = dags.Count();
  785. for ( int i = 0; i < nDags; ++i )
  786. {
  787. if ( !V_stricmp( dags[ i ]->GetTypeString(), "DmeGameParticleSystem" ) )
  788. return true;
  789. }
  790. }
  791. return false;
  792. }
  793. void CDmeChannelsClip::BakeTimeScale( float scale /*= 1.0f*/ )
  794. {
  795. float flNewScale = scale * GetTimeScale();
  796. // HACK - particle systems can't really be un-scaled in this way, for apparently two reasons:
  797. // 1) we're storing time data in the dmegameparticlesystem (ie in the scene, rather than in clips/channels)
  798. // 2) the game's particle systems appear to be semi-hardcoded in relation to time (so blinking materials don't blink at the scaled rate after baking)
  799. if ( IsParticleSystemChannelsClip( this ) )
  800. {
  801. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  802. tf->SetStartTime ( tf->GetStartTime () / scale );
  803. tf->SetDuration ( tf->GetDuration () / scale );
  804. tf->SetTimeOffset( tf->GetTimeOffset() / scale );
  805. tf->SetTimeScale ( scale );
  806. return; // skip particle system channels clips
  807. }
  808. int nChannels = m_Channels.Count();
  809. for ( int i = 0; i < nChannels; ++i )
  810. {
  811. CDmeChannel *pChannel = m_Channels[ i ];
  812. if ( !pChannel )
  813. continue;
  814. pChannel->ScaleSampleTimes( 1.0f / flNewScale );
  815. }
  816. BaseClass::BakeTimeScale( scale );
  817. }
  818. CDmeChannel *CDmeChannelsClip::CreatePassThruConnection( char const *passThruName,
  819. CDmElement *pFrom, char const *pFromAttribute,
  820. CDmElement *pTo, char const *pToAttribute, int index /*= 0*/ )
  821. {
  822. CDmeChannel *helper = CreateElement< CDmeChannel >( passThruName, GetFileId() );
  823. Assert( helper );
  824. helper->SetMode( CM_PASS );
  825. helper->SetInput( pFrom, pFromAttribute );
  826. helper->SetOutput( pTo, pToAttribute, index );
  827. m_Channels.AddToTail( helper );
  828. return helper;
  829. }
  830. void CDmeChannelsClip::RemoveChannel( CDmeChannel *pChannel )
  831. {
  832. int nCount = m_Channels.Count();
  833. for ( int i = 0; i < nCount; ++i )
  834. {
  835. if ( pChannel == m_Channels[i] )
  836. {
  837. m_Channels.Remove( i );
  838. break;
  839. }
  840. }
  841. }
  842. //-----------------------------------------------------------------------------
  843. // Purpose: Set the mode of all of the channels in the clip
  844. //-----------------------------------------------------------------------------
  845. void CDmeChannelsClip::SetChannelMode( const ChannelMode_t &mode )
  846. {
  847. int nCount = m_Channels.Count();
  848. for ( int i = 0; i < nCount; ++i )
  849. {
  850. CDmeChannel *pChannel = m_Channels[ i ];
  851. if ( pChannel )
  852. {
  853. pChannel->SetMode( mode );
  854. }
  855. }
  856. }
  857. //-----------------------------------------------------------------------------
  858. // Purpose: Operate all of the channels in the clip
  859. //-----------------------------------------------------------------------------
  860. void CDmeChannelsClip::OperateChannels()
  861. {
  862. int nCount = m_Channels.Count();
  863. for ( int i = 0; i < nCount; ++i )
  864. {
  865. CDmeChannel *pChannel = m_Channels[ i ];
  866. if ( pChannel )
  867. {
  868. pChannel->Operate();
  869. }
  870. }
  871. }
  872. //-----------------------------------------------------------------------------
  873. // Purpose: Play all of the channels in the clip
  874. //-----------------------------------------------------------------------------
  875. void CDmeChannelsClip::PlayChannels()
  876. {
  877. int nCount = m_Channels.Count();
  878. for ( int i = 0; i < nCount; ++i )
  879. {
  880. CDmeChannel *pChannel = m_Channels[ i ];
  881. if ( pChannel )
  882. {
  883. pChannel->Play();
  884. }
  885. }
  886. }
  887. //-----------------------------------------------------------------------------
  888. // CDmeFXClip - timeframe view into an effect
  889. //-----------------------------------------------------------------------------
  890. IMPLEMENT_ELEMENT_FACTORY( DmeFXClip, CDmeFXClip );
  891. void CDmeFXClip::OnConstruction()
  892. {
  893. }
  894. void CDmeFXClip::OnDestruction()
  895. {
  896. }
  897. //-----------------------------------------------------------------------------
  898. // Global list of FX clip types
  899. //-----------------------------------------------------------------------------
  900. const char *CDmeFXClip::s_pFXClipTypes[MAX_FXCLIP_TYPES];
  901. const char *CDmeFXClip::s_pFXClipDescriptions[MAX_FXCLIP_TYPES];
  902. int CDmeFXClip::s_nFXClipTypeCount = 0;
  903. void CDmeFXClip::InstallFXClipType( const char *pElementType, const char *pDescription )
  904. {
  905. s_pFXClipTypes[s_nFXClipTypeCount] = pElementType;
  906. s_pFXClipDescriptions[s_nFXClipTypeCount] = pDescription;
  907. ++s_nFXClipTypeCount;
  908. }
  909. int CDmeFXClip::FXClipTypeCount()
  910. {
  911. return s_nFXClipTypeCount;
  912. }
  913. const char *CDmeFXClip::FXClipType( int nIndex )
  914. {
  915. Assert( s_nFXClipTypeCount > nIndex );
  916. return s_pFXClipTypes[nIndex];
  917. }
  918. const char *CDmeFXClip::FXClipDescription( int nIndex )
  919. {
  920. Assert( s_nFXClipTypeCount > nIndex );
  921. return s_pFXClipDescriptions[nIndex];
  922. }
  923. //-----------------------------------------------------------------------------
  924. // CDmeFilmClip - hierarchical clip (movie, sequence or shot) w/ scene info
  925. //-----------------------------------------------------------------------------
  926. IMPLEMENT_ELEMENT_FACTORY( DmeFilmClip, CDmeFilmClip );
  927. void CDmeFilmClip::OnConstruction()
  928. {
  929. m_pRemoteVideoMaterial = NULL;
  930. m_MaterialOverlayEffect.Init( this, "materialOverlay" );
  931. m_MapName.Init( this, "mapname" );
  932. m_Camera.Init( this, "camera" );
  933. m_MonitorCameras.Init( this, "monitorCameras" );
  934. m_nActiveMonitor.InitAndSet( this, "activeMonitor", -1 );
  935. m_Scene.Init( this, "scene" );
  936. m_AVIFile.Init( this, "aviFile", FATTRIB_HAS_CALLBACK );
  937. m_fadeInDuration .InitAndSet( this, "fadeIn", DMETIME_ZERO );
  938. m_fadeOutDuration.InitAndSet( this, "fadeOut", DMETIME_ZERO );
  939. m_Inputs.Init( this, "inputs" );
  940. m_Operators.Init( this, "operators" );
  941. m_bIsUsingCachedVersion.Init( this, "useAviFile", FATTRIB_HAS_CALLBACK );
  942. m_AnimationSets.Init( this, "animationSets" );
  943. m_BookmarkSets.Init( this, "bookmarkSets" );
  944. m_nActiveBookmarkSet.Init(this, "activeBookmarkSet", 0 );
  945. m_FilmTrackGroup.Init( this, "subClipTrackGroup", FATTRIB_HAS_CALLBACK );
  946. m_Volume.InitAndSet( this, "volume", 1.0);
  947. m_ConCommands.Init( this, "concommands" );
  948. m_ConVars.Init( this, "convars" );
  949. m_hCachedVersion = AVIMATERIAL_INVALID;
  950. m_bIsUsingCachedVersion = false;
  951. m_bReloadCachedVersion = false;
  952. m_CameraStack.Init( this, "camerastack" );
  953. m_nCurrentStackCamera = 0;
  954. }
  955. void CDmeFilmClip::OnDestruction()
  956. {
  957. AssignRemoteVideoMaterial( NULL );
  958. if ( m_hCachedVersion != AVIMATERIAL_INVALID )
  959. {
  960. g_pAVI->DestroyAVIMaterial( m_hCachedVersion );
  961. m_hCachedVersion = AVIMATERIAL_INVALID;
  962. }
  963. PurgeCameraStack();
  964. }
  965. void CDmeFilmClip::BakeTimeScale( float scale /*= 1.0f*/ )
  966. {
  967. float flNewScale = scale * GetTimeScale();
  968. float flInvScale = 1.0f / flNewScale;
  969. int nBookmarkSets = m_BookmarkSets.Count();
  970. for ( int i = 0; i < nBookmarkSets; ++i )
  971. {
  972. CDmeBookmarkSet *pBookmarkSet = m_BookmarkSets[ i ];
  973. if ( !pBookmarkSet )
  974. continue;
  975. pBookmarkSet->ScaleBookmarkTimes( flInvScale );
  976. }
  977. m_fadeInDuration *= flInvScale;
  978. m_fadeOutDuration *= flInvScale;
  979. if ( CDmeTrack *pTrack = GetFilmTrack() )
  980. {
  981. int nClips = pTrack->GetClipCount();
  982. for ( int i = 0; i < nClips; ++i )
  983. {
  984. CDmeClip *pClip = pTrack->GetClip( i );
  985. if ( !pClip )
  986. continue;
  987. pClip->BakeTimeScale( flNewScale );
  988. }
  989. }
  990. BaseClass::BakeTimeScale( scale );
  991. }
  992. //-----------------------------------------------------------------------------
  993. // Returns the special film track group
  994. //-----------------------------------------------------------------------------
  995. CDmeTrackGroup *CDmeFilmClip::GetFilmTrackGroup() const
  996. {
  997. return m_FilmTrackGroup;
  998. }
  999. //-----------------------------------------------------------------------------
  1000. // Returns the special film track
  1001. //-----------------------------------------------------------------------------
  1002. CDmeTrack *CDmeFilmClip::GetFilmTrack() const
  1003. {
  1004. CDmeTrackGroup *pTrackGroup = m_FilmTrackGroup.GetElement();
  1005. if ( pTrackGroup )
  1006. return pTrackGroup->GetFilmTrack();
  1007. return NULL;
  1008. }
  1009. CDmeTrackGroup *CDmeFilmClip::FindOrCreateFilmTrackGroup()
  1010. {
  1011. if ( !m_FilmTrackGroup )
  1012. {
  1013. m_FilmTrackGroup = CreateElement< CDmeTrackGroup >( "subClipTrackGroup", GetFileId() );
  1014. m_FilmTrackGroup->SetMinimized( false );
  1015. m_FilmTrackGroup->SetMaxTrackCount( 1 );
  1016. }
  1017. return m_FilmTrackGroup;
  1018. }
  1019. CDmeTrack *CDmeFilmClip::FindOrCreateFilmTrack()
  1020. {
  1021. CDmeTrackGroup *pTrackGroup = FindOrCreateFilmTrackGroup();
  1022. CDmeTrack *pTrack = pTrackGroup->GetFilmTrack();
  1023. return pTrack ? pTrack : m_FilmTrackGroup->CreateFilmTrack();
  1024. }
  1025. //-----------------------------------------------------------------------------
  1026. // Finding clips in track groups
  1027. //-----------------------------------------------------------------------------
  1028. CDmeTrack *CDmeFilmClip::FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup /*= NULL*/ ) const
  1029. {
  1030. if ( m_FilmTrackGroup.GetElement() )
  1031. {
  1032. CDmeTrack *pTrack = m_FilmTrackGroup->FindTrackForClip( pClip );
  1033. if ( pTrack )
  1034. {
  1035. if ( ppTrackGroup )
  1036. {
  1037. *ppTrackGroup = m_FilmTrackGroup;
  1038. }
  1039. return pTrack;
  1040. }
  1041. }
  1042. return CDmeClip::FindTrackForClip( pClip, ppTrackGroup );
  1043. }
  1044. //-----------------------------------------------------------------------------
  1045. // Finding clips in tracks by time
  1046. //-----------------------------------------------------------------------------
  1047. void CDmeFilmClip::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  1048. {
  1049. if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) )
  1050. {
  1051. if ( m_FilmTrackGroup )
  1052. {
  1053. m_FilmTrackGroup->FindClipsAtTime( clipType, time, flags, clips );
  1054. }
  1055. }
  1056. CDmeClip::FindClipsAtTime( clipType, time, flags, clips );
  1057. }
  1058. void CDmeFilmClip::FindClipsIntersectingTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  1059. {
  1060. if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) )
  1061. {
  1062. if ( m_FilmTrackGroup )
  1063. {
  1064. m_FilmTrackGroup->FindClipsIntersectingTime( clipType, startTime, endTime, flags, clips );
  1065. }
  1066. }
  1067. CDmeClip::FindClipsIntersectingTime( clipType, startTime, endTime, flags, clips );
  1068. }
  1069. void CDmeFilmClip::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  1070. {
  1071. if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) )
  1072. {
  1073. if ( m_FilmTrackGroup )
  1074. {
  1075. m_FilmTrackGroup->FindClipsWithinTime( clipType, startTime, endTime, flags, clips );
  1076. }
  1077. }
  1078. CDmeClip::FindClipsWithinTime( clipType, startTime, endTime, flags, clips );
  1079. }
  1080. //-----------------------------------------------------------------------------
  1081. // Volume
  1082. //-----------------------------------------------------------------------------
  1083. void CDmeFilmClip::SetVolume( float state )
  1084. {
  1085. m_Volume = state;
  1086. }
  1087. float CDmeFilmClip::GetVolume() const
  1088. {
  1089. return m_Volume.Get();
  1090. }
  1091. int CDmeFilmClip::GetConCommandCount() const
  1092. {
  1093. return m_ConCommands.Count();
  1094. }
  1095. const char *CDmeFilmClip::GetConCommand( int i ) const
  1096. {
  1097. return m_ConCommands[ i ];
  1098. }
  1099. int CDmeFilmClip::GetConVarCount() const
  1100. {
  1101. return m_ConVars.Count();
  1102. }
  1103. const char *CDmeFilmClip::GetConVar( int i ) const
  1104. {
  1105. return m_ConVars[ i ];
  1106. }
  1107. //-----------------------------------------------------------------------------
  1108. // mapname helper methods
  1109. //-----------------------------------------------------------------------------
  1110. const char *CDmeFilmClip::GetMapName()
  1111. {
  1112. return m_MapName.Get();
  1113. }
  1114. void CDmeFilmClip::SetMapName( const char *pMapName )
  1115. {
  1116. m_MapName.Set( pMapName );
  1117. }
  1118. //-----------------------------------------------------------------------------
  1119. // Attribute changed
  1120. //-----------------------------------------------------------------------------
  1121. void CDmeFilmClip::OnAttributeChanged( CDmAttribute *pAttribute )
  1122. {
  1123. BaseClass::OnAttributeChanged( pAttribute );
  1124. if ( pAttribute == m_FilmTrackGroup.GetAttribute() )
  1125. {
  1126. if ( m_FilmTrackGroup.GetElement() )
  1127. {
  1128. m_FilmTrackGroup->SetMaxTrackCount( 1 );
  1129. }
  1130. }
  1131. else if ( pAttribute->GetOwner() == m_TimeFrame.GetElement() )
  1132. {
  1133. InvokeOnAttributeChangedOnReferrers( GetHandle(), pAttribute );
  1134. }
  1135. else if( pAttribute == m_bIsUsingCachedVersion.GetAttribute() || pAttribute == m_AVIFile.GetAttribute() )
  1136. {
  1137. // video caching info has changed ...
  1138. UpdateRemoteVideoMaterialStatus();
  1139. }
  1140. }
  1141. //-----------------------------------------------------------------------------
  1142. // methods for dealing with remote cached video
  1143. //-----------------------------------------------------------------------------
  1144. void CDmeFilmClip::AssignRemoteVideoMaterial( IRemoteVideoMaterial *theMaterial )
  1145. {
  1146. if ( theMaterial == m_pRemoteVideoMaterial ) return; // no change
  1147. // ok, release any previous material
  1148. if ( m_pRemoteVideoMaterial != NULL )
  1149. {
  1150. m_pRemoteVideoMaterial->Release();
  1151. }
  1152. // assign the new material
  1153. m_pRemoteVideoMaterial = theMaterial;
  1154. }
  1155. void CDmeFilmClip::UpdateRemoteVideoMaterialStatus()
  1156. {
  1157. // is the quicktime Video caching service available? If not, we don't do anything...
  1158. if ( m_pRemoteVideoMaterial == NULL || !m_pRemoteVideoMaterial->IsInitialized() )
  1159. {
  1160. return;
  1161. }
  1162. // are we selecting to not used cached video?
  1163. if ( m_bIsUsingCachedVersion == false )
  1164. {
  1165. // check to see if we've gone from using cached video for this clip to off
  1166. if ( m_pRemoteVideoMaterial->IsRemoteVideoAvailable() && m_pRemoteVideoMaterial->IsConnectedToRemoteVideo() )
  1167. {
  1168. // turn off video caching for the specified clip
  1169. m_pRemoteVideoMaterial->DisconnectFromRemoteVideo();
  1170. }
  1171. return;
  1172. }
  1173. // ok, we've selected to use a remotely cached video. If the filename is setup correctly
  1174. // this should attempt to connect to the remote video
  1175. m_pRemoteVideoMaterial->ConnectToRemoteVideo( m_AVIFile.Get() );
  1176. }
  1177. bool CDmeFilmClip::HasRemoteVideo()
  1178. {
  1179. // if we don't have a working connection, say we don't have any video
  1180. return ( ( m_pRemoteVideoMaterial == NULL ) ? false : m_pRemoteVideoMaterial->IsRemoteVideoAvailable() );
  1181. }
  1182. bool CDmeFilmClip::GetCachedQTVideoFrameAt( float theTime )
  1183. {
  1184. if ( m_pRemoteVideoMaterial == NULL ) return false;
  1185. return m_pRemoteVideoMaterial->GetRemoteVideoFrame( theTime );
  1186. }
  1187. IMaterial* CDmeFilmClip::GetRemoteVideoMaterial()
  1188. {
  1189. return ( m_pRemoteVideoMaterial == NULL ) ? NULL : m_pRemoteVideoMaterial->GetRemoteVideoFrameMaterial();
  1190. }
  1191. void CDmeFilmClip::GetRemoteVideoMaterialTexCoordRange( float *u, float *v )
  1192. {
  1193. if ( m_pRemoteVideoMaterial == NULL )
  1194. {
  1195. *u = 0.0f;
  1196. *v = 0.0f;
  1197. }
  1198. else
  1199. {
  1200. m_pRemoteVideoMaterial->GetRemoteVideoFrameTextureCoordRange( *u, *v );
  1201. }
  1202. }
  1203. void CDmeFilmClip::OnElementUnserialized()
  1204. {
  1205. BaseClass::OnElementUnserialized();
  1206. CDmeTrackGroup *pFilmTrackGroup = m_FilmTrackGroup.GetElement();
  1207. if ( pFilmTrackGroup )
  1208. {
  1209. pFilmTrackGroup->SetMaxTrackCount( 1 );
  1210. if ( pFilmTrackGroup->GetTrackCount() == 0 )
  1211. {
  1212. pFilmTrackGroup->CreateFilmTrack();
  1213. }
  1214. }
  1215. }
  1216. //-----------------------------------------------------------------------------
  1217. // Resolve
  1218. //-----------------------------------------------------------------------------
  1219. void CDmeFilmClip::Resolve()
  1220. {
  1221. BaseClass::Resolve();
  1222. if ( m_AVIFile.IsDirty() )
  1223. {
  1224. m_bReloadCachedVersion = true;
  1225. m_AVIFile.GetAttribute()->RemoveFlag( FATTRIB_DIRTY );
  1226. }
  1227. }
  1228. //-----------------------------------------------------------------------------
  1229. // Helper for overlays
  1230. //-----------------------------------------------------------------------------
  1231. void CDmeFilmClip::SetOverlay( const char *pMaterialName )
  1232. {
  1233. if ( pMaterialName && pMaterialName[0] )
  1234. {
  1235. if ( !m_MaterialOverlayEffect.GetElement() )
  1236. {
  1237. m_MaterialOverlayEffect = CreateElement<CDmeMaterialOverlayFXClip>( "materialOverlay", GetFileId() );
  1238. }
  1239. m_MaterialOverlayEffect->SetOverlayEffect( pMaterialName );
  1240. }
  1241. else
  1242. {
  1243. m_MaterialOverlayEffect.Set( NULL );
  1244. }
  1245. }
  1246. IMaterial *CDmeFilmClip::GetOverlayMaterial()
  1247. {
  1248. return m_MaterialOverlayEffect.GetElement() ? m_MaterialOverlayEffect->GetMaterial() : NULL;
  1249. }
  1250. float CDmeFilmClip::GetOverlayAlpha()
  1251. {
  1252. return m_MaterialOverlayEffect.GetElement() ? m_MaterialOverlayEffect->GetAlpha() : 0.0f;
  1253. }
  1254. void CDmeFilmClip::SetOverlayAlpha( float alpha )
  1255. {
  1256. if ( m_MaterialOverlayEffect.GetElement() )
  1257. {
  1258. m_MaterialOverlayEffect->SetAlpha( alpha );
  1259. }
  1260. }
  1261. bool CDmeFilmClip::HasOpaqueOverlay( void )
  1262. {
  1263. if ( m_MaterialOverlayEffect->GetMaterial()->IsTranslucent() ||
  1264. ( m_MaterialOverlayEffect->GetAlpha() < 1.0f ) )
  1265. {
  1266. return false;
  1267. }
  1268. return true;
  1269. }
  1270. void CDmeFilmClip::DrawOverlay( DmeTime_t time, Rect_t &currentRect, Rect_t &totalRect )
  1271. {
  1272. if ( m_MaterialOverlayEffect.GetElement() )
  1273. {
  1274. m_MaterialOverlayEffect->ApplyEffect( ToChildMediaTime( time ), currentRect, totalRect, NULL );
  1275. }
  1276. float fade = 1.0f;
  1277. if ( time < GetStartTime() + m_fadeInDuration )
  1278. {
  1279. fade = ( time - GetStartTime() ) / m_fadeInDuration;
  1280. }
  1281. if ( time > GetEndTime() - m_fadeOutDuration )
  1282. {
  1283. fade = MIN( fade, ( GetEndTime() - time ) / m_fadeOutDuration );
  1284. }
  1285. if ( fade < 1.0f )
  1286. {
  1287. if ( !m_FadeMaterial.IsValid() )
  1288. {
  1289. m_FadeMaterial.Init( "engine\\singlecolor.vmt", NULL, false );
  1290. }
  1291. float r, g, b;
  1292. m_FadeMaterial->GetColorModulation( &r, &g, &b );
  1293. float a = m_FadeMaterial->GetAlphaModulation();
  1294. m_FadeMaterial->ColorModulate( 0.0f, 0.0f, 0.0f );
  1295. m_FadeMaterial->AlphaModulate( 1.0f - fade );
  1296. CMatRenderContextPtr pRenderContext( materials );
  1297. pRenderContext->Bind( m_FadeMaterial );
  1298. float w = currentRect.width;
  1299. float h = currentRect.height;
  1300. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  1301. CMeshBuilder meshBuilder;
  1302. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );
  1303. meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
  1304. meshBuilder.AdvanceVertexF<VTX_HAVEPOS, 0>();
  1305. meshBuilder.Position3f( 0.0f, h, 0.0f );
  1306. meshBuilder.AdvanceVertexF<VTX_HAVEPOS, 0>();
  1307. meshBuilder.Position3f( w, 0.0f, 0.0f );
  1308. meshBuilder.AdvanceVertexF<VTX_HAVEPOS, 0>();
  1309. meshBuilder.Position3f( w, h, 0.0f );
  1310. meshBuilder.AdvanceVertexF<VTX_HAVEPOS, 0>();
  1311. meshBuilder.End();
  1312. pMesh->Draw();
  1313. m_FadeMaterial->ColorModulate( r, g, b );
  1314. m_FadeMaterial->AlphaModulate( a );
  1315. }
  1316. }
  1317. //-----------------------------------------------------------------------------
  1318. // AVI tape out
  1319. //-----------------------------------------------------------------------------
  1320. void CDmeFilmClip::UseCachedVersion( bool bUseCachedVersion )
  1321. {
  1322. m_bIsUsingCachedVersion = bUseCachedVersion;
  1323. }
  1324. bool CDmeFilmClip::IsUsingCachedVersion() const
  1325. {
  1326. return m_bIsUsingCachedVersion;
  1327. }
  1328. AVIMaterial_t CDmeFilmClip::GetCachedAVI()
  1329. {
  1330. if ( m_bReloadCachedVersion )
  1331. {
  1332. if ( g_pAVI )
  1333. {
  1334. if ( m_hCachedVersion != AVIMATERIAL_INVALID )
  1335. {
  1336. g_pAVI->DestroyAVIMaterial( m_hCachedVersion );
  1337. m_hCachedVersion = AVIMATERIAL_INVALID;
  1338. }
  1339. if ( m_AVIFile[0] )
  1340. {
  1341. m_hCachedVersion = g_pAVI->CreateAVIMaterial( m_AVIFile, m_AVIFile, "MOD" );
  1342. }
  1343. }
  1344. m_bReloadCachedVersion = false;
  1345. }
  1346. return m_hCachedVersion;
  1347. }
  1348. void CDmeFilmClip::SetCachedAVI( const char *pAVIFile )
  1349. {
  1350. m_AVIFile = pAVIFile;
  1351. m_bReloadCachedVersion = true;
  1352. }
  1353. //-----------------------------------------------------------------------------
  1354. // Camera helper methods
  1355. //-----------------------------------------------------------------------------
  1356. CDmeCamera *CDmeFilmClip::GetCamera()
  1357. {
  1358. return m_Camera;
  1359. }
  1360. void CDmeFilmClip::SetCamera( CDmeCamera *pCamera )
  1361. {
  1362. m_Camera = pCamera;
  1363. }
  1364. //-----------------------------------------------------------------------------
  1365. // Returns the monitor camera associated with the clip (for now, only 1 supported)
  1366. //-----------------------------------------------------------------------------
  1367. CDmeCamera *CDmeFilmClip::GetMonitorCamera()
  1368. {
  1369. if ( m_nActiveMonitor < 0 )
  1370. return NULL;
  1371. return m_MonitorCameras[ m_nActiveMonitor ];
  1372. }
  1373. void CDmeFilmClip::AddMonitorCamera( CDmeCamera *pCamera )
  1374. {
  1375. m_MonitorCameras.AddToTail( pCamera );
  1376. }
  1377. int CDmeFilmClip::FindMonitorCamera( CDmeCamera *pCamera )
  1378. {
  1379. return m_MonitorCameras.Find( pCamera->GetHandle() );
  1380. }
  1381. void CDmeFilmClip::RemoveMonitorCamera( CDmeCamera *pCamera )
  1382. {
  1383. int i = m_MonitorCameras.Find( pCamera->GetHandle() );
  1384. if ( i >= 0 )
  1385. {
  1386. if ( m_nActiveMonitor == i )
  1387. {
  1388. m_nActiveMonitor = -1;
  1389. }
  1390. m_MonitorCameras.FastRemove( i );
  1391. }
  1392. }
  1393. void CDmeFilmClip::SelectMonitorCamera( CDmeCamera *pCamera )
  1394. {
  1395. m_nActiveMonitor = pCamera ? m_MonitorCameras.Find( pCamera->GetHandle() ) : -1;
  1396. }
  1397. //-----------------------------------------------------------------------------
  1398. // Scene / Dag helper methods
  1399. //-----------------------------------------------------------------------------
  1400. CDmeDag *CDmeFilmClip::GetScene( bool bCreateIfNull /*= false*/ )
  1401. {
  1402. CDmeDag *pScene = m_Scene.GetElement();
  1403. if ( !pScene && bCreateIfNull )
  1404. {
  1405. pScene = CreateElement< CDmeDag >( "scene", GetFileId() );
  1406. m_Scene = pScene;
  1407. }
  1408. return pScene;
  1409. }
  1410. void CDmeFilmClip::SetScene( CDmeDag *pDag )
  1411. {
  1412. m_Scene.Set( pDag );
  1413. }
  1414. //-----------------------------------------------------------------------------
  1415. // helper for inputs and operators
  1416. //-----------------------------------------------------------------------------
  1417. int CDmeFilmClip::GetInputCount()
  1418. {
  1419. return m_Inputs.Count();
  1420. }
  1421. CDmeInput *CDmeFilmClip::GetInput( int nIndex )
  1422. {
  1423. if ( nIndex < 0 || nIndex >= m_Inputs.Count() )
  1424. return NULL;
  1425. return m_Inputs[ nIndex ];
  1426. }
  1427. void CDmeFilmClip::AddInput( CDmeInput *pInput )
  1428. {
  1429. m_Inputs.AddToTail( pInput );
  1430. }
  1431. void CDmeFilmClip::RemoveAllInputs()
  1432. {
  1433. m_Inputs.RemoveAll();
  1434. }
  1435. void CDmeFilmClip::AddOperator( CDmeOperator *pOperator )
  1436. {
  1437. m_Operators.AddToTail( pOperator );
  1438. }
  1439. void CDmeFilmClip::RemoveOperator( CDmeOperator *pOperator )
  1440. {
  1441. for ( int i = m_Operators.Count() - 1 ; i >= 0; --i )
  1442. {
  1443. if ( m_Operators[ i ] == pOperator )
  1444. {
  1445. m_Operators.Remove( i );
  1446. }
  1447. }
  1448. }
  1449. void CDmeFilmClip::CollectOperators( CUtlVector< DmElementHandle_t > &operators )
  1450. {
  1451. int numInputs = m_Inputs.Count();
  1452. for ( int i = 0; i < numInputs; ++i )
  1453. {
  1454. operators.AddToTail( m_Inputs[ i ]->GetHandle() );
  1455. }
  1456. int numOperators = m_Operators.Count();
  1457. for ( int i = 0; i < numOperators; ++i )
  1458. {
  1459. operators.AddToTail( m_Operators[ i ]->GetHandle() );
  1460. }
  1461. }
  1462. CDmaElementArray< CDmeOperator > &CDmeFilmClip::GetOperators()
  1463. {
  1464. return m_Operators;
  1465. }
  1466. CDmaElementArray< CDmeAnimationSet > &CDmeFilmClip::GetAnimationSets()
  1467. {
  1468. return m_AnimationSets;
  1469. }
  1470. const CDmaElementArray< CDmeAnimationSet > &CDmeFilmClip::GetAnimationSets() const
  1471. {
  1472. return m_AnimationSets;
  1473. }
  1474. CDmeAnimationSet *CDmeFilmClip::FindAnimationSet( const char *pAnimSetName ) const
  1475. {
  1476. int nAnimSets = m_AnimationSets.Count();
  1477. for ( int i = 0; i < nAnimSets; ++i )
  1478. {
  1479. CDmeAnimationSet *pAnimSet = m_AnimationSets[ i ];
  1480. if ( !pAnimSet )
  1481. continue;
  1482. if ( V_stricmp( pAnimSet->GetName(), pAnimSetName ) == 0 )
  1483. return pAnimSet;
  1484. }
  1485. return NULL;
  1486. }
  1487. const CDmaElementArray< CDmeBookmarkSet > &CDmeFilmClip::GetBookmarkSets() const
  1488. {
  1489. return m_BookmarkSets;
  1490. }
  1491. CDmaElementArray< CDmeBookmarkSet > &CDmeFilmClip::GetBookmarkSets()
  1492. {
  1493. return m_BookmarkSets;
  1494. }
  1495. int CDmeFilmClip::GetActiveBookmarkSetIndex() const
  1496. {
  1497. return m_nActiveBookmarkSet;
  1498. }
  1499. void CDmeFilmClip::SetActiveBookmarkSetIndex( int nActiveBookmarkSet )
  1500. {
  1501. m_nActiveBookmarkSet = nActiveBookmarkSet;
  1502. }
  1503. CDmeBookmarkSet *CDmeFilmClip::GetActiveBookmarkSet()
  1504. {
  1505. int nBookmarkSets = m_BookmarkSets.Count();
  1506. if ( m_nActiveBookmarkSet >= nBookmarkSets )
  1507. return NULL;
  1508. return m_BookmarkSets[ m_nActiveBookmarkSet ];
  1509. }
  1510. CDmeBookmarkSet *CDmeFilmClip::CreateBookmarkSet( const char *pName /*= "default set"*/ )
  1511. {
  1512. CDmeBookmarkSet *pBookmarkSet = CreateElement< CDmeBookmarkSet >( pName, GetFileId() );
  1513. m_BookmarkSets.AddToTail( pBookmarkSet );
  1514. return pBookmarkSet;
  1515. }
  1516. //-----------------------------------------------------------------------------
  1517. // Used to move clips in non-film track groups with film clips
  1518. // Call BuildClipAssociations before modifying the film track,
  1519. // then UpdateAssociatedClips after modifying it.
  1520. //-----------------------------------------------------------------------------
  1521. void CDmeFilmClip::BuildClipAssociations( CUtlVector< ClipAssociation_t > &association, bool bHandleGaps )
  1522. {
  1523. association.RemoveAll();
  1524. CDmeTrack *pFilmTrack = GetFilmTrack();
  1525. if ( !pFilmTrack )
  1526. return;
  1527. int c = pFilmTrack->GetClipCount();
  1528. int gc = GetTrackGroupCount();
  1529. if ( c == 0 || gc == 0 )
  1530. return;
  1531. DmeTime_t clipStartTime = GetStartInChildMediaTime();
  1532. DmeTime_t clipEndTime = GetEndInChildMediaTime();
  1533. // These slugs will be removed in UpdateAssociatedClips
  1534. if ( bHandleGaps )
  1535. {
  1536. pFilmTrack->FillAllGapsWithSlugs( "__tempSlug__", clipStartTime, clipEndTime );
  1537. }
  1538. for ( int i = 0; i < gc; ++i )
  1539. {
  1540. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  1541. int tc = pTrackGroup->GetTrackCount();
  1542. for ( int j = 0; j < tc; ++j )
  1543. {
  1544. CDmeTrack *pTrack = pTrackGroup->GetTrack( j );
  1545. if ( !pTrack->IsSynched() )
  1546. continue;
  1547. // Only have visible tracks now
  1548. int cc = pTrack->GetClipCount();
  1549. association.EnsureCapacity( association.Count() + cc );
  1550. for ( int k = 0; k < cc; ++k )
  1551. {
  1552. CDmeClip *pClip = pTrack->GetClip( k );
  1553. CDmeClip *pFilmClip = pFilmTrack->FindFilmClipAtTime( pClip->GetStartTime() );
  1554. int nIndex = association.AddToTail();
  1555. association[nIndex].m_hClip = pClip;
  1556. association[nIndex].m_hAssociation = pFilmClip;
  1557. association[nIndex].m_startTimeInAssociatedClip = DMETIME_ZERO;
  1558. association[nIndex].m_offset = DMETIME_ZERO;
  1559. if ( pFilmClip )
  1560. {
  1561. association[nIndex].m_startTimeInAssociatedClip = pFilmClip->ToChildMediaTime( pClip->GetStartTime(), false );
  1562. association[nIndex].m_nType = ClipAssociation_t::HAS_CLIP;
  1563. continue;
  1564. }
  1565. // Handle edge cases
  1566. if ( pClip->GetStartTime() <= clipStartTime )
  1567. {
  1568. association[nIndex].m_offset = pClip->GetStartTime() - clipStartTime;
  1569. association[nIndex].m_nType = ClipAssociation_t::BEFORE_START;
  1570. continue;
  1571. }
  1572. if ( pClip->GetStartTime() >= clipEndTime )
  1573. {
  1574. association[nIndex].m_offset = pClip->GetStartTime() - clipEndTime;
  1575. association[nIndex].m_nType = ClipAssociation_t::AFTER_END;
  1576. continue;
  1577. }
  1578. association[nIndex].m_nType = ClipAssociation_t::NO_MOVEMENT;
  1579. }
  1580. }
  1581. }
  1582. }
  1583. void CDmeFilmClip::UpdateAssociatedClips( CUtlVector< ClipAssociation_t > &association )
  1584. {
  1585. int i;
  1586. CDmeTrack *pFilmTrack = GetFilmTrack();
  1587. if ( !pFilmTrack )
  1588. return;
  1589. int c = association.Count();
  1590. if ( c > 0 )
  1591. {
  1592. DmeTime_t clipStartTime = GetStartInChildMediaTime();
  1593. DmeTime_t clipEndTime = GetEndInChildMediaTime();
  1594. for ( i = 0; i < c; ++i )
  1595. {
  1596. ClipAssociation_t &curr = association[i];
  1597. if ( !curr.m_hClip.Get() )
  1598. continue;
  1599. switch( curr.m_nType )
  1600. {
  1601. case ClipAssociation_t::HAS_CLIP:
  1602. if ( curr.m_hAssociation.Get() )
  1603. {
  1604. curr.m_hClip->SetStartTime( curr.m_hAssociation->FromChildMediaTime( curr.m_startTimeInAssociatedClip, false ) );
  1605. }
  1606. break;
  1607. case ClipAssociation_t::BEFORE_START:
  1608. curr.m_hClip->SetStartTime( clipStartTime + curr.m_offset );
  1609. break;
  1610. case ClipAssociation_t::AFTER_END:
  1611. curr.m_hClip->SetStartTime( clipEndTime + curr.m_offset );
  1612. break;
  1613. }
  1614. }
  1615. }
  1616. c = pFilmTrack->GetClipCount();
  1617. for ( i = c; --i >= 0; )
  1618. {
  1619. CDmeClip *pClip = pFilmTrack->GetClip(i);
  1620. if ( !Q_strcmp( pClip->GetName(), "__tempSlug__" ) )
  1621. {
  1622. pFilmTrack->RemoveClip( i );
  1623. }
  1624. }
  1625. }
  1626. //-----------------------------------------------------------------------------
  1627. // Creates a slug clip
  1628. //-----------------------------------------------------------------------------
  1629. CDmeFilmClip *CreateSlugClip( const char *pClipName, DmeTime_t startTime, DmeTime_t endTime, DmFileId_t fileid )
  1630. {
  1631. CDmeFilmClip *pSlugClip = CreateElement<CDmeFilmClip>( pClipName, fileid );
  1632. pSlugClip->CreateBookmarkSet();
  1633. pSlugClip->GetTimeFrame()->SetName( "timeframe" );
  1634. pSlugClip->SetStartTime( startTime );
  1635. pSlugClip->SetDuration( endTime - startTime );
  1636. pSlugClip->SetTimeOffset( DmeTime_t( 0 ) );
  1637. pSlugClip->SetTimeScale( 1.0f );
  1638. pSlugClip->SetClipColor( Color( 0, 0, 0, 128 ) );
  1639. pSlugClip->SetOverlay( "vgui/black" );
  1640. return pSlugClip;
  1641. }
  1642. //-----------------------------------------------------------------------------
  1643. // helper methods
  1644. //-----------------------------------------------------------------------------
  1645. CDmeTrack *GetParentTrack( CDmeClip *pClip )
  1646. {
  1647. DmAttributeReferenceIterator_t hAttr = g_pDataModel->FirstAttributeReferencingElement( pClip->GetHandle() );
  1648. for ( ; hAttr != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; hAttr = g_pDataModel->NextAttributeReferencingElement( hAttr ) )
  1649. {
  1650. CDmAttribute *pAttr = g_pDataModel->GetAttribute( hAttr );
  1651. if ( !pAttr )
  1652. continue;
  1653. CDmeTrack *pTrack = CastElement< CDmeTrack >( pAttr->GetOwner() );
  1654. if ( pTrack )
  1655. return pTrack;
  1656. }
  1657. return NULL;
  1658. }
  1659. //-----------------------------------------------------------------------------
  1660. // Purpose: Find the channel within targeting the specified element and
  1661. // attribute.
  1662. //-----------------------------------------------------------------------------
  1663. CDmeChannel *FindChannelTargetingElement( CDmElement *pElement, const char *pAttributeName )
  1664. {
  1665. CUtlVector< CDmeChannel* > channels( 0, 8 );
  1666. FindAncestorsReferencingElement( pElement, channels );
  1667. int nChannels = channels.Count();
  1668. for ( int i = 0; i < nChannels; ++i )
  1669. {
  1670. CDmeChannel *pChannel = channels[ i ];
  1671. if ( !pChannel )
  1672. continue;
  1673. CDmElement *toElement = pChannel->GetToElement();
  1674. if ( toElement != pElement )
  1675. continue;
  1676. if ( pAttributeName && ( Q_stricmp( pChannel->GetToAttribute()->GetName(), pAttributeName ) != 0 ) )
  1677. continue;
  1678. return pChannel;
  1679. }
  1680. return NULL;
  1681. }
  1682. //-----------------------------------------------------------------------------
  1683. // Purpose: Find the channel within the specified channels clip targeting the
  1684. // specified element and attribute.
  1685. //-----------------------------------------------------------------------------
  1686. CDmeChannel *FindChannelTargetingElement( CDmeChannelsClip *pChannelsClip, CDmElement *pElement, const char *pAttributeName )
  1687. {
  1688. int nChannels = pChannelsClip->m_Channels.Count();
  1689. for ( int i = 0; i < nChannels; ++i )
  1690. {
  1691. CDmeChannel *pChannel = pChannelsClip->m_Channels[ i ];
  1692. if ( !pChannel )
  1693. continue;
  1694. CDmElement *toElement = pChannel->GetToElement();
  1695. if ( toElement != pElement )
  1696. continue;
  1697. if ( pAttributeName && ( Q_stricmp( pChannel->GetToAttribute()->GetName(), pAttributeName ) != 0 ) )
  1698. continue;
  1699. return pChannel;
  1700. }
  1701. return NULL;
  1702. }
  1703. //-----------------------------------------------------------------------------
  1704. // Purpose: Find the channel within the specified film clip targeting the
  1705. // specified element and attribute.
  1706. //-----------------------------------------------------------------------------
  1707. CDmeChannel *FindChannelTargetingElement( CDmeFilmClip *pClip, CDmElement *pElement, const char *pAttributeName, CDmeChannelsClip **ppChannelsClip, CDmeTrack **ppTrack, CDmeTrackGroup **ppTrackGroup )
  1708. {
  1709. int gc = pClip->GetTrackGroupCount();
  1710. for ( int i = 0; i < gc; ++i )
  1711. {
  1712. CDmeTrackGroup *pTrackGroup = pClip->GetTrackGroup( i );
  1713. DMETRACKGROUP_FOREACH_CLIP_TYPE_START( CDmeChannelsClip, pTrackGroup, pTrack, pChannelsClip )
  1714. CDmeChannel *pChannel = FindChannelTargetingElement( pChannelsClip, pElement, pAttributeName );
  1715. if ( !pChannel )
  1716. continue;
  1717. if ( ppChannelsClip )
  1718. {
  1719. *ppChannelsClip = pChannelsClip;
  1720. }
  1721. if ( ppTrack )
  1722. {
  1723. *ppTrack = pTrack;
  1724. }
  1725. if ( ppTrackGroup )
  1726. {
  1727. *ppTrackGroup = pTrackGroup;
  1728. }
  1729. return pChannel;
  1730. DMETRACKGROUP_FOREACH_CLIP_TYPE_END()
  1731. }
  1732. return NULL;
  1733. }
  1734. //-----------------------------------------------------------------------------
  1735. // Purpose: Construct a clip stack for each one of the channels in the provided
  1736. // list using the specified root movie and shot.
  1737. //-----------------------------------------------------------------------------
  1738. void BuildClipStackList( const CUtlVector< CDmeChannel* > &channelList, CUtlVector< DmeClipStack_t > &clipStackList, CUtlVector< DmeTime_t > &orginalTimeList, const CDmeClip *pMovie, CDmeClip *pShot )
  1739. {
  1740. int nChannels = channelList.Count();
  1741. clipStackList.Purge();
  1742. clipStackList.EnsureCount( nChannels );
  1743. orginalTimeList.Purge();
  1744. orginalTimeList.EnsureCount( nChannels );
  1745. for ( int iChannel = 0; iChannel < nChannels; ++iChannel )
  1746. {
  1747. CDmeChannel *pChannel = channelList[ iChannel ];
  1748. CDmeChannelsClip *pChannelsClip = FindAncestorReferencingElement< CDmeChannelsClip >( pChannel );
  1749. if ( pChannelsClip )
  1750. {
  1751. pChannelsClip->BuildClipStack( &clipStackList[ iChannel ], pMovie, pShot );
  1752. }
  1753. else
  1754. {
  1755. if ( pMovie )
  1756. {
  1757. clipStackList[ iChannel ].AddClipToTail( pMovie );
  1758. }
  1759. if ( pShot && ( pShot != pMovie ) )
  1760. {
  1761. clipStackList[ iChannel ].AddClipToTail( pShot );
  1762. }
  1763. }
  1764. orginalTimeList[ iChannel ] = pChannel->GetCurrentTime();
  1765. }
  1766. }
  1767. //-----------------------------------------------------------------------------
  1768. // Purpose: Play each of the channels in the provided list at the specified
  1769. // global time.
  1770. //-----------------------------------------------------------------------------
  1771. void PlayChannelsAtTime( DmeTime_t time, const CUtlVector< CDmeChannel* > &channelList, const CUtlVector< CDmeOperator* > &operatorList, const CUtlVector< DmeClipStack_t > &clipStackList, bool forcePlay )
  1772. {
  1773. int nCount = channelList.Count();
  1774. for ( int iChannel = 0; iChannel < nCount; ++iChannel )
  1775. {
  1776. CDmeChannel *pChannel = channelList[ iChannel ];
  1777. DmeTime_t localTime = clipStackList[ iChannel ].ToChildMediaTime( time, false );
  1778. pChannel->SetCurrentTime( localTime );
  1779. if ( forcePlay || ( pChannel->GetMode() == CM_RECORD ) )
  1780. {
  1781. pChannel->Play();
  1782. }
  1783. else
  1784. {
  1785. pChannel->Operate();
  1786. }
  1787. }
  1788. int nOperators = operatorList.Count();
  1789. for ( int iOpeator = 0; iOpeator < nOperators; ++iOpeator )
  1790. {
  1791. operatorList[ iOpeator ]->Operate();
  1792. }
  1793. }
  1794. //-----------------------------------------------------------------------------
  1795. // Purpose: Play each of the channels in the provided list at the specified
  1796. // local time.
  1797. //-----------------------------------------------------------------------------
  1798. void PlayChannelsAtLocalTimes( const CUtlVector< DmeTime_t > &timeList, const CUtlVector< CDmeChannel* > &channelList, const CUtlVector< CDmeOperator* > &operatorList, bool forcePlay )
  1799. {
  1800. int nCount = channelList.Count();
  1801. Assert( timeList.Count() >= channelList.Count() );
  1802. if ( timeList.Count() < nCount )
  1803. return;
  1804. for ( int iChannel = 0; iChannel < nCount; ++iChannel )
  1805. {
  1806. CDmeChannel *pChannel = channelList[ iChannel ];
  1807. pChannel->SetCurrentTime( timeList[ iChannel ] );
  1808. if ( forcePlay || ( pChannel->GetMode() == CM_RECORD ) )
  1809. {
  1810. pChannel->Play();
  1811. }
  1812. else
  1813. {
  1814. pChannel->Operate();
  1815. }
  1816. }
  1817. int nOperators = operatorList.Count();
  1818. for ( int iOpeator = 0; iOpeator < nOperators; ++iOpeator )
  1819. {
  1820. operatorList[ iOpeator ]->Operate();
  1821. }
  1822. }
  1823. CDmeFilmClip *FindFilmClipContainingDag( CDmeDag *pDag )
  1824. {
  1825. CDmeFilmClip *pFilmClip = FindReferringElement< CDmeFilmClip >( pDag, "scene" );
  1826. if ( pFilmClip )
  1827. return pFilmClip;
  1828. for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( pDag->GetHandle() );
  1829. it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  1830. it = g_pDataModel->NextAttributeReferencingElement( it ) )
  1831. {
  1832. CDmAttribute *pAttr = g_pDataModel->GetAttribute( it );
  1833. Assert( pAttr );
  1834. static const CUtlSymbolLarge symChildren = g_pDataModel->GetSymbol( "children" );
  1835. if ( pAttr->GetNameSymbol() != symChildren )
  1836. continue;
  1837. CDmeDag* pParent = CastElement< CDmeDag >( pAttr->GetOwner() );
  1838. if ( !pParent )
  1839. continue;
  1840. CDmeFilmClip *pFilmClip = FindFilmClipContainingDag( pParent );
  1841. if ( pFilmClip )
  1842. return pFilmClip;
  1843. }
  1844. return NULL;
  1845. }
  1846. static ConVar sfm_maxcamerastack( "sfm_maxcamerastack", "10", FCVAR_ARCHIVE, "Number of work cameras to store in camera stack." );
  1847. void CDmeFilmClip::LatchWorkCamera( CDmeCamera *pCamera )
  1848. {
  1849. // Wipe everything after current stack ptr
  1850. while ( ( m_CameraStack.Count() - 1 ) > m_nCurrentStackCamera )
  1851. {
  1852. m_CameraStack.Remove( m_CameraStack.Count() - 1 );
  1853. }
  1854. // Add to end
  1855. CDmeCamera *newEntry = CreateElement< CDmeCamera >( "camerastack", GetFileId() );
  1856. newEntry->FromCamera( pCamera );
  1857. m_CameraStack.AddToTail( newEntry );
  1858. m_nCurrentStackCamera = m_CameraStack.Count() - 1;
  1859. int maxStack = clamp( sfm_maxcamerastack.GetInt(), 4, 100 );
  1860. while ( m_CameraStack.Count() > maxStack )
  1861. {
  1862. m_CameraStack.Remove( 0 );
  1863. --m_nCurrentStackCamera;
  1864. }
  1865. }
  1866. void CDmeFilmClip::UpdateWorkCamera( CDmeCamera *pCamera )
  1867. {
  1868. m_nCurrentStackCamera = clamp( m_nCurrentStackCamera, 0, m_CameraStack.Count() - 1 );
  1869. if ( m_nCurrentStackCamera < 0 || m_nCurrentStackCamera >= m_CameraStack.Count() )
  1870. return;
  1871. m_CameraStack[ m_nCurrentStackCamera ]->FromCamera( pCamera );
  1872. }
  1873. void CDmeFilmClip::PreviousWorkCamera()
  1874. {
  1875. m_nCurrentStackCamera -= 1;
  1876. }
  1877. void CDmeFilmClip::NextWorkCamera()
  1878. {
  1879. m_nCurrentStackCamera += 1;
  1880. }
  1881. CDmeCamera *CDmeFilmClip::GetCurrentCameraStackEntry()
  1882. {
  1883. m_nCurrentStackCamera = clamp( m_nCurrentStackCamera, 0, m_CameraStack.Count() - 1 );
  1884. if ( m_nCurrentStackCamera < 0 || m_nCurrentStackCamera >= m_CameraStack.Count() )
  1885. return NULL;
  1886. CDmeCamera *entry = m_CameraStack[ m_nCurrentStackCamera ];
  1887. return entry;
  1888. }
  1889. void CDmeFilmClip::PurgeCameraStack()
  1890. {
  1891. m_nCurrentStackCamera = -1;
  1892. while ( m_CameraStack.Count() > 0 )
  1893. {
  1894. m_CameraStack.Remove( 0 );
  1895. }
  1896. }