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.

4528 lines
115 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "tier0/dbg.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include "choreoevent.h"
  12. #include "choreoactor.h"
  13. #include "choreochannel.h"
  14. #include "mathlib/mathlib.h"
  15. #include "tier1/strtools.h"
  16. #include "choreoscene.h"
  17. #include "ichoreoeventcallback.h"
  18. #include "tier1/utlbuffer.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. int CChoreoEvent::s_nGlobalID = 1;
  22. //-----------------------------------------------------------------------------
  23. // Purpose:
  24. // Input : *owner -
  25. // *name -
  26. // percentage -
  27. //-----------------------------------------------------------------------------
  28. CEventRelativeTag::CEventRelativeTag( CChoreoEvent *owner, const char *name, float percentage )
  29. {
  30. Assert( owner );
  31. Assert( name );
  32. Assert( percentage >= 0.0f );
  33. Assert( percentage <= 1.0f );
  34. m_Name = name;
  35. m_flPercentage = percentage;
  36. m_pOwner = owner;
  37. }
  38. //-----------------------------------------------------------------------------
  39. // Purpose:
  40. // Input : src -
  41. //-----------------------------------------------------------------------------
  42. CEventRelativeTag::CEventRelativeTag( const CEventRelativeTag& src )
  43. {
  44. m_Name = src.m_Name;
  45. m_flPercentage = src.m_flPercentage;
  46. m_pOwner = src.m_pOwner;
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose:
  50. // Output : const char
  51. //-----------------------------------------------------------------------------
  52. const char *CEventRelativeTag::GetName( void )
  53. {
  54. return m_Name.Get();
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose:
  58. // Output : float
  59. //-----------------------------------------------------------------------------
  60. float CEventRelativeTag::GetPercentage( void )
  61. {
  62. return m_flPercentage;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose:
  66. // Input : percentage -
  67. //-----------------------------------------------------------------------------
  68. void CEventRelativeTag::SetPercentage( float percentage )
  69. {
  70. m_flPercentage = percentage;
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. // Output : CChoreoEvent
  75. //-----------------------------------------------------------------------------
  76. CChoreoEvent *CEventRelativeTag::GetOwner( void )
  77. {
  78. return m_pOwner;
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. // Input : *event -
  83. //-----------------------------------------------------------------------------
  84. void CEventRelativeTag::SetOwner( CChoreoEvent *event )
  85. {
  86. m_pOwner = event;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Purpose: Returns the corrected time based on the owner's length and start time
  90. // Output : float
  91. //-----------------------------------------------------------------------------
  92. float CEventRelativeTag::GetStartTime( void )
  93. {
  94. Assert( m_pOwner );
  95. if ( !m_pOwner )
  96. {
  97. return 0.0f;
  98. }
  99. float ownerstart = m_pOwner->GetStartTime();
  100. float ownerduration = m_pOwner->GetDuration();
  101. return ( ownerstart + ownerduration * m_flPercentage );
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Purpose:
  105. // Input : *owner -
  106. // *name -
  107. // percentage -
  108. //-----------------------------------------------------------------------------
  109. CFlexTimingTag::CFlexTimingTag( CChoreoEvent *owner, const char *name, float percentage, bool locked )
  110. : BaseClass( owner, name, percentage )
  111. {
  112. m_bLocked = locked;
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose:
  116. // Input : src -
  117. //-----------------------------------------------------------------------------
  118. CFlexTimingTag::CFlexTimingTag( const CFlexTimingTag& src )
  119. : BaseClass( src )
  120. {
  121. m_bLocked = src.m_bLocked;
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Purpose:
  125. // Output : Returns true on success, false on failure.
  126. //-----------------------------------------------------------------------------
  127. bool CFlexTimingTag::GetLocked( void )
  128. {
  129. return m_bLocked;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Purpose:
  133. // Input : locked -
  134. //-----------------------------------------------------------------------------
  135. void CFlexTimingTag::SetLocked( bool locked )
  136. {
  137. m_bLocked = locked;
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Purpose:
  141. // Input : *owner -
  142. // *name -
  143. // percentage -
  144. //-----------------------------------------------------------------------------
  145. CEventAbsoluteTag::CEventAbsoluteTag( CChoreoEvent *owner, const char *name, float t )
  146. {
  147. Assert( owner );
  148. Assert( name );
  149. Assert( t >= 0.0f );
  150. m_Name = name;
  151. m_flPercentage = t;
  152. m_pOwner = owner;
  153. m_bLocked = false;
  154. m_bLinear = false;
  155. m_bEntry = false;
  156. m_bExit = false;
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Purpose:
  160. // Input : src -
  161. //-----------------------------------------------------------------------------
  162. CEventAbsoluteTag::CEventAbsoluteTag( const CEventAbsoluteTag& src )
  163. {
  164. m_Name = src.m_Name;
  165. m_flPercentage = src.m_flPercentage;
  166. m_pOwner = src.m_pOwner;
  167. m_bLocked = src.m_bLocked;
  168. m_bLinear = src.m_bLinear;
  169. m_bEntry = src.m_bEntry;
  170. m_bExit = src.m_bExit;
  171. }
  172. //-----------------------------------------------------------------------------
  173. // Purpose:
  174. // Output : const char
  175. //-----------------------------------------------------------------------------
  176. const char *CEventAbsoluteTag::GetName( void )
  177. {
  178. return m_Name.Get();
  179. }
  180. //-----------------------------------------------------------------------------
  181. // Purpose:
  182. // Output : float
  183. //-----------------------------------------------------------------------------
  184. float CEventAbsoluteTag::GetPercentage( void )
  185. {
  186. return m_flPercentage;
  187. }
  188. //-----------------------------------------------------------------------------
  189. // Purpose:
  190. // Input : percentage -
  191. //-----------------------------------------------------------------------------
  192. void CEventAbsoluteTag::SetPercentage( float percentage )
  193. {
  194. m_flPercentage = percentage;
  195. }
  196. //-----------------------------------------------------------------------------
  197. // Purpose:
  198. // Output : float
  199. //-----------------------------------------------------------------------------
  200. float CEventAbsoluteTag::GetEventTime( void )
  201. {
  202. Assert( m_pOwner );
  203. if ( !m_pOwner )
  204. {
  205. return 0.0f;
  206. }
  207. float ownerduration = m_pOwner->GetDuration();
  208. return (m_flPercentage * ownerduration);
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Purpose:
  212. // Input : percentage -
  213. //-----------------------------------------------------------------------------
  214. void CEventAbsoluteTag::SetEventTime( float t )
  215. {
  216. Assert( m_pOwner );
  217. if ( !m_pOwner )
  218. {
  219. return;
  220. }
  221. float ownerduration = m_pOwner->GetDuration();
  222. m_flPercentage = (t / ownerduration);
  223. }
  224. //-----------------------------------------------------------------------------
  225. // Purpose:
  226. // Output : float
  227. //-----------------------------------------------------------------------------
  228. float CEventAbsoluteTag::GetAbsoluteTime( void )
  229. {
  230. Assert( m_pOwner );
  231. if ( !m_pOwner )
  232. {
  233. return 0.0f;
  234. }
  235. float ownerstart = m_pOwner->GetStartTime();
  236. float ownerduration = m_pOwner->GetDuration();
  237. return (ownerstart + m_flPercentage * ownerduration);
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose:
  241. // Input : percentage -
  242. //-----------------------------------------------------------------------------
  243. void CEventAbsoluteTag::SetAbsoluteTime( float t )
  244. {
  245. Assert( m_pOwner );
  246. if ( !m_pOwner )
  247. {
  248. return;
  249. }
  250. float ownerstart = m_pOwner->GetStartTime();
  251. float ownerduration = m_pOwner->GetDuration();
  252. m_flPercentage = (t - ownerstart) / ownerduration;
  253. }
  254. //-----------------------------------------------------------------------------
  255. // Purpose:
  256. // Output : CChoreoEvent
  257. //-----------------------------------------------------------------------------
  258. CChoreoEvent *CEventAbsoluteTag::GetOwner( void )
  259. {
  260. return m_pOwner;
  261. }
  262. //-----------------------------------------------------------------------------
  263. // Purpose:
  264. // Input : *event -
  265. //-----------------------------------------------------------------------------
  266. void CEventAbsoluteTag::SetOwner( CChoreoEvent *event )
  267. {
  268. m_pOwner = event;
  269. }
  270. //-----------------------------------------------------------------------------
  271. // Purpose:
  272. // Input : *event -
  273. //-----------------------------------------------------------------------------
  274. void CEventAbsoluteTag::SetLocked( bool bLocked )
  275. {
  276. m_bLocked = bLocked;
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Purpose:
  280. // Output : CChoreoEvent
  281. //-----------------------------------------------------------------------------
  282. bool CEventAbsoluteTag::GetLocked( void )
  283. {
  284. return m_bLocked;
  285. }
  286. //-----------------------------------------------------------------------------
  287. // Purpose:
  288. // Input : *event -
  289. //-----------------------------------------------------------------------------
  290. void CEventAbsoluteTag::SetLinear( bool bLinear )
  291. {
  292. m_bLinear = bLinear;
  293. }
  294. //-----------------------------------------------------------------------------
  295. // Purpose:
  296. // Output : CChoreoEvent
  297. //-----------------------------------------------------------------------------
  298. bool CEventAbsoluteTag::GetLinear( void )
  299. {
  300. return m_bLinear;
  301. }
  302. //-----------------------------------------------------------------------------
  303. // Purpose:
  304. // Input : *event -
  305. //-----------------------------------------------------------------------------
  306. void CEventAbsoluteTag::SetEntry( bool bEntry )
  307. {
  308. m_bEntry = bEntry;
  309. }
  310. //-----------------------------------------------------------------------------
  311. // Purpose:
  312. // Output : CChoreoEvent
  313. //-----------------------------------------------------------------------------
  314. bool CEventAbsoluteTag::GetEntry( void )
  315. {
  316. return m_bEntry;
  317. }
  318. //-----------------------------------------------------------------------------
  319. // Purpose:
  320. // Input : *event -
  321. //-----------------------------------------------------------------------------
  322. void CEventAbsoluteTag::SetExit( bool bExit )
  323. {
  324. m_bExit = bExit;
  325. }
  326. //-----------------------------------------------------------------------------
  327. // Purpose:
  328. // Output : CChoreoEvent
  329. //-----------------------------------------------------------------------------
  330. bool CEventAbsoluteTag::GetExit( void )
  331. {
  332. return m_bExit;
  333. }
  334. // FLEX ANIMATIONS
  335. //-----------------------------------------------------------------------------
  336. // Purpose: Constructor
  337. // Input : *event -
  338. //-----------------------------------------------------------------------------
  339. CFlexAnimationTrack::CFlexAnimationTrack( CChoreoEvent *event )
  340. {
  341. m_pEvent = event;
  342. m_pControllerName = NULL;
  343. m_bActive = false;
  344. m_bCombo = false;
  345. m_bServerSide = false;
  346. m_nFlexControllerIndex[ 0 ] = m_nFlexControllerIndex[ 1 ] = -1;
  347. m_nFlexControllerIndexRaw[ 0 ] = m_nFlexControllerIndexRaw[ 1 ] = LocalFlexController_t(-1);
  348. // base track has range, combo is always 0..1
  349. m_flMin = 0.0f;
  350. m_flMax = 0.0f;
  351. }
  352. //-----------------------------------------------------------------------------
  353. // Purpose:
  354. // Input : src -
  355. //-----------------------------------------------------------------------------
  356. CFlexAnimationTrack::CFlexAnimationTrack( const CFlexAnimationTrack* src )
  357. {
  358. m_pControllerName = NULL;
  359. SetFlexControllerName( src->m_pControllerName ? src->m_pControllerName : "" );
  360. m_bActive = src->m_bActive;
  361. m_bCombo = src->m_bCombo;
  362. m_bServerSide = src->m_bServerSide;
  363. for ( int t = 0; t < 2; t++ )
  364. {
  365. m_Samples[ t ].Purge();
  366. for ( int i = 0 ;i < src->m_Samples[ t ].Count(); i++ )
  367. {
  368. CExpressionSample s = src->m_Samples[ t ][ i ];
  369. m_Samples[ t ].AddToTail( s );
  370. }
  371. }
  372. for ( int side = 0; side < 2; side++ )
  373. {
  374. m_nFlexControllerIndex[ side ] = src->m_nFlexControllerIndex[ side ];
  375. m_nFlexControllerIndexRaw[ side ] = src->m_nFlexControllerIndexRaw[ side ];
  376. }
  377. m_flMin = src->m_flMin;
  378. m_flMax = src->m_flMax;
  379. m_EdgeInfo[ 0 ] = src->m_EdgeInfo[ 0 ];
  380. m_EdgeInfo[ 1 ] = src->m_EdgeInfo[ 1 ];
  381. m_pEvent = NULL;
  382. }
  383. //-----------------------------------------------------------------------------
  384. // Purpose:
  385. //-----------------------------------------------------------------------------
  386. CFlexAnimationTrack::~CFlexAnimationTrack( void )
  387. {
  388. delete[] m_pControllerName;
  389. for ( int t = 0; t < 2; t++ )
  390. {
  391. m_Samples[ t ].Purge();
  392. }
  393. }
  394. //-----------------------------------------------------------------------------
  395. // Purpose:
  396. // Input : *event -
  397. //-----------------------------------------------------------------------------
  398. void CFlexAnimationTrack::SetEvent( CChoreoEvent *event )
  399. {
  400. m_pEvent = event;
  401. }
  402. //-----------------------------------------------------------------------------
  403. // Purpose:
  404. //-----------------------------------------------------------------------------
  405. void CFlexAnimationTrack::Clear( void )
  406. {
  407. for ( int t = 0; t < 2; t++ )
  408. {
  409. m_Samples[ t ].RemoveAll();
  410. }
  411. }
  412. //-----------------------------------------------------------------------------
  413. // Purpose:
  414. // Input : index -
  415. //-----------------------------------------------------------------------------
  416. void CFlexAnimationTrack::RemoveSample( int index, int type /*=0*/ )
  417. {
  418. Assert( type == 0 || type == 1 );
  419. m_Samples[ type ].Remove( index );
  420. }
  421. //-----------------------------------------------------------------------------
  422. // Purpose:
  423. // Input : *name -
  424. //-----------------------------------------------------------------------------
  425. void CFlexAnimationTrack::SetFlexControllerName( const char *name )
  426. {
  427. delete[] m_pControllerName;
  428. int len = Q_strlen( name ) + 1;
  429. m_pControllerName = new char[ len ];
  430. Q_strncpy( m_pControllerName, name, len );
  431. }
  432. //-----------------------------------------------------------------------------
  433. // Purpose:
  434. // Output : char const
  435. //-----------------------------------------------------------------------------
  436. const char *CFlexAnimationTrack::GetFlexControllerName( void )
  437. {
  438. return m_pControllerName ? m_pControllerName : "";
  439. }
  440. //-----------------------------------------------------------------------------
  441. // Purpose:
  442. // Output : int
  443. //-----------------------------------------------------------------------------
  444. int CFlexAnimationTrack::GetNumSamples( int type /*=0*/ )
  445. {
  446. Assert( type == 0 || type == 1 );
  447. return m_Samples[ type ].Count();
  448. }
  449. //-----------------------------------------------------------------------------
  450. // Purpose:
  451. // Input : index -
  452. // Output : CExpressionSample
  453. //-----------------------------------------------------------------------------
  454. CExpressionSample *CFlexAnimationTrack::GetSample( int index, int type /*=0*/ )
  455. {
  456. Assert( type == 0 || type == 1 );
  457. if ( index < 0 || index >= GetNumSamples( type ) )
  458. return NULL;
  459. return &m_Samples[ type ][ index ];
  460. }
  461. //-----------------------------------------------------------------------------
  462. // Purpose:
  463. // Output : Returns true on success, false on failure.
  464. //-----------------------------------------------------------------------------
  465. bool CFlexAnimationTrack::IsTrackActive( void )
  466. {
  467. return m_bActive;
  468. }
  469. //-----------------------------------------------------------------------------
  470. // Purpose:
  471. // Input : active -
  472. //-----------------------------------------------------------------------------
  473. void CFlexAnimationTrack::SetTrackActive( bool active )
  474. {
  475. m_bActive = active;
  476. }
  477. void CFlexAnimationTrack::SetEdgeInfo( bool leftEdge, int curveType, float zero )
  478. {
  479. int idx = leftEdge ? 0 : 1;
  480. m_EdgeInfo[ idx ].m_CurveType = curveType;
  481. m_EdgeInfo[ idx ].m_flZeroPos = zero;
  482. }
  483. void CFlexAnimationTrack::GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const
  484. {
  485. int idx = leftEdge ? 0 : 1;
  486. curveType = m_EdgeInfo[ idx ].m_CurveType;
  487. zero = m_EdgeInfo[ idx ].m_flZeroPos;
  488. }
  489. void CFlexAnimationTrack::SetEdgeActive( bool leftEdge, bool state )
  490. {
  491. int idx = leftEdge ? 0 : 1;
  492. m_EdgeInfo[ idx ].m_bActive = state;
  493. }
  494. bool CFlexAnimationTrack::IsEdgeActive( bool leftEdge ) const
  495. {
  496. int idx = leftEdge ? 0 : 1;
  497. return m_EdgeInfo[ idx ].m_bActive;
  498. }
  499. int CFlexAnimationTrack::GetEdgeCurveType( bool leftEdge ) const
  500. {
  501. if ( !IsEdgeActive( leftEdge ) )
  502. {
  503. return CURVE_DEFAULT;
  504. }
  505. int idx = leftEdge ? 0 : 1;
  506. return m_EdgeInfo[ idx ].m_CurveType;
  507. }
  508. float CFlexAnimationTrack::GetEdgeZeroValue( bool leftEdge ) const
  509. {
  510. if ( !IsEdgeActive( leftEdge ) )
  511. {
  512. return 0.0f;
  513. }
  514. int idx = leftEdge ? 0 : 1;
  515. return m_EdgeInfo[ idx ].m_flZeroPos;
  516. }
  517. float CFlexAnimationTrack::GetDefaultEdgeZeroPos() const
  518. {
  519. float zero = 0.0f;
  520. if ( m_flMin != m_flMax )
  521. {
  522. zero = ( 0.0f - m_flMin ) / ( m_flMax - m_flMin );
  523. }
  524. return zero;
  525. }
  526. //-----------------------------------------------------------------------------
  527. // Purpose:
  528. //-----------------------------------------------------------------------------
  529. float CFlexAnimationTrack::GetZeroValue( int type, bool leftSide )
  530. {
  531. // Stereo track is always clamped to 0.5 and doesn't care about l/r settings
  532. if ( type == 1 )
  533. {
  534. return 0.5f;
  535. }
  536. if ( IsEdgeActive( leftSide ) )
  537. {
  538. return GetEdgeZeroValue( leftSide );
  539. }
  540. return GetDefaultEdgeZeroPos();
  541. }
  542. //-----------------------------------------------------------------------------
  543. // Purpose:
  544. // Input : number -
  545. // Output : CExpressionSample
  546. //-----------------------------------------------------------------------------
  547. CExpressionSample *CFlexAnimationTrack::GetBoundedSample( int number, bool& bClamped, int type /*=0*/ )
  548. {
  549. Assert( type == 0 || type == 1 );
  550. if ( number < 0 )
  551. {
  552. // Search for two samples which span time f
  553. static CExpressionSample nullstart;
  554. nullstart.time = 0.0f;
  555. nullstart.value = GetZeroValue( type, true );
  556. if ( type == 0 )
  557. {
  558. nullstart.SetCurveType( GetEdgeCurveType( true ) );
  559. }
  560. else
  561. {
  562. nullstart.SetCurveType( CURVE_DEFAULT );
  563. }
  564. bClamped = true;
  565. return &nullstart;
  566. }
  567. else if ( number >= GetNumSamples( type ) )
  568. {
  569. static CExpressionSample nullend;
  570. nullend.time = m_pEvent->GetDuration();
  571. nullend.value = GetZeroValue( type, false );
  572. if ( type == 0 )
  573. {
  574. nullend.SetCurveType( GetEdgeCurveType( false ) );
  575. }
  576. else
  577. {
  578. nullend.SetCurveType( CURVE_DEFAULT );
  579. }
  580. bClamped = true;
  581. return &nullend;
  582. }
  583. bClamped = false;
  584. return GetSample( number, type );
  585. }
  586. //-----------------------------------------------------------------------------
  587. // Purpose:
  588. // Input : time -
  589. // type -
  590. // Output : float
  591. //-----------------------------------------------------------------------------
  592. float CFlexAnimationTrack::GetIntensityInternal( float time, int type )
  593. {
  594. Assert( type == 0 || type == 1 );
  595. float retval = 0.0f;
  596. // find samples that span the time
  597. if ( !m_pEvent || !m_pEvent->HasEndTime() || time < m_pEvent->GetStartTime() )
  598. {
  599. retval = GetZeroValue( type, true );;
  600. }
  601. else if ( time > m_pEvent->GetEndTime() )
  602. {
  603. retval = GetZeroValue( type, false );;
  604. }
  605. else
  606. {
  607. float elapsed = time - m_pEvent->GetStartTime();
  608. retval = GetFracIntensity( elapsed, type );
  609. }
  610. // scale
  611. if (type == 0 && m_flMin != m_flMax)
  612. {
  613. retval = retval * (m_flMax - m_flMin) + m_flMin;
  614. }
  615. return retval;
  616. }
  617. //-----------------------------------------------------------------------------
  618. // Purpose:
  619. // Input : time -
  620. // type -
  621. // Output : float
  622. //-----------------------------------------------------------------------------
  623. float CFlexAnimationTrack::GetFracIntensity( float time, int type )
  624. {
  625. float zeroValueLeft = GetZeroValue( type, true );
  626. Assert( type == 0 || type == 1 );
  627. // find samples that span the time
  628. if ( !m_pEvent || !m_pEvent->HasEndTime() )
  629. return zeroValueLeft;
  630. int rampCount = GetNumSamples( type );
  631. if ( rampCount < 1 )
  632. {
  633. return zeroValueLeft;
  634. }
  635. CExpressionSample *esStart = NULL;
  636. CExpressionSample *esEnd = NULL;
  637. // do binary search for sample in time period
  638. int j = MAX( rampCount / 2, 1 );
  639. int i = j;
  640. while ( i > -2 && i < rampCount + 1 )
  641. {
  642. bool dummy;
  643. esStart = GetBoundedSample( i, dummy, type );
  644. esEnd = GetBoundedSample( i + 1, dummy, type );
  645. j = MAX( j / 2, 1 );
  646. if ( time < esStart->time)
  647. {
  648. i -= j;
  649. }
  650. else if ( time > esEnd->time)
  651. {
  652. i += j;
  653. }
  654. else
  655. {
  656. if ( time == esEnd->time )
  657. {
  658. ++i;
  659. esStart = GetBoundedSample( i, dummy, type );
  660. esEnd = GetBoundedSample( i + 1, dummy, type );
  661. }
  662. break;
  663. }
  664. }
  665. if (!esStart)
  666. {
  667. return zeroValueLeft;
  668. }
  669. int prev = i - 1;
  670. int next = i + 2;
  671. prev = MAX( -1, prev );
  672. next = MIN( next, rampCount );
  673. bool bBoundedSampleClamped[ 2 ];
  674. CExpressionSample *esPre = GetBoundedSample( prev, bBoundedSampleClamped[ 0 ], type );
  675. CExpressionSample *esNext = GetBoundedSample( next, bBoundedSampleClamped[ 1 ], type );
  676. float dt = esEnd->time - esStart->time;
  677. Vector vPre( esPre->time, esPre->value, 0 );
  678. Vector vStart( esStart->time, esStart->value, 0 );
  679. Vector vEnd( esEnd->time, esEnd->value, 0 );
  680. Vector vNext( esNext->time, esNext->value, 0 );
  681. float f2 = 0.0f;
  682. if ( dt > 0.0f )
  683. {
  684. f2 = ( time - esStart->time ) / ( dt );
  685. }
  686. f2 = clamp( f2, 0.0f, 1.0f );
  687. Vector vOut;
  688. int dummy;
  689. int earlypart, laterpart;
  690. // Not holding out value of previous curve...
  691. Interpolator_CurveInterpolatorsForType( esStart->GetCurveType(), dummy, earlypart );
  692. Interpolator_CurveInterpolatorsForType( esEnd->GetCurveType(), laterpart, dummy );
  693. if ( earlypart == INTERPOLATE_HOLD )
  694. {
  695. // Hold "out" of previous sample (can cause a discontinuity)
  696. VectorLerp( vStart, vEnd, f2, vOut );
  697. vOut.y = vStart.y;
  698. }
  699. else if ( laterpart == INTERPOLATE_HOLD )
  700. {
  701. // Hold "out" of previous sample (can cause a discontinuity)
  702. VectorLerp( vStart, vEnd, f2, vOut );
  703. vOut.y = vEnd.y;
  704. }
  705. else
  706. {
  707. bool sameCurveType = earlypart == laterpart ? true : false;
  708. if ( sameCurveType )
  709. {
  710. Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut );
  711. }
  712. else // curves differ, sigh
  713. {
  714. Vector vOut1, vOut2;
  715. Interpolator_CurveInterpolate( earlypart, vPre, vStart, vEnd, vNext, f2, vOut1 );
  716. Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut2 );
  717. VectorLerp( vOut1, vOut2, f2, vOut );
  718. }
  719. }
  720. float retval = clamp( vOut.y, 0.0f, 1.0f );
  721. return retval;
  722. }
  723. //-----------------------------------------------------------------------------
  724. // Purpose:
  725. // Input : time -
  726. // Output : float
  727. //-----------------------------------------------------------------------------
  728. float CFlexAnimationTrack::GetSampleIntensity( float time )
  729. {
  730. return GetIntensityInternal( time, 0 );
  731. }
  732. //-----------------------------------------------------------------------------
  733. // Purpose:
  734. // Input : time -
  735. // Output : float
  736. //-----------------------------------------------------------------------------
  737. float CFlexAnimationTrack::GetBalanceIntensity( float time )
  738. {
  739. if ( IsComboType() )
  740. {
  741. return GetIntensityInternal( time, 1 );
  742. }
  743. return 1.0f;
  744. }
  745. // For a given time, computes 0->1 intensity value for the slider
  746. //-----------------------------------------------------------------------------
  747. // Purpose:
  748. // Input : time -
  749. // Output : float
  750. //-----------------------------------------------------------------------------
  751. float CFlexAnimationTrack::GetIntensity( float time, int side )
  752. {
  753. float mag = GetSampleIntensity( time );
  754. float scale = 1.0f;
  755. if ( IsComboType() )
  756. {
  757. float balance = GetBalanceIntensity( time );
  758. // Asking for left but balance is to right, then fall off as we go
  759. // further right
  760. if ( side == 0 && balance > 0.5f )
  761. {
  762. scale = (1.0f - balance ) / 0.5f;
  763. }
  764. // Asking for right, but balance is left, fall off as we go left.
  765. else if ( side == 1 && balance < 0.5f )
  766. {
  767. scale = ( balance / 0.5f );
  768. }
  769. }
  770. return mag * scale;
  771. }
  772. //-----------------------------------------------------------------------------
  773. // Purpose:
  774. // Input : time -
  775. // value -
  776. //-----------------------------------------------------------------------------
  777. CExpressionSample *CFlexAnimationTrack::AddSample( float time, float value, int type /*=0*/ )
  778. {
  779. Assert( type == 0 || type == 1 );
  780. CExpressionSample sample;
  781. sample.time = time;
  782. sample.value = value;
  783. sample.selected = false;
  784. int idx = m_Samples[ type ].AddToTail( sample );
  785. // Resort( type );
  786. return &m_Samples[ type ][ idx ];
  787. }
  788. //-----------------------------------------------------------------------------
  789. // Purpose:
  790. //-----------------------------------------------------------------------------
  791. void CFlexAnimationTrack::Resort( int type /*=0*/ )
  792. {
  793. Assert( type == 0 || type == 1 );
  794. for ( int i = 0; i < m_Samples[ type ].Count(); i++ )
  795. {
  796. for ( int j = i + 1; j < m_Samples[ type ].Count(); j++ )
  797. {
  798. CExpressionSample src = m_Samples[ type ][ i ];
  799. CExpressionSample dest = m_Samples[ type ][ j ];
  800. if ( src.time > dest.time )
  801. {
  802. m_Samples[ type ][ i ] = dest;
  803. m_Samples[ type ][ j ] = src;
  804. }
  805. }
  806. }
  807. // Make sure nothing is out of range
  808. RemoveOutOfRangeSamples( 0 );
  809. RemoveOutOfRangeSamples( 1 );
  810. }
  811. //-----------------------------------------------------------------------------
  812. // Purpose:
  813. // Output : CChoreoEvent
  814. //-----------------------------------------------------------------------------
  815. CChoreoEvent *CFlexAnimationTrack::GetEvent( void )
  816. {
  817. return m_pEvent;
  818. }
  819. //-----------------------------------------------------------------------------
  820. // Purpose:
  821. // Input : side -
  822. // Output : int
  823. //-----------------------------------------------------------------------------
  824. int CFlexAnimationTrack::GetFlexControllerIndex( int side /*= 0*/ )
  825. {
  826. Assert( side == 0 || side == 1 );
  827. if ( IsComboType() )
  828. {
  829. return m_nFlexControllerIndex[ side ];
  830. }
  831. return m_nFlexControllerIndex[ 0 ];
  832. }
  833. //-----------------------------------------------------------------------------
  834. // Purpose:
  835. // Input : side -
  836. // Output : int
  837. //-----------------------------------------------------------------------------
  838. LocalFlexController_t CFlexAnimationTrack::GetRawFlexControllerIndex( int side /*= 0*/ )
  839. {
  840. Assert( side == 0 || side == 1 );
  841. if ( IsComboType() )
  842. {
  843. return m_nFlexControllerIndexRaw[ side ];
  844. }
  845. return m_nFlexControllerIndexRaw[ 0 ];
  846. }
  847. //-----------------------------------------------------------------------------
  848. // Purpose:
  849. // Input : index -
  850. // side -
  851. //-----------------------------------------------------------------------------
  852. void CFlexAnimationTrack::SetFlexControllerIndex( LocalFlexController_t raw, int index, int side /*= 0*/ )
  853. {
  854. Assert( side == 0 || side == 1 );
  855. m_nFlexControllerIndex[ side ] = index;
  856. // Model specific
  857. m_nFlexControllerIndexRaw[ side ] = raw;
  858. }
  859. //-----------------------------------------------------------------------------
  860. // Purpose:
  861. // Input : combo -
  862. //-----------------------------------------------------------------------------
  863. void CFlexAnimationTrack::SetComboType( bool combo )
  864. {
  865. m_bCombo = combo;
  866. }
  867. //-----------------------------------------------------------------------------
  868. // Purpose:
  869. // Output : Returns true on success, false on failure.
  870. //-----------------------------------------------------------------------------
  871. bool CFlexAnimationTrack::IsComboType( void )
  872. {
  873. return m_bCombo;
  874. }
  875. //-----------------------------------------------------------------------------
  876. // Purpose: True if this should be simulated on the server side always
  877. // Input : state -
  878. //-----------------------------------------------------------------------------
  879. void CFlexAnimationTrack::SetServerSide( bool state )
  880. {
  881. m_bServerSide = state;
  882. }
  883. //-----------------------------------------------------------------------------
  884. // Purpose:
  885. // Input : -
  886. // Output : Returns true on success, false on failure.
  887. //-----------------------------------------------------------------------------
  888. bool CFlexAnimationTrack::IsServerSide() const
  889. {
  890. return m_bServerSide;
  891. }
  892. //-----------------------------------------------------------------------------
  893. // Purpose:
  894. //-----------------------------------------------------------------------------
  895. void CFlexAnimationTrack::SetMin( float value )
  896. {
  897. m_flMin = value;
  898. }
  899. //-----------------------------------------------------------------------------
  900. // Purpose:
  901. //-----------------------------------------------------------------------------
  902. void CFlexAnimationTrack::SetMax( float value )
  903. {
  904. m_flMax = value;
  905. }
  906. //-----------------------------------------------------------------------------
  907. // Purpose:
  908. //-----------------------------------------------------------------------------
  909. float CFlexAnimationTrack::GetMin( int type )
  910. {
  911. if (type == 0)
  912. return m_flMin;
  913. else
  914. return 0.0f;
  915. }
  916. //-----------------------------------------------------------------------------
  917. // Purpose:
  918. //-----------------------------------------------------------------------------
  919. float CFlexAnimationTrack::GetMax( int type )
  920. {
  921. if (type == 0)
  922. return m_flMax;
  923. else
  924. return 1.0f;
  925. }
  926. //-----------------------------------------------------------------------------
  927. // Purpose:
  928. //-----------------------------------------------------------------------------
  929. bool CFlexAnimationTrack::IsInverted( void )
  930. {
  931. if (m_bInverted)
  932. return true;
  933. return false;
  934. }
  935. //-----------------------------------------------------------------------------
  936. // Purpose:
  937. //-----------------------------------------------------------------------------
  938. void CFlexAnimationTrack::SetInverted( bool isInverted )
  939. {
  940. m_bInverted = isInverted;
  941. }
  942. //-----------------------------------------------------------------------------
  943. // Purpose:
  944. // Output : float
  945. //-----------------------------------------------------------------------------
  946. void CFlexAnimationTrack::RemoveOutOfRangeSamples( int type )
  947. {
  948. Assert( m_pEvent );
  949. if ( !m_pEvent )
  950. return;
  951. Assert( m_pEvent->HasEndTime() );
  952. float duration = m_pEvent->GetDuration();
  953. int c = m_Samples[ type ].Count();
  954. for ( int i = c-1; i >= 0; i-- )
  955. {
  956. CExpressionSample src = m_Samples[ type ][ i ];
  957. if ( src.time < 0 ||
  958. src.time > duration )
  959. {
  960. m_Samples[ type ].Remove( i );
  961. }
  962. }
  963. }
  964. //-----------------------------------------------------------------------------
  965. // Purpose:
  966. //-----------------------------------------------------------------------------
  967. CChoreoEvent::CChoreoEvent( CChoreoScene *scene )
  968. {
  969. Init( scene );
  970. }
  971. //-----------------------------------------------------------------------------
  972. // Purpose:
  973. // Input : type -
  974. // *name -
  975. //-----------------------------------------------------------------------------
  976. CChoreoEvent::CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name )
  977. {
  978. Init( scene );
  979. SetType( type );
  980. SetName( name );
  981. }
  982. //-----------------------------------------------------------------------------
  983. // Purpose:
  984. // Input : type -
  985. // *name -
  986. // *param -
  987. //-----------------------------------------------------------------------------
  988. CChoreoEvent::CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name, const char *param )
  989. {
  990. Init( scene );
  991. SetType( type );
  992. SetName( name );
  993. SetParameters( param );
  994. }
  995. //-----------------------------------------------------------------------------
  996. // Purpose:
  997. //-----------------------------------------------------------------------------
  998. CChoreoEvent::~CChoreoEvent( void )
  999. {
  1000. RemoveAllTracks();
  1001. ClearEventDependencies();
  1002. delete m_pSubScene;
  1003. }
  1004. //-----------------------------------------------------------------------------
  1005. // Purpose: Assignment
  1006. // Input : src -
  1007. // Output : CChoreoEvent&
  1008. //-----------------------------------------------------------------------------
  1009. CChoreoEvent& CChoreoEvent::operator=( const CChoreoEvent& src )
  1010. {
  1011. MEM_ALLOC_CREDIT();
  1012. // Copy global id when copying entity
  1013. m_nGlobalID = src.m_nGlobalID;
  1014. m_pActor = NULL;
  1015. m_pChannel = NULL;
  1016. m_nDefaultCurveType = src.m_nDefaultCurveType;
  1017. m_fType = src.m_fType;
  1018. m_Name = src.m_Name;
  1019. m_Parameters = src.m_Parameters;
  1020. m_Parameters2= src.m_Parameters2;
  1021. m_Parameters3= src.m_Parameters3;
  1022. m_flStartTime = src.m_flStartTime;
  1023. m_flEndTime = src.m_flEndTime;
  1024. m_bFixedLength = src.m_bFixedLength;
  1025. m_flGestureSequenceDuration = src.m_flGestureSequenceDuration;
  1026. m_bResumeCondition = src.m_bResumeCondition;
  1027. m_bLockBodyFacing = src.m_bLockBodyFacing;
  1028. m_flDistanceToTarget = src.m_flDistanceToTarget;
  1029. m_bForceShortMovement = src.m_bForceShortMovement;
  1030. m_bSyncToFollowingGesture = src.m_bSyncToFollowingGesture;
  1031. m_bPlayOverScript = src.m_bPlayOverScript;
  1032. m_bUsesTag = src.m_bUsesTag;
  1033. m_TagName = src.m_TagName;
  1034. m_TagWavName = src.m_TagWavName;
  1035. ClearAllRelativeTags();
  1036. ClearAllTimingTags();
  1037. int t;
  1038. for ( t = 0; t < NUM_ABS_TAG_TYPES; t++ )
  1039. {
  1040. ClearAllAbsoluteTags( (AbsTagType)t );
  1041. }
  1042. int i;
  1043. for ( i = 0; i < src.m_RelativeTags.Count(); i++ )
  1044. {
  1045. CEventRelativeTag newtag( src.m_RelativeTags[ i ] );
  1046. newtag.SetOwner( this );
  1047. m_RelativeTags.AddToTail( newtag );
  1048. }
  1049. for ( i = 0; i < src.m_TimingTags.Count(); i++ )
  1050. {
  1051. CFlexTimingTag newtag( src.m_TimingTags[ i ] );
  1052. newtag.SetOwner( this );
  1053. m_TimingTags.AddToTail( newtag );
  1054. }
  1055. for ( t = 0; t < NUM_ABS_TAG_TYPES; t++ )
  1056. {
  1057. for ( i = 0; i < src.m_AbsoluteTags[ t ].Count(); i++ )
  1058. {
  1059. CEventAbsoluteTag newtag( src.m_AbsoluteTags[ t ][ i ] );
  1060. newtag.SetOwner( this );
  1061. m_AbsoluteTags[ t ].AddToTail( newtag );
  1062. }
  1063. }
  1064. RemoveAllTracks();
  1065. for ( i = 0 ; i < src.m_FlexAnimationTracks.Count(); i++ )
  1066. {
  1067. CFlexAnimationTrack *newtrack = new CFlexAnimationTrack( src.m_FlexAnimationTracks[ i ] );
  1068. newtrack->SetEvent( this );
  1069. m_FlexAnimationTracks.AddToTail( newtrack );
  1070. }
  1071. m_bTrackLookupSet = src.m_bTrackLookupSet;
  1072. // FIXME: Use a safe handle?
  1073. //m_pSubScene = src.m_pSubScene;
  1074. m_bProcessing = src.m_bProcessing;
  1075. m_bHasStopped = src.m_bHasStopped;
  1076. m_pMixer = src.m_pMixer;
  1077. m_pScene = src.m_pScene;
  1078. m_nPitch = src.m_nPitch;
  1079. m_nYaw = src.m_nYaw;
  1080. m_nNumLoops = src.m_nNumLoops;
  1081. m_nLoopsRemaining = src.m_nLoopsRemaining;
  1082. // Copy ramp over
  1083. m_Ramp = src.m_Ramp;
  1084. m_ccType = src.m_ccType;
  1085. m_CCToken = src.m_CCToken;
  1086. m_bUsingCombinedSoundFile = src.m_bUsingCombinedSoundFile;
  1087. m_uRequiredCombinedChecksum = src.m_uRequiredCombinedChecksum;
  1088. m_nNumSlaves = src.m_nNumSlaves;
  1089. m_flLastSlaveEndTime = src.m_flLastSlaveEndTime;
  1090. m_bCCTokenValid = src.m_bCCTokenValid;
  1091. m_bCombinedUsingGenderToken = src.m_bCombinedUsingGenderToken;
  1092. m_bSuppressCaptionAttenuation = src.m_bSuppressCaptionAttenuation;
  1093. m_bActive = src.m_bActive;
  1094. return *this;
  1095. }
  1096. //-----------------------------------------------------------------------------
  1097. // Purpose:
  1098. //-----------------------------------------------------------------------------
  1099. void CChoreoEvent::Init( CChoreoScene *scene )
  1100. {
  1101. m_nGlobalID = s_nGlobalID++;
  1102. m_nDefaultCurveType = CURVE_CATMULL_ROM_TO_CATMULL_ROM;
  1103. m_fType = UNSPECIFIED;
  1104. m_Name.Set("");
  1105. m_Parameters.Set("");
  1106. m_Parameters2.Set("");
  1107. m_Parameters3.Set("");
  1108. m_flStartTime = 0.0f;
  1109. m_flEndTime = -1.0f;
  1110. m_pActor = NULL;
  1111. m_pChannel = NULL;
  1112. m_pScene = scene;
  1113. m_bFixedLength = false;
  1114. m_bResumeCondition = false;
  1115. SetUsingRelativeTag( false, 0, 0 );
  1116. m_bTrackLookupSet = false;
  1117. m_bLockBodyFacing = false;
  1118. m_flDistanceToTarget = 0.0f;
  1119. m_bForceShortMovement = false;
  1120. m_bSyncToFollowingGesture = false;
  1121. m_bPlayOverScript = false;
  1122. m_pSubScene = NULL;
  1123. m_bProcessing = false;
  1124. m_bHasStopped = false;
  1125. m_pMixer = NULL;
  1126. m_flGestureSequenceDuration = 0.0f;
  1127. m_nPitch = m_nYaw = 0;
  1128. m_nNumLoops = -1;
  1129. m_nLoopsRemaining = 0;
  1130. // Close captioning/localization support
  1131. m_CCToken.Set("");
  1132. m_ccType = CC_MASTER;
  1133. m_bUsingCombinedSoundFile = false;
  1134. m_uRequiredCombinedChecksum = 0;
  1135. m_nNumSlaves = 0;
  1136. m_flLastSlaveEndTime = 0.0f;
  1137. m_bCCTokenValid = false;
  1138. m_bCombinedUsingGenderToken = false;
  1139. m_bSuppressCaptionAttenuation = false;
  1140. m_bActive = true;
  1141. }
  1142. //-----------------------------------------------------------------------------
  1143. // Purpose:
  1144. // Output : int
  1145. //-----------------------------------------------------------------------------
  1146. CChoreoEvent::EVENTTYPE CChoreoEvent::GetType( void )
  1147. {
  1148. return (EVENTTYPE)m_fType;
  1149. }
  1150. //-----------------------------------------------------------------------------
  1151. // Purpose:
  1152. // Input : type -
  1153. //-----------------------------------------------------------------------------
  1154. void CChoreoEvent::SetType( EVENTTYPE type )
  1155. {
  1156. m_fType = type;
  1157. if ( m_fType == SPEAK ||
  1158. m_fType == SUBSCENE )
  1159. {
  1160. m_bFixedLength = true;
  1161. }
  1162. else
  1163. {
  1164. m_bFixedLength = false;
  1165. }
  1166. }
  1167. //-----------------------------------------------------------------------------
  1168. // Purpose:
  1169. // Input : *name -
  1170. //-----------------------------------------------------------------------------
  1171. void CChoreoEvent::SetName( const char *name )
  1172. {
  1173. m_Name = name;
  1174. }
  1175. //-----------------------------------------------------------------------------
  1176. // Purpose:
  1177. // Output : const char
  1178. //-----------------------------------------------------------------------------
  1179. const char *CChoreoEvent::GetName( void )
  1180. {
  1181. return m_Name.Get();
  1182. }
  1183. //-----------------------------------------------------------------------------
  1184. // Purpose:
  1185. // Input : *param -
  1186. //-----------------------------------------------------------------------------
  1187. void CChoreoEvent::SetParameters( const char *param )
  1188. {
  1189. m_Parameters = param;
  1190. }
  1191. //-----------------------------------------------------------------------------
  1192. // Purpose:
  1193. // Output : const char
  1194. //-----------------------------------------------------------------------------
  1195. const char *CChoreoEvent::GetParameters( void )
  1196. {
  1197. return m_Parameters.Get();
  1198. }
  1199. //-----------------------------------------------------------------------------
  1200. // Purpose:
  1201. // Input : *param -
  1202. //-----------------------------------------------------------------------------
  1203. void CChoreoEvent::SetParameters2( const char *param )
  1204. {
  1205. int iLength = Q_strlen( param );
  1206. m_Parameters2 = param;
  1207. // HACK: Remove trailing " " until faceposer is fixed
  1208. if ( iLength > 0 )
  1209. {
  1210. if ( param[iLength-1] == ' ' )
  1211. {
  1212. char tmp[1024];
  1213. Q_strncpy( tmp, param, sizeof(tmp) );
  1214. tmp[iLength-1] = 0;
  1215. m_Parameters2.Set(tmp);
  1216. }
  1217. }
  1218. }
  1219. //-----------------------------------------------------------------------------
  1220. // Purpose:
  1221. // Output : const char
  1222. //-----------------------------------------------------------------------------
  1223. const char *CChoreoEvent::GetParameters2( void )
  1224. {
  1225. return m_Parameters2.Get();
  1226. }
  1227. //-----------------------------------------------------------------------------
  1228. // Purpose:
  1229. // Input : *param -
  1230. //-----------------------------------------------------------------------------
  1231. void CChoreoEvent::SetParameters3( const char *param )
  1232. {
  1233. int iLength = Q_strlen( param );
  1234. m_Parameters3 = param;
  1235. // HACK: Remove trailing " " until faceposer is fixed
  1236. if ( iLength > 0 )
  1237. {
  1238. if ( param[iLength-1] == ' ' )
  1239. {
  1240. char tmp[1024];
  1241. Q_strncpy( tmp, param, sizeof(tmp) );
  1242. tmp[iLength-1] = 0;
  1243. m_Parameters3.Set(tmp);
  1244. }
  1245. }
  1246. }
  1247. //-----------------------------------------------------------------------------
  1248. // Purpose:
  1249. // Output : const char
  1250. //-----------------------------------------------------------------------------
  1251. const char *CChoreoEvent::GetParameters3( void )
  1252. {
  1253. return m_Parameters3.Get();
  1254. }
  1255. //-----------------------------------------------------------------------------
  1256. // Purpose: debugging description
  1257. // Output : const char
  1258. //-----------------------------------------------------------------------------
  1259. const char *CChoreoEvent::GetDescription( void )
  1260. {
  1261. static char description[ 256 ];
  1262. description[ 0 ] = 0;
  1263. if ( !GetActor() )
  1264. {
  1265. Q_snprintf( description,sizeof(description), "global %s", m_Name.Get() );
  1266. }
  1267. else
  1268. {
  1269. Assert( m_pChannel );
  1270. Q_snprintf( description,sizeof(description), "%s : %s : %s -- %s \"%s\"", m_pActor->GetName(), m_pChannel->GetName(), GetName(), NameForType( GetType() ), GetParameters() );
  1271. if ( GetType() == EXPRESSION )
  1272. {
  1273. char sz[ 256 ];
  1274. Q_snprintf( sz,sizeof(sz), " \"%s\"", GetParameters2() );
  1275. Q_strncat( description, sz, sizeof(description), COPY_ALL_CHARACTERS );
  1276. }
  1277. }
  1278. return description;
  1279. }
  1280. //-----------------------------------------------------------------------------
  1281. // Purpose:
  1282. // Input : starttime -
  1283. //-----------------------------------------------------------------------------
  1284. void CChoreoEvent::SetStartTime( float starttime )
  1285. {
  1286. m_flStartTime = starttime;
  1287. if ( m_flEndTime != -1.0f )
  1288. {
  1289. if ( m_flEndTime < m_flStartTime )
  1290. {
  1291. m_flEndTime = m_flStartTime;
  1292. }
  1293. }
  1294. }
  1295. //-----------------------------------------------------------------------------
  1296. // Purpose:
  1297. // Output : float
  1298. //-----------------------------------------------------------------------------
  1299. float CChoreoEvent::GetStartTime( )
  1300. {
  1301. return m_flStartTime;
  1302. }
  1303. //-----------------------------------------------------------------------------
  1304. // Purpose:
  1305. // Input : endtime -
  1306. //-----------------------------------------------------------------------------
  1307. void CChoreoEvent::SetEndTime( float endtime )
  1308. {
  1309. bool changed = m_flEndTime != endtime;
  1310. m_flEndTime = endtime;
  1311. if ( endtime != -1.0f )
  1312. {
  1313. if ( m_flEndTime < m_flStartTime )
  1314. {
  1315. m_flEndTime = m_flStartTime;
  1316. }
  1317. if ( changed )
  1318. {
  1319. OnEndTimeChanged();
  1320. }
  1321. }
  1322. }
  1323. //-----------------------------------------------------------------------------
  1324. // Purpose:
  1325. // Output : float
  1326. //-----------------------------------------------------------------------------
  1327. float CChoreoEvent::GetEndTime( )
  1328. {
  1329. return m_flEndTime;
  1330. }
  1331. //-----------------------------------------------------------------------------
  1332. // Purpose:
  1333. // Output : Returns true on success, false on failure.
  1334. //-----------------------------------------------------------------------------
  1335. bool CChoreoEvent::HasEndTime( void )
  1336. {
  1337. return m_flEndTime != -1.0f ? true : false;
  1338. }
  1339. //-----------------------------------------------------------------------------
  1340. // Purpose:
  1341. // Output : float
  1342. //-----------------------------------------------------------------------------
  1343. float CChoreoEvent::GetCompletion( float time )
  1344. {
  1345. float t = (time - GetStartTime()) / (GetEndTime() - GetStartTime());
  1346. if (t < 0.0f)
  1347. return 0.0f;
  1348. else if (t > 1.0f)
  1349. return 1.0f;
  1350. return t;
  1351. }
  1352. // ICurveDataAccessor method
  1353. bool CChoreoEvent::CurveHasEndTime()
  1354. {
  1355. return HasEndTime();
  1356. }
  1357. //-----------------------------------------------------------------------------
  1358. // Default curve type
  1359. //-----------------------------------------------------------------------------
  1360. void CChoreoEvent::SetDefaultCurveType( int nCurveType )
  1361. {
  1362. m_nDefaultCurveType = nCurveType;
  1363. }
  1364. int CChoreoEvent::GetDefaultCurveType()
  1365. {
  1366. return m_nDefaultCurveType;
  1367. }
  1368. float CCurveData::GetIntensity( ICurveDataAccessor *data, float time )
  1369. {
  1370. float zeroValue = 0.0f;
  1371. // find samples that span the time
  1372. if ( !data->CurveHasEndTime() )
  1373. {
  1374. return zeroValue;
  1375. }
  1376. int rampCount = GetCount();
  1377. if ( rampCount < 1 )
  1378. {
  1379. // Full intensity
  1380. return 1.0f;
  1381. }
  1382. CExpressionSample *esStart = NULL;
  1383. CExpressionSample *esEnd = NULL;
  1384. // do binary search for sample in time period
  1385. int j = MAX( rampCount / 2, 1 );
  1386. int i = j;
  1387. while ( i > -2 && i < rampCount + 1 )
  1388. {
  1389. bool dummy;
  1390. esStart = GetBoundedSample( data, i, dummy );
  1391. esEnd = GetBoundedSample( data, i + 1, dummy );
  1392. j = MAX( j / 2, 1 );
  1393. if ( time < esStart->time)
  1394. {
  1395. i -= j;
  1396. }
  1397. else if ( time > esEnd->time)
  1398. {
  1399. i += j;
  1400. }
  1401. else
  1402. {
  1403. break;
  1404. }
  1405. }
  1406. if (!esStart)
  1407. {
  1408. return 1.0f;
  1409. }
  1410. int prev = i - 1;
  1411. int next = i + 2;
  1412. prev = MAX( -1, prev );
  1413. next = MIN( next, rampCount );
  1414. bool bBoundedSampleClamped[ 2 ];
  1415. CExpressionSample *esPre = GetBoundedSample( data, prev, bBoundedSampleClamped[ 0 ] );
  1416. CExpressionSample *esNext = GetBoundedSample( data, next, bBoundedSampleClamped[ 1 ] );
  1417. float dt = esEnd->time - esStart->time;
  1418. Vector vPre( esPre->time, esPre->value, 0 );
  1419. Vector vStart( esStart->time, esStart->value, 0 );
  1420. Vector vEnd( esEnd->time, esEnd->value, 0 );
  1421. Vector vNext( esNext->time, esNext->value, 0 );
  1422. if ( bBoundedSampleClamped[ 0 ] )
  1423. {
  1424. vPre.x = vStart.x;
  1425. }
  1426. if ( bBoundedSampleClamped[ 1 ] )
  1427. {
  1428. vNext.x = vEnd.x;
  1429. }
  1430. float f2 = 0.0f;
  1431. if ( dt > 0.0f )
  1432. {
  1433. f2 = ( time - esStart->time ) / ( dt );
  1434. }
  1435. f2 = clamp( f2, 0.0f, 1.0f );
  1436. Vector vOut;
  1437. int dummy;
  1438. int earlypart, laterpart;
  1439. int startCurve = esStart->GetCurveType();
  1440. int endCurve = esEnd->GetCurveType();
  1441. if ( startCurve == CURVE_DEFAULT )
  1442. {
  1443. startCurve = data->GetDefaultCurveType();
  1444. }
  1445. if ( endCurve == CURVE_DEFAULT )
  1446. {
  1447. endCurve = data->GetDefaultCurveType();
  1448. }
  1449. // Not holding out value of previous curve...
  1450. Interpolator_CurveInterpolatorsForType( startCurve, dummy, earlypart );
  1451. Interpolator_CurveInterpolatorsForType( endCurve, laterpart, dummy );
  1452. if ( earlypart == INTERPOLATE_HOLD )
  1453. {
  1454. // Hold "out" of previous sample (can cause a discontinuity)
  1455. VectorLerp( vStart, vEnd, f2, vOut );
  1456. vOut.y = vStart.y;
  1457. }
  1458. else if ( laterpart == INTERPOLATE_HOLD )
  1459. {
  1460. // Hold "out" of previous sample (can cause a discontinuity)
  1461. VectorLerp( vStart, vEnd, f2, vOut );
  1462. vOut.y = vEnd.y;
  1463. }
  1464. else
  1465. {
  1466. bool sameCurveType = earlypart == laterpart ? true : false;
  1467. if ( sameCurveType )
  1468. {
  1469. Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut );
  1470. }
  1471. else // curves differ, sigh
  1472. {
  1473. Vector vOut1, vOut2;
  1474. Interpolator_CurveInterpolate( earlypart, vPre, vStart, vEnd, vNext, f2, vOut1 );
  1475. Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut2 );
  1476. VectorLerp( vOut1, vOut2, f2, vOut );
  1477. }
  1478. }
  1479. float retval = clamp( vOut.y, 0.0f, 1.0f );
  1480. return retval;
  1481. }
  1482. //-----------------------------------------------------------------------------
  1483. // Purpose: Get intensity for event, bounded by scene global intensity
  1484. // Output : float
  1485. //-----------------------------------------------------------------------------
  1486. float CChoreoEvent::GetIntensity( float scenetime )
  1487. {
  1488. float global_intensity = 1.0f;
  1489. if ( m_pScene )
  1490. {
  1491. global_intensity = m_pScene->GetSceneRampIntensity( scenetime );
  1492. }
  1493. else
  1494. {
  1495. Assert( 0 );
  1496. }
  1497. float event_intensity = _GetIntensity( scenetime );
  1498. return global_intensity * event_intensity;
  1499. }
  1500. //-----------------------------------------------------------------------------
  1501. // Purpose:
  1502. // Output : float
  1503. //-----------------------------------------------------------------------------
  1504. float CChoreoEvent::_GetIntensity( float scenetime )
  1505. {
  1506. // Convert to event local time
  1507. float time = scenetime - GetStartTime();
  1508. return m_Ramp.GetIntensity( this, time );
  1509. }
  1510. float CChoreoEvent::GetIntensityArea( float scenetime )
  1511. {
  1512. // Convert to event local time
  1513. float time = scenetime - GetStartTime();
  1514. return m_Ramp.GetIntensityArea( this, time );
  1515. }
  1516. //-----------------------------------------------------------------------------
  1517. // Purpose:
  1518. // Output : float
  1519. //-----------------------------------------------------------------------------
  1520. float CCurveData::GetIntensityArea( ICurveDataAccessor *data, float time )
  1521. {
  1522. float zeroValue = 0.0f;
  1523. // find samples that span the time
  1524. if ( !data->CurveHasEndTime() )
  1525. {
  1526. return zeroValue;
  1527. }
  1528. int rampCount = GetCount();
  1529. if ( rampCount < 1 )
  1530. {
  1531. // Full intensity
  1532. return 1.0f;
  1533. }
  1534. CExpressionSample *esStart = NULL;
  1535. CExpressionSample *esEnd = NULL;
  1536. // do binary search for sample in time period
  1537. int j = MAX( rampCount / 2, 1 );
  1538. int i = j;
  1539. while ( i > -2 && i < rampCount + 1 )
  1540. {
  1541. bool dummy;
  1542. esStart = GetBoundedSample( data, i, dummy );
  1543. esEnd = GetBoundedSample( data, i + 1, dummy );
  1544. j = MAX( j / 2, 1 );
  1545. if ( time < esStart->time)
  1546. {
  1547. i -= j;
  1548. }
  1549. else if ( time > esEnd->time)
  1550. {
  1551. i += j;
  1552. }
  1553. else
  1554. {
  1555. break;
  1556. }
  1557. }
  1558. UpdateIntensityArea( data );
  1559. float flTotal = 0.0f;
  1560. flTotal = m_RampAccumulator[i+1];
  1561. int prev = i - 1;
  1562. int next = i + 2;
  1563. prev = MAX( -1, prev );
  1564. next = MIN( next, rampCount );
  1565. bool bBoundedSampleClamped[ 2 ];
  1566. CExpressionSample *esPre = GetBoundedSample( data, prev, bBoundedSampleClamped[ 0 ] );
  1567. CExpressionSample *esNext = GetBoundedSample( data, next, bBoundedSampleClamped[ 1 ] );
  1568. float dt = esEnd->time - esStart->time;
  1569. Vector vPre( esPre->time, esPre->value, 0 );
  1570. Vector vStart( esStart->time, esStart->value, 0 );
  1571. Vector vEnd( esEnd->time, esEnd->value, 0 );
  1572. Vector vNext( esNext->time, esNext->value, 0 );
  1573. if ( bBoundedSampleClamped[ 0 ] )
  1574. {
  1575. vPre.x = vStart.x;
  1576. }
  1577. if ( bBoundedSampleClamped[ 1 ] )
  1578. {
  1579. vNext.x = vEnd.x;
  1580. }
  1581. float f2 = 0.0f;
  1582. if ( dt > 0.0f )
  1583. {
  1584. f2 = ( time - esStart->time ) / ( dt );
  1585. }
  1586. f2 = clamp( f2, 0.0f, 1.0f );
  1587. Vector vOut;
  1588. int dummy;
  1589. int earlypart, laterpart;
  1590. int startCurve = esStart->GetCurveType();
  1591. int endCurve = esEnd->GetCurveType();
  1592. if ( startCurve == CURVE_DEFAULT )
  1593. {
  1594. startCurve = data->GetDefaultCurveType();
  1595. }
  1596. if ( endCurve == CURVE_DEFAULT )
  1597. {
  1598. endCurve = data->GetDefaultCurveType();
  1599. }
  1600. // Not holding out value of previous curve...
  1601. Interpolator_CurveInterpolatorsForType( startCurve, dummy, earlypart );
  1602. Interpolator_CurveInterpolatorsForType( endCurve, laterpart, dummy );
  1603. // FIXME: needs other curve types
  1604. Catmull_Rom_Spline_Integral_Normalize(
  1605. vPre,
  1606. vStart,
  1607. vEnd,
  1608. vNext,
  1609. f2,
  1610. vOut );
  1611. // Con_Printf( "Accum %f : Partial %f\n", flTotal, vOut.y * (vEnd.x - vStart.x) * f2 );
  1612. flTotal = flTotal + clamp( vOut.y, 0.0f, 1.0f ) * (vEnd.x - vStart.x);
  1613. return flTotal;
  1614. }
  1615. void CCurveData::UpdateIntensityArea( ICurveDataAccessor *data )
  1616. {
  1617. int rampCount = GetCount();;
  1618. if ( rampCount < 1 )
  1619. {
  1620. return;
  1621. }
  1622. if (m_RampAccumulator.Count() == rampCount + 2)
  1623. {
  1624. return;
  1625. }
  1626. m_RampAccumulator.SetCount( rampCount + 2 );
  1627. int i = -1;
  1628. bool dummy;
  1629. CExpressionSample *esPre = GetBoundedSample( data, i - 1, dummy );
  1630. CExpressionSample *esStart = GetBoundedSample( data, i, dummy );
  1631. CExpressionSample *esEnd = GetBoundedSample( data, MIN( i + 1, rampCount ), dummy );
  1632. Vector vPre( esPre->time, esPre->value, 0 );
  1633. Vector vStart( esStart->time, esStart->value, 0 );
  1634. Vector vEnd( esEnd->time, esEnd->value, 0 );
  1635. Vector vOut;
  1636. for (i = -1; i < rampCount; i++)
  1637. {
  1638. CExpressionSample *esNext = GetBoundedSample( data, MIN( i + 2, rampCount ), dummy );
  1639. Vector vNext( esNext->time, esNext->value, 0 );
  1640. Catmull_Rom_Spline_Integral_Normalize(
  1641. vPre,
  1642. vStart,
  1643. vEnd,
  1644. vNext,
  1645. 1.0f,
  1646. vOut );
  1647. m_RampAccumulator[i+1] = clamp( vOut.y, 0.0f, 1.0f ) * (vEnd.x - vStart.x);
  1648. vPre = vStart;
  1649. vStart = vEnd;
  1650. vEnd = vNext;
  1651. }
  1652. }
  1653. //-----------------------------------------------------------------------------
  1654. // Purpose:
  1655. // Input : dt -
  1656. //-----------------------------------------------------------------------------
  1657. void CChoreoEvent::OffsetStartTime( float dt )
  1658. {
  1659. SetStartTime( GetStartTime() + dt );
  1660. }
  1661. //-----------------------------------------------------------------------------
  1662. // Purpose:
  1663. // Input : dt -
  1664. //-----------------------------------------------------------------------------
  1665. void CChoreoEvent::OffsetEndTime( float dt )
  1666. {
  1667. if ( HasEndTime() )
  1668. {
  1669. SetEndTime( GetEndTime() + dt );
  1670. }
  1671. }
  1672. //-----------------------------------------------------------------------------
  1673. // Purpose:
  1674. // Input : dt -
  1675. //-----------------------------------------------------------------------------
  1676. void CChoreoEvent::OffsetTime( float dt )
  1677. {
  1678. if ( HasEndTime() )
  1679. {
  1680. m_flEndTime += dt;
  1681. }
  1682. m_flStartTime += dt;
  1683. }
  1684. //-----------------------------------------------------------------------------
  1685. // Purpose:
  1686. // Input : *actor -
  1687. //-----------------------------------------------------------------------------
  1688. void CChoreoEvent::SetActor( CChoreoActor *actor )
  1689. {
  1690. m_pActor = actor;
  1691. }
  1692. //-----------------------------------------------------------------------------
  1693. // Purpose:
  1694. // Output : CChoreoActor
  1695. //-----------------------------------------------------------------------------
  1696. CChoreoActor *CChoreoEvent::GetActor( void )
  1697. {
  1698. return m_pActor;
  1699. }
  1700. //-----------------------------------------------------------------------------
  1701. // Purpose:
  1702. // Input : *channel -
  1703. //-----------------------------------------------------------------------------
  1704. void CChoreoEvent::SetChannel( CChoreoChannel *channel )
  1705. {
  1706. m_pChannel = channel;
  1707. }
  1708. //-----------------------------------------------------------------------------
  1709. // Purpose:
  1710. // Output : CChoreoChannel
  1711. //-----------------------------------------------------------------------------
  1712. CChoreoChannel *CChoreoEvent::GetChannel( void )
  1713. {
  1714. return m_pChannel;
  1715. }
  1716. //-----------------------------------------------------------------------------
  1717. // Purpose:
  1718. // Input : *scene -
  1719. //-----------------------------------------------------------------------------
  1720. void CChoreoEvent::SetSubScene( CChoreoScene *scene )
  1721. {
  1722. m_pSubScene = scene;
  1723. }
  1724. //-----------------------------------------------------------------------------
  1725. // Purpose:
  1726. // Output : CChoreoScene
  1727. //-----------------------------------------------------------------------------
  1728. CChoreoScene *CChoreoEvent::GetSubScene( void )
  1729. {
  1730. return m_pSubScene;
  1731. }
  1732. //-----------------------------------------------------------------------------
  1733. // Purpose:
  1734. //-----------------------------------------------------------------------------
  1735. struct EventNameMap_t
  1736. {
  1737. CChoreoEvent::EVENTTYPE type;
  1738. char const *name;
  1739. };
  1740. static EventNameMap_t g_NameMap[] =
  1741. {
  1742. { CChoreoEvent::UNSPECIFIED, "unspecified" }, // error condition!!!
  1743. { CChoreoEvent::SECTION, "section" },
  1744. { CChoreoEvent::EXPRESSION, "expression" },
  1745. { CChoreoEvent::LOOKAT, "lookat" },
  1746. { CChoreoEvent::MOVETO, "moveto" },
  1747. { CChoreoEvent::SPEAK, "speak" },
  1748. { CChoreoEvent::GESTURE, "gesture" },
  1749. { CChoreoEvent::SEQUENCE, "sequence" },
  1750. { CChoreoEvent::FACE, "face" },
  1751. { CChoreoEvent::FIRETRIGGER, "firetrigger" },
  1752. { CChoreoEvent::FLEXANIMATION, "flexanimation" },
  1753. { CChoreoEvent::SUBSCENE, "subscene" },
  1754. { CChoreoEvent::LOOP, "loop" },
  1755. { CChoreoEvent::INTERRUPT, "interrupt" },
  1756. { CChoreoEvent::STOPPOINT, "stoppoint" },
  1757. { CChoreoEvent::PERMIT_RESPONSES, "permitresponses" },
  1758. { CChoreoEvent::GENERIC, "generic" },
  1759. { CChoreoEvent::CAMERA, "camera" },
  1760. { CChoreoEvent::SCRIPT, "script" },
  1761. };
  1762. //-----------------------------------------------------------------------------
  1763. // Purpose: A simple class to verify the names data above at runtime
  1764. //-----------------------------------------------------------------------------
  1765. class CCheckEventNames
  1766. {
  1767. public:
  1768. CCheckEventNames()
  1769. {
  1770. if ( ARRAYSIZE( g_NameMap ) != CChoreoEvent::NUM_TYPES )
  1771. {
  1772. Error( "g_NameMap contains %i entries, CChoreoEvent::NUM_TYPES == %i!",
  1773. ARRAYSIZE( g_NameMap ), CChoreoEvent::NUM_TYPES );
  1774. }
  1775. for ( int i = 0; i < CChoreoEvent::NUM_TYPES; ++i )
  1776. {
  1777. if ( !g_NameMap[ i ].name )
  1778. {
  1779. Error( "g_NameMap: Event type at %i has NULL name string!", i );
  1780. }
  1781. if ( (CChoreoEvent::EVENTTYPE)(i) == g_NameMap[ i ].type )
  1782. continue;
  1783. Error( "g_NameMap: Event type at %i has wrong value (%i)!",
  1784. i, (int)g_NameMap[ i ].type );
  1785. }
  1786. }
  1787. };
  1788. static CCheckEventNames g_CheckNamesSingleton;
  1789. //-----------------------------------------------------------------------------
  1790. // Purpose:
  1791. // Input : *name -
  1792. // Output : int
  1793. //-----------------------------------------------------------------------------
  1794. CChoreoEvent::EVENTTYPE CChoreoEvent::TypeForName( const char *name )
  1795. {
  1796. for ( int i = 0; i < NUM_TYPES; ++i )
  1797. {
  1798. EventNameMap_t *slot = &g_NameMap[ i ];
  1799. if ( !Q_stricmp( name, slot->name ) )
  1800. return slot->type;
  1801. }
  1802. Assert( !"CChoreoEvent::TypeForName failed!!!" );
  1803. return UNSPECIFIED;
  1804. }
  1805. //-----------------------------------------------------------------------------
  1806. // Purpose:
  1807. // Input : type -
  1808. // Output : const char
  1809. //-----------------------------------------------------------------------------
  1810. const char *CChoreoEvent::NameForType( EVENTTYPE type )
  1811. {
  1812. int i = (int)type;
  1813. if ( i < 0 || i >= NUM_TYPES )
  1814. {
  1815. Assert( "!CChoreoEvent::NameForType: bogus type!" );
  1816. // returns "unspecified!!!";
  1817. return g_NameMap[ 0 ].name;
  1818. }
  1819. return g_NameMap[ i ].name;
  1820. }
  1821. //-----------------------------------------------------------------------------
  1822. // Purpose:
  1823. //-----------------------------------------------------------------------------
  1824. struct CCNameMap_t
  1825. {
  1826. CChoreoEvent::CLOSECAPTION type;
  1827. char const *name;
  1828. };
  1829. static CCNameMap_t g_CCNameMap[] =
  1830. {
  1831. { CChoreoEvent::CC_MASTER, "cc_master" }, // error condition!!!
  1832. { CChoreoEvent::CC_SLAVE, "cc_slave" },
  1833. { CChoreoEvent::CC_DISABLED, "cc_disabled" },
  1834. };
  1835. //-----------------------------------------------------------------------------
  1836. // Purpose: A simple class to verify the names data above at runtime
  1837. //-----------------------------------------------------------------------------
  1838. class CCheckCCNames
  1839. {
  1840. public:
  1841. CCheckCCNames()
  1842. {
  1843. if ( ARRAYSIZE( g_CCNameMap ) != CChoreoEvent::NUM_CC_TYPES )
  1844. {
  1845. Error( "g_CCNameMap contains %i entries, CChoreoEvent::NUM_CC_TYPES == %i!",
  1846. ARRAYSIZE( g_CCNameMap ), CChoreoEvent::NUM_CC_TYPES );
  1847. }
  1848. for ( int i = 0; i < CChoreoEvent::NUM_CC_TYPES; ++i )
  1849. {
  1850. if ( !g_CCNameMap[ i ].name )
  1851. {
  1852. Error( "g_NameMap: CC type at %i has NULL name string!", i );
  1853. }
  1854. if ( (CChoreoEvent::CLOSECAPTION)(i) == g_CCNameMap[ i ].type )
  1855. continue;
  1856. Error( "g_CCNameMap: Event type at %i has wrong value (%i)!",
  1857. i, (int)g_CCNameMap[ i ].type );
  1858. }
  1859. }
  1860. };
  1861. static CCheckCCNames g_CheckCCNamesSingleton;
  1862. //-----------------------------------------------------------------------------
  1863. // Purpose:
  1864. // Input : *name -
  1865. // Output : CLOSECAPTION
  1866. //-----------------------------------------------------------------------------
  1867. CChoreoEvent::CLOSECAPTION CChoreoEvent::CCTypeForName( const char *name )
  1868. {
  1869. for ( int i = 0; i < NUM_CC_TYPES; ++i )
  1870. {
  1871. CCNameMap_t *slot = &g_CCNameMap[ i ];
  1872. if ( !Q_stricmp( name, slot->name ) )
  1873. return slot->type;
  1874. }
  1875. Assert( !"CChoreoEvent::TypeForName failed!!!" );
  1876. return CC_MASTER;
  1877. }
  1878. //-----------------------------------------------------------------------------
  1879. // Purpose:
  1880. // Input : type -
  1881. // Output : const char
  1882. //-----------------------------------------------------------------------------
  1883. const char *CChoreoEvent::NameForCCType( CLOSECAPTION type )
  1884. {
  1885. int i = (int)type;
  1886. if ( i < 0 || i >= NUM_CC_TYPES )
  1887. {
  1888. Assert( "!CChoreoEvent::NameForType: bogus type!" );
  1889. // returns "unspecified!!!";
  1890. return g_CCNameMap[ 0 ].name;
  1891. }
  1892. return g_CCNameMap[ i ].name;
  1893. }
  1894. //-----------------------------------------------------------------------------
  1895. // Purpose: Is the event something that can be sized ( a wave file, e.g. )
  1896. // Output : Returns true on success, false on failure.
  1897. //-----------------------------------------------------------------------------
  1898. bool CChoreoEvent::IsFixedLength( void )
  1899. {
  1900. return m_bFixedLength;
  1901. }
  1902. //-----------------------------------------------------------------------------
  1903. // Purpose:
  1904. // Input : isfixedlength -
  1905. //-----------------------------------------------------------------------------
  1906. void CChoreoEvent::SetFixedLength( bool isfixedlength )
  1907. {
  1908. m_bFixedLength = isfixedlength;
  1909. }
  1910. //-----------------------------------------------------------------------------
  1911. // Purpose:
  1912. // Input : resumecondition -
  1913. //-----------------------------------------------------------------------------
  1914. void CChoreoEvent::SetResumeCondition( bool resumecondition )
  1915. {
  1916. m_bResumeCondition = resumecondition;
  1917. }
  1918. //-----------------------------------------------------------------------------
  1919. // Purpose:
  1920. // Output : Returns true on success, false on failure.
  1921. //-----------------------------------------------------------------------------
  1922. bool CChoreoEvent::IsResumeCondition( void )
  1923. {
  1924. return m_bResumeCondition;
  1925. }
  1926. //-----------------------------------------------------------------------------
  1927. // Purpose:
  1928. // Input : lockbodyfacing -
  1929. //-----------------------------------------------------------------------------
  1930. void CChoreoEvent::SetLockBodyFacing( bool lockbodyfacing )
  1931. {
  1932. m_bLockBodyFacing = lockbodyfacing;
  1933. }
  1934. //-----------------------------------------------------------------------------
  1935. // Purpose:
  1936. // Output : Returns true on success, false on failure.
  1937. //-----------------------------------------------------------------------------
  1938. bool CChoreoEvent::IsLockBodyFacing( void )
  1939. {
  1940. return m_bLockBodyFacing;
  1941. }
  1942. //-----------------------------------------------------------------------------
  1943. // Purpose:
  1944. // Input : distancetotarget -
  1945. //-----------------------------------------------------------------------------
  1946. void CChoreoEvent::SetDistanceToTarget( float distancetotarget )
  1947. {
  1948. m_flDistanceToTarget = distancetotarget;
  1949. }
  1950. //-----------------------------------------------------------------------------
  1951. // Purpose:
  1952. // Output : Returns ideal distance to target
  1953. //-----------------------------------------------------------------------------
  1954. float CChoreoEvent::GetDistanceToTarget( void )
  1955. {
  1956. return m_flDistanceToTarget;
  1957. }
  1958. //-----------------------------------------------------------------------------
  1959. // Purpose:
  1960. // Input : set if small (sub-1/2 bbox) movements are forced
  1961. //-----------------------------------------------------------------------------
  1962. void CChoreoEvent::SetForceShortMovement( bool bForceShortMovement )
  1963. {
  1964. m_bForceShortMovement = bForceShortMovement;
  1965. }
  1966. //-----------------------------------------------------------------------------
  1967. // Purpose:
  1968. // Output : get if small (sub-1/2 bbox) movements are forced
  1969. //-----------------------------------------------------------------------------
  1970. bool CChoreoEvent::GetForceShortMovement( void )
  1971. {
  1972. return m_bForceShortMovement;
  1973. }
  1974. //-----------------------------------------------------------------------------
  1975. // Purpose:
  1976. // Input : set if the gesture should sync its exit tag with the following gestures entry tag
  1977. //-----------------------------------------------------------------------------
  1978. void CChoreoEvent::SetSyncToFollowingGesture( bool bSyncToFollowingGesture )
  1979. {
  1980. m_bSyncToFollowingGesture = bSyncToFollowingGesture;
  1981. }
  1982. //-----------------------------------------------------------------------------
  1983. // Purpose:
  1984. // Output : get if the gesture should sync its exit tag with the following gestures entry tag
  1985. //-----------------------------------------------------------------------------
  1986. bool CChoreoEvent::GetSyncToFollowingGesture( void )
  1987. {
  1988. return m_bSyncToFollowingGesture;
  1989. }
  1990. //-----------------------------------------------------------------------------
  1991. // Purpose:
  1992. // Input : set if the sequence should player overtop of an underlying SS
  1993. //-----------------------------------------------------------------------------
  1994. void CChoreoEvent::SetPlayOverScript( bool bPlayOverScript )
  1995. {
  1996. m_bPlayOverScript = bPlayOverScript;
  1997. }
  1998. //-----------------------------------------------------------------------------
  1999. // Purpose:
  2000. // Output : get if the sequence should player overtop of an underlying SS
  2001. //-----------------------------------------------------------------------------
  2002. bool CChoreoEvent::GetPlayOverScript( void )
  2003. {
  2004. return m_bPlayOverScript;
  2005. }
  2006. //-----------------------------------------------------------------------------
  2007. // Purpose:
  2008. // Output : float
  2009. //-----------------------------------------------------------------------------
  2010. float CChoreoEvent::GetDuration( void )
  2011. {
  2012. if ( HasEndTime() )
  2013. {
  2014. return GetEndTime() - GetStartTime();
  2015. }
  2016. return 0.0f;
  2017. }
  2018. //-----------------------------------------------------------------------------
  2019. // Purpose:
  2020. //-----------------------------------------------------------------------------
  2021. void CChoreoEvent::ClearAllRelativeTags( void )
  2022. {
  2023. m_RelativeTags.Purge();
  2024. }
  2025. //-----------------------------------------------------------------------------
  2026. // Purpose:
  2027. // Output : int
  2028. //-----------------------------------------------------------------------------
  2029. int CChoreoEvent::GetNumRelativeTags( void )
  2030. {
  2031. return m_RelativeTags.Count();
  2032. }
  2033. //-----------------------------------------------------------------------------
  2034. // Purpose:
  2035. // Input : tagnum -
  2036. // Output : CEventRelativeTag
  2037. //-----------------------------------------------------------------------------
  2038. CEventRelativeTag *CChoreoEvent::GetRelativeTag( int tagnum )
  2039. {
  2040. Assert( tagnum >= 0 && tagnum < m_RelativeTags.Count() );
  2041. return &m_RelativeTags[ tagnum ];
  2042. }
  2043. //-----------------------------------------------------------------------------
  2044. // Purpose:
  2045. // Input : *tagname -
  2046. // percentage -
  2047. //-----------------------------------------------------------------------------
  2048. void CChoreoEvent::AddRelativeTag( const char *tagname, float percentage )
  2049. {
  2050. CEventRelativeTag rt( this, tagname, percentage );
  2051. m_RelativeTags.AddToTail( rt );
  2052. }
  2053. //-----------------------------------------------------------------------------
  2054. // Purpose:
  2055. // Input : *tagname -
  2056. //-----------------------------------------------------------------------------
  2057. void CChoreoEvent::RemoveRelativeTag( const char *tagname )
  2058. {
  2059. for ( int i = 0; i < m_RelativeTags.Count(); i++ )
  2060. {
  2061. CEventRelativeTag *prt = &m_RelativeTags[ i ];
  2062. if ( !prt )
  2063. continue;
  2064. if ( !stricmp( prt->GetName(), tagname ) )
  2065. {
  2066. m_RelativeTags.Remove( i );
  2067. return;
  2068. }
  2069. }
  2070. }
  2071. //-----------------------------------------------------------------------------
  2072. // Purpose:
  2073. // Input : *tagname -
  2074. // Output : CEventRelativeTag *
  2075. //-----------------------------------------------------------------------------
  2076. CEventRelativeTag * CChoreoEvent::FindRelativeTag( const char *tagname )
  2077. {
  2078. for ( int i = 0; i < m_RelativeTags.Count(); i++ )
  2079. {
  2080. CEventRelativeTag *prt = &m_RelativeTags[ i ];
  2081. if ( !prt )
  2082. continue;
  2083. if ( !stricmp( prt->GetName(), tagname ) )
  2084. {
  2085. return prt;
  2086. }
  2087. }
  2088. return NULL;
  2089. }
  2090. //-----------------------------------------------------------------------------
  2091. // Purpose:
  2092. // Output : Returns true on success, false on failure.
  2093. //-----------------------------------------------------------------------------
  2094. bool CChoreoEvent::IsUsingRelativeTag( void )
  2095. {
  2096. return m_bUsesTag;
  2097. }
  2098. //-----------------------------------------------------------------------------
  2099. // Purpose:
  2100. // Input : usetag -
  2101. // 0 -
  2102. //-----------------------------------------------------------------------------
  2103. void CChoreoEvent::SetUsingRelativeTag( bool usetag, const char *tagname /*= 0*/,
  2104. const char *wavname /* = 0 */ )
  2105. {
  2106. m_bUsesTag = usetag;
  2107. if ( tagname )
  2108. {
  2109. m_TagName = tagname;
  2110. }
  2111. else
  2112. {
  2113. m_TagName.Set("");
  2114. }
  2115. if ( wavname )
  2116. {
  2117. m_TagWavName = wavname;
  2118. }
  2119. else
  2120. {
  2121. m_TagWavName.Set("");
  2122. }
  2123. }
  2124. //-----------------------------------------------------------------------------
  2125. // Purpose:
  2126. // Output : const char
  2127. //-----------------------------------------------------------------------------
  2128. const char *CChoreoEvent::GetRelativeTagName( void )
  2129. {
  2130. return m_TagName.Get();
  2131. }
  2132. //-----------------------------------------------------------------------------
  2133. // Purpose:
  2134. // Output : const char
  2135. //-----------------------------------------------------------------------------
  2136. const char *CChoreoEvent::GetRelativeWavName( void )
  2137. {
  2138. return m_TagWavName.Get();
  2139. }
  2140. //-----------------------------------------------------------------------------
  2141. // Purpose:
  2142. //-----------------------------------------------------------------------------
  2143. void CChoreoEvent::ClearAllTimingTags( void )
  2144. {
  2145. m_TimingTags.Purge();
  2146. }
  2147. //-----------------------------------------------------------------------------
  2148. // Purpose:
  2149. // Output : int
  2150. //-----------------------------------------------------------------------------
  2151. int CChoreoEvent::GetNumTimingTags( void )
  2152. {
  2153. return m_TimingTags.Count();
  2154. }
  2155. //-----------------------------------------------------------------------------
  2156. // Purpose:
  2157. // Input : tagnum -
  2158. // Output : CEventRelativeTag
  2159. //-----------------------------------------------------------------------------
  2160. CFlexTimingTag *CChoreoEvent::GetTimingTag( int tagnum )
  2161. {
  2162. Assert( tagnum >= 0 && tagnum < m_TimingTags.Count() );
  2163. return &m_TimingTags[ tagnum ];
  2164. }
  2165. //-----------------------------------------------------------------------------
  2166. // Purpose:
  2167. // Input : *tagname -
  2168. // percentage -
  2169. //-----------------------------------------------------------------------------
  2170. void CChoreoEvent::AddTimingTag( const char *tagname, float percentage, bool locked )
  2171. {
  2172. CFlexTimingTag tt( this, tagname, percentage, locked );
  2173. m_TimingTags.AddToTail( tt );
  2174. // Sort tags
  2175. CFlexTimingTag temp( (CChoreoEvent *)0x1, "", 0.0f, false );
  2176. // ugly bubble sort
  2177. for ( int i = 0; i < m_TimingTags.Count(); i++ )
  2178. {
  2179. for ( int j = i + 1; j < m_TimingTags.Count(); j++ )
  2180. {
  2181. CFlexTimingTag *t1 = &m_TimingTags[ i ];
  2182. CFlexTimingTag *t2 = &m_TimingTags[ j ];
  2183. if ( t1->GetPercentage() > t2->GetPercentage() )
  2184. {
  2185. temp = *t1;
  2186. *t1 = *t2;
  2187. *t2 = temp;
  2188. }
  2189. }
  2190. }
  2191. }
  2192. //-----------------------------------------------------------------------------
  2193. // Purpose:
  2194. // Input : *tagname -
  2195. //-----------------------------------------------------------------------------
  2196. void CChoreoEvent::RemoveTimingTag( const char *tagname )
  2197. {
  2198. for ( int i = 0; i < m_TimingTags.Count(); i++ )
  2199. {
  2200. CFlexTimingTag *ptt = &m_TimingTags[ i ];
  2201. if ( !ptt )
  2202. continue;
  2203. if ( !stricmp( ptt->GetName(), tagname ) )
  2204. {
  2205. m_TimingTags.Remove( i );
  2206. return;
  2207. }
  2208. }
  2209. }
  2210. //-----------------------------------------------------------------------------
  2211. // Purpose:
  2212. // Input : *tagname -
  2213. // Output : CEventRelativeTag *
  2214. //-----------------------------------------------------------------------------
  2215. CFlexTimingTag * CChoreoEvent::FindTimingTag( const char *tagname )
  2216. {
  2217. for ( int i = 0; i < m_TimingTags.Count(); i++ )
  2218. {
  2219. CFlexTimingTag *ptt = &m_TimingTags[ i ];
  2220. if ( !ptt )
  2221. continue;
  2222. if ( !stricmp( ptt->GetName(), tagname ) )
  2223. {
  2224. return ptt;
  2225. }
  2226. }
  2227. return NULL;
  2228. }
  2229. //-----------------------------------------------------------------------------
  2230. // Purpose:
  2231. //-----------------------------------------------------------------------------
  2232. void CChoreoEvent::OnEndTimeChanged( void )
  2233. {
  2234. int c = GetNumFlexAnimationTracks();
  2235. for ( int i = 0; i < c; i++ )
  2236. {
  2237. CFlexAnimationTrack *track = GetFlexAnimationTrack( i );
  2238. Assert( track );
  2239. if ( !track )
  2240. continue;
  2241. track->Resort( 0 );
  2242. }
  2243. }
  2244. //-----------------------------------------------------------------------------
  2245. // Purpose:
  2246. // Output : int
  2247. //-----------------------------------------------------------------------------
  2248. int CChoreoEvent::GetNumFlexAnimationTracks( void )
  2249. {
  2250. return m_FlexAnimationTracks.Count();
  2251. }
  2252. //-----------------------------------------------------------------------------
  2253. // Purpose:
  2254. // Input : index -
  2255. // Output : CFlexAnimationTrack
  2256. //-----------------------------------------------------------------------------
  2257. CFlexAnimationTrack *CChoreoEvent::GetFlexAnimationTrack( int index )
  2258. {
  2259. if ( index < 0 || index >= GetNumFlexAnimationTracks() )
  2260. return NULL;
  2261. return m_FlexAnimationTracks[ index ];
  2262. }
  2263. //-----------------------------------------------------------------------------
  2264. // Purpose:
  2265. // Input : *controllername -
  2266. // Output : CFlexAnimationTrack
  2267. //-----------------------------------------------------------------------------
  2268. CFlexAnimationTrack *CChoreoEvent::AddTrack( const char *controllername )
  2269. {
  2270. CFlexAnimationTrack *newTrack = new CFlexAnimationTrack( this );
  2271. newTrack->SetFlexControllerName( controllername );
  2272. m_FlexAnimationTracks.AddToTail( newTrack );
  2273. return newTrack;
  2274. }
  2275. //-----------------------------------------------------------------------------
  2276. // Purpose:
  2277. // Input : index -
  2278. //-----------------------------------------------------------------------------
  2279. void CChoreoEvent::RemoveTrack( int index )
  2280. {
  2281. CFlexAnimationTrack *track = GetFlexAnimationTrack( index );
  2282. if ( !track )
  2283. return;
  2284. m_FlexAnimationTracks.Remove( index );
  2285. delete track;
  2286. }
  2287. //-----------------------------------------------------------------------------
  2288. // Purpose:
  2289. //-----------------------------------------------------------------------------
  2290. void CChoreoEvent::RemoveAllTracks( void )
  2291. {
  2292. while ( GetNumFlexAnimationTracks() > 0 )
  2293. {
  2294. RemoveTrack( 0 );
  2295. }
  2296. }
  2297. //-----------------------------------------------------------------------------
  2298. // Purpose:
  2299. // Input : *controllername -
  2300. // Output : CFlexAnimationTrack
  2301. //-----------------------------------------------------------------------------
  2302. CFlexAnimationTrack *CChoreoEvent::FindTrack( const char *controllername )
  2303. {
  2304. for ( int i = 0; i < GetNumFlexAnimationTracks(); i++ )
  2305. {
  2306. CFlexAnimationTrack *t = GetFlexAnimationTrack( i );
  2307. if ( t && !stricmp( t->GetFlexControllerName(), controllername ) )
  2308. {
  2309. return t;
  2310. }
  2311. }
  2312. return NULL;
  2313. }
  2314. //-----------------------------------------------------------------------------
  2315. // Purpose:
  2316. // Output : Returns true on success, false on failure.
  2317. //-----------------------------------------------------------------------------
  2318. bool CChoreoEvent::GetTrackLookupSet( void )
  2319. {
  2320. return m_bTrackLookupSet;
  2321. }
  2322. //-----------------------------------------------------------------------------
  2323. // Purpose:
  2324. // Input : set -
  2325. //-----------------------------------------------------------------------------
  2326. void CChoreoEvent::SetTrackLookupSet( bool set )
  2327. {
  2328. m_bTrackLookupSet = set;
  2329. }
  2330. //-----------------------------------------------------------------------------
  2331. // Purpose:
  2332. // Output : Returns true on success, false on failure.
  2333. //-----------------------------------------------------------------------------
  2334. bool CChoreoEvent::IsProcessing( void ) const
  2335. {
  2336. return m_bProcessing;
  2337. }
  2338. //-----------------------------------------------------------------------------
  2339. // Purpose: Indicates it the even has already stopped (in that case it should not be restarted).
  2340. // Output : Returns true if the even has stopped, false otherwise.
  2341. //-----------------------------------------------------------------------------
  2342. bool CChoreoEvent::HasStopped() const
  2343. {
  2344. return m_bHasStopped;
  2345. }
  2346. //-----------------------------------------------------------------------------
  2347. // Purpose:
  2348. // Input : *cb -
  2349. // t -
  2350. //-----------------------------------------------------------------------------
  2351. void CChoreoEvent::StartProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
  2352. {
  2353. Assert( !m_bProcessing );
  2354. m_bProcessing = true;
  2355. if ( cb )
  2356. {
  2357. cb->StartEvent( t, scene, this );
  2358. }
  2359. }
  2360. //-----------------------------------------------------------------------------
  2361. // Purpose:
  2362. // Input : *cb -
  2363. // t -
  2364. //-----------------------------------------------------------------------------
  2365. void CChoreoEvent::ContinueProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
  2366. {
  2367. Assert( m_bProcessing );
  2368. if ( cb )
  2369. {
  2370. cb->ProcessEvent( t, scene, this );
  2371. }
  2372. }
  2373. //-----------------------------------------------------------------------------
  2374. // Purpose:
  2375. // Input : *cb -
  2376. // t -
  2377. //-----------------------------------------------------------------------------
  2378. void CChoreoEvent::StopProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
  2379. {
  2380. Assert( m_bProcessing );
  2381. if ( cb )
  2382. {
  2383. cb->EndEvent( t, scene, this );
  2384. }
  2385. m_bProcessing = false;
  2386. m_bHasStopped = true;
  2387. }
  2388. //-----------------------------------------------------------------------------
  2389. // Purpose:
  2390. // Input : *cb -
  2391. // t -
  2392. //-----------------------------------------------------------------------------
  2393. bool CChoreoEvent::CheckProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
  2394. {
  2395. //Assert( !m_bProcessing );
  2396. if ( cb )
  2397. {
  2398. return cb->CheckEvent( t, scene, this );
  2399. }
  2400. return true;
  2401. }
  2402. //-----------------------------------------------------------------------------
  2403. // Purpose:
  2404. //-----------------------------------------------------------------------------
  2405. void CChoreoEvent::ResetProcessing( void )
  2406. {
  2407. if ( GetType() == LOOP )
  2408. {
  2409. m_nLoopsRemaining = m_nNumLoops;
  2410. }
  2411. m_bProcessing = false;
  2412. m_bHasStopped = false;
  2413. }
  2414. //-----------------------------------------------------------------------------
  2415. // Purpose:
  2416. // Input : *mixer -
  2417. //-----------------------------------------------------------------------------
  2418. void CChoreoEvent::SetMixer( CAudioMixer *mixer )
  2419. {
  2420. m_pMixer = mixer;
  2421. }
  2422. //-----------------------------------------------------------------------------
  2423. // Purpose:
  2424. // Output : CAudioMixer
  2425. //-----------------------------------------------------------------------------
  2426. CAudioMixer *CChoreoEvent::GetMixer( void ) const
  2427. {
  2428. return m_pMixer;
  2429. }
  2430. // Snap to scene framerate
  2431. //-----------------------------------------------------------------------------
  2432. // Purpose:
  2433. //-----------------------------------------------------------------------------
  2434. void CChoreoEvent::SnapTimes()
  2435. {
  2436. if ( HasEndTime() && !IsFixedLength() )
  2437. {
  2438. m_flEndTime = SnapTime( m_flEndTime );
  2439. }
  2440. float oldstart = m_flStartTime;
  2441. m_flStartTime = SnapTime( m_flStartTime );
  2442. // Don't snap end time for fixed length events, just set based on new start time
  2443. if ( IsFixedLength() )
  2444. {
  2445. float dt = m_flStartTime - oldstart;
  2446. m_flEndTime += dt;
  2447. }
  2448. }
  2449. //-----------------------------------------------------------------------------
  2450. // Purpose:
  2451. // Input : t -
  2452. // Output : float
  2453. //-----------------------------------------------------------------------------
  2454. float CChoreoEvent::SnapTime( float t )
  2455. {
  2456. CChoreoScene *scene = GetScene();
  2457. if ( !scene)
  2458. {
  2459. Assert( 0 );
  2460. return t;
  2461. }
  2462. return scene->SnapTime( t );
  2463. }
  2464. //-----------------------------------------------------------------------------
  2465. // Purpose:
  2466. // Output : CChoreoScene
  2467. //-----------------------------------------------------------------------------
  2468. CChoreoScene *CChoreoEvent::GetScene( void )
  2469. {
  2470. return m_pScene;
  2471. }
  2472. //-----------------------------------------------------------------------------
  2473. // Purpose:
  2474. // Input : *scene -
  2475. //-----------------------------------------------------------------------------
  2476. void CChoreoEvent::SetScene( CChoreoScene *scene )
  2477. {
  2478. m_pScene = scene;
  2479. }
  2480. //-----------------------------------------------------------------------------
  2481. // Purpose:
  2482. // Input : t -
  2483. // Output : char const
  2484. //-----------------------------------------------------------------------------
  2485. const char *CChoreoEvent::NameForAbsoluteTagType( AbsTagType t )
  2486. {
  2487. switch ( t )
  2488. {
  2489. case PLAYBACK:
  2490. return "playback_time";
  2491. case ORIGINAL:
  2492. return "shifted_time";
  2493. default:
  2494. break;
  2495. }
  2496. return "AbsTagType(unknown)";
  2497. }
  2498. //-----------------------------------------------------------------------------
  2499. // Purpose:
  2500. // Input : *name -
  2501. // Output : AbsTagType
  2502. //-----------------------------------------------------------------------------
  2503. CChoreoEvent::AbsTagType CChoreoEvent::TypeForAbsoluteTagName( const char *name )
  2504. {
  2505. if ( !Q_strcasecmp( name, "playback_time" ) )
  2506. {
  2507. return PLAYBACK;
  2508. }
  2509. else if ( !Q_strcasecmp( name, "shifted_time" ) )
  2510. {
  2511. return ORIGINAL;
  2512. }
  2513. return INVALID;
  2514. }
  2515. //-----------------------------------------------------------------------------
  2516. // Purpose:
  2517. // Input : type -
  2518. //-----------------------------------------------------------------------------
  2519. void CChoreoEvent::ClearAllAbsoluteTags( AbsTagType type )
  2520. {
  2521. m_AbsoluteTags[ type ].Purge();
  2522. }
  2523. //-----------------------------------------------------------------------------
  2524. // Purpose:
  2525. // Input : type -
  2526. // Output : int
  2527. //-----------------------------------------------------------------------------
  2528. int CChoreoEvent::GetNumAbsoluteTags( AbsTagType type )
  2529. {
  2530. return m_AbsoluteTags[ type ].Count();
  2531. }
  2532. //-----------------------------------------------------------------------------
  2533. // Purpose:
  2534. // Input : type -
  2535. // tagnum -
  2536. // Output : CEventAbsoluteTag
  2537. //-----------------------------------------------------------------------------
  2538. CEventAbsoluteTag *CChoreoEvent::GetAbsoluteTag( AbsTagType type, int tagnum )
  2539. {
  2540. Assert( tagnum >= 0 && tagnum < m_AbsoluteTags[ type ].Count() );
  2541. return &m_AbsoluteTags[ type ][ tagnum ];
  2542. }
  2543. //-----------------------------------------------------------------------------
  2544. // Purpose:
  2545. // Input : type -
  2546. // *tagname -
  2547. // Output : CEventAbsoluteTag
  2548. //-----------------------------------------------------------------------------
  2549. CEventAbsoluteTag *CChoreoEvent::FindAbsoluteTag( AbsTagType type, const char *tagname )
  2550. {
  2551. for ( int i = 0; i < m_AbsoluteTags[ type ].Count(); i++ )
  2552. {
  2553. CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
  2554. if ( !ptag )
  2555. continue;
  2556. if ( !stricmp( ptag->GetName(), tagname ) )
  2557. {
  2558. return ptag;
  2559. }
  2560. }
  2561. return NULL;
  2562. }
  2563. //-----------------------------------------------------------------------------
  2564. // Purpose:
  2565. // Input : type -
  2566. // *tagname -
  2567. // t -
  2568. //-----------------------------------------------------------------------------
  2569. void CChoreoEvent::AddAbsoluteTag( AbsTagType type, const char *tagname, float t )
  2570. {
  2571. CEventAbsoluteTag at( this, tagname, t );
  2572. m_AbsoluteTags[ type ].AddToTail( at );
  2573. // Sort tags
  2574. CEventAbsoluteTag temp( (CChoreoEvent *)0x1, "", 0.0f );
  2575. // ugly bubble sort
  2576. for ( int i = 0; i < m_AbsoluteTags[ type ].Count(); i++ )
  2577. {
  2578. for ( int j = i + 1; j < m_AbsoluteTags[ type ].Count(); j++ )
  2579. {
  2580. CEventAbsoluteTag *t1 = &m_AbsoluteTags[ type ][ i ];
  2581. CEventAbsoluteTag *t2 = &m_AbsoluteTags[ type ][ j ];
  2582. if ( t1->GetPercentage() > t2->GetPercentage() )
  2583. {
  2584. temp = *t1;
  2585. *t1 = *t2;
  2586. *t2 = temp;
  2587. }
  2588. }
  2589. }
  2590. }
  2591. //-----------------------------------------------------------------------------
  2592. // Purpose:
  2593. // Input : type -
  2594. // *tagname -
  2595. //-----------------------------------------------------------------------------
  2596. void CChoreoEvent::RemoveAbsoluteTag( AbsTagType type, const char *tagname )
  2597. {
  2598. for ( int i = 0; i < m_AbsoluteTags[ type ].Count(); i++ )
  2599. {
  2600. CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
  2601. if ( !ptag )
  2602. continue;
  2603. if ( !stricmp( ptag->GetName(), tagname ) )
  2604. {
  2605. m_AbsoluteTags[ type ].Remove( i );
  2606. return;
  2607. }
  2608. }
  2609. }
  2610. //-----------------------------------------------------------------------------
  2611. // Purpose: makes sure tags in PLAYBACK are in the same order as ORIGINAL
  2612. // Input :
  2613. // Output : true if they were in order, false if it has to reorder them
  2614. //-----------------------------------------------------------------------------
  2615. bool CChoreoEvent::VerifyTagOrder( )
  2616. {
  2617. bool bInOrder = true;
  2618. // Sort tags
  2619. CEventAbsoluteTag temp( (CChoreoEvent *)0x1, "", 0.0f );
  2620. for ( int i = 0; i < m_AbsoluteTags[ CChoreoEvent::ORIGINAL ].Count(); i++ )
  2621. {
  2622. CEventAbsoluteTag *ptag = &m_AbsoluteTags[ CChoreoEvent::ORIGINAL ][ i ];
  2623. if ( !ptag )
  2624. continue;
  2625. CEventAbsoluteTag *t1 = &m_AbsoluteTags[ CChoreoEvent::PLAYBACK ][ i ];
  2626. if ( stricmp( ptag->GetName(), t1->GetName() ) == 0)
  2627. continue;
  2628. bInOrder = false;
  2629. for ( int j = i + 1; j < m_AbsoluteTags[ CChoreoEvent::PLAYBACK ].Count(); j++ )
  2630. {
  2631. CEventAbsoluteTag *t2 = &m_AbsoluteTags[ CChoreoEvent::PLAYBACK ][ j ];
  2632. if ( stricmp( ptag->GetName(), t2->GetName() ) == 0 )
  2633. {
  2634. temp = *t1;
  2635. *t1 = *t2;
  2636. *t2 = temp;
  2637. break;
  2638. }
  2639. }
  2640. }
  2641. return bInOrder;
  2642. }
  2643. //-----------------------------------------------------------------------------
  2644. // Purpose:
  2645. // Input : type -
  2646. // *tagname -
  2647. //-----------------------------------------------------------------------------
  2648. float CChoreoEvent::GetBoundedAbsoluteTagPercentage( AbsTagType type, int tagnum )
  2649. {
  2650. if ( tagnum <= -2 )
  2651. {
  2652. /*
  2653. if (GetNumAbsoluteTags( type ) >= 1)
  2654. {
  2655. CEventAbsoluteTag *tag = GetAbsoluteTag( type, 0 );
  2656. Assert( tag );
  2657. return -tag->GetTime();
  2658. }
  2659. */
  2660. return 0.0f; // -0.5f;
  2661. }
  2662. else if ( tagnum == -1 )
  2663. {
  2664. return 0.0f;
  2665. }
  2666. else if ( tagnum == GetNumAbsoluteTags( type ) )
  2667. {
  2668. return 1.0;
  2669. }
  2670. else if ( tagnum > GetNumAbsoluteTags( type ) )
  2671. {
  2672. /*
  2673. if (GetNumAbsoluteTags( type ) >= 1)
  2674. {
  2675. CEventAbsoluteTag *tag = GetAbsoluteTag( type, tagnum - 2 );
  2676. Assert( tag );
  2677. return 2.0 - tag->GetTime();
  2678. }
  2679. */
  2680. return 1.0; // 1.5;
  2681. }
  2682. /*
  2683. {
  2684. float duration = GetDuration();
  2685. if ( type == SHIFTED )
  2686. {
  2687. float seqduration;
  2688. GetGestureSequenceDuration( seqduration );
  2689. return seqduration;
  2690. }
  2691. return duration;
  2692. }
  2693. */
  2694. CEventAbsoluteTag *tag = GetAbsoluteTag( type, tagnum );
  2695. Assert( tag );
  2696. return tag->GetPercentage();
  2697. }
  2698. //-----------------------------------------------------------------------------
  2699. // Purpose:
  2700. // Input : t -
  2701. // Output : float
  2702. //-----------------------------------------------------------------------------
  2703. float CChoreoEvent::GetOriginalPercentageFromPlaybackPercentage( float t )
  2704. {
  2705. Assert( GetType() == GESTURE );
  2706. if ( GetType() != GESTURE )
  2707. return t;
  2708. int count = GetNumAbsoluteTags( PLAYBACK );
  2709. if ( count != GetNumAbsoluteTags( ORIGINAL ) )
  2710. {
  2711. return t;
  2712. }
  2713. if ( count <= 0 )
  2714. {
  2715. return t;
  2716. }
  2717. if ( t <= 0.0f )
  2718. return 0.0f;
  2719. float s = 0.0f, n = 0.0f;
  2720. // find what tags this is between
  2721. int i;
  2722. for ( i = -1 ; i < count; i++ )
  2723. {
  2724. s = GetBoundedAbsoluteTagPercentage( PLAYBACK, i );
  2725. n = GetBoundedAbsoluteTagPercentage( PLAYBACK, i + 1 );
  2726. if ( t >= s && t <= n )
  2727. {
  2728. break;
  2729. }
  2730. }
  2731. int prev = i - 1;
  2732. int start = i;
  2733. int end = i + 1;
  2734. int next = i + 2;
  2735. prev = MAX( -2, prev );
  2736. start = MAX( -1, start );
  2737. end = MIN( end, count );
  2738. next = MIN( next, count + 1 );
  2739. CEventAbsoluteTag *pStartTag = NULL;
  2740. CEventAbsoluteTag *pEndTag = NULL;
  2741. // check for linear portion of lookup
  2742. if (start >= 0 && start < count)
  2743. {
  2744. pStartTag = GetAbsoluteTag( PLAYBACK, start );
  2745. }
  2746. if (end >= 0 && end < count)
  2747. {
  2748. pEndTag = GetAbsoluteTag( PLAYBACK, end );
  2749. }
  2750. if (pStartTag && pEndTag)
  2751. {
  2752. if (pStartTag->GetLinear() && pEndTag->GetLinear())
  2753. {
  2754. CEventAbsoluteTag *pOrigStartTag = GetAbsoluteTag( ORIGINAL, start );
  2755. CEventAbsoluteTag *pOrigEndTag = GetAbsoluteTag( ORIGINAL, end );
  2756. if (pOrigStartTag && pOrigEndTag)
  2757. {
  2758. s = ( t - pStartTag->GetPercentage() ) / (pEndTag->GetPercentage() - pStartTag->GetPercentage());
  2759. return (1 - s) * pOrigStartTag->GetPercentage() + s * pOrigEndTag->GetPercentage();
  2760. }
  2761. }
  2762. }
  2763. float dt = n - s;
  2764. Vector vPre( GetBoundedAbsoluteTagPercentage( PLAYBACK, prev ), GetBoundedAbsoluteTagPercentage( ORIGINAL, prev ), 0 );
  2765. Vector vStart( GetBoundedAbsoluteTagPercentage( PLAYBACK, start ), GetBoundedAbsoluteTagPercentage( ORIGINAL, start ), 0 );
  2766. Vector vEnd( GetBoundedAbsoluteTagPercentage( PLAYBACK, end ), GetBoundedAbsoluteTagPercentage( ORIGINAL, end ), 0 );
  2767. Vector vNext( GetBoundedAbsoluteTagPercentage( PLAYBACK, next ), GetBoundedAbsoluteTagPercentage( ORIGINAL, next ), 0 );
  2768. // simulate sections of either side of "linear" portion of ramp as linear slope
  2769. if (pStartTag && pStartTag->GetLinear())
  2770. {
  2771. vPre.Init( vStart.x - (vEnd.x - vStart.x), vStart.y - (vEnd.y - vStart.y), 0 );
  2772. }
  2773. if (pEndTag && pEndTag->GetLinear())
  2774. {
  2775. vNext.Init( vEnd.x + (vEnd.x - vStart.x), vEnd.y + (vEnd.y - vStart.y), 0 );
  2776. }
  2777. float f2 = 0.0f;
  2778. if ( dt > 0.0f )
  2779. {
  2780. f2 = ( t - s ) / ( dt );
  2781. }
  2782. f2 = clamp( f2, 0.0f, 1.0f );
  2783. Vector vOut;
  2784. Catmull_Rom_Spline_NormalizeX(
  2785. vPre,
  2786. vStart,
  2787. vEnd,
  2788. vNext,
  2789. f2,
  2790. vOut );
  2791. return vOut.y;
  2792. /*
  2793. float duration;
  2794. GetGestureSequenceDuration( duration );
  2795. float retval = clamp( vOut.y, 0.0f, duration );
  2796. return retval;
  2797. */
  2798. }
  2799. //-----------------------------------------------------------------------------
  2800. // Purpose:
  2801. // Input : t -
  2802. // Output : float
  2803. //-----------------------------------------------------------------------------
  2804. float CChoreoEvent::GetPlaybackPercentageFromOriginalPercentage( float t )
  2805. {
  2806. Assert( GetType() == GESTURE );
  2807. if ( GetType() != GESTURE )
  2808. return t;
  2809. int count = GetNumAbsoluteTags( PLAYBACK );
  2810. if ( count != GetNumAbsoluteTags( ORIGINAL ) )
  2811. {
  2812. return t;
  2813. }
  2814. if ( count <= 0 )
  2815. {
  2816. return t;
  2817. }
  2818. if ( t <= 0.0f )
  2819. return 0.0f;
  2820. float s = 0.0f, n = 0.0f;
  2821. // find what tags this is between
  2822. int i;
  2823. for ( i = -1 ; i < count; i++ )
  2824. {
  2825. s = GetBoundedAbsoluteTagPercentage( PLAYBACK, i );
  2826. n = GetBoundedAbsoluteTagPercentage( PLAYBACK, i + 1 );
  2827. if ( t >= s && t <= n )
  2828. {
  2829. break;
  2830. }
  2831. }
  2832. int prev = i - 1;
  2833. int start = i;
  2834. int end = i + 1;
  2835. int next = i + 2;
  2836. prev = MAX( -2, prev );
  2837. start = MAX( -1, start );
  2838. end = MIN( end, count );
  2839. next = MIN( next, count + 1 );
  2840. CEventAbsoluteTag *pStartTag = NULL;
  2841. CEventAbsoluteTag *pEndTag = NULL;
  2842. // check for linear portion of lookup
  2843. if (start >= 0 && start < count)
  2844. {
  2845. pStartTag = GetAbsoluteTag( ORIGINAL, start );
  2846. }
  2847. if (end >= 0 && end < count)
  2848. {
  2849. pEndTag = GetAbsoluteTag( ORIGINAL, end );
  2850. }
  2851. // check for linear portion of lookup
  2852. if (pStartTag && pEndTag)
  2853. {
  2854. if (pStartTag->GetLinear() && pEndTag->GetLinear())
  2855. {
  2856. CEventAbsoluteTag *pPlaybackStartTag = GetAbsoluteTag( PLAYBACK, start );
  2857. CEventAbsoluteTag *pPlaybackEndTag = GetAbsoluteTag( PLAYBACK, end );
  2858. if (pPlaybackStartTag && pPlaybackEndTag)
  2859. {
  2860. s = ( t - pStartTag->GetPercentage() ) / (pEndTag->GetPercentage() - pStartTag->GetPercentage());
  2861. return (1 - s) * pPlaybackStartTag->GetPercentage() + s * pPlaybackEndTag->GetPercentage();
  2862. }
  2863. }
  2864. }
  2865. float dt = n - s;
  2866. Vector vPre( GetBoundedAbsoluteTagPercentage( ORIGINAL, prev ), GetBoundedAbsoluteTagPercentage( PLAYBACK, prev ), 0 );
  2867. Vector vStart( GetBoundedAbsoluteTagPercentage( ORIGINAL, start ), GetBoundedAbsoluteTagPercentage( PLAYBACK, start ), 0 );
  2868. Vector vEnd( GetBoundedAbsoluteTagPercentage( ORIGINAL, end ), GetBoundedAbsoluteTagPercentage( PLAYBACK, end ), 0 );
  2869. Vector vNext( GetBoundedAbsoluteTagPercentage( ORIGINAL, next ), GetBoundedAbsoluteTagPercentage( PLAYBACK, next ), 0 );
  2870. // simulate sections of either side of "linear" portion of ramp as linear slope
  2871. if (pStartTag && pStartTag->GetLinear())
  2872. {
  2873. vPre.Init( vStart.x - (vEnd.x - vStart.x), vStart.y - (vEnd.y - vStart.y), 0 );
  2874. }
  2875. if (pEndTag && pEndTag->GetLinear())
  2876. {
  2877. vNext.Init( vEnd.x + (vEnd.x - vStart.x), vEnd.y + (vEnd.y - vStart.y), 0 );
  2878. }
  2879. float f2 = 0.0f;
  2880. if ( dt > 0.0f )
  2881. {
  2882. f2 = ( t - s ) / ( dt );
  2883. }
  2884. f2 = clamp( f2, 0.0f, 1.0f );
  2885. Vector vOut;
  2886. Catmull_Rom_Spline_NormalizeX(
  2887. vPre,
  2888. vStart,
  2889. vEnd,
  2890. vNext,
  2891. f2,
  2892. vOut );
  2893. return vOut.y;
  2894. /*
  2895. float duration;
  2896. GetGestureSequenceDuration( duration );
  2897. float retval = clamp( vOut.y, 0.0f, duration );
  2898. return retval;
  2899. */
  2900. }
  2901. //-----------------------------------------------------------------------------
  2902. // Purpose:
  2903. // Input : duration -
  2904. //-----------------------------------------------------------------------------
  2905. void CChoreoEvent::SetGestureSequenceDuration( float duration )
  2906. {
  2907. m_flGestureSequenceDuration = duration;
  2908. }
  2909. //-----------------------------------------------------------------------------
  2910. // Purpose:
  2911. // Input : duration -
  2912. // Output : Returns true on success, false on failure.
  2913. //-----------------------------------------------------------------------------
  2914. bool CChoreoEvent::GetGestureSequenceDuration( float& duration )
  2915. {
  2916. bool valid = m_flGestureSequenceDuration != 0.0f;
  2917. if ( !valid )
  2918. {
  2919. duration = GetDuration();
  2920. }
  2921. else
  2922. {
  2923. duration = m_flGestureSequenceDuration;
  2924. }
  2925. return valid;
  2926. }
  2927. //-----------------------------------------------------------------------------
  2928. // Purpose:
  2929. // Input : pitch -
  2930. //-----------------------------------------------------------------------------
  2931. int CChoreoEvent::GetPitch( void ) const
  2932. {
  2933. return m_nPitch;
  2934. }
  2935. //-----------------------------------------------------------------------------
  2936. // Purpose:
  2937. // Input : pitch -
  2938. //-----------------------------------------------------------------------------
  2939. void CChoreoEvent::SetPitch( int pitch )
  2940. {
  2941. m_nPitch = pitch;
  2942. }
  2943. //-----------------------------------------------------------------------------
  2944. // Purpose:
  2945. // Input : yaw -
  2946. //-----------------------------------------------------------------------------
  2947. int CChoreoEvent::GetYaw( void ) const
  2948. {
  2949. return m_nYaw;
  2950. }
  2951. //-----------------------------------------------------------------------------
  2952. // Purpose:
  2953. // Input : yaw -
  2954. //-----------------------------------------------------------------------------
  2955. void CChoreoEvent::SetYaw( int yaw )
  2956. {
  2957. m_nYaw = yaw;
  2958. }
  2959. //-----------------------------------------------------------------------------
  2960. // Purpose:
  2961. // Input : t -
  2962. // -1 -
  2963. //-----------------------------------------------------------------------------
  2964. void CChoreoEvent::SetLoopCount( int numloops )
  2965. {
  2966. Assert( GetType() == LOOP );
  2967. // Never below -1
  2968. m_nNumLoops = MAX( numloops, -1 );
  2969. }
  2970. //-----------------------------------------------------------------------------
  2971. // Purpose:
  2972. // Output : int
  2973. //-----------------------------------------------------------------------------
  2974. int CChoreoEvent::GetNumLoopsRemaining( void )
  2975. {
  2976. Assert( GetType() == LOOP );
  2977. return m_nLoopsRemaining;
  2978. }
  2979. //-----------------------------------------------------------------------------
  2980. // Purpose:
  2981. // Input : loops -
  2982. //-----------------------------------------------------------------------------
  2983. void CChoreoEvent::SetNumLoopsRemaining( int loops )
  2984. {
  2985. Assert( GetType() == LOOP );
  2986. m_nLoopsRemaining = loops;
  2987. }
  2988. //-----------------------------------------------------------------------------
  2989. // Purpose:
  2990. // Output : int
  2991. //-----------------------------------------------------------------------------
  2992. int CChoreoEvent::GetLoopCount( void )
  2993. {
  2994. Assert( GetType() == LOOP );
  2995. return m_nNumLoops;
  2996. }
  2997. EdgeInfo_t *CCurveData::GetEdgeInfo( int idx )
  2998. {
  2999. return &m_RampEdgeInfo[ idx ];
  3000. }
  3001. int CCurveData::GetCount( void )
  3002. {
  3003. return m_Ramp.Count();
  3004. }
  3005. CExpressionSample *CCurveData::Get( int index )
  3006. {
  3007. if ( index < 0 || index >= GetCount() )
  3008. return NULL;
  3009. return &m_Ramp[ index ];
  3010. }
  3011. CExpressionSample *CCurveData::Add( float time, float value, bool selected )
  3012. {
  3013. CExpressionSample sample;
  3014. sample.time = time;
  3015. sample.value = value;
  3016. sample.selected = selected;
  3017. int idx = m_Ramp.AddToTail( sample );
  3018. return &m_Ramp[ idx ];
  3019. }
  3020. void CCurveData::Delete( int index )
  3021. {
  3022. if ( index < 0 || index >= GetCount() )
  3023. return;
  3024. m_Ramp.Remove( index );
  3025. }
  3026. void CCurveData::Clear( void )
  3027. {
  3028. m_Ramp.RemoveAll();
  3029. }
  3030. //-----------------------------------------------------------------------------
  3031. // Purpose:
  3032. //-----------------------------------------------------------------------------
  3033. void CCurveData::Resort( ICurveDataAccessor *data )
  3034. {
  3035. for ( int i = 0; i < m_Ramp.Count(); i++ )
  3036. {
  3037. for ( int j = i + 1; j < m_Ramp.Count(); j++ )
  3038. {
  3039. CExpressionSample src = m_Ramp[ i ];
  3040. CExpressionSample dest = m_Ramp[ j ];
  3041. if ( src.time > dest.time )
  3042. {
  3043. m_Ramp[ i ] = dest;
  3044. m_Ramp[ j ] = src;
  3045. }
  3046. }
  3047. }
  3048. RemoveOutOfRangeSamples( data );
  3049. // m_RampAccumulator.RemoveAll();
  3050. }
  3051. //-----------------------------------------------------------------------------
  3052. // Purpose:
  3053. // Input : number -
  3054. // Output : CExpressionSample
  3055. //-----------------------------------------------------------------------------
  3056. CExpressionSample *CCurveData::GetBoundedSample( ICurveDataAccessor *data, int number, bool& bClamped )
  3057. {
  3058. // Search for two samples which span time f
  3059. if ( number < 0 )
  3060. {
  3061. static CExpressionSample nullstart;
  3062. nullstart.time = 0.0f;
  3063. nullstart.value = GetEdgeZeroValue( true );
  3064. nullstart.SetCurveType( GetEdgeCurveType( true ) );
  3065. bClamped = true;
  3066. return &nullstart;
  3067. }
  3068. else if ( number >= GetCount() )
  3069. {
  3070. static CExpressionSample nullend;
  3071. nullend.time = data->GetDuration();
  3072. nullend.value = GetEdgeZeroValue( false );
  3073. nullend.SetCurveType( GetEdgeCurveType( false ) );
  3074. bClamped = true;
  3075. return &nullend;
  3076. }
  3077. bClamped = false;
  3078. return Get( number );
  3079. }
  3080. //-----------------------------------------------------------------------------
  3081. // Purpose:
  3082. //-----------------------------------------------------------------------------
  3083. void CCurveData::RemoveOutOfRangeSamples( ICurveDataAccessor *data )
  3084. {
  3085. float duration = data->GetDuration();
  3086. int c = GetCount();
  3087. for ( int i = c-1; i >= 0; i-- )
  3088. {
  3089. CExpressionSample src = m_Ramp[ i ];
  3090. if ( src.time < 0 ||
  3091. src.time > duration + 0.01 )
  3092. {
  3093. m_Ramp.Remove( i );
  3094. }
  3095. }
  3096. }
  3097. //-----------------------------------------------------------------------------
  3098. // Purpose:
  3099. //-----------------------------------------------------------------------------
  3100. void CChoreoEvent::RescaleGestureTimes( float newstart, float newend, bool bMaintainAbsoluteTagPositions )
  3101. {
  3102. if ( GetType() != CChoreoEvent::GESTURE )
  3103. return;
  3104. // Did it actually change
  3105. if ( newstart == GetStartTime() &&
  3106. newend == GetEndTime() )
  3107. {
  3108. return;
  3109. }
  3110. float newduration = newend - newstart;
  3111. float dt = 0.0f;
  3112. //If the end is moving, leave tags stay where they are (dt == 0.0f)
  3113. if ( newstart != GetStartTime() )
  3114. {
  3115. // Otherwise, if the new start is later, then tags need to be shifted backwards
  3116. dt -= ( newstart - GetStartTime() );
  3117. }
  3118. if ( bMaintainAbsoluteTagPositions )
  3119. {
  3120. int i;
  3121. int count = GetNumAbsoluteTags( CChoreoEvent::PLAYBACK );
  3122. for ( i = 0; i < count; i++ )
  3123. {
  3124. CEventAbsoluteTag *tag = GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
  3125. float tagtime = tag->GetPercentage() * GetDuration();
  3126. tagtime += dt;
  3127. tagtime = clamp( tagtime / newduration, 0.0f, 1.0f );
  3128. tag->SetPercentage( tagtime );
  3129. }
  3130. }
  3131. }
  3132. //-----------------------------------------------------------------------------
  3133. // Purpose: Make sure tags aren't co-located or out of order
  3134. //-----------------------------------------------------------------------------
  3135. bool CChoreoEvent::PreventTagOverlap( void )
  3136. {
  3137. bool bHadOverlap = false;
  3138. // FIXME: limit to single frame?
  3139. float minDp = 0.01;
  3140. float minP = 1.00;
  3141. int count = GetNumAbsoluteTags( CChoreoEvent::PLAYBACK );
  3142. for ( int i = count - 1; i >= 0; i-- )
  3143. {
  3144. CEventAbsoluteTag *tag = GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
  3145. if (tag->GetPercentage() > minP)
  3146. {
  3147. tag->SetPercentage( minP );
  3148. minDp = MIN( 0.01, minP / (i + 1) );
  3149. bHadOverlap = true;
  3150. }
  3151. else
  3152. {
  3153. minP = tag->GetPercentage();
  3154. }
  3155. minP = MAX( minP - minDp, 0 );
  3156. }
  3157. return bHadOverlap;
  3158. }
  3159. //-----------------------------------------------------------------------------
  3160. // Purpose:
  3161. // Input : type -
  3162. // Output : CEventAbsoluteTag
  3163. //-----------------------------------------------------------------------------
  3164. CEventAbsoluteTag *CChoreoEvent::FindEntryTag( AbsTagType type )
  3165. {
  3166. for ( int i = 0; i < m_AbsoluteTags[ type ].Count(); i++ )
  3167. {
  3168. CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
  3169. if ( !ptag )
  3170. continue;
  3171. if ( ptag->GetEntry() )
  3172. {
  3173. return ptag;
  3174. }
  3175. }
  3176. return NULL;
  3177. }
  3178. //-----------------------------------------------------------------------------
  3179. // Purpose:
  3180. // Input : type -
  3181. // Output : CEventAbsoluteTag
  3182. //-----------------------------------------------------------------------------
  3183. CEventAbsoluteTag *CChoreoEvent::FindExitTag( AbsTagType type )
  3184. {
  3185. for ( int i = 0; i < m_AbsoluteTags[ type ].Count(); i++ )
  3186. {
  3187. CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
  3188. if ( !ptag )
  3189. continue;
  3190. if ( ptag->GetExit() )
  3191. {
  3192. return ptag;
  3193. }
  3194. }
  3195. return NULL;
  3196. }
  3197. //-----------------------------------------------------------------------------
  3198. // Purpose:
  3199. // Input : *style -
  3200. // maxlen -
  3201. //-----------------------------------------------------------------------------
  3202. void CChoreoEvent::GetMovementStyle( char *style, int maxlen )
  3203. {
  3204. Assert( GetType() == MOVETO );
  3205. style[0] = 0;
  3206. const char *in = m_Parameters2.Get();
  3207. char *out = style;
  3208. while ( *in && *in != '\0' && *in != ' ' )
  3209. {
  3210. if ( out - style >= maxlen - 1 )
  3211. break;
  3212. *out++ = *in++;
  3213. }
  3214. *out = 0;
  3215. }
  3216. //-----------------------------------------------------------------------------
  3217. // Purpose:
  3218. // Input : *style -
  3219. // maxlen -
  3220. //-----------------------------------------------------------------------------
  3221. void CChoreoEvent::GetDistanceStyle( char *style, int maxlen )
  3222. {
  3223. Assert( GetType() == MOVETO );
  3224. style[0]= 0;
  3225. const char *in = Q_strstr( m_Parameters2.Get(), " " );
  3226. if ( !in )
  3227. return;
  3228. in++;
  3229. char *out = style;
  3230. while ( *in && *in != '\0' )
  3231. {
  3232. if ( out - style >= maxlen - 1 )
  3233. break;
  3234. *out++ = *in++;
  3235. }
  3236. *out = 0;
  3237. }
  3238. void CChoreoEvent::SetCloseCaptionType( CLOSECAPTION type )
  3239. {
  3240. Assert( m_fType == SPEAK );
  3241. m_ccType = type;
  3242. }
  3243. CChoreoEvent::CLOSECAPTION CChoreoEvent::GetCloseCaptionType() const
  3244. {
  3245. Assert( m_fType == SPEAK );
  3246. return (CLOSECAPTION)m_ccType;
  3247. }
  3248. void CChoreoEvent::SetCloseCaptionToken( char const *token )
  3249. {
  3250. Assert( m_fType == SPEAK );
  3251. Assert( token );
  3252. m_CCToken = token;
  3253. }
  3254. char const *CChoreoEvent::GetCloseCaptionToken() const
  3255. {
  3256. Assert( m_fType == SPEAK );
  3257. return m_CCToken.Get();
  3258. }
  3259. bool CChoreoEvent::GetPlaybackCloseCaptionToken( char *dest, int destlen )
  3260. {
  3261. dest[0] = 0;
  3262. Assert( m_fType == SPEAK );
  3263. switch ( m_ccType )
  3264. {
  3265. default:
  3266. case CC_DISABLED:
  3267. {
  3268. return false;
  3269. }
  3270. case CC_SLAVE:
  3271. {
  3272. // If it's a slave, then only disable if we're not using the combined wave
  3273. if ( IsUsingCombinedFile() )
  3274. {
  3275. return false;
  3276. }
  3277. if ( m_CCToken[ 0 ] != 0 )
  3278. {
  3279. Q_strncpy( dest, m_CCToken.Get(), destlen );
  3280. }
  3281. else
  3282. {
  3283. Q_strncpy( dest, m_Parameters.Get(), destlen );
  3284. }
  3285. return true;
  3286. }
  3287. case CC_MASTER:
  3288. {
  3289. // Always use the override if we're the master, otherwise always use the default
  3290. // parameter
  3291. if ( m_CCToken[ 0 ] != 0 )
  3292. {
  3293. Q_strncpy( dest, m_CCToken.Get(), destlen );
  3294. }
  3295. else
  3296. {
  3297. Q_strncpy( dest, m_Parameters.Get(), destlen );
  3298. }
  3299. return true;
  3300. }
  3301. }
  3302. return false;
  3303. }
  3304. void CChoreoEvent::SetUsingCombinedFile( bool isusing )
  3305. {
  3306. Assert( m_fType == SPEAK );
  3307. m_bUsingCombinedSoundFile = isusing;
  3308. }
  3309. bool CChoreoEvent::IsUsingCombinedFile() const
  3310. {
  3311. Assert( m_fType == SPEAK );
  3312. return m_bUsingCombinedSoundFile;
  3313. }
  3314. void CChoreoEvent::SetRequiredCombinedChecksum( unsigned int checksum )
  3315. {
  3316. Assert( m_fType == SPEAK );
  3317. m_uRequiredCombinedChecksum = checksum;
  3318. }
  3319. unsigned int CChoreoEvent::GetRequiredCombinedChecksum()
  3320. {
  3321. Assert( m_fType == SPEAK );
  3322. return m_uRequiredCombinedChecksum;
  3323. }
  3324. void CChoreoEvent::SetNumSlaves( int num )
  3325. {
  3326. Assert( m_fType == SPEAK );
  3327. Assert( num >= 0 );
  3328. m_nNumSlaves = num;
  3329. }
  3330. int CChoreoEvent::GetNumSlaves() const
  3331. {
  3332. Assert( m_fType == SPEAK );
  3333. return m_nNumSlaves;
  3334. }
  3335. void CChoreoEvent::SetLastSlaveEndTime( float t )
  3336. {
  3337. Assert( m_fType == SPEAK );
  3338. m_flLastSlaveEndTime = t;
  3339. }
  3340. float CChoreoEvent::GetLastSlaveEndTime() const
  3341. {
  3342. Assert( m_fType == SPEAK );
  3343. return m_flLastSlaveEndTime;
  3344. }
  3345. void CChoreoEvent::SetCloseCaptionTokenValid( bool valid )
  3346. {
  3347. Assert( m_fType == SPEAK );
  3348. m_bCCTokenValid = valid;
  3349. }
  3350. bool CChoreoEvent::GetCloseCaptionTokenValid() const
  3351. {
  3352. Assert( m_fType == SPEAK );
  3353. return m_bCCTokenValid;
  3354. }
  3355. //-----------------------------------------------------------------------------
  3356. // Purpose: Removes characters which can't appear in windows filenames
  3357. // Input : *in -
  3358. // *dest -
  3359. // destlen -
  3360. // Output : static void
  3361. //-----------------------------------------------------------------------------
  3362. static void CleanupTokenName( char const *in, char *dest, int destlen )
  3363. {
  3364. char *out = dest;
  3365. while ( *in && ( out - dest ) < destlen )
  3366. {
  3367. if ( V_isalnum( *in ) || // lowercase, uppercase, digits and underscore are valid
  3368. *in == '_' )
  3369. {
  3370. *out++ = *in;
  3371. }
  3372. else
  3373. {
  3374. *out++ = '_'; // Put underscores in for bogus characters
  3375. }
  3376. in++;
  3377. }
  3378. *out = 0;
  3379. }
  3380. bool CChoreoEvent::ComputeCombinedBaseFileName( char *dest, int destlen, bool creategenderwildcard )
  3381. {
  3382. if ( m_fType != SPEAK )
  3383. return false;
  3384. if ( m_ccType != CC_MASTER )
  3385. return false;
  3386. if ( GetNumSlaves() == 0 )
  3387. return false;
  3388. if ( !m_pScene )
  3389. return false;
  3390. char vcdpath[ 512 ];
  3391. char cleanedtoken[ MAX_CCTOKEN_STRING ];
  3392. CleanupTokenName( m_CCToken.Get(), cleanedtoken, sizeof( cleanedtoken ) );
  3393. if ( Q_strlen( cleanedtoken ) <= 0 )
  3394. return false;
  3395. Q_strncpy( vcdpath, m_pScene->GetFilename(), sizeof( vcdpath ) );
  3396. Q_StripFilename( vcdpath );
  3397. Q_FixSlashes( vcdpath, '/' );
  3398. char *pvcd = vcdpath;
  3399. char *offset = Q_strstr( vcdpath, "scenes" );
  3400. if ( offset )
  3401. {
  3402. pvcd = offset + 6;
  3403. if ( *pvcd == '/' )
  3404. {
  3405. ++pvcd;
  3406. }
  3407. }
  3408. int len = Q_strlen( pvcd );
  3409. if ( len > 0 && ( len + 1 ) < ( sizeof( vcdpath ) - 1 ) )
  3410. {
  3411. pvcd[ len ] = '/';
  3412. pvcd[ len + 1 ] = 0;
  3413. }
  3414. Assert( !Q_strstr( pvcd, ":" ) );
  3415. if ( creategenderwildcard )
  3416. {
  3417. Q_snprintf( dest, destlen, "sound/combined/%s%s_$gender.wav", pvcd, cleanedtoken );
  3418. }
  3419. else
  3420. {
  3421. Q_snprintf( dest, destlen, "sound/combined/%s%s.wav", pvcd, cleanedtoken );
  3422. }
  3423. return true;
  3424. }
  3425. bool CChoreoEvent::IsCombinedUsingGenderToken() const
  3426. {
  3427. return m_bCombinedUsingGenderToken;
  3428. }
  3429. void CChoreoEvent::SetCombinedUsingGenderToken( bool using_gender )
  3430. {
  3431. m_bCombinedUsingGenderToken = using_gender;
  3432. }
  3433. int CChoreoEvent::ValidateCombinedFile()
  3434. {
  3435. return 0;
  3436. }
  3437. bool CChoreoEvent::IsSuppressingCaptionAttenuation() const
  3438. {
  3439. return m_bSuppressCaptionAttenuation;
  3440. }
  3441. void CChoreoEvent::SetSuppressingCaptionAttenuation( bool suppress )
  3442. {
  3443. m_bSuppressCaptionAttenuation = suppress;
  3444. }
  3445. //-----------------------------------------------------------------------------
  3446. // Purpose:
  3447. //-----------------------------------------------------------------------------
  3448. void CChoreoEvent::ClearEventDependencies()
  3449. {
  3450. m_Dependencies.RemoveAll();
  3451. }
  3452. //-----------------------------------------------------------------------------
  3453. // Purpose:
  3454. // Input : *other -
  3455. //-----------------------------------------------------------------------------
  3456. void CChoreoEvent::AddEventDependency( CChoreoEvent *other )
  3457. {
  3458. if ( m_Dependencies.Find( other ) == m_Dependencies.InvalidIndex() )
  3459. {
  3460. m_Dependencies.AddToTail( other );
  3461. }
  3462. }
  3463. //-----------------------------------------------------------------------------
  3464. // Purpose:
  3465. // Input : list -
  3466. //-----------------------------------------------------------------------------
  3467. void CChoreoEvent::GetEventDependencies( CUtlVector< CChoreoEvent * >& list )
  3468. {
  3469. int c = m_Dependencies.Count();
  3470. for ( int i = 0; i < c; ++i )
  3471. {
  3472. list.AddToTail( m_Dependencies[ i ] );
  3473. }
  3474. }
  3475. void CCurveData::SetEdgeInfo( bool leftEdge, int curveType, float zero )
  3476. {
  3477. int idx = leftEdge ? 0 : 1;
  3478. m_RampEdgeInfo[ idx ].m_CurveType = curveType;
  3479. m_RampEdgeInfo[ idx ].m_flZeroPos = zero;
  3480. }
  3481. void CCurveData::GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const
  3482. {
  3483. int idx = leftEdge ? 0 : 1;
  3484. curveType = m_RampEdgeInfo[ idx ].m_CurveType;
  3485. zero = m_RampEdgeInfo[ idx ].m_flZeroPos;
  3486. }
  3487. void CCurveData::SetEdgeActive( bool leftEdge, bool state )
  3488. {
  3489. int idx = leftEdge ? 0 : 1;
  3490. m_RampEdgeInfo[ idx ].m_bActive = state;
  3491. }
  3492. bool CCurveData::IsEdgeActive( bool leftEdge ) const
  3493. {
  3494. int idx = leftEdge ? 0 : 1;
  3495. return m_RampEdgeInfo[ idx ].m_bActive;
  3496. }
  3497. int CCurveData::GetEdgeCurveType( bool leftEdge ) const
  3498. {
  3499. if ( !IsEdgeActive( leftEdge ) )
  3500. {
  3501. return CURVE_DEFAULT;
  3502. }
  3503. int idx = leftEdge ? 0 : 1;
  3504. return m_RampEdgeInfo[ idx ].m_CurveType;
  3505. }
  3506. float CCurveData::GetEdgeZeroValue( bool leftEdge ) const
  3507. {
  3508. if ( !IsEdgeActive( leftEdge ) )
  3509. {
  3510. return 0.0f;
  3511. }
  3512. int idx = leftEdge ? 0 : 1;
  3513. return m_RampEdgeInfo[ idx ].m_flZeroPos;
  3514. }
  3515. void CChoreoEvent::SaveToBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool )
  3516. {
  3517. buf.PutChar( GetType() );
  3518. buf.PutShort( pStringPool->FindOrAddString( GetName() ) );
  3519. float st = GetStartTime();
  3520. buf.PutFloat( st );
  3521. float et = GetEndTime();
  3522. buf.PutFloat( et );
  3523. buf.PutShort( pStringPool->FindOrAddString( GetParameters() ) );
  3524. buf.PutShort( pStringPool->FindOrAddString( GetParameters2() ) );
  3525. buf.PutShort( pStringPool->FindOrAddString( GetParameters3() ) );
  3526. m_Ramp.SaveToBuffer( buf, pStringPool );
  3527. int flags = 0;
  3528. flags |= IsResumeCondition() ? 1<<0 : 0;
  3529. flags |= IsLockBodyFacing() ? 1<<1 : 0;
  3530. flags |= IsFixedLength() ? 1<<2 : 0;
  3531. flags |= GetActive() ? 1<<3 : 0;
  3532. flags |= GetForceShortMovement() ? 1<<4 : 0;
  3533. flags |= GetPlayOverScript() ? 1<<5 : 0;
  3534. buf.PutUnsignedChar( flags );
  3535. buf.PutFloat( GetDistanceToTarget() );
  3536. int numRelativeTags = GetNumRelativeTags();
  3537. Assert( numRelativeTags <= 255 );
  3538. buf.PutUnsignedChar( numRelativeTags );
  3539. for ( int t = 0; t < numRelativeTags; t++ )
  3540. {
  3541. CEventRelativeTag *rt = GetRelativeTag( t );
  3542. Assert( rt );
  3543. buf.PutShort( pStringPool->FindOrAddString( rt->GetName() ) );
  3544. Assert( rt->GetPercentage() >= 0.0f && rt->GetPercentage() <= 1.0f );
  3545. unsigned char p = rt->GetPercentage() * 255.0f;
  3546. buf.PutUnsignedChar( p );
  3547. }
  3548. int numTimingTags = GetNumTimingTags();
  3549. Assert( numTimingTags <= 255 );
  3550. buf.PutUnsignedChar( numTimingTags );
  3551. for ( int t = 0; t < numTimingTags; t++ )
  3552. {
  3553. CFlexTimingTag *tt = GetTimingTag( t );
  3554. Assert( tt );
  3555. buf.PutShort( pStringPool->FindOrAddString( tt->GetName() ) );
  3556. // save as u0.8
  3557. Assert( tt->GetPercentage() >= 0.0f && tt->GetPercentage() <= 1.0f );
  3558. unsigned char p = tt->GetPercentage() * 255.0f;
  3559. buf.PutUnsignedChar( p );
  3560. // Don't save locked state, it's only used by the editor tt->GetLocked()
  3561. }
  3562. int tagtype;
  3563. for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
  3564. {
  3565. int num = GetNumAbsoluteTags( (CChoreoEvent::AbsTagType)tagtype );
  3566. Assert( num <= 255 );
  3567. buf.PutUnsignedChar( num );
  3568. for ( int i = 0; i < num ; ++i )
  3569. {
  3570. CEventAbsoluteTag *abstag = GetAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, i );
  3571. Assert( abstag );
  3572. buf.PutShort( pStringPool->FindOrAddString( abstag->GetName() ) );
  3573. // save as u4.12
  3574. Assert( abstag->GetPercentage() >= 0.0f && abstag->GetPercentage() <= 15.0f );
  3575. unsigned short p = abstag->GetPercentage() * 4096.0f;
  3576. buf.PutUnsignedShort( p );
  3577. }
  3578. }
  3579. if ( GetType() == CChoreoEvent::GESTURE )
  3580. {
  3581. float duration;
  3582. if ( GetGestureSequenceDuration( duration ) )
  3583. {
  3584. buf.PutFloat( duration );
  3585. }
  3586. else
  3587. {
  3588. buf.PutFloat( -1.0f );
  3589. }
  3590. }
  3591. buf.PutChar( IsUsingRelativeTag() ? 1 : 0 );
  3592. if ( IsUsingRelativeTag() )
  3593. {
  3594. buf.PutShort( pStringPool->FindOrAddString( GetRelativeTagName() ) );
  3595. buf.PutShort( pStringPool->FindOrAddString( GetRelativeWavName() ) );
  3596. }
  3597. SaveFlexAnimationsToBuffer( buf, pStringPool );
  3598. if ( GetType() == LOOP )
  3599. {
  3600. buf.PutChar( GetLoopCount() );
  3601. }
  3602. if ( GetType() == CChoreoEvent::SPEAK )
  3603. {
  3604. buf.PutChar( GetCloseCaptionType() );
  3605. buf.PutShort( pStringPool->FindOrAddString( GetCloseCaptionToken() ) );
  3606. flags = 0;
  3607. if ( GetCloseCaptionType() != CChoreoEvent::CC_DISABLED &&
  3608. IsUsingCombinedFile() )
  3609. {
  3610. flags |= ( 1<<0 );
  3611. }
  3612. if ( IsCombinedUsingGenderToken() )
  3613. {
  3614. flags |= ( 1<<1 );
  3615. }
  3616. if ( IsSuppressingCaptionAttenuation() )
  3617. {
  3618. flags |= ( 1<<2 );
  3619. }
  3620. buf.PutChar( flags );
  3621. }
  3622. }
  3623. bool CChoreoEvent::RestoreFromBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool )
  3624. {
  3625. MEM_ALLOC_CREDIT();
  3626. SetType( (EVENTTYPE)buf.GetChar() );
  3627. char sz[ 256 ];
  3628. pStringPool->GetString( buf.GetShort(), sz, sizeof( sz ) );
  3629. SetName( sz );
  3630. SetStartTime( buf.GetFloat() );
  3631. SetEndTime( buf.GetFloat() );
  3632. char params[ 2048 ];
  3633. pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
  3634. SetParameters( params );
  3635. pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
  3636. SetParameters2( params );
  3637. pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
  3638. SetParameters3( params );
  3639. if ( !m_Ramp.RestoreFromBuffer( buf, pStringPool ) )
  3640. return false;
  3641. int flags = buf.GetUnsignedChar();
  3642. SetResumeCondition( ( flags & ( 1<<0 ) ) ? true : false );
  3643. SetLockBodyFacing( ( flags & ( 1<<1 ) ) ? true : false );
  3644. SetFixedLength( ( flags & ( 1<<2 ) ) ? true : false );
  3645. SetActive( ( flags & ( 1<<3 ) ) ? true : false );
  3646. SetForceShortMovement( ( flags & ( 1<<4 ) ) ? true : false );
  3647. SetPlayOverScript( ( flags & ( 1<<5 ) ) ? true : false );
  3648. SetDistanceToTarget( buf.GetFloat() );
  3649. int numRelTags = buf.GetUnsignedChar();
  3650. for ( int i = 0; i < numRelTags; ++i )
  3651. {
  3652. char tagName[ 256 ];
  3653. pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
  3654. float percentage = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
  3655. AddRelativeTag( tagName, percentage );
  3656. }
  3657. int numTimingTags = buf.GetUnsignedChar();
  3658. for ( int i = 0; i < numTimingTags; ++i )
  3659. {
  3660. char tagName[ 256 ];
  3661. pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
  3662. float percentage = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
  3663. // Don't parse locked state, only used by editors
  3664. AddTimingTag( tagName, percentage, false );
  3665. }
  3666. int tagtype;
  3667. for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
  3668. {
  3669. int num = buf.GetUnsignedChar();
  3670. for ( int i = 0; i < num; ++i )
  3671. {
  3672. char tagName[ 256 ];
  3673. pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
  3674. float percentage = (float)buf.GetUnsignedShort() * 1.0f/4096.0f;
  3675. // Don't parse locked state, only used by editors
  3676. AddAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, tagName, percentage );
  3677. }
  3678. }
  3679. if ( GetType() == CChoreoEvent::GESTURE )
  3680. {
  3681. float duration = buf.GetFloat();
  3682. if ( duration != -1 )
  3683. {
  3684. SetGestureSequenceDuration( duration );
  3685. }
  3686. }
  3687. if ( buf.GetChar() == 1 )
  3688. {
  3689. char tagname[ 256 ];
  3690. char wavname[ 256 ];
  3691. pStringPool->GetString( buf.GetShort(), tagname, sizeof( tagname ) );
  3692. pStringPool->GetString( buf.GetShort(), wavname, sizeof( wavname ) );
  3693. SetUsingRelativeTag( true, tagname, wavname );
  3694. }
  3695. if ( !RestoreFlexAnimationsFromBuffer( buf, pStringPool ) )
  3696. return false;
  3697. if ( GetType() == LOOP )
  3698. {
  3699. SetLoopCount( buf.GetChar() );
  3700. }
  3701. if ( GetType() == CChoreoEvent::SPEAK )
  3702. {
  3703. SetCloseCaptionType( (CLOSECAPTION)buf.GetChar() );
  3704. char cctoken[ 256 ];
  3705. pStringPool->GetString( buf.GetShort(), cctoken, sizeof( cctoken ) );
  3706. SetCloseCaptionToken( cctoken );
  3707. int flags = buf.GetChar();
  3708. if ( flags & ( 1<<0 ) )
  3709. {
  3710. SetUsingCombinedFile( true );
  3711. }
  3712. if ( flags & ( 1<<1 ) )
  3713. {
  3714. SetCombinedUsingGenderToken( true );
  3715. }
  3716. if ( flags & ( 1<<2 ) )
  3717. {
  3718. SetSuppressingCaptionAttenuation( true );
  3719. }
  3720. }
  3721. return true;
  3722. }
  3723. void CCurveData::SaveToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
  3724. {
  3725. int c = GetCount();
  3726. Assert( c <= 255 );
  3727. buf.PutUnsignedChar( c );
  3728. for ( int i = 0; i < c; i++ )
  3729. {
  3730. CExpressionSample *sample = Get( i );
  3731. buf.PutFloat( sample->time );
  3732. Assert( sample->value >= 0.0f && sample->value <= 1.0f );
  3733. unsigned char v = sample->value * 255.0f;
  3734. buf.PutUnsignedChar( v );
  3735. }
  3736. }
  3737. bool CCurveData::RestoreFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
  3738. {
  3739. int c = buf.GetUnsignedChar();
  3740. for ( int i = 0; i < c; i++ )
  3741. {
  3742. float t, v;
  3743. t = buf.GetFloat();
  3744. v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
  3745. Add( t, v, false );
  3746. }
  3747. return true;
  3748. }
  3749. void CChoreoEvent::SaveFlexAnimationsToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
  3750. {
  3751. int numFlexAnimationTracks = GetNumFlexAnimationTracks();
  3752. Assert( numFlexAnimationTracks <= 255 );
  3753. buf.PutUnsignedChar( numFlexAnimationTracks );
  3754. for ( int i = 0; i < numFlexAnimationTracks; i++ )
  3755. {
  3756. CFlexAnimationTrack *track = GetFlexAnimationTrack( i );
  3757. buf.PutShort( pStringPool->FindOrAddString( track->GetFlexControllerName() ) );
  3758. int flags = 0;
  3759. flags |= track->IsTrackActive() ? 1<<0 : 0;
  3760. flags |= track->IsComboType() ? 1<<1 : 0;
  3761. buf.PutUnsignedChar( flags );
  3762. buf.PutFloat( track->GetMin() );
  3763. buf.PutFloat( track->GetMax() );
  3764. buf.PutShort( track->GetNumSamples( 0 ) );
  3765. for ( int j = 0 ; j < track->GetNumSamples( 0 ) ; j++ )
  3766. {
  3767. CExpressionSample *s = track->GetSample( j, 0 );
  3768. if ( !s )
  3769. continue;
  3770. buf.PutFloat( s->time );
  3771. Assert( s->value >= 0.0f && s->value <= 1.0f );
  3772. unsigned char v = s->value * 255.0f;
  3773. buf.PutUnsignedChar( v );
  3774. buf.PutUnsignedShort( s->GetCurveType() );
  3775. }
  3776. // Write out combo samples
  3777. if ( track->IsComboType() )
  3778. {
  3779. int numSamples = track->GetNumSamples( 1 );
  3780. Assert( numSamples <= 32767 );
  3781. buf.PutUnsignedShort( numSamples );
  3782. for ( int j = 0; j < numSamples; j++ )
  3783. {
  3784. CExpressionSample *s = track->GetSample( j, 1 );
  3785. if ( !s )
  3786. continue;
  3787. buf.PutFloat( s->time );
  3788. Assert( s->value >= 0.0f && s->value <= 1.0f );
  3789. unsigned char v = s->value * 255.0f;
  3790. buf.PutUnsignedChar( v );
  3791. buf.PutUnsignedShort( s->GetCurveType() );
  3792. }
  3793. }
  3794. }
  3795. }
  3796. bool CChoreoEvent::RestoreFlexAnimationsFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
  3797. {
  3798. int numTracks = buf.GetUnsignedChar();
  3799. for ( int i = 0; i < numTracks; i++ )
  3800. {
  3801. char name[ 256 ];
  3802. pStringPool->GetString( buf.GetShort(), name, sizeof( name ) );
  3803. CFlexAnimationTrack *track = AddTrack( name );
  3804. int flags = buf.GetUnsignedChar();
  3805. track->SetTrackActive( ( flags & ( 1<<0 ) ) ? true : false );
  3806. track->SetComboType( ( flags & ( 1<<1 ) ) ? true : false );
  3807. track->SetMin( buf.GetFloat() );
  3808. track->SetMax( buf.GetFloat() );
  3809. int s = buf.GetShort();
  3810. for ( int j = 0; j < s; ++j )
  3811. {
  3812. float t, v;
  3813. t = buf.GetFloat();
  3814. v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
  3815. CExpressionSample *pSample = track->AddSample( t, v, 0 );
  3816. pSample->SetCurveType( buf.GetUnsignedShort() );
  3817. }
  3818. if ( track->IsComboType() )
  3819. {
  3820. int s = buf.GetUnsignedShort();
  3821. for ( int j = 0; j < s; ++j )
  3822. {
  3823. float t, v;
  3824. t = buf.GetFloat();
  3825. v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
  3826. CExpressionSample *pSample = track->AddSample( t, v, 1 );
  3827. pSample->SetCurveType( buf.GetUnsignedShort() );
  3828. }
  3829. }
  3830. }
  3831. return true;
  3832. }
  3833. //-----------------------------------------------------------------------------
  3834. // Purpose: Marks the event as enabled/disabled
  3835. // Input : state -
  3836. //-----------------------------------------------------------------------------
  3837. void CChoreoEvent::SetActive( bool state )
  3838. {
  3839. m_bActive = state;
  3840. }
  3841. bool CChoreoEvent::GetActive() const
  3842. {
  3843. return m_bActive;
  3844. }