diff options
Diffstat (limited to 'public/movieobjects/dmecombinationoperator.h')
| -rw-r--r-- | public/movieobjects/dmecombinationoperator.h | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/public/movieobjects/dmecombinationoperator.h b/public/movieobjects/dmecombinationoperator.h new file mode 100644 index 0000000..ee40735 --- /dev/null +++ b/public/movieobjects/dmecombinationoperator.h @@ -0,0 +1,459 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Operators that generate combinations +// +//============================================================================= + +#ifndef DMECOMBINATIONOPERATOR_H +#define DMECOMBINATIONOPERATOR_H +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/dmelement.h" +#include "datamodel/dmattribute.h" +#include "datamodel/dmattributevar.h" +#include "movieobjects/dmeoperator.h" +#include "movieobjects/dmeexpressionoperator.h" +#include "datamodel/dmehandle.h" + + +//----------------------------------------------------------------------------- +// Expression operator +//----------------------------------------------------------------------------- +class CDmeChannel; +class CDmeDag; +class CDmElement; +class CDmeChannelsClip; +class CDmeShape; + + +//----------------------------------------------------------------------------- +// Control handles +//----------------------------------------------------------------------------- +typedef int ControlIndex_t; + + +//----------------------------------------------------------------------------- +// Basic version.. +//----------------------------------------------------------------------------- +class CDmeCombinationInputControl : public CDmElement +{ + DEFINE_ELEMENT( CDmeCombinationInputControl, CDmElement ); + +public: + virtual void OnElementUnserialized(); + + // Adds a control, returns the control index, + // returns true if remapped control lists need updating + bool AddRawControl( const char *pRawControlName ); + + // Removes controls + // returns true if remapped control lists need updating + bool RemoveRawControl( const char *pRawControlName ); + void RemoveAllRawControls(); + + // Iterates remapped controls + int RawControlCount() const; + const char *RawControlName( int nIndex ) const; + + // Do we have a raw control? + bool HasRawControl( const char *pRawControlName ) const; + + // Reordering controls + void MoveRawControlUp( const char *pRawControlName ); + void MoveRawControlDown( const char *pRawControlName ); + + // Is this control a stereo control? + bool IsStereo() const; + void SetStereo( bool bStereo ); + + // Is this control an eyelid control? + bool IsEyelid() const; + void SetEyelid( bool bEyelid ); + + // Returns the name of the eyeball + const char *GetEyesUpDownFlexName() const; + + // Returns the wrinkle scale for a particular control + float WrinkleScale( const char *pRawControlName ); + float WrinkleScale( int nIndex ); + void SetWrinkleScale( const char *pRawControlName, float flWrinkleScale ); + + float GetDefaultValue() const; + float GetBaseValue() const; + +private: + int FindRawControl( const char *pRawControlName ); + + CDmaStringArray m_RawControlNames; + CDmaVar<bool> m_bIsStereo; + CDmaVar< bool > m_bIsEyelid; + + // FIXME! Remove soon! Used to autogenerate wrinkle deltas + CDmaArray< float > m_WrinkleScales; +}; + + +//----------------------------------------------------------------------------- +// Basic version.. +//----------------------------------------------------------------------------- +class CDmeCombinationDominationRule : public CDmElement +{ + DEFINE_ELEMENT( CDmeCombinationDominationRule, CDmElement ); + +public: + // Methods of IDmElement + virtual void OnAttributeChanged( CDmAttribute *pAttribute ); + + // Adds a dominating control + void AddDominator( const char *pDominatorControl ); + + // Add a suppressed control + void AddSuppressed( const char *pSuppressedControl ); + + // Remove all dominatior + suppressed controls + void RemoveAllDominators(); + void RemoveAllSuppressed(); + + // Iteration + int DominatorCount() const; + const char *GetDominator( int i ) const; + + int SuppressedCount() const; + const char *GetSuppressed( int i ) const; + + // Search + bool HasDominatorControl( const char *pDominatorControl ) const; + bool HasSuppressedControl( const char *pSuppressedControl ) const; + +private: + bool HasString( const char *pString, const CDmaStringArray& attr ); + + CDmaStringArray m_Dominators; + CDmaStringArray m_Suppressed; +}; + + +//----------------------------------------------------------------------------- +// Basic version.. needs channels to copy the data out of its output attributes +//----------------------------------------------------------------------------- +enum CombinationControlType_t +{ + COMBO_CONTROL_FIRST = 0, + + COMBO_CONTROL_NORMAL = 0, + COMBO_CONTROL_LAGGED, + + COMBO_CONTROL_TYPE_COUNT, +}; + +class CDmeCombinationOperator : public CDmeOperator +{ + DEFINE_ELEMENT( CDmeCombinationOperator, CDmeOperator ); + +public: + // Methods of IDmElement + virtual void OnAttributeChanged( CDmAttribute *pAttribute ); + + virtual void OnElementUnserialized(); + + // Adds a control, returns the control index. Also adds a raw control with the same name to this control + ControlIndex_t FindOrCreateControl( const char *pControlName, bool bStereo, bool bAutoAddRawControl = false ); + + // Finds the index of the control with the specified name + ControlIndex_t FindControlIndex( const char *pControlName ); + + // Changes a control's name + void SetControlName( ControlIndex_t nControl, const char *pControlName ); + + // Removes a control + void RemoveControl( const char *pControlName ); + void RemoveAllControls(); + + // Adds a remapped control to a input control + void AddRawControl( ControlIndex_t nControl, const char *pRawControlName ); + + // Removes an remapped control from a control + void RemoveRawControl( ControlIndex_t nControl, const char *pRawControlName ); + void RemoveAllRawControls( ControlIndex_t nControl ); + + // Iterates output controls associated with an input control + int GetRawControlCount( ControlIndex_t nControl ) const; + const char *GetRawControlName( ControlIndex_t nControl, int nIndex ) const; + float GetRawControlWrinkleScale( ControlIndex_t nControl, int nIndex ) const; + float GetRawControlWrinkleScale( ControlIndex_t nControl, const char *pRawControlName ) const; + + // Iterates a global list of output controls + int GetRawControlCount( ) const; + const char *GetRawControlName( int nIndex ) const; + float GetRawControlWrinkleScale( int nIndex ) const; + bool IsStereoRawControl( int nIndex ) const; + bool IsEyelidRawControl( int nIndex ) const; + + // Gets Input Control Default & Base Values + float GetControlDefaultValue( ControlIndex_t nControl ) const; + float GetControlBaseValue( ControlIndex_t nControl ) const; + + // Do we have a raw control? + bool HasRawControl( const char *pRawControlName ) const; + + // Sets the wrinkle scale for a particular raw control + void SetWrinkleScale( ControlIndex_t nControlIndex, const char *pRawControlName, float flWrinkleScale ); + + // Sets the value of a control + void SetControlValue( ControlIndex_t nControlIndex, float flValue, CombinationControlType_t type = COMBO_CONTROL_NORMAL ); + + // Sets the value of a stereo control + void SetControlValue( ControlIndex_t nControlIndex, float flLevel, float flBalance, CombinationControlType_t type = COMBO_CONTROL_NORMAL ); + void SetControlValue( ControlIndex_t nControlIndex, const Vector2D& vec, CombinationControlType_t type = COMBO_CONTROL_NORMAL ); + + // Returns true if a control is a stereo control + void SetStereoControl( ControlIndex_t nControlIndex, bool bIsStereo ); + bool IsStereoControl( ControlIndex_t nControlIndex ) const; + + // Sets the level of a control (only used by controls w/ 3 or more remappings) + void SetMultiControlLevel( ControlIndex_t nControlIndex, float flLevel, CombinationControlType_t type = COMBO_CONTROL_NORMAL ); + float GetMultiControlLevel( ControlIndex_t nControlIndex, CombinationControlType_t type = COMBO_CONTROL_NORMAL ) const; + + // Reordering controls + void MoveControlUp( const char *pControlName ); + void MoveControlDown( const char *pControlName ); + void MoveControlBefore( const char *pDragControlName, const char *pDropControlName ); + void MoveControlAfter( const char *pDragControlName, const char *pDropControlName ); + + void MoveRawControlUp( ControlIndex_t nControlIndex, const char *pRawControlName ); + void MoveRawControlDown( ControlIndex_t nControlIndex, const char *pRawControlName ); + + // Returns true if a control is a multi control (a control w/ 3 or more remappings) + bool IsMultiControl( ControlIndex_t nControlIndex ) const; + + // Returns true if a control is a multi-control which controls eyelids + void SetEyelidControl( ControlIndex_t nControlIndex, bool bIsEyelid ); + bool IsEyelidControl( ControlIndex_t nControlIndex ) const; + const char *GetEyesUpDownFlexName( ControlIndex_t nControlIndex ) const; + + // Sets the value of a control + float GetControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type = COMBO_CONTROL_NORMAL ) const; + const Vector2D& GetStereoControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type = COMBO_CONTROL_NORMAL ) const; + + // Iterates controls + int GetControlCount() const; + const char *GetControlName( ControlIndex_t i ) const; + + // Attaches a channel to an input + void AttachChannelToControlValue( ControlIndex_t nControlIndex, CombinationControlType_t type, CDmeChannel *pChannel ); + + // Adds a domination rule. Domination rules are specified using raw control names + CDmeCombinationDominationRule *AddDominationRule( ); + CDmeCombinationDominationRule *AddDominationRule( int nDominatorCount, const char **ppDominatorOutputControlNames, int nSuppressedCount, const char **ppSuppressedOutputControlNames ); + CDmeCombinationDominationRule *AddDominationRule( const CUtlVector< const char * > dominators, const CUtlVector< const char * > suppressed ); + CDmeCombinationDominationRule *AddDominationRule( CDmeCombinationDominationRule *pSrcRule ); + + // Removes a domination rule + void RemoveDominationRule( int nIndex ); + void RemoveDominationRule( CDmeCombinationDominationRule *pRule ); + void RemoveAllDominationRules(); + + // Iteration + int DominationRuleCount() const; + CDmeCombinationDominationRule *GetDominationRule( int i ); + + // Rule reordering + void MoveDominationRuleUp( CDmeCombinationDominationRule* pRule ); + void MoveDominationRuleDown( CDmeCombinationDominationRule* pRule ); + + // Indicates we're using lagged control values + void UsingLaggedData( bool bEnable ); + bool IsUsingLaggedData() const; + + // Adds a target model/arbitrary element to perform the combinations on + // The arbitrary element must have two attributes + // "deltaStates", which is an array of elements + // "deltaStateWeights", which is an array of floats + // In the case of the model, it will look for all shapes in the dag hierarchy + // and attempt to add that shape as a target + // NOTE: Targets are not saved + void AddTarget( CDmeDag *pDag ); + void AddTarget( CDmElement *pElement ); + void RemoveAllTargets(); + + // Used by studiomdl to discover the various combination rules + int GetOperationTargetCount() const; + CDmElement *GetOperationTarget( int nTargetIndex ); + int GetOperationCount( int nTargetIndex ) const; + CDmElement *GetOperationDeltaState( int nTargetIndex, int nOpIndex ); + const CUtlVector< int > &GetOperationControls( int nTargetIndex, int nOpIndex ) const; + int GetOperationDominatorCount( int nTargetIndex, int nOpIndex ) const; + const CUtlVector< int > &GetOperationDominator( int nTargetIndex, int nOpIndex, int nDominatorIndex ) const; + + // Does one of the targets we refer to contain a particular delta state? + bool DoesTargetContainDeltaState( const char *pDeltaStateName ); + + virtual void Operate(); + + virtual void Resolve(); + + virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs ); + virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ); + + // Would a particular delta state attached to this combination operator end up stero? + bool IsDeltaStateStereo( const char *pDeltaStateName ); + + void CopyControls( CDmeCombinationOperator *pSrc ); + + // FIXME: Remove soon! + // This is a very short-term solution to the problem of autogenerating + // wrinkle data; when we have real editors we can remove it + void GenerateWrinkleDeltas( bool bOverwrite = true ); + + void SetToDefault(); + + // The base values are different from the default values see CDmeCombinationInputControl + void SetToBase(); + + // Remove all controls and domination rules which are not referring to anything + void Purge(); + +protected: + void ComputeCombinationInfo( int nIndex ); + +private: + typedef int RawControlIndex_t; + + struct DominatorInfo_t + { + CUtlVector< RawControlIndex_t > m_DominantIndices; + CUtlVector< RawControlIndex_t > m_SuppressedIndices; + }; + + struct CombinationOperation_t + { + int m_nDeltaStateIndex; + CUtlVector< RawControlIndex_t > m_ControlIndices; + CUtlVector< RawControlIndex_t > m_DominatorIndices; + }; + + struct CombinationInfo_t + { + DmAttributeHandle_t m_hDestAttribute[COMBO_CONTROL_TYPE_COUNT]; + CUtlVector< CombinationOperation_t > m_Outputs; + }; + + struct RawControlInfo_t + { + CUtlString m_Name; + bool m_bIsDefaultControl; + ControlIndex_t m_InputControl; + float m_flWrinkleScale; + bool m_bLowerEyelid; + Vector4D m_FilterRamp; // [0] = point at which ramp starts going up + // [1] = point at which ramp hits 1.0 + // [2] = point at which ramp stops holding at 1.0 + // [3] = point at which ramp starts going down + }; + + void ComputeCombinationInfo(); + void CleanUpCombinationInfo( int nIndex ); + void CleanUpCombinationInfo(); + + // Is a particular remapped control stereo? + bool IsRawControlStereo( const char *pRawControlName ); + + // Determines the weighting of input controls based on the deltaState name + int FindDeltaStateIndex( CDmAttribute *pDeltaArray, const char *pDeltaStateName ); + + // Determines which combination to use based on the deltaState name + int ParseDeltaName( const char *pDeltaStateName, int *pControlIndices ); + + // Finds dominators + void FindDominators( CombinationOperation_t& op ); + + // Computes lists of dominators and suppressors + void RebuildDominatorInfo(); + + // Computes list of all remapped controls + void RebuildRawControlList(); + + // Remaps non-stereo -> stereo, stereo ->left/right + void ComputeInternalControlValue( RawControlIndex_t nRawControlIndex, CombinationControlType_t type, Vector2D &value ); + + // Computes lagged input values from non-lagged input + void ComputeLaggedInputValues(); + + // Finds the index of the remapped control with the specified name + RawControlIndex_t FindRawControlIndex( const char *pControlName, bool bIgnoreDefaultControls = false ) const; + + // Updates the default value associated with a control + void UpdateDefaultValue( ControlIndex_t nControlIndex ); + + // Finds a domination rule + int FindDominationRule( CDmeCombinationDominationRule *pRule ); + + // Generates wrinkle deltas for a dag hierarchy + void GenerateWrinkleDeltas( CDmeShape *pShape, bool bOverwrite ); + + CDmaElementArray< CDmeCombinationInputControl > m_InputControls; + CDmaArray< Vector > m_ControlValues[COMBO_CONTROL_TYPE_COUNT]; + CDmaVar< bool > m_bSpecifyingLaggedData; + + CDmaElementArray< CDmeCombinationDominationRule > m_Dominators; + + CDmaElementArray< CDmElement > m_Targets; + + CUtlVector< bool > m_IsDefaultValue; // one per control value + CUtlVector< RawControlInfo_t > m_RawControlInfo; + CUtlVector< CombinationInfo_t > m_CombinationInfo; + CUtlVector< DominatorInfo_t > m_DominatorInfo; + + float m_flLastLaggedComputationTime; +}; + + +//----------------------------------------------------------------------------- +// Indicates we're using lagged control values +//----------------------------------------------------------------------------- +inline void CDmeCombinationOperator::UsingLaggedData( bool bEnable ) +{ + m_bSpecifyingLaggedData = bEnable; +} + +inline bool CDmeCombinationOperator::IsUsingLaggedData() const +{ + return m_bSpecifyingLaggedData; +} + + +//----------------------------------------------------------------------------- +// Helper method to create a lagged version of channel data from source data +//----------------------------------------------------------------------------- +void CreateLaggedVertexAnimation( CDmeChannelsClip *pClip, int nSamplesPerSec ); + + +//----------------------------------------------------------------------------- +// +// A class used to edit combination operators in Maya.. doesn't connect to targets +// +//----------------------------------------------------------------------------- +class CDmeMayaCombinationOperator : public CDmeCombinationOperator +{ + DEFINE_ELEMENT( CDmeMayaCombinationOperator, CDmeCombinationOperator ); + +public: + void AddDeltaState( const char *pDeltaStateName ); + void RemoveDeltaState( const char *pDeltaStateName ); + void RemoveAllDeltaStates(); + + int FindDeltaState( const char *pDeltaStateName ); + + int DeltaStateCount() const; + const char *GetDeltaState( int nIndex ) const; + const Vector2D& GetDeltaStateWeight( int nIndex, CombinationControlType_t type ) const; + +private: + CDmaElementArray< CDmElement > m_DeltaStates; + CDmaArray< Vector2D > m_DeltaStateWeights[COMBO_CONTROL_TYPE_COUNT]; +}; + + +#endif // DMECOMBINATIONOPERATOR_H |