Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4514 lines
114 KiB

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