summaryrefslogtreecommitdiff
path: root/unittests/dmxtest/dmxtestdmelog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/dmxtest/dmxtestdmelog.cpp')
-rw-r--r--unittests/dmxtest/dmxtestdmelog.cpp393
1 files changed, 393 insertions, 0 deletions
diff --git a/unittests/dmxtest/dmxtestdmelog.cpp b/unittests/dmxtest/dmxtestdmelog.cpp
new file mode 100644
index 0000000..3f98678
--- /dev/null
+++ b/unittests/dmxtest/dmxtestdmelog.cpp
@@ -0,0 +1,393 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#include "unitlib/unitlib.h"
+#include "datamodel/dmelement.h"
+#include "movieobjects/movieobjects.h"
+#include "datamodel/idatamodel.h"
+#include "tier1/utlbuffer.h"
+#include "filesystem.h"
+#include "movieobjects/dmelog.h"
+#include "choreoscene.h"
+#include "choreoevent.h"
+
+struct data_t
+{
+ int tms; // tenths of a millisecond
+ float value;
+ int curvetype;
+};
+
+struct tvpair_t
+{
+ int tms;
+ float expectedvalue;
+};
+
+data_t data[] =
+{
+ { 0, 0.0f, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_CATMULL_ROM_NORMALIZEX ) },
+ { 10000, 0.5f, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_CATMULL_ROM_NORMALIZEX ) },
+ { 20000, 0.5f, MAKE_CURVE_TYPE( INTERPOLATE_EASE_IN, INTERPOLATE_EASE_OUT ) },
+ { 30000, 0.5f, MAKE_CURVE_TYPE( INTERPOLATE_EASE_OUT, INTERPOLATE_EASE_INOUT ) },
+ { 40000, 0.5f, MAKE_CURVE_TYPE( INTERPOLATE_EASE_INOUT, INTERPOLATE_BSPLINE ) },
+ { 50000, 0.5f, MAKE_CURVE_TYPE( INTERPOLATE_BSPLINE, INTERPOLATE_LINEAR_INTERP ) },
+ { 60000, 1.0f, MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_KOCHANEK_BARTELS ) },
+ { 70000, 0.0f, MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS, INTERPOLATE_KOCHANEK_BARTELS_EARLY ) },
+ { 80000, 0.5f, MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS_EARLY, INTERPOLATE_KOCHANEK_BARTELS_LATE ) },
+ { 90000, 0.0f, MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS_LATE, INTERPOLATE_SIMPLE_CUBIC ) },
+ { 100000, 0.25f, MAKE_CURVE_TYPE( INTERPOLATE_SIMPLE_CUBIC, INTERPOLATE_CATMULL_ROM ) },
+ { 110000, 0.0f, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM, INTERPOLATE_CATMULL_ROM_NORMALIZE ) },
+ { 120000, 0.125f, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZE, INTERPOLATE_EXPONENTIAL_DECAY ) },
+ { 130000, 0.0f, MAKE_CURVE_TYPE( INTERPOLATE_EXPONENTIAL_DECAY, INTERPOLATE_HOLD ) },
+ { 140000, 0.0625f, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_EXPONENTIAL_DECAY ) },
+ { 150000, 0.0f, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_CATMULL_ROM_NORMALIZEX ) },
+};
+
+#define NUM_DEF_TESTS 3
+
+static data_t values1[] =
+{
+ { -1, 0.0f, 0 },
+};
+static data_t values2[] =
+{
+ { 5000, 0.5f, CURVE_DEFAULT },
+ { -1, 0.0f, 0 },
+};
+static data_t values3[] =
+{
+ { 2500, 0.25f, CURVE_DEFAULT },
+ { 7500, 0.75f, CURVE_DEFAULT },
+ { -1, 0.0f, 0 },
+};
+
+static data_t *defaultvaluetest[ NUM_DEF_TESTS ] =
+{
+ values1,
+ values2,
+ values3
+};
+
+#define NUM_TEST_VALUES 3
+
+static tvpair_t expectedvalues1[NUM_TEST_VALUES] =
+{
+ { 0, 0.5f },
+ { 5000, 0.5f },
+ { 10000, 0.5f },
+};
+
+static tvpair_t expectedvalues2[NUM_TEST_VALUES] =
+{
+ { 0, 0.5f },
+ { 5000, 0.5f },
+ { 10000, 0.5f },
+};
+
+static tvpair_t expectedvalues3[NUM_TEST_VALUES] =
+{
+ { 0, 0.25f },
+ { 5000, 0.5f },
+ { 10000, 0.75f },
+};
+
+static tvpair_t *expectedvalues[ NUM_DEF_TESTS ] =
+{
+ expectedvalues1,
+ expectedvalues2,
+ expectedvalues3
+};
+
+void ResetLog( CDmeFloatLog *log, bool useCurveTypes, int startIndex = 0, int endIndex = -1 )
+{
+ log->ClearKeys();
+
+ CDmeCurveInfo *pCurveInfo = useCurveTypes ? log->GetOrCreateCurveInfo() : log->GetCurveInfo();
+ if ( useCurveTypes )
+ {
+ pCurveInfo->SetDefaultCurveType( MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_CATMULL_ROM_NORMALIZEX ) );
+ }
+ else if ( !useCurveTypes && pCurveInfo )
+ {
+ g_pDataModel->DestroyElement( pCurveInfo->GetHandle() );
+ log->SetCurveInfo( NULL );
+ }
+
+ int i;
+ int c;
+
+ c = ARRAYSIZE( data );
+ for ( i = startIndex; i < c; ++i )
+ {
+ log->SetKey( DmeTime_t( data[ i ].tms ), data[ i ].value, useCurveTypes ? data[ i ].curvetype : CURVE_DEFAULT );
+
+ if ( endIndex != -1 && i >= endIndex )
+ break;
+ }
+}
+
+void CompareFloats( float f1, float f2, float tol, char const *fmt, ... )
+{
+ float diff = fabs( f1 - f2 );
+ if ( diff < tol )
+ return;
+
+ char buf[ 256 ];
+ va_list argptr;
+ va_start( argptr, fmt );
+ _vsnprintf( buf, sizeof( buf ) - 1, fmt, argptr );
+ va_end( argptr );
+
+ Msg( buf );
+}
+
+DEFINE_TESTCASE_NOSUITE( DmxRunDefaultValueLogTest )
+{
+ Msg( "Running CDmeTypedLog<float> default value (stereo channel w/ value 0.5) tests...\n" );
+ CDisableUndoScopeGuard sg;
+
+ DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxTestDmeLog>" );
+
+ for ( int i = 0; i < NUM_DEF_TESTS; ++i )
+ {
+ data_t *pdata = defaultvaluetest[ i ];
+ tvpair_t *pexpected = expectedvalues[ i ];
+
+ // Run each test
+
+ CDmeFloatLog *log = CreateElement<CDmeFloatLog>( "curve", fileid );
+ if ( !log )
+ {
+ Msg( "Unable to create CDmeFloatLog object!!!" );
+ continue;
+ }
+
+ log->SetDefaultValue( 0.5f );
+
+ if ( pdata )
+ {
+ // Run the test
+ for ( int j = 0; ; ++j )
+ {
+ if ( pdata[ j ].tms == -1 )
+ break;
+
+ log->SetKey( DmeTime_t( pdata[ j ].tms ), pdata[ j ].value );
+ }
+ }
+
+ // Now compare against expected values
+ for ( int j = 0; j < NUM_TEST_VALUES; ++j )
+ {
+ DmeTime_t t = DmeTime_t( pexpected[ j ].tms );
+ float v = pexpected[ j ].expectedvalue;
+ float logv = log->GetValue( t );
+ Shipping_Assert( v == logv );
+ }
+
+ DestroyElement( log );
+ }
+
+ g_pDataModel->RemoveFileId( fileid );
+}
+
+void RunDmeFloatLogTests( CDmeFloatLog *log )
+{
+ Msg( " Testing general log data...\n" );
+
+ ResetLog( log, false );
+
+ CompareFloats( 0.5f, log->GetValue( DmeTime_t( 2.0f ) ), 0.000001f, "log->GetValue( 2.0 ) expected to be 0.5f\n" );
+ CompareFloats( 0.5f, log->GetValue( DmeTime_t( 2.5f ) ), 0.000001f, "log->GetValue( 2.5 ) expected to be 0.5f\n" );
+ CompareFloats( 0.5f, log->GetValue( DmeTime_t( 2.5f ) ), 0.000001f, "log->GetValue( 2.5 ) expected to be 0.5f\n" );
+ CompareFloats( 0.5f, log->GetValue( DmeTime_t( 6.5f ) ), 0.000001f, "log->GetValue( 6.5 ) expected to be 0.5f\n" );
+
+ CDmeCurveInfo *pCurveInfo = log->GetOrCreateCurveInfo();
+
+ int idx = log->FindKeyWithinTolerance( DmeTime_t( 6.0f ), DmeTime_t( 0 ) );
+ Shipping_Assert( log->GetKeyTime( idx ) == DmeTime_t( 6.0f ) );
+ log->SetKeyCurveType( idx, MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_LINEAR_INTERP ) );
+ log->SetKeyCurveType( idx + 1, MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_LINEAR_INTERP ) );
+
+ float val = log->GetValue( DmeTime_t( 6.5f ) );
+ float qval = log->GetValue( DmeTime_t( 6.25f ) );
+
+ CompareFloats( 0.5f, val, 0.000001f, "INTERPOLATE_LINEAR_INTERPlog->GetValue( 6500 ) expcted to be 0.5f\n" );
+ CompareFloats( 0.75f, qval, 0.000001f, "INTERPOLATE_LINEAR_INTERPlog->GetValue( 6250 ) expcted to be 0.75f\n" );
+
+ log->SetKeyCurveType( idx, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_CATMULL_ROM_NORMALIZEX ) );
+ log->SetKeyCurveType( idx + 1, MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX, INTERPOLATE_CATMULL_ROM_NORMALIZEX ) );
+
+ float val2 = log->GetValue( DmeTime_t( 6.5f ) );
+ float qval2 = log->GetValue( DmeTime_t( 6.25f ) );
+ Shipping_Assert( val2 == val );
+ Shipping_Assert( qval2 != val );
+
+ log->SetKeyCurveType( idx, MAKE_CURVE_TYPE( INTERPOLATE_EASE_INOUT, INTERPOLATE_EASE_INOUT ) );
+ log->SetKeyCurveType( idx + 1, MAKE_CURVE_TYPE( INTERPOLATE_EASE_INOUT, INTERPOLATE_EASE_INOUT ) );
+
+ float val3 = log->GetValue( DmeTime_t( 6.5f ) );
+ float qval3 = log->GetValue( DmeTime_t( 6.25f ) );
+ Shipping_Assert( val3 == val );
+ Shipping_Assert( qval3 != val );
+
+ log->SetKeyCurveType( idx, MAKE_CURVE_TYPE( INTERPOLATE_EXPONENTIAL_DECAY, INTERPOLATE_EXPONENTIAL_DECAY ) );
+ log->SetKeyCurveType( idx + 1, MAKE_CURVE_TYPE( INTERPOLATE_EXPONENTIAL_DECAY, INTERPOLATE_EXPONENTIAL_DECAY ) );
+
+ float val4 = log->GetValue( DmeTime_t( 6.5f ) );
+ float qval4 = log->GetValue( DmeTime_t( 6.25f ) );
+ Shipping_Assert( val4 != val );
+ Shipping_Assert( qval4 != val );
+
+ log->SetKeyCurveType( idx, MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS, INTERPOLATE_KOCHANEK_BARTELS ) );
+ log->SetKeyCurveType( idx + 1, MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS, INTERPOLATE_KOCHANEK_BARTELS ) );
+
+ float val5 = log->GetValue( DmeTime_t( 6.5f ) );
+ float qval5 = log->GetValue( DmeTime_t( 6.25f ) );
+ Shipping_Assert( val5 == val );
+ Shipping_Assert( qval5 != val );
+
+ pCurveInfo->SetDefaultCurveType( MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS, INTERPOLATE_KOCHANEK_BARTELS ) );
+ log->SetKeyCurveType( idx, MAKE_CURVE_TYPE( INTERPOLATE_DEFAULT, INTERPOLATE_DEFAULT ) );
+ log->SetKeyCurveType( idx + 1, MAKE_CURVE_TYPE( INTERPOLATE_DEFAULT, INTERPOLATE_DEFAULT ) );
+
+ float val6 = log->GetValue( DmeTime_t( 6.5f ) );
+ float qval6 = log->GetValue( DmeTime_t( 6.25f ) );
+ Shipping_Assert( val5 == val6 );
+ Shipping_Assert( qval6 == qval5 );
+
+}
+
+void CompareLogToChoreo( CFlexAnimationTrack *track, CDmeFloatLog *log )
+{
+ // Now run tests
+ for ( DmeTime_t t( 0 ); t < DmeTime_t( 20.0f ); t += DmeTime_t( 0.1f ) )
+ {
+ // Compare values
+ float dmevalue = log->GetValue( t );
+ float choreovalue = track->GetIntensity( t.GetSeconds() );
+
+ CompareFloats( dmevalue, choreovalue, 0.001f, "Time(%f sec) , dme [%f] choreo[%f], diff[%f]\n",
+ t.GetSeconds(),
+ dmevalue,
+ choreovalue,
+ fabs( dmevalue - choreovalue ) );
+ }
+}
+
+void ResetChoreo( CFlexAnimationTrack *track, bool useCurveTypes, int startIndex = 0, int endIndex = -1 )
+{
+ track->Clear();
+
+ int i;
+ int c;
+
+ c = ARRAYSIZE( data );
+ for ( i = startIndex; i < c; ++i )
+ {
+ data_t *e = &data[ i ];
+
+ float t = (float)e->tms / 10000.0f;
+
+ CExpressionSample *sample = track->AddSample( t, e->value );
+ Shipping_Assert( sample );
+ if ( useCurveTypes )
+ {
+ sample->SetCurveType( e->curvetype );
+ }
+
+ if ( endIndex != -1 && i >= endIndex )
+ break;
+ }
+}
+
+void RunDmeChoreoComparisons( CDmeFloatLog *log )
+{
+ Msg( " Testing choreo-style log data...\n" );
+
+ ResetLog( log, true );
+ log->SetRightEdgeTime( DmeTime_t( 15.0f ) );
+
+ CChoreoScene *scene = new CChoreoScene( NULL );
+ CChoreoEvent *event = new CChoreoEvent( scene, CChoreoEvent::FLEXANIMATION, "test" );
+ event->SetStartTime( 0.0f );
+ event->SetEndTime( 15.0f );
+ CFlexAnimationTrack *track = new CFlexAnimationTrack( event );
+ track->SetFlexControllerName( "flextest" );
+ track->SetComboType( false );
+
+ ResetChoreo( track, true );
+
+ Msg( " Comparing default data...\n" );
+
+ CompareLogToChoreo( track, log );
+
+ ResetLog( log, true, 3, 14 );
+ ResetChoreo( track, true, 3, 14 );
+
+ Msg( " Comparing subset of data...\n" );
+
+ CompareLogToChoreo( track, log );
+
+ Msg( " Comparing left/right edge settings...\n" );
+ // Now test right and left edge stuff
+ // Enable left edge stuff
+ track->SetEdgeActive( true, true );
+ track->SetEdgeInfo( true, MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_LINEAR_INTERP ), 0.75f );
+ track->SetEdgeActive( false, true );
+ track->SetEdgeInfo( false, MAKE_CURVE_TYPE( INTERPOLATE_EASE_OUT, INTERPOLATE_EASE_OUT ), 0.25f );
+
+ // Same settings for log
+ log->SetUseEdgeInfo( true );
+ log->SetDefaultEdgeZeroValue( 0.0f );
+ log->SetEdgeInfo( 0, true, 0.75f, MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_LINEAR_INTERP ) );
+ log->SetEdgeInfo( 1, true, 0.25f, MAKE_CURVE_TYPE( INTERPOLATE_EASE_OUT, INTERPOLATE_EASE_OUT ) );
+
+ CompareLogToChoreo( track, log );
+
+ int i;
+ for ( i = 1; i < NUM_INTERPOLATE_TYPES; ++i )
+ {
+ Msg( " Comparing left/right edge settings[ %s ]...\n", Interpolator_NameForInterpolator( i, true ) );
+
+ float val = (float)i / (float)( NUM_INTERPOLATE_TYPES - 1 ) ;
+ // Now test right and left edge stuff with different data
+ track->SetEdgeInfo( true, MAKE_CURVE_TYPE( i, i ), val );
+ track->SetEdgeInfo( false, MAKE_CURVE_TYPE( i, i ), val );
+ log->SetEdgeInfo( 0, true, val, MAKE_CURVE_TYPE( i, i ) );
+ log->SetEdgeInfo( 1, true, val, MAKE_CURVE_TYPE( i, i ) );
+
+ CompareLogToChoreo( track, log );
+ }
+
+ delete event;
+ delete scene;
+}
+
+DEFINE_TESTCASE_NOSUITE( DmxTestDmeLog )
+{
+ Msg( "Running CDmeTypedLog<float> tests...\n" );
+ CDisableUndoScopeGuard sg;
+
+ DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxTestDmeLog>" );
+
+ CDmeFloatLog *pElement = CreateElement<CDmeFloatLog>( "curve", fileid );
+ if ( !pElement )
+ {
+ Msg( "Unable to create CDmeFloatLog object!!!" );
+ return;
+ }
+
+ // Run tests
+ RunDmeFloatLogTests( pElement );
+
+ RunDmeChoreoComparisons( pElement );
+
+ g_pDataModel->RemoveFileId( fileid );
+} \ No newline at end of file