87 lines
No EOL
3.2 KiB
C#
87 lines
No EOL
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace JD.Serialization
|
|
{
|
|
/// <summary>
|
|
/// A tape reference can loop, this represent a part in the loop process of the tape reference.
|
|
/// </summary>
|
|
public struct LoopSection
|
|
{
|
|
public int Start;
|
|
public int End;
|
|
public bool IsPartial;
|
|
public bool IsUnusedSpace;
|
|
public bool IsReversed;
|
|
|
|
public int Length => End - Start;
|
|
}
|
|
|
|
public static class LoopSectionExtensions
|
|
{
|
|
/// <summary>
|
|
/// True if the loop type is a repeat loop.
|
|
/// </summary>
|
|
public static bool Repeats(this TapeReferenceClip.Loop_Enum type)
|
|
{
|
|
return type == TapeReferenceClip.Loop_Enum.LoopingType_PingPong ||
|
|
type == TapeReferenceClip.Loop_Enum.LoopingType_PingPongInfinite ||
|
|
type == TapeReferenceClip.Loop_Enum.LoopingType_Loop ||
|
|
type == TapeReferenceClip.Loop_Enum.LoopingType_Infinite;
|
|
}
|
|
|
|
public static bool PingPongs(this TapeReferenceClip.Loop_Enum type)
|
|
{
|
|
return type == TapeReferenceClip.Loop_Enum.LoopingType_PingPong ||
|
|
type == TapeReferenceClip.Loop_Enum.LoopingType_PingPongInfinite;
|
|
}
|
|
|
|
public static IEnumerable<LoopSection> EnumerateLoopSections(this TapeReferenceClip tapeReference)
|
|
{
|
|
int tapeDuration = tapeReference.TapeDuration;
|
|
if (tapeDuration <= 0)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
if (tapeReference.Loop == TapeReferenceClip.Loop_Enum.LoopingType_Reverse)
|
|
{
|
|
var lastPart = CreateSection(tapeReference, tapeReference.StopFrame - tapeDuration, tapeReference.StopFrame, tapeDuration);
|
|
lastPart.IsReversed = true;
|
|
yield return lastPart;
|
|
|
|
if (lastPart.Start > tapeReference.StartFrame)
|
|
{
|
|
var unusedSpace = CreateSection(tapeReference, tapeReference.StartFrame, lastPart.Start, tapeDuration);
|
|
unusedSpace.IsUnusedSpace = true;
|
|
unusedSpace.IsReversed = true;
|
|
yield return unusedSpace;
|
|
}
|
|
yield break;
|
|
}
|
|
|
|
int i = 0;
|
|
for (int frame = tapeReference.StartFrame; frame < tapeReference.StopFrame; frame += tapeDuration)
|
|
{
|
|
i++;
|
|
var section = CreateSection(tapeReference, frame, frame + tapeDuration, tapeDuration);
|
|
section.IsUnusedSpace = frame != tapeReference.StartFrame && !tapeReference.Loop.Repeats();
|
|
section.IsReversed = tapeReference.Loop.PingPongs() && i % 2 == 0;
|
|
yield return section;
|
|
}
|
|
}
|
|
|
|
private static LoopSection CreateSection(TapeReferenceClip tapeReference, int start, int end, int tapeDuration)
|
|
{
|
|
var result = new LoopSection
|
|
{
|
|
Start = Math.Max(start, tapeReference.StartFrame),
|
|
End = Math.Min(end, tapeReference.StopFrame)
|
|
};
|
|
|
|
result.IsPartial = result.Length != tapeDuration;
|
|
return result;
|
|
}
|
|
|
|
}
|
|
} |