|
|
//====== Copyright � 1996-2006, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "dme_controls/BaseAnimationSetEditorController.h"
#include "tier1/fmtstr.h"
#include "tier1/KeyValues.h"
#include "tier2/fileutils.h"
#include "vgui_controls/FileOpenDialog.h"
#include "vgui_controls/MessageBox.h"
#include "vgui_controls/perforcefilelistframe.h"
#include "dme_controls/BaseAnimationSetEditor.h"
#include "dme_controls/BaseAnimSetAttributeSliderPanel.h"
#include "dme_controls/BaseAnimSetPresetFaderPanel.h"
#include "dme_controls/attributeslider.h"
#include "movieobjects/dmechannel.h"
#include "movieobjects/dmeanimationset.h"
#include "movieobjects/dmeanimationlist.h"
#include "movieobjects/dmeclip.h"
#include "movieobjects/dmegamemodel.h"
#include "movieobjects/dmetransformcontrol.h"
#include "vgui/IInput.h"
#include <windows.h>
#undef PostMessage
#undef MessageBox
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Blends flex values in left-right space instead of balance/value space
//-----------------------------------------------------------------------------
void BlendValues( bool bTransform, AttributeValue_t *pResult, const AttributeValue_t &src, const AttributeValue_t &dest, float flBlend, float flBalanceFilter = 0.5f );
DEFINE_FIXEDSIZE_ALLOCATOR( SelectionInfo_t, 256, CUtlMemoryPool::GROW_SLOW );
// TODO - we really need to create a solid way of notifying panels when things they care about changes
// right now, we sometimes send vgui messages, sometimes call methods, sometimes use NotifyDataChanged, OnPreviewChanged, FireXXXChangedListeners, etc.
class CNotifyAnimationSetControlSelectionChangedScopeGuard { public: CNotifyAnimationSetControlSelectionChangedScopeGuard( CBaseAnimationSetControl *pControl ) : m_pControl( pControl ), m_selectionMode( SELECTION_REMOVE ) { } CNotifyAnimationSetControlSelectionChangedScopeGuard( CBaseAnimationSetControl *pControl, ESelectionMode selectionMode ) : m_pControl( pControl ), m_selectionMode( selectionMode ) { ++m_nDepth; } ~CNotifyAnimationSetControlSelectionChangedScopeGuard() { Assert( m_nDepth >= 0 ); if ( m_nDepth > 0 ) { Finish(); } }
void Start( ESelectionMode selectionMode ) { m_selectionMode = selectionMode; ++m_nDepth; } void Finish() { Assert( m_nDepth > 0 ); if ( --m_nDepth == 0 ) { m_pControl->FireControlSelectionChangedListeners(); } }
private: CBaseAnimationSetControl *m_pControl; ESelectionMode m_selectionMode; static int m_nDepth; }; int CNotifyAnimationSetControlSelectionChangedScopeGuard::m_nDepth = 0;
CBaseAnimationSetControl::CBaseAnimationSetControl() : m_pEditor( NULL ), m_bShowHiddenControls( false ), m_PreviousPresetSlider( "" ), m_flPreviousPresetAmount( 0.0f ), m_bPresetPreviouslyDragged( false ), m_bPreviouslyHoldingPresetPreviewKey( false ), m_bPresetSliderChanged( false ), m_nDominantSlider( -1 ) { }
CBaseAnimationSetControl::~CBaseAnimationSetControl() { m_ControlSelectionChangedListeners.RemoveAll();
ChangeAnimationSetClip( NULL );
int nCount = m_crossfadePresetControlValues.Count(); for ( int i = 0; i < nCount; ++i ) { DestroyElement( m_crossfadePresetControlValues[ i ], TD_SHALLOW ); } }
void CBaseAnimationSetControl::ChangeAnimationSetClip( CDmeFilmClip *pFilmClip ) { m_hFilmClip = pFilmClip;
// Force recomputation
m_nDominantSlider = -1;
SetWorkCameraParent( NULL ); ClearSelection();
if ( CBaseAnimSetPresetFaderPanel *pPresetFader = m_pEditor->GetPresetFader() ) { pPresetFader->PopulatePresetList( true ); } }
void CBaseAnimationSetControl::OnControlsAddedOrRemoved() { // Force recomputation
m_nDominantSlider = -1;
bool bSelectionChanged = false; for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); ) { SelectionInfo_t *psi = m_SelectionHistory[ i ]; int iCurr = i; i = m_SelectionHistory.Next( i );
CDmElement *pControl = psi->m_hControl.Get(); if ( pControl && IsControlVisible( pControl ) ) continue;
psi->m_nComponentFlags = TRANSFORM_COMPONENT_NONE; m_SelectionHistory.Remove( iCurr ); bSelectionChanged = true; }
if ( bSelectionChanged ) { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, SELECTION_REMOVE ); }
m_pEditor->GetPresetFader()->PopulatePresetList( false ); }
void CBaseAnimationSetControl::SetWorkCameraParent( CDmeDag *pParent ) { m_hWorkCameraParent = pParent; }
CDmeDag *CBaseAnimationSetControl::GetWorkCameraParent() { return m_hWorkCameraParent; }
void CBaseAnimationSetControl::AddOverrideParentChangedListener( IOverrideParentChangedListener *pListener ) { if ( m_OverrideParentChangedListeners.Find( pListener ) == m_OverrideParentChangedListeners.InvalidIndex() ) { m_OverrideParentChangedListeners.AddToTail( pListener ); } }
void CBaseAnimationSetControl::RemoveOverrideParentChangedListener( IOverrideParentChangedListener *pListener ) { m_OverrideParentChangedListeners.FindAndRemove( pListener ); }
void CBaseAnimationSetControl::FireOverrideParentChangedListeners( CDmeDag *pChildDag ) { int nNumListeners = m_OverrideParentChangedListeners.Count(); for ( int i = 0; i < nNumListeners; ++i ) { m_OverrideParentChangedListeners[ i ]->OnOverrideParentChanged( pChildDag ); } }
void CBaseAnimationSetControl::AddControlSelectionChangedListener( IAnimationSetControlSelectionChangedListener *listener ) { if ( m_ControlSelectionChangedListeners.Find( listener ) == m_ControlSelectionChangedListeners.InvalidIndex() ) { m_ControlSelectionChangedListeners.AddToTail( listener ); } }
void CBaseAnimationSetControl::RemoveControlSelectionChangedListener( IAnimationSetControlSelectionChangedListener *listener ) { m_ControlSelectionChangedListeners.FindAndRemove( listener ); }
void CBaseAnimationSetControl::FireControlSelectionChangedListeners() { for ( int i = 0; i < m_ControlSelectionChangedListeners.Count(); ++i ) { m_ControlSelectionChangedListeners[ i ]->OnControlSelectionChanged(); } }
void CBaseAnimationSetControl::FireRebuildControlHierarchyListeners() { for ( int i = 0; i < m_ControlSelectionChangedListeners.Count(); ++i ) { m_ControlSelectionChangedListeners[ i ]->OnRebuildControlHierarchy(); } }
CDmeFilmClip *CBaseAnimationSetControl::GetAnimationSetClip() { return m_hFilmClip; }
bool CBaseAnimationSetControl::IsControlSelected( CDmElement *pControl ) const { return GetSelectionComponentFlags( pControl ) != 0; }
void CBaseAnimationSetControl::ClearSelection() { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, SELECTION_REMOVE );
for ( int i = m_SelectionHistory.Tail(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Previous( i ) ) { m_SelectionHistory[ i ]->m_nComponentFlags = TRANSFORM_COMPONENT_NONE; }
m_SelectionHistory.RemoveAll(); }
bool CBaseAnimationSetControl::SelectControl( const CDmElement *pControl, ESelectionMode selectionMode /*= SELECTION_ADD*/, TransformComponent_t nComponentFlags /*= TRANFORM_COMPONENT_ALL*/, bool bExpandTree /*= false*/ ) { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, selectionMode );
if ( !pControl ) return false;
// Check to see if the control is hidden, if it is hidden it may not be selected.
if ( !IsControlVisible( pControl ) && ( selectionMode != SELECTION_REMOVE ) ) return false;
SelectionInfo_t *psi = FindSelectionInfoForControl( pControl ); Assert( psi ); if ( !psi ) return false;
if ( selectionMode == SELECTION_SET ) { ClearSelection(); psi->m_nComponentFlags = nComponentFlags; } else { if ( psi->m_nComponentFlags != 0 ) { m_SelectionHistory.FindAndRemove( psi ); }
switch ( selectionMode ) { case SELECTION_ADD: psi->m_nComponentFlags |= nComponentFlags; break; case SELECTION_REMOVE: psi->m_nComponentFlags &= ~nComponentFlags; break; case SELECTION_TOGGLE: psi->m_nComponentFlags ^= nComponentFlags; break; } }
if ( psi->m_nComponentFlags != 0 ) { m_SelectionHistory.AddToTail( psi );
if ( bExpandTree ) { for ( int i = 0; i < m_ControlSelectionChangedListeners.Count(); ++i ) { m_ControlSelectionChangedListeners[ i ]->ExpandTreeToControl( pControl, nComponentFlags ); } } } return true; }
void CBaseAnimationSetControl::SaveSelection( CUtlVector< SelectionInfo_t > &selection ) const { int nSelectionCount = m_SelectionHistory.Count(); selection.RemoveAll(); selection.EnsureCapacity( nSelectionCount ); for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { const SelectionInfo_t *pSelection = m_SelectionHistory[ i ]; if ( pSelection ) { selection.AddToTail( *pSelection ); } } }
void CBaseAnimationSetControl::RestoreSelection( const CUtlVector< SelectionInfo_t > &selection ) { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, SELECTION_SET );
ClearSelection();
int nNumSelected = selection.Count(); for ( int iSelected = 0; iSelected < nNumSelected; ++iSelected ) { const SelectionInfo_t &selectionElement = selection[ iSelected ]; CDmElement *pControl = g_pDataModel->GetElement( selectionElement.m_hControl ); if ( pControl == NULL ) continue;
SelectionInfo_t *pSelectionInfo = FindSelectionInfoForControl( pControl ); if ( pSelectionInfo == NULL ) continue;
pSelectionInfo->m_nComponentFlags = selectionElement.m_nComponentFlags;
if ( pSelectionInfo->m_nComponentFlags != 0 ) { m_SelectionHistory.AddToHead( pSelectionInfo ); } } }
void CBaseAnimationSetControl::DeselectHiddenControls() { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, SELECTION_REMOVE );
// Find all of the selected controls which are hidden
CUtlVector< const CDmElement* > hiddenControls( 0, m_SelectionHistory.Count() ); for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { const SelectionInfo_t *pSelection = m_SelectionHistory[ i ]; if ( pSelection ) { const CDmElement *pControl = pSelection->m_hControl; if ( pControl == NULL ) continue;
if ( IsControlVisible( pControl ) == false ) { hiddenControls.AddToTail( pSelection->m_hControl ); } } }
// Remove the hidden controls from the selection
int nNumHiddenControls = hiddenControls.Count(); for ( int iControl = 0; iControl < nNumHiddenControls; ++iControl ) { SelectControl( hiddenControls[ iControl ], SELECTION_REMOVE ); } }
void CBaseAnimationSetControl::SelectControlGroup( CDmeControlGroup *pGroup, ESelectionMode selectionMode /*= SELECTION_ADD*/ ) { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, selectionMode );
if ( !pGroup ) return;
CUtlVector< CDmElement * > list( 0, 32 ); pGroup->GetControlsInGroup( list, true );
for ( int j = list.Count() - 1; j >= 0 ; --j ) { // Only set selection on the first control which was actually selected,
// otherwise we'll de-select everything but the last control
if ( SelectControl( list[ j ], selectionMode ) && ( selectionMode == SELECTION_SET ) ) { selectionMode = SELECTION_ADD; } } }
void CBaseAnimationSetControl::SelectControlForDag( const CDmeDag *pDag, ESelectionMode selectionMode ) { CDmeTransformControl *pTransformControl = pDag->FindTransformControl(); if ( pTransformControl ) { SelectControl( pTransformControl, selectionMode, TRANSFORM_COMPONENT_ALL, true ); } }
void CBaseAnimationSetControl::SetRangeSelectionState( bool bInRangeSelection ) { static CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this ); if ( bInRangeSelection ) { sg.Start( SELECTION_SET ); } else { sg.Finish(); } }
void CBaseAnimationSetControl::SelectAnimationSet( CDmeAnimationSet *pAnimSet, ESelectionMode selectionMode /*= SELECTION_ADD*/ ) { CNotifyAnimationSetControlSelectionChangedScopeGuard sg( this, selectionMode );
SelectControlGroup( pAnimSet->GetRootControlGroup(), selectionMode );
// Find all of the root of the aniamtion set
CUtlVector< CDmeDag* > rootDagNodes; pAnimSet->FindRootDagNodes( rootDagNodes ); // Make the fist selected root the primary selection
// by moving it to the end of the selection list
int nNumRoots = rootDagNodes.Count(); for ( int iRoot = 0; iRoot < nNumRoots; ++iRoot ) { CDmeDag *pRootDag = rootDagNodes[ iRoot ]; if ( pRootDag == NULL ) continue; CDmeTransformControl *pControl = pRootDag->FindTransformControl();
SelectionInfo_t *pSelectionInfo = FindSelectionInfoForControl( pControl ); if ( ( pSelectionInfo ) && ( pSelectionInfo->m_nComponentFlags != 0 ) ) { m_SelectionHistory.FindAndRemove( pSelectionInfo ); m_SelectionHistory.AddToTail( pSelectionInfo ); break; } } }
SelectionState_t CBaseAnimationSetControl::GetSelectionState( CDmeAnimationSet *pAnimSet ) const { if ( !pAnimSet ) return SEL_EMPTY;
return GetSelectionState( pAnimSet->GetRootControlGroup() ); }
SelectionState_t CBaseAnimationSetControl::GetSelectionState( CDmeControlGroup *pControlGroup ) const { if ( !pControlGroup ) return SEL_EMPTY;
SelectionState_t selection = SEL_EMPTY;
const CDmaElementArray< CDmeControlGroup > &children = pControlGroup->Children(); int nChildren = children.Count(); for ( int i = 0; i < nChildren; ++i ) { selection += GetSelectionState( children[ i ] ); if ( selection == SEL_SOME ) return SEL_SOME; // once we get to SEL_SOME, there we stay
}
const CDmaElementArray< CDmElement > &controls = pControlGroup->Controls(); int nControls = controls.Count(); for ( int i = 0; i < nControls; ++i ) { selection += GetSelectionState( controls[ i ] ); if ( selection == SEL_SOME ) return SEL_SOME; // once we get to SEL_SOME, there we stay
}
return selection; }
SelectionState_t CBaseAnimationSetControl::GetSelectionState( CDmElement *pControl, TransformComponent_t componentFlags /*= TRANSFORM_COMPONENT_ALL*/ ) const { Assert( pControl ); if ( ( pControl == NULL ) || !IsControlVisible( pControl ) ) return SEL_EMPTY;
TransformComponent_t nSelectionComponentFlags = GetSelectionComponentFlags( pControl ); TransformComponent_t nCombinedComponentFlags = nSelectionComponentFlags & componentFlags; if ( nCombinedComponentFlags == 0 ) return SEL_NONE;
if ( nCombinedComponentFlags == componentFlags ) return SEL_ALL;
return SEL_SOME; }
CDmElement *CBaseAnimationSetControl::GetMostRecentlySelectedControl() { int i = m_SelectionHistory.Tail(); if ( i == m_SelectionHistory.InvalidIndex() ) return NULL;
return m_SelectionHistory[ i ]->m_hControl; }
TransformComponent_t CBaseAnimationSetControl::GetSelectionComponentFlags( CDmElement *pControl ) const { if ( pControl == NULL ) return TRANSFORM_COMPONENT_NONE;
for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { const SelectionInfo_t *psi = m_SelectionHistory[ i ]; if ( psi->m_hControl.Get() == pControl ) return psi->m_nComponentFlags; } return TRANSFORM_COMPONENT_NONE; }
void SetPresetFromControl( CDmePreset *pPreset, CDmElement *pControl ) { CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( pControl );
if ( pTransformControl ) { CDmElement *pControlValue = pPreset->FindOrAddControlValue( pControl->GetName() ); if ( pControlValue == NULL ) return;
CDmeChannel *pPosChannel = pTransformControl->GetPositionChannel(); if ( pPosChannel ) { pControlValue->SetValue< Vector >( "valuePosition", pTransformControl->GetPosition() ); }
CDmeChannel *pRotChannel = pTransformControl->GetOrientationChannel(); if ( pRotChannel ) { pControlValue->SetValue< Quaternion >( "valueOrientation", pTransformControl->GetOrientation() ); } } else { // Stamp the control value
CDmElement *pControlValue = pPreset->FindOrAddControlValue( pControl->GetName() ); if ( IsStereoControl( pControl ) ) { pControlValue->RemoveAttribute( "value" ); pControlValue->SetValue< float >( "leftValue", pControl->GetValue< float >( "leftValue" ) ); pControlValue->SetValue< float >( "rightValue", pControl->GetValue< float >( "rightValue" ) ); } else { pControlValue->SetValue< float >( "value", pControl->GetValue< float >( "value" ) ); pControlValue->RemoveAttribute( "leftValue" ); pControlValue->RemoveAttribute( "rightValue" ); } } }
template < class T > void AddKeysToPreset( CDmePreset *pPreset, const char *pValuesAttrName, const char *pTimesAttrName, const CDmElement *pControl, const char *pChannelAttrName, DmeTime_t tHead, DmeTime_t tStart, DmeTime_t tEnd ) { if ( !pPreset || !pControl ) return;
CDmeChannel *pChannel = pControl->GetValueElement< CDmeChannel >( pChannelAttrName ); if ( !pChannel ) return;
CDmElement *pControlValue = pPreset->FindOrAddControlValue( pControl->GetName() );
CDmrArray< T > values( pControlValue, pValuesAttrName, true ); CDmrArray< DmeTime_t > times ( pControlValue, pTimesAttrName, true );
CDmeTypedLog< T > *pLog = CastElement< CDmeTypedLog< T > >( pChannel->GetLog() ); CDmeChannelsClip *pChannelsClip = FindReferringElement< CDmeChannelsClip >( pChannel, "channels" ); if ( !pLog || pLog->IsEmpty() || !pChannelsClip ) { times.AddToTail( DMETIME_ZERO );
T v; pChannel->GetInputValue( v ); values.AddToTail( v ); return; }
DmeTime_t tLocalStart = pChannelsClip->ToChildMediaTime( tStart, false ); DmeTime_t tLocalEnd = pChannelsClip->ToChildMediaTime( tEnd, false );
bool bFirst = true;
int nKeys = pLog->GetKeyCount(); for ( int i = 0; i < nKeys; ++i ) { DmeTime_t t = pLog->GetKeyTime( i ); if ( t < tLocalStart ) continue;
if ( bFirst ) { bFirst = false; times.AddToTail( tStart - tHead ); values.AddToTail( pLog->GetValue( tLocalStart ) ); if ( t == tLocalStart ) continue; }
if ( t >= tLocalEnd ) { int nTimes = times.Count(); DmeTime_t tLast = nTimes > 0 ? times[ nTimes - 1 ] : tEnd; if ( tLast <= tLocalEnd ) { times.AddToTail( tEnd - tHead ); values.AddToTail( pLog->GetValue( tLocalEnd ) ); } break; }
t = pChannelsClip->FromChildMediaTime( t, false );
times.AddToTail( t - tHead ); values.AddToTail( pLog->GetKeyValue( i ) ); } }
void SetPresetFromControlChannels( CDmePreset *pPreset, const CDmElement *pControl, DmeTime_t tHead, DmeTime_t tStart, DmeTime_t tEnd ) { if ( IsTransformControl( pControl ) ) { AddKeysToPreset< Vector >( pPreset, AS_VALUES_POSITION_ATTR, AS_TIMES_POSITION_ATTR, pControl, "positionChannel", tHead, tStart, tEnd ); AddKeysToPreset< Quaternion >( pPreset, AS_VALUES_ORIENTATION_ATTR, AS_TIMES_ORIENTATION_ATTR, pControl, "orientationChannel", tHead, tStart, tEnd ); }
if ( IsStereoControl( pControl ) ) { AddKeysToPreset< float >( pPreset, AS_VALUES_LEFT_ATTR, AS_TIMES_LEFT_ATTR, pControl, "leftvaluechannel", tHead, tStart, tEnd ); AddKeysToPreset< float >( pPreset, AS_VALUES_RIGHT_ATTR, AS_TIMES_RIGHT_ATTR, pControl, "rightvaluechannel", tHead, tStart, tEnd ); } else { AddKeysToPreset< float >( pPreset, AS_VALUES_ATTR, AS_TIMES_ATTR, pControl, "channel", tHead, tStart, tEnd ); } }
//-----------------------------------------------------------------------------
// Reads the current animation set control values, creates presets
//-----------------------------------------------------------------------------
void CBaseAnimationSetControl::SetPresetFromControls( const char *pPresetGroupName, const char *pPresetName ) { if ( !m_hFilmClip.Get() ) return;
CUndoScopeGuard guard( 0, NOTIFY_SETDIRTYFLAG, "Set Preset" );
for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { SelectionInfo_t *psi = m_SelectionHistory[ i ]; CDmeAnimationSet *pAnimSet = psi->m_hAnimSet; CDmElement *pControl = psi->m_hControl; if ( !pControl || !pAnimSet ) continue;
CDmePresetGroup *pPresetGroup = pAnimSet->FindPresetGroup( pPresetGroupName ); if ( !pPresetGroup ) continue;
CDmePreset *pPreset = pPresetGroup->FindPreset( pPresetName ); if ( !pPreset ) continue;
SetPresetFromControl( pPreset, pControl ); } }
void CBaseAnimationSetControl::AddPreset( const char *pPresetGroupName, const char *pPresetName, bool bAnimated ) { CUndoScopeGuard guard( 0, NOTIFY_SETDIRTYFLAG, "Add Preset" );
CAnimSetGroupAnimSetTraversal traversal( m_hFilmClip ); while ( CDmeAnimationSet *pAnimSet = traversal.Next() ) { SelectionState_t selstate = GetSelectionState( pAnimSet ); if ( selstate == SEL_EMPTY || selstate == SEL_NONE ) continue;
AddPreset( pAnimSet, pPresetGroupName, pPresetName, bAnimated ); } }
void CBaseAnimationSetControl::GetAnimatedPresetTimeParameters( DmeTime_t &tHead, DmeTime_t &tStart, DmeTime_t &tEnd ) { tHead = DMETIME_ZERO; tStart = DMETIME_MINTIME / 2; tEnd = DMETIME_MAXTIME / 2; }
void CBaseAnimationSetControl::AddPreset( CDmeAnimationSet *pAnimSet, const char *pPresetGroupName, const char *pPresetName, bool bAnimated ) { CDmePresetGroup *pPresetGroup = pAnimSet->FindOrAddPresetGroup( pPresetGroupName ); CDmePreset *pPreset = pPresetGroup->FindPreset( pPresetName ); if ( pPreset ) { Assert( 0 ); return; // TODO - should this preset be skipped, deleted and re-added, or somehow merged? (merging gives undesirable results if the control selections differ)
}
pPreset = pPresetGroup->FindOrAddPreset( pPresetName );
if ( bAnimated ) { DmeTime_t tHead, tStart, tEnd; GetAnimatedPresetTimeParameters( tHead, tStart, tEnd );
pPreset->SetValue( "animated", true );
for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { SelectionInfo_t *psi = m_SelectionHistory[ i ]; if ( psi->m_hAnimSet != pAnimSet ) continue;
// TODO - factor in componentFlags!!!
SetPresetFromControlChannels( pPreset, psi->m_hControl, tHead, tStart, tEnd ); } } else { for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { SelectionInfo_t *psi = m_SelectionHistory[ i ]; if ( psi->m_hAnimSet != pAnimSet ) continue;
// TODO - factor in componentFlags!!!
SetPresetFromControl( pPreset, psi->m_hControl ); } } }
//-----------------------------------------------------------------------------
// Can the control be snapped to
//-----------------------------------------------------------------------------
bool CBaseAnimationSetControl::IsControlSnapTarget( const CDmElement *pControl ) const { CDmeControlGroup *pGroup = CDmeControlGroup::FindGroupContainingControl( pControl ); if ( pGroup == NULL ) return false; return pGroup->IsSnappable(); }
//-----------------------------------------------------------------------------
// Is the control selectable in the viewport
//-----------------------------------------------------------------------------
bool CBaseAnimationSetControl::IsControlSelectable( const CDmElement *pControl ) const { CDmeControlGroup *pGroup = CDmeControlGroup::FindGroupContainingControl( pControl ); if ( pGroup == NULL ) return false;
return ( pGroup->IsVisible() && pGroup->IsSelectable() ); }
//-----------------------------------------------------------------------------
// Purpose: Determine if the specified control is hidden
//-----------------------------------------------------------------------------
bool CBaseAnimationSetControl::IsControlVisible( const CDmElement *pControl ) const { if ( IsShowingHiddenControls() ) return true;
CDmeControlGroup *pGroup = CDmeControlGroup::FindGroupContainingControl( pControl ); if ( pGroup ) { return pGroup->IsVisible(); }
return false; }
//-----------------------------------------------------------------------------
// Determine if the specified control group is visible
//-----------------------------------------------------------------------------
bool CBaseAnimationSetControl::IsControlGroupVisible( const CDmeControlGroup *pGroup ) const { if ( IsShowingHiddenControls() ) return true;
return pGroup->IsVisible(); }
void CBaseAnimationSetControl::UpdatePreviewSliderValues() { CBaseAnimSetAttributeSliderPanel *pAttributeSlider = m_pEditor->GetAttributeSlider(); if ( !pAttributeSlider ) return;
float flBalanceSliderValue = pAttributeSlider->GetBalanceSliderValue();
CBaseAnimSetPresetFaderPanel *presets = m_pEditor->GetPresetFader(); if ( !presets ) return;
FaderPreview_t fader; presets->GetPreviewFader( fader );
bool nameChanged = fader.name && ( m_PreviousPresetSlider.IsEmpty() || Q_stricmp( m_PreviousPresetSlider.Get(), fader.name ) ); bool beingDraggedChanged = fader.isbeingdragged != m_bPresetPreviouslyDragged; bool previewKeyChanged = fader.holdingPreviewKey != m_bPreviouslyHoldingPresetPreviewKey; bool bFaderChanged = nameChanged || beingDraggedChanged || previewKeyChanged; bool faderAmountChanged = fader.amount != m_flPreviousPresetAmount;
// Update values for procedural presets, but not if we are already actively dragging, otherwise the
// target value of the head preset can change during the drag if the head is within the falloff region.
if ( fader.holdingPreviewKey || ( fader.isbeingdragged && beingDraggedChanged ) || bFaderChanged ) { presets->UpdateProceduralPresetSlider( fader.values ); }
// logic moved from CAnimSetAttributeSliderPanel for simplicity - another pass may remove a fair amount of it entirely
bool previewKeyPressed = fader.holdingPreviewKey && previewKeyChanged; bool startedDrag = fader.isbeingdragged && beingDraggedChanged; bool newControl = nameChanged; m_bPresetSliderChanged = newControl || previewKeyPressed || startedDrag;
m_PreviousPresetSlider = fader.name; m_flPreviousPresetAmount = fader.amount; m_bPresetPreviouslyDragged = fader.isbeingdragged; m_bPreviouslyHoldingPresetPreviewKey = fader.holdingPreviewKey;
bool shiftDown = input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT );
int c = pAttributeSlider->GetSliderCount(); for ( int i = 0; i < c; ++i ) { CAttributeSlider *slider = pAttributeSlider->GetSlider( i ); if ( !slider->IsVisible() ) continue;
CDmElement *pControl = slider->GetControl(); if ( !pControl ) continue;
bool bTransform = slider->IsTransform();
if ( m_ActiveAttributeSlider.Get() == slider && !slider->IsDragging() && shiftDown ) { // The preset stuff shouldn't be active when we're holding the preview key over the raw attribute sliders!!!
Assert( !fader.isbeingdragged );
AttributeValue_t dest; if ( !bTransform ) { int x, y; input()->GetCursorPos( x, y ); slider->ScreenToLocal( x, y ); float flEstimatedValue = slider->EstimateValueAtPos( x, y );
dest.m_pValue[ ANIM_CONTROL_VALUE ] = flEstimatedValue; dest.m_pValue[ ANIM_CONTROL_VALUE_LEFT ] = flEstimatedValue; dest.m_pValue[ ANIM_CONTROL_VALUE_RIGHT ] = flEstimatedValue; } else { slider->GetValue( ANIM_CONTROL_TXFORM_POSITION, dest.m_Vector ); slider->GetValue( ANIM_CONTROL_TXFORM_ORIENTATION, dest.m_Quaternion ); }
// If we aren't over any of the preset sliders, then we need to be able to ramp down to the current value, too
slider->SetPreview( dest, dest ); continue; }
if ( !fader.values ) continue;
bool simple = fader.isbeingdragged || !fader.holdingPreviewKey; if ( bFaderChanged || fader.isbeingdragged ) { int idx = fader.values->Find( pControl->GetHandle() ); const AttributeValue_t &previewin = idx == fader.values->InvalidIndex() ? slider->GetValue() : fader.values->Element( idx ); const AttributeValue_t ¤t = slider->GetValue(); AttributeValue_t preview; BlendValues( bTransform, &preview, current, previewin, 1.0f, flBalanceSliderValue );
// If being dragged, slam to current value right away
if ( simple ) { slider->SetPreview( preview, preview ); } else { // Apply the left-right balance to the target
AttributeValue_t dest; BlendValues( bTransform, &dest, current, preview, fader.amount ); slider->SetPreview( dest, preview ); } }
if ( faderAmountChanged || fader.isbeingdragged || fader.holdingPreviewKey ) { slider->UpdateFaderAmount( fader.amount ); } } }
void CBaseAnimationSetControl::UpdatePreviewSliderTimes() { CBaseAnimSetAttributeSliderPanel *pAttributeSlider = m_pEditor->GetAttributeSlider(); if ( !pAttributeSlider ) return;
bool ctrlDown = input()->IsKeyDown( KEY_LCONTROL ) || input()->IsKeyDown( KEY_RCONTROL ); bool shiftDown = input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT ); if ( ctrlDown ) { int mx, my; input()->GetCursorPos( mx, my ); bool bInside = pAttributeSlider->IsWithin( mx, my ); if ( !bInside ) { shiftDown = false; ctrlDown = false; }
VPANEL topMost = input()->GetMouseOver(); if ( topMost && !ipanel()->HasParent( topMost, pAttributeSlider->GetVPanel() ) ) { shiftDown = false; ctrlDown = false; } }
bool previewing = ( m_bPreviouslyHoldingPresetPreviewKey ) || ( m_ActiveAttributeSlider.Get() && shiftDown ); bool changingvalues = ( m_bPresetPreviouslyDragged ) || ( m_ActiveAttributeSlider.Get() && m_ActiveAttributeSlider->IsDragging() );
// If control is being pressed or this slider is the currently active dominant slider set
// this slider to be the new dominant slider. This will cause the dominant slider to be
// selected when you press control but not to be lost if the control key is released.
int newDominantSlider = -1; if ( m_ActiveAttributeSlider.Get() && m_ActiveAttributeSlider->IsDragging() ) { if ( ctrlDown || ( m_nDominantSlider >= 0 && pAttributeSlider->GetSlider( m_nDominantSlider ) == m_ActiveAttributeSlider.Get() ) ) { newDominantSlider = pAttributeSlider->FindSliderIndexForControl( m_ActiveAttributeSlider->GetControl() ); } }
// If the dominant slider has changed update starting values that are used to determine what
// values the other sliders should fade from as the value of the dominant slider increases.
if ( newDominantSlider != m_nDominantSlider ) { UpdateDominantSliderStartValues( newDominantSlider < 0 ); m_nDominantSlider = newDominantSlider; }
CAttributeSlider *dragSlider = m_ActiveAttributeSlider && m_ActiveAttributeSlider->IsDragging() ? m_ActiveAttributeSlider.Get() : NULL; pAttributeSlider->UpdateControlSetMode( changingvalues, previewing, dragSlider ); }
bool CBaseAnimationSetControl::IsPresetFaderBeingDragged() const { return m_bPresetPreviouslyDragged; }
float CBaseAnimationSetControl::GetDominantSliderStartValue( int nSliderIndex, AnimationControlType_t type ) { return m_DominantSliderStartValues[ nSliderIndex ].m_pValue[ type ]; }
//-----------------------------------------------------------------------------
// Purpose: Save the current values of the visible sliders to the dominant
// slider start value or restore slider values to the value saved before if
// the restoreSliderValues flag is true.
//-----------------------------------------------------------------------------
void CBaseAnimationSetControl::UpdateDominantSliderStartValues( bool restoreSliderValues ) { CBaseAnimSetAttributeSliderPanel *pAttributeSlider = m_pEditor->GetAttributeSlider(); if ( !pAttributeSlider ) return;
int nSliders = pAttributeSlider->GetSliderCount();
// If the start values have not been saved yet the array will need to be allocated.
if ( m_DominantSliderStartValues.Count() != nSliders ) { Assert( m_DominantSliderStartValues.Count() == 0 ); m_DominantSliderStartValues.SetCount( nSliders );
// Can't restore the values of the sliders to the
// start values if the start values have not been set.
if ( restoreSliderValues ) { Assert( restoreSliderValues == false ); return; } }
// Loop through all of the sliders and update the values of the visible sliders.
for ( int i = 0; i < nSliders; ++i ) { CAttributeSlider *pSlider = pAttributeSlider->GetSlider( i ); if ( pSlider == NULL ) continue;
if ( !pSlider->IsVisible() ) continue;
if ( restoreSliderValues ) { if ( pSlider->IsDragging() == false ) { pSlider->SetValue( m_DominantSliderStartValues[ i ] ); } } else { m_DominantSliderStartValues[ i ] = pSlider->GetValue(); } } }
//-----------------------------------------------------------------------------
// Purpose: Get the start and current values for the dominant slider based on
// the first active control.
//-----------------------------------------------------------------------------
void CBaseAnimationSetControl::GetDominantSliderValues( float &flDomStart, float &flDomValue ) { flDomStart = 0.0f; flDomValue = 0.0f;
if ( m_nDominantSlider < 0 ) return;
CBaseAnimSetAttributeSliderPanel *pAttributeSlider = m_pEditor->GetAttributeSlider(); if ( !pAttributeSlider ) return;
CAttributeSlider *pDominantSlider = pAttributeSlider->GetSlider( m_nDominantSlider ); if ( pDominantSlider == NULL ) return;
if ( pDominantSlider->IsTransform() ) return;
AnimationControlType_t type = pDominantSlider->IsStereo() ? ANIM_CONTROL_VALUE_RIGHT : ANIM_CONTROL_VALUE; flDomStart = max( 0.0f, min( 1.0f, GetDominantSliderStartValue( m_nDominantSlider, type ) ) ); flDomValue = max( 0.0f, min( 1.0f, pDominantSlider->GetValue( type ) ) ); }
void CBaseAnimationSetControl::ApplyPreset( float flScale, AttributeDict_t& values ) { CBaseAnimSetAttributeSliderPanel *pAttributeSlider = m_pEditor->GetAttributeSlider(); if ( !pAttributeSlider ) return;
bool bChanged = false; int c = pAttributeSlider->GetSliderCount(); for ( int i = 0; i < c; ++i ) { CAttributeSlider *slider = pAttributeSlider->GetSlider( i ); if ( !slider || !slider->IsVisible() ) continue;
int idx = values.Find( slider->GetControl()->GetHandle() ); const AttributeValue_t &target = idx == values.InvalidIndex() ? slider->GetValue() : values[ idx ]; const AttributeValue_t ¤t = slider->GetValue();
// Apply the left-right balance to the target
AttributeValue_t blend; BlendValues( slider->IsTransform(), &blend, current, target, flScale, pAttributeSlider->GetBalanceSliderValue() ); slider->SetValue( blend ); bChanged = true; }
if ( bChanged ) { pAttributeSlider->UpdatePreview( "ApplyPreset\n" ); } }
template< class T > void CBaseAnimationSetControl::ApplyTransformSliderValue( CAttributeSlider *pSlider, CDmeTransformControl *pTranformControl, bool bUsePreviewValue, bool bForce, bool &valuesChanged, AnimationControlType_t type ) { CDmAttribute *pAttr = NULL; CDmeChannel *pChannel = NULL; if ( type == ANIM_CONTROL_TXFORM_POSITION ) { pAttr = pTranformControl->GetPositionAttr(); pChannel = pTranformControl->GetPositionChannel(); } else if ( type == ANIM_CONTROL_TXFORM_ORIENTATION ) { pAttr = pTranformControl->GetOrientationAttr(); pChannel = pTranformControl->GetOrientationChannel(); }
Assert( pAttr ); if ( !pAttr ) return; Assert( pChannel );
// Figure out what to do based on the channel's mode
ChannelMode_t mode = pChannel ? pChannel->GetMode() : CM_PASS; bool bPushSlidersIntoScene = ( mode == CM_PASS || mode == CM_RECORD ); bool bPullSlidersFromScene = ( mode == CM_PLAY );
if ( bPullSlidersFromScene ) { T value = pAttr->GetValue< T >(); pChannel->GetCurrentPlaybackValue< T >( value ); pSlider->SetValue( type, value ); pAttr->SetValue( value ); } else if ( bPushSlidersIntoScene ) { T value; if ( bUsePreviewValue ) { pSlider->GetPreview( type, value ); } else { pSlider->GetValue( type, value ); } if ( pAttr->GetValue< T >() != value || bForce ) { // The txform manipulator drives the UpdatePreview call, so don't do it twice unless
// we are just dialing in a preset (bForce == true)
valuesChanged = bForce; T currentValue = pAttr->GetValue< T >(); T maskedValue = MaskValue( value, currentValue, pSlider->VisibleComponents() ); pAttr->SetValue( maskedValue ); } } }
void CBaseAnimationSetControl::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 ) { CDmAttribute *pAttr = pControl->GetAttribute( pValueAttrName, AT_FLOAT ); Assert( pAttr ); if ( !pAttr ) return;
CDmeChannel *pChannel = pControl->GetValueElement< CDmeChannel >( pChannelAttrName ); Assert( pChannel );
// Figure out what to do based on the channel's mode
ChannelMode_t mode = pChannel ? pChannel->GetMode() : CM_PASS; bool bPushSlidersIntoScene = ( mode == CM_PASS || mode == CM_RECORD ); bool bPullSlidersFromScene = ( mode == CM_PLAY );
if ( bPullSlidersFromScene ) { // If it's actively being manipulated, the UI will be up to date
if ( pSlider->IsDragging() ) return;
// Drive value setting based on the output data
float flValue = pControl->GetValue< float >( DEFAULT_FLOAT_ATTR ); if ( pChannel->GetCurrentPlaybackValue< float >( flValue ) ) { pAttr->SetValue( flValue ); } else { flValue = pAttr->GetValue< float >(); } pSlider->SetValue( type, flValue ); } else if ( bPushSlidersIntoScene ) { float flValue = bUsePreviewValue ? pSlider->GetPreview( type ) : pSlider->GetValue( type );
// If there is an active dominant slider then all other visible
// sliders, should scale down based on the value of the dominant slider.
if ( ( m_nDominantSlider >= 0 ) && pSlider->IsVisible() && !bUsePreviewValue ) { if ( m_nDominantSlider != si ) { float flSliderStart = GetDominantSliderStartValue( si, type ); float flRange = 1.0f - flDomStart; float flScale = ( flRange > 0 ) ? ( max( 0.0f, flDomValue - flDomStart ) / flRange ) : 0.0f; float flTargetValue = pControl->GetValue< float >( DEFAULT_FLOAT_ATTR ); flValue = flSliderStart * ( 1.0f - flScale ) + flTargetValue * flScale; pSlider->SetValue( type, flValue ); } }
if ( pAttr->GetValue< float >() != flValue || bForce ) { valuesChanged = true; pAttr->SetValue( flValue ); } } }
bool CBaseAnimationSetControl::ApplySliderValues( bool bForce ) { CBaseAnimSetAttributeSliderPanel *pAttributeSlider = m_pEditor->GetAttributeSlider(); if ( !pAttributeSlider ) return false;
if ( !bForce ) { bForce = m_bPresetPreviouslyDragged; }
CDisableUndoScopeGuard guard;
float flDomStart = 0; float flDomValue = 0; GetDominantSliderValues( flDomStart, flDomValue );
bool valuesChanged = false;
int nSliders = pAttributeSlider->GetSliderCount(); for ( int si = 0; si < nSliders; ++si ) { CAttributeSlider *pSlider = pAttributeSlider->GetSlider( si ); Assert( pSlider ); if ( !pSlider || !pSlider->IsVisible() ) continue;
CDmElement *pControl = pSlider->GetControl(); if ( !pControl ) continue;
bool shiftDown = input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT ); bool bPreviewingAttributeSlider = m_ActiveAttributeSlider.Get() == pSlider && !pSlider->IsDragging() && shiftDown; bool bMouseOverPresetSlider = m_pEditor->GetPresetFader()->GetActivePresetSlider() != NULL; bool bUsePreviewValue = m_bPreviouslyHoldingPresetPreviewKey || bPreviewingAttributeSlider || ( bForce && bMouseOverPresetSlider );
CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( pControl ); if ( pTransformControl ) { if ( pSlider->IsOrientation() ) { ApplyTransformSliderValue< Quaternion >( pSlider, pTransformControl, bUsePreviewValue, bForce, valuesChanged, ANIM_CONTROL_TXFORM_ORIENTATION ); } else { ApplyTransformSliderValue< Vector >( pSlider, pTransformControl, bUsePreviewValue, bForce, valuesChanged, ANIM_CONTROL_TXFORM_POSITION ); } } else if ( IsStereoControl( pControl ) ) { ApplySliderValueWithDominance( pSlider, si, flDomStart, flDomValue, pControl, bUsePreviewValue, bForce, valuesChanged, ANIM_CONTROL_VALUE_LEFT, "leftvaluechannel", "leftValue" ); ApplySliderValueWithDominance( pSlider, si, flDomStart, flDomValue, pControl, bUsePreviewValue, bForce, valuesChanged, ANIM_CONTROL_VALUE_RIGHT, "rightvaluechannel", "rightValue" ); } else { ApplySliderValueWithDominance( pSlider, si, flDomStart, flDomValue, pControl, bUsePreviewValue, bForce, valuesChanged, ANIM_CONTROL_VALUE, "channel", "value" ); } }
guard.Release();
return valuesChanged; }
void CBaseAnimationSetControl::SetActiveAttributeSlider( CAttributeSlider *pSlider ) { m_ActiveAttributeSlider = pSlider; }
void CBaseAnimationSetControl::EnsureCrossfadePresetControlValues( int nCount ) { m_crossfadePresetControlValues.RemoveAll();
int nOldCount = m_crossfadePresetControlValues.Count(); for ( int i = nOldCount; i < nCount; ++i ) { m_crossfadePresetControlValues.AddToTail( CreateElement< CDmElement >( "procedural preset control value", DMFILEID_INVALID ) ); } }
void CBaseAnimationSetControl::ProceduralPreset_UpdateCrossfade( AttributeDict_t *pPresetValuesLookup, int nPresetType ) { switch ( nPresetType ) { case PROCEDURAL_PRESET_HEAD_CROSSFADE: case PROCEDURAL_PRESET_IN_CROSSFADE: case PROCEDURAL_PRESET_OUT_CROSSFADE: return; // can only update these in the sfm (or an app that knows about current time (head) and time selection (in/out)
}
CDisableUndoScopeGuard guard;
bool bIsDefaultPreset = nPresetType == PROCEDURAL_PRESET_DEFAULT_CROSSFADE; bool bSinglePreset = !bIsDefaultPreset; // the only other presets this code deals with are zero, half, one
EnsureCrossfadePresetControlValues( bSinglePreset ? 1 : m_SelectionHistory.Count() );
if ( bSinglePreset ) { float flValue = 0.0f; switch ( nPresetType ) { case PROCEDURAL_PRESET_ZERO_CROSSFADE: flValue = 0.0f; break; case PROCEDURAL_PRESET_HALF_CROSSFADE: flValue = 0.5f; break; case PROCEDRUAL_PRESET_ONE_CROSSFADE: flValue = 1.0f; break; }
CDmElement *pPresetControlValue = m_crossfadePresetControlValues[ 0 ]; pPresetControlValue->SetValue( "valuePosition", vec3_origin ); pPresetControlValue->SetValue( "valueOrientation", quat_identity ); pPresetControlValue->SetValue( "leftValue", flValue ); pPresetControlValue->SetValue( "rightValue", flValue ); pPresetControlValue->SetValue( "value", flValue ); }
pPresetValuesLookup->RemoveAll();
int pcvi = -1; for ( int i = m_SelectionHistory.Head(); i != m_SelectionHistory.InvalidIndex(); i = m_SelectionHistory.Next( i ) ) { SelectionInfo_t *psi = m_SelectionHistory[ i ]; CDmElement *pControl = psi->m_hControl; if ( !pControl ) continue;
CDmElement *pPresetControlValue = m_crossfadePresetControlValues[ bSinglePreset ? 0 : ++pcvi ];
DmElementHandle_t handle; handle = pControl->GetHandle(); int idx = pPresetValuesLookup->Find( handle ); if ( idx == pPresetValuesLookup->InvalidIndex() ) { idx = pPresetValuesLookup->Insert( handle ); } AnimationControlAttributes_t &val = pPresetValuesLookup->Element( idx ); val.Clear();
CDmeTransformControl *pTransformControl = CastElement< CDmeTransformControl >( pControl ); if ( pTransformControl ) { if ( psi->AreAnyPositionComponentsSelected() ) { CDmAttribute *pValueAttribute = pPresetControlValue->AddAttribute( "valuePosition", AT_VECTOR3 ); Assert( pValueAttribute ); if ( !pValueAttribute ) continue;
if ( !bSinglePreset ) { pValueAttribute->SetValue( pTransformControl->GetDefaultPosition() ); }
val.m_pValueAttribute[ ANIM_CONTROL_TXFORM_POSITION ] = pValueAttribute; val.m_Vector = pValueAttribute->GetValue< Vector >(); }
if ( psi->AreAnyOrientationComponentsSelected() ) { CDmAttribute *pValueAttribute = pPresetControlValue->AddAttribute( "valueOrientation", AT_QUATERNION ); Assert( pValueAttribute ); if ( !pValueAttribute ) continue;
if ( !bSinglePreset ) { pValueAttribute->SetValue( pTransformControl->GetDefaultOrientation() ); }
val.m_pValueAttribute[ ANIM_CONTROL_TXFORM_ORIENTATION ] = pValueAttribute; val.m_Quaternion = pValueAttribute->GetValue< Quaternion >(); } } else if ( IsStereoControl( pControl ) ) { CDmAttribute *pLeftValueAttribute = pPresetControlValue->AddAttribute( "leftValue", AT_FLOAT ); CDmAttribute *pRightValueAttribute = pPresetControlValue->AddAttribute( "rightValue", AT_FLOAT ); Assert( pLeftValueAttribute && pRightValueAttribute ); if ( !pLeftValueAttribute || !pRightValueAttribute ) continue;
if ( !bSinglePreset ) { float flDefaultValue = pControl->GetValue< float >( DEFAULT_FLOAT_ATTR ); pLeftValueAttribute ->SetValue( flDefaultValue ); pRightValueAttribute->SetValue( flDefaultValue ); }
val.m_pValueAttribute[ ANIM_CONTROL_VALUE_LEFT ] = pLeftValueAttribute; val.m_pValue [ ANIM_CONTROL_VALUE_LEFT ] = pLeftValueAttribute->GetValue< float >(); val.m_pValueAttribute[ ANIM_CONTROL_VALUE_RIGHT ] = pRightValueAttribute; val.m_pValue [ ANIM_CONTROL_VALUE_RIGHT ] = pRightValueAttribute->GetValue< float >(); } else { CDmAttribute *pValueAttribute = pPresetControlValue->AddAttribute( "value", AT_FLOAT ); Assert( pValueAttribute ); if ( !pValueAttribute ) continue;
if ( !bSinglePreset ) { pValueAttribute->SetValue( pControl->GetValue< float >( DEFAULT_FLOAT_ATTR ) ); }
val.m_pValueAttribute[ ANIM_CONTROL_VALUE ] = pValueAttribute; val.m_pValue [ ANIM_CONTROL_VALUE ] = pValueAttribute->GetValue< float >(); } } }
|