You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
908 lines
26 KiB
908 lines
26 KiB
//========= 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 "movieobjects/dmechannel.h" |
|
#include "movieobjects/dmelog.h" |
|
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
#define NUM_CHANNELS 1 |
|
#define NUM_LOG_ENTRIES 10 |
|
|
|
enum |
|
{ |
|
SPEW_DIFFS = (1<<0), |
|
SPEW_VALUES= (1<<1), |
|
SPEW_KEYS= (1<<2), |
|
}; |
|
|
|
static void ValidateDataSets( int spew, char const *testname, CUtlVector< CUtlVector< float > >& values, CUtlVector< CUtlVector< float > >& valuesbaked ) |
|
{ |
|
int i, j; |
|
// Compare baked, unbaked values |
|
Assert( values.Count() == valuesbaked.Count() ); |
|
int c = values.Count(); |
|
bool differs = false; |
|
bool spewvalues = ( spew & SPEW_VALUES ) ? true : false; |
|
|
|
float tol = 0.0001f; |
|
|
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CUtlVector< float >& v = values[ i ]; |
|
CUtlVector< float >& vb = valuesbaked[ i ]; |
|
|
|
Assert( v.Count() == vb.Count() ); |
|
|
|
// Now get the values of the samples in the log |
|
for ( j = 0; j < v.Count(); ++j ) |
|
{ |
|
Assert( vb.IsValidIndex( j ) ); |
|
if ( !vb.IsValidIndex( j ) ) |
|
continue; |
|
|
|
float v1 = v[ j ]; |
|
float v2 = vb[ j ]; |
|
if ( fabs( v1 - v2 ) > tol ) |
|
{ |
|
differs = true; |
|
} |
|
|
|
if ( spewvalues ) |
|
{ |
|
Msg( "%d %f %f\n", j, v[ j ], vb[ j ] ); |
|
} |
|
} |
|
} |
|
|
|
Msg( " %s\n", differs ? "FAILED" : "OK" ); |
|
|
|
if ( !(spew & SPEW_DIFFS ) ) |
|
return; |
|
|
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CUtlVector< float >& v = values[ i ]; |
|
CUtlVector< float >& vb = valuesbaked[ i ]; |
|
|
|
Assert( v.Count() == vb.Count() ); |
|
|
|
// Now get the values of the samples in the log |
|
for ( j = 0; j < v.Count(); ++j ) |
|
{ |
|
Assert( vb.IsValidIndex( j ) ); |
|
if ( !vb.IsValidIndex( j ) ) |
|
continue; |
|
|
|
if ( v[ j ] == vb[ j ] ) |
|
{ |
|
if ( differs ) |
|
{ |
|
Msg( "%d found %f to equal %f\n", j, v[ j ], vb[ j ] ); |
|
} |
|
continue; |
|
} |
|
|
|
Msg( "%d expected %f to equal %f\n", j, v[ j ], vb[ j ] ); |
|
} |
|
} |
|
|
|
if ( differs ) |
|
{ |
|
Msg( "End Test '%s'\n---------------\n", testname ); |
|
} |
|
} |
|
|
|
static void CreateChannels( int num, CUtlVector< CDmeChannel * >& channels, DmFileId_t fileid ) |
|
{ |
|
CDisableUndoScopeGuard guard; |
|
|
|
for ( int i = 0; i < num; ++i ) |
|
{ |
|
CDmeChannel *channel = NULL; |
|
|
|
channel = CreateElement< CDmeChannel >( "channel1", fileid ); |
|
channels.AddToTail( channel ); |
|
channel->CreateLog( AT_FLOAT ); // only care about float logs for now |
|
channel->SetMode( CM_PLAY );// Make sure it's in playback mode |
|
} |
|
} |
|
|
|
struct TestLayer_t |
|
{ |
|
enum |
|
{ |
|
TYPE_SIMPLESLOPE = 0, // value == time |
|
TYPE_SINE, // sinusoidal |
|
TYPE_CONSTANT, |
|
}; |
|
|
|
TestLayer_t() : |
|
startTime( 0 ), |
|
endTime( 0 ), |
|
timeStep( 0 ), |
|
usecurvetype( false ), |
|
curvetype( CURVE_DEFAULT ), |
|
type( TYPE_SIMPLESLOPE ), |
|
constantvalue( 0.0f ) |
|
{ |
|
} |
|
|
|
float ValueForTime( DmeTime_t time ) const |
|
{ |
|
float t = (float)time.GetSeconds(); |
|
switch ( type ) |
|
{ |
|
default: |
|
case TYPE_SIMPLESLOPE: |
|
return t; |
|
case TYPE_SINE: |
|
return constantvalue * ( 1.0f + sin( ( t * 0.002f ) * 2 * M_PI ) ) * 0.5f; |
|
case TYPE_CONSTANT: |
|
return constantvalue; |
|
} |
|
|
|
return t; |
|
} |
|
|
|
int type; |
|
DmeTime_t startTime; |
|
DmeTime_t endTime; |
|
DmeTime_t timeStep; |
|
|
|
bool usecurvetype; |
|
int curvetype; |
|
|
|
float constantvalue; |
|
}; |
|
|
|
struct TestParams_t |
|
{ |
|
TestParams_t() : |
|
testundo( false ), |
|
usecurves( false ), |
|
purgevalues( true ), |
|
testabort( false ), |
|
spew( 0 ), |
|
spewnontopmostlayers( false ), |
|
defaultcurve( CURVE_DEFAULT ), |
|
mintime( DmeTime_t( 0 ) ), |
|
maxtime( DmeTime_t( 100 ) ) |
|
{ |
|
} |
|
int spew; |
|
bool usecurves; |
|
bool purgevalues; |
|
bool testundo; |
|
bool testabort; |
|
bool spewnontopmostlayers; |
|
int defaultcurve; |
|
DmeTime_t mintime; |
|
DmeTime_t maxtime; |
|
CUtlVector< TestLayer_t > layers; |
|
|
|
void Reset() |
|
{ |
|
purgevalues = true; |
|
usecurves = false; |
|
testundo = false; |
|
testabort = false; |
|
spewnontopmostlayers = false; |
|
spew = 0; |
|
mintime = DmeTime_t( 0 ); |
|
maxtime = DmeTime_t( 100 ); |
|
defaultcurve = CURVE_DEFAULT; |
|
layers.RemoveAll(); |
|
} |
|
|
|
void AddLayer( DmeTime_t start, DmeTime_t end, DmeTime_t step, int curvetype, int valuetype, float constantvalue = 0.0f ) |
|
{ |
|
TestLayer_t tl; |
|
tl.startTime = start; |
|
tl.endTime = end; |
|
tl.timeStep = step; |
|
tl.curvetype = curvetype; |
|
tl.type = valuetype; |
|
tl.constantvalue = constantvalue; |
|
|
|
layers.AddToTail( tl ); |
|
} |
|
}; |
|
|
|
static void RunLayerTest( char const *testname, CUtlVector< CDmeChannel * >& channels, const TestParams_t& params ) |
|
{ |
|
if ( params.layers.Count() == 0 ) |
|
{ |
|
Assert( 0 ); |
|
return; |
|
} |
|
|
|
Msg( "Test '%s'...\n", testname ); |
|
|
|
g_pDataModel->StartUndo( testname, testname ); |
|
|
|
int i; |
|
int c = channels.Count(); |
|
|
|
{ |
|
CDisableUndoScopeGuard guard; |
|
|
|
for ( i = 0; i < NUM_CHANNELS; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
pLog->ClearKeys(); // reset it |
|
|
|
CDmeCurveInfo *pCurveInfo = NULL; |
|
if ( params.usecurves ) |
|
{ |
|
pCurveInfo = pLog->GetOrCreateCurveInfo(); |
|
pCurveInfo->SetDefaultCurveType( params.defaultcurve ); |
|
pCurveInfo->SetMinValue( 0.0f ); |
|
pCurveInfo->SetMaxValue( 1000.0f ); |
|
} |
|
else |
|
{ |
|
if ( pLog->GetCurveInfo() ) |
|
{ |
|
g_pDataModel->DestroyElement( pLog->GetCurveInfo()->GetHandle() ); |
|
} |
|
pLog->SetCurveInfo( NULL ); |
|
} |
|
|
|
const TestLayer_t& tl = params.layers[ 0 ]; |
|
// Now add entries |
|
DmeTime_t logStep = tl.timeStep; |
|
DmeTime_t logStart = tl.startTime; |
|
|
|
for ( DmeTime_t t = logStart; t <= tl.endTime + logStep - DmeTime_t( 1 ); t += logStep ) |
|
{ |
|
DmeTime_t useTime = t; |
|
if ( useTime > tl.endTime ) |
|
{ |
|
useTime = tl.endTime; |
|
} |
|
float value = tl.ValueForTime( useTime ); |
|
if ( tl.usecurvetype ) |
|
{ |
|
pLog->SetKey( useTime, value, tl.curvetype ); |
|
} |
|
else |
|
{ |
|
pLog->SetKey( useTime, value ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
for ( int layer = 1; layer < params.layers.Count(); ++layer ) |
|
{ |
|
const TestLayer_t& tl = params.layers[ layer ]; |
|
|
|
// Test creating a layer and collapsing it back down |
|
g_pChannelRecordingMgr->StartLayerRecording( "layer operations" ); |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
g_pChannelRecordingMgr->AddChannelToRecordingLayer( channels[ i ] ); // calls log->CreateNewLayer() |
|
} |
|
|
|
// Now add values to channel logs |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
|
|
// Now add entries |
|
DmeTime_t logStep = tl.timeStep; |
|
DmeTime_t logStart = tl.startTime; |
|
|
|
for ( DmeTime_t t = logStart; t <= tl.endTime + logStep - DmeTime_t( 1 ); t += logStep ) |
|
{ |
|
DmeTime_t useTime = t; |
|
if ( useTime > tl.endTime ) |
|
{ |
|
useTime = tl.endTime; |
|
} |
|
float value = tl.ValueForTime( useTime ); |
|
if ( tl.usecurvetype ) |
|
{ |
|
pLog->SetKey( useTime, value, tl.curvetype ); |
|
} |
|
else |
|
{ |
|
pLog->SetKey( useTime, value ); |
|
} |
|
} |
|
} |
|
|
|
g_pChannelRecordingMgr->FinishLayerRecording( 0.0f, false ); // don't flatten layers here, we'll do it manually |
|
} |
|
|
|
// Now sample values |
|
CUtlVector< CUtlVector< float > > values; |
|
CUtlVector< CUtlVector< float > > valuesbaked; |
|
|
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
|
|
int idx = values.AddToTail(); |
|
|
|
CUtlVector< float >& v = values[ idx ]; |
|
|
|
// Now get the values of the samples in the log |
|
for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) ) |
|
{ |
|
float fval = pLog->GetValue( j ); |
|
v.AddToTail( fval ); |
|
} |
|
} |
|
|
|
if ( params.spewnontopmostlayers ) |
|
{ |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
|
|
// Now get the values of the samples in the log |
|
for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) ) |
|
{ |
|
float topValue = pLog->GetValue( j ); |
|
float underlyingValue = pLog->GetValueSkippingTopmostLayer( j ); |
|
|
|
Msg( "t(%d) top [%f] rest [%f]\n", |
|
j.GetTenthsOfMS(), topValue, underlyingValue ); |
|
} |
|
} |
|
} |
|
|
|
// Now test creating a layer and "undo/redo" of the layer |
|
if ( params.testundo ) |
|
{ |
|
g_pDataModel->FinishUndo(); |
|
g_pDataModel->Undo(); |
|
g_pDataModel->Redo(); |
|
g_pDataModel->StartUndo( testname, testname ); |
|
} |
|
|
|
{ |
|
CUndoScopeGuard guard( "Bake Layers" ); |
|
// Now bake down and resample values |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
|
|
pLog->FlattenLayers( 0.0f, params.spew & SPEW_DIFFS ); |
|
|
|
int idx = valuesbaked.AddToTail(); |
|
|
|
CUtlVector< float >& v = valuesbaked[ idx ]; |
|
|
|
// Now get the values of the samples in the log |
|
for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) ) |
|
{ |
|
float fval = pLog->GetValue( j ); |
|
v.AddToTail( fval ); |
|
} |
|
} |
|
} |
|
|
|
ValidateDataSets( params.spew, testname, values, valuesbaked ); |
|
|
|
// Now test creating a layer and "undo/redo" of the layer |
|
if ( params.testundo ) |
|
{ |
|
g_pDataModel->FinishUndo(); |
|
g_pDataModel->Undo(); |
|
g_pDataModel->Redo(); |
|
g_pDataModel->StartUndo( testname, testname ); |
|
} |
|
|
|
if ( params.testabort ) |
|
{ |
|
g_pDataModel->AbortUndoableOperation(); |
|
} |
|
else |
|
{ |
|
g_pDataModel->FinishUndo(); |
|
} |
|
} |
|
|
|
static void RunTimeSelectionTest( char const *testname, CUtlVector< CDmeChannel * >& channels, |
|
const TestParams_t& params, DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& ts, float value ) |
|
{ |
|
if ( params.layers.Count() == 0 ) |
|
{ |
|
Assert( 0 ); |
|
return; |
|
} |
|
|
|
Msg( "Test '%s'...\n", testname ); |
|
|
|
int i, j; |
|
int c = channels.Count(); |
|
|
|
if ( params.purgevalues ) |
|
{ |
|
CDisableUndoScopeGuard guard; |
|
|
|
for ( i = 0; i < NUM_CHANNELS; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
pLog->ClearKeys(); // reset it |
|
|
|
CDmeCurveInfo *pCurveInfo = params.usecurves ? pLog->GetOrCreateCurveInfo() : pLog->GetCurveInfo(); |
|
if ( params.usecurves ) |
|
{ |
|
pCurveInfo->SetDefaultCurveType( params.defaultcurve ); |
|
pCurveInfo->SetMinValue( 0.0f ); |
|
pCurveInfo->SetMaxValue( 1000.0f ); |
|
} |
|
else if ( !params.usecurves && pCurveInfo ) |
|
{ |
|
g_pDataModel->DestroyElement( pCurveInfo->GetHandle() ); |
|
pLog->SetCurveInfo( NULL ); |
|
} |
|
|
|
const TestLayer_t& tl = params.layers[ 0 ]; |
|
// Now add entries |
|
DmeTime_t logStep = tl.timeStep; |
|
DmeTime_t logStart = tl.startTime; |
|
|
|
for ( DmeTime_t t = logStart; t <= tl.endTime + logStep - DmeTime_t( 1 ); t += logStep ) |
|
{ |
|
DmeTime_t useTime = t; |
|
if ( useTime > tl.endTime ) |
|
useTime = tl.endTime; |
|
|
|
float value = tl.ValueForTime( useTime ); |
|
if ( tl.usecurvetype ) |
|
{ |
|
pLog->SetKey( useTime, value, tl.curvetype ); |
|
} |
|
else |
|
{ |
|
pLog->SetKey( useTime, value ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Test creating a layer and collapsing it back down |
|
g_pChannelRecordingMgr->StartLayerRecording( "layer operations", &ts ); |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
g_pChannelRecordingMgr->AddChannelToRecordingLayer( channels[ i ] ); // calls log->CreateNewLayer() |
|
} |
|
|
|
// Now add values to channel logs |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
|
|
pLog->StampKeyAtHead( tHeadPosition, tHeadPosition, ts, value ); |
|
} |
|
|
|
// Flattens the layers |
|
g_pChannelRecordingMgr->FinishLayerRecording( 0.0f, true ); |
|
|
|
if ( params.spew & SPEW_VALUES ) |
|
{ |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
Assert( pLog->GetNumLayers() == 1 ); |
|
|
|
for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) ) |
|
{ |
|
float fval = pLog->GetValue( j ); |
|
Msg( "%d %f\n", j.GetTenthsOfMS(), fval ); |
|
} |
|
} |
|
} |
|
|
|
if ( params.spew & SPEW_KEYS ) |
|
{ |
|
for ( i = 0; i < c; ++i ) |
|
{ |
|
CDmeChannel *channel = channels[ i ]; |
|
CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() ); |
|
Assert( pLog ); |
|
Assert( pLog->GetNumLayers() == 1 ); |
|
|
|
int kc = pLog->GetKeyCount(); |
|
for ( j = 0; j < kc; ++j ) |
|
{ |
|
DmeTime_t time = pLog->GetKeyTime( j ); |
|
|
|
float fval = pLog->GetValue( time ); |
|
Msg( "%d %f %f\n", j, time.GetSeconds(), fval ); |
|
} |
|
} |
|
} |
|
|
|
// Now test creating a layer and "undo/redo" of the layer |
|
if ( params.testundo ) |
|
{ |
|
g_pDataModel->Undo(); |
|
g_pDataModel->Redo(); |
|
} |
|
} |
|
|
|
DEFINE_TESTCASE_NOSUITE( DmxTestDmeLogLayers ) |
|
{ |
|
Msg( "Running CDmeTypedLog<float> layering tests...\n" ); |
|
|
|
#ifdef _DEBUG |
|
int nStartingCount = g_pDataModel->GetAllocatedElementCount(); |
|
#endif |
|
|
|
CUtlVector< CDmeChannel * > channels; |
|
|
|
DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxTestDmeLogLayers>" ); |
|
|
|
CreateChannels( NUM_CHANNELS, channels, fileid ); |
|
|
|
TestParams_t params; |
|
{ |
|
params.testundo = false; |
|
params.usecurves = false; |
|
params.defaultcurve = CURVE_DEFAULT; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_DEFAULT, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 95 ), DmeTime_t( 10 ), CURVE_DEFAULT, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "One-Layer", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Single layer using lerp everywhere |
|
// ----------------------- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "One-Layer Lerp", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Two layers using lerp |
|
// ---------------------------- |
|
// ------------------------ |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 95 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Two-Layer Lerp (contained)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Two layers using CURVE_EASE_IN_TO_EASE_OUT, there should be some disparity |
|
// ---------------------------- |
|
// ------------------------ |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_EASE_IN_TO_EASE_OUT; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_EASE_IN_TO_EASE_OUT, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 95 ), DmeTime_t( 10 ), CURVE_EASE_IN_TO_EASE_OUT, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Two-Layer Ease In/Out (contained)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Two layers using lerp |
|
// ---------------------------- |
|
// --------- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.mintime = DmeTime_t( -20 ); |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( -20 ), DmeTime_t( 20 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Two-Layer Lerp (overhang start)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Two layers using lerp |
|
// ---------------------------- |
|
// ------------ |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.maxtime = DmeTime_t( 120 ); |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 80 ), DmeTime_t( 120 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Two-Layer Lerp (overhang end)", channels, params ); |
|
params.Reset(); |
|
} |
|
// Three layers using lerp |
|
// ------------- |
|
// ----- ----- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.mintime = DmeTime_t( -12 ); |
|
params.maxtime = DmeTime_t( 115 ); |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( -12 ), DmeTime_t( 12 ), DmeTime_t( 4 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 85 ), DmeTime_t( 115 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Three-Layer Lerp (overhang start + end)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Three layers using lerp |
|
// ------------- |
|
// ----- |
|
// -- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 25 ), DmeTime_t( 75 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 40 ), DmeTime_t( 60 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Three-Layer Lerp (layer inside layer)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Three layers using lerp |
|
// ------------- |
|
// ----- |
|
// -- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 25 ), DmeTime_t( 75 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 70 ), DmeTime_t( 80 ), DmeTime_t( 2 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Three-Layer Lerp (first layer contained, second layer overlapping first at end)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Three layers using lerp |
|
// ------------- |
|
// ----- |
|
// -- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 25 ), DmeTime_t( 75 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 15 ), DmeTime_t( 35 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Three-Layer Lerp (first layer contained, second layer overlapping first at start)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Four layers using lerp |
|
// --------------- |
|
// ----- |
|
// ---- |
|
// ------- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
// params.spewnontopmostlayers = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 20.0f ); |
|
params.AddLayer( DmeTime_t( 15 ), DmeTime_t( 40 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 60 ), DmeTime_t( 85 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
params.AddLayer( DmeTime_t( 35 ), DmeTime_t( 79 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Four-Layer Lerp (top overlapping end of 1st and start of 2nd layer)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// Single layer using lerp everywhere |
|
// ----------------------- |
|
{ |
|
params.testundo = false; |
|
params.usecurves = true; |
|
params.spew = 0; //SPEW_VALUES | SPEW_KEYS; |
|
params.mintime = DmeTime_t( 0 ); |
|
params.maxtime = DmeTime_t( 10000 ); |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 10000 ), DmeTime_t( 20 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SINE, 100.0f ); |
|
|
|
DmeTime_t tHeadPosition = DmeTime_t( 5000 ); |
|
|
|
DmeLog_TimeSelection_t ts; |
|
ts.m_nTimes[ TS_LEFT_FALLOFF ] = tHeadPosition + DmeTime_t( -987 ); |
|
ts.m_nTimes[ TS_LEFT_HOLD ] = ts.m_nTimes[ TS_RIGHT_HOLD ] = tHeadPosition; |
|
ts.m_nTimes[ TS_RIGHT_FALLOFF ] = tHeadPosition + DmeTime_t( 1052 ); |
|
ts.m_nFalloffInterpolatorTypes[ 0 ] = ts.m_nFalloffInterpolatorTypes[ 1 ] = INTERPOLATE_EASE_INOUT; |
|
|
|
// Resample at 50 msec intervals |
|
ts.m_bResampleMode = true; |
|
ts.m_nResampleInterval = DmeTime_t( 50 ); |
|
|
|
///params.spew |= SPEW_KEYS | SPEW_VALUES; |
|
|
|
RunTimeSelectionTest( "One-Layer Time Selection at 50, falloff 25, EASE_INOUT interp", channels, params, tHeadPosition, ts, 250 ); |
|
|
|
params.purgevalues = false; |
|
// params.spew |= SPEW_VALUES; |
|
|
|
// Shift the head and do it all again |
|
tHeadPosition = DmeTime_t( 2000 ); |
|
ts.m_nTimes[ TS_LEFT_FALLOFF ] = DmeTime_t( 1487 ); |
|
ts.m_nTimes[ TS_LEFT_HOLD ] = ts.m_nTimes[ TS_RIGHT_HOLD ] = tHeadPosition; |
|
ts.m_nTimes[ TS_RIGHT_FALLOFF ] = tHeadPosition + DmeTime_t( 631 ); |
|
|
|
RunTimeSelectionTest( "2nd layer", channels, params, tHeadPosition, ts, 500 ); |
|
params.Reset(); |
|
} |
|
// Single layer using lerp everywhere |
|
// ----------------------- |
|
{ |
|
params.testundo = true; |
|
params.usecurves = true; |
|
params.spew = 0; //SPEW_VALUES | SPEW_KEYS; |
|
params.mintime = DmeTime_t( 0 ); |
|
params.maxtime = DmeTime_t( 1000 ); |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 1000 ), DmeTime_t( 20 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 100.0f ); |
|
|
|
DmeTime_t tHeadPosition = DmeTime_t( 500 ); |
|
DmeLog_TimeSelection_t ts; |
|
ts.m_nTimes[ TS_LEFT_FALLOFF ] = tHeadPosition + DmeTime_t( -100 ); |
|
ts.m_nTimes[ TS_LEFT_HOLD ] = ts.m_nTimes[ TS_RIGHT_HOLD ] = tHeadPosition; |
|
ts.m_nTimes[ TS_RIGHT_FALLOFF ] = tHeadPosition + DmeTime_t( 100 ); |
|
ts.m_nFalloffInterpolatorTypes[ 0 ] = ts.m_nFalloffInterpolatorTypes[ 1 ] = INTERPOLATE_LINEAR_INTERP; |
|
|
|
// Resample at 50 msec intervals |
|
ts.m_bResampleMode = true; |
|
ts.m_nResampleInterval = DmeTime_t( 10 ); |
|
|
|
// params.spew |= SPEW_VALUES; |
|
|
|
RunTimeSelectionTest( "Resetting layer", channels, params, tHeadPosition, ts, 200 ); |
|
|
|
params.purgevalues = false; |
|
//params.spew |= SPEW_VALUES; |
|
|
|
// Shift the head and do it all again |
|
//ts.m_nRelativeFalloffTimes[ 0 ] = 1487 - 2000; |
|
//ts.m_nRelativeHoldTimes[ 0 ] = ts.m_nRelativeHoldTimes[ 1 ] = 0; |
|
//ts.m_nRelativeFalloffTimes[ 1 ] = 631; |
|
//ts.SetHeadPosition( 2000 ); |
|
|
|
RunTimeSelectionTest( "2nd layer", channels, params, tHeadPosition, ts, 110 ); |
|
params.Reset(); |
|
} |
|
// g_pDataModel->TraceUndo( true ); |
|
|
|
// Test abort undo stuff |
|
for ( int i = 0; i < 2; ++i ) |
|
// Four layers using lerp |
|
// --------------- |
|
// ----- |
|
// ---- |
|
// ------- |
|
{ |
|
params.testundo = false; |
|
params.testabort = i != 1 ? true : false; |
|
params.usecurves = false; |
|
// params.spewnontopmostlayers = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 10 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 20.0f ); |
|
params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 6 ), DmeTime_t( 1 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Four-Layer Lerp (top overlapping end of 1st and start of 2nd layer)", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// g_pDataModel->TraceUndo( false ); |
|
|
|
|
|
//DestroyChannels( channels ); |
|
|
|
g_pDataModel->ClearUndo(); |
|
|
|
g_pDataModel->RemoveFileId( fileid ); |
|
|
|
#ifdef _DEBUG |
|
int nEndingCount = g_pDataModel->GetAllocatedElementCount(); |
|
AssertEquals( nEndingCount, nStartingCount ); |
|
if ( nEndingCount != nStartingCount ) |
|
{ |
|
for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ; |
|
hElement != DMELEMENT_HANDLE_INVALID; |
|
hElement = g_pDataModel->NextAllocatedElement( hElement ) ) |
|
{ |
|
CDmElement *pElement = g_pDataModel->GetElement( hElement ); |
|
Assert( pElement ); |
|
if ( !pElement ) |
|
return; |
|
|
|
Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() ); |
|
} |
|
} |
|
#endif |
|
} |
|
|
|
DEFINE_TESTCASE_NOSUITE( DmxTestDmeLogLayersUndo ) |
|
{ |
|
Msg( "Running CDmeTypedLog<float> layering UNDO tests...\n" ); |
|
|
|
#ifdef _DEBUG |
|
int nStartingCount = g_pDataModel->GetAllocatedElementCount(); |
|
#endif |
|
|
|
CUtlVector< CDmeChannel * > channels; |
|
|
|
DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxTestDmeLogLayersUndo>" ); |
|
|
|
CreateChannels( NUM_CHANNELS, channels, fileid ); |
|
|
|
TestParams_t params; |
|
|
|
// g_pDataModel->TraceUndo( true ); |
|
|
|
// Test abort undo stuff |
|
for ( int i = 0; i < 2; ++i ) |
|
{ |
|
params.testundo = false; |
|
params.testabort = true; |
|
params.usecurves = false; |
|
// params.spewnontopmostlayers = true; |
|
params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP; |
|
params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 1000 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 20.0f ); |
|
params.AddLayer( DmeTime_t( 100 ), DmeTime_t( 900 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE ); |
|
RunLayerTest( "Abort undo", channels, params ); |
|
params.Reset(); |
|
} |
|
|
|
// g_pDataModel->TraceUndo( false ); |
|
|
|
g_pDataModel->ClearUndo(); |
|
g_pDataModel->RemoveFileId( fileid ); |
|
|
|
#ifdef _DEBUG |
|
int nEndingCount = g_pDataModel->GetAllocatedElementCount(); |
|
AssertEquals( nEndingCount, nStartingCount ); |
|
if ( nEndingCount != nStartingCount ) |
|
{ |
|
for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ; |
|
hElement != DMELEMENT_HANDLE_INVALID; |
|
hElement = g_pDataModel->NextAllocatedElement( hElement ) ) |
|
{ |
|
CDmElement *pElement = g_pDataModel->GetElement( hElement ); |
|
Assert( pElement ); |
|
if ( !pElement ) |
|
return; |
|
|
|
Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() ); |
|
} |
|
} |
|
#endif |
|
}
|
|
|