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

//========= 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