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.

459 lines
16 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Operators that generate combinations
  4. //
  5. //=============================================================================
  6. #ifndef DMECOMBINATIONOPERATOR_H
  7. #define DMECOMBINATIONOPERATOR_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 "movieobjects/dmeoperator.h"
  15. #include "movieobjects/dmeexpressionoperator.h"
  16. #include "datamodel/dmehandle.h"
  17. //-----------------------------------------------------------------------------
  18. // Expression operator
  19. //-----------------------------------------------------------------------------
  20. class CDmeChannel;
  21. class CDmeDag;
  22. class CDmElement;
  23. class CDmeChannelsClip;
  24. class CDmeShape;
  25. //-----------------------------------------------------------------------------
  26. // Control handles
  27. //-----------------------------------------------------------------------------
  28. typedef int ControlIndex_t;
  29. //-----------------------------------------------------------------------------
  30. // Basic version..
  31. //-----------------------------------------------------------------------------
  32. class CDmeCombinationInputControl : public CDmElement
  33. {
  34. DEFINE_ELEMENT( CDmeCombinationInputControl, CDmElement );
  35. public:
  36. virtual void OnElementUnserialized();
  37. // Adds a control, returns the control index,
  38. // returns true if remapped control lists need updating
  39. bool AddRawControl( const char *pRawControlName );
  40. // Removes controls
  41. // returns true if remapped control lists need updating
  42. bool RemoveRawControl( const char *pRawControlName );
  43. void RemoveAllRawControls();
  44. // Iterates remapped controls
  45. int RawControlCount() const;
  46. const char *RawControlName( int nIndex ) const;
  47. // Do we have a raw control?
  48. bool HasRawControl( const char *pRawControlName ) const;
  49. // Reordering controls
  50. void MoveRawControlUp( const char *pRawControlName );
  51. void MoveRawControlDown( const char *pRawControlName );
  52. // Is this control a stereo control?
  53. bool IsStereo() const;
  54. void SetStereo( bool bStereo );
  55. // Is this control an eyelid control?
  56. bool IsEyelid() const;
  57. void SetEyelid( bool bEyelid );
  58. // Returns the name of the eyeball
  59. const char *GetEyesUpDownFlexName() const;
  60. // Returns the wrinkle scale for a particular control
  61. float WrinkleScale( const char *pRawControlName );
  62. float WrinkleScale( int nIndex );
  63. void SetWrinkleScale( const char *pRawControlName, float flWrinkleScale );
  64. float GetDefaultValue() const;
  65. float GetBaseValue() const;
  66. private:
  67. int FindRawControl( const char *pRawControlName );
  68. CDmaStringArray m_RawControlNames;
  69. CDmaVar<bool> m_bIsStereo;
  70. CDmaVar< bool > m_bIsEyelid;
  71. // FIXME! Remove soon! Used to autogenerate wrinkle deltas
  72. CDmaArray< float > m_WrinkleScales;
  73. };
  74. //-----------------------------------------------------------------------------
  75. // Basic version..
  76. //-----------------------------------------------------------------------------
  77. class CDmeCombinationDominationRule : public CDmElement
  78. {
  79. DEFINE_ELEMENT( CDmeCombinationDominationRule, CDmElement );
  80. public:
  81. // Methods of IDmElement
  82. virtual void OnAttributeChanged( CDmAttribute *pAttribute );
  83. // Adds a dominating control
  84. void AddDominator( const char *pDominatorControl );
  85. // Add a suppressed control
  86. void AddSuppressed( const char *pSuppressedControl );
  87. // Remove all dominatior + suppressed controls
  88. void RemoveAllDominators();
  89. void RemoveAllSuppressed();
  90. // Iteration
  91. int DominatorCount() const;
  92. const char *GetDominator( int i ) const;
  93. int SuppressedCount() const;
  94. const char *GetSuppressed( int i ) const;
  95. // Search
  96. bool HasDominatorControl( const char *pDominatorControl ) const;
  97. bool HasSuppressedControl( const char *pSuppressedControl ) const;
  98. private:
  99. bool HasString( const char *pString, const CDmaStringArray& attr );
  100. CDmaStringArray m_Dominators;
  101. CDmaStringArray m_Suppressed;
  102. };
  103. //-----------------------------------------------------------------------------
  104. // Basic version.. needs channels to copy the data out of its output attributes
  105. //-----------------------------------------------------------------------------
  106. enum CombinationControlType_t
  107. {
  108. COMBO_CONTROL_FIRST = 0,
  109. COMBO_CONTROL_NORMAL = 0,
  110. COMBO_CONTROL_LAGGED,
  111. COMBO_CONTROL_TYPE_COUNT,
  112. };
  113. class CDmeCombinationOperator : public CDmeOperator
  114. {
  115. DEFINE_ELEMENT( CDmeCombinationOperator, CDmeOperator );
  116. public:
  117. // Methods of IDmElement
  118. virtual void OnAttributeChanged( CDmAttribute *pAttribute );
  119. virtual void OnElementUnserialized();
  120. // Adds a control, returns the control index. Also adds a raw control with the same name to this control
  121. ControlIndex_t FindOrCreateControl( const char *pControlName, bool bStereo, bool bAutoAddRawControl = false );
  122. // Finds the index of the control with the specified name
  123. ControlIndex_t FindControlIndex( const char *pControlName );
  124. // Changes a control's name
  125. void SetControlName( ControlIndex_t nControl, const char *pControlName );
  126. // Removes a control
  127. void RemoveControl( const char *pControlName );
  128. void RemoveAllControls();
  129. // Adds a remapped control to a input control
  130. void AddRawControl( ControlIndex_t nControl, const char *pRawControlName );
  131. // Removes an remapped control from a control
  132. void RemoveRawControl( ControlIndex_t nControl, const char *pRawControlName );
  133. void RemoveAllRawControls( ControlIndex_t nControl );
  134. // Iterates output controls associated with an input control
  135. int GetRawControlCount( ControlIndex_t nControl ) const;
  136. const char *GetRawControlName( ControlIndex_t nControl, int nIndex ) const;
  137. float GetRawControlWrinkleScale( ControlIndex_t nControl, int nIndex ) const;
  138. float GetRawControlWrinkleScale( ControlIndex_t nControl, const char *pRawControlName ) const;
  139. // Iterates a global list of output controls
  140. int GetRawControlCount( ) const;
  141. const char *GetRawControlName( int nIndex ) const;
  142. float GetRawControlWrinkleScale( int nIndex ) const;
  143. bool IsStereoRawControl( int nIndex ) const;
  144. bool IsEyelidRawControl( int nIndex ) const;
  145. // Gets Input Control Default & Base Values
  146. float GetControlDefaultValue( ControlIndex_t nControl ) const;
  147. float GetControlBaseValue( ControlIndex_t nControl ) const;
  148. // Do we have a raw control?
  149. bool HasRawControl( const char *pRawControlName ) const;
  150. // Sets the wrinkle scale for a particular raw control
  151. void SetWrinkleScale( ControlIndex_t nControlIndex, const char *pRawControlName, float flWrinkleScale );
  152. // Sets the value of a control
  153. void SetControlValue( ControlIndex_t nControlIndex, float flValue, CombinationControlType_t type = COMBO_CONTROL_NORMAL );
  154. // Sets the value of a stereo control
  155. void SetControlValue( ControlIndex_t nControlIndex, float flLevel, float flBalance, CombinationControlType_t type = COMBO_CONTROL_NORMAL );
  156. void SetControlValue( ControlIndex_t nControlIndex, const Vector2D& vec, CombinationControlType_t type = COMBO_CONTROL_NORMAL );
  157. // Returns true if a control is a stereo control
  158. void SetStereoControl( ControlIndex_t nControlIndex, bool bIsStereo );
  159. bool IsStereoControl( ControlIndex_t nControlIndex ) const;
  160. // Sets the level of a control (only used by controls w/ 3 or more remappings)
  161. void SetMultiControlLevel( ControlIndex_t nControlIndex, float flLevel, CombinationControlType_t type = COMBO_CONTROL_NORMAL );
  162. float GetMultiControlLevel( ControlIndex_t nControlIndex, CombinationControlType_t type = COMBO_CONTROL_NORMAL ) const;
  163. // Reordering controls
  164. void MoveControlUp( const char *pControlName );
  165. void MoveControlDown( const char *pControlName );
  166. void MoveControlBefore( const char *pDragControlName, const char *pDropControlName );
  167. void MoveControlAfter( const char *pDragControlName, const char *pDropControlName );
  168. void MoveRawControlUp( ControlIndex_t nControlIndex, const char *pRawControlName );
  169. void MoveRawControlDown( ControlIndex_t nControlIndex, const char *pRawControlName );
  170. // Returns true if a control is a multi control (a control w/ 3 or more remappings)
  171. bool IsMultiControl( ControlIndex_t nControlIndex ) const;
  172. // Returns true if a control is a multi-control which controls eyelids
  173. void SetEyelidControl( ControlIndex_t nControlIndex, bool bIsEyelid );
  174. bool IsEyelidControl( ControlIndex_t nControlIndex ) const;
  175. const char *GetEyesUpDownFlexName( ControlIndex_t nControlIndex ) const;
  176. // Sets the value of a control
  177. float GetControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type = COMBO_CONTROL_NORMAL ) const;
  178. const Vector2D& GetStereoControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type = COMBO_CONTROL_NORMAL ) const;
  179. // Iterates controls
  180. int GetControlCount() const;
  181. const char *GetControlName( ControlIndex_t i ) const;
  182. // Attaches a channel to an input
  183. void AttachChannelToControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type, CDmeChannel *pChannel );
  184. // Adds a domination rule. Domination rules are specified using raw control names
  185. CDmeCombinationDominationRule *AddDominationRule( );
  186. CDmeCombinationDominationRule *AddDominationRule( int nDominatorCount, const char **ppDominatorOutputControlNames, int nSuppressedCount, const char **ppSuppressedOutputControlNames );
  187. CDmeCombinationDominationRule *AddDominationRule( const CUtlVector< const char * > dominators, const CUtlVector< const char * > suppressed );
  188. CDmeCombinationDominationRule *AddDominationRule( CDmeCombinationDominationRule *pSrcRule );
  189. // Removes a domination rule
  190. void RemoveDominationRule( int nIndex );
  191. void RemoveDominationRule( CDmeCombinationDominationRule *pRule );
  192. void RemoveAllDominationRules();
  193. // Iteration
  194. int DominationRuleCount() const;
  195. CDmeCombinationDominationRule *GetDominationRule( int i );
  196. // Rule reordering
  197. void MoveDominationRuleUp( CDmeCombinationDominationRule* pRule );
  198. void MoveDominationRuleDown( CDmeCombinationDominationRule* pRule );
  199. // Indicates we're using lagged control values
  200. void UsingLaggedData( bool bEnable );
  201. bool IsUsingLaggedData() const;
  202. // Adds a target model/arbitrary element to perform the combinations on
  203. // The arbitrary element must have two attributes
  204. // "deltaStates", which is an array of elements
  205. // "deltaStateWeights", which is an array of floats
  206. // In the case of the model, it will look for all shapes in the dag hierarchy
  207. // and attempt to add that shape as a target
  208. // NOTE: Targets are not saved
  209. void AddTarget( CDmeDag *pDag );
  210. void AddTarget( CDmElement *pElement );
  211. void RemoveAllTargets();
  212. // Used by studiomdl to discover the various combination rules
  213. int GetOperationTargetCount() const;
  214. CDmElement *GetOperationTarget( int nTargetIndex );
  215. int GetOperationCount( int nTargetIndex ) const;
  216. CDmElement *GetOperationDeltaState( int nTargetIndex, int nOpIndex );
  217. const CUtlVector< int > &GetOperationControls( int nTargetIndex, int nOpIndex ) const;
  218. int GetOperationDominatorCount( int nTargetIndex, int nOpIndex ) const;
  219. const CUtlVector< int > &GetOperationDominator( int nTargetIndex, int nOpIndex, int nDominatorIndex ) const;
  220. // Does one of the targets we refer to contain a particular delta state?
  221. bool DoesTargetContainDeltaState( const char *pDeltaStateName );
  222. virtual void Operate();
  223. virtual void Resolve();
  224. virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs );
  225. virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs );
  226. // Would a particular delta state attached to this combination operator end up stero?
  227. bool IsDeltaStateStereo( const char *pDeltaStateName );
  228. void CopyControls( CDmeCombinationOperator *pSrc );
  229. // FIXME: Remove soon!
  230. // This is a very short-term solution to the problem of autogenerating
  231. // wrinkle data; when we have real editors we can remove it
  232. void GenerateWrinkleDeltas( bool bOverwrite = true );
  233. void SetToDefault();
  234. // The base values are different from the default values see CDmeCombinationInputControl
  235. void SetToBase();
  236. // Remove all controls and domination rules which are not referring to anything
  237. void Purge();
  238. protected:
  239. void ComputeCombinationInfo( int nIndex );
  240. private:
  241. typedef int RawControlIndex_t;
  242. struct DominatorInfo_t
  243. {
  244. CUtlVector< RawControlIndex_t > m_DominantIndices;
  245. CUtlVector< RawControlIndex_t > m_SuppressedIndices;
  246. };
  247. struct CombinationOperation_t
  248. {
  249. int m_nDeltaStateIndex;
  250. CUtlVector< RawControlIndex_t > m_ControlIndices;
  251. CUtlVector< RawControlIndex_t > m_DominatorIndices;
  252. };
  253. struct CombinationInfo_t
  254. {
  255. DmAttributeHandle_t m_hDestAttribute[COMBO_CONTROL_TYPE_COUNT];
  256. CUtlVector< CombinationOperation_t > m_Outputs;
  257. };
  258. struct RawControlInfo_t
  259. {
  260. CUtlString m_Name;
  261. bool m_bIsDefaultControl;
  262. ControlIndex_t m_InputControl;
  263. float m_flWrinkleScale;
  264. bool m_bLowerEyelid;
  265. Vector4D m_FilterRamp; // [0] = point at which ramp starts going up
  266. // [1] = point at which ramp hits 1.0
  267. // [2] = point at which ramp stops holding at 1.0
  268. // [3] = point at which ramp starts going down
  269. };
  270. void ComputeCombinationInfo();
  271. void CleanUpCombinationInfo( int nIndex );
  272. void CleanUpCombinationInfo();
  273. // Is a particular remapped control stereo?
  274. bool IsRawControlStereo( const char *pRawControlName );
  275. // Determines the weighting of input controls based on the deltaState name
  276. int FindDeltaStateIndex( CDmAttribute *pDeltaArray, const char *pDeltaStateName );
  277. // Determines which combination to use based on the deltaState name
  278. int ParseDeltaName( const char *pDeltaStateName, int *pControlIndices );
  279. // Finds dominators
  280. void FindDominators( CombinationOperation_t& op );
  281. // Computes lists of dominators and suppressors
  282. void RebuildDominatorInfo();
  283. // Computes list of all remapped controls
  284. void RebuildRawControlList();
  285. // Remaps non-stereo -> stereo, stereo ->left/right
  286. void ComputeInternalControlValue( RawControlIndex_t nRawControlIndex, CombinationControlType_t type, Vector2D &value );
  287. // Computes lagged input values from non-lagged input
  288. void ComputeLaggedInputValues();
  289. // Finds the index of the remapped control with the specified name
  290. RawControlIndex_t FindRawControlIndex( const char *pControlName, bool bIgnoreDefaultControls = false ) const;
  291. // Updates the default value associated with a control
  292. void UpdateDefaultValue( ControlIndex_t nControlIndex );
  293. // Finds a domination rule
  294. int FindDominationRule( CDmeCombinationDominationRule *pRule );
  295. // Generates wrinkle deltas for a dag hierarchy
  296. void GenerateWrinkleDeltas( CDmeShape *pShape, bool bOverwrite );
  297. CDmaElementArray< CDmeCombinationInputControl > m_InputControls;
  298. CDmaArray< Vector > m_ControlValues[COMBO_CONTROL_TYPE_COUNT];
  299. CDmaVar< bool > m_bSpecifyingLaggedData;
  300. CDmaElementArray< CDmeCombinationDominationRule > m_Dominators;
  301. CDmaElementArray< CDmElement > m_Targets;
  302. CUtlVector< bool > m_IsDefaultValue; // one per control value
  303. CUtlVector< RawControlInfo_t > m_RawControlInfo;
  304. CUtlVector< CombinationInfo_t > m_CombinationInfo;
  305. CUtlVector< DominatorInfo_t > m_DominatorInfo;
  306. float m_flLastLaggedComputationTime;
  307. };
  308. //-----------------------------------------------------------------------------
  309. // Indicates we're using lagged control values
  310. //-----------------------------------------------------------------------------
  311. inline void CDmeCombinationOperator::UsingLaggedData( bool bEnable )
  312. {
  313. m_bSpecifyingLaggedData = bEnable;
  314. }
  315. inline bool CDmeCombinationOperator::IsUsingLaggedData() const
  316. {
  317. return m_bSpecifyingLaggedData;
  318. }
  319. //-----------------------------------------------------------------------------
  320. // Helper method to create a lagged version of channel data from source data
  321. //-----------------------------------------------------------------------------
  322. void CreateLaggedVertexAnimation( CDmeChannelsClip *pClip, int nSamplesPerSec );
  323. //-----------------------------------------------------------------------------
  324. //
  325. // A class used to edit combination operators in Maya.. doesn't connect to targets
  326. //
  327. //-----------------------------------------------------------------------------
  328. class CDmeMayaCombinationOperator : public CDmeCombinationOperator
  329. {
  330. DEFINE_ELEMENT( CDmeMayaCombinationOperator, CDmeCombinationOperator );
  331. public:
  332. void AddDeltaState( const char *pDeltaStateName );
  333. void RemoveDeltaState( const char *pDeltaStateName );
  334. void RemoveAllDeltaStates();
  335. int FindDeltaState( const char *pDeltaStateName );
  336. int DeltaStateCount() const;
  337. const char *GetDeltaState( int nIndex ) const;
  338. const Vector2D& GetDeltaStateWeight( int nIndex, CombinationControlType_t type ) const;
  339. private:
  340. CDmaElementArray< CDmElement > m_DeltaStates;
  341. CDmaArray< Vector2D > m_DeltaStateWeights[COMBO_CONTROL_TYPE_COUNT];
  342. };
  343. #endif // DMECOMBINATIONOPERATOR_H