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.

918 lines
36 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef DMELOG_H
  7. #define DMELOG_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "datamodel/dmelement.h"
  12. #include "datamodel/dmattribute.h"
  13. #include "datamodel/dmattributevar.h"
  14. #include "datamodel/dmehandle.h"
  15. #include "interpolatortypes.h"
  16. #include "movieobjects/timeutils.h"
  17. #include "movieobjects/dmetimeselectiontimes.h"
  18. class IUniformRandomStream;
  19. template < class T > class CDmeTypedLog;
  20. enum
  21. {
  22. FILTER_SMOOTH = 0,
  23. FILTER_JITTER,
  24. FILTER_SHARPEN,
  25. FILTER_SOFTEN,
  26. NUM_FILTERS
  27. };
  28. enum RecordingMode_t
  29. {
  30. RECORD_PRESET = 0, // Preset/fader slider being dragged
  31. RECORD_ATTRIBUTESLIDER, // Single attribute slider being dragged
  32. };
  33. #define DMELOG_DEFAULT_THRESHHOLD 0.0001f
  34. class DmeLog_TimeSelection_t
  35. {
  36. public:
  37. DmeLog_TimeSelection_t() :
  38. m_flIntensity( 1.0f ),
  39. m_bAttachedMode( true ),
  40. m_bTimeAdvancing( false ),
  41. m_bResampleMode( true ),
  42. m_nResampleInterval( DmeTime_t( .05f ) ),// 50 msec sampling interval by default
  43. m_flThreshold( DMELOG_DEFAULT_THRESHHOLD ),
  44. m_pPresetValue( 0 ),
  45. m_RecordingMode( RECORD_PRESET )
  46. {
  47. m_nTimes[ TS_LEFT_FALLOFF ] = m_nTimes[ TS_LEFT_HOLD ] =
  48. m_nTimes[ TS_RIGHT_HOLD ] = m_nTimes[ TS_RIGHT_FALLOFF ] = DmeTime_t( 0 );
  49. m_nFalloffInterpolatorTypes[ 0 ] = m_nFalloffInterpolatorTypes[ 1 ] = INTERPOLATE_LINEAR_INTERP;
  50. }
  51. inline void ResetTimeAdvancing()
  52. {
  53. // Reset the time advancing flag
  54. m_bTimeAdvancing = false;
  55. }
  56. inline void StartTimeAdvancing()
  57. {
  58. m_bTimeAdvancing = true;
  59. }
  60. inline bool IsTimeAdvancing() const
  61. {
  62. return m_bTimeAdvancing;
  63. }
  64. inline RecordingMode_t GetRecordingMode() const
  65. {
  66. return m_RecordingMode;
  67. }
  68. void SetRecordingMode( RecordingMode_t mode )
  69. {
  70. m_RecordingMode = mode;
  71. }
  72. float GetAmountForTime( DmeTime_t curtime ) const;
  73. float AdjustFactorForInterpolatorType( float factor, int side ) const;
  74. // NOTE: See DmeTimeSelectionTimes_t for return values, 0 means before, 1= left fallof, 2=hold, 3=right falloff, 4=after
  75. int ComputeRegionForTime( DmeTime_t curtime ) const;
  76. DmeTime_t m_nTimes[ TS_TIME_COUNT ];
  77. int m_nFalloffInterpolatorTypes[ 2 ];
  78. DmeTime_t m_nResampleInterval; // Only used if m_bResampleMode is true
  79. float m_flIntensity; // How much to drive values toward m_HeadValue (generally 1.0f)
  80. float m_flThreshold;
  81. CDmAttribute* m_pPresetValue;
  82. bool m_bAttachedMode : 1; // Is the current time "attached" to the head position
  83. // Adds new, evenly spaced samples based on m_nResampleInterval
  84. // Also adds zero intensity samples at the falloff edges
  85. bool m_bResampleMode : 1;
  86. private:
  87. bool m_bTimeAdvancing : 1; // Has time ever been advancing
  88. RecordingMode_t m_RecordingMode;
  89. };
  90. class CDmeChannel;
  91. class CDmeChannelsClip;
  92. class CDmeFilmClip;
  93. class CDmeLog;
  94. class CDmeLogLayer;
  95. struct LayerSelectionData_t
  96. {
  97. LayerSelectionData_t();
  98. void Release();
  99. CDmeHandle< CDmeChannel > m_hChannel;
  100. CDmeHandle< CDmeChannelsClip > m_hOwner;
  101. CDmeHandle< CDmeFilmClip > m_hShot;
  102. CDmeHandle< CDmeLog > m_hLog;
  103. DmAttributeType_t m_DataType;
  104. int m_nDuration;
  105. int m_nHoldTimes[ 2 ];
  106. DmeTime_t m_tStartOffset;
  107. // This is dynamic and needs to be released
  108. struct DataLayer_t
  109. {
  110. DataLayer_t( float frac, CDmeLogLayer *layer );
  111. float m_flStartFraction;
  112. CDmeHandle< CDmeLogLayer, true > m_hData;
  113. };
  114. CUtlVector< DataLayer_t > m_vecData;
  115. };
  116. //-----------------------------------------------------------------------------
  117. // CDmeLogLayer - abstract base class
  118. //-----------------------------------------------------------------------------
  119. abstract_class CDmeLogLayer : public CDmElement
  120. {
  121. friend class CDmeLog;
  122. DEFINE_ELEMENT( CDmeLogLayer, CDmElement );
  123. public:
  124. virtual void CopyLayer( const CDmeLogLayer *src ) = 0;
  125. virtual void CopyPartialLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps ) = 0;
  126. virtual void ExplodeLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps, DmeTime_t tResampleInterval ) = 0;
  127. virtual void InsertKeyFromLayer( DmeTime_t keyTime, const CDmeLogLayer *src, DmeTime_t srcKeyTime ) = 0;
  128. DmeTime_t GetBeginTime() const;
  129. DmeTime_t GetEndTime() const;
  130. int GetKeyCount() const;
  131. // Returns the index of a key closest to this time, within tolerance
  132. // NOTE: Insertion or removal may change this index!
  133. // Returns -1 if the time isn't within tolerance.
  134. int FindKeyWithinTolerance( DmeTime_t time, DmeTime_t nTolerance );
  135. // Returns the type of attribute being logged
  136. virtual DmAttributeType_t GetDataType() const = 0;
  137. // Sets a key, removes all keys after this time
  138. virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT ) = 0;
  139. virtual bool SetDuplicateKeyAtTime( DmeTime_t time ) = 0;
  140. // This inserts a key using the current values to construct the proper value for the time
  141. virtual int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT ) = 0;
  142. // Sets the interpolated value of the log at the specified time into the attribute
  143. virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const = 0;
  144. virtual float GetComponent( DmeTime_t time, int componentIndex ) const = 0;
  145. // Returns the time at which a particular key occurs
  146. DmeTime_t GetKeyTime( int nKeyIndex ) const;
  147. void SetKeyTime( int nKeyIndex, DmeTime_t keyTime );
  148. // Scale + bias key times
  149. void ScaleBiasKeyTimes( double flScale, DmeTime_t nBias );
  150. // Removes a single key by index
  151. virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 ) = 0;
  152. // Removes all keys
  153. virtual void ClearKeys() = 0;
  154. virtual bool IsConstantValued() const = 0;
  155. virtual void RemoveRedundantKeys() = 0;
  156. virtual void RemoveRedundantKeys( float threshold ) = 0;
  157. // resampling and filtering
  158. virtual void Resample( DmeFramerate_t samplerate ) = 0;
  159. virtual void Filter( int nSampleRadius ) = 0;
  160. virtual void Filter2( DmeTime_t sampleRadius ) = 0;
  161. virtual void SetOwnerLog( CDmeLog *owner ) = 0;
  162. CDmeLog *GetOwnerLog();
  163. const CDmeLog *GetOwnerLog() const;
  164. bool IsUsingCurveTypes() const;
  165. int GetDefaultCurveType() const;
  166. // Override curvetype for specific key
  167. void SetKeyCurveType( int nKeyIndex, int curveType );
  168. int GetKeyCurveType( int nKeyIndex ) const;
  169. // Validates that all keys are correctly sorted in time
  170. bool ValidateKeys() const;
  171. // Removes all keys outside the specified time range
  172. void RemoveKeysOutsideRange( DmeTime_t tStart, DmeTime_t tEnd );
  173. protected:
  174. int FindKey( DmeTime_t time ) const;
  175. void OnUsingCurveTypesChanged();
  176. CDmeLog *m_pOwnerLog;
  177. mutable int m_lastKey;
  178. CDmaArray< int > m_times;
  179. CDmaArray< int > m_CurveTypes;
  180. };
  181. template< class T >
  182. CDmeLogLayer *CreateLayer( CDmeTypedLog< T > *ownerLog );
  183. //-----------------------------------------------------------------------------
  184. // CDmeLogLayer - abstract base class
  185. //-----------------------------------------------------------------------------
  186. abstract_class CDmeCurveInfo : public CDmElement
  187. {
  188. DEFINE_ELEMENT( CDmeCurveInfo, CDmElement );
  189. public:
  190. // Global override for all keys unless overriden by specific key
  191. void SetDefaultCurveType( int curveType );
  192. int GetDefaultCurveType() const;
  193. void SetMinValue( float val );
  194. float GetMinValue() const;
  195. void SetMaxValue( float val );
  196. float GetMaxValue() const;
  197. protected:
  198. CDmaVar< int > m_DefaultCurveType;
  199. CDmaVar< float > m_MinValue;
  200. CDmaVar< float > m_MaxValue;
  201. };
  202. template <class T > class CDmeTypedLogLayer;
  203. //-----------------------------------------------------------------------------
  204. // CDmeLog - abstract base class
  205. //-----------------------------------------------------------------------------
  206. abstract_class CDmeLog : public CDmElement
  207. {
  208. DEFINE_ELEMENT( CDmeLog, CDmElement );
  209. public:
  210. int FindLayerForTime( DmeTime_t time ) const;
  211. int FindLayerForTimeSkippingTopmost( DmeTime_t time ) const;
  212. void FindLayersForTime( DmeTime_t time, CUtlVector< int >& list ) const;
  213. virtual void FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params ) = 0; // in attached, timeadvancing mode, we need to blend out of the final sample over the fadeout interval
  214. virtual void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const CDmAttribute *pAttr, uint index = 0 ) = 0;
  215. virtual void FilterUsingTimeSelection( IUniformRandomStream *random, float flScale, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer ) = 0;
  216. virtual void FilterUsingTimeSelection( IUniformRandomStream *random, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff ) = 0;
  217. virtual void StaggerUsingTimeSelection( const DmeLog_TimeSelection_t& params, DmeTime_t tStaggerAmount, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer ) = 0;
  218. virtual void RevealUsingTimeSelection( const DmeLog_TimeSelection_t &params, CDmeLogLayer *savedLayer ) = 0;
  219. virtual void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t &params ) = 0;
  220. virtual void BlendLayersUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, bool bUseBaseLayerSamples, DmeTime_t tStartOffset ) = 0;
  221. virtual void BlendTimesUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, DmeTime_t tStartOffset ) = 0;
  222. virtual void PasteAndRescaleSamples( const CDmeLogLayer *src, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion ) = 0;
  223. virtual void PasteAndRescaleSamples( const CDmeLogLayer *pBaseLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion ) = 0;
  224. virtual void BuildNormalizedLayer( CDmeTypedLogLayer< float > *target ) = 0;
  225. virtual void BuildCorrespondingLayer( const CDmeLogLayer *pReferenceLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer ) = 0;
  226. int GetTopmostLayer() const;
  227. int GetNumLayers() const;
  228. CDmeLogLayer *GetLayer( int index );
  229. const CDmeLogLayer *GetLayer( int index ) const;
  230. DmeTime_t GetBeginTime() const;
  231. DmeTime_t GetEndTime() const;
  232. int GetKeyCount() const;
  233. bool IsEmpty() const;
  234. // Returns the index of a key closest to this time, within tolerance
  235. // NOTE: Insertion or removal may change this index!
  236. // Returns -1 if the time isn't within tolerance.
  237. virtual int FindKeyWithinTolerance( DmeTime_t time, DmeTime_t nTolerance ) = 0;
  238. // Returns the type of attribute being logged
  239. virtual DmAttributeType_t GetDataType() const = 0;
  240. // Sets a key, removes all keys after this time
  241. virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT ) = 0;
  242. virtual bool SetDuplicateKeyAtTime( DmeTime_t time ) = 0;
  243. virtual int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT ) = 0;
  244. // Sets the interpolated value of the log at the specified time into the attribute
  245. virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const = 0;
  246. virtual void GetValueSkippingTopmostLayer( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const = 0;
  247. virtual float GetComponent( DmeTime_t time, int componentIndex ) const = 0;
  248. // Returns the time at which a particular key occurs
  249. virtual DmeTime_t GetKeyTime( int nKeyIndex ) const = 0;
  250. virtual void SetKeyTime( int nKeyIndex, DmeTime_t keyTime ) = 0;
  251. // Override curvetype for specific key
  252. void SetKeyCurveType( int nKeyIndex, int curveType );
  253. int GetKeyCurveType( int nKeyIndex ) const;
  254. // Removes a single key by index
  255. virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 ) = 0;
  256. // Removes all keys within the time range, returns true if keys were removed
  257. bool RemoveKeys( DmeTime_t tStartTime, DmeTime_t tEndTime );
  258. // Removes all keys
  259. virtual void ClearKeys() = 0;
  260. // Scale + bias key times
  261. void ScaleBiasKeyTimes( double flScale, DmeTime_t nBias );
  262. virtual float GetValueThreshold() const = 0;
  263. virtual void SetValueThreshold( float thresh ) = 0;
  264. virtual bool IsConstantValued() const = 0;
  265. virtual void RemoveRedundantKeys() = 0;
  266. virtual void RemoveRedundantKeys( float threshold ) = 0;
  267. // resampling and filtering
  268. virtual void Resample( DmeFramerate_t samplerate ) = 0;
  269. virtual void Filter( int nSampleRadius ) = 0;
  270. virtual void Filter2( DmeTime_t sampleRadius ) = 0;
  271. // Creates a log of a requested type
  272. static CDmeLog *CreateLog( DmAttributeType_t type, DmFileId_t fileid );
  273. virtual CDmeLogLayer *AddNewLayer() = 0;
  274. enum
  275. {
  276. FLATTEN_NODISCONTINUITY_FIXUP = (1<<0), // Don't add "helper" samples to preserve discontinuities. This occurs when the time selection is "detached" from the head position
  277. FLATTEN_SPEW = (1<<1),
  278. };
  279. virtual void FlattenLayers( float threshold, int flags ) = 0;
  280. // Only used by undo system!!!
  281. virtual void AddLayerToTail( CDmeLogLayer *layer ) = 0;
  282. virtual CDmeLogLayer *RemoveLayerFromTail() = 0;
  283. virtual CDmeLogLayer *RemoveLayer( int iLayer ) = 0;
  284. // Resolve
  285. virtual void Resolve();
  286. // curve info helpers
  287. bool IsUsingCurveTypes() const;
  288. const CDmeCurveInfo *GetCurveInfo() const;
  289. CDmeCurveInfo *GetCurveInfo();
  290. virtual CDmeCurveInfo *GetOrCreateCurveInfo() = 0;
  291. virtual void SetCurveInfo( CDmeCurveInfo *pCurveInfo ) = 0;
  292. // accessors for CurveInfo data
  293. int GetDefaultCurveType() const;
  294. // FIXME - this should really be in the CurveInfo
  295. // but the animset editor currently asks for these, without having set a curveinfo...
  296. void SetMinValue( float val );
  297. void SetMaxValue( float val );
  298. float GetMinValue() const;
  299. float GetMaxValue() const;
  300. virtual bool HasDefaultValue() const = 0;
  301. protected:
  302. // int FindKey( DmeTime_t time ) const;
  303. void OnUsingCurveTypesChanged();
  304. virtual void OnAttributeChanged( CDmAttribute *pAttribute );
  305. CDmaElementArray< CDmeLogLayer > m_Layers;
  306. CDmaElement< CDmeCurveInfo > m_CurveInfo;
  307. };
  308. //-----------------------------------------------------------------------------
  309. // CDmeTypedCurveInfo - implementation class for all logs
  310. //-----------------------------------------------------------------------------
  311. template< class T >
  312. class CDmeTypedCurveInfo : public CDmeCurveInfo
  313. {
  314. DEFINE_ELEMENT( CDmeTypedCurveInfo, CDmeCurveInfo );
  315. public:
  316. // For "faceposer" style left/right edges, this controls whether interpolators try to mimic faceposer left/right edge behavior
  317. void SetUseEdgeInfo( bool state );
  318. bool IsUsingEdgeInfo() const;
  319. void SetEdgeInfo( int edge, bool active, const T& val, int curveType );
  320. void GetEdgeInfo( int edge, bool& active, T& val, int& curveType ) const;
  321. void SetDefaultEdgeZeroValue( const T& val );
  322. const T& GetDefaultEdgeZeroValue() const;
  323. void SetRightEdgeTime( DmeTime_t time );
  324. DmeTime_t GetRightEdgeTime() const;
  325. bool IsEdgeActive( int edge ) const;
  326. void GetEdgeValue( int edge, T& value ) const;
  327. int GetEdgeCurveType( int edge ) const;
  328. void GetZeroValue( int side, T& val ) const;
  329. protected:
  330. CDmaVar< bool > m_bUseEdgeInfo;
  331. // Array of 2 for left/right edges...
  332. CDmaVar< bool > m_bEdgeActive[ 2 ];
  333. CDmaVar< T > m_EdgeValue[ 2 ];
  334. CDmaVar< int > m_EdgeCurveType[ 2 ];
  335. CDmaVar< int > m_RightEdgeTime;
  336. CDmaVar< T > m_DefaultEdgeValue;
  337. };
  338. // forward declaration
  339. template< class T > class CDmeTypedLog;
  340. //-----------------------------------------------------------------------------
  341. // CDmeTypedLogLayer - implementation class for all logs
  342. //-----------------------------------------------------------------------------
  343. template< class T >
  344. class CDmeTypedLogLayer : public CDmeLogLayer
  345. {
  346. DEFINE_ELEMENT( CDmeTypedLogLayer, CDmeLogLayer );
  347. public:
  348. virtual void CopyLayer( const CDmeLogLayer *src );
  349. virtual void CopyPartialLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps );
  350. virtual void ExplodeLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps, DmeTime_t tResampleInterval );
  351. virtual void InsertKeyFromLayer( DmeTime_t keyTime, const CDmeLogLayer *src, DmeTime_t srcKeyTime );
  352. // Finds a key within tolerance, or adds one. Unlike SetKey, this will *not* delete keys after the specified time
  353. int FindOrAddKey( DmeTime_t nTime, DmeTime_t nTolerance, const T& value, int curveType = CURVE_DEFAULT );
  354. // Sets a key, removes all keys after this time
  355. void SetKey( DmeTime_t time, const T& value, int curveType = CURVE_DEFAULT );
  356. // This inserts a key using the current values to construct the proper value for the time
  357. virtual int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT );
  358. void SetKeyValue( int nKey, const T& value );
  359. const T& GetValue( DmeTime_t time ) const;
  360. const T& GetKeyValue( int nKeyIndex ) const;
  361. const T& GetValueSkippingKey( int nKeyToSkip ) const;
  362. // This inserts a key. Unlike SetKey, this will *not* delete keys after the specified time
  363. int InsertKey( DmeTime_t nTime, const T& value, int curveType = CURVE_DEFAULT );
  364. // inherited from CDmeLog
  365. virtual void ClearKeys();
  366. virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT );
  367. virtual bool SetDuplicateKeyAtTime( DmeTime_t time );
  368. virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const;
  369. virtual float GetComponent( DmeTime_t time, int componentIndex ) const;
  370. virtual DmAttributeType_t GetDataType() const;
  371. virtual bool IsConstantValued() const;
  372. virtual void RemoveRedundantKeys();
  373. virtual void RemoveRedundantKeys( float threshold );
  374. virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 );
  375. virtual void Resample( DmeFramerate_t samplerate );
  376. virtual void Filter( int nSampleRadius );
  377. virtual void Filter2( DmeTime_t sampleRadius );
  378. void RemoveKeys( DmeTime_t starttime );
  379. // curve info helpers
  380. const CDmeTypedCurveInfo< T > *GetTypedCurveInfo() const;
  381. CDmeTypedCurveInfo< T > *GetTypedCurveInfo();
  382. bool IsUsingEdgeInfo() const;
  383. void GetEdgeInfo( int edge, bool& active, T& val, int& curveType ) const;
  384. const T& GetDefaultEdgeZeroValue() const;
  385. DmeTime_t GetRightEdgeTime() const;
  386. void SetOwnerLog( CDmeLog *owner );
  387. CDmeTypedLog< T > *GetTypedOwnerLog();
  388. const CDmeTypedLog< T > *GetTypedOwnerLog() const;
  389. protected:
  390. int GetEdgeCurveType( int edge ) const;
  391. void GetZeroValue( int side, T& val ) const;
  392. void GetValueUsingCurveInfo( DmeTime_t time, T& out ) const;
  393. void GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, T& out ) const;
  394. void GetBoundedSample( int keyindex, DmeTime_t& time, T& val, int& curveType ) const;
  395. void CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< T > *output );
  396. friend CDmeTypedLog< T >;
  397. protected:
  398. CDmaArray< T > m_values;
  399. };
  400. //-----------------------------------------------------------------------------
  401. // CDmeTypedLog - implementation class for all logs
  402. //-----------------------------------------------------------------------------
  403. template< class T >
  404. class CDmeTypedLog : public CDmeLog
  405. {
  406. DEFINE_ELEMENT( CDmeTypedLog, CDmeLog );
  407. public:
  408. virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem );
  409. CDmeTypedLogLayer< T > *GetLayer( int index );
  410. const CDmeTypedLogLayer< T > *GetLayer( int index ) const;
  411. void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const T& value );
  412. void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const CDmAttribute *pAttr, uint index = 0 );
  413. void FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params ); // in attached, timeadvancing mode, we need to blend out of the final sample over the fadeout interval
  414. void FilterUsingTimeSelection( IUniformRandomStream *random, float flScale, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer );
  415. void FilterUsingTimeSelection( IUniformRandomStream *random, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff );
  416. void StaggerUsingTimeSelection( const DmeLog_TimeSelection_t& params, DmeTime_t tStaggerAmount, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer );
  417. void RevealUsingTimeSelection( const DmeLog_TimeSelection_t &params, CDmeLogLayer *savedLayer );
  418. void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t &params );
  419. void BlendLayersUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, bool bUseBaseLayerSamples, DmeTime_t tStartOffset );
  420. void BlendTimesUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, DmeTime_t tStartOffset );
  421. virtual void PasteAndRescaleSamples( const CDmeLogLayer *src, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion );
  422. virtual void PasteAndRescaleSamples( const CDmeLogLayer *pBaseLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion );
  423. virtual void BuildCorrespondingLayer( const CDmeLogLayer *pReferenceLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer );
  424. virtual void BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
  425. // Finds a key within tolerance, or adds one. Unlike SetKey, this will *not* delete keys after the specified time
  426. int FindOrAddKey( DmeTime_t nTime, DmeTime_t nTolerance, const T& value, int curveType = CURVE_DEFAULT );
  427. // Sets a key, removes all keys after this time
  428. void SetKey( DmeTime_t time, const T& value, int curveType = CURVE_DEFAULT );
  429. int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT );
  430. bool ValuesDiffer( const T& a, const T& b ) const;
  431. const T& GetValue( DmeTime_t time ) const;
  432. const T& GetValueSkippingTopmostLayer( DmeTime_t time ) const;
  433. const T& GetKeyValue( int nKeyIndex ) const;
  434. // This inserts a key. Unlike SetKey, this will *not* delete keys after the specified time
  435. int InsertKey( DmeTime_t nTime, const T& value, int curveType = CURVE_DEFAULT );
  436. // inherited from CDmeLog
  437. virtual void ClearKeys();
  438. virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT );
  439. virtual bool SetDuplicateKeyAtTime( DmeTime_t time );
  440. virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const;
  441. virtual void GetValueSkippingTopmostLayer( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const;
  442. virtual float GetComponent( DmeTime_t time, int componentIndex ) const;
  443. virtual DmAttributeType_t GetDataType() const;
  444. virtual float GetValueThreshold() const { return m_threshold; }
  445. virtual void SetValueThreshold( float thresh );
  446. virtual bool IsConstantValued() const;
  447. virtual void RemoveRedundantKeys();
  448. virtual void RemoveRedundantKeys( float threshold );
  449. virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 );
  450. virtual void Resample( DmeFramerate_t samplerate );
  451. virtual void Filter( int nSampleRadius );
  452. virtual void Filter2( DmeTime_t sampleRadius );
  453. virtual int FindKeyWithinTolerance( DmeTime_t time, DmeTime_t nTolerance );
  454. virtual DmeTime_t GetKeyTime( int nKeyIndex ) const;
  455. virtual void SetKeyTime( int nKeyIndex, DmeTime_t keyTime );
  456. virtual CDmeLogLayer *AddNewLayer();
  457. virtual void FlattenLayers( float threshhold, int flags );
  458. // Only used by undo system!!!
  459. virtual void AddLayerToTail( CDmeLogLayer *layer );
  460. virtual CDmeLogLayer *RemoveLayerFromTail();
  461. virtual CDmeLogLayer *RemoveLayer( int iLayer );
  462. // curve info helpers
  463. const CDmeTypedCurveInfo< T > *GetTypedCurveInfo() const;
  464. CDmeTypedCurveInfo< T > *GetTypedCurveInfo();
  465. virtual CDmeCurveInfo *GetOrCreateCurveInfo();
  466. virtual void SetCurveInfo( CDmeCurveInfo *pCurveInfo );
  467. // For "faceposer" style left/right edges, this controls whether interpolators try to mimic faceposer left/right edge behavior
  468. void SetUseEdgeInfo( bool state );
  469. bool IsUsingEdgeInfo() const;
  470. void SetEdgeInfo( int edge, bool active, const T& val, int curveType );
  471. void GetEdgeInfo( int edge, bool& active, T& val, int& curveType ) const;
  472. void SetDefaultEdgeZeroValue( const T& val );
  473. const T& GetDefaultEdgeZeroValue() const;
  474. void SetRightEdgeTime( DmeTime_t time );
  475. DmeTime_t GetRightEdgeTime() const;
  476. bool IsEdgeActive( int edge ) const;
  477. void GetEdgeValue( int edge, T& value ) const;
  478. int GetEdgeCurveType( int edge ) const;
  479. void GetZeroValue( int side, T& val ) const;
  480. T ClampValue( const T& value );
  481. void SetDefaultValue( const T& value );
  482. const T& GetDefaultValue() const;
  483. bool HasDefaultValue() const;
  484. void ClearDefaultValue();
  485. static void SetDefaultValueThreshold( float thresh );
  486. static float GetDefaultValueThreshold();
  487. static float s_defaultThreshold;
  488. protected:
  489. void RemoveKeys( DmeTime_t starttime );
  490. void _StampKeyAtHeadResample( DmeTime_t tHeadPosition, const DmeLog_TimeSelection_t & params, const T& value, bool bSkipToHead, bool bClearPreviousKeys );
  491. void _StampKeyAtHeadFilteredByTimeSelection( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t & params, const T& value );
  492. void _StampKeyFilteredByTimeSelection( CDmeTypedLogLayer< T > *pWriteLayer, DmeTime_t t, const DmeLog_TimeSelection_t &params, const T& value, bool bForce = false );
  493. protected:
  494. // this really only makes sense for some of our subclasses, basically those which have float data
  495. // anything else's threshhold is almost certainly 0, and that class just ignores m_threshold
  496. float m_threshold;
  497. CDmaVar< bool > m_UseDefaultValue;
  498. CDmaVar< T > m_DefaultValue;
  499. };
  500. //-----------------------------------------------------------------------------
  501. // Template methods
  502. //-----------------------------------------------------------------------------
  503. template< class T >
  504. DmAttributeType_t CDmeTypedLogLayer<T>::GetDataType() const
  505. {
  506. return CDmAttributeInfo< T >::AttributeType();
  507. }
  508. template< class T >
  509. bool CDmeTypedLogLayer<T>::IsConstantValued() const
  510. {
  511. if ( m_values.Count() < 2 )
  512. return true;
  513. if ( m_values.Count() == 2 && !GetTypedOwnerLog()->ValuesDiffer( m_values[ 0 ], m_values[ 1 ] ) )
  514. return true;
  515. // we're throwing away duplicate values during recording, so this is generally correct
  516. // although there are paths to set keys that don't use the duplicate test, so it's not 100%
  517. return false;
  518. }
  519. //-----------------------------------------------------------------------------
  520. // Template methods
  521. //-----------------------------------------------------------------------------
  522. template< class T >
  523. DmAttributeType_t CDmeTypedLog<T>::GetDataType() const
  524. {
  525. return CDmAttributeInfo< T >::AttributeType();
  526. }
  527. template< class T >
  528. void CDmeTypedLog<T>::SetDefaultValueThreshold( float thresh )
  529. {
  530. s_defaultThreshold = thresh;
  531. }
  532. template< class T >
  533. float CDmeTypedLog<T>::GetDefaultValueThreshold()
  534. {
  535. return s_defaultThreshold;
  536. }
  537. template< class T >
  538. void CDmeTypedLog<T>::SetValueThreshold( float thresh )
  539. {
  540. m_threshold = thresh;
  541. }
  542. template< class T >
  543. bool CDmeTypedLog<T>::IsConstantValued() const
  544. {
  545. int c = m_Layers.Count();
  546. for ( int i = 0; i < c; ++i )
  547. {
  548. if ( !GetLayer( i )->IsConstantValued() )
  549. return false;
  550. }
  551. return true;
  552. }
  553. template< class T >
  554. void CDmeTypedLog<T>::RemoveRedundantKeys()
  555. {
  556. int bestLayer = GetTopmostLayer();
  557. if ( bestLayer < 0 )
  558. return;
  559. GetLayer( bestLayer )->RemoveRedundantKeys();
  560. }
  561. template< class T >
  562. inline float Normalize( const T& val )
  563. {
  564. Assert( 0 );
  565. return 0.5f;
  566. }
  567. // AT_INT
  568. // AT_FLOAT
  569. // AT_VECTOR*
  570. template<>
  571. inline float Normalize( const bool& val )
  572. {
  573. return val ? 1.0f : 0.0f;
  574. }
  575. template<>
  576. inline float Normalize( const Color& val )
  577. {
  578. float sum = 0.0f;
  579. for ( int i = 0 ; i < 4; ++i )
  580. {
  581. sum += val[ i ];
  582. }
  583. sum /= 4.0f;
  584. return clamp( sum / 255.0f, 0.0f, 1.0f );
  585. }
  586. template<>
  587. inline float Normalize( const QAngle& val )
  588. {
  589. float sum = 0.0f;
  590. for ( int i = 0 ; i < 3; ++i )
  591. {
  592. float ang = val[ i ];
  593. if ( ang < 0.0f )
  594. {
  595. ang += 360.0f;
  596. }
  597. sum += ang;
  598. }
  599. return clamp( ( sum / 3.0f ) / 360.0f, 0.0f, 1.0f );
  600. }
  601. template<>
  602. inline float Normalize( const Quaternion& val )
  603. {
  604. QAngle angle;
  605. QuaternionAngles( val, angle );
  606. return Normalize( angle );
  607. }
  608. template< class T >
  609. inline void CDmeTypedLog< T >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *pTarget )
  610. {
  611. Assert( pTarget );
  612. Assert( GetDataType() != AT_FLOAT );
  613. CDmeTypedLogLayer< T > *pBaseLayer = static_cast< CDmeTypedLogLayer< T > * >( GetLayer( 0 ) );
  614. if ( !pBaseLayer )
  615. return;
  616. int kc = pBaseLayer->GetKeyCount();
  617. for ( int i = 0; i < kc; ++i )
  618. {
  619. DmeTime_t tKeyTime = pBaseLayer->GetKeyTime( i );
  620. T keyValue = pBaseLayer->GetKeyValue( i );
  621. float flNormalized = Normalize( keyValue );
  622. pTarget->InsertKey( tKeyTime, flNormalized );
  623. }
  624. if ( HasDefaultValue() )
  625. {
  626. pTarget->GetTypedOwnerLog()->SetDefaultValue( Normalize( GetDefaultValue() ) );
  627. }
  628. }
  629. // Generic implementations all stubbed
  630. // Forward declare specific typed instantiations for float types
  631. template< class T > T CDmeTypedLog< T >::ClampValue( const T& value ) { return value; }
  632. template<> float CDmeTypedLog< float >::ClampValue( const float& value );
  633. template< class T > void CDmeTypedCurveInfo< T >::GetZeroValue( int side, T& val ) const{ Assert( 0 ); }
  634. template< class T > bool CDmeTypedCurveInfo< T >::IsEdgeActive( int edge ) const{ Assert( 0 ); return false; }
  635. template< class T > void CDmeTypedCurveInfo< T >::GetEdgeValue( int edge, T &value ) const{ Assert( 0 ); }
  636. template<> void CDmeTypedCurveInfo< float >::GetZeroValue( int side, float& val ) const;
  637. template<> bool CDmeTypedCurveInfo< float >::IsEdgeActive( int edge ) const;
  638. template<> void CDmeTypedCurveInfo< float >::GetEdgeValue( int edge, float &value ) const;
  639. template<> void CDmeTypedCurveInfo< Vector >::GetZeroValue( int side, Vector& val ) const;
  640. template<> void CDmeTypedCurveInfo< Quaternion >::GetZeroValue( int side, Quaternion& val ) const;
  641. template< class T > void CDmeTypedLogLayer< T >::GetValueUsingCurveInfo( DmeTime_t time, T& out ) const { Assert( 0 ); }
  642. template< class T > void CDmeTypedLogLayer< T >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, T& out ) const { Assert( 0 ); }
  643. template<> void CDmeTypedLogLayer< float >::GetValueUsingCurveInfo( DmeTime_t time, float& out ) const;
  644. template<> void CDmeTypedLogLayer< float >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, float& out ) const;
  645. template<> void CDmeTypedLogLayer< Vector >::GetValueUsingCurveInfo( DmeTime_t time, Vector& out ) const;
  646. template<> void CDmeTypedLogLayer< Vector >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, Vector& out ) const;
  647. template<> void CDmeTypedLogLayer< Quaternion >::GetValueUsingCurveInfo( DmeTime_t time, Quaternion& out ) const;
  648. template<> void CDmeTypedLogLayer< Quaternion >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, Quaternion& out ) const;
  649. template<class T> void CDmeTypedLogLayer< T >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< T > *output );
  650. template<> void CDmeTypedLogLayer< bool >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< bool > *output );
  651. template<> void CDmeTypedLogLayer< int >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< int > *output );
  652. template<> void CDmeTypedLogLayer< Color >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< Color > *output );
  653. template<> void CDmeTypedLogLayer< Quaternion >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< Quaternion > *output );
  654. template<> void CDmeTypedLogLayer< VMatrix >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< VMatrix > *output );
  655. template<> void CDmeTypedLog< Vector >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
  656. template<> void CDmeTypedLog< Vector2D >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
  657. template<> void CDmeTypedLog< Vector4D >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
  658. template<> void CDmeTypedLog< float >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
  659. template<> void CDmeTypedLog< int >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
  660. //template<> void CDmeTypedLog< float >::FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params );
  661. //template<> void CDmeTypedLog< bool >::_StampKeyAtHeadResample( const DmeLog_TimeSelection_t& params, const bool& value ) { Assert( 0 ); }
  662. //-----------------------------------------------------------------------------
  663. // typedefs for convenience (and so the user-supplied names match the programmer names)
  664. //-----------------------------------------------------------------------------
  665. typedef CDmeTypedLog<int> CDmeIntLog;
  666. typedef CDmeTypedLog<float> CDmeFloatLog;
  667. typedef CDmeTypedLog<bool> CDmeBoolLog;
  668. typedef CDmeTypedLog<Color> CDmeColorLog;
  669. typedef CDmeTypedLog<Vector2D> CDmeVector2Log;
  670. typedef CDmeTypedLog<Vector> CDmeVector3Log;
  671. typedef CDmeTypedLog<Vector4D> CDmeVector4Log;
  672. typedef CDmeTypedLog<QAngle> CDmeQAngleLog;
  673. typedef CDmeTypedLog<Quaternion> CDmeQuaternionLog;
  674. typedef CDmeTypedLog<VMatrix> CDmeVMatrixLog;
  675. typedef CDmeTypedLog<CUtlString> CDmeStringLog;
  676. //-----------------------------------------------------------------------------
  677. // typedefs for convenience (and so the user-supplied names match the programmer names)
  678. //-----------------------------------------------------------------------------
  679. typedef CDmeTypedLogLayer<int> CDmeIntLogLayer;
  680. typedef CDmeTypedLogLayer<float> CDmeFloatLogLayer;
  681. typedef CDmeTypedLogLayer<bool> CDmeBoolLogLayer;
  682. typedef CDmeTypedLogLayer<Color> CDmeColorLogLayer;
  683. typedef CDmeTypedLogLayer<Vector2D> CDmeVector2LogLayer;
  684. typedef CDmeTypedLogLayer<Vector> CDmeVector3LogLayer;
  685. typedef CDmeTypedLogLayer<Vector4D> CDmeVector4LogLayer;
  686. typedef CDmeTypedLogLayer<QAngle> CDmeQAngleLogLayer;
  687. typedef CDmeTypedLogLayer<Quaternion> CDmeQuaternionLogLayer;
  688. typedef CDmeTypedLogLayer<VMatrix> CDmeVMatrixLogLayer;
  689. typedef CDmeTypedLogLayer<CUtlString> CDmeStringLogLayer;
  690. //-----------------------------------------------------------------------------
  691. // typedefs for convenience (and so the user-supplied names match the programmer names)
  692. //-----------------------------------------------------------------------------
  693. typedef CDmeTypedCurveInfo<int> CDmeIntCurveInfo;
  694. typedef CDmeTypedCurveInfo<float> CDmeFloatCurveInfo;
  695. typedef CDmeTypedCurveInfo<bool> CDmeBoolCurveInfo;
  696. typedef CDmeTypedCurveInfo<Color> CDmeColorCurveInfo;
  697. typedef CDmeTypedCurveInfo<Vector2D> CDmeVector2CurveInfo;
  698. typedef CDmeTypedCurveInfo<Vector> CDmeVector3CurveInfo;
  699. typedef CDmeTypedCurveInfo<Vector4D> CDmeVector4CurveInfo;
  700. typedef CDmeTypedCurveInfo<QAngle> CDmeQAngleCurveInfo;
  701. typedef CDmeTypedCurveInfo<Quaternion> CDmeQuaternionCurveInfo;
  702. typedef CDmeTypedCurveInfo<VMatrix> CDmeVMatrixCurveInfo;
  703. typedef CDmeTypedCurveInfo<CUtlString> CDmeStringCurveInfo;
  704. // the following types are not supported
  705. // AT_ELEMENT,
  706. // AT_VOID,
  707. // AT_OBJECTID,
  708. // <all array types>
  709. //-----------------------------------------------------------------------------
  710. // Helpers for particular types of log layers
  711. //-----------------------------------------------------------------------------
  712. void GenerateRotationLog( CDmeQuaternionLogLayer *pLayer, const Vector &vecAxis, DmeTime_t pTime[4], float pRevolutionsPerSec[4] );
  713. // rotates a position log
  714. void RotatePositionLog( CDmeVector3LogLayer *pPositionLog, const matrix3x4_t& matrix );
  715. // rotates an orientation log
  716. void RotateOrientationLog( CDmeQuaternionLogLayer *pOrientationLog, const matrix3x4_t& matrix, bool bPreMultiply );
  717. #endif // DMELOG_H