csgo-2018-source/public/dme_controls/BaseAnimationSetEditorController.h
2021-07-24 21:11:47 -07:00

392 lines
14 KiB
C++

//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef BASEANIMATIONSETEDITORCONTROLLER_H
#define BASEANIMATIONSETEDITORCONTROLLER_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/dmehandle.h"
#include "movieobjects/animsetattributevalue.h"
#include "dme_controls/dmecontrols_utils.h"
#include "dme_controls/RecordingState.h"
#include "tier1/utlvector.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct SelectionInfo_t;
class CDmeAnimationSet;
class CDmeAnimationList;
class CDmeChannelsClip;
class CDmeChannel;
class CBaseAnimationSetEditor;
class CAttributeSlider;
class CNotifyAnimationSetControlSelectionChangedScopeGuard;
struct AttributeValue_t;
enum ESelectionMode
{
SELECTION_SET,
SELECTION_ADD,
SELECTION_REMOVE,
SELECTION_TOGGLE,
};
// NOTE - these values were chosen specifically to allow bitwise or (|) to combine selection states together properly
enum SelectionState_t
{
SEL_EMPTY = 0,
SEL_NONE = 1,
SEL_ALL = 2,
SEL_SOME = 3,
};
inline SelectionState_t operator+( SelectionState_t a, SelectionState_t b )
{
return SelectionState_t( int( a ) | int( b ) );
}
inline SelectionState_t operator+=( SelectionState_t &a, SelectionState_t b )
{
return a = a + b;
}
enum TransformComponent_t
{
TRANSFORM_COMPONENT_NONE = 0,
TRANSFORM_COMPONENT_POSITION_X = ( 1 << 0 ),
TRANSFORM_COMPONENT_POSITION_Y = ( 1 << 1 ),
TRANSFORM_COMPONENT_POSITION_Z = ( 1 << 2 ),
TRANSFORM_COMPONENT_ROTATION_X = ( 1 << 3 ),
TRANSFORM_COMPONENT_ROTATION_Y = ( 1 << 4 ),
TRANSFORM_COMPONENT_ROTATION_Z = ( 1 << 5 ),
TRANSFORM_COMPONENT_POSITION = TRANSFORM_COMPONENT_POSITION_X | TRANSFORM_COMPONENT_POSITION_Y | TRANSFORM_COMPONENT_POSITION_Z,
TRANSFORM_COMPONENT_ROTATION = TRANSFORM_COMPONENT_ROTATION_X | TRANSFORM_COMPONENT_ROTATION_Y | TRANSFORM_COMPONENT_ROTATION_Z,
TRANSFORM_COMPONENT_ALL = TRANSFORM_COMPONENT_POSITION | TRANSFORM_COMPONENT_ROTATION
};
DEFINE_ENUM_BITWISE_OPERATORS( TransformComponent_t )
class IOverrideParentChangedListener
{
public:
virtual void OnOverrideParentChanged( CDmeDag *pChildDag ) = 0;
};
class IAnimationSetControlSelectionChangedListener
{
public:
virtual void OnControlSelectionChanged() {}
virtual void OnRebuildControlHierarchy() {}
virtual void ExpandTreeToControl( const CDmElement *pSelection, TransformComponent_t nComponentFlags ) {}
};
struct SelectionInfo_t
{
DECLARE_FIXEDSIZE_ALLOCATOR( SelectionInfo_t );
public:
SelectionInfo_t() : m_nComponentFlags( TRANSFORM_COMPONENT_NONE ) {}
SelectionInfo_t( CDmeAnimationSet *pAnimSet, CDmElement *pControl, TransformComponent_t nComponentFlags = TRANSFORM_COMPONENT_NONE )
: m_hAnimSet( pAnimSet ), m_hControl( pControl ), m_nComponentFlags( nComponentFlags )
{
}
bool IsPositionFullySelected() const
{
return ( ( m_nComponentFlags & TRANSFORM_COMPONENT_POSITION ) == TRANSFORM_COMPONENT_POSITION );
}
bool IsRotationFullySelected() const
{
return ( ( m_nComponentFlags & TRANSFORM_COMPONENT_ROTATION ) == TRANSFORM_COMPONENT_ROTATION );
}
bool AreAnyPositionComponentsSelected()
{
return ( ( m_nComponentFlags & TRANSFORM_COMPONENT_POSITION ) > 0 );
}
bool AreAnyOrientationComponentsSelected()
{
return ( ( m_nComponentFlags & TRANSFORM_COMPONENT_ROTATION ) > 0 );
}
static LogComponents_t ConvertTransformFlagsToLogFlags( TransformComponent_t nTransformFlags, bool bOrientation )
{
LogComponents_t nFlags = LOG_COMPONENTS_NONE;
if ( bOrientation )
{
nFlags |= ( ( nTransformFlags & TRANSFORM_COMPONENT_ROTATION_X ) > 0 ) ? LOG_COMPONENTS_X : LOG_COMPONENTS_NONE;
nFlags |= ( ( nTransformFlags & TRANSFORM_COMPONENT_ROTATION_Y ) > 0 ) ? LOG_COMPONENTS_Y : LOG_COMPONENTS_NONE;
nFlags |= ( ( nTransformFlags & TRANSFORM_COMPONENT_ROTATION_Z ) > 0 ) ? LOG_COMPONENTS_Z : LOG_COMPONENTS_NONE;
}
else
{
nFlags |= ( ( nTransformFlags & TRANSFORM_COMPONENT_POSITION_X ) > 0 ) ? LOG_COMPONENTS_X : LOG_COMPONENTS_NONE;
nFlags |= ( ( nTransformFlags & TRANSFORM_COMPONENT_POSITION_Y ) > 0 ) ? LOG_COMPONENTS_Y : LOG_COMPONENTS_NONE;
nFlags |= ( ( nTransformFlags & TRANSFORM_COMPONENT_POSITION_Z ) > 0 ) ? LOG_COMPONENTS_Z : LOG_COMPONENTS_NONE;
}
return nFlags;
}
static TransformComponent_t ConvertLogFlagsToTransformFlags( LogComponents_t nLogFlags, bool bOrientation )
{
TransformComponent_t nFlags = TRANSFORM_COMPONENT_NONE;
if ( bOrientation )
{
nFlags |= ( ( nLogFlags & LOG_COMPONENTS_X ) > 0 ) ? TRANSFORM_COMPONENT_ROTATION_X : TRANSFORM_COMPONENT_NONE;
nFlags |= ( ( nLogFlags & LOG_COMPONENTS_Y ) > 0 ) ? TRANSFORM_COMPONENT_ROTATION_Y : TRANSFORM_COMPONENT_NONE;
nFlags |= ( ( nLogFlags & LOG_COMPONENTS_Z ) > 0 ) ? TRANSFORM_COMPONENT_ROTATION_Z : TRANSFORM_COMPONENT_NONE;
}
else
{
nFlags |= ( ( nLogFlags & LOG_COMPONENTS_X ) > 0 ) ? TRANSFORM_COMPONENT_POSITION_X : TRANSFORM_COMPONENT_NONE;
nFlags |= ( ( nLogFlags & LOG_COMPONENTS_Y ) > 0 ) ? TRANSFORM_COMPONENT_POSITION_Y : TRANSFORM_COMPONENT_NONE;
nFlags |= ( ( nLogFlags & LOG_COMPONENTS_Z ) > 0 ) ? TRANSFORM_COMPONENT_POSITION_Z : TRANSFORM_COMPONENT_NONE;
}
return nFlags;
}
CDmeHandle< CDmeAnimationSet > m_hAnimSet;
CDmeHandle< CDmElement > m_hControl;
TransformComponent_t m_nComponentFlags;
};
template < class T >
void RebuildControlList( CUtlVector< T* > &controlList, CDmeFilmClip *pFilmClip )
{
int nControls = controlList.Count();
for ( int i = 0; i < nControls; ++i )
{
delete controlList[ i ];
}
controlList.RemoveAll();
CAnimSetGroupAnimSetTraversal traversal( pFilmClip );
while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
{
CDmaElementArray< CDmElement > &controls = pAnimSet->GetControls();
int nControls = controls.Count();
for ( int i = 0; i < nControls; ++i )
{
CDmElement *pControl = controls[ i ];
if ( !pControl )
continue;
controlList.AddToTail( new T( pAnimSet, pControl, TRANSFORM_COMPONENT_NONE ) );
}
}
}
template < class T >
T *FindSelectionInfoForControl( CUtlVector< T* > &controlList, const CDmElement *pControl )
{
if ( !pControl )
return NULL;
int nControls = controlList.Count();
for ( int i = 0; i < nControls; ++i )
{
T *pT = controlList[ i ];
if ( pT->m_hControl.Get() == pControl )
return pT;
}
return NULL;
}
template < class T >
void RemoveNullControls( CUtlVector< T* > &controlList )
{
int nControls = controlList.Count();
for ( int i = nControls-1; i >= 0; --i )
{
if ( controlList[ i ]->m_hControl )
continue; // TODO - are there other conditions that could cause a control to exist, but not want to be part of the full list?
delete controlList[ i ];
controlList.Remove( i );
}
}
template < class T >
void AddMissingControls( CUtlVector< T* > &controlList, CDmeFilmClip *pFilmClip )
{
CAnimSetGroupAnimSetTraversal traversal( pFilmClip );
while ( CDmeAnimationSet *pAnimSet = traversal.Next() )
{
CDmaElementArray< CDmElement > &controls = pAnimSet->GetControls();
int nControls = controls.Count();
for ( int i = 0; i < nControls; ++i )
{
CDmElement *pControl = controls[ i ];
if ( !pControl )
continue;
if ( FindSelectionInfoForControl( controlList, pControl ) )
continue;
controlList.AddToTail( new T( pAnimSet, pControl, TRANSFORM_COMPONENT_NONE ) );
}
}
}
//-----------------------------------------------------------------------------
// Base class for the panel for editing animation sets
//-----------------------------------------------------------------------------
class CBaseAnimationSetControl
{
public:
CBaseAnimationSetControl();
~CBaseAnimationSetControl();
void SetAnimationSetEditorPanel( CBaseAnimationSetEditor *pEditor ) { m_pEditor = pEditor; }
virtual void ChangeAnimationSetClip( CDmeFilmClip *pFilmClip );
virtual void OnControlsAddedOrRemoved();
virtual RecordingState_t GetRecordingState() const { return AS_PREVIEW; }
CDmeFilmClip *GetAnimationSetClip();
virtual void OnSliderRangeRemapped() {}
void AddOverrideParentChangedListener( IOverrideParentChangedListener *pListener );
void RemoveOverrideParentChangedListener( IOverrideParentChangedListener *pListener );
void AddControlSelectionChangedListener ( IAnimationSetControlSelectionChangedListener *listener );
void RemoveControlSelectionChangedListener( IAnimationSetControlSelectionChangedListener *listener );
void ClearSelection();
SelectionState_t GetSelectionState( CDmeAnimationSet *pAnimSet ) const;
SelectionState_t GetSelectionState( CDmeControlGroup *pControlGroup ) const;
SelectionState_t GetSelectionState( CDmElement *pControl, TransformComponent_t componentFlags = TRANSFORM_COMPONENT_ALL ) const;
void SetRangeSelectionState( bool bInRangeSelection );
void SelectAnimationSet( CDmeAnimationSet *pAnimSet, ESelectionMode selectionMode = SELECTION_ADD );
void SelectControlGroup( CDmeControlGroup *pControlGroup, ESelectionMode selectionMode = SELECTION_ADD );
void SelectControlForDag( const CDmeDag *pDag, ESelectionMode selectionMode = SELECTION_ADD );
bool SelectControl( const CDmElement *pControl, ESelectionMode selectionMode = SELECTION_ADD, TransformComponent_t componentFlags = TRANSFORM_COMPONENT_ALL, bool bExpandTree = false );
void SaveSelection( CUtlVector< SelectionInfo_t > &selection ) const;
void RestoreSelection( const CUtlVector< SelectionInfo_t > &selection );
void DeselectHiddenControls();
CDmElement *GetMostRecentlySelectedControl();
bool IsControlSelected( CDmElement *pControl ) const;
TransformComponent_t GetSelectionComponentFlags( CDmElement *pControl ) const;
virtual void ProceduralPreset_UpdateCrossfade( AttributeDict_t *values, int nPresetType );
void SetWorkCameraParent( CDmeDag *pWorkCameraParent );
CDmeDag *GetWorkCameraParent();
void SetPresetFromControls( const char *pPresetGroupName, const char *pPresetName );
void AddPreset( const char *pPresetGroupName, const char *pPresetName, bool bAnimated );
void UpdatePreviewSliderValues();
void UpdatePreviewSliderTimes();
bool IsPresetFaderBeingDragged() const;
void UpdateDominantSliderStartValues( bool restoreSliderValues );
void GetDominantSliderValues( float &flDomStart, float &flDomValue );
void ApplyPreset( float flScale, AttributeDict_t& values );
bool ApplySliderValues( bool force );
void SetActiveAttributeSlider( CAttributeSlider *pSlider );
CAttributeSlider *GetActiveAttributeSlider() { return m_ActiveAttributeSlider; }
// HACK - these should be removed after creating the CAnimationSetControl,
// and CAnimSetAttributeSliderPanel::ApplySliderValues is moved to there
float GetPreviousPresetAmount() const { return m_flPreviousPresetAmount; }
bool WasPreviouslyHoldingPresetPreviewKey() const { return m_bPreviouslyHoldingPresetPreviewKey; }
bool HasPresetSliderChanged() const { return m_bPresetSliderChanged; }
float GetDominantSliderStartValue( int nSliderIndex, AnimationControlType_t type );
int GetDominantSliderIndex() const { return m_nDominantSlider; }
// Can the control be snapped to
bool IsControlSnapTarget( const CDmElement *pControl ) const;
// Is the control selectable in the viewport
bool IsControlSelectable( const CDmElement *pControl ) const;
// Determine if the specified control is visible
bool IsControlVisible( const CDmElement *pControl ) const;
// Determine if the specified control group is visible
bool IsControlGroupVisible( const CDmeControlGroup *pGroup ) const;
// Return the state indicating if hidden controls are being displayed
bool IsShowingHiddenControls() const { return m_bShowHiddenControls; }
// Set the state indicating if hidden controls are to be displayed
void SetShowHiddenControls( bool showHidden ) { m_bShowHiddenControls = showHidden; }
protected:
void AddPreset( CDmeAnimationSet *pAnimSet, const char *pPresetGroupName, const char *pPresetName, bool bAnimated );
virtual void GetAnimatedPresetTimeParameters( DmeTime_t &tHead, DmeTime_t &tStart, DmeTime_t &tEnd );
// from CBaseAnimSetControlGroupPanel:
void FireOverrideParentChangedListeners( CDmeDag *pChildDag );
virtual void FireControlSelectionChangedListeners();
virtual void FireRebuildControlHierarchyListeners();
template< class T >
void ApplyTransformSliderValue( CAttributeSlider *pSlider, CDmeTransformControl *pControl, bool bUsePreviewValue, bool bForce, bool &valuesChanged, AnimationControlType_t type );
void ApplySliderValueWithDominance( CAttributeSlider *pSlider, int si, float flDomStart, float flDomValue, CDmElement *pControl, bool bUsePreviewValue, bool bForce, bool &valuesChanged, AnimationControlType_t type, const char *pChannelAttrName, const char *pValueAttrName );
virtual SelectionInfo_t *FindSelectionInfoForControl( const CDmElement *pControl ) = 0;
void EnsureCrossfadePresetControlValues( int nCount );
protected:
// from CBaseAnimationSetEditor:
CDmeHandle< CDmeFilmClip > m_hFilmClip;
CBaseAnimationSetEditor *m_pEditor;
// from CBaseAnimSetControlGroupPanel:
CUtlLinkedList< SelectionInfo_t* > m_SelectionHistory;
CDmeHandle< CDmeDag > m_hWorkCameraParent;
CUtlVector< IOverrideParentChangedListener * > m_OverrideParentChangedListeners;
CUtlVector< IAnimationSetControlSelectionChangedListener * > m_ControlSelectionChangedListeners;
// from CBaseAnimSetAttributeSliderPanel:
CUtlString m_PreviousPresetSlider;
float m_flPreviousPresetAmount;
bool m_bPresetPreviouslyDragged : 1;
bool m_bPreviouslyHoldingPresetPreviewKey : 1;
bool m_bPresetSliderChanged : 1;
vgui::DHANDLE< CAttributeSlider > m_ActiveAttributeSlider;
CUtlVector< AttributeValue_t > m_DominantSliderStartValues; // Values of all sliders at start of drag of dominant slider
int m_nDominantSlider;
// Flag indicating if hidden controls are to be displayed
bool m_bShowHiddenControls;
CUtlVector< CDmElement* > m_crossfadePresetControlValues;
friend CBaseAnimationSetEditor;
friend CNotifyAnimationSetControlSelectionChangedScopeGuard;
};
#endif // BASEANIMATIONSETEDITORCONTROLLER_H