Implemented sync track blending for tracks with more than 2 markers.
This commit is contained in:
+58
-28
@@ -27,8 +27,7 @@ struct SyncTrack {
|
||||
int m_num_intervals;
|
||||
float m_sync_markers[cSyncTrackMaxIntervals];
|
||||
float m_interval_start[cSyncTrackMaxIntervals];
|
||||
float m_interval_end[cSyncTrackMaxIntervals];
|
||||
float m_interval_durations[cSyncTrackMaxIntervals];
|
||||
float m_interval_ratio[cSyncTrackMaxIntervals];
|
||||
|
||||
void CalcIntervals() {
|
||||
int i;
|
||||
@@ -36,20 +35,21 @@ struct SyncTrack {
|
||||
if (m_num_intervals == 0) {
|
||||
m_num_intervals = 1;
|
||||
m_interval_start[0] = 0.f;
|
||||
m_interval_end[0] = 1.f;
|
||||
m_interval_ratio[0] = 1.f;
|
||||
} else {
|
||||
for (i = 0; i < m_num_intervals; i++) {
|
||||
assert (m_sync_markers[i] >= 0.f && m_sync_markers[i] <= 1.0f);
|
||||
|
||||
int end_index = i < m_num_intervals - 1 ? i + 1 : 0;
|
||||
|
||||
m_interval_start[i] = m_sync_markers[i];
|
||||
m_interval_end[i] = m_sync_markers[end_index];
|
||||
float interval_end = m_sync_markers[end_index];
|
||||
|
||||
if (m_interval_end[i] > m_interval_start[i]) {
|
||||
m_interval_durations[i] = m_interval_end[i] - m_interval_start[i];
|
||||
} else {
|
||||
m_interval_durations[i] =
|
||||
m_interval_end[i] + (1. - m_interval_start[i]);
|
||||
if (interval_end < m_interval_start[i]) {
|
||||
interval_end += 1.0f;
|
||||
}
|
||||
|
||||
m_interval_ratio[i] = interval_end - m_interval_start[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,13 +58,12 @@ struct SyncTrack {
|
||||
float sync_time = fmodf(abs_time, m_duration) / m_duration;
|
||||
|
||||
int interval_index = 0;
|
||||
while (sync_time >= m_interval_durations[interval_index]) {
|
||||
sync_time -= m_interval_durations[interval_index];
|
||||
while (sync_time >= m_interval_ratio[interval_index]) {
|
||||
sync_time -= m_interval_ratio[interval_index];
|
||||
interval_index++;
|
||||
}
|
||||
|
||||
return float(interval_index)
|
||||
+ sync_time / m_interval_durations[interval_index];
|
||||
return float(interval_index) + sync_time / m_interval_ratio[interval_index];
|
||||
}
|
||||
|
||||
float CalcRatioFromSyncTime(float sync_time) {
|
||||
@@ -73,10 +72,29 @@ struct SyncTrack {
|
||||
|
||||
return fmodf(
|
||||
m_interval_start[interval]
|
||||
+ m_interval_durations[interval] * interval_ratio,
|
||||
+ m_interval_ratio[interval] * interval_ratio,
|
||||
1.0f);
|
||||
}
|
||||
|
||||
bool operator==(const SyncTrack& other) const {
|
||||
bool result = m_duration == other.m_duration
|
||||
&& m_num_intervals == other.m_num_intervals;
|
||||
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_num_intervals; i++) {
|
||||
if ((fabsf(m_interval_start[i] - other.m_interval_start[i]) > 1.0e-5)
|
||||
|| (fabsf(m_interval_ratio[i] - other.m_interval_ratio[i])
|
||||
> 1.0e-5)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static SyncTrack
|
||||
Blend(float weight, const SyncTrack& track_A, const SyncTrack& track_B) {
|
||||
assert(track_A.m_num_intervals == track_B.m_num_intervals);
|
||||
@@ -87,22 +105,34 @@ struct SyncTrack {
|
||||
result.m_duration =
|
||||
(1.0f - weight) * track_A.m_duration + weight * track_B.m_duration;
|
||||
|
||||
float interval_0_offset =
|
||||
track_B.m_interval_start[0] - track_A.m_interval_start[0];
|
||||
if (interval_0_offset > 0.5f) {
|
||||
interval_0_offset = -fmodf(1.f - interval_0_offset, 1.0f);
|
||||
} else if (interval_0_offset < -0.5) {
|
||||
interval_0_offset = fmodf(1.f + interval_0_offset, 1.0f);
|
||||
}
|
||||
|
||||
result.m_interval_start[0] = fmodf(
|
||||
1.0 + (1.0f - weight) * track_A.m_interval_start[0]
|
||||
+ weight * (track_A.m_interval_start[0] + interval_0_offset),
|
||||
1.0f);
|
||||
result.m_sync_markers[0] = result.m_interval_start[0];
|
||||
|
||||
for (int i = 0; i < result.m_num_intervals; i++) {
|
||||
result.m_interval_durations[i] =
|
||||
(1.0f - weight) * track_A.m_interval_durations[i]
|
||||
+ weight * track_B.m_interval_durations[i];
|
||||
float interval_duration_A = track_A.m_interval_ratio[i];
|
||||
float interval_duration_B = track_B.m_interval_ratio[i];
|
||||
result.m_interval_ratio[i] =
|
||||
(1.0f - weight) * interval_duration_A + weight * interval_duration_B;
|
||||
|
||||
result.m_interval_start[i] =
|
||||
(1.0f - weight) * track_A.m_interval_start[i]
|
||||
+ weight * track_B.m_interval_start[i];
|
||||
|
||||
result.m_interval_end[i] =
|
||||
(1.0f - weight) * track_A.m_interval_end[i]
|
||||
+ weight * track_B.m_interval_end[i];
|
||||
|
||||
result.m_sync_markers[i] =
|
||||
(1.0f - weight) * track_A.m_sync_markers[i]
|
||||
+ weight * track_B.m_sync_markers[i];
|
||||
if (i < cSyncTrackMaxIntervals) {
|
||||
result.m_interval_start[i + 1] =
|
||||
result.m_interval_start[i] + result.m_interval_ratio[i];
|
||||
if (result.m_interval_start[i + 1] > 1.0f) {
|
||||
result.m_interval_start[i + 1] =
|
||||
fmodf(result.m_interval_start[i + 1], 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user