flame_channel_parser 1.3.1 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -10
- data/bin/bake_flame_channel +2 -2
- data/lib/extractor.rb +30 -14
- data/lib/flame_channel_parser.rb +1 -1
- data/lib/interpolator.rb +31 -6
- data/lib/segments.rb +11 -16
- data/test/snaps/RefT_Steadicam_Extraction_F19_to_347.txt +117 -117
- data/test/test_extractor.rb +10 -1
- data/test/test_interpolator.rb +12 -1
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
=== 1.3.2 / 2011-05-30
|
2
|
+
|
3
|
+
* Fix linear extrapolation occurring after linear keyframes, enforce the tangent/increment of zero for linear extrap. segments
|
4
|
+
|
1
5
|
=== 1.3.1 / 2011-05-30
|
2
6
|
|
3
7
|
* Add minor fixes and imporvements to the curve extraction bin
|
@@ -8,16 +12,6 @@
|
|
8
12
|
* Add bake_flame_channel binary
|
9
13
|
* Ensure linear prepolation works when counting to a linear interpolated keyframe
|
10
14
|
|
11
|
-
=== 1.2.0 / 2011-05-20
|
12
|
-
|
13
|
-
* Ensure single-key channels interpolate correctly
|
14
|
-
|
15
|
-
=== 1.1.1 / 2011-05-17
|
16
|
-
|
17
|
-
* Added support for 2012 Bezier splines
|
18
|
-
|
19
|
-
=== 1.1.1 / 2011-05-17
|
20
|
-
|
21
15
|
* Added support for 2012 Bezier splines
|
22
16
|
|
23
17
|
=== 1.0.0 / 2011-03-21
|
data/bin/bake_flame_channel
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require File.dirname(__FILE__) + '/../lib/flame_channel_parser'
|
2
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../lib/flame_channel_parser'
|
3
3
|
require 'optparse'
|
4
4
|
|
5
5
|
options = {}
|
6
6
|
|
7
7
|
op = OptionParser.new
|
8
|
-
op.banner = "Usage: bake_flame_channel --channel
|
8
|
+
op.banner = "Usage: bake_flame_channel --channel Timing/Timing -e 123 /usr/discreet/projects/Luxury/timewarp/shot2_tw.timewarp > /mnt/3d/curves/shot2_tw.framecurve.txt\n" +
|
9
9
|
"The output file can be used as Time+Value ASCII input for Nuke " +
|
10
10
|
"or parsed with any simple script"
|
11
11
|
op.on(" -c", "--channel CHANNEL_NAME", String,
|
data/lib/extractor.rb
CHANGED
@@ -10,27 +10,40 @@ class FlameChannelParser::Extractor
|
|
10
10
|
# Raised when you try to autodetect the length of a channel that has no keyframes
|
11
11
|
class NoKeyframesError < RuntimeError; end
|
12
12
|
|
13
|
-
#
|
13
|
+
# Raised when you try to bake 0 or negative amount of frames
|
14
|
+
class EmptySegmentError < RuntimeError; end
|
15
|
+
|
16
|
+
# Pass the path to Flame setup here and you will get the animation curve on the object passed in
|
17
|
+
# the :destionation option (defaults to STDOUT). The following options are accepted:
|
18
|
+
#
|
19
|
+
# :destination - The object to write the output to, anything that responds to shovel (<<) will do
|
20
|
+
# :start_frame - From which frame the curve should be baked. Will default to the first keyframe of the curve
|
21
|
+
# :end_frame - Upto which frame to bake. Will default to the last keyframe of the curve
|
22
|
+
# :channel - Name of the channel to extract from the setup. Defaults to "Timing/Timing" (timewarp frame)
|
14
23
|
def self.extract(path, options = {})
|
15
24
|
options = DEFAULTS.merge(options)
|
16
|
-
File.open(path) do |
|
25
|
+
File.open(path) do |f|
|
17
26
|
channels = FlameChannelParser.parse(f)
|
18
|
-
selected_channel = channels
|
19
|
-
|
20
|
-
|
21
|
-
message << "\n"
|
22
|
-
message += channels.map{|c| "\t%s\n" % c.path }.join
|
23
|
-
raise ChannelNotFoundError, message
|
24
|
-
end
|
25
|
-
|
26
|
-
write_channel(selected_channel, options[:destination], options[:start_frame], options[:end_frame])
|
27
|
+
selected_channel = find_channel_in(channels, options[:channel])
|
28
|
+
interpolator = FlameChannelParser::Interpolator.new(selected_channel)
|
29
|
+
write_channel(interpolator, options[:destination], options[:start_frame], options[:end_frame])
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
30
33
|
private
|
31
34
|
|
32
|
-
def self.
|
33
|
-
|
35
|
+
def self.find_channel_in(channels, channel_path)
|
36
|
+
selected_channel = channels.find{|c| channel_path == c.path }
|
37
|
+
unless selected_channel
|
38
|
+
message = "Channel #{channel_path.inspect} not found in this setup (set the channel with the --channel option). Found other channels though:"
|
39
|
+
message << "\n"
|
40
|
+
message += channels.map{|c| "\t%s\n" % c.path }.join
|
41
|
+
raise ChannelNotFoundError, message
|
42
|
+
end
|
43
|
+
selected_channel
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.write_channel(interpolator, to_io, start_frame, end_frame)
|
34
47
|
|
35
48
|
from_frame = start_frame || interpolator.first_defined_frame
|
36
49
|
to_frame = end_frame || interpolator.last_defined_frame
|
@@ -39,8 +52,11 @@ class FlameChannelParser::Extractor
|
|
39
52
|
"Please set the start and end frame explicitly."
|
40
53
|
end
|
41
54
|
|
55
|
+
raise EmptySegmentError, "The segment you are trying to bake is too small (it has nothing in it)" if to_frame - from_frame < 1
|
56
|
+
|
42
57
|
(from_frame..to_frame).each do | frame |
|
43
|
-
|
58
|
+
line = "%d\t%.5f\n" % [frame, interpolator.sample_at(frame)]
|
59
|
+
to_io << line
|
44
60
|
end
|
45
61
|
end
|
46
62
|
|
data/lib/flame_channel_parser.rb
CHANGED
data/lib/interpolator.rb
CHANGED
@@ -16,6 +16,7 @@ class FlameChannelParser::Interpolator
|
|
16
16
|
# segments from which samples can be made
|
17
17
|
def initialize(channel)
|
18
18
|
@segments = []
|
19
|
+
@extrap = channel.extrapolation
|
19
20
|
|
20
21
|
# Edge case - channel has no anim at all
|
21
22
|
if channel.length.zero?
|
@@ -31,16 +32,27 @@ class FlameChannelParser::Interpolator
|
|
31
32
|
end
|
32
33
|
|
33
34
|
# so we just output it separately
|
34
|
-
@segments << pick_extrapolation(channel.extrapolation, channel[-1])
|
35
|
+
@segments << pick_extrapolation(channel.extrapolation, channel[-2], channel[-1])
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
39
|
# Sample the value of the animation curve at this frame
|
39
40
|
def sample_at(frame)
|
40
|
-
|
41
|
-
|
41
|
+
# No test files present for now so we turn this off
|
42
|
+
# if [:cycle, :rev_cycle].include?(frame)
|
43
|
+
# # Recompute the frame number and retry
|
44
|
+
# unless frame >= first_defined_frame && frame <= last_defined_frame
|
45
|
+
# animated_on = (last_defined_frame - first_defined_frame)
|
46
|
+
# fdiff = if frame < first_defined_frame
|
47
|
+
# (first_defined_frame - frame) % animated_on
|
48
|
+
# else
|
49
|
+
# (frame - last_defined_frame) % animated_on
|
50
|
+
# end
|
51
|
+
# sample_from_segments(first_defined_frame + fdiff)
|
52
|
+
# end
|
53
|
+
# end
|
42
54
|
|
43
|
-
|
55
|
+
sample_from_segments(frame)
|
44
56
|
end
|
45
57
|
|
46
58
|
# Returns the first frame number that is concretely defined as a keyframe
|
@@ -61,6 +73,12 @@ class FlameChannelParser::Interpolator
|
|
61
73
|
|
62
74
|
private
|
63
75
|
|
76
|
+
def sample_from_segments(at_frame)
|
77
|
+
segment = @segments.find{|s| s.defines?(at_frame) }
|
78
|
+
raise "No segment on this curve that can interpolate the value at #{frame}" unless segment
|
79
|
+
segment.value_at(at_frame)
|
80
|
+
end
|
81
|
+
|
64
82
|
def pick_prepolation(extrap_symbol, first_key, second_key)
|
65
83
|
if extrap_symbol == :linear && second_key
|
66
84
|
if first_key.interpolation != :linear
|
@@ -76,9 +94,16 @@ class FlameChannelParser::Interpolator
|
|
76
94
|
end
|
77
95
|
end
|
78
96
|
|
79
|
-
def pick_extrapolation(extrap_symbol, last_key)
|
97
|
+
def pick_extrapolation(extrap_symbol, previous_key, last_key)
|
80
98
|
if extrap_symbol == :linear
|
81
|
-
|
99
|
+
if previous_key && last_key.interpolation == :linear
|
100
|
+
# For linear keys the tangent actually does not do anything, so we need to look a frame
|
101
|
+
# ahead and compute the increment
|
102
|
+
increment = (last_key.value - previous_key.value) / (last_key.frame - previous_key.frame)
|
103
|
+
LinearExtrapolate.new(last_key.frame, last_key.value, increment)
|
104
|
+
else
|
105
|
+
LinearExtrapolate.new(last_key.frame, last_key.value, last_key.right_slope)
|
106
|
+
end
|
82
107
|
else
|
83
108
|
ConstantExtrapolate.new(last_key.frame, last_key.value)
|
84
109
|
end
|
data/lib/segments.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
require "matrix"
|
2
2
|
|
3
|
-
|
4
|
-
# :nodoc:
|
5
|
-
module FlameChannelParser::Segments
|
3
|
+
module FlameChannelParser::Segments #:nodoc:
|
6
4
|
|
7
5
|
# This segment just stays on the value of it's keyframe
|
8
|
-
class ConstantSegment
|
6
|
+
class ConstantSegment #:nodoc:
|
9
7
|
|
10
8
|
NEG_INF = (-1.0/0.0)
|
11
9
|
POS_INF = (1.0/0.0)
|
@@ -30,7 +28,7 @@ module FlameChannelParser::Segments
|
|
30
28
|
end
|
31
29
|
|
32
30
|
# This segment linearly interpolates
|
33
|
-
class LinearSegment < ConstantSegment
|
31
|
+
class LinearSegment < ConstantSegment #:nodoc:
|
34
32
|
|
35
33
|
def initialize(from_frame, to_frame, value1, value2)
|
36
34
|
@vint = (value2 - value1)
|
@@ -46,7 +44,7 @@ module FlameChannelParser::Segments
|
|
46
44
|
|
47
45
|
# This segment does Hermite interpolation
|
48
46
|
# using the Flame algo.
|
49
|
-
class HermiteSegment < LinearSegment
|
47
|
+
class HermiteSegment < LinearSegment #:nodoc:
|
50
48
|
|
51
49
|
# In Ruby matrix columns are arrays, so here we go
|
52
50
|
HERMATRIX = Matrix[
|
@@ -94,7 +92,7 @@ module FlameChannelParser::Segments
|
|
94
92
|
|
95
93
|
end
|
96
94
|
|
97
|
-
class BezierSegment < LinearSegment
|
95
|
+
class BezierSegment < LinearSegment #:nodoc:
|
98
96
|
Pt = Struct.new(:x, :y, :tanx, :tany)
|
99
97
|
|
100
98
|
def initialize(x1, x2, y1, y2, t1x, t1y, t2x, t2y)
|
@@ -185,7 +183,7 @@ module FlameChannelParser::Segments
|
|
185
183
|
end
|
186
184
|
|
187
185
|
# This segment does prepolation of a constant value
|
188
|
-
class ConstantPrepolate < LinearSegment
|
186
|
+
class ConstantPrepolate < LinearSegment #:nodoc:
|
189
187
|
def initialize(upto_frame, base_value)
|
190
188
|
@value = base_value
|
191
189
|
@end_frame = upto_frame
|
@@ -198,13 +196,12 @@ module FlameChannelParser::Segments
|
|
198
196
|
end
|
199
197
|
|
200
198
|
# This segment does prepolation with a linear coefficient
|
201
|
-
class LinearPrepolate < LinearSegment
|
199
|
+
class LinearPrepolate < LinearSegment #:nodoc:
|
202
200
|
def initialize(upto_frame, base_value, tangent)
|
203
201
|
@value = base_value
|
204
202
|
@end_frame = upto_frame
|
205
203
|
@start_frame = NEG_INF
|
206
204
|
@tangent = tangent.to_f
|
207
|
-
|
208
205
|
end
|
209
206
|
|
210
207
|
def value_at(frame)
|
@@ -214,7 +211,7 @@ module FlameChannelParser::Segments
|
|
214
211
|
end
|
215
212
|
|
216
213
|
# This segment does extrapolation using a constant value
|
217
|
-
class ConstantExtrapolate < LinearSegment
|
214
|
+
class ConstantExtrapolate < LinearSegment #:nodoc:
|
218
215
|
def initialize(from_frame, base_value)
|
219
216
|
@start_frame = from_frame
|
220
217
|
@base_value = base_value
|
@@ -227,10 +224,10 @@ module FlameChannelParser::Segments
|
|
227
224
|
end
|
228
225
|
|
229
226
|
# This segment does extrapolation using the tangent from the preceding keyframe
|
230
|
-
class LinearExtrapolate < ConstantExtrapolate
|
227
|
+
class LinearExtrapolate < ConstantExtrapolate #:nodoc:
|
231
228
|
def initialize(from_frame, base_value, tangent)
|
232
229
|
super(from_frame, base_value)
|
233
|
-
@tangent = tangent
|
230
|
+
@tangent = tangent.to_f
|
234
231
|
end
|
235
232
|
|
236
233
|
def value_at(frame)
|
@@ -240,7 +237,7 @@ module FlameChannelParser::Segments
|
|
240
237
|
end
|
241
238
|
|
242
239
|
# This can be used for an anim curve that stays constant all along
|
243
|
-
class ConstantFunction < ConstantSegment
|
240
|
+
class ConstantFunction < ConstantSegment #:nodoc:
|
244
241
|
|
245
242
|
def defines?(frame)
|
246
243
|
true
|
@@ -255,5 +252,3 @@ module FlameChannelParser::Segments
|
|
255
252
|
end
|
256
253
|
end
|
257
254
|
end
|
258
|
-
|
259
|
-
# :nodoc:
|
@@ -210,120 +210,120 @@
|
|
210
210
|
228 5.00000
|
211
211
|
229 3.00000
|
212
212
|
230 1.00000
|
213
|
-
231 -
|
214
|
-
232 -
|
215
|
-
233 -
|
216
|
-
234 -
|
217
|
-
235 -
|
218
|
-
236 -
|
219
|
-
237 -
|
220
|
-
238 -
|
221
|
-
239 -
|
222
|
-
240 -
|
223
|
-
241 -
|
224
|
-
242 -
|
225
|
-
243 -
|
226
|
-
244 -
|
227
|
-
245 -
|
228
|
-
246 -
|
229
|
-
247 -
|
230
|
-
248 -
|
231
|
-
249 -
|
232
|
-
250 -
|
233
|
-
251 -
|
234
|
-
252 -
|
235
|
-
253 -
|
236
|
-
254 -
|
237
|
-
255 -
|
238
|
-
256 -
|
239
|
-
257 -
|
240
|
-
258 -
|
241
|
-
259 -
|
242
|
-
260 -
|
243
|
-
261 -
|
244
|
-
262 -
|
245
|
-
263 -
|
246
|
-
264 -
|
247
|
-
265 -
|
248
|
-
266 -
|
249
|
-
267 -
|
250
|
-
268 -
|
251
|
-
269 -
|
252
|
-
270 -
|
253
|
-
271 -
|
254
|
-
272 -
|
255
|
-
273 -
|
256
|
-
274 -
|
257
|
-
275 -
|
258
|
-
276 -
|
259
|
-
277 -
|
260
|
-
278 -
|
261
|
-
279 -
|
262
|
-
280 -
|
263
|
-
281 -
|
264
|
-
282 -
|
265
|
-
283 -
|
266
|
-
284 -
|
267
|
-
285 -
|
268
|
-
286 -
|
269
|
-
287 -
|
270
|
-
288 -
|
271
|
-
289 -
|
272
|
-
290 -
|
273
|
-
291 -
|
274
|
-
292 -
|
275
|
-
293 -
|
276
|
-
294 -
|
277
|
-
295 -
|
278
|
-
296 -
|
279
|
-
297 -
|
280
|
-
298 -
|
281
|
-
299 -
|
282
|
-
300 -
|
283
|
-
301 -
|
284
|
-
302 -
|
285
|
-
303 -
|
286
|
-
304 -
|
287
|
-
305 -
|
288
|
-
306 -
|
289
|
-
307 -
|
290
|
-
308 -
|
291
|
-
309 -
|
292
|
-
310 -
|
293
|
-
311 -
|
294
|
-
312 -
|
295
|
-
313 -
|
296
|
-
314 -
|
297
|
-
315 -
|
298
|
-
316 -
|
299
|
-
317 -
|
300
|
-
318 -
|
301
|
-
319 -
|
302
|
-
320 -
|
303
|
-
321 -
|
304
|
-
322 -
|
305
|
-
323 -
|
306
|
-
324 -
|
307
|
-
325 -
|
308
|
-
326 -
|
309
|
-
327 -
|
310
|
-
328 -
|
311
|
-
329 -
|
312
|
-
330 -
|
313
|
-
331 -
|
314
|
-
332 -
|
315
|
-
333 -
|
316
|
-
334 -
|
317
|
-
335 -
|
318
|
-
336 -
|
319
|
-
337 -
|
320
|
-
338 -
|
321
|
-
339 -
|
322
|
-
340 -
|
323
|
-
341 -
|
324
|
-
342 -
|
325
|
-
343 -
|
326
|
-
344 -
|
327
|
-
345 -
|
328
|
-
346 -
|
329
|
-
347 -
|
213
|
+
231 -1.00000
|
214
|
+
232 -3.00000
|
215
|
+
233 -5.00000
|
216
|
+
234 -7.00000
|
217
|
+
235 -9.00000
|
218
|
+
236 -11.00000
|
219
|
+
237 -13.00000
|
220
|
+
238 -15.00000
|
221
|
+
239 -17.00000
|
222
|
+
240 -19.00000
|
223
|
+
241 -21.00000
|
224
|
+
242 -23.00000
|
225
|
+
243 -25.00000
|
226
|
+
244 -27.00000
|
227
|
+
245 -29.00000
|
228
|
+
246 -31.00000
|
229
|
+
247 -33.00000
|
230
|
+
248 -35.00000
|
231
|
+
249 -37.00000
|
232
|
+
250 -39.00000
|
233
|
+
251 -41.00000
|
234
|
+
252 -43.00000
|
235
|
+
253 -45.00000
|
236
|
+
254 -47.00000
|
237
|
+
255 -49.00000
|
238
|
+
256 -51.00000
|
239
|
+
257 -53.00000
|
240
|
+
258 -55.00000
|
241
|
+
259 -57.00000
|
242
|
+
260 -59.00000
|
243
|
+
261 -61.00000
|
244
|
+
262 -63.00000
|
245
|
+
263 -65.00000
|
246
|
+
264 -67.00000
|
247
|
+
265 -69.00000
|
248
|
+
266 -71.00000
|
249
|
+
267 -73.00000
|
250
|
+
268 -75.00000
|
251
|
+
269 -77.00000
|
252
|
+
270 -79.00000
|
253
|
+
271 -81.00000
|
254
|
+
272 -83.00000
|
255
|
+
273 -85.00000
|
256
|
+
274 -87.00000
|
257
|
+
275 -89.00000
|
258
|
+
276 -91.00000
|
259
|
+
277 -93.00000
|
260
|
+
278 -95.00000
|
261
|
+
279 -97.00000
|
262
|
+
280 -99.00000
|
263
|
+
281 -101.00000
|
264
|
+
282 -103.00000
|
265
|
+
283 -105.00000
|
266
|
+
284 -107.00000
|
267
|
+
285 -109.00000
|
268
|
+
286 -111.00000
|
269
|
+
287 -113.00000
|
270
|
+
288 -115.00000
|
271
|
+
289 -117.00000
|
272
|
+
290 -119.00000
|
273
|
+
291 -121.00000
|
274
|
+
292 -123.00000
|
275
|
+
293 -125.00000
|
276
|
+
294 -127.00000
|
277
|
+
295 -129.00000
|
278
|
+
296 -131.00000
|
279
|
+
297 -133.00000
|
280
|
+
298 -135.00000
|
281
|
+
299 -137.00000
|
282
|
+
300 -139.00000
|
283
|
+
301 -141.00000
|
284
|
+
302 -143.00000
|
285
|
+
303 -145.00000
|
286
|
+
304 -147.00000
|
287
|
+
305 -149.00000
|
288
|
+
306 -151.00000
|
289
|
+
307 -153.00000
|
290
|
+
308 -155.00000
|
291
|
+
309 -157.00000
|
292
|
+
310 -159.00000
|
293
|
+
311 -161.00000
|
294
|
+
312 -163.00000
|
295
|
+
313 -165.00000
|
296
|
+
314 -167.00000
|
297
|
+
315 -169.00000
|
298
|
+
316 -171.00000
|
299
|
+
317 -173.00000
|
300
|
+
318 -175.00000
|
301
|
+
319 -177.00000
|
302
|
+
320 -179.00000
|
303
|
+
321 -181.00000
|
304
|
+
322 -183.00000
|
305
|
+
323 -185.00000
|
306
|
+
324 -187.00000
|
307
|
+
325 -189.00000
|
308
|
+
326 -191.00000
|
309
|
+
327 -193.00000
|
310
|
+
328 -195.00000
|
311
|
+
329 -197.00000
|
312
|
+
330 -199.00000
|
313
|
+
331 -201.00000
|
314
|
+
332 -203.00000
|
315
|
+
333 -205.00000
|
316
|
+
334 -207.00000
|
317
|
+
335 -209.00000
|
318
|
+
336 -211.00000
|
319
|
+
337 -213.00000
|
320
|
+
338 -215.00000
|
321
|
+
339 -217.00000
|
322
|
+
340 -219.00000
|
323
|
+
341 -221.00000
|
324
|
+
342 -223.00000
|
325
|
+
343 -225.00000
|
326
|
+
344 -227.00000
|
327
|
+
345 -229.00000
|
328
|
+
346 -231.00000
|
329
|
+
347 -233.00000
|
data/test/test_extractor.rb
CHANGED
@@ -22,14 +22,23 @@ class TestExtractor < Test::Unit::TestCase
|
|
22
22
|
io = StringIO.new
|
23
23
|
ops = {:destination => io, :channel => "axis1/position/y"}
|
24
24
|
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/FLEM_curves_example_migrated_to_2012.action", ops)
|
25
|
-
|
25
|
+
line_re = /12 -101.80433/
|
26
|
+
assert_match line_re , io.string
|
26
27
|
end
|
27
28
|
|
29
|
+
def test_extraction_succeeds_for_tw_with_odd_end
|
30
|
+
io = StringIO.new
|
31
|
+
ops = {:start_frame => 1, :end_frame => 504, :destination => io, :channel => "Timing/Timing"}
|
32
|
+
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/timewarp_where_interp_fails_at_end.timewarp", ops)
|
33
|
+
line_re = /1\t-7.00000\n2\t-6.00000/
|
34
|
+
assert_match line_re , io.string
|
35
|
+
end
|
28
36
|
|
29
37
|
def test_frame_overrides
|
30
38
|
io = StringIO.new
|
31
39
|
o = {:destination => io, :start_frame => 19, :end_frame => 347 }
|
32
40
|
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/RefT_Steadicam.timewarp", o)
|
41
|
+
|
33
42
|
assert_equal File.read(File.dirname(__FILE__) + "/snaps/RefT_Steadicam_Extraction_F19_to_347.txt"), io.string
|
34
43
|
end
|
35
44
|
|
data/test/test_interpolator.rb
CHANGED
@@ -116,6 +116,17 @@ class TestInterpolator < Test::Unit::TestCase
|
|
116
116
|
assert_in_delta 1, interp.sample_at(230), DELTA
|
117
117
|
end
|
118
118
|
|
119
|
+
def test_ascending_linear_extrapolation_on_baked_curve
|
120
|
+
data = File.open(File.dirname(__FILE__) + "/snaps/timewarp_where_interp_fails_at_end.timewarp")
|
121
|
+
channels_in_tw = FlameChannelParser.parse(data)
|
122
|
+
chan = channels_in_tw.find{|c| c.name == "Timing/Timing"}
|
123
|
+
interp = chan.to_interpolator
|
124
|
+
assert_in_delta -7, interp.sample_at(1), DELTA
|
125
|
+
assert_in_delta 492, interp.sample_at(502), DELTA
|
126
|
+
assert_in_delta 492, interp.sample_at(502), DELTA
|
127
|
+
assert_in_delta 494, interp.sample_at(504), DELTA
|
128
|
+
end
|
129
|
+
|
119
130
|
def test_descending_linear_prepolate_two_KFs
|
120
131
|
data = File.open(File.dirname(__FILE__) + "/snaps/RefT_Steadicam_TwoKFs.timewarp")
|
121
132
|
channels_in_tw = FlameChannelParser.parse(data)
|
@@ -125,7 +136,7 @@ class TestInterpolator < Test::Unit::TestCase
|
|
125
136
|
assert_in_delta 459, interp.sample_at(1), DELTA
|
126
137
|
assert_in_delta 421, interp.sample_at(20), DELTA
|
127
138
|
assert_in_delta 1, interp.sample_at(230), DELTA
|
128
|
-
assert_in_delta -39, interp.sample_at(250), DELTA
|
139
|
+
assert_in_delta( -39, interp.sample_at(250), DELTA)
|
129
140
|
end
|
130
141
|
|
131
142
|
def test_descending_linear_prepolate_two_KFs_different_slope
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flame_channel_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 2
|
10
|
+
version: 1.3.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Julik Tarkhanov
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-06 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|