Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "unitlib/unitlib.h"
  9. #include "datamodel/dmelement.h"
  10. #include "movieobjects/movieobjects.h"
  11. #include "datamodel/idatamodel.h"
  12. #include "movieobjects/dmechannel.h"
  13. #include "movieobjects/dmelog.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. #define NUM_CHANNELS 1
  17. #define NUM_LOG_ENTRIES 10
  18. enum
  19. {
  20. SPEW_DIFFS = (1<<0),
  21. SPEW_VALUES= (1<<1),
  22. SPEW_KEYS= (1<<2),
  23. };
  24. static void ValidateDataSets( int spew, char const *testname, CUtlVector< CUtlVector< float > >& values, CUtlVector< CUtlVector< float > >& valuesbaked )
  25. {
  26. int i, j;
  27. // Compare baked, unbaked values
  28. Assert( values.Count() == valuesbaked.Count() );
  29. int c = values.Count();
  30. bool differs = false;
  31. bool spewvalues = ( spew & SPEW_VALUES ) ? true : false;
  32. float tol = 0.0001f;
  33. for ( i = 0; i < c; ++i )
  34. {
  35. CUtlVector< float >& v = values[ i ];
  36. CUtlVector< float >& vb = valuesbaked[ i ];
  37. Assert( v.Count() == vb.Count() );
  38. // Now get the values of the samples in the log
  39. for ( j = 0; j < v.Count(); ++j )
  40. {
  41. Assert( vb.IsValidIndex( j ) );
  42. if ( !vb.IsValidIndex( j ) )
  43. continue;
  44. float v1 = v[ j ];
  45. float v2 = vb[ j ];
  46. if ( fabs( v1 - v2 ) > tol )
  47. {
  48. differs = true;
  49. }
  50. if ( spewvalues )
  51. {
  52. Msg( "%d %f %f\n", j, v[ j ], vb[ j ] );
  53. }
  54. }
  55. }
  56. Msg( " %s\n", differs ? "FAILED" : "OK" );
  57. if ( !(spew & SPEW_DIFFS ) )
  58. return;
  59. for ( i = 0; i < c; ++i )
  60. {
  61. CUtlVector< float >& v = values[ i ];
  62. CUtlVector< float >& vb = valuesbaked[ i ];
  63. Assert( v.Count() == vb.Count() );
  64. // Now get the values of the samples in the log
  65. for ( j = 0; j < v.Count(); ++j )
  66. {
  67. Assert( vb.IsValidIndex( j ) );
  68. if ( !vb.IsValidIndex( j ) )
  69. continue;
  70. if ( v[ j ] == vb[ j ] )
  71. {
  72. if ( differs )
  73. {
  74. Msg( "%d found %f to equal %f\n", j, v[ j ], vb[ j ] );
  75. }
  76. continue;
  77. }
  78. Msg( "%d expected %f to equal %f\n", j, v[ j ], vb[ j ] );
  79. }
  80. }
  81. if ( differs )
  82. {
  83. Msg( "End Test '%s'\n---------------\n", testname );
  84. }
  85. }
  86. static void CreateChannels( int num, CUtlVector< CDmeChannel * >& channels, DmFileId_t fileid )
  87. {
  88. CDisableUndoScopeGuard guard;
  89. for ( int i = 0; i < num; ++i )
  90. {
  91. CDmeChannel *channel = NULL;
  92. channel = CreateElement< CDmeChannel >( "channel1", fileid );
  93. channels.AddToTail( channel );
  94. channel->CreateLog( AT_FLOAT ); // only care about float logs for now
  95. channel->SetMode( CM_PLAY );// Make sure it's in playback mode
  96. }
  97. }
  98. struct TestLayer_t
  99. {
  100. enum
  101. {
  102. TYPE_SIMPLESLOPE = 0, // value == time
  103. TYPE_SINE, // sinusoidal
  104. TYPE_CONSTANT,
  105. };
  106. TestLayer_t() :
  107. startTime( 0 ),
  108. endTime( 0 ),
  109. timeStep( 0 ),
  110. usecurvetype( false ),
  111. curvetype( CURVE_DEFAULT ),
  112. type( TYPE_SIMPLESLOPE ),
  113. constantvalue( 0.0f )
  114. {
  115. }
  116. float ValueForTime( DmeTime_t time ) const
  117. {
  118. float t = (float)time.GetSeconds();
  119. switch ( type )
  120. {
  121. default:
  122. case TYPE_SIMPLESLOPE:
  123. return t;
  124. case TYPE_SINE:
  125. return constantvalue * ( 1.0f + sin( ( t * 0.002f ) * 2 * M_PI ) ) * 0.5f;
  126. case TYPE_CONSTANT:
  127. return constantvalue;
  128. }
  129. return t;
  130. }
  131. int type;
  132. DmeTime_t startTime;
  133. DmeTime_t endTime;
  134. DmeTime_t timeStep;
  135. bool usecurvetype;
  136. int curvetype;
  137. float constantvalue;
  138. };
  139. struct TestParams_t
  140. {
  141. TestParams_t() :
  142. testundo( false ),
  143. usecurves( false ),
  144. purgevalues( true ),
  145. testabort( false ),
  146. spew( 0 ),
  147. spewnontopmostlayers( false ),
  148. defaultcurve( CURVE_DEFAULT ),
  149. mintime( DmeTime_t( 0 ) ),
  150. maxtime( DmeTime_t( 100 ) )
  151. {
  152. }
  153. int spew;
  154. bool usecurves;
  155. bool purgevalues;
  156. bool testundo;
  157. bool testabort;
  158. bool spewnontopmostlayers;
  159. int defaultcurve;
  160. DmeTime_t mintime;
  161. DmeTime_t maxtime;
  162. CUtlVector< TestLayer_t > layers;
  163. void Reset()
  164. {
  165. purgevalues = true;
  166. usecurves = false;
  167. testundo = false;
  168. testabort = false;
  169. spewnontopmostlayers = false;
  170. spew = 0;
  171. mintime = DmeTime_t( 0 );
  172. maxtime = DmeTime_t( 100 );
  173. defaultcurve = CURVE_DEFAULT;
  174. layers.RemoveAll();
  175. }
  176. void AddLayer( DmeTime_t start, DmeTime_t end, DmeTime_t step, int curvetype, int valuetype, float constantvalue = 0.0f )
  177. {
  178. TestLayer_t tl;
  179. tl.startTime = start;
  180. tl.endTime = end;
  181. tl.timeStep = step;
  182. tl.curvetype = curvetype;
  183. tl.type = valuetype;
  184. tl.constantvalue = constantvalue;
  185. layers.AddToTail( tl );
  186. }
  187. };
  188. static void RunLayerTest( char const *testname, CUtlVector< CDmeChannel * >& channels, const TestParams_t& params )
  189. {
  190. if ( params.layers.Count() == 0 )
  191. {
  192. Assert( 0 );
  193. return;
  194. }
  195. Msg( "Test '%s'...\n", testname );
  196. g_pDataModel->StartUndo( testname, testname );
  197. int i;
  198. int c = channels.Count();
  199. {
  200. CDisableUndoScopeGuard guard;
  201. for ( i = 0; i < NUM_CHANNELS; ++i )
  202. {
  203. CDmeChannel *channel = channels[ i ];
  204. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  205. Assert( pLog );
  206. pLog->ClearKeys(); // reset it
  207. CDmeCurveInfo *pCurveInfo = NULL;
  208. if ( params.usecurves )
  209. {
  210. pCurveInfo = pLog->GetOrCreateCurveInfo();
  211. pCurveInfo->SetDefaultCurveType( params.defaultcurve );
  212. pCurveInfo->SetMinValue( 0.0f );
  213. pCurveInfo->SetMaxValue( 1000.0f );
  214. }
  215. else
  216. {
  217. if ( pLog->GetCurveInfo() )
  218. {
  219. g_pDataModel->DestroyElement( pLog->GetCurveInfo()->GetHandle() );
  220. }
  221. pLog->SetCurveInfo( NULL );
  222. }
  223. const TestLayer_t& tl = params.layers[ 0 ];
  224. // Now add entries
  225. DmeTime_t logStep = tl.timeStep;
  226. DmeTime_t logStart = tl.startTime;
  227. for ( DmeTime_t t = logStart; t <= tl.endTime + logStep - DmeTime_t( 1 ); t += logStep )
  228. {
  229. DmeTime_t useTime = t;
  230. if ( useTime > tl.endTime )
  231. {
  232. useTime = tl.endTime;
  233. }
  234. float value = tl.ValueForTime( useTime );
  235. if ( tl.usecurvetype )
  236. {
  237. pLog->SetKey( useTime, value, tl.curvetype );
  238. }
  239. else
  240. {
  241. pLog->SetKey( useTime, value );
  242. }
  243. }
  244. }
  245. }
  246. for ( int layer = 1; layer < params.layers.Count(); ++layer )
  247. {
  248. const TestLayer_t& tl = params.layers[ layer ];
  249. // Test creating a layer and collapsing it back down
  250. g_pChannelRecordingMgr->StartLayerRecording( "layer operations" );
  251. for ( i = 0; i < c; ++i )
  252. {
  253. g_pChannelRecordingMgr->AddChannelToRecordingLayer( channels[ i ] ); // calls log->CreateNewLayer()
  254. }
  255. // Now add values to channel logs
  256. for ( i = 0; i < c; ++i )
  257. {
  258. CDmeChannel *channel = channels[ i ];
  259. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  260. Assert( pLog );
  261. // Now add entries
  262. DmeTime_t logStep = tl.timeStep;
  263. DmeTime_t logStart = tl.startTime;
  264. for ( DmeTime_t t = logStart; t <= tl.endTime + logStep - DmeTime_t( 1 ); t += logStep )
  265. {
  266. DmeTime_t useTime = t;
  267. if ( useTime > tl.endTime )
  268. {
  269. useTime = tl.endTime;
  270. }
  271. float value = tl.ValueForTime( useTime );
  272. if ( tl.usecurvetype )
  273. {
  274. pLog->SetKey( useTime, value, tl.curvetype );
  275. }
  276. else
  277. {
  278. pLog->SetKey( useTime, value );
  279. }
  280. }
  281. }
  282. g_pChannelRecordingMgr->FinishLayerRecording( 0.0f, false ); // don't flatten layers here, we'll do it manually
  283. }
  284. // Now sample values
  285. CUtlVector< CUtlVector< float > > values;
  286. CUtlVector< CUtlVector< float > > valuesbaked;
  287. for ( i = 0; i < c; ++i )
  288. {
  289. CDmeChannel *channel = channels[ i ];
  290. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  291. Assert( pLog );
  292. int idx = values.AddToTail();
  293. CUtlVector< float >& v = values[ idx ];
  294. // Now get the values of the samples in the log
  295. for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) )
  296. {
  297. float fval = pLog->GetValue( j );
  298. v.AddToTail( fval );
  299. }
  300. }
  301. if ( params.spewnontopmostlayers )
  302. {
  303. for ( i = 0; i < c; ++i )
  304. {
  305. CDmeChannel *channel = channels[ i ];
  306. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  307. Assert( pLog );
  308. // Now get the values of the samples in the log
  309. for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) )
  310. {
  311. float topValue = pLog->GetValue( j );
  312. float underlyingValue = pLog->GetValueSkippingTopmostLayer( j );
  313. Msg( "t(%d) top [%f] rest [%f]\n",
  314. j.GetTenthsOfMS(), topValue, underlyingValue );
  315. }
  316. }
  317. }
  318. // Now test creating a layer and "undo/redo" of the layer
  319. if ( params.testundo )
  320. {
  321. g_pDataModel->FinishUndo();
  322. g_pDataModel->Undo();
  323. g_pDataModel->Redo();
  324. g_pDataModel->StartUndo( testname, testname );
  325. }
  326. {
  327. CUndoScopeGuard guard( "Bake Layers" );
  328. // Now bake down and resample values
  329. for ( i = 0; i < c; ++i )
  330. {
  331. CDmeChannel *channel = channels[ i ];
  332. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  333. Assert( pLog );
  334. pLog->FlattenLayers( 0.0f, params.spew & SPEW_DIFFS );
  335. int idx = valuesbaked.AddToTail();
  336. CUtlVector< float >& v = valuesbaked[ idx ];
  337. // Now get the values of the samples in the log
  338. for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) )
  339. {
  340. float fval = pLog->GetValue( j );
  341. v.AddToTail( fval );
  342. }
  343. }
  344. }
  345. ValidateDataSets( params.spew, testname, values, valuesbaked );
  346. // Now test creating a layer and "undo/redo" of the layer
  347. if ( params.testundo )
  348. {
  349. g_pDataModel->FinishUndo();
  350. g_pDataModel->Undo();
  351. g_pDataModel->Redo();
  352. g_pDataModel->StartUndo( testname, testname );
  353. }
  354. if ( params.testabort )
  355. {
  356. g_pDataModel->AbortUndoableOperation();
  357. }
  358. else
  359. {
  360. g_pDataModel->FinishUndo();
  361. }
  362. }
  363. static void RunTimeSelectionTest( char const *testname, CUtlVector< CDmeChannel * >& channels,
  364. const TestParams_t& params, DmeTime_t tHeadPosition, DmeLog_TimeSelection_t& ts, float value )
  365. {
  366. if ( params.layers.Count() == 0 )
  367. {
  368. Assert( 0 );
  369. return;
  370. }
  371. Msg( "Test '%s'...\n", testname );
  372. int i, j;
  373. int c = channels.Count();
  374. if ( params.purgevalues )
  375. {
  376. CDisableUndoScopeGuard guard;
  377. for ( i = 0; i < NUM_CHANNELS; ++i )
  378. {
  379. CDmeChannel *channel = channels[ i ];
  380. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  381. Assert( pLog );
  382. pLog->ClearKeys(); // reset it
  383. CDmeCurveInfo *pCurveInfo = params.usecurves ? pLog->GetOrCreateCurveInfo() : pLog->GetCurveInfo();
  384. if ( params.usecurves )
  385. {
  386. pCurveInfo->SetDefaultCurveType( params.defaultcurve );
  387. pCurveInfo->SetMinValue( 0.0f );
  388. pCurveInfo->SetMaxValue( 1000.0f );
  389. }
  390. else if ( !params.usecurves && pCurveInfo )
  391. {
  392. g_pDataModel->DestroyElement( pCurveInfo->GetHandle() );
  393. pLog->SetCurveInfo( NULL );
  394. }
  395. const TestLayer_t& tl = params.layers[ 0 ];
  396. // Now add entries
  397. DmeTime_t logStep = tl.timeStep;
  398. DmeTime_t logStart = tl.startTime;
  399. for ( DmeTime_t t = logStart; t <= tl.endTime + logStep - DmeTime_t( 1 ); t += logStep )
  400. {
  401. DmeTime_t useTime = t;
  402. if ( useTime > tl.endTime )
  403. useTime = tl.endTime;
  404. float value = tl.ValueForTime( useTime );
  405. if ( tl.usecurvetype )
  406. {
  407. pLog->SetKey( useTime, value, tl.curvetype );
  408. }
  409. else
  410. {
  411. pLog->SetKey( useTime, value );
  412. }
  413. }
  414. }
  415. }
  416. // Test creating a layer and collapsing it back down
  417. g_pChannelRecordingMgr->StartLayerRecording( "layer operations", &ts );
  418. for ( i = 0; i < c; ++i )
  419. {
  420. g_pChannelRecordingMgr->AddChannelToRecordingLayer( channels[ i ] ); // calls log->CreateNewLayer()
  421. }
  422. // Now add values to channel logs
  423. for ( i = 0; i < c; ++i )
  424. {
  425. CDmeChannel *channel = channels[ i ];
  426. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  427. Assert( pLog );
  428. pLog->StampKeyAtHead( tHeadPosition, tHeadPosition, ts, value );
  429. }
  430. // Flattens the layers
  431. g_pChannelRecordingMgr->FinishLayerRecording( 0.0f, true );
  432. if ( params.spew & SPEW_VALUES )
  433. {
  434. for ( i = 0; i < c; ++i )
  435. {
  436. CDmeChannel *channel = channels[ i ];
  437. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  438. Assert( pLog );
  439. Assert( pLog->GetNumLayers() == 1 );
  440. for ( DmeTime_t j = params.mintime; j <= params.maxtime; j += DmeTime_t( 1 ) )
  441. {
  442. float fval = pLog->GetValue( j );
  443. Msg( "%d %f\n", j.GetTenthsOfMS(), fval );
  444. }
  445. }
  446. }
  447. if ( params.spew & SPEW_KEYS )
  448. {
  449. for ( i = 0; i < c; ++i )
  450. {
  451. CDmeChannel *channel = channels[ i ];
  452. CDmeTypedLog< float > *pLog = CastElement< CDmeTypedLog< float > >( channel->GetLog() );
  453. Assert( pLog );
  454. Assert( pLog->GetNumLayers() == 1 );
  455. int kc = pLog->GetKeyCount();
  456. for ( j = 0; j < kc; ++j )
  457. {
  458. DmeTime_t time = pLog->GetKeyTime( j );
  459. float fval = pLog->GetValue( time );
  460. Msg( "%d %f %f\n", j, time.GetSeconds(), fval );
  461. }
  462. }
  463. }
  464. // Now test creating a layer and "undo/redo" of the layer
  465. if ( params.testundo )
  466. {
  467. g_pDataModel->Undo();
  468. g_pDataModel->Redo();
  469. }
  470. }
  471. DEFINE_TESTCASE_NOSUITE( DmxTestDmeLogLayers )
  472. {
  473. Msg( "Running CDmeTypedLog<float> layering tests...\n" );
  474. #ifdef _DEBUG
  475. int nStartingCount = g_pDataModel->GetAllocatedElementCount();
  476. #endif
  477. CUtlVector< CDmeChannel * > channels;
  478. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxTestDmeLogLayers>" );
  479. CreateChannels( NUM_CHANNELS, channels, fileid );
  480. TestParams_t params;
  481. {
  482. params.testundo = false;
  483. params.usecurves = false;
  484. params.defaultcurve = CURVE_DEFAULT;
  485. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_DEFAULT, TestLayer_t::TYPE_SIMPLESLOPE );
  486. params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 95 ), DmeTime_t( 10 ), CURVE_DEFAULT, TestLayer_t::TYPE_SIMPLESLOPE );
  487. RunLayerTest( "One-Layer", channels, params );
  488. params.Reset();
  489. }
  490. // Single layer using lerp everywhere
  491. // -----------------------
  492. {
  493. params.testundo = false;
  494. params.usecurves = true;
  495. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  496. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  497. RunLayerTest( "One-Layer Lerp", channels, params );
  498. params.Reset();
  499. }
  500. // Two layers using lerp
  501. // ----------------------------
  502. // ------------------------
  503. {
  504. params.testundo = false;
  505. params.usecurves = true;
  506. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  507. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  508. params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 95 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  509. RunLayerTest( "Two-Layer Lerp (contained)", channels, params );
  510. params.Reset();
  511. }
  512. // Two layers using CURVE_EASE_IN_TO_EASE_OUT, there should be some disparity
  513. // ----------------------------
  514. // ------------------------
  515. {
  516. params.testundo = false;
  517. params.usecurves = true;
  518. params.defaultcurve = CURVE_EASE_IN_TO_EASE_OUT;
  519. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_EASE_IN_TO_EASE_OUT, TestLayer_t::TYPE_SIMPLESLOPE );
  520. params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 95 ), DmeTime_t( 10 ), CURVE_EASE_IN_TO_EASE_OUT, TestLayer_t::TYPE_SIMPLESLOPE );
  521. RunLayerTest( "Two-Layer Ease In/Out (contained)", channels, params );
  522. params.Reset();
  523. }
  524. // Two layers using lerp
  525. // ----------------------------
  526. // ---------
  527. {
  528. params.testundo = false;
  529. params.usecurves = true;
  530. params.mintime = DmeTime_t( -20 );
  531. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  532. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  533. params.AddLayer( DmeTime_t( -20 ), DmeTime_t( 20 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  534. RunLayerTest( "Two-Layer Lerp (overhang start)", channels, params );
  535. params.Reset();
  536. }
  537. // Two layers using lerp
  538. // ----------------------------
  539. // ------------
  540. {
  541. params.testundo = false;
  542. params.usecurves = true;
  543. params.maxtime = DmeTime_t( 120 );
  544. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  545. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  546. params.AddLayer( DmeTime_t( 80 ), DmeTime_t( 120 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  547. RunLayerTest( "Two-Layer Lerp (overhang end)", channels, params );
  548. params.Reset();
  549. }
  550. // Three layers using lerp
  551. // -------------
  552. // ----- -----
  553. {
  554. params.testundo = false;
  555. params.usecurves = true;
  556. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  557. params.mintime = DmeTime_t( -12 );
  558. params.maxtime = DmeTime_t( 115 );
  559. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  560. params.AddLayer( DmeTime_t( -12 ), DmeTime_t( 12 ), DmeTime_t( 4 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  561. params.AddLayer( DmeTime_t( 85 ), DmeTime_t( 115 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  562. RunLayerTest( "Three-Layer Lerp (overhang start + end)", channels, params );
  563. params.Reset();
  564. }
  565. // Three layers using lerp
  566. // -------------
  567. // -----
  568. // --
  569. {
  570. params.testundo = false;
  571. params.usecurves = true;
  572. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  573. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  574. params.AddLayer( DmeTime_t( 25 ), DmeTime_t( 75 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  575. params.AddLayer( DmeTime_t( 40 ), DmeTime_t( 60 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  576. RunLayerTest( "Three-Layer Lerp (layer inside layer)", channels, params );
  577. params.Reset();
  578. }
  579. // Three layers using lerp
  580. // -------------
  581. // -----
  582. // --
  583. {
  584. params.testundo = false;
  585. params.usecurves = true;
  586. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  587. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  588. params.AddLayer( DmeTime_t( 25 ), DmeTime_t( 75 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  589. params.AddLayer( DmeTime_t( 70 ), DmeTime_t( 80 ), DmeTime_t( 2 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  590. RunLayerTest( "Three-Layer Lerp (first layer contained, second layer overlapping first at end)", channels, params );
  591. params.Reset();
  592. }
  593. // Three layers using lerp
  594. // -------------
  595. // -----
  596. // --
  597. {
  598. params.testundo = false;
  599. params.usecurves = true;
  600. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  601. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  602. params.AddLayer( DmeTime_t( 25 ), DmeTime_t( 75 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  603. params.AddLayer( DmeTime_t( 15 ), DmeTime_t( 35 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  604. RunLayerTest( "Three-Layer Lerp (first layer contained, second layer overlapping first at start)", channels, params );
  605. params.Reset();
  606. }
  607. // Four layers using lerp
  608. // ---------------
  609. // -----
  610. // ----
  611. // -------
  612. {
  613. params.testundo = false;
  614. params.usecurves = true;
  615. // params.spewnontopmostlayers = true;
  616. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  617. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 100 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 20.0f );
  618. params.AddLayer( DmeTime_t( 15 ), DmeTime_t( 40 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  619. params.AddLayer( DmeTime_t( 60 ), DmeTime_t( 85 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  620. params.AddLayer( DmeTime_t( 35 ), DmeTime_t( 79 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  621. RunLayerTest( "Four-Layer Lerp (top overlapping end of 1st and start of 2nd layer)", channels, params );
  622. params.Reset();
  623. }
  624. // Single layer using lerp everywhere
  625. // -----------------------
  626. {
  627. params.testundo = false;
  628. params.usecurves = true;
  629. params.spew = 0; //SPEW_VALUES | SPEW_KEYS;
  630. params.mintime = DmeTime_t( 0 );
  631. params.maxtime = DmeTime_t( 10000 );
  632. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  633. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 10000 ), DmeTime_t( 20 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SINE, 100.0f );
  634. DmeTime_t tHeadPosition = DmeTime_t( 5000 );
  635. DmeLog_TimeSelection_t ts;
  636. ts.m_nTimes[ TS_LEFT_FALLOFF ] = tHeadPosition + DmeTime_t( -987 );
  637. ts.m_nTimes[ TS_LEFT_HOLD ] = ts.m_nTimes[ TS_RIGHT_HOLD ] = tHeadPosition;
  638. ts.m_nTimes[ TS_RIGHT_FALLOFF ] = tHeadPosition + DmeTime_t( 1052 );
  639. ts.m_nFalloffInterpolatorTypes[ 0 ] = ts.m_nFalloffInterpolatorTypes[ 1 ] = INTERPOLATE_EASE_INOUT;
  640. // Resample at 50 msec intervals
  641. ts.m_bResampleMode = true;
  642. ts.m_nResampleInterval = DmeTime_t( 50 );
  643. ///params.spew |= SPEW_KEYS | SPEW_VALUES;
  644. RunTimeSelectionTest( "One-Layer Time Selection at 50, falloff 25, EASE_INOUT interp", channels, params, tHeadPosition, ts, 250 );
  645. params.purgevalues = false;
  646. // params.spew |= SPEW_VALUES;
  647. // Shift the head and do it all again
  648. tHeadPosition = DmeTime_t( 2000 );
  649. ts.m_nTimes[ TS_LEFT_FALLOFF ] = DmeTime_t( 1487 );
  650. ts.m_nTimes[ TS_LEFT_HOLD ] = ts.m_nTimes[ TS_RIGHT_HOLD ] = tHeadPosition;
  651. ts.m_nTimes[ TS_RIGHT_FALLOFF ] = tHeadPosition + DmeTime_t( 631 );
  652. RunTimeSelectionTest( "2nd layer", channels, params, tHeadPosition, ts, 500 );
  653. params.Reset();
  654. }
  655. // Single layer using lerp everywhere
  656. // -----------------------
  657. {
  658. params.testundo = true;
  659. params.usecurves = true;
  660. params.spew = 0; //SPEW_VALUES | SPEW_KEYS;
  661. params.mintime = DmeTime_t( 0 );
  662. params.maxtime = DmeTime_t( 1000 );
  663. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  664. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 1000 ), DmeTime_t( 20 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 100.0f );
  665. DmeTime_t tHeadPosition = DmeTime_t( 500 );
  666. DmeLog_TimeSelection_t ts;
  667. ts.m_nTimes[ TS_LEFT_FALLOFF ] = tHeadPosition + DmeTime_t( -100 );
  668. ts.m_nTimes[ TS_LEFT_HOLD ] = ts.m_nTimes[ TS_RIGHT_HOLD ] = tHeadPosition;
  669. ts.m_nTimes[ TS_RIGHT_FALLOFF ] = tHeadPosition + DmeTime_t( 100 );
  670. ts.m_nFalloffInterpolatorTypes[ 0 ] = ts.m_nFalloffInterpolatorTypes[ 1 ] = INTERPOLATE_LINEAR_INTERP;
  671. // Resample at 50 msec intervals
  672. ts.m_bResampleMode = true;
  673. ts.m_nResampleInterval = DmeTime_t( 10 );
  674. // params.spew |= SPEW_VALUES;
  675. RunTimeSelectionTest( "Resetting layer", channels, params, tHeadPosition, ts, 200 );
  676. params.purgevalues = false;
  677. //params.spew |= SPEW_VALUES;
  678. // Shift the head and do it all again
  679. //ts.m_nRelativeFalloffTimes[ 0 ] = 1487 - 2000;
  680. //ts.m_nRelativeHoldTimes[ 0 ] = ts.m_nRelativeHoldTimes[ 1 ] = 0;
  681. //ts.m_nRelativeFalloffTimes[ 1 ] = 631;
  682. //ts.SetHeadPosition( 2000 );
  683. RunTimeSelectionTest( "2nd layer", channels, params, tHeadPosition, ts, 110 );
  684. params.Reset();
  685. }
  686. // g_pDataModel->TraceUndo( true );
  687. // Test abort undo stuff
  688. for ( int i = 0; i < 2; ++i )
  689. // Four layers using lerp
  690. // ---------------
  691. // -----
  692. // ----
  693. // -------
  694. {
  695. params.testundo = false;
  696. params.testabort = i != 1 ? true : false;
  697. params.usecurves = false;
  698. // params.spewnontopmostlayers = true;
  699. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  700. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 10 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 20.0f );
  701. params.AddLayer( DmeTime_t( 5 ), DmeTime_t( 6 ), DmeTime_t( 1 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  702. RunLayerTest( "Four-Layer Lerp (top overlapping end of 1st and start of 2nd layer)", channels, params );
  703. params.Reset();
  704. }
  705. // g_pDataModel->TraceUndo( false );
  706. //DestroyChannels( channels );
  707. g_pDataModel->ClearUndo();
  708. g_pDataModel->RemoveFileId( fileid );
  709. #ifdef _DEBUG
  710. int nEndingCount = g_pDataModel->GetAllocatedElementCount();
  711. AssertEquals( nEndingCount, nStartingCount );
  712. if ( nEndingCount != nStartingCount )
  713. {
  714. for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ;
  715. hElement != DMELEMENT_HANDLE_INVALID;
  716. hElement = g_pDataModel->NextAllocatedElement( hElement ) )
  717. {
  718. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  719. Assert( pElement );
  720. if ( !pElement )
  721. return;
  722. Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() );
  723. }
  724. }
  725. #endif
  726. }
  727. DEFINE_TESTCASE_NOSUITE( DmxTestDmeLogLayersUndo )
  728. {
  729. Msg( "Running CDmeTypedLog<float> layering UNDO tests...\n" );
  730. #ifdef _DEBUG
  731. int nStartingCount = g_pDataModel->GetAllocatedElementCount();
  732. #endif
  733. CUtlVector< CDmeChannel * > channels;
  734. DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( "<DmxTestDmeLogLayersUndo>" );
  735. CreateChannels( NUM_CHANNELS, channels, fileid );
  736. TestParams_t params;
  737. // g_pDataModel->TraceUndo( true );
  738. // Test abort undo stuff
  739. for ( int i = 0; i < 2; ++i )
  740. {
  741. params.testundo = false;
  742. params.testabort = true;
  743. params.usecurves = false;
  744. // params.spewnontopmostlayers = true;
  745. params.defaultcurve = CURVE_LINEAR_INTERP_TO_LINEAR_INTERP;
  746. params.AddLayer( DmeTime_t( 0 ), DmeTime_t( 1000 ), DmeTime_t( 10 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_CONSTANT, 20.0f );
  747. params.AddLayer( DmeTime_t( 100 ), DmeTime_t( 900 ), DmeTime_t( 5 ), CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, TestLayer_t::TYPE_SIMPLESLOPE );
  748. RunLayerTest( "Abort undo", channels, params );
  749. params.Reset();
  750. }
  751. // g_pDataModel->TraceUndo( false );
  752. g_pDataModel->ClearUndo();
  753. g_pDataModel->RemoveFileId( fileid );
  754. #ifdef _DEBUG
  755. int nEndingCount = g_pDataModel->GetAllocatedElementCount();
  756. AssertEquals( nEndingCount, nStartingCount );
  757. if ( nEndingCount != nStartingCount )
  758. {
  759. for ( DmElementHandle_t hElement = g_pDataModel->FirstAllocatedElement() ;
  760. hElement != DMELEMENT_HANDLE_INVALID;
  761. hElement = g_pDataModel->NextAllocatedElement( hElement ) )
  762. {
  763. CDmElement *pElement = g_pDataModel->GetElement( hElement );
  764. Assert( pElement );
  765. if ( !pElement )
  766. return;
  767. Msg( "[%s : %s] in memory\n", pElement->GetName(), pElement->GetTypeString() );
  768. }
  769. }
  770. #endif
  771. }