Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

601 lines
20 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // The channel class - connects elements together, and allows for logging of data
  4. //
  5. //=============================================================================
  6. #ifndef DMECHANNEL_H
  7. #define DMECHANNEL_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "movieobjects/animsetattributevalue.h"
  12. #include "movieobjects/dmeoperator.h"
  13. #include "movieobjects/dmelog.h"
  14. #include "movieobjects/dmedag.h"
  15. #include "movieobjects/dmeclip.h"
  16. #include "movieobjects/proceduralpresets.h"
  17. #include "datamodel/idatamodel.h"
  18. #include "datamodel/dmehandle.h"
  19. #include "tier1/utlbuffer.h"
  20. //-----------------------------------------------------------------------------
  21. // Forward declarations
  22. //-----------------------------------------------------------------------------
  23. class CDmeClip;
  24. class CDmeChannel;
  25. class CDmeTimeSelection;
  26. class CUndoAddRecordingLayer;
  27. class CUndoSetTimeSelection;
  28. void RemapFloatLogValues( CDmeChannel *pChannel, float flBias, float flScale );
  29. CDmeChannel *FindChannelTargetingAttribute( CDmAttribute *pTargetAttr );
  30. //-----------------------------------------------------------------------------
  31. // different channel modes of operation
  32. //-----------------------------------------------------------------------------
  33. enum ChannelMode_t
  34. {
  35. CM_OFF,
  36. CM_PASS,
  37. CM_RECORD,
  38. CM_PLAY,
  39. };
  40. enum PlayMode_t
  41. {
  42. PM_HOLD,
  43. PM_LOOP,
  44. };
  45. enum RecordOperationFlags_t
  46. {
  47. RECORD_OPERATION_FLAG_PRESET = ( 1 << 0 ),
  48. RECORD_OPERATION_FLAG_REVERSE = ( 1 << 1 ),
  49. RECORD_OPERATION_FLAG_REVEAL = ( 1 << 2 ),
  50. RECORD_OPERATION_FLAG_REBASE_TIME = ( 1 << 3 )
  51. };
  52. //-----------------------------------------------------------------------------
  53. // The layer channel info structure contains information about a channel which
  54. // is currently being modified within a recording layer.
  55. //-----------------------------------------------------------------------------
  56. struct LayerChannelInfo_t
  57. {
  58. LayerChannelInfo_t()
  59. : m_BaseLayer( 0 )
  60. , m_ModLayerIndex( -1 )
  61. , m_HeadPosition( 0 )
  62. , m_TransformWriteMode( TRANSFORM_WRITE_MODE_OVERWRITE )
  63. , m_bManipulateInFalloff( false )
  64. , m_ComponentFlags( LOG_COMPONENTS_ALL )
  65. , m_pPresetValue( 0 )
  66. , m_pPresetTimes( 0 )
  67. , m_pRoot( 0 )
  68. , m_pShot( 0 )
  69. {
  70. SetIdentityMatrix( m_Transform );
  71. }
  72. CDmeHandle< CDmeChannel > m_Channel;
  73. DmeClipStack_t m_ClipStack;
  74. CUtlBuffer m_ToAttrData; // Data of the channel's to attribute before the recording operation
  75. CUtlBuffer m_FromAttrData; // Data of the channel's from attribute after the recording operation
  76. int m_BaseLayer; // Index of the log layer which represents the modification layer
  77. int m_ModLayerIndex; // Index of the channel within the modification layer
  78. DmeTime_t m_HeadPosition; // Time position of the head when the recording operation took place
  79. TransformWriteMode_t m_TransformWriteMode; // Specification of how existing values in the channel are to be modified
  80. bool m_bManipulateInFalloff; // Should manipulation be applied in falloff (true), or should interpolation be used (false)
  81. matrix3x4_t m_Transform; // Transform matrix which was applied to the log positions of the channel
  82. Quaternion m_DeltaRotationLocal; // Delta rotation value to be used with rotation operations ( local space )
  83. Quaternion m_DeltaRotationParent; // Delta rotation value to be used with rotation operations ( parent space )
  84. Vector m_PivotPosition; // Pivot position value to be used with rotation operations
  85. LogComponents_t m_ComponentFlags; // Flags specifying which individual components of the channel can be modified
  86. const CDmAttribute *m_pPresetValue; // Pointer to the attribute storing the preset value for the operation
  87. const CDmAttribute *m_pPresetTimes; // Pointer to the attribute storing animated preset times for the operation
  88. CDmeClip *m_pRoot; // Pointer to the root clip (sequence) in which the operation occurs
  89. CDmeClip *m_pShot; // Pointer to the shot clip in which the operation occurs
  90. CDmeHandle< CDmeLogLayer, HT_STRONG > m_hRawDataLayer; // Handle to the log layer containing the raw recorded data
  91. };
  92. typedef void ( *FnRecordChannelCallback )( CDmeChannel *pChannel );
  93. //-----------------------------------------------------------------------------
  94. // The recording layer structure contains a set of channels and the information
  95. // about a recording operation which was performed on the channels.
  96. //-----------------------------------------------------------------------------
  97. class CRecordingLayer
  98. {
  99. public:
  100. CRecordingLayer();
  101. ~CRecordingLayer();
  102. AttributeDict_t *m_pPresetValuesDict;
  103. DmeTime_t m_tHeadShotTime;
  104. int m_ProceduralType;
  105. int m_OperationFlags;
  106. int m_RandomSeed;
  107. float m_flThreshold;
  108. float m_flIntensity;
  109. RecordingMode_t m_RecordingMode;
  110. TimeSelection_t m_BaseTimes;
  111. TimeSelection_t m_OriginalTimes;
  112. CUtlVector< LayerChannelInfo_t > m_LayerChannels;
  113. CUtlVector< KeyValues * > m_ClipboardData;
  114. CUndoAddRecordingLayer *m_pUndoOperation;
  115. FnRecordChannelCallback m_pfnAddChannelCallback;
  116. FnRecordChannelCallback m_pfnFinishChannelCallback;
  117. };
  118. //-----------------------------------------------------------------------------
  119. // Simple helper structure used to specify a channel and the components of the
  120. // channel that should be modified.
  121. //-----------------------------------------------------------------------------
  122. class ModifyChannel
  123. {
  124. public:
  125. explicit ModifyChannel( CDmeChannel *pChannel = NULL, LogComponents_t nComponentFlags = LOG_COMPONENTS_ALL )
  126. : m_pChannel( pChannel ), m_nComponentFlags( nComponentFlags ) { }
  127. static bool IsChannelInList( CUtlVector< ModifyChannel > const &modifyList, CDmeChannel *pChannel );
  128. CDmeChannel *m_pChannel;
  129. LogComponents_t m_nComponentFlags;
  130. };
  131. //-----------------------------------------------------------------------------
  132. // The channel modification layer manages a group of log layer modifications
  133. // which can be applied to a varying time range.
  134. //-----------------------------------------------------------------------------
  135. class CDmeChannelModificationLayer
  136. {
  137. public:
  138. // Default constructor
  139. CDmeChannelModificationLayer();
  140. // Destructor
  141. ~CDmeChannelModificationLayer();
  142. // Add a channel to the modification layer if it is not already present,
  143. // adding the channel to the modification layer causes a new log layer to
  144. // be added to the channel to which modifications will be made.
  145. int AddChannel( CDmeChannel *pChannel, bool enableUndo );
  146. // Add a recording layer to the modification layer.
  147. CRecordingLayer *AddRecordingLayer();
  148. // Remove the last recording layer from the modification layer.
  149. void RemoveLastRecordingLayer();
  150. // Complete the channel modification layer by flattening all the log layers of
  151. // the active channels and clearing out the contents of the modification layer.
  152. void Finish( bool bFlattenLayers, bool bSaveChanges, bool bRunChannelCallbacks );
  153. // Return the modification layer of each channel to is base state.
  154. void WipeChannelModifications();
  155. // Get the number of recording layers in the modification layer
  156. int NumRecordingLayers() const;
  157. // Get a reference to the specified recording layer
  158. CRecordingLayer &GetRecordingLayer( int index );
  159. // Is the modification layer visible to the user
  160. bool IsVisible() const;
  161. // Apply the specified transform write mode all of the active channels in each of the recording layers
  162. void UpdateTransformWriteMode( TransformWriteMode_t mode );
  163. private:
  164. struct ChannelRef_t
  165. {
  166. int m_RefCount;
  167. CDmeHandle< CDmeChannel > m_Channel;
  168. };
  169. bool m_bVisible;
  170. CUtlVector< CRecordingLayer > m_RecordingLayerStack;
  171. CUtlVector< ChannelRef_t > m_ActiveChannels;
  172. };
  173. //-----------------------------------------------------------------------------
  174. // A class managing channel recording
  175. //-----------------------------------------------------------------------------
  176. class CDmeChannelRecordingMgr
  177. {
  178. public:
  179. // constructor
  180. CDmeChannelRecordingMgr();
  181. // Start and complete a modification layer. All recording layers must be placed within a modification
  182. // layer, so a modification layer must be active before starting a recording layer.
  183. void StartModificationLayer( const DmeLog_TimeSelection_t *pTimeSelection = NULL, bool createLayer = true );
  184. void FinishModificationLayer( bool bSaveChanges = true, bool bFlattenLayers = true );
  185. // Enable or disable use of the modification layer.
  186. void EnableModificationLayer( bool enable );
  187. // Activates, deactivates layer recording.
  188. void StartLayerRecording( const char * const pUndoRedoDesc, AttributeDict_t *pPresetValuesDict = NULL, DmeTime_t tHeadShotTime = DMETIME_INVALID, int proceduralType = PROCEDURAL_PRESET_NOT, int recordFlags = 0, FnRecordChannelCallback pfnAddChannel = NULL, FnRecordChannelCallback pfnFinishChannel = NULL );
  189. void FinishLayerRecording( float flThreshold, bool bFlattenLayers = true, bool bAllowFinishModification = true );
  190. void CancelLayerRecording();
  191. // Adds a channel to the recording layer
  192. int AddChannelToRecordingLayer( CDmeChannel *pChannel, LogComponents_t componentWriteFlags = LOG_COMPONENTS_ALL, CDmeClip *pRoot = NULL, CDmeClip *pShot = NULL );
  193. // Explicitly set the clipboard data for the active recording layer
  194. void CopyClipboardDataForRecordingLayer( const CUtlVector< KeyValues * > &keyValuesList );
  195. // Used to iterate over all channels currently being recorded
  196. // NOTE: Use CDmeChannel::AddToRecordingLayer to add a channel to the recording layer
  197. int GetLayerRecordingChannelCount();
  198. CDmeChannel* GetLayerRecordingChannel( int nIndex );
  199. // Computes time selection info in log time for a particular recorded channel
  200. // NOTE: Only valid if IsUsingTimeSelection() returns true
  201. void GetLocalTimeSelection( DmeLog_TimeSelection_t& selection, int nIndex );
  202. // Get the index of the modification base layer for the specified channel within the current recording layer.
  203. int GetModificationBaseLayer( int nIndex );
  204. // Set the time selection for the modification layer and re-apply all recording layers that are on the current modification
  205. // layer with the new time selection. Must be done with active modification layer, but without an active recording layer.
  206. void SetTimeSelection( const DmeLog_TimeSelection_t &timeSelection, bool bUpdateBaseTime );
  207. // Start or continue processing of the recording layers within the modification layer.
  208. CRecordingLayer *ProcessModificationLayer( int &recordingLayer );
  209. // Complete the modification layer processing for the specified recording layer.
  210. void CompleteModificationProcessing( );
  211. // Save the to or from attribute data of the specified channel within the current recording layer.
  212. void StoreChannelAttributeData( int nChannelIndex, bool fromAttr );
  213. // Get the current time selection
  214. void GetTimeSelection( CDmeTimeSelection &timeSelection ) const;
  215. const DmeLog_TimeSelection_t &GetTimeSelection() const;
  216. // Methods which control various aspects of recording
  217. void UpdateTimeAdvancing( bool bPaused, DmeTime_t tCurTime );
  218. void UpdateRecordingChannelHeadPositions( DmeTime_t tCurTime );
  219. void UpdateRecordingTimeSelectionTimes( const DmeLog_TimeSelection_t& timeSelection );
  220. void SetIntensityOnAllLayers( float flIntensity );
  221. void SetRecordingMode( RecordingMode_t mode );
  222. void SetPresetValue( CDmeChannel* pChannel, const CDmAttribute *pPresetValue, const CDmAttribute *pPresetTimes );
  223. void SetInRedo( bool bInRedo );
  224. void SetProceduralTarget( int nProceduralMode, const CDmAttribute *pTarget );
  225. void SetProceduralTarget( int nProceduralMode, const CUtlVector< KeyValues * >& list, int randomSeed );
  226. int GetProceduralType() const;
  227. const CDmAttribute *GetProceduralTarget() const;
  228. const CUtlVector< KeyValues * > &GetPasteTarget() const;
  229. void GetPasteClipboardData( CUtlVector< KeyValues * > &list ) const;
  230. void SetModificationLayerDirty();
  231. CDmeChannelModificationLayer *GetModificationLayer();
  232. void SetTransformWriteMode( TransformWriteMode_t mode );
  233. TransformWriteMode_t GetTransformWriteMode() const;
  234. void UpdateActiveLayerManipulateInFalloff( bool bManipulateInFalloff );
  235. static void RunFinishCallbacksOnRecordingLayer( CRecordingLayer *pRecordingLayer );
  236. // Methods to query aspects of recording
  237. bool IsTimeAdvancing() const;
  238. bool IsUsingDetachedTimeSelection() const;
  239. bool IsUsingTimeSelection() const;
  240. bool IsRecordingLayerActive() const;
  241. bool IsModificationLayerActive() const;
  242. bool IsModificationLayerVisible() const;
  243. bool IsProcessingModifications() const;
  244. bool IsModificationLayerEnabled() const;
  245. bool IsInRedo() const;
  246. private:
  247. // Methods available for CDmeChannel
  248. bool ShouldRecordUsingTimeSelection() const;
  249. // Internal methods
  250. void FlattenLayers( CRecordingLayer *pRecordingLayer );
  251. void RemoveAllChannelsFromRecordingLayer( CRecordingLayer *pRecordingLayer, bool destroyLogLayers );
  252. // Apply the effects of the recording layer to its channels with the active time selection.
  253. bool ApplyRecordingLayer( CRecordingLayer &recordingLayer );
  254. // Update the time selection state, this is used by undo
  255. void UpdateTimeSelection( const TimeSelection_t &timeSelection, const CUtlVector< TimeSelection_t > &baseTimeSelection, int leftFalloff, int rightFalloff, bool bLeftInfinite, bool bRightInfinite );
  256. bool m_bSavedUndoState : 1;
  257. bool m_bUseTimeSelection : 1;
  258. bool m_bModificationLayerDirty : 1;
  259. bool m_bModificationProcessing : 1;
  260. bool m_bWantsToFinish : 1;
  261. bool m_bFinishFlattenLayers : 1;
  262. bool m_bModificationLayerEnabled : 1;
  263. bool m_bInRedo : 1;
  264. CRecordingLayer *m_pActiveRecordingLayer;
  265. CDmeChannelModificationLayer *m_pModificationLayer;
  266. DmeLog_TimeSelection_t m_TimeSelection;
  267. int m_nProceduralType;
  268. const CDmAttribute *m_pRevealTarget;
  269. CUtlVector< KeyValues * > m_PasteTarget;
  270. int m_RandomSeed;
  271. TransformWriteMode_t m_TransformWriteMode;
  272. friend CDmeChannel;
  273. friend CUndoAddRecordingLayer;
  274. friend CUndoSetTimeSelection;
  275. };
  276. // Singleton
  277. extern CDmeChannelRecordingMgr *g_pChannelRecordingMgr;
  278. struct TimeState_t
  279. {
  280. TimeState_t() : m_timeOutsideTimeframe( DMETIME_INVALID ), m_tCurrentTime( DMETIME_INVALID ), m_tPreviousTime( DMETIME_INVALID )
  281. {
  282. }
  283. DmeTime_t m_timeOutsideTimeframe;
  284. DmeTime_t m_tCurrentTime;
  285. DmeTime_t m_tPreviousTime;
  286. };
  287. //-----------------------------------------------------------------------------
  288. // A class representing a channel
  289. //-----------------------------------------------------------------------------
  290. class CDmeChannel : public CDmeOperator
  291. {
  292. DEFINE_ELEMENT( CDmeChannel, CDmeOperator );
  293. public:
  294. virtual bool IsDirty(); // ie needs to operate
  295. virtual void Operate();
  296. virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs );
  297. virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs );
  298. void SetInput ( CDmElement* pElement, const char* pAttribute, int index = 0 );
  299. void SetOutput( CDmElement* pElement, const char* pAttribute, int index = 0 );
  300. void SetInput( CDmAttribute *pAttribute, int index = 0 );
  301. void SetOutput( CDmAttribute *pAttribute, int index = 0 );
  302. CDmElement *GetFromElement() const;
  303. CDmElement *GetToElement() const;
  304. CDmAttribute *GetFromAttribute();
  305. CDmAttribute *GetToAttribute();
  306. int GetFromArrayIndex() const;
  307. int GetToArrayIndex() const;
  308. int GetRecordLayerIndex() const;
  309. void SetRecordLayerIndex( int layerIndex );
  310. ChannelMode_t GetMode();
  311. void SetMode( ChannelMode_t mode );
  312. void ClearLog();
  313. CDmeLog *GetLog();
  314. void SetLog( CDmeLog *pLog );
  315. CDmeLog *CreateLog( DmAttributeType_t type );
  316. template < class T > CDmeTypedLog<T> *CreateLog();
  317. void ClearTimeMetric();
  318. void SetCurrentTime( DmeTime_t time, DmeTime_t start, DmeTime_t end );
  319. void SetCurrentTime( DmeTime_t time ); // Simple version. Only works if multiple active channels clips do not reference the same channels
  320. DmeTime_t GetCurrentTime() const;
  321. const TimeState_t &GetTimeState() const;
  322. void SetTimeState( TimeState_t &TimeState );
  323. void SetChannelToPlayToSelf( const char *outputAttributeName, float defaultValue, bool force = false );
  324. template< class T >
  325. void SetValueOnInput( const T &value );
  326. // need this until we have the EditApply message queue
  327. void OnAttributeChanged( CDmAttribute *pAttribute );
  328. template< class T >
  329. bool GetInputValue( T &value );
  330. template< class T >
  331. bool GetOutputValue( T &value );
  332. template< class T >
  333. bool GetCurrentPlaybackValue( T& value );
  334. template< class T >
  335. bool GetPlaybackValueAtTime( DmeTime_t time, T& value );
  336. void Play( bool useEmptyLog = false );
  337. void Record();
  338. void SetNextKeyCurveType( int nCurveType );
  339. // Builds a clip stack for the channel
  340. CDmeClip* FindOwnerClipForChannel( CDmeClip *pRoot );
  341. bool BuildClipStack( DmeClipStack_t *pClipStack, CDmeClip *pRoot, CDmeClip *pShot ) const;
  342. void ScaleSampleTimes( float scale );
  343. void ClearAndAddSampleAtTime( DmeTime_t time );
  344. protected:
  345. // Used to cache off handles to attributes
  346. CDmAttribute* SetupFromAttribute();
  347. CDmAttribute* SetupToAttribute();
  348. template< class T >
  349. bool GetValue( T &value, const CDmAttribute *pAttr, int nIndex );
  350. void Pass();
  351. CDmaElement< CDmElement > m_fromElement;
  352. CDmaString m_fromAttribute;
  353. CDmaVar< int > m_fromIndex;
  354. CDmaElement< CDmElement > m_toElement;
  355. CDmaString m_toAttribute;
  356. CDmaVar< int > m_toIndex;
  357. CDmaVar< int > m_mode;
  358. CDmaElement< CDmeLog > m_log;
  359. DmAttributeHandle_t m_FromAttributeHandle;
  360. DmAttributeHandle_t m_ToAttributeHandle;
  361. TimeState_t m_TimeState;
  362. int m_nRecordLayerIndex;
  363. int m_nNextCurveType;
  364. };
  365. //-----------------------------------------------------------------------------
  366. // Inline methods
  367. //-----------------------------------------------------------------------------
  368. template < class T >
  369. inline CDmeTypedLog<T> *CDmeChannel::CreateLog()
  370. {
  371. return CastElement< CDmeTypedLog<T> >( CreateLog( CDmAttributeInfo<T>::AttributeType() ) );
  372. }
  373. inline CDmAttribute *CDmeChannel::GetFromAttribute()
  374. {
  375. CDmAttribute *pAttribute = g_pDataModel->GetAttribute( m_FromAttributeHandle );
  376. if ( !pAttribute )
  377. {
  378. pAttribute = SetupFromAttribute();
  379. }
  380. return pAttribute;
  381. }
  382. inline CDmAttribute *CDmeChannel::GetToAttribute()
  383. {
  384. CDmAttribute *pAttribute = g_pDataModel->GetAttribute( m_ToAttributeHandle );
  385. if ( !pAttribute )
  386. {
  387. pAttribute = SetupToAttribute();
  388. }
  389. return pAttribute;
  390. }
  391. template< class T >
  392. inline bool CDmeChannel::GetPlaybackValueAtTime( DmeTime_t time, T& value )
  393. {
  394. CDmeTypedLog< T > *pLog = CastElement< CDmeTypedLog< T > >( GetLog() );
  395. if ( !pLog || pLog->IsEmpty() )
  396. return false;
  397. DmeTime_t t0 = pLog->GetBeginTime();
  398. DmeTime_t tn = pLog->GetEndTime();
  399. PlayMode_t pmode = PM_HOLD;
  400. switch ( pmode )
  401. {
  402. case PM_HOLD:
  403. time = clamp( time, t0, tn );
  404. break;
  405. case PM_LOOP:
  406. if ( tn == t0 )
  407. {
  408. time = t0;
  409. }
  410. else
  411. {
  412. time -= t0;
  413. time = time % ( tn - t0 );
  414. time += t0;
  415. }
  416. break;
  417. }
  418. value = pLog->GetValue( time );
  419. return true;
  420. }
  421. template< class T >
  422. inline bool CDmeChannel::GetValue( T &value, const CDmAttribute *pAttr, int nIndex )
  423. {
  424. if ( pAttr )
  425. {
  426. if ( IsArrayType( pAttr->GetType() ) )
  427. {
  428. CDmrArrayConst< T > array( pAttr );
  429. if ( nIndex >= 0 && nIndex < array.Count() )
  430. {
  431. value = array[ nIndex ];
  432. return true;
  433. }
  434. }
  435. else
  436. {
  437. value = pAttr->GetValue< T >();
  438. return true;
  439. }
  440. }
  441. CDmAttributeInfo< T >::SetDefaultValue( value );
  442. return false;
  443. }
  444. template< class T >
  445. inline bool CDmeChannel::GetInputValue( T &value )
  446. {
  447. return GetValue< T >( value, GetFromAttribute(), m_fromIndex );
  448. }
  449. template< class T >
  450. inline bool CDmeChannel::GetOutputValue( T &value )
  451. {
  452. return GetValue< T >( value, GetToAttribute(), m_toIndex );
  453. }
  454. template< class T >
  455. inline bool CDmeChannel::GetCurrentPlaybackValue( T& value )
  456. {
  457. return GetPlaybackValueAtTime( GetCurrentTime(), value );
  458. }
  459. template< class T >
  460. void CDmeChannel::SetValueOnInput( const T &value )
  461. {
  462. CDmAttribute *pFromAttr = GetFromAttribute();
  463. if ( !pFromAttr )
  464. return;
  465. if ( IsArrayType( pFromAttr->GetType() ) )
  466. {
  467. if ( ArrayTypeToValueType( pFromAttr->GetType() ) != CDmAttributeInfo< T >::AttributeType() )
  468. return;
  469. CDmrArray< T > array( pFromAttr );
  470. array.Set( m_fromIndex.Get(), value );
  471. }
  472. else
  473. {
  474. if ( pFromAttr->GetType() != CDmAttributeInfo< T >::AttributeType() )
  475. return;
  476. pFromAttr->SetValue( value );
  477. }
  478. }
  479. #endif // DMECHANNEL_H