//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. ======= // // Purpose: // //============================================================================= #ifndef DMELOG_H #define DMELOG_H #ifdef _WIN32 #pragma once #endif #include #include "datamodel/dmelement.h" #include "datamodel/dmattribute.h" #include "datamodel/dmattributevar.h" #include "datamodel/dmehandle.h" #include "datamodel/dmattributevar.h" #include "interpolatortypes.h" #include "movieobjects/dmetimeselectiontimes.h" #include "movieobjects/proceduralpresets.h" class IUniformRandomStream; template < class T > class CDmeTypedLog; enum { FILTER_SMOOTH = 0, FILTER_JITTER, FILTER_SHARPEN, FILTER_SOFTEN, FILTER_INOUT, NUM_FILTERS }; enum RecordingMode_t { RECORD_PRESET = 0, // Preset/fader slider being dragged RECORD_ATTRIBUTESLIDER, // Single attribute slider being dragged }; // Transform write mode types, specify how a transform is to apply to existing values. enum TransformWriteMode_t { TRANSFORM_WRITE_MODE_HOLD, TRANSFORM_WRITE_MODE_OFFSET, TRANSFORM_WRITE_MODE_OVERWRITE, TRANSFORM_WRITE_MODE_TRANSFORM }; enum LogComponents_t { LOG_COMPONENTS_NONE = 0, LOG_COMPONENTS_X = ( 1 << 0 ), LOG_COMPONENTS_Y = ( 1 << 1 ), LOG_COMPONENTS_Z = ( 1 << 2 ), LOG_COMPONENTS_ALL = LOG_COMPONENTS_X | LOG_COMPONENTS_Y | LOG_COMPONENTS_Z, }; DEFINE_ENUM_BITWISE_OPERATORS( LogComponents_t ) enum SegmentInterpolation_t { SEGMENT_INTERPOLATE, SEGMENT_NOINTERPOLATE, }; static const unsigned int LOG_MAX_COMPONENTS = 4; #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_nResampleInterval( DmeTime_t( .05f ) ),// 50 msec sampling interval by default m_flThreshold( DMELOG_DEFAULT_THRESHHOLD ), m_pPresetValue( 0 ), m_pPresetTimes( 0 ), m_pOldHeadValue( 0 ), m_OldHeadValueIndex( -1 ), m_tHeadPosition( 0 ), m_TransformWriteMode( TRANSFORM_WRITE_MODE_OVERWRITE ), m_bManipulateInFalloff( false ), m_nComponentFlags( LOG_COMPONENTS_ALL ), 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; m_bInfinite[ 0 ] = m_bInfinite[ 1 ] = false; } 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 TimeSelectionTimes_t for return values, 0 means before, 1= left falloff, 2=hold, 3=right falloff, 4=after int ComputeRegionForTime( DmeTime_t curtime ) const; TimeSelection_t m_nTimes; int m_nFalloffInterpolatorTypes[ 2 ]; DmeTime_t m_nResampleInterval; float m_flIntensity; // How much to drive values toward m_HeadValue (generally 1.0f) float m_flThreshold; const CDmAttribute* m_pPresetValue; // Pointer to the attribute storing the value to be used for presets const CDmAttribute* m_pPresetTimes; // Pointer to the attribute storing the times to be used for animated presets CDmAttribute* m_pOldHeadValue; // Pointer to the attribute storing the original head value int m_OldHeadValueIndex; // Array index of the original head value within the specified attribute DmeTime_t m_tHeadPosition; // Time position of the head TransformWriteMode_t m_TransformWriteMode; // Specification of how values are to be written into the log with respect to the existing values bool m_bAttachedMode : 1; // Is the current time "attached" to the head position bool m_bManipulateInFalloff : 1; // Should the rotation be applied as a transform to the position instead of interpolating LogComponents_t m_nComponentFlags; // Flag indicating which components of the log should be modified bool m_bInfinite[ 2 ]; private: bool m_bTimeAdvancing : 1; // Has time ever been advancing RecordingMode_t m_RecordingMode; }; class CDmeChannel; class CDmeChannelsClip; class CDmeClip; class CDmeFilmClip; class CDmeLog; class CDmeLogLayer; struct DmeClipStack_t; 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; DmeTime_t m_nTimes[ TS_TIME_COUNT ]; // This is dynamic and needs to be released struct DataLayer_t { DataLayer_t( float frac, CDmeLogLayer *layer ); float m_flStartFraction; CDmeHandle< CDmeLogLayer, HT_STRONG > m_hData; }; CUtlVector< DataLayer_t > m_vecData; }; struct DmeLogTransformParams_t { DmeLogTransformParams_t() : m_RotationLocal( quat_identity ) , m_RotationParent( quat_identity ) , m_Pivot( vec3_origin ) , m_nProceduralType( PROCEDURAL_PRESET_NOT ) , m_pRotationLog( NULL ) { SetIdentityMatrix( m_Transform ); } matrix3x4_t m_Transform; Quaternion m_RotationLocal; Quaternion m_RotationParent; Vector m_Pivot; int m_nProceduralType; CDmeTypedLog< Quaternion > *m_pRotationLog; }; //----------------------------------------------------------------------------- // 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( bool bAllowInfinite ) const; DmeTime_t GetEndTime( bool bAllowInfinite ) const; int GetKeyCount() const; void ScaleSampleTimes( float scale ); // 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, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, 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; virtual void TrimKeys( DmeTime_t tStartTime, DmeTime_t tEndTime ) = 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 ); // Scale the keys within the source time selection to fill the destination time selection, keys outside the time selection will be shifted void RescaleSamplesInTimeSelection( const TimeSelection_t &srcTimeSeleciton, const TimeSelection_t &dstTimeSelection ); // 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( bool bKeepEnds ) = 0; virtual void RemoveRedundantKeys( float threshold, bool bKeepEnds ) = 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; // Layers may extend to infinity on the left or right, if so the start / end time will be min / max void SetInfinite( bool bLeftInfinite, bool bRightInfinite ); bool IsLeftInfinite() { return m_bLeftInfinite; } bool IsRightInfinite() { return m_bRightInfinite; } // 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 ); SegmentInterpolation_t GetSegmentInterpolationSetting( int nKeyIndex ) const; SegmentInterpolation_t GetSegmentInterpolationSetting( int nStartKeyIndex, int nEndKeyIndex ) const; //return SEGMENT_NOINTERPOLATE if any segment checked is non-interpolated SegmentInterpolation_t GetSegmentInterpolationSetting( DmeTime_t time ) const; SegmentInterpolation_t GetSegmentInterpolationSetting( DmeTime_t startTime, DmeTime_t endTime, bool bExcludeActualEndTimeKey ) const; //return SEGMENT_NOINTERPOLATE if any segment checked is non-interpolated // Masks all keys within the time range, returns true if keys were modified virtual bool MaskKeyRange( DmeTime_t tStartTime, DmeTime_t tEndTime, LogComponents_t nComponentFlags, bool bInfiniteLeft = false, bool bInfiniteRight = false ) = 0; virtual void MakeRoomForSamplesMaskedSubcomponents( CDmeLogLayer *pBaseLayer, DmeTime_t tStart, DmeTime_t tEnd, DmeTime_t tLeftShift, DmeTime_t tRightShift, LogComponents_t nComponents ) = 0; virtual void Compress() = 0; virtual void Decompress() = 0; virtual bool IsCompressed() const = 0; virtual size_t GetCompressedSize() const = 0; virtual size_t GetDataSize() const = 0; protected: int FindKey( DmeTime_t time ) const; void OnUsingCurveTypesChanged(); CDmeLog *m_pOwnerLog; mutable int m_lastKey; bool m_bLeftInfinite; bool m_bRightInfinite; CDmaArray< DmeTime_t > m_times; CDmaArray< int > m_CurveTypes; CDmaArray< bool > m_NonInterpolatedSegments; }; 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 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; int FindLayerForTimeBelowLayer( DmeTime_t time, int topLayerIndex ) const; void FindLayersForTime( DmeTime_t time, CUtlVector< int >& list ) const; virtual void FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params ) = 0; // in attached, time advancing 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 DmeLogTransformParams_t &transformParams, const CDmAttribute *pAttr, uint arrayIndex = 0, bool bTimeFilter = true, int layerIndex = -1 ) = 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 ¶ms, const CDmeLogLayer *pTargetLayer ) = 0; virtual void RecaleAndRevealUsingTimeSelection( const DmeLog_TimeSelection_t ¶ms, TimeSelection_t &sourceTimeSelection, const CDmeLogLayer *pTargetLayer ) = 0; virtual void GenerateSplineUsingTimeSelection( const DmeLog_TimeSelection_t& params, const CUtlVector< DmeTime_t > &sortedSplineKeyTimes, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer ) = 0; virtual void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t ¶ms, int baseLayer = 0 ) = 0; virtual void BlendLayersUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t ¶ms, bool bUseBaseLayerSamples, bool bUseFalloff, bool bSelectionSamples, DmeTime_t tStartOffset ) = 0; virtual void BlendLayersUsingTimeSelection( const CDmeLogLayer *baseLayer, const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t ¶ms, bool bUseBaseLayerSamples, DmeTime_t tStartOffset ) = 0; virtual void BlendTimesUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t ¶ms, DmeTime_t tStartOffset, bool bFeatherBlendInFalloff ) = 0; virtual void PasteAndRescaleSamples( const CDmeLogLayer *src, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion, bool bReverse ) = 0; virtual void PasteAndRescaleSamples( const CDmeLogLayer *pBaseLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion, bool bReverse ) = 0; virtual void BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ) = 0; virtual void BuildCorrespondingLayer( const CDmeLogLayer *pReferenceLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer ) = 0; virtual void HoldOrReleaseUsingTimeSelection( const DmeLog_TimeSelection_t& params, bool bHold, const CDmeLogLayer *pBaseLayer, CDmeLogLayer *pWriteLayer ) = 0; virtual void SteadyUsingTimeSelection( const DmeLog_TimeSelection_t& params, const CDmeLogLayer *pBaseLayer, CDmeLogLayer *pWriteLayer ) = 0; virtual void CopySamplesFromPreset( const DmeLog_TimeSelection_t& params, const CDmAttribute *pPresetValue, const CDmAttribute *pPresetTimes, DmeTime_t tLogTimeOffset, const CDmeChannelsClip *pChannelsClip, const CDmeLogLayer *pBaseLayer, CDmeLogLayer *pWriteLayer ) = 0; // preset samples are in shot time, not log time 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; void ScaleSampleTimes( float scale ); virtual void ClearAndAddSampleAtTime( DmeTime_t time ) = 0; // 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, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, 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 ); // Add keys at tStartTime and tEndTime, and remove all keys outside the range void TrimKeys( 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 bool IsConstantValued() const = 0; virtual void RemoveRedundantKeys( bool bKeepEnds ) = 0; virtual void RemoveRedundantKeys( float threshold, bool bKeepEnds ) = 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, int baseLayer = 0 ) = 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; // Bookmark functions virtual void InitalizeBookmarkArrays() = 0; virtual int GetNumBookmarkComponents() const = 0; int GetNumBookmarks( int nComponentIndex ) const; DmeTime_t GetBookmarkTime( int nBookmarkIndex, int nComponentIndex ) const; void AddBookmark( DmeTime_t time, int nComponentIndex ); bool RemoveBookmark( DmeTime_t time, int nComponentIndex ); void RemoveAllBookmarks( int nComponentIndex ); void SetAllBookmarks( int nComponentIndex, const CUtlVector< DmeTime_t > &time ); // Masks all keys within the time range, returns true if keys were modified virtual bool MaskKeyRange( DmeTime_t tStartTime, DmeTime_t tEndTime, LogComponents_t nComponentFlags, bool bInfiniteLeft = false, bool bInfiniteRight = false ) = 0; protected: // int FindKey( DmeTime_t time ) const; void OnUsingCurveTypesChanged(); virtual void OnAttributeChanged( CDmAttribute *pAttribute ); CDmaElementArray< CDmeLogLayer > m_Layers; CDmaElement< CDmeCurveInfo > m_CurveInfo; CDmaArray< DmeTime_t > m_BookmarkTimes[ LOG_MAX_COMPONENTS ]; }; //----------------------------------------------------------------------------- // 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 ]; CDmaTime m_RightEdgeTime; CDmaVar< T > m_DefaultEdgeValue; }; // forward declaration template< class T > class CDmeTypedLog; template< typename T > struct LogKeyValue_t { T value; DmeTime_t time; }; //----------------------------------------------------------------------------- // 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, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, int curveType = CURVE_DEFAULT ); // Sets a key, removes all keys after this time void SetKey( DmeTime_t time, const T& value, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, int curveType = CURVE_DEFAULT, bool removeRedundant = true ); // Sets all of the keys on the layer from the provided array of times and values void SetAllKeys( const CUtlVector< DmeTime_t > ×, const CUtlVector< T > &values ); // Copy all of the keys into the specified array void GetAllKeys( CUtlVector< DmeTime_t > ×, CUtlVector< T > &values ) const; // 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 ); // Add keys at tStartTime and tEndTime, and remove all keys outside the range virtual void TrimKeys( DmeTime_t tStartTime, DmeTime_t tEndTime ); 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; // Returns the key time / value pair for the specified key void GetKeyValue( int keyIndex, LogKeyValue_t< T > &keyValue ) const; // This inserts a key. Unlike SetKey, this will *not* delete keys after the specified time int InsertKey( DmeTime_t nTime, const T& value, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, int curveType = CURVE_DEFAULT, bool bIgnoreTolerance = false ); // inherited from CDmeLog virtual void ClearKeys(); virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, 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( bool bKeepEnds ); virtual void RemoveRedundantKeys( float threshold, bool bKeepEnds ); 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; T MaskValue( DmeTime_t time, const T& value, LogComponents_t componentFlags ) const; // Masks all keys within the time range, returns true if keys were modified virtual bool MaskKeyRange( DmeTime_t tStartTime, DmeTime_t tEndTime, LogComponents_t nComponentFlags, bool bInfiniteLeft = false, bool bInfiniteRight = false ); virtual void MakeRoomForSamplesMaskedSubcomponents( CDmeLogLayer *pBaseLayer, DmeTime_t tStart, DmeTime_t tEnd, DmeTime_t tLeftShift, DmeTime_t tRightShift, LogComponents_t nComponents ); virtual void Compress(); virtual void Decompress(); virtual bool IsCompressed() const; virtual size_t GetCompressedSize() const; virtual size_t GetDataSize() 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 >; void GetTwoKeyValues( int keyindex, T &v1, T &v2 ) const; void GetCompressedValue( int nKeyIndex, T &value ) const; void GetCompressedValues( int nKeyIndex, T &value1, T &value2 ) const; void CompressValues( CDmaArray< T > &stream, CUtlBinaryBlock &block, float flMaxError = 0.1f ); protected: CDmaArray< T > m_values; // When compressed, m_values is empty and data is read from here CDmaVar< CUtlBinaryBlock > m_Compressed; }; //----------------------------------------------------------------------------- // 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 DmeLogTransformParams_t &transformParams, const T& value, bool bTimeFilter = true, int layerIndex = -1 ); void StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t& params, const DmeLogTransformParams_t &transformParams, const CDmAttribute *pAttr, uint arrayIndex = 0, bool bTimeFilter = true, int logLayer = -1 ); void FinishTimeSelection( DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& params ); // in attached, time advancing 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 ¶ms, const CDmeLogLayer *pTargetLayer ); void RecaleAndRevealUsingTimeSelection( const DmeLog_TimeSelection_t ¶ms, TimeSelection_t &sourceTimeSelection, const CDmeLogLayer *pTargetLayer ); void GenerateSplineUsingTimeSelection( const DmeLog_TimeSelection_t& params, const CUtlVector< DmeTime_t > &sortedSplineKeyTimes, const CDmeLogLayer *baseLayer, CDmeLogLayer *writeLayer ); void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t ¶ms, int baseLayer = 0 ); void BlendLayersUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t ¶ms, bool bUseBaseLayerSamples, bool bUseFalloff, bool bSelectionSamples, DmeTime_t tStartOffset ); void BlendLayersUsingTimeSelection( const CDmeLogLayer *baseLayer, const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t ¶ms, bool bUseBaseLayerSamples, DmeTime_t tStartOffset ); void BlendLayersUsingTimeSelection( const DmeLog_TimeSelection_t ¶ms, const CDmeTypedLogLayer< T > *pBaseLayer, const CDmeTypedLogLayer< T > *pBlendLayer, CDmeTypedLogLayer< T > *pOutputLayer ); void BlendTimesUsingTimeSelection( const CDmeLogLayer *firstLayer, const CDmeLogLayer *secondLayer, CDmeLogLayer *outputLayer, const DmeLog_TimeSelection_t ¶ms, DmeTime_t tStartOffset, bool bFeatherBlendInFalloff ); void HoldOrReleaseUsingTimeSelection( const DmeLog_TimeSelection_t& params, bool bHold, const CDmeLogLayer *pBaseLayer, CDmeLogLayer *pWriteLayer ); void SteadyUsingTimeSelection( const DmeLog_TimeSelection_t& params, const CDmeLogLayer *pBaseLayer, CDmeLogLayer *pWriteLayer ); void CopySamplesFromPreset( const DmeLog_TimeSelection_t& params, const CDmAttribute *pPresetValue, const CDmAttribute *pPresetTimes, DmeTime_t tLogTimeOffset, const CDmeChannelsClip *pChannelsClip, const CDmeLogLayer *pBaseLayer, CDmeLogLayer *pWriteLayer ); // preset samples are in shot time, not log time virtual void PasteAndRescaleSamples( const CDmeLogLayer *src, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion, bool bReverse ); virtual void PasteAndRescaleSamples( const CDmeLogLayer *pBaseLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer, const DmeLog_TimeSelection_t& srcParams, const DmeLog_TimeSelection_t& destParams, bool bBlendAreaInFalloffRegion, bool bReverse ); virtual void BuildCorrespondingLayer( const CDmeLogLayer *pReferenceLayer, const CDmeLogLayer *pDataLayer, CDmeLogLayer *pOutputLayer ); virtual void BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); // 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, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, int curveType = CURVE_DEFAULT ); // Sets a key, removes all keys after this time void SetKey( DmeTime_t time, const T& value, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, 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& GetValueBelowLayer( DmeTime_t time, int nTopLayerIndex ) 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, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, int curveType = CURVE_DEFAULT, bool bIgnoreTolerance = false ); // inherited from CDmeLog virtual void ClearKeys(); virtual void SetKey( DmeTime_t time, const CDmAttribute *pAttr, uint index = 0, SegmentInterpolation_t interpSetting = SEGMENT_INTERPOLATE, 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 bool IsConstantValued() const; virtual void RemoveRedundantKeys( bool bKeepEnds ); virtual void RemoveRedundantKeys( float threshold, bool bKeepEnds ); 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 void ClearAndAddSampleAtTime( DmeTime_t time ); virtual CDmeLogLayer *AddNewLayer(); virtual void FlattenLayers( float threshhold, int flags, int baseLayer = 0 ); // 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 ); T MaskValue( DmeTime_t time, const T& value, LogComponents_t componentFlags ) const; void SetDefaultValue( const T& value ); const T& GetDefaultValue() const; bool HasDefaultValue() const; void ClearDefaultValue(); static float s_threshold; static float GetValueThreshold() { return s_threshold; } static void SetValueThreshold( float s_threshold ); // Bookmark functions virtual void InitalizeBookmarkArrays(); virtual int GetNumBookmarkComponents() const; // Removes all keys within the time range, returns true if keys were removed virtual bool MaskKeyRange( DmeTime_t tStartTime, DmeTime_t tEndTime, LogComponents_t nComponentFlags, bool bInfiniteLeft = false, bool bInfiniteRight = false ); void MaskAgainstLayer( CDmeTypedLogLayer< T > *pFinalLayer, const CDmeTypedLogLayer< T > *pReferenceLayer, LogComponents_t nComponentFlags ); SegmentInterpolation_t GetSegmentInterpolationSetting( DmeTime_t time ) const; SegmentInterpolation_t GetSegmentInterpolationSetting_SkippingTopmostLayer( DmeTime_t time ) const; protected: void RemoveKeys( DmeTime_t starttime ); void _StampKeyAtHeadResample( DmeTime_t tHeadPosition, const DmeLog_TimeSelection_t & params, const DmeLogTransformParams_t &transformParams, const T& value, bool bSkipToHead, bool bClearPreviousKeys, int layerIndex = -1 ); void _StampKeyAtHead( DmeTime_t tHeadPosition, DmeTime_t tPreviousHeadPosition, const DmeLog_TimeSelection_t & params, const T& value, bool bFilteredByTimeSelection, int layerIndex = -1 ); void _StampKeyAtTime( CDmeTypedLogLayer< T > *pWriteLayer, DmeTime_t t, const DmeLog_TimeSelection_t ¶ms, const T& value, bool bFilterByTimeSelection, bool bForce = false ); protected: CDmaVar< bool > m_UseDefaultValue; CDmaVar< T > m_DefaultValue; }; //----------------------------------------------------------------------------- // Template methods //----------------------------------------------------------------------------- template< class T > DmAttributeType_t CDmeTypedLogLayer::GetDataType() const { return CDmAttributeInfo< T >::AttributeType(); } template< class T > bool CDmeTypedLogLayer::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::GetDataType() const { return CDmAttributeInfo< T >::AttributeType(); } template< class T > void CDmeTypedLog::SetValueThreshold( float thresh ) { s_threshold = thresh; } template< class T > bool CDmeTypedLog::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::RemoveRedundantKeys( bool bKeepEnds ) { int bestLayer = GetTopmostLayer(); if ( bestLayer < 0 ) return; GetLayer( bestLayer )->RemoveRedundantKeys( bKeepEnds ); } template< class T > inline T MaskValue( const T& newValue, const T ¤tValue, LogComponents_t componentFlags ) { return newValue; } template<> inline Vector MaskValue( const Vector& value, const Vector &curValue, LogComponents_t componentFlags ) { Vector writeValue; writeValue.x = ( componentFlags & LOG_COMPONENTS_X ) ? value.x : curValue.x; writeValue.y = ( componentFlags & LOG_COMPONENTS_Y ) ? value.y : curValue.y; writeValue.z = ( componentFlags & LOG_COMPONENTS_Z ) ? value.z : curValue.z; return writeValue; } template<> inline Quaternion MaskValue( const Quaternion& value, const Quaternion &curQuat, LogComponents_t componentFlags ) { Quaternion writeValue; // Convert to euler QAngle curQA; QuaternionAngles( curQuat, curQA ); QAngle valueQA; QuaternionAngles( value, valueQA ); // Mask euler valueQA.x = ( componentFlags & LOG_COMPONENTS_X ) ? valueQA.x : curQA.x; valueQA.y = ( componentFlags & LOG_COMPONENTS_Y ) ? valueQA.y : curQA.y; valueQA.z = ( componentFlags & LOG_COMPONENTS_Z ) ? valueQA.z : curQA.z; // convert back to Quaternion for output AngleQuaternion( valueQA, writeValue ); return writeValue; } 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 ) { float flAngle = 2.0f * acos( fabs( val.w ) ); return flAngle / M_PI; // QAngle angle; // QuaternionAngles( val, angle ); // return Normalize( angle ); } template< class T > inline void CDmeTypedLog< T >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ) { VPROF_BUDGET( "CDmeTypedLog< T >::BuildNormalizedLayer", "SFM" ); Assert( pChannels ); Assert( GetDataType() != AT_FLOAT ); CDmeTypedLogLayer< T > *pBaseLayer = static_cast< CDmeTypedLogLayer< T > * >( GetLayer( nLayer ) ); 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 ); pChannels[ 0 ]->InsertKey( tKeyTime, flNormalized, pBaseLayer->GetSegmentInterpolationSetting( i ) ); } if ( HasDefaultValue() ) { pChannels[ 0 ]->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 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( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template<> void CDmeTypedLog< Vector2D >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template<> void CDmeTypedLog< Vector4D >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template<> void CDmeTypedLog< float >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template<> void CDmeTypedLog< int >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template<> void CDmeTypedLog< DmeTime_t >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template<> void CDmeTypedLog< Quaternion >::BuildNormalizedLayer( int nChannels, CDmeTypedLogLayer< float > **pChannels, int nLayer ); template< class T >int CDmeTypedLog< T >::GetNumBookmarkComponents() const; template<> int CDmeTypedLog< Vector >::GetNumBookmarkComponents() const; template<> int CDmeTypedLog< Vector2D >::GetNumBookmarkComponents() const; template<> int CDmeTypedLog< Vector4D >::GetNumBookmarkComponents() const; template<> int CDmeTypedLog< Quaternion >::GetNumBookmarkComponents() const; template< class T > void CDmeTypedLog< T >::InitalizeBookmarkArrays(); template<> void CDmeTypedLog< Vector >::InitalizeBookmarkArrays(); template<> void CDmeTypedLog< Vector2D >::InitalizeBookmarkArrays(); template<> void CDmeTypedLog< Vector4D >::InitalizeBookmarkArrays(); template<> void CDmeTypedLog< Quaternion >::InitalizeBookmarkArrays(); //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 CDmeIntLog; typedef CDmeTypedLog CDmeFloatLog; typedef CDmeTypedLog CDmeBoolLog; typedef CDmeTypedLog CDmeColorLog; typedef CDmeTypedLog CDmeVector2Log; typedef CDmeTypedLog CDmeVector3Log; typedef CDmeTypedLog CDmeVector4Log; typedef CDmeTypedLog CDmeQAngleLog; typedef CDmeTypedLog CDmeQuaternionLog; typedef CDmeTypedLog CDmeVMatrixLog; typedef CDmeTypedLog CDmeStringLog; typedef CDmeTypedLog CDmeTimeLog; //----------------------------------------------------------------------------- // typedefs for convenience (and so the user-supplied names match the programmer names) //----------------------------------------------------------------------------- typedef CDmeTypedLogLayer CDmeIntLogLayer; typedef CDmeTypedLogLayer CDmeFloatLogLayer; typedef CDmeTypedLogLayer CDmeBoolLogLayer; typedef CDmeTypedLogLayer CDmeColorLogLayer; typedef CDmeTypedLogLayer CDmeVector2LogLayer; typedef CDmeTypedLogLayer CDmeVector3LogLayer; typedef CDmeTypedLogLayer CDmeVector4LogLayer; typedef CDmeTypedLogLayer CDmeQAngleLogLayer; typedef CDmeTypedLogLayer CDmeQuaternionLogLayer; typedef CDmeTypedLogLayer CDmeVMatrixLogLayer; typedef CDmeTypedLogLayer CDmeStringLogLayer; typedef CDmeTypedLogLayer CDmeTimeLogLayer; //----------------------------------------------------------------------------- // typedefs for convenience (and so the user-supplied names match the programmer names) //----------------------------------------------------------------------------- typedef CDmeTypedCurveInfo CDmeIntCurveInfo; typedef CDmeTypedCurveInfo CDmeFloatCurveInfo; typedef CDmeTypedCurveInfo CDmeBoolCurveInfo; typedef CDmeTypedCurveInfo CDmeColorCurveInfo; typedef CDmeTypedCurveInfo CDmeVector2CurveInfo; typedef CDmeTypedCurveInfo CDmeVector3CurveInfo; typedef CDmeTypedCurveInfo CDmeVector4CurveInfo; typedef CDmeTypedCurveInfo CDmeQAngleCurveInfo; typedef CDmeTypedCurveInfo CDmeQuaternionCurveInfo; typedef CDmeTypedCurveInfo CDmeVMatrixCurveInfo; typedef CDmeTypedCurveInfo CDmeStringCurveInfo; typedef CDmeTypedCurveInfo CDmeTimeCurveInfo; // the following types are not supported // AT_ELEMENT, // AT_VOID, // //----------------------------------------------------------------------------- // 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 ); float ComputeInterpolationFactor( float flFactor, int nInterpolatorType ); float GetAmountForTime( DmeTime_t dmetime, const TimeSelection_t ×, const int nInterpolationTypes[ 2 ] ); #endif // DMELOG_H