diff --git a/src/SkinnedMesh.h b/src/SkinnedMesh.h index 3d344b2..99a1e3e 100644 --- a/src/SkinnedMesh.h +++ b/src/SkinnedMesh.h @@ -27,14 +27,32 @@ struct SyncTrack { int m_num_intervals; float m_interval_durations[cSyncTrackMaxIntervals]; - float ConvertAbsTimeToSyncTime (float abs_time) { + float CalcSyncFromAbsTime (float abs_time) { float sync_time = fmodf (abs_time, m_duration) / m_duration; int interval_index = 0; - while (sync_time < m_interval_durations[interval_index]) { + while (sync_time >= m_interval_durations[interval_index]) { sync_time -= m_interval_durations[interval_index]; interval_index ++; } + + return float(interval_index) + sync_time / m_interval_durations[interval_index]; + } + + float CalcRatioFromSyncTime (float sync_time) { + float interval_ratio = fmodf(sync_time, 1.0f); + int interval = int(sync_time - interval_ratio); + + float result = 0.f; + int i = 0; + while (i < interval) { + result += m_interval_durations[i]; + i++; + } + + result += m_interval_durations[i] * interval_ratio; + + return result; } static SyncTrack Blend(float weight, const SyncTrack& track_A, const SyncTrack& track_B) { diff --git a/tests/SyncTrackTests.cc b/tests/SyncTrackTests.cc index 816bef5..3c1da49 100644 --- a/tests/SyncTrackTests.cc +++ b/tests/SyncTrackTests.cc @@ -9,15 +9,50 @@ TEST_CASE("SyncTrackBlendSimple", "[SyncTrackBlend]") { SyncTrack track_A; track_A.m_num_intervals = 2; - track_A.m_duration = 1.0; - track_A.m_interval_durations[0] = 0.8; - track_A.m_interval_durations[1] = 0.2; + track_A.m_duration = 2.0; + track_A.m_interval_durations[0] = 0.7; + track_A.m_interval_durations[1] = 0.3; SyncTrack track_B; track_B.m_num_intervals = 2; - track_B.m_duration = 2.0; - track_B.m_interval_durations[0] = 0.1; - track_B.m_interval_durations[1] = 0.9; + track_B.m_duration = 1.5; + track_B.m_interval_durations[0] = 0.6; + track_B.m_interval_durations[1] = 0.4; + + WHEN ("Calculating sync time of track_B at 0.5 duration") { + float sync_time_at_0_75 = track_B.CalcSyncFromAbsTime(0.5 * track_B.m_duration); + REQUIRE(sync_time_at_0_75 == Catch::Detail::Approx(0.83333)); + } + + WHEN ("Calculating sync time of track_B at 0.6 duration") { + float sync_time_at_0_6 = track_B.CalcSyncFromAbsTime(0.6 * track_B.m_duration); + REQUIRE(sync_time_at_0_6 == Catch::Detail::Approx(1.0)); + } + + WHEN ("Calculating sync time of track_B at 0.7 duration") { + float sync_time_at_0_7 = track_B.CalcSyncFromAbsTime(0.7 * track_B.m_duration); + REQUIRE(sync_time_at_0_7 == Catch::Detail::Approx(1.25)); + } + + WHEN ("Calculating sync time of track_B at 0.0 duration") { + float sync_time_at_1_0 = track_B.CalcSyncFromAbsTime(0.0 * track_B.m_duration); + REQUIRE(sync_time_at_1_0 == Catch::Detail::Approx(0.0)); + } + + WHEN ("Calculating sync time of track_B at 1.0 duration") { + float sync_time_at_1_0 = track_B.CalcSyncFromAbsTime(0.9999 * track_B.m_duration); + REQUIRE(sync_time_at_1_0 == Catch::Detail::Approx(2.0).epsilon(0.001f)); + } + + WHEN ("Calculating ratio from sync time on track_A at 0.83333") { + float ratio = track_A.CalcRatioFromSyncTime(0.83333333); + REQUIRE (ratio == Catch::Detail::Approx(0.5833333)); + } + + WHEN ("Calculating ratio from sync time on track_A at 0.83333") { + float ratio = track_A.CalcRatioFromSyncTime(1.25); + REQUIRE (ratio == Catch::Detail::Approx(0.775)); + } WHEN("Blending two synctracks with weight 0.") { SyncTrack blended = SyncTrack::Blend(0.f, track_A, track_B);