@@ -21,6 +21,14 @@ public TimelineConverter(IReadOnlyCollection<(int time, DmxPacket packet)> packe
21
21
}
22
22
}
23
23
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
+
24
32
public void SaveDmxTimelineClips ( string directory )
25
33
{
26
34
if ( System . IO . Directory . Exists ( directory ) == false )
@@ -51,6 +59,11 @@ public void SaveDmxTimelineClips(string directory)
51
59
AssetDatabase . Refresh ( ) ;
52
60
}
53
61
62
+ public List < ( int time , DmxPacket packet ) > ToDmxPackets ( )
63
+ {
64
+ return Timelines . SelectMany ( x => x . ToDmxPackets ( ) ) . OrderBy ( x => x . time ) . ToList ( ) ;
65
+ }
66
+
54
67
private static void SaveAsset < T > ( T asset , string directory , string fileName ) where T : UnityEngine . Object
55
68
{
56
69
var path = $ "{ directory } /{ fileName } ";
@@ -77,6 +90,71 @@ public TimelineUniverse(int universe, IReadOnlyCollection<(int time, DmxPacket p
77
90
}
78
91
}
79
92
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
+
80
158
public AnimationClip ToAnimationClip ( )
81
159
{
82
160
var curves = ConvertAnimationCurves ( ) ;
@@ -144,6 +222,35 @@ private static bool IsOmittedFrame(
144
222
145
223
return Math . Abs ( ( float ) prevDiff / prevDiffTime - ( float ) nextDiff / nextDiffTime ) <= tolerance ;
146
224
}
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
+ }
147
254
}
148
255
149
256
public struct DmxFrameData
0 commit comments