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
459 lines
16 KiB
//========= 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
|
|
|