summaryrefslogtreecommitdiff
path: root/public/movieobjects/dmelog.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /public/movieobjects/dmelog.h
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'public/movieobjects/dmelog.h')
-rw-r--r--public/movieobjects/dmelog.h918
1 files changed, 918 insertions, 0 deletions
diff --git a/public/movieobjects/dmelog.h b/public/movieobjects/dmelog.h
new file mode 100644
index 0000000..a0e85b0
--- /dev/null
+++ b/public/movieobjects/dmelog.h
@@ -0,0 +1,918 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#ifndef DMELOG_H
+#define DMELOG_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "datamodel/dmelement.h"
+#include "datamodel/dmattribute.h"
+#include "datamodel/dmattributevar.h"
+#include "datamodel/dmehandle.h"
+#include "interpolatortypes.h"
+#include "movieobjects/timeutils.h"
+#include "movieobjects/dmetimeselectiontimes.h"
+
+class IUniformRandomStream;
+
+template < class T > class CDmeTypedLog;
+
+enum
+{
+ FILTER_SMOOTH = 0,
+ FILTER_JITTER,
+ FILTER_SHARPEN,
+ FILTER_SOFTEN,
+
+ NUM_FILTERS
+};
+
+enum RecordingMode_t
+{
+ RECORD_PRESET = 0, // Preset/fader slider being dragged
+ RECORD_ATTRIBUTESLIDER, // Single attribute slider being dragged
+};
+
+#define DMELOG_DEFAULT_THRESHHOLD 0.0001f
+
+class DmeLog_TimeSelection_t
+{
+public:
+ DmeLog_TimeSelection_t() :
+ m_flIntensity( 1.0f ),
+ m_bAttachedMode( true ),
+ m_bTimeAdvancing( false ),
+ m_bResampleMode( true ),
+ m_nResampleInterval( DmeTime_t( .05f ) ),// 50 msec sampling interval by default
+ m_flThreshold( DMELOG_DEFAULT_THRESHHOLD ),
+ m_pPresetValue( 0 ),
+ m_RecordingMode( RECORD_PRESET )
+ {
+ m_nTimes[ TS_LEFT_FALLOFF ] = m_nTimes[ TS_LEFT_HOLD ] =
+ m_nTimes[ TS_RIGHT_HOLD ] = m_nTimes[ TS_RIGHT_FALLOFF ] = DmeTime_t( 0 );
+ m_nFalloffInterpolatorTypes[ 0 ] = m_nFalloffInterpolatorTypes[ 1 ] = INTERPOLATE_LINEAR_INTERP;
+ }
+
+ inline void ResetTimeAdvancing()
+ {
+ // Reset the time advancing flag
+ m_bTimeAdvancing = false;
+ }
+
+ inline void StartTimeAdvancing()
+ {
+ m_bTimeAdvancing = true;
+ }
+
+ inline bool IsTimeAdvancing() const
+ {
+ return m_bTimeAdvancing;
+ }
+
+ inline RecordingMode_t GetRecordingMode() const
+ {
+ return m_RecordingMode;
+ }
+
+ void SetRecordingMode( RecordingMode_t mode )
+ {
+ m_RecordingMode = mode;
+ }
+
+ float GetAmountForTime( DmeTime_t curtime ) const;
+ float AdjustFactorForInterpolatorType( float factor, int side ) const;
+
+ // NOTE: See DmeTimeSelectionTimes_t for return values, 0 means before, 1= left fallof, 2=hold, 3=right falloff, 4=after
+ int ComputeRegionForTime( DmeTime_t curtime ) const;
+
+ DmeTime_t m_nTimes[ TS_TIME_COUNT ];
+ int m_nFalloffInterpolatorTypes[ 2 ];
+ DmeTime_t m_nResampleInterval; // Only used if m_bResampleMode is true
+ float m_flIntensity; // How much to drive values toward m_HeadValue (generally 1.0f)
+ float m_flThreshold;
+ CDmAttribute* m_pPresetValue;
+
+ bool m_bAttachedMode : 1; // Is the current time "attached" to the head position
+
+ // Adds new, evenly spaced samples based on m_nResampleInterval
+ // Also adds zero intensity samples at the falloff edges
+ bool m_bResampleMode : 1;
+
+private:
+ bool m_bTimeAdvancing : 1; // Has time ever been advancing
+ RecordingMode_t m_RecordingMode;
+};
+
+class CDmeChannel;
+class CDmeChannelsClip;
+class CDmeFilmClip;
+class CDmeLog;
+class CDmeLogLayer;
+
+struct LayerSelectionData_t
+{
+ LayerSelectionData_t();
+ void Release();
+
+ CDmeHandle< CDmeChannel > m_hChannel;
+ CDmeHandle< CDmeChannelsClip > m_hOwner;
+ CDmeHandle< CDmeFilmClip > m_hShot;
+ CDmeHandle< CDmeLog > m_hLog;
+ DmAttributeType_t m_DataType;
+ int m_nDuration;
+ int m_nHoldTimes[ 2 ];
+ DmeTime_t m_tStartOffset;
+
+ // This is dynamic and needs to be released
+ struct DataLayer_t
+ {
+ DataLayer_t( float frac, CDmeLogLayer *layer );
+
+ float m_flStartFraction;
+ CDmeHandle< CDmeLogLayer, true > m_hData;
+ };
+
+ CUtlVector< DataLayer_t > m_vecData;
+};
+
+//-----------------------------------------------------------------------------
+// CDmeLogLayer - abstract base class
+//-----------------------------------------------------------------------------
+abstract_class CDmeLogLayer : public CDmElement
+{
+ friend class CDmeLog;
+
+ DEFINE_ELEMENT( CDmeLogLayer, CDmElement );
+
+public:
+ virtual void CopyLayer( const CDmeLogLayer *src ) = 0;
+ virtual void CopyPartialLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps ) = 0;
+ virtual void ExplodeLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps, DmeTime_t tResampleInterval ) = 0;
+ virtual void InsertKeyFromLayer( DmeTime_t keyTime, const CDmeLogLayer *src, DmeTime_t srcKeyTime ) = 0;
+
+ DmeTime_t GetBeginTime() const;
+ DmeTime_t GetEndTime() const;
+ int GetKeyCount() const;
+
+ // Returns the index of a key closest to this time, within tolerance
+ // NOTE: Insertion or removal may change this index!
+ // Returns -1 if the time isn't within tolerance.
+ int FindKeyWithinTolerance( DmeTime_t time, DmeTime_t nTolerance );
+
+ // Returns the type of attribute being logged
+ virtual DmAttributeType_t GetDataType() const = 0;
+
+ // Sets a key, removes all keys after this time
+ virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT ) = 0;
+ virtual bool SetDuplicateKeyAtTime( DmeTime_t time ) = 0;
+ // This inserts a key using the current values to construct the proper value for the time
+ virtual int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT ) = 0;
+
+ // Sets the interpolated value of the log at the specified time into the attribute
+ virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const = 0;
+
+ virtual float GetComponent( DmeTime_t time, int componentIndex ) const = 0;
+
+ // Returns the time at which a particular key occurs
+ DmeTime_t GetKeyTime( int nKeyIndex ) const;
+ void SetKeyTime( int nKeyIndex, DmeTime_t keyTime );
+
+ // Scale + bias key times
+ void ScaleBiasKeyTimes( double flScale, DmeTime_t nBias );
+
+ // Removes a single key by index
+ virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 ) = 0;
+
+ // Removes all keys
+ virtual void ClearKeys() = 0;
+
+ virtual bool IsConstantValued() const = 0;
+ virtual void RemoveRedundantKeys() = 0;
+ virtual void RemoveRedundantKeys( float threshold ) = 0;
+
+ // resampling and filtering
+ virtual void Resample( DmeFramerate_t samplerate ) = 0;
+ virtual void Filter( int nSampleRadius ) = 0;
+ virtual void Filter2( DmeTime_t sampleRadius ) = 0;
+
+ virtual void SetOwnerLog( CDmeLog *owner ) = 0;
+ CDmeLog *GetOwnerLog();
+ const CDmeLog *GetOwnerLog() const;
+
+ bool IsUsingCurveTypes() const;
+ int GetDefaultCurveType() const;
+
+ // Override curvetype for specific key
+ void SetKeyCurveType( int nKeyIndex, int curveType );
+ int GetKeyCurveType( int nKeyIndex ) const;
+
+ // Validates that all keys are correctly sorted in time
+ bool ValidateKeys() const;
+
+ // Removes all keys outside the specified time range
+ void RemoveKeysOutsideRange( DmeTime_t tStart, DmeTime_t tEnd );
+
+protected:
+ int FindKey( DmeTime_t time ) const;
+
+ void OnUsingCurveTypesChanged();
+
+ CDmeLog *m_pOwnerLog;
+
+ mutable int m_lastKey;
+ CDmaArray< int > m_times;
+ CDmaArray< int > m_CurveTypes;
+};
+
+template< class T >
+CDmeLogLayer *CreateLayer( CDmeTypedLog< T > *ownerLog );
+
+
+//-----------------------------------------------------------------------------
+// CDmeLogLayer - abstract base class
+//-----------------------------------------------------------------------------
+abstract_class CDmeCurveInfo : public CDmElement
+{
+ DEFINE_ELEMENT( CDmeCurveInfo, CDmElement );
+
+public:
+ // Global override for all keys unless overriden by specific key
+ void SetDefaultCurveType( int curveType );
+ int GetDefaultCurveType() const;
+
+ void SetMinValue( float val );
+ float GetMinValue() const;
+ void SetMaxValue( float val );
+ float GetMaxValue() const;
+
+protected:
+ CDmaVar< int > m_DefaultCurveType;
+
+ CDmaVar< float > m_MinValue;
+ CDmaVar< float > m_MaxValue;
+};
+
+template <class T > class CDmeTypedLogLayer;
+
+//-----------------------------------------------------------------------------
+// CDmeLog - abstract base class
+//-----------------------------------------------------------------------------
+abstract_class CDmeLog : public CDmElement
+{
+ DEFINE_ELEMENT( CDmeLog, CDmElement );
+
+public:
+ int FindLayerForTime( DmeTime_t time ) const;
+ int FindLayerForTimeSkippingTopmost( DmeTime_t time ) const;
+ void FindLayersForTime( DmeTime_t time, CUtlVector< int >& list ) const;
+
+ virtual void FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params ) = 0; // in attached, timeadvancing mode, we need to blend out of the final sample over the fadeout interval
+ virtual void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const CDmAttribute *pAttr, uint index = 0 ) = 0;
+ virtual void FilterUsingTimeSelection( IUniformRandomStream *random, float flScale, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer ) = 0;
+ virtual void FilterUsingTimeSelection( IUniformRandomStream *random, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff ) = 0;
+ virtual void StaggerUsingTimeSelection( const DmeLog_TimeSelection_t& params, DmeTime_t tStaggerAmount, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer ) = 0;
+ virtual void RevealUsingTimeSelection( const DmeLog_TimeSelection_t &params, CDmeLogLayer *savedLayer ) = 0;
+ virtual void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t &params ) = 0;
+ virtual void BlendLayersUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, bool bUseBaseLayerSamples, DmeTime_t tStartOffset ) = 0;
+ virtual void BlendTimesUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, DmeTime_t tStartOffset ) = 0;
+ virtual void PasteAndRescaleSamples( const CDmeLogLayer *src, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion ) = 0;
+ virtual void PasteAndRescaleSamples( const CDmeLogLayer *pBaseLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion ) = 0;
+ virtual void BuildNormalizedLayer( CDmeTypedLogLayer< float > *target ) = 0;
+ virtual void BuildCorrespondingLayer( const CDmeLogLayer *pReferenceLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer ) = 0;
+
+ int GetTopmostLayer() const;
+ int GetNumLayers() const;
+ CDmeLogLayer *GetLayer( int index );
+ const CDmeLogLayer *GetLayer( int index ) const;
+
+ DmeTime_t GetBeginTime() const;
+ DmeTime_t GetEndTime() const;
+ int GetKeyCount() const;
+
+ bool IsEmpty() const;
+
+ // Returns the index of a key closest to this time, within tolerance
+ // NOTE: Insertion or removal may change this index!
+ // Returns -1 if the time isn't within tolerance.
+ virtual int FindKeyWithinTolerance( DmeTime_t time, DmeTime_t nTolerance ) = 0;
+
+ // Returns the type of attribute being logged
+ virtual DmAttributeType_t GetDataType() const = 0;
+
+ // Sets a key, removes all keys after this time
+ virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT ) = 0;
+ virtual bool SetDuplicateKeyAtTime( DmeTime_t time ) = 0;
+ virtual int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT ) = 0;
+ // Sets the interpolated value of the log at the specified time into the attribute
+ virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const = 0;
+ virtual void GetValueSkippingTopmostLayer( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const = 0;
+
+ virtual float GetComponent( DmeTime_t time, int componentIndex ) const = 0;
+
+ // Returns the time at which a particular key occurs
+ virtual DmeTime_t GetKeyTime( int nKeyIndex ) const = 0;
+ virtual void SetKeyTime( int nKeyIndex, DmeTime_t keyTime ) = 0;
+
+ // Override curvetype for specific key
+ void SetKeyCurveType( int nKeyIndex, int curveType );
+ int GetKeyCurveType( int nKeyIndex ) const;
+
+ // Removes a single key by index
+ virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 ) = 0;
+
+ // Removes all keys within the time range, returns true if keys were removed
+ bool RemoveKeys( DmeTime_t tStartTime, DmeTime_t tEndTime );
+
+ // Removes all keys
+ virtual void ClearKeys() = 0;
+
+ // Scale + bias key times
+ void ScaleBiasKeyTimes( double flScale, DmeTime_t nBias );
+
+ virtual float GetValueThreshold() const = 0;
+ virtual void SetValueThreshold( float thresh ) = 0;
+ virtual bool IsConstantValued() const = 0;
+ virtual void RemoveRedundantKeys() = 0;
+ virtual void RemoveRedundantKeys( float threshold ) = 0;
+
+ // resampling and filtering
+ virtual void Resample( DmeFramerate_t samplerate ) = 0;
+ virtual void Filter( int nSampleRadius ) = 0;
+ virtual void Filter2( DmeTime_t sampleRadius ) = 0;
+
+ // Creates a log of a requested type
+ static CDmeLog *CreateLog( DmAttributeType_t type, DmFileId_t fileid );
+
+ virtual CDmeLogLayer *AddNewLayer() = 0;
+ enum
+ {
+ FLATTEN_NODISCONTINUITY_FIXUP = (1<<0), // Don't add "helper" samples to preserve discontinuities. This occurs when the time selection is "detached" from the head position
+ FLATTEN_SPEW = (1<<1),
+ };
+ virtual void FlattenLayers( float threshold, int flags ) = 0;
+
+ // Only used by undo system!!!
+ virtual void AddLayerToTail( CDmeLogLayer *layer ) = 0;
+ virtual CDmeLogLayer *RemoveLayerFromTail() = 0;
+ virtual CDmeLogLayer *RemoveLayer( int iLayer ) = 0;
+
+
+ // Resolve
+ virtual void Resolve();
+
+ // curve info helpers
+ bool IsUsingCurveTypes() const;
+ const CDmeCurveInfo *GetCurveInfo() const;
+ CDmeCurveInfo *GetCurveInfo();
+ virtual CDmeCurveInfo *GetOrCreateCurveInfo() = 0;
+ virtual void SetCurveInfo( CDmeCurveInfo *pCurveInfo ) = 0;
+
+ // accessors for CurveInfo data
+ int GetDefaultCurveType() const;
+
+ // FIXME - this should really be in the CurveInfo
+ // but the animset editor currently asks for these, without having set a curveinfo...
+ void SetMinValue( float val );
+ void SetMaxValue( float val );
+ float GetMinValue() const;
+ float GetMaxValue() const;
+
+ virtual bool HasDefaultValue() const = 0;
+
+
+protected:
+// int FindKey( DmeTime_t time ) const;
+
+ void OnUsingCurveTypesChanged();
+
+ virtual void OnAttributeChanged( CDmAttribute *pAttribute );
+
+ CDmaElementArray< CDmeLogLayer > m_Layers;
+ CDmaElement< CDmeCurveInfo > m_CurveInfo;
+};
+
+
+
+//-----------------------------------------------------------------------------
+// CDmeTypedCurveInfo - implementation class for all logs
+//-----------------------------------------------------------------------------
+template< class T >
+class CDmeTypedCurveInfo : public CDmeCurveInfo
+{
+ DEFINE_ELEMENT( CDmeTypedCurveInfo, CDmeCurveInfo );
+
+public:
+ // For "faceposer" style left/right edges, this controls whether interpolators try to mimic faceposer left/right edge behavior
+ void SetUseEdgeInfo( bool state );
+ bool IsUsingEdgeInfo() const;
+
+ void SetEdgeInfo( int edge, bool active, const T& val, int curveType );
+ void GetEdgeInfo( int edge, bool& active, T& val, int& curveType ) const;
+
+ void SetDefaultEdgeZeroValue( const T& val );
+ const T& GetDefaultEdgeZeroValue() const;
+
+ void SetRightEdgeTime( DmeTime_t time );
+ DmeTime_t GetRightEdgeTime() const;
+
+ bool IsEdgeActive( int edge ) const;
+ void GetEdgeValue( int edge, T& value ) const;
+
+ int GetEdgeCurveType( int edge ) const;
+ void GetZeroValue( int side, T& val ) const;
+
+protected:
+ CDmaVar< bool > m_bUseEdgeInfo;
+ // Array of 2 for left/right edges...
+ CDmaVar< bool > m_bEdgeActive[ 2 ];
+ CDmaVar< T > m_EdgeValue[ 2 ];
+ CDmaVar< int > m_EdgeCurveType[ 2 ];
+ CDmaVar< int > m_RightEdgeTime;
+ CDmaVar< T > m_DefaultEdgeValue;
+};
+
+
+// forward declaration
+template< class T > class CDmeTypedLog;
+
+
+//-----------------------------------------------------------------------------
+// CDmeTypedLogLayer - implementation class for all logs
+//-----------------------------------------------------------------------------
+template< class T >
+class CDmeTypedLogLayer : public CDmeLogLayer
+{
+ DEFINE_ELEMENT( CDmeTypedLogLayer, CDmeLogLayer );
+
+public:
+ virtual void CopyLayer( const CDmeLogLayer *src );
+ virtual void CopyPartialLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps );
+ virtual void ExplodeLayer( const CDmeLogLayer *src, DmeTime_t startTime, DmeTime_t endTime, bool bRebaseTimestamps, DmeTime_t tResampleInterval );
+ virtual void InsertKeyFromLayer( DmeTime_t keyTime, const CDmeLogLayer *src, DmeTime_t srcKeyTime );
+
+ // Finds a key within tolerance, or adds one. Unlike SetKey, this will *not* delete keys after the specified time
+ int FindOrAddKey( DmeTime_t nTime, DmeTime_t nTolerance, const T& value, int curveType = CURVE_DEFAULT );
+
+ // Sets a key, removes all keys after this time
+ void SetKey( DmeTime_t time, const T& value, int curveType = CURVE_DEFAULT );
+ // This inserts a key using the current values to construct the proper value for the time
+ virtual int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT );
+
+ void SetKeyValue( int nKey, const T& value );
+
+ const T& GetValue( DmeTime_t time ) const;
+
+ const T& GetKeyValue( int nKeyIndex ) const;
+ const T& GetValueSkippingKey( int nKeyToSkip ) const;
+
+ // This inserts a key. Unlike SetKey, this will *not* delete keys after the specified time
+ int InsertKey( DmeTime_t nTime, const T& value, int curveType = CURVE_DEFAULT );
+
+ // inherited from CDmeLog
+ virtual void ClearKeys();
+ virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT );
+ virtual bool SetDuplicateKeyAtTime( DmeTime_t time );
+ virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const;
+ virtual float GetComponent( DmeTime_t time, int componentIndex ) const;
+ virtual DmAttributeType_t GetDataType() const;
+ virtual bool IsConstantValued() const;
+ virtual void RemoveRedundantKeys();
+ virtual void RemoveRedundantKeys( float threshold );
+
+ virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 );
+ virtual void Resample( DmeFramerate_t samplerate );
+ virtual void Filter( int nSampleRadius );
+ virtual void Filter2( DmeTime_t sampleRadius );
+
+ void RemoveKeys( DmeTime_t starttime );
+
+ // curve info helpers
+ const CDmeTypedCurveInfo< T > *GetTypedCurveInfo() const;
+ CDmeTypedCurveInfo< T > *GetTypedCurveInfo();
+
+ bool IsUsingEdgeInfo() const;
+ void GetEdgeInfo( int edge, bool& active, T& val, int& curveType ) const;
+ const T& GetDefaultEdgeZeroValue() const;
+ DmeTime_t GetRightEdgeTime() const;
+
+ void SetOwnerLog( CDmeLog *owner );
+
+ CDmeTypedLog< T > *GetTypedOwnerLog();
+ const CDmeTypedLog< T > *GetTypedOwnerLog() const;
+
+protected:
+
+ int GetEdgeCurveType( int edge ) const;
+ void GetZeroValue( int side, T& val ) const;
+
+ void GetValueUsingCurveInfo( DmeTime_t time, T& out ) const;
+ void GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, T& out ) const;
+ void GetBoundedSample( int keyindex, DmeTime_t& time, T& val, int& curveType ) const;
+
+ void CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< T > *output );
+
+ friend CDmeTypedLog< T >;
+
+protected:
+ CDmaArray< T > m_values;
+};
+
+
+//-----------------------------------------------------------------------------
+// CDmeTypedLog - implementation class for all logs
+//-----------------------------------------------------------------------------
+template< class T >
+class CDmeTypedLog : public CDmeLog
+{
+ DEFINE_ELEMENT( CDmeTypedLog, CDmeLog );
+
+public:
+
+ virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem );
+
+ CDmeTypedLogLayer< T > *GetLayer( int index );
+ const CDmeTypedLogLayer< T > *GetLayer( int index ) const;
+
+ void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const T& value );
+ void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const CDmAttribute *pAttr, uint index = 0 );
+ void FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params ); // in attached, timeadvancing mode, we need to blend out of the final sample over the fadeout interval
+ void FilterUsingTimeSelection( IUniformRandomStream *random, float flScale, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer );
+ void FilterUsingTimeSelection( IUniformRandomStream *random, const DmeLog_TimeSelection_t& params, int filterType, bool bResample, bool bApplyFalloff );
+ void StaggerUsingTimeSelection( const DmeLog_TimeSelection_t& params, DmeTime_t tStaggerAmount, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer );
+ void RevealUsingTimeSelection( const DmeLog_TimeSelection_t &params, CDmeLogLayer *savedLayer );
+ void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t &params );
+ void BlendLayersUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, bool bUseBaseLayerSamples, DmeTime_t tStartOffset );
+ void BlendTimesUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t &params, DmeTime_t tStartOffset );
+
+ virtual void PasteAndRescaleSamples( const CDmeLogLayer *src, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion );
+ virtual void PasteAndRescaleSamples( const CDmeLogLayer *pBaseLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion );
+ virtual void BuildCorrespondingLayer( const CDmeLogLayer *pReferenceLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer );
+
+ virtual void BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
+
+ // Finds a key within tolerance, or adds one. Unlike SetKey, this will *not* delete keys after the specified time
+ int FindOrAddKey( DmeTime_t nTime, DmeTime_t nTolerance, const T& value, int curveType = CURVE_DEFAULT );
+
+ // Sets a key, removes all keys after this time
+ void SetKey( DmeTime_t time, const T& value, int curveType = CURVE_DEFAULT );
+ int InsertKeyAtTime( DmeTime_t nTime, int curveType = CURVE_DEFAULT );
+ bool ValuesDiffer( const T& a, const T& b ) const;
+ const T& GetValue( DmeTime_t time ) const;
+ const T& GetValueSkippingTopmostLayer( DmeTime_t time ) const;
+
+ const T& GetKeyValue( int nKeyIndex ) const;
+
+ // This inserts a key. Unlike SetKey, this will *not* delete keys after the specified time
+ int InsertKey( DmeTime_t nTime, const T& value, int curveType = CURVE_DEFAULT );
+
+ // inherited from CDmeLog
+ virtual void ClearKeys();
+ virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, int curveType = CURVE_DEFAULT );
+ virtual bool SetDuplicateKeyAtTime( DmeTime_t time );
+ virtual void GetValue( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const;
+ virtual void GetValueSkippingTopmostLayer( DmeTime_t time, CDmAttribute *pAttr, uint index = 0 ) const;
+ virtual float GetComponent( DmeTime_t time, int componentIndex ) const;
+ virtual DmAttributeType_t GetDataType() const;
+ virtual float GetValueThreshold() const { return m_threshold; }
+ virtual void SetValueThreshold( float thresh );
+ virtual bool IsConstantValued() const;
+ virtual void RemoveRedundantKeys();
+ virtual void RemoveRedundantKeys( float threshold );
+ virtual void RemoveKey( int nKeyIndex, int nNumKeysToRemove = 1 );
+ virtual void Resample( DmeFramerate_t samplerate );
+ virtual void Filter( int nSampleRadius );
+ virtual void Filter2( DmeTime_t sampleRadius );
+
+ virtual int FindKeyWithinTolerance( DmeTime_t time, DmeTime_t nTolerance );
+ virtual DmeTime_t GetKeyTime( int nKeyIndex ) const;
+ virtual void SetKeyTime( int nKeyIndex, DmeTime_t keyTime );
+
+ virtual CDmeLogLayer *AddNewLayer();
+ virtual void FlattenLayers( float threshhold, int flags );
+
+ // Only used by undo system!!!
+ virtual void AddLayerToTail( CDmeLogLayer *layer );
+ virtual CDmeLogLayer *RemoveLayerFromTail();
+ virtual CDmeLogLayer *RemoveLayer( int iLayer );
+
+ // curve info helpers
+ const CDmeTypedCurveInfo< T > *GetTypedCurveInfo() const;
+ CDmeTypedCurveInfo< T > *GetTypedCurveInfo();
+ virtual CDmeCurveInfo *GetOrCreateCurveInfo();
+ virtual void SetCurveInfo( CDmeCurveInfo *pCurveInfo );
+
+ // For "faceposer" style left/right edges, this controls whether interpolators try to mimic faceposer left/right edge behavior
+ void SetUseEdgeInfo( bool state );
+ bool IsUsingEdgeInfo() const;
+
+ void SetEdgeInfo( int edge, bool active, const T& val, int curveType );
+ void GetEdgeInfo( int edge, bool& active, T& val, int& curveType ) const;
+
+ void SetDefaultEdgeZeroValue( const T& val );
+ const T& GetDefaultEdgeZeroValue() const;
+
+ void SetRightEdgeTime( DmeTime_t time );
+ DmeTime_t GetRightEdgeTime() const;
+
+ bool IsEdgeActive( int edge ) const;
+ void GetEdgeValue( int edge, T& value ) const;
+
+ int GetEdgeCurveType( int edge ) const;
+ void GetZeroValue( int side, T& val ) const;
+
+ T ClampValue( const T& value );
+
+ void SetDefaultValue( const T& value );
+ const T& GetDefaultValue() const;
+ bool HasDefaultValue() const;
+ void ClearDefaultValue();
+
+ static void SetDefaultValueThreshold( float thresh );
+ static float GetDefaultValueThreshold();
+
+ static float s_defaultThreshold;
+
+protected:
+ void RemoveKeys( DmeTime_t starttime );
+
+ void _StampKeyAtHeadResample( DmeTime_t tHeadPosition, const DmeLog_TimeSelection_t & params, const T& value, bool bSkipToHead, bool bClearPreviousKeys );
+ void _StampKeyAtHeadFilteredByTimeSelection( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t & params, const T& value );
+ void _StampKeyFilteredByTimeSelection( CDmeTypedLogLayer< T > *pWriteLayer, DmeTime_t t, const DmeLog_TimeSelection_t &params, const T& value, bool bForce = false );
+
+protected:
+ // this really only makes sense for some of our subclasses, basically those which have float data
+ // anything else's threshhold is almost certainly 0, and that class just ignores m_threshold
+ float m_threshold;
+
+ CDmaVar< bool > m_UseDefaultValue;
+ CDmaVar< T > m_DefaultValue;
+};
+
+
+//-----------------------------------------------------------------------------
+// Template methods
+//-----------------------------------------------------------------------------
+template< class T >
+DmAttributeType_t CDmeTypedLogLayer<T>::GetDataType() const
+{
+ return CDmAttributeInfo< T >::AttributeType();
+}
+
+template< class T >
+bool CDmeTypedLogLayer<T>::IsConstantValued() const
+{
+ if ( m_values.Count() < 2 )
+ return true;
+
+ if ( m_values.Count() == 2 && !GetTypedOwnerLog()->ValuesDiffer( m_values[ 0 ], m_values[ 1 ] ) )
+ return true;
+
+ // we're throwing away duplicate values during recording, so this is generally correct
+ // although there are paths to set keys that don't use the duplicate test, so it's not 100%
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Template methods
+//-----------------------------------------------------------------------------
+template< class T >
+DmAttributeType_t CDmeTypedLog<T>::GetDataType() const
+{
+ return CDmAttributeInfo< T >::AttributeType();
+}
+
+template< class T >
+void CDmeTypedLog<T>::SetDefaultValueThreshold( float thresh )
+{
+ s_defaultThreshold = thresh;
+}
+
+template< class T >
+float CDmeTypedLog<T>::GetDefaultValueThreshold()
+{
+ return s_defaultThreshold;
+}
+
+template< class T >
+void CDmeTypedLog<T>::SetValueThreshold( float thresh )
+{
+ m_threshold = thresh;
+}
+
+template< class T >
+bool CDmeTypedLog<T>::IsConstantValued() const
+{
+ int c = m_Layers.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ if ( !GetLayer( i )->IsConstantValued() )
+ return false;
+ }
+
+ return true;
+}
+
+template< class T >
+void CDmeTypedLog<T>::RemoveRedundantKeys()
+{
+ int bestLayer = GetTopmostLayer();
+ if ( bestLayer < 0 )
+ return;
+
+ GetLayer( bestLayer )->RemoveRedundantKeys();
+}
+
+template< class T >
+inline float Normalize( const T& val )
+{
+ Assert( 0 );
+ return 0.5f;
+}
+
+// AT_INT
+// AT_FLOAT
+// AT_VECTOR*
+
+template<>
+inline float Normalize( const bool& val )
+{
+ return val ? 1.0f : 0.0f;
+}
+
+template<>
+inline float Normalize( const Color& val )
+{
+ float sum = 0.0f;
+ for ( int i = 0 ; i < 4; ++i )
+ {
+ sum += val[ i ];
+ }
+ sum /= 4.0f;
+ return clamp( sum / 255.0f, 0.0f, 1.0f );
+}
+
+template<>
+inline float Normalize( const QAngle& val )
+{
+ float sum = 0.0f;
+ for ( int i = 0 ; i < 3; ++i )
+ {
+ float ang = val[ i ];
+ if ( ang < 0.0f )
+ {
+ ang += 360.0f;
+ }
+
+ sum += ang;
+ }
+ return clamp( ( sum / 3.0f ) / 360.0f, 0.0f, 1.0f );
+}
+
+template<>
+inline float Normalize( const Quaternion& val )
+{
+ QAngle angle;
+ QuaternionAngles( val, angle );
+ return Normalize( angle );
+}
+
+template< class T >
+inline void CDmeTypedLog< T >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *pTarget )
+{
+ Assert( pTarget );
+ Assert( GetDataType() != AT_FLOAT );
+
+ CDmeTypedLogLayer< T > *pBaseLayer = static_cast< CDmeTypedLogLayer< T > * >( GetLayer( 0 ) );
+ if ( !pBaseLayer )
+ return;
+
+ int kc = pBaseLayer->GetKeyCount();
+ for ( int i = 0; i < kc; ++i )
+ {
+ DmeTime_t tKeyTime = pBaseLayer->GetKeyTime( i );
+ T keyValue = pBaseLayer->GetKeyValue( i );
+ float flNormalized = Normalize( keyValue );
+
+ pTarget->InsertKey( tKeyTime, flNormalized );
+ }
+
+ if ( HasDefaultValue() )
+ {
+ pTarget->GetTypedOwnerLog()->SetDefaultValue( Normalize( GetDefaultValue() ) );
+ }
+}
+
+// Generic implementations all stubbed
+// Forward declare specific typed instantiations for float types
+
+template< class T > T CDmeTypedLog< T >::ClampValue( const T& value ) { return value; }
+template<> float CDmeTypedLog< float >::ClampValue( const float& value );
+
+
+template< class T > void CDmeTypedCurveInfo< T >::GetZeroValue( int side, T& val ) const{ Assert( 0 ); }
+template< class T > bool CDmeTypedCurveInfo< T >::IsEdgeActive( int edge ) const{ Assert( 0 ); return false; }
+template< class T > void CDmeTypedCurveInfo< T >::GetEdgeValue( int edge, T &value ) const{ Assert( 0 ); }
+
+template<> void CDmeTypedCurveInfo< float >::GetZeroValue( int side, float& val ) const;
+template<> bool CDmeTypedCurveInfo< float >::IsEdgeActive( int edge ) const;
+template<> void CDmeTypedCurveInfo< float >::GetEdgeValue( int edge, float &value ) const;
+
+template<> void CDmeTypedCurveInfo< Vector >::GetZeroValue( int side, Vector& val ) const;
+template<> void CDmeTypedCurveInfo< Quaternion >::GetZeroValue( int side, Quaternion& val ) const;
+
+template< class T > void CDmeTypedLogLayer< T >::GetValueUsingCurveInfo( DmeTime_t time, T& out ) const { Assert( 0 ); }
+template< class T > void CDmeTypedLogLayer< T >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, T& out ) const { Assert( 0 ); }
+template<> void CDmeTypedLogLayer< float >::GetValueUsingCurveInfo( DmeTime_t time, float& out ) const;
+template<> void CDmeTypedLogLayer< float >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, float& out ) const;
+
+template<> void CDmeTypedLogLayer< Vector >::GetValueUsingCurveInfo( DmeTime_t time, Vector& out ) const;
+template<> void CDmeTypedLogLayer< Vector >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, Vector& out ) const;
+
+template<> void CDmeTypedLogLayer< Quaternion >::GetValueUsingCurveInfo( DmeTime_t time, Quaternion& out ) const;
+template<> void CDmeTypedLogLayer< Quaternion >::GetValueUsingCurveInfoSkippingKey( int nKeyToSkip, Quaternion& out ) const;
+
+template<class T> void CDmeTypedLogLayer< T >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< T > *output );
+template<> void CDmeTypedLogLayer< bool >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< bool > *output );
+template<> void CDmeTypedLogLayer< int >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< int > *output );
+template<> void CDmeTypedLogLayer< Color >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< Color > *output );
+template<> void CDmeTypedLogLayer< Quaternion >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< Quaternion > *output );
+template<> void CDmeTypedLogLayer< VMatrix >::CurveSimplify_R( float thresholdSqr, int startPoint, int endPoint, CDmeTypedLogLayer< VMatrix > *output );
+
+template<> void CDmeTypedLog< Vector >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
+template<> void CDmeTypedLog< Vector2D >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
+template<> void CDmeTypedLog< Vector4D >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
+template<> void CDmeTypedLog< float >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
+template<> void CDmeTypedLog< int >::BuildNormalizedLayer( CDmeTypedLogLayer< float > *target );
+
+//template<> void CDmeTypedLog< float >::FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params );
+//template<> void CDmeTypedLog< bool >::_StampKeyAtHeadResample( const DmeLog_TimeSelection_t& params, const bool& value ) { Assert( 0 ); }
+
+//-----------------------------------------------------------------------------
+// typedefs for convenience (and so the user-supplied names match the programmer names)
+//-----------------------------------------------------------------------------
+typedef CDmeTypedLog<int> CDmeIntLog;
+typedef CDmeTypedLog<float> CDmeFloatLog;
+typedef CDmeTypedLog<bool> CDmeBoolLog;
+typedef CDmeTypedLog<Color> CDmeColorLog;
+typedef CDmeTypedLog<Vector2D> CDmeVector2Log;
+typedef CDmeTypedLog<Vector> CDmeVector3Log;
+typedef CDmeTypedLog<Vector4D> CDmeVector4Log;
+typedef CDmeTypedLog<QAngle> CDmeQAngleLog;
+typedef CDmeTypedLog<Quaternion> CDmeQuaternionLog;
+typedef CDmeTypedLog<VMatrix> CDmeVMatrixLog;
+typedef CDmeTypedLog<CUtlString> CDmeStringLog;
+
+//-----------------------------------------------------------------------------
+// typedefs for convenience (and so the user-supplied names match the programmer names)
+//-----------------------------------------------------------------------------
+typedef CDmeTypedLogLayer<int> CDmeIntLogLayer;
+typedef CDmeTypedLogLayer<float> CDmeFloatLogLayer;
+typedef CDmeTypedLogLayer<bool> CDmeBoolLogLayer;
+typedef CDmeTypedLogLayer<Color> CDmeColorLogLayer;
+typedef CDmeTypedLogLayer<Vector2D> CDmeVector2LogLayer;
+typedef CDmeTypedLogLayer<Vector> CDmeVector3LogLayer;
+typedef CDmeTypedLogLayer<Vector4D> CDmeVector4LogLayer;
+typedef CDmeTypedLogLayer<QAngle> CDmeQAngleLogLayer;
+typedef CDmeTypedLogLayer<Quaternion> CDmeQuaternionLogLayer;
+typedef CDmeTypedLogLayer<VMatrix> CDmeVMatrixLogLayer;
+typedef CDmeTypedLogLayer<CUtlString> CDmeStringLogLayer;
+
+//-----------------------------------------------------------------------------
+// typedefs for convenience (and so the user-supplied names match the programmer names)
+//-----------------------------------------------------------------------------
+typedef CDmeTypedCurveInfo<int> CDmeIntCurveInfo;
+typedef CDmeTypedCurveInfo<float> CDmeFloatCurveInfo;
+typedef CDmeTypedCurveInfo<bool> CDmeBoolCurveInfo;
+typedef CDmeTypedCurveInfo<Color> CDmeColorCurveInfo;
+typedef CDmeTypedCurveInfo<Vector2D> CDmeVector2CurveInfo;
+typedef CDmeTypedCurveInfo<Vector> CDmeVector3CurveInfo;
+typedef CDmeTypedCurveInfo<Vector4D> CDmeVector4CurveInfo;
+typedef CDmeTypedCurveInfo<QAngle> CDmeQAngleCurveInfo;
+typedef CDmeTypedCurveInfo<Quaternion> CDmeQuaternionCurveInfo;
+typedef CDmeTypedCurveInfo<VMatrix> CDmeVMatrixCurveInfo;
+typedef CDmeTypedCurveInfo<CUtlString> CDmeStringCurveInfo;
+
+// the following types are not supported
+// AT_ELEMENT,
+// AT_VOID,
+// AT_OBJECTID,
+// <all array types>
+
+//-----------------------------------------------------------------------------
+// Helpers for particular types of log layers
+//-----------------------------------------------------------------------------
+void GenerateRotationLog( CDmeQuaternionLogLayer *pLayer, const Vector &vecAxis, DmeTime_t pTime[4], float pRevolutionsPerSec[4] );
+
+// rotates a position log
+void RotatePositionLog( CDmeVector3LogLayer *pPositionLog, const matrix3x4_t& matrix );
+
+// rotates an orientation log
+void RotateOrientationLog( CDmeQuaternionLogLayer *pOrientationLog, const matrix3x4_t& matrix, bool bPreMultiply );
+
+
+#endif // DMELOG_H