flame_channel_parser 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|