Skip to content

Commit cef42bb

Browse files
committed
AnimationClip から TimelineUniverse を作れるようにする
1 parent eff0fe2 commit cef42bb

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

Assets/ArtNet/Editor/DmxRecorder/TimelineConverter.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ public TimelineConverter(IReadOnlyCollection<(int time, DmxPacket packet)> packe
2121
}
2222
}
2323

24+
public TimelineConverter(DmxTimelineSetting dmxTimelineSetting)
25+
{
26+
foreach (var timelineElement in dmxTimelineSetting.DmxTimelines)
27+
{
28+
Timelines.Add(new TimelineUniverse(timelineElement.Universe, timelineElement.DmxTimelineClip));
29+
}
30+
}
31+
2432
public void SaveDmxTimelineClips(string directory)
2533
{
2634
if (System.IO.Directory.Exists(directory) == false)
@@ -51,6 +59,11 @@ public void SaveDmxTimelineClips(string directory)
5159
AssetDatabase.Refresh();
5260
}
5361

62+
public List<(int time, DmxPacket packet)> ToDmxPackets()
63+
{
64+
return Timelines.SelectMany(x => x.ToDmxPackets()).OrderBy(x => x.time).ToList();
65+
}
66+
5467
private static void SaveAsset<T>(T asset, string directory, string fileName) where T : UnityEngine.Object
5568
{
5669
var path = $"{directory}/{fileName}";
@@ -77,6 +90,71 @@ public TimelineUniverse(int universe, IReadOnlyCollection<(int time, DmxPacket p
7790
}
7891
}
7992

93+
public TimelineUniverse(int universe, AnimationClip clip)
94+
{
95+
Universe = universe;
96+
var curveBindings = AnimationUtility.GetCurveBindings(clip);
97+
ChannelDmxFrameData = new List<DmxFrameData>[512];
98+
for (var i = 0; i < ChannelDmxFrameData.Length; i++)
99+
{
100+
var propertyName = $"Ch{i + 1:D3}";
101+
102+
var curve = curveBindings
103+
.Where(binding => binding.propertyName == propertyName)
104+
.Select(binding => AnimationUtility.GetEditorCurve(clip, binding))
105+
.FirstOrDefault();
106+
107+
if (curve is null) continue;
108+
109+
ChannelDmxFrameData[i] = curve.keys.Select(x => new DmxFrameData((int) (x.time * 1000), (byte) x.value)).ToList();
110+
}
111+
}
112+
113+
public IEnumerable<int> AllFrameTimes()
114+
{
115+
return ChannelDmxFrameData.SelectMany(x => x.Select(frameData => frameData.Millisecond)).Distinct();
116+
}
117+
118+
public byte FrameValue(int channel, int time)
119+
{
120+
var dmxFrameData = ChannelDmxFrameData[channel];
121+
122+
// If there is a frame data at the exact time, return it
123+
foreach (var frameData in dmxFrameData.Where(frameData => frameData.Millisecond == time))
124+
{
125+
return frameData.Value;
126+
}
127+
128+
// if there is no frame data, return 0
129+
if (dmxFrameData.Count == 0) return 0;
130+
131+
// if time is out of range, return the first or last value
132+
if (time < dmxFrameData[0].Millisecond) return dmxFrameData[0].Value;
133+
if (time > dmxFrameData[^1].Millisecond) return dmxFrameData[^1].Value;
134+
135+
// return the estimated value from frames around the specified time.
136+
137+
// Find the frame data before and after the specified time
138+
var prev = dmxFrameData[0];
139+
var next = dmxFrameData[0];
140+
foreach (var frameData in dmxFrameData)
141+
{
142+
if (frameData.Millisecond > time)
143+
{
144+
next = frameData;
145+
break;
146+
}
147+
148+
prev = frameData;
149+
}
150+
151+
// Calculate the estimated value
152+
var prevDiff = next.Value - prev.Value;
153+
var prevDiffTime = next.Millisecond - prev.Millisecond;
154+
var timeDiff = time - prev.Millisecond;
155+
return (byte) (prev.Value + (prevDiff * timeDiff / prevDiffTime));
156+
}
157+
80158
public AnimationClip ToAnimationClip()
81159
{
82160
var curves = ConvertAnimationCurves();
@@ -144,6 +222,35 @@ private static bool IsOmittedFrame(
144222

145223
return Math.Abs((float) prevDiff / prevDiffTime - (float) nextDiff / nextDiffTime) <= tolerance;
146224
}
225+
226+
public IEnumerable<(int time, DmxPacket packet)> ToDmxPackets()
227+
{
228+
byte sequence = 0;
229+
var packets = new List<(int time, DmxPacket packet)>();
230+
var allFrameTimes = AllFrameTimes().OrderBy(x => x).ToList();
231+
232+
foreach (var time in allFrameTimes)
233+
{
234+
var dmx = new byte[512];
235+
for (var i = 0; i < ChannelDmxFrameData.Length; i++)
236+
{
237+
dmx[i] = FrameValue(i, time);
238+
}
239+
240+
var packet = new DmxPacket { Sequence = sequence, Universe = (ushort) Universe, Dmx = dmx };
241+
packets.Add((time, packet));
242+
if (sequence >= 255)
243+
{
244+
sequence = 0;
245+
}
246+
else
247+
{
248+
sequence++;
249+
}
250+
}
251+
252+
return packets;
253+
}
147254
}
148255

149256
public struct DmxFrameData

0 commit comments

Comments
 (0)