Team Fortress 2 Source Code as on 22/4/2020
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.

1725 lines
46 KiB

  1. //========= Copyright 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/dmelight.h"
  16. #include "movieobjects/dmedag.h"
  17. #include "movieobjects/dmeinput.h"
  18. #include "movieobjects/dmeoperator.h"
  19. #include "movieobjects/dmematerial.h"
  20. #include "movieobjects/dmetrack.h"
  21. #include "movieobjects/dmetrackgroup.h"
  22. #include "movieobjects/dmematerialoverlayfxclip.h"
  23. #include "movieobjects/dmeanimationset.h"
  24. #include "movieobjects_interfaces.h"
  25. #include "materialsystem/imaterialsystem.h"
  26. #include "materialsystem/imaterial.h"
  27. #include "materialsystem/imesh.h"
  28. #include "tier3/tier3.h"
  29. // memdbgon must be the last include file in a .cpp file!!!
  30. #include "tier0/memdbgon.h"
  31. //-----------------------------------------------------------------------------
  32. // String to clip type + back
  33. //-----------------------------------------------------------------------------
  34. static const char *s_pClipTypeNames[DMECLIP_TYPE_COUNT] =
  35. {
  36. "Channel",
  37. "Audio",
  38. "Effects",
  39. "Film",
  40. };
  41. DmeClipType_t ClipTypeFromString( const char *pName )
  42. {
  43. for ( DmeClipType_t i = DMECLIP_FIRST; i <= DMECLIP_LAST; ++i )
  44. {
  45. if ( !Q_stricmp( pName, s_pClipTypeNames[i] ) )
  46. return i;
  47. }
  48. return DMECLIP_UNKNOWN;
  49. }
  50. const char *ClipTypeToString( DmeClipType_t type )
  51. {
  52. if ( type >= DMECLIP_FIRST && type <= DMECLIP_LAST )
  53. return s_pClipTypeNames[ type ];
  54. return "Unknown";
  55. }
  56. //-----------------------------------------------------------------------------
  57. // CDmeClip - common base class for filmclips, soundclips, and channelclips
  58. //-----------------------------------------------------------------------------
  59. IMPLEMENT_ELEMENT_FACTORY( DmeClip, CDmeClip );
  60. void CDmeClip::OnConstruction()
  61. {
  62. m_TimeFrame.InitAndCreate( this, "timeFrame" );
  63. m_ClipColor.InitAndSet( this, "color", Color( 0, 0, 0, 0 ) );
  64. m_ClipText.Init( this, "text" );
  65. m_bMute.Init( this, "mute" );
  66. m_TrackGroups.Init( this, "trackGroups", FATTRIB_MUSTCOPY | FATTRIB_HAS_ARRAY_CALLBACK );
  67. }
  68. void CDmeClip::OnDestruction()
  69. {
  70. }
  71. //-----------------------------------------------------------------------------
  72. // Inherited from IDmElement
  73. //-----------------------------------------------------------------------------
  74. void CDmeClip::OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem )
  75. {
  76. BaseClass::OnAttributeArrayElementAdded( pAttribute, nFirstElem, nLastElem );
  77. if ( pAttribute == m_TrackGroups.GetAttribute() )
  78. {
  79. for ( int i = nFirstElem; i <= nLastElem; ++i )
  80. {
  81. CDmeTrackGroup *pTrackGroup = m_TrackGroups[ i ];
  82. if ( pTrackGroup )
  83. {
  84. pTrackGroup->SetOwnerClip( this );
  85. }
  86. }
  87. return;
  88. }
  89. }
  90. void CDmeClip::OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem )
  91. {
  92. BaseClass::OnAttributeArrayElementRemoved( pAttribute, nFirstElem, nLastElem );
  93. if ( pAttribute == m_TrackGroups.GetAttribute() )
  94. {
  95. for ( int i = nFirstElem; i <= nLastElem; ++i )
  96. {
  97. CDmeTrackGroup *pTrackGroup = m_TrackGroups[ i ];
  98. if ( pTrackGroup )
  99. {
  100. pTrackGroup->SetOwnerClip( NULL );
  101. }
  102. }
  103. return;
  104. }
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Clip color
  108. //-----------------------------------------------------------------------------
  109. void CDmeClip::SetClipColor( const Color& clr )
  110. {
  111. m_ClipColor.Set( clr );
  112. }
  113. Color CDmeClip::GetClipColor() const
  114. {
  115. return m_ClipColor.Get();
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Clip text
  119. //-----------------------------------------------------------------------------
  120. void CDmeClip::SetClipText( const char *pText )
  121. {
  122. m_ClipText = pText;
  123. }
  124. const char* CDmeClip::GetClipText() const
  125. {
  126. return m_ClipText;
  127. }
  128. //-----------------------------------------------------------------------------
  129. // Returns the time frame
  130. //-----------------------------------------------------------------------------
  131. CDmeTimeFrame *CDmeClip::GetTimeFrame() const
  132. {
  133. return m_TimeFrame.GetElement();
  134. }
  135. DmeTime_t CDmeClip::ToChildMediaTime( DmeTime_t t, bool bClamp ) const
  136. {
  137. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  138. return tf ? tf->ToChildMediaTime( t, bClamp ) : DmeTime_t( 0 );
  139. }
  140. DmeTime_t CDmeClip::FromChildMediaTime( DmeTime_t t, bool bClamp ) const
  141. {
  142. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  143. return tf ? tf->FromChildMediaTime( t, bClamp ) : DmeTime_t( 0 );
  144. }
  145. DmeTime_t CDmeClip::ToChildMediaDuration( DmeTime_t dt ) const
  146. {
  147. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  148. return tf ? tf->ToChildMediaDuration( dt ) : DmeTime_t( 0 );
  149. }
  150. DmeTime_t CDmeClip::FromChildMediaDuration( DmeTime_t dt ) const
  151. {
  152. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  153. return tf ? tf->FromChildMediaDuration( dt ) : DmeTime_t( 0 );
  154. }
  155. DmeTime_t CDmeClip::GetTimeOffset() const
  156. {
  157. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  158. return tf ? tf->GetTimeOffset() : DmeTime_t( 0 );
  159. }
  160. float CDmeClip::GetTimeScale() const
  161. {
  162. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  163. return tf ? tf->GetTimeScale() : 0.0f;
  164. }
  165. DmeTime_t CDmeClip::GetStartTime() const
  166. {
  167. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  168. return tf ? tf->GetStartTime() : DmeTime_t( 0 );
  169. }
  170. DmeTime_t CDmeClip::GetEndTime() const
  171. {
  172. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  173. return tf ? tf->GetStartTime() + tf->GetDuration() : DmeTime_t( 0 );
  174. }
  175. DmeTime_t CDmeClip::GetDuration() const
  176. {
  177. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  178. return tf ? tf->GetDuration() : DmeTime_t( 0 );
  179. }
  180. DmeTime_t CDmeClip::GetStartInChildMediaTime() const
  181. {
  182. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  183. return tf ? tf->GetStartInChildMediaTime() : DmeTime_t( 0 );
  184. }
  185. DmeTime_t CDmeClip::GetEndInChildMediaTime() const
  186. {
  187. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  188. return tf ? tf->GetEndInChildMediaTime() : DmeTime_t( 0 );
  189. }
  190. void CDmeClip::SetTimeOffset( DmeTime_t t )
  191. {
  192. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  193. if ( tf )
  194. {
  195. tf->SetTimeOffset( t );
  196. }
  197. }
  198. void CDmeClip::SetTimeScale( float s )
  199. {
  200. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  201. if ( tf )
  202. {
  203. tf->SetTimeScale( s );
  204. }
  205. }
  206. void CDmeClip::SetStartTime( DmeTime_t t )
  207. {
  208. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  209. if ( tf )
  210. {
  211. tf->SetStartTime( t );
  212. }
  213. }
  214. void CDmeClip::SetDuration( DmeTime_t t )
  215. {
  216. CDmeTimeFrame *tf = m_TimeFrame.GetElement();
  217. if ( tf )
  218. {
  219. tf->SetDuration( t );
  220. }
  221. }
  222. //-----------------------------------------------------------------------------
  223. // Track iteration
  224. //-----------------------------------------------------------------------------
  225. const CUtlVector< DmElementHandle_t > &CDmeClip::GetTrackGroups( ) const
  226. {
  227. return m_TrackGroups.Get();
  228. }
  229. int CDmeClip::GetTrackGroupCount( ) const
  230. {
  231. // Make sure no invalid clip types have snuck in
  232. return m_TrackGroups.Count();
  233. }
  234. CDmeTrackGroup *CDmeClip::GetTrackGroup( int nIndex ) const
  235. {
  236. if ( ( nIndex >= 0 ) && ( nIndex < m_TrackGroups.Count() ) )
  237. return m_TrackGroups[ nIndex ];
  238. return NULL;
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Is a track group valid to add?
  242. //-----------------------------------------------------------------------------
  243. bool CDmeClip::IsTrackGroupValid( CDmeTrackGroup *pTrackGroup )
  244. {
  245. // FIXME: If track groups have allowed types, we can check for validity
  246. for ( DmeClipType_t i = DMECLIP_FIRST; i <= DMECLIP_LAST; ++i )
  247. {
  248. if ( !IsSubClipTypeAllowed( i ) && pTrackGroup->IsSubClipTypeAllowed( i ) )
  249. return false;
  250. }
  251. return true;
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Track group addition/removal
  255. //-----------------------------------------------------------------------------
  256. void CDmeClip::AddTrackGroup( CDmeTrackGroup *pTrackGroup )
  257. {
  258. if ( !IsTrackGroupValid( pTrackGroup ) )
  259. return;
  260. // FIXME: Should check if track with same name already exists???
  261. if ( GetTrackGroupIndex( pTrackGroup ) < 0 )
  262. {
  263. m_TrackGroups.AddToTail( pTrackGroup );
  264. }
  265. }
  266. void CDmeClip::AddTrackGroupBefore( CDmeTrackGroup *pTrackGroup, CDmeTrackGroup *pBefore )
  267. {
  268. if ( !IsTrackGroupValid( pTrackGroup ) )
  269. return;
  270. // FIXME: Should check if track with same name already exists???
  271. if ( GetTrackGroupIndex( pTrackGroup ) < 0 )
  272. {
  273. int nBeforeIndex = pBefore ? GetTrackGroupIndex( pBefore ) : GetTrackGroupCount();
  274. if ( nBeforeIndex >= 0 )
  275. {
  276. m_TrackGroups.InsertBefore( nBeforeIndex, pTrackGroup );
  277. }
  278. }
  279. }
  280. CDmeTrackGroup *CDmeClip::AddTrackGroup( const char *pTrackGroupName )
  281. {
  282. CDmeTrackGroup *pTrackGroup = CreateElement< CDmeTrackGroup >( pTrackGroupName, GetFileId() );
  283. pTrackGroup->SetMinimized( false );
  284. m_TrackGroups.AddToTail( pTrackGroup );
  285. return pTrackGroup;
  286. }
  287. void CDmeClip::RemoveTrackGroup( int nIndex )
  288. {
  289. Assert( nIndex >= 0 && nIndex < m_TrackGroups.Count() );
  290. m_TrackGroups.Remove( nIndex );
  291. }
  292. void CDmeClip::RemoveTrackGroup( CDmeTrackGroup *pTrackGroup )
  293. {
  294. int i = GetTrackGroupIndex( pTrackGroup );
  295. if ( i < 0 )
  296. return;
  297. m_TrackGroups.Remove( i );
  298. }
  299. void CDmeClip::RemoveTrackGroup( const char *pTrackGroupName )
  300. {
  301. if ( !pTrackGroupName )
  302. {
  303. pTrackGroupName = DMETRACKGROUP_DEFAULT_NAME;
  304. }
  305. int c = m_TrackGroups.Count();
  306. for ( int i = c; --i >= 0; )
  307. {
  308. if ( !Q_strcmp( m_TrackGroups[i]->GetName(), pTrackGroupName ) )
  309. {
  310. m_TrackGroups.Remove( i );
  311. return;
  312. }
  313. }
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Swap track groups
  317. //-----------------------------------------------------------------------------
  318. void CDmeClip::SwapOrder( CDmeTrackGroup *pTrackGroup1, CDmeTrackGroup *pTrackGroup2 )
  319. {
  320. if ( pTrackGroup1 == pTrackGroup2 )
  321. return;
  322. if ( pTrackGroup1->IsFilmTrackGroup() || pTrackGroup2->IsFilmTrackGroup() )
  323. return;
  324. int nIndex1 = -1, nIndex2 = -1;
  325. int c = m_TrackGroups.Count();
  326. for ( int i = c; --i >= 0; )
  327. {
  328. if ( m_TrackGroups[i] == pTrackGroup1 )
  329. {
  330. nIndex1 = i;
  331. }
  332. if ( m_TrackGroups[i] == pTrackGroup2 )
  333. {
  334. nIndex2 = i;
  335. }
  336. }
  337. if ( ( nIndex1 < 0 ) || ( nIndex2 < 0 ) )
  338. return;
  339. m_TrackGroups.Swap( nIndex1, nIndex2 );
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Track group finding
  343. //-----------------------------------------------------------------------------
  344. CDmeTrackGroup *CDmeClip::FindTrackGroup( const char *pTrackGroupName ) const
  345. {
  346. if ( !pTrackGroupName )
  347. {
  348. pTrackGroupName = DMETRACKGROUP_DEFAULT_NAME;
  349. }
  350. int c = m_TrackGroups.Count();
  351. for ( int i = 0 ; i < c; ++i )
  352. {
  353. CDmeTrackGroup *pTrackGroup = m_TrackGroups[i];
  354. if ( !pTrackGroup )
  355. continue;
  356. if ( !Q_strcmp( pTrackGroup->GetName(), pTrackGroupName ) )
  357. return pTrackGroup;
  358. }
  359. return NULL;
  360. }
  361. int CDmeClip::GetTrackGroupIndex( CDmeTrackGroup *pTrackGroup ) const
  362. {
  363. int nTrackGroups = m_TrackGroups.Count();
  364. for ( int i = 0 ; i < nTrackGroups; ++i )
  365. {
  366. if ( pTrackGroup == m_TrackGroups[i] )
  367. return i;
  368. }
  369. return -1;
  370. }
  371. //-----------------------------------------------------------------------------
  372. // Find or create a track group
  373. //-----------------------------------------------------------------------------
  374. CDmeTrackGroup *CDmeClip::FindOrAddTrackGroup( const char *pTrackGroupName )
  375. {
  376. CDmeTrackGroup *pTrackGroup = FindTrackGroup( pTrackGroupName );
  377. if ( !pTrackGroup )
  378. {
  379. pTrackGroup = AddTrackGroup( pTrackGroupName );
  380. }
  381. return pTrackGroup;
  382. }
  383. //-----------------------------------------------------------------------------
  384. // Finding clips in track groups
  385. //-----------------------------------------------------------------------------
  386. CDmeTrack *CDmeClip::FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup /*= NULL*/ ) const
  387. {
  388. // DmeClipType_t type = pClip->GetClipType();
  389. int c = m_TrackGroups.Count();
  390. for ( int i = 0 ; i < c; ++i )
  391. {
  392. // FIXME: If trackgroups have valid types, can early out here
  393. CDmeTrack *pTrack = m_TrackGroups[i]->FindTrackForClip( pClip );
  394. if ( pTrack )
  395. {
  396. if ( ppTrackGroup )
  397. {
  398. *ppTrackGroup = m_TrackGroups[i];
  399. }
  400. return pTrack;
  401. }
  402. }
  403. return NULL;
  404. }
  405. bool CDmeClip::FindMultiTrackGroupForClip( CDmeClip *pClip, int *pTrackGroupIndex, int *pTrackIndex, int *pClipIndex ) const
  406. {
  407. int nTrackGroups = m_TrackGroups.Count();
  408. for ( int gi = 0 ; gi < nTrackGroups; ++gi )
  409. {
  410. CDmeTrackGroup *pTrackGroup = m_TrackGroups[ gi ];
  411. if ( !pTrackGroup )
  412. continue;
  413. if ( !pTrackGroup->FindTrackForClip( pClip, pTrackIndex, pClipIndex ) )
  414. continue;
  415. if ( pTrackGroupIndex )
  416. {
  417. *pTrackGroupIndex = gi;
  418. }
  419. return true;
  420. }
  421. return false;
  422. }
  423. //-----------------------------------------------------------------------------
  424. // Finding clips in tracks by time
  425. //-----------------------------------------------------------------------------
  426. void CDmeClip::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  427. {
  428. if ( clipType == DMECLIP_FILM )
  429. return;
  430. int gc = GetTrackGroupCount();
  431. for ( int i = 0; i < gc; ++i )
  432. {
  433. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  434. if ( !pTrackGroup )
  435. continue;
  436. pTrackGroup->FindClipsAtTime( clipType, time, flags, clips );
  437. }
  438. }
  439. void CDmeClip::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  440. {
  441. if ( clipType == DMECLIP_FILM )
  442. return;
  443. int gc = GetTrackGroupCount();
  444. for ( int i = 0; i < gc; ++i )
  445. {
  446. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  447. if ( !pTrackGroup )
  448. continue;
  449. pTrackGroup->FindClipsWithinTime( clipType, startTime, endTime, flags, clips );
  450. }
  451. }
  452. //-----------------------------------------------------------------------------
  453. // Build a list of all referring clips
  454. //-----------------------------------------------------------------------------
  455. static int BuildReferringClipList( CDmeClip *pClip, CDmeClip** ppParents, int nMaxCount )
  456. {
  457. int nCount = 0;
  458. DmAttributeReferenceIterator_t it, it2, it3;
  459. for ( it = g_pDataModel->FirstAttributeReferencingElement( pClip->GetHandle() );
  460. it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  461. it = g_pDataModel->NextAttributeReferencingElement( it ) )
  462. {
  463. CDmAttribute *pAttribute = g_pDataModel->GetAttribute( it );
  464. const char *pName = pAttribute->GetName();
  465. CDmElement *pElement = pAttribute->GetOwner();
  466. CDmeTrack *pTrack = CastElement< CDmeTrack >( pElement );
  467. if ( !pTrack )
  468. continue;
  469. for ( it2 = g_pDataModel->FirstAttributeReferencingElement( pTrack->GetHandle() );
  470. it2 != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  471. it2 = g_pDataModel->NextAttributeReferencingElement( it2 ) )
  472. {
  473. pAttribute = g_pDataModel->GetAttribute( it2 );
  474. pName = pAttribute->GetName();
  475. pElement = pAttribute->GetOwner();
  476. CDmeTrackGroup *pTrackGroup = CastElement< CDmeTrackGroup >( pElement );
  477. if ( !pTrackGroup )
  478. continue;
  479. for ( it3 = g_pDataModel->FirstAttributeReferencingElement( pTrackGroup->GetHandle() );
  480. it3 != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID;
  481. it3 = g_pDataModel->NextAttributeReferencingElement( it3 ) )
  482. {
  483. pAttribute = g_pDataModel->GetAttribute( it3 );
  484. pName = pAttribute->GetName();
  485. pElement = pAttribute->GetOwner();
  486. CDmeClip *pParent = CastElement< CDmeClip >( pElement );
  487. if ( !pParent )
  488. continue;
  489. Assert( nCount < nMaxCount );
  490. if ( nCount >= nMaxCount )
  491. return nCount;
  492. ppParents[nCount++] = pParent;
  493. }
  494. }
  495. }
  496. return nCount;
  497. }
  498. //-----------------------------------------------------------------------------
  499. // Clip stack
  500. //-----------------------------------------------------------------------------
  501. static bool BuildClipStack_R( DmeClipStack_t* pStack, CDmeClip *pMovie, CDmeClip *pShot, CDmeClip *pCurrent )
  502. {
  503. // Add this clip to the stack
  504. int nIndex = pStack->AddToHead( CDmeHandle< CDmeClip >( pCurrent ) );
  505. // Is this clip the shot? We don't need to look for it any more.
  506. if ( pCurrent == pShot )
  507. {
  508. pShot = NULL;
  509. }
  510. // Is this clip the movie? We succeeded if we already found the shot!
  511. if ( pCurrent == pMovie )
  512. {
  513. if ( !pShot )
  514. return true;
  515. }
  516. else
  517. {
  518. // NOTE: This algorithm assumes a clip can never appear twice under another clip
  519. // at a single level of hierarchy.
  520. CDmeClip* ppParents[1024];
  521. int nCount = BuildReferringClipList( pCurrent, ppParents, 1024 );
  522. for ( int i = 0; i < nCount; ++i )
  523. {
  524. // Can we find a path to the root through the shot? We succeeded!
  525. if ( BuildClipStack_R( pStack, pMovie, pShot, ppParents[i] ) )
  526. return true;
  527. }
  528. }
  529. // This clip didn't work out for us. Remove it.
  530. pStack->Remove( nIndex );
  531. return false;
  532. }
  533. bool CDmeClip::BuildClipStack( DmeClipStack_t* pStack, CDmeClip *pMovie, CDmeClip *pShot )
  534. {
  535. // Walk through each shot in the movie and look for the subClip, if don't find it recurse into each shot
  536. return BuildClipStack_R( pStack, pMovie, pShot, this );
  537. }
  538. DmeTime_t CDmeClip::ToChildMediaTime( const DmeClipStack_t& stack, DmeTime_t globalTime, bool bClamp /* = true */ )
  539. {
  540. DmeTime_t time = globalTime;
  541. int nClips = stack.Count();
  542. for ( int i = 0; i < nClips; ++i )
  543. {
  544. time = stack[ i ]->ToChildMediaTime( time, bClamp );
  545. }
  546. return time;
  547. }
  548. DmeTime_t CDmeClip::FromChildMediaTime( const DmeClipStack_t& stack, DmeTime_t localTime, bool bClamp /* = true */ )
  549. {
  550. DmeTime_t time = localTime;
  551. int nClips = stack.Count();
  552. for ( int i = nClips-1; i >= 0; --i )
  553. {
  554. time = stack[ i ]->FromChildMediaTime( time, bClamp );
  555. }
  556. return time;
  557. }
  558. DmeTime_t CDmeClip::ToChildMediaDuration( const DmeClipStack_t& stack, DmeTime_t globalDuration )
  559. {
  560. DmeTime_t duration = globalDuration;
  561. int nClips = stack.Count();
  562. for ( int i = 0; i < nClips; ++i )
  563. {
  564. duration = stack[ i ]->ToChildMediaDuration( duration );
  565. }
  566. return duration;
  567. }
  568. DmeTime_t CDmeClip::FromChildMediaDuration( const DmeClipStack_t& stack, DmeTime_t localDuration )
  569. {
  570. DmeTime_t duration = localDuration;
  571. int nClips = stack.Count();
  572. for ( int i = nClips-1; i >= 0; --i )
  573. {
  574. duration = stack[ i ]->FromChildMediaDuration( duration );
  575. }
  576. return duration;
  577. }
  578. void CDmeClip::ToChildMediaTime( DmeLog_TimeSelection_t &params, const DmeClipStack_t& stack )
  579. {
  580. for ( int i = 0; i < TS_TIME_COUNT; ++i )
  581. {
  582. params.m_nTimes[i] = ToChildMediaTime( stack, params.m_nTimes[i], false );
  583. }
  584. }
  585. //-----------------------------------------------------------------------------
  586. //
  587. // CDmeSoundClip - timeframe view into a dmesound
  588. //
  589. //-----------------------------------------------------------------------------
  590. IMPLEMENT_ELEMENT_FACTORY( DmeSoundClip, CDmeSoundClip );
  591. void CDmeSoundClip::OnConstruction()
  592. {
  593. m_Sound.Init( this, "sound" );
  594. m_bShowWave.InitAndSet( this, "showwave", false );
  595. }
  596. void CDmeSoundClip::OnDestruction()
  597. {
  598. }
  599. void CDmeSoundClip::SetShowWave( bool state )
  600. {
  601. m_bShowWave = state;
  602. }
  603. bool CDmeSoundClip::ShouldShowWave( ) const
  604. {
  605. return m_bShowWave;
  606. }
  607. //-----------------------------------------------------------------------------
  608. // CDmeChannelsClip - timeframe view into a set of channels
  609. //-----------------------------------------------------------------------------
  610. IMPLEMENT_ELEMENT_FACTORY( DmeChannelsClip, CDmeChannelsClip );
  611. void CDmeChannelsClip::OnConstruction()
  612. {
  613. m_Channels.Init( this, "channels" );
  614. }
  615. void CDmeChannelsClip::OnDestruction()
  616. {
  617. }
  618. CDmeChannel *CDmeChannelsClip::CreatePassThruConnection( char const *passThruName,
  619. CDmElement *pFrom, char const *pFromAttribute,
  620. CDmElement *pTo, char const *pToAttribute, int index /*= 0*/ )
  621. {
  622. CDmeChannel *helper = CreateElement< CDmeChannel >( passThruName, GetFileId() );
  623. Assert( helper );
  624. helper->SetMode( CM_PASS );
  625. helper->SetInput( pFrom, pFromAttribute );
  626. helper->SetOutput( pTo, pToAttribute, index );
  627. m_Channels.AddToTail( helper );
  628. return helper;
  629. }
  630. void CDmeChannelsClip::RemoveChannel( CDmeChannel *pChannel )
  631. {
  632. int nCount = m_Channels.Count();
  633. for ( int i = 0; i < nCount; ++i )
  634. {
  635. if ( pChannel == m_Channels[i] )
  636. {
  637. m_Channels.Remove( i );
  638. break;
  639. }
  640. }
  641. }
  642. //-----------------------------------------------------------------------------
  643. // CDmeFXClip - timeframe view into an effect
  644. //-----------------------------------------------------------------------------
  645. IMPLEMENT_ELEMENT_FACTORY( DmeFXClip, CDmeFXClip );
  646. void CDmeFXClip::OnConstruction()
  647. {
  648. }
  649. void CDmeFXClip::OnDestruction()
  650. {
  651. }
  652. //-----------------------------------------------------------------------------
  653. // Global list of FX clip types
  654. //-----------------------------------------------------------------------------
  655. const char *CDmeFXClip::s_pFXClipTypes[MAX_FXCLIP_TYPES];
  656. const char *CDmeFXClip::s_pFXClipDescriptions[MAX_FXCLIP_TYPES];
  657. int CDmeFXClip::s_nFXClipTypeCount = 0;
  658. void CDmeFXClip::InstallFXClipType( const char *pElementType, const char *pDescription )
  659. {
  660. s_pFXClipTypes[s_nFXClipTypeCount] = pElementType;
  661. s_pFXClipDescriptions[s_nFXClipTypeCount] = pDescription;
  662. ++s_nFXClipTypeCount;
  663. }
  664. int CDmeFXClip::FXClipTypeCount()
  665. {
  666. return s_nFXClipTypeCount;
  667. }
  668. const char *CDmeFXClip::FXClipType( int nIndex )
  669. {
  670. Assert( s_nFXClipTypeCount > nIndex );
  671. return s_pFXClipTypes[nIndex];
  672. }
  673. const char *CDmeFXClip::FXClipDescription( int nIndex )
  674. {
  675. Assert( s_nFXClipTypeCount > nIndex );
  676. return s_pFXClipDescriptions[nIndex];
  677. }
  678. //-----------------------------------------------------------------------------
  679. // CDmeFilmClip - hierarchical clip (movie, sequence or shot) w/ scene info
  680. //-----------------------------------------------------------------------------
  681. IMPLEMENT_ELEMENT_FACTORY( DmeFilmClip, CDmeFilmClip );
  682. void CDmeFilmClip::OnConstruction()
  683. {
  684. m_MaterialOverlayEffect.Init( this, "materialOverlay" );
  685. m_MapName.Init( this, "mapname" );
  686. m_Camera.Init( this, "camera" );
  687. m_MonitorCameras.Init( this, "monitorCameras" );
  688. m_nActiveMonitor.InitAndSet( this, "activeMonitor", -1 );
  689. m_Lights.Init( this, "lights" );
  690. m_Scene.Init( this, "scene" );
  691. m_AVIFile.Init( this, "aviFile" );
  692. m_fadeInDuration .InitAndSet( this, "fadeIn", 0 );
  693. m_fadeOutDuration.InitAndSet( this, "fadeOut", 0 );
  694. m_Inputs.Init( this, "inputs" );
  695. m_Operators.Init( this, "operators" );
  696. m_bIsUsingCachedVersion.Init( this, "useAviFile" );
  697. m_AnimationSets.Init( this, "animationSets" );
  698. m_Bookmarks.Init( this, "bookmarks" );
  699. m_FilmTrackGroup.Init( this, "subClipTrackGroup", FATTRIB_HAS_CALLBACK | FATTRIB_HAS_PRE_CALLBACK );
  700. m_Volume.InitAndSet( this, "volume", 1.0);
  701. m_pCachedVersion = NULL;
  702. m_bIsUsingCachedVersion = false;
  703. m_bReloadCachedVersion = false;
  704. }
  705. void CDmeFilmClip::OnDestruction()
  706. {
  707. if ( g_pVideo != NULL && m_pCachedVersion != NULL )
  708. {
  709. g_pVideo->DestroyVideoMaterial( m_pCachedVersion );
  710. m_pCachedVersion = NULL;
  711. }
  712. }
  713. //-----------------------------------------------------------------------------
  714. // Returns the special film track group
  715. //-----------------------------------------------------------------------------
  716. CDmeTrackGroup *CDmeFilmClip::GetFilmTrackGroup() const
  717. {
  718. return m_FilmTrackGroup;
  719. }
  720. //-----------------------------------------------------------------------------
  721. // Returns the special film track
  722. //-----------------------------------------------------------------------------
  723. CDmeTrack *CDmeFilmClip::GetFilmTrack() const
  724. {
  725. CDmeTrackGroup *pTrackGroup = m_FilmTrackGroup.GetElement();
  726. if ( pTrackGroup )
  727. return pTrackGroup->GetFilmTrack();
  728. return NULL;
  729. }
  730. CDmeTrackGroup *CDmeFilmClip::FindOrCreateFilmTrackGroup()
  731. {
  732. if ( !m_FilmTrackGroup )
  733. {
  734. m_FilmTrackGroup = CreateElement< CDmeTrackGroup >( "subClipTrackGroup", GetFileId() );
  735. m_FilmTrackGroup->SetMinimized( false );
  736. m_FilmTrackGroup->SetMaxTrackCount( 1 );
  737. m_FilmTrackGroup->SetOwnerClip( this );
  738. }
  739. return m_FilmTrackGroup;
  740. }
  741. CDmeTrack *CDmeFilmClip::FindOrCreateFilmTrack()
  742. {
  743. CDmeTrackGroup *pTrackGroup = FindOrCreateFilmTrackGroup();
  744. CDmeTrack *pTrack = pTrackGroup->GetFilmTrack();
  745. return pTrack ? pTrack : m_FilmTrackGroup->CreateFilmTrack();
  746. }
  747. //-----------------------------------------------------------------------------
  748. // Finding clips in track groups
  749. //-----------------------------------------------------------------------------
  750. CDmeTrack *CDmeFilmClip::FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup /*= NULL*/ ) const
  751. {
  752. if ( m_FilmTrackGroup.GetElement() )
  753. {
  754. CDmeTrack *pTrack = m_FilmTrackGroup->FindTrackForClip( pClip );
  755. if ( pTrack )
  756. {
  757. if ( ppTrackGroup )
  758. {
  759. *ppTrackGroup = m_FilmTrackGroup;
  760. }
  761. return pTrack;
  762. }
  763. }
  764. return CDmeClip::FindTrackForClip( pClip, ppTrackGroup );
  765. }
  766. //-----------------------------------------------------------------------------
  767. // Finding clips in tracks by time
  768. //-----------------------------------------------------------------------------
  769. void CDmeFilmClip::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  770. {
  771. if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) )
  772. {
  773. if ( m_FilmTrackGroup )
  774. {
  775. m_FilmTrackGroup->FindClipsAtTime( clipType, time, flags, clips );
  776. }
  777. }
  778. CDmeClip::FindClipsAtTime( clipType, time, flags, clips );
  779. }
  780. void CDmeFilmClip::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
  781. {
  782. if ( ( clipType == DMECLIP_FILM ) || ( clipType == DMECLIP_UNKNOWN ) )
  783. {
  784. if ( m_FilmTrackGroup )
  785. {
  786. m_FilmTrackGroup->FindClipsWithinTime( clipType, startTime, endTime, flags, clips );
  787. }
  788. }
  789. CDmeClip::FindClipsWithinTime( clipType, startTime, endTime, flags, clips );
  790. }
  791. //-----------------------------------------------------------------------------
  792. // Volume
  793. //-----------------------------------------------------------------------------
  794. void CDmeFilmClip::SetVolume( float state )
  795. {
  796. m_Volume = state;
  797. }
  798. float CDmeFilmClip::GetVolume() const
  799. {
  800. return m_Volume.Get();
  801. }
  802. //-----------------------------------------------------------------------------
  803. // mapname helper methods
  804. //-----------------------------------------------------------------------------
  805. const char *CDmeFilmClip::GetMapName()
  806. {
  807. return m_MapName.Get();
  808. }
  809. void CDmeFilmClip::SetMapName( const char *pMapName )
  810. {
  811. m_MapName.Set( pMapName );
  812. }
  813. //-----------------------------------------------------------------------------
  814. // Attribute changed
  815. //-----------------------------------------------------------------------------
  816. void CDmeFilmClip::PreAttributeChanged( CDmAttribute *pAttribute )
  817. {
  818. BaseClass::PreAttributeChanged( pAttribute );
  819. if ( pAttribute == m_FilmTrackGroup.GetAttribute() )
  820. {
  821. if ( m_FilmTrackGroup.GetElement() )
  822. {
  823. m_FilmTrackGroup->SetOwnerClip( NULL );
  824. }
  825. return;
  826. }
  827. }
  828. void CDmeFilmClip::OnAttributeChanged( CDmAttribute *pAttribute )
  829. {
  830. BaseClass::OnAttributeChanged( pAttribute );
  831. if ( pAttribute == m_FilmTrackGroup.GetAttribute() )
  832. {
  833. if ( m_FilmTrackGroup.GetElement() )
  834. {
  835. m_FilmTrackGroup->SetMaxTrackCount( 1 );
  836. m_FilmTrackGroup->SetOwnerClip( this );
  837. }
  838. }
  839. else if ( pAttribute->GetOwner() == m_TimeFrame.GetElement() )
  840. {
  841. InvokeOnAttributeChangedOnReferrers( GetHandle(), pAttribute );
  842. }
  843. }
  844. void CDmeFilmClip::OnElementUnserialized( )
  845. {
  846. BaseClass::OnElementUnserialized();
  847. CDmeTrackGroup *pFilmTrackGroup = m_FilmTrackGroup.GetElement();
  848. if ( pFilmTrackGroup )
  849. {
  850. pFilmTrackGroup->SetMaxTrackCount( 1 );
  851. if ( pFilmTrackGroup->GetTrackCount() == 0 )
  852. {
  853. pFilmTrackGroup->CreateFilmTrack();
  854. }
  855. }
  856. // this conversion code went in on 10/31/2005
  857. // 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
  858. Assert( !HasAttribute( "overlay" ) && !HasAttribute( "overlayalpha" ) );
  859. if ( HasAttribute( "overlay" ) || HasAttribute( "overlayalpha" ) )
  860. {
  861. Warning( "CDmeFilmClip %s is an old version that has overlay and/or overlayalpha attributes!\n", GetName() );
  862. // Backward compat conversion
  863. // If this is an older file with an overlay attribute, strip it out into materialoverlay
  864. CDmAttribute *pOverlayAttribute = GetAttribute( "overlay" );
  865. if ( !pOverlayAttribute )
  866. goto cleanUp;
  867. const char *pName = pOverlayAttribute->GetValueString();
  868. if ( !pName || !pName[0] )
  869. goto cleanUp;
  870. // If we don't yet have a material overlay, create one
  871. if ( m_MaterialOverlayEffect.GetElement() == NULL )
  872. {
  873. m_MaterialOverlayEffect = CreateElement<CDmeMaterialOverlayFXClip>( "materialOverlay", GetFileId() );
  874. }
  875. m_MaterialOverlayEffect->SetOverlayEffect( pName );
  876. // If this is an older file with an overlayalpha attribute, strip it out into materialoverlay
  877. CDmAttribute *pOverlayAlphaAttribute = GetAttribute( "overlayalpha" );
  878. if ( pOverlayAlphaAttribute )
  879. {
  880. float alpha = pOverlayAlphaAttribute->GetValue<float>();
  881. m_MaterialOverlayEffect->SetAlpha( alpha );
  882. }
  883. cleanUp:
  884. // Always strip out the old overlay attribute
  885. RemoveAttribute( "overlay" );
  886. RemoveAttribute( "overlayalpha" );
  887. }
  888. }
  889. //-----------------------------------------------------------------------------
  890. // Resolve
  891. //-----------------------------------------------------------------------------
  892. void CDmeFilmClip::Resolve()
  893. {
  894. BaseClass::Resolve();
  895. if ( m_AVIFile.IsDirty() )
  896. {
  897. m_bReloadCachedVersion = true;
  898. m_AVIFile.GetAttribute()->RemoveFlag( FATTRIB_DIRTY );
  899. }
  900. }
  901. //-----------------------------------------------------------------------------
  902. // Helper for overlays
  903. //-----------------------------------------------------------------------------
  904. void CDmeFilmClip::SetOverlay( const char *pMaterialName )
  905. {
  906. if ( pMaterialName && pMaterialName[0] )
  907. {
  908. if ( !m_MaterialOverlayEffect.GetElement() )
  909. {
  910. m_MaterialOverlayEffect = CreateElement<CDmeMaterialOverlayFXClip>( "materialOverlay", GetFileId() );
  911. }
  912. m_MaterialOverlayEffect->SetOverlayEffect( pMaterialName );
  913. }
  914. else
  915. {
  916. m_MaterialOverlayEffect.Set( NULL );
  917. }
  918. }
  919. IMaterial *CDmeFilmClip::GetOverlayMaterial()
  920. {
  921. return m_MaterialOverlayEffect.GetElement() ? m_MaterialOverlayEffect->GetMaterial() : NULL;
  922. }
  923. float CDmeFilmClip::GetOverlayAlpha()
  924. {
  925. return m_MaterialOverlayEffect.GetElement() ? m_MaterialOverlayEffect->GetAlpha() : 0.0f;
  926. }
  927. void CDmeFilmClip::SetOverlayAlpha( float alpha )
  928. {
  929. if ( m_MaterialOverlayEffect.GetElement() )
  930. {
  931. m_MaterialOverlayEffect->SetAlpha( alpha );
  932. }
  933. }
  934. bool CDmeFilmClip::HasOpaqueOverlay( void )
  935. {
  936. if ( m_MaterialOverlayEffect->GetMaterial()->IsTranslucent() ||
  937. ( m_MaterialOverlayEffect->GetAlpha() < 1.0f ) )
  938. {
  939. return false;
  940. }
  941. return true;
  942. }
  943. void CDmeFilmClip::DrawOverlay( DmeTime_t time, Rect_t &currentRect, Rect_t &totalRect )
  944. {
  945. if ( m_MaterialOverlayEffect.GetElement() )
  946. {
  947. m_MaterialOverlayEffect->ApplyEffect( ToChildMediaTime( time ), currentRect, totalRect, NULL );
  948. }
  949. DmeTime_t fadeIn( m_fadeInDuration );
  950. DmeTime_t fadeOut( m_fadeOutDuration );
  951. float fade = 1.0f;
  952. if ( time < GetStartTime() + fadeIn )
  953. {
  954. fade = ( time - GetStartTime() ) / fadeIn;
  955. }
  956. if ( time > GetEndTime() - fadeOut )
  957. {
  958. fade = min( fade, ( GetEndTime() - time ) / fadeOut );
  959. }
  960. if ( fade < 1.0f )
  961. {
  962. if ( !m_FadeMaterial.IsValid() )
  963. {
  964. m_FadeMaterial.Init( "engine\\singlecolor.vmt", NULL, false );
  965. }
  966. float r, g, b;
  967. m_FadeMaterial->GetColorModulation( &r, &g, &b );
  968. float a = m_FadeMaterial->GetAlphaModulation();
  969. m_FadeMaterial->ColorModulate( 0.0f, 0.0f, 0.0f );
  970. m_FadeMaterial->AlphaModulate( 1.0f - fade );
  971. CMatRenderContextPtr pRenderContext( materials );
  972. pRenderContext->Bind( m_FadeMaterial );
  973. float w = currentRect.width;
  974. float h = currentRect.height;
  975. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  976. CMeshBuilder meshBuilder;
  977. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );
  978. meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
  979. meshBuilder.AdvanceVertex();
  980. meshBuilder.Position3f( 0.0f, h, 0.0f );
  981. meshBuilder.AdvanceVertex();
  982. meshBuilder.Position3f( w, 0.0f, 0.0f );
  983. meshBuilder.AdvanceVertex();
  984. meshBuilder.Position3f( w, h, 0.0f );
  985. meshBuilder.AdvanceVertex();
  986. meshBuilder.End();
  987. pMesh->Draw();
  988. m_FadeMaterial->ColorModulate( r, g, b );
  989. m_FadeMaterial->AlphaModulate( a );
  990. }
  991. }
  992. //-----------------------------------------------------------------------------
  993. // AVI tape out
  994. //-----------------------------------------------------------------------------
  995. void CDmeFilmClip::UseCachedVersion( bool bUseCachedVersion )
  996. {
  997. m_bIsUsingCachedVersion = bUseCachedVersion;
  998. }
  999. bool CDmeFilmClip::IsUsingCachedVersion() const
  1000. {
  1001. return m_bIsUsingCachedVersion;
  1002. }
  1003. IVideoMaterial *CDmeFilmClip::GetCachedVideoMaterial()
  1004. {
  1005. if ( m_bReloadCachedVersion )
  1006. {
  1007. if ( g_pVideo )
  1008. {
  1009. if ( m_pCachedVersion != NULL )
  1010. {
  1011. g_pVideo->DestroyVideoMaterial( m_pCachedVersion );
  1012. m_pCachedVersion = NULL;
  1013. }
  1014. if ( m_AVIFile[0] )
  1015. {
  1016. m_pCachedVersion = g_pVideo->CreateVideoMaterial( m_AVIFile, m_AVIFile, "MOD" );
  1017. }
  1018. }
  1019. m_bReloadCachedVersion = false;
  1020. }
  1021. return m_pCachedVersion;
  1022. }
  1023. void CDmeFilmClip::SetCachedAVI( const char *pAVIFile )
  1024. {
  1025. m_AVIFile = pAVIFile;
  1026. m_bReloadCachedVersion = true;
  1027. }
  1028. //-----------------------------------------------------------------------------
  1029. // Camera helper methods
  1030. //-----------------------------------------------------------------------------
  1031. CDmeCamera *CDmeFilmClip::GetCamera()
  1032. {
  1033. return m_Camera;
  1034. }
  1035. void CDmeFilmClip::SetCamera( CDmeCamera *pCamera )
  1036. {
  1037. m_Camera = pCamera;
  1038. }
  1039. //-----------------------------------------------------------------------------
  1040. // Returns the monitor camera associated with the clip (for now, only 1 supported)
  1041. //-----------------------------------------------------------------------------
  1042. CDmeCamera *CDmeFilmClip::GetMonitorCamera()
  1043. {
  1044. if ( m_nActiveMonitor < 0 )
  1045. return NULL;
  1046. return m_MonitorCameras[ m_nActiveMonitor ];
  1047. }
  1048. void CDmeFilmClip::AddMonitorCamera( CDmeCamera *pCamera )
  1049. {
  1050. m_MonitorCameras.AddToTail( pCamera );
  1051. }
  1052. int CDmeFilmClip::FindMonitorCamera( CDmeCamera *pCamera )
  1053. {
  1054. return m_MonitorCameras.Find( pCamera->GetHandle() );
  1055. }
  1056. void CDmeFilmClip::RemoveMonitorCamera( CDmeCamera *pCamera )
  1057. {
  1058. int i = m_MonitorCameras.Find( pCamera->GetHandle() );
  1059. if ( i >= 0 )
  1060. {
  1061. if ( m_nActiveMonitor == i )
  1062. {
  1063. m_nActiveMonitor = -1;
  1064. }
  1065. m_MonitorCameras.FastRemove( i );
  1066. }
  1067. }
  1068. void CDmeFilmClip::SelectMonitorCamera( CDmeCamera *pCamera )
  1069. {
  1070. m_nActiveMonitor = pCamera ? m_MonitorCameras.Find( pCamera->GetHandle() ) : -1;
  1071. }
  1072. //-----------------------------------------------------------------------------
  1073. // Light helper methods
  1074. //-----------------------------------------------------------------------------
  1075. int CDmeFilmClip::GetLightCount()
  1076. {
  1077. return m_Lights.Count();
  1078. }
  1079. CDmeLight *CDmeFilmClip::GetLight( int nIndex )
  1080. {
  1081. if ( ( nIndex < 0 ) || ( nIndex >= m_Lights.Count() ) )
  1082. return NULL;
  1083. return m_Lights[ nIndex ];
  1084. }
  1085. void CDmeFilmClip::AddLight( CDmeLight *pLight )
  1086. {
  1087. m_Lights.AddToTail( pLight );
  1088. }
  1089. //-----------------------------------------------------------------------------
  1090. // Scene / Dag helper methods
  1091. //-----------------------------------------------------------------------------
  1092. CDmeDag *CDmeFilmClip::GetScene()
  1093. {
  1094. return m_Scene.GetElement();
  1095. }
  1096. void CDmeFilmClip::SetScene( CDmeDag *pDag )
  1097. {
  1098. m_Scene.Set( pDag );
  1099. }
  1100. //-----------------------------------------------------------------------------
  1101. // helper for inputs and operators
  1102. //-----------------------------------------------------------------------------
  1103. int CDmeFilmClip::GetInputCount()
  1104. {
  1105. return m_Inputs.Count();
  1106. }
  1107. CDmeInput *CDmeFilmClip::GetInput( int nIndex )
  1108. {
  1109. if ( nIndex < 0 || nIndex >= m_Inputs.Count() )
  1110. return NULL;
  1111. return m_Inputs[ nIndex ];
  1112. }
  1113. void CDmeFilmClip::AddInput( CDmeInput *pInput )
  1114. {
  1115. m_Inputs.AddToTail( pInput );
  1116. }
  1117. void CDmeFilmClip::RemoveAllInputs()
  1118. {
  1119. m_Inputs.RemoveAll();
  1120. }
  1121. void CDmeFilmClip::AddOperator( CDmeOperator *pOperator )
  1122. {
  1123. m_Operators.AddToTail( pOperator );
  1124. }
  1125. void CDmeFilmClip::CollectOperators( CUtlVector< DmElementHandle_t > &operators )
  1126. {
  1127. int numInputs = m_Inputs.Count();
  1128. for ( int i = 0; i < numInputs; ++i )
  1129. {
  1130. operators.AddToTail( m_Inputs[ i ]->GetHandle() );
  1131. }
  1132. int numOperators = m_Operators.Count();
  1133. for ( int i = 0; i < numOperators; ++i )
  1134. {
  1135. operators.AddToTail( m_Operators[ i ]->GetHandle() );
  1136. }
  1137. }
  1138. int CDmeFilmClip::GetAnimationSetCount()
  1139. {
  1140. // yes, this is nasty perf-wise, but since we only have a dozen or so animation sets,
  1141. // and we're about to rewrite the entire structure of animation sets vs. clips vs. scene
  1142. // it's not worth polluting the leaf code just to save a couple cycles short term
  1143. int nCount = 0;
  1144. int nElements = m_AnimationSets.Count();
  1145. for ( int i = 0; i < nElements; ++i )
  1146. {
  1147. CDmElement *pElement = m_AnimationSets.Get( i );
  1148. if ( !pElement )
  1149. continue;
  1150. CDmeAnimationSet *pAnimSet = CastElement< CDmeAnimationSet >( pElement );
  1151. if ( pAnimSet )
  1152. {
  1153. ++nCount;
  1154. }
  1155. else
  1156. {
  1157. const CDmAttribute *pChildren = pElement->GetAttribute( "children", AT_ELEMENT_ARRAY );
  1158. if ( !pChildren )
  1159. continue;
  1160. CDmrElementArrayConst< CDmElement > array( pChildren );
  1161. nCount += array.Count();
  1162. }
  1163. }
  1164. return nCount;
  1165. }
  1166. CDmeAnimationSet *CDmeFilmClip::GetAnimationSet( int idx )
  1167. {
  1168. // yes, this is nasty perf-wise, but since we only have a dozen or so animation sets,
  1169. // and we're about to rewrite the entire structure of animation sets vs. clips vs. scene
  1170. // it's not worth polluting the leaf code just to save a couple cycles short term
  1171. int nElements = m_AnimationSets.Count();
  1172. for ( int i = 0; i < nElements; ++i )
  1173. {
  1174. CDmElement *pElement = m_AnimationSets.Get( i );
  1175. if ( !pElement )
  1176. continue;
  1177. CDmeAnimationSet *pAnimSet = CastElement< CDmeAnimationSet >( pElement );
  1178. if ( pAnimSet )
  1179. {
  1180. if ( idx == 0 )
  1181. return pAnimSet;
  1182. --idx;
  1183. }
  1184. else
  1185. {
  1186. const CDmAttribute *pChildren = pElement->GetAttribute( "children", AT_ELEMENT_ARRAY );
  1187. if ( !pChildren )
  1188. continue;
  1189. CDmrElementArrayConst< CDmElement > array( pChildren );
  1190. int nChildren = array.Count();
  1191. if ( idx < nChildren )
  1192. return CastElement< CDmeAnimationSet >( array[ idx ] );
  1193. idx -= nChildren;
  1194. }
  1195. }
  1196. return NULL;
  1197. }
  1198. void CDmeFilmClip::AddAnimationSet( CDmeAnimationSet *element )
  1199. {
  1200. m_AnimationSets.AddToTail( element );
  1201. }
  1202. void CDmeFilmClip::RemoveAllAnimationSets()
  1203. {
  1204. m_AnimationSets.RemoveAll();
  1205. }
  1206. CDmaElementArray< CDmElement > &CDmeFilmClip::GetAnimationSets()
  1207. {
  1208. return m_AnimationSets;
  1209. }
  1210. const CDmaElementArray< CDmElement > &CDmeFilmClip::GetAnimationSets() const
  1211. {
  1212. return m_AnimationSets;
  1213. }
  1214. const CDmaElementArray< CDmeBookmark > &CDmeFilmClip::GetBookmarks() const
  1215. {
  1216. return m_Bookmarks;
  1217. }
  1218. CDmaElementArray< CDmeBookmark > &CDmeFilmClip::GetBookmarks()
  1219. {
  1220. return m_Bookmarks;
  1221. }
  1222. //-----------------------------------------------------------------------------
  1223. // Used to move clips in non-film track groups with film clips
  1224. // Call BuildClipAssociations before modifying the film track,
  1225. // then UpdateAssociatedClips after modifying it.
  1226. //-----------------------------------------------------------------------------
  1227. void CDmeFilmClip::BuildClipAssociations( CUtlVector< ClipAssociation_t > &association, bool bHandleGaps )
  1228. {
  1229. association.RemoveAll();
  1230. CDmeTrack *pFilmTrack = GetFilmTrack();
  1231. if ( !pFilmTrack )
  1232. return;
  1233. int c = pFilmTrack->GetClipCount();
  1234. int gc = GetTrackGroupCount();
  1235. if ( c == 0 || gc == 0 )
  1236. return;
  1237. DmeTime_t clipStartTime = GetStartInChildMediaTime();
  1238. DmeTime_t clipEndTime = GetEndInChildMediaTime();
  1239. // These slugs will be removed in UpdateAssociatedClips
  1240. if ( bHandleGaps )
  1241. {
  1242. pFilmTrack->FillAllGapsWithSlugs( "__tempSlug__", clipStartTime, clipEndTime );
  1243. }
  1244. for ( int i = 0; i < gc; ++i )
  1245. {
  1246. CDmeTrackGroup *pTrackGroup = GetTrackGroup( i );
  1247. int tc = pTrackGroup->GetTrackCount();
  1248. for ( int j = 0; j < tc; ++j )
  1249. {
  1250. CDmeTrack *pTrack = pTrackGroup->GetTrack( j );
  1251. if ( !pTrack->IsSynched() )
  1252. continue;
  1253. // Only have visible tracks now
  1254. int cc = pTrack->GetClipCount();
  1255. association.EnsureCapacity( association.Count() + cc );
  1256. for ( int k = 0; k < cc; ++k )
  1257. {
  1258. CDmeClip *pClip = pTrack->GetClip( k );
  1259. CDmeClip *pFilmClip = pFilmTrack->FindFilmClipAtTime( pClip->GetStartTime() );
  1260. int nIndex = association.AddToTail();
  1261. association[nIndex].m_hClip = pClip;
  1262. association[nIndex].m_hAssociation = pFilmClip;
  1263. if ( pFilmClip )
  1264. {
  1265. association[nIndex].m_offset = pClip->GetStartTime() - pFilmClip->GetStartTime();
  1266. association[nIndex].m_nType = ClipAssociation_t::HAS_CLIP;
  1267. continue;
  1268. }
  1269. // Handle edge cases
  1270. if ( pClip->GetStartTime() <= clipStartTime )
  1271. {
  1272. association[nIndex].m_offset = pClip->GetStartTime() - clipStartTime;
  1273. association[nIndex].m_nType = ClipAssociation_t::BEFORE_START;
  1274. continue;
  1275. }
  1276. if ( pClip->GetStartTime() >= clipEndTime )
  1277. {
  1278. association[nIndex].m_offset = pClip->GetStartTime() - clipEndTime;
  1279. association[nIndex].m_nType = ClipAssociation_t::AFTER_END;
  1280. continue;
  1281. }
  1282. association[nIndex].m_offset = DmeTime_t( 0 );
  1283. association[nIndex].m_nType = ClipAssociation_t::NO_MOVEMENT;
  1284. }
  1285. }
  1286. }
  1287. }
  1288. //-----------------------------------------------------------------------------
  1289. // Rolls associated clips so they remain in the same relative time
  1290. //-----------------------------------------------------------------------------
  1291. void CDmeFilmClip::RollAssociatedClips( CDmeClip *pClip, CUtlVector< ClipAssociation_t > &association, DmeTime_t dt )
  1292. {
  1293. int c = association.Count();
  1294. for ( int i = 0; i < c; ++i )
  1295. {
  1296. if ( association[i].m_nType != ClipAssociation_t::HAS_CLIP )
  1297. continue;
  1298. if ( association[i].m_hAssociation.Get() != pClip )
  1299. continue;
  1300. DmeTime_t newStartTime = association[i].m_hClip->GetStartTime() - dt;
  1301. association[i].m_hClip->SetStartTime( newStartTime );
  1302. }
  1303. }
  1304. //-----------------------------------------------------------------------------
  1305. // Rolls associated clips so they remain in the same relative time
  1306. //-----------------------------------------------------------------------------
  1307. void CDmeFilmClip::ScaleAssociatedClips( CDmeClip *pClip, CUtlVector< ClipAssociation_t > &association, float ratio, DmeTime_t oldOffset )
  1308. {
  1309. int c = association.Count();
  1310. for ( int i = 0; i < c; ++i )
  1311. {
  1312. if ( association[i].m_nType != ClipAssociation_t::HAS_CLIP )
  1313. continue;
  1314. if ( association[i].m_hAssociation.Get() != pClip )
  1315. continue;
  1316. DmeTime_t clipStartTime = pClip->GetStartTime();
  1317. DmeTime_t oldStartTime = association[i].m_hClip->GetStartTime();
  1318. DmeTime_t newStartTime = ( oldStartTime - clipStartTime + oldOffset ) / ratio + clipStartTime - pClip->GetTimeOffset();
  1319. association[i].m_hClip->SetStartTime( newStartTime );
  1320. }
  1321. }
  1322. void CDmeFilmClip::UpdateAssociatedClips( CUtlVector< ClipAssociation_t > &association )
  1323. {
  1324. int i;
  1325. CDmeTrack *pFilmTrack = GetFilmTrack();
  1326. if ( !pFilmTrack )
  1327. return;
  1328. int c = association.Count();
  1329. if ( c > 0 )
  1330. {
  1331. DmeTime_t clipStartTime = GetStartInChildMediaTime();
  1332. DmeTime_t clipEndTime = GetEndInChildMediaTime();
  1333. for ( i = 0; i < c; ++i )
  1334. {
  1335. ClipAssociation_t &curr = association[i];
  1336. if ( !curr.m_hClip.Get() )
  1337. continue;
  1338. switch( curr.m_nType )
  1339. {
  1340. case ClipAssociation_t::HAS_CLIP:
  1341. if ( curr.m_hAssociation.Get() )
  1342. {
  1343. curr.m_hClip->SetStartTime( curr.m_hAssociation->GetStartTime() + curr.m_offset );
  1344. }
  1345. break;
  1346. case ClipAssociation_t::BEFORE_START:
  1347. curr.m_hClip->SetStartTime( clipStartTime + curr.m_offset );
  1348. break;
  1349. case ClipAssociation_t::AFTER_END:
  1350. curr.m_hClip->SetStartTime( clipEndTime + curr.m_offset );
  1351. break;
  1352. }
  1353. }
  1354. }
  1355. c = pFilmTrack->GetClipCount();
  1356. for ( i = c; --i >= 0; )
  1357. {
  1358. CDmeClip *pClip = pFilmTrack->GetClip(i);
  1359. if ( !Q_strcmp( pClip->GetName(), "__tempSlug__" ) )
  1360. {
  1361. pFilmTrack->RemoveClip( i );
  1362. }
  1363. }
  1364. }
  1365. //-----------------------------------------------------------------------------
  1366. // Creates a slug clip
  1367. //-----------------------------------------------------------------------------
  1368. CDmeFilmClip *CreateSlugClip( const char *pClipName, DmeTime_t startTime, DmeTime_t endTime, DmFileId_t fileid )
  1369. {
  1370. CDmeFilmClip *pSlugClip = CreateElement<CDmeFilmClip>( pClipName, fileid );
  1371. pSlugClip->GetTimeFrame()->SetName( "timeframe" );
  1372. pSlugClip->SetStartTime( startTime );
  1373. pSlugClip->SetDuration( endTime - startTime );
  1374. pSlugClip->SetTimeOffset( DmeTime_t( 0 ) );
  1375. pSlugClip->SetTimeScale( 1.0f );
  1376. pSlugClip->SetClipColor( Color( 0, 0, 0, 128 ) );
  1377. pSlugClip->SetOverlay( "vgui/black" );
  1378. return pSlugClip;
  1379. }
  1380. //-----------------------------------------------------------------------------
  1381. // helper methods
  1382. //-----------------------------------------------------------------------------
  1383. CDmeTrack *GetParentTrack( CDmeClip *pClip )
  1384. {
  1385. DmAttributeReferenceIterator_t hAttr = g_pDataModel->FirstAttributeReferencingElement( pClip->GetHandle() );
  1386. for ( ; hAttr != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; hAttr = g_pDataModel->NextAttributeReferencingElement( hAttr ) )
  1387. {
  1388. CDmAttribute *pAttr = g_pDataModel->GetAttribute( hAttr );
  1389. if ( !pAttr )
  1390. continue;
  1391. CDmeTrack *pTrack = CastElement< CDmeTrack >( pAttr->GetOwner() );
  1392. if ( pTrack )
  1393. return pTrack;
  1394. }
  1395. return NULL;
  1396. }
  1397. //-----------------------------------------------------------------------------
  1398. // Finds a channel in a channel or film clip targetting a particular element
  1399. //-----------------------------------------------------------------------------
  1400. CDmeChannel *FindChannelTargetingElement( CDmeChannelsClip *pChannelsClip, CDmElement *pElement, const char *pAttributeName )
  1401. {
  1402. int nChannels = pChannelsClip->m_Channels.Count();
  1403. for ( int i = 0; i < nChannels; ++i )
  1404. {
  1405. CDmeChannel *pChannel = pChannelsClip->m_Channels[ i ];
  1406. CDmElement *toElement = pChannel->GetToElement();
  1407. if ( toElement != pElement )
  1408. continue;
  1409. if ( pAttributeName && ( Q_stricmp( pChannel->GetToAttribute()->GetName(), pAttributeName ) != 0 ) )
  1410. continue;
  1411. return pChannel;
  1412. }
  1413. return NULL;
  1414. }
  1415. CDmeChannel *FindChannelTargetingElement( CDmeFilmClip *pClip, CDmElement *pElement, const char *pAttributeName, CDmeChannelsClip **ppChannelsClip, CDmeTrack **ppTrack, CDmeTrackGroup **ppTrackGroup )
  1416. {
  1417. int gc = pClip->GetTrackGroupCount();
  1418. for ( int i = 0; i < gc; ++i )
  1419. {
  1420. CDmeTrackGroup *pTrackGroup = pClip->GetTrackGroup( i );
  1421. DMETRACKGROUP_FOREACH_CLIP_TYPE_START( CDmeChannelsClip, pTrackGroup, pTrack, pChannelsClip )
  1422. CDmeChannel *pChannel = FindChannelTargetingElement( pChannelsClip, pElement, pAttributeName );
  1423. if ( !pChannel )
  1424. continue;
  1425. if ( ppChannelsClip )
  1426. {
  1427. *ppChannelsClip = pChannelsClip;
  1428. }
  1429. if ( ppTrack )
  1430. {
  1431. *ppTrack = pTrack;
  1432. }
  1433. if ( ppTrackGroup )
  1434. {
  1435. *ppTrackGroup = pTrackGroup;
  1436. }
  1437. return pChannel;
  1438. DMETRACKGROUP_FOREACH_CLIP_TYPE_END()
  1439. }
  1440. return NULL;
  1441. }