tracksperanto 2.9.5 → 2.9.6
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/Gemfile +1 -1
- data/History.txt +5 -0
- data/bin/tracksperanto +32 -22
- data/lib/export/equalizer3.rb +1 -1
- data/lib/export/equalizer4.rb +1 -1
- data/lib/import/flame_stabilizer.rb +3 -3
- data/lib/import/nuke_script.rb +25 -7
- data/lib/middleware/base.rb +14 -7
- data/lib/middleware/crop.rb +9 -2
- data/lib/middleware/flip.rb +5 -3
- data/lib/middleware/flop.rb +4 -2
- data/lib/middleware/golden.rb +5 -2
- data/lib/middleware/length_cutoff.rb +6 -2
- data/lib/middleware/lerp.rb +5 -2
- data/lib/middleware/lint.rb +5 -0
- data/lib/middleware/move_to_first.rb +50 -0
- data/lib/middleware/pad.rb +8 -2
- data/lib/middleware/prefix.rb +6 -2
- data/lib/middleware/reformat.rb +6 -3
- data/lib/middleware/scaler.rb +6 -2
- data/lib/middleware/shift.rb +7 -2
- data/lib/middleware/slipper.rb +6 -2
- data/lib/middleware/start_trim.rb +6 -6
- data/lib/pipeline/base.rb +34 -38
- data/lib/tracksperanto.rb +18 -1
- data/lib/tracksperanto/format_detector.rb +26 -26
- data/lib/tracksperanto/parameters.rb +56 -0
- data/lib/tracksperanto/yield_non_empty.rb +15 -0
- data/test/import/test_nuke_import.rb +16 -1
- data/test/middleware/test_crop_middleware.rb +5 -0
- data/test/middleware/test_flip_middleware.rb +4 -19
- data/test/middleware/test_flop_middleware.rb +4 -9
- data/test/middleware/test_golden_middleware.rb +3 -10
- data/test/middleware/test_length_cutoff_middleware.rb +5 -0
- data/test/middleware/test_lerp_middleware.rb +6 -20
- data/test/middleware/test_lint_middleware.rb +5 -0
- data/test/middleware/test_move_to_first_frame_middleware.rb +38 -0
- data/test/middleware/test_pad_middleware.rb +5 -0
- data/test/middleware/test_prefix.rb +4 -0
- data/test/middleware/test_reformat_middleware.rb +3 -2
- data/test/middleware/test_scaler_middleware.rb +5 -0
- data/test/middleware/test_shift_middleware.rb +5 -0
- data/test/middleware/test_slip_middleware.rb +5 -0
- data/test/middleware/test_start_trim_middleware.rb +3 -9
- data/test/test_cli.rb +3 -3
- data/test/test_format_detector.rb +1 -1
- data/test/test_parameters.rb +38 -0
- data/test/test_tracksperanto.rb +10 -0
- data/test/test_yield_non_empty.rb +11 -0
- data/tracksperanto.gemspec +11 -5
- metadata +27 -21
data/Gemfile
CHANGED
data/History.txt
CHANGED
data/bin/tracksperanto
CHANGED
@@ -17,7 +17,7 @@ require 'progressbar'
|
|
17
17
|
require "update_hints"
|
18
18
|
|
19
19
|
def disclaimer
|
20
|
-
"Please consider a small donation to keep Tracksperanto going
|
20
|
+
"Please consider a small donation to keep Tracksperanto going: http://guerilla-di.org/source-and-license/\n"+
|
21
21
|
"For information and support please contact info#{64.chr}guerilla-di.org"
|
22
22
|
end
|
23
23
|
|
@@ -29,13 +29,21 @@ writers = Tracksperanto.exporter_names
|
|
29
29
|
|
30
30
|
op = OptionParser.new
|
31
31
|
|
32
|
-
def mw(
|
32
|
+
def mw(*name_option_and_default_value)
|
33
33
|
Proc.new do |value|
|
34
|
+
name, option, default_value = name_option_and_default_value
|
34
35
|
v = value.nil? ? default_value : value
|
35
|
-
|
36
|
+
mw_tuple = [name]
|
37
|
+
mw_tuple.push({option => v}) if option
|
38
|
+
|
39
|
+
$middlewares.push(mw_tuple)
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
43
|
+
def mwd(name)
|
44
|
+
Tracksperanto.get_middleware(name).action_description
|
45
|
+
end
|
46
|
+
|
39
47
|
def list_exporters(dest = $stderr)
|
40
48
|
dest.puts "The following export modules are available:"
|
41
49
|
Tracksperanto.exporters.each do | exporter |
|
@@ -66,32 +74,35 @@ op.on(" -w", "--width WIDTH_IN_PIXELS", Integer, "Absolute input comp width in p
|
|
66
74
|
op.on(" -h", "--height HEIGHT_IN_PIXELS", Integer, "Absolute input comp height in pixels (will try to autodetect)") {|w| options[:height] = w }
|
67
75
|
op.on(" -o", "--only EXPORTER_NAME", String, "Only export the selected format, format must be one of #{writers.join(", ")}") { |f| writer_class_name = f }
|
68
76
|
|
69
|
-
op.on(" -xs", "--xscale X_SCALING_FACTOR", Float, "
|
77
|
+
op.on(" -xs", "--xscale X_SCALING_FACTOR", Float, mwd("Scaler"), &mw("Scaler", :x_factor))
|
70
78
|
|
71
|
-
op.on(" -pad", "--pad PAD_FRACTION_VALUES_COMMA_SEPARATED", String, "Pad
|
79
|
+
op.on(" -pad", "--pad PAD_FRACTION_VALUES_COMMA_SEPARATED", String, mwd("Pad")) do | pads|
|
72
80
|
left, right, top, bottom = pads.split(",").map{|e| e.to_f }
|
73
81
|
$middlewares.push(["Pad", {"left_pad" => left, "right_pad"=> right, "top_pad" => top, "bottom_pad" => bottom}])
|
74
82
|
end
|
75
83
|
|
76
|
-
op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String, "Crop
|
84
|
+
op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String, mwd("Crop")) do | pads|
|
77
85
|
left, right, top, bottom = pads.split(",").map{|e| e.to_i }
|
78
86
|
$middlewares.push(["Crop", {"left" => left, "right"=> right, "top" => top, "bottom" => bottom}])
|
79
87
|
end
|
80
88
|
|
81
|
-
op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, "
|
82
|
-
op.on(" -t", "--trim",
|
83
|
-
op.on(" -s", "--slip FRAMES", Integer, "
|
84
|
-
|
85
|
-
op.on(" -
|
89
|
+
op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, mwd("Scaler"), &mw("Scaler", :y_factor))
|
90
|
+
op.on(" -t", "--trim", Float, mwd("StartTrim"), &mw("StartTrim")) # Before slip!
|
91
|
+
op.on(" -s", "--slip FRAMES", Integer, mwd("Slipper"), &mw("Slipper", :slip))
|
92
|
+
op.on(" -g", "--golden", mwd("Golden"), &mw("Golden"))
|
93
|
+
op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer, mwd("LengthCutoff"), &mw("LengthCutoff", :min_length))
|
94
|
+
op.on(" -p", "--prefix PREFIX", String, mwd("Prefix"), &mw("Prefix", :prefix))
|
95
|
+
op.on("--lerp", mwd("Lerp"), &mw("Lerp"))
|
96
|
+
op.on("--flip", mwd("Flip"), &mw("Flip"))
|
97
|
+
op.on("--flop", mwd("Flop"), &mw("Flop"))
|
98
|
+
|
99
|
+
# TODO - multiparameters
|
86
100
|
op.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it", &mw("Reformat", :width))
|
87
101
|
op.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it", &mw("Reformat", :height))
|
88
|
-
op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer, "Only export trackers having more than X keyframes", &mw("LengthCutoff", :min_length))
|
89
102
|
op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &mw("Shift", :x_shift))
|
90
103
|
op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &mw("Shift", :y_shift))
|
91
|
-
|
92
|
-
|
93
|
-
op.on("--flip", "Flip the comp horizontally", &mw("Flip", :enabled, true))
|
94
|
-
op.on("--flop", "Flop the comp vertically", &mw("Flop", :enabled, true))
|
104
|
+
|
105
|
+
|
95
106
|
op.on("--list-exporters", "Show available export modules") do
|
96
107
|
list_exporters; exit(0)
|
97
108
|
end
|
@@ -131,22 +142,21 @@ begin
|
|
131
142
|
pipe = Tracksperanto::Pipeline::Base.new(:progress_block => progress, :middleware_tuples => $middlewares)
|
132
143
|
pipe.exporters = [Tracksperanto.get_exporter(writer_class_name)] if writer_class_name
|
133
144
|
pipe.run(input_file, options)
|
145
|
+
pbar.finish
|
146
|
+
$stdout.puts "Found and converted %d trackers with %d keyframes." % [pipe.converted_points, pipe.converted_keyframes]
|
134
147
|
rescue Tracksperanto::UnknownExporterError => damn
|
135
148
|
$stderr.puts damn.message
|
136
149
|
list_exporters($stderr)
|
137
|
-
|
150
|
+
fail "Unknown exporter"
|
138
151
|
rescue Tracksperanto::UnknownImporterError => damn
|
139
152
|
$stderr.puts damn.message
|
140
153
|
list_importers($stderr)
|
141
|
-
|
154
|
+
fail "Unknown importer"
|
142
155
|
rescue Tracksperanto::UnknownMiddlewareError => damn
|
143
156
|
$stderr.puts damn.message
|
144
|
-
|
145
|
-
exit(2)
|
157
|
+
fail "This is a bug, please report it"
|
146
158
|
rescue Exception => damn
|
147
159
|
fail damn.message
|
148
|
-
ensure
|
149
|
-
pbar.finish
|
150
160
|
end
|
151
161
|
|
152
162
|
puts disclaimer
|
data/lib/export/equalizer3.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# Export for 3DE v3 point files
|
2
|
+
# Export for 3DE v3 point files. 3DE always starts frames at 1.
|
3
3
|
class Tracksperanto::Export::Equalizer3 < Tracksperanto::Export::Base
|
4
4
|
|
5
5
|
HEADER = '// 3DE Multiple Tracking Curves Export %d x %d * %d frames'
|
data/lib/export/equalizer4.rb
CHANGED
@@ -131,8 +131,8 @@ class Tracksperanto::Import::FlameStabilizer < Tracksperanto::Import::Base
|
|
131
131
|
|
132
132
|
def find_base_x_and_y(track_tuples, shift_tuples)
|
133
133
|
base_track_tuple = track_tuples.find do | track_tuple |
|
134
|
-
shift_tuples.find { |shift_tuple| shift_tuple[0] == track_tuple
|
135
|
-
end
|
136
|
-
base_track_tuple[1..2]
|
134
|
+
shift_tuples.find { |shift_tuple| shift_tuple[0] == track_tuple[0] }
|
135
|
+
end
|
136
|
+
(base_track_tuple || track_tuples[0])[1..2]
|
137
137
|
end
|
138
138
|
end
|
data/lib/import/nuke_script.rb
CHANGED
@@ -5,7 +5,7 @@ require File.expand_path(File.dirname(__FILE__)) + "/nuke_grammar/utils"
|
|
5
5
|
class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
|
6
6
|
|
7
7
|
def self.human_name
|
8
|
-
"Nuke .nk script file"
|
8
|
+
"Nuke .nk script file with Tracker or Reconcile3D nodes"
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.distinct_file_ext
|
@@ -16,7 +16,9 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
|
|
16
16
|
io = Tracksperanto::ExtIO.new(@io)
|
17
17
|
while line = io.gets_and_strip
|
18
18
|
if line =~ TRACKER_3_PATTERN
|
19
|
-
scan_tracker_node(io).each
|
19
|
+
scan_tracker_node(io).each(&Proc.new)
|
20
|
+
elsif line =~ RECONCILE_PATTERN
|
21
|
+
scan_reconcile_node(io).each(&Proc.new)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -24,9 +26,26 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
|
|
24
26
|
private
|
25
27
|
|
26
28
|
TRACKER_3_PATTERN = /^Tracker3 \{/
|
29
|
+
RECONCILE_PATTERN = /^Reconcile3D \{/
|
30
|
+
OUTPUT_PATTERN = /^output \{/
|
27
31
|
TRACK_PATTERN = /^track(\d) \{/
|
28
32
|
NODENAME = /^name ([^\n]+)/
|
29
33
|
|
34
|
+
|
35
|
+
# Scans a Reconcile3D node and returs it's output
|
36
|
+
def scan_reconcile_node(io)
|
37
|
+
t = Tracksperanto::Tracker.new
|
38
|
+
while line = io.gets_and_strip
|
39
|
+
if line =~ OUTPUT_PATTERN
|
40
|
+
t = extract_tracker(line)
|
41
|
+
elsif line =~ NODENAME
|
42
|
+
t.name = "Reconcile_#{$1}"
|
43
|
+
report_progress("Scavenging Reconcile3D node #{t.name}")
|
44
|
+
return [t] # Klunky
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
30
49
|
# Scans a tracker node and return all tracks within that node (no more than 4)
|
31
50
|
def scan_tracker_node(io)
|
32
51
|
tracks_in_tracker = []
|
@@ -56,11 +75,10 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
|
|
56
75
|
def extract_tracker(line)
|
57
76
|
tuples = scan_track(line)
|
58
77
|
return nil unless (tuples && tuples.any?)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Tracksperanto::Keyframe.new(:frame => f -1, :abs_x => x, :abs_y => y)
|
78
|
+
Tracksperanto::Tracker.new do | t |
|
79
|
+
tuples.each do | (f, x, y) |
|
80
|
+
t.keyframe!(:frame => (f -1), :abs_x => x, :abs_y => y)
|
63
81
|
end
|
64
|
-
|
82
|
+
end
|
65
83
|
end
|
66
84
|
end
|
data/lib/middleware/base.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
require "forwardable"
|
3
|
+
|
2
4
|
# The base middleware class works just like a Tracksperanto::Export::Base, but it only wraps another exporting object and does not get registered on it's own
|
3
5
|
# as an export format. Middleware can be used to massage the tracks being exported in various interesting ways - like moving the coordinates, clipping the keyframes,
|
4
6
|
# scaling the whole export or even reversing the trackers to go backwards
|
@@ -7,6 +9,10 @@ class Tracksperanto::Middleware::Base
|
|
7
9
|
include Tracksperanto::BlockInit
|
8
10
|
include Tracksperanto::ConstName
|
9
11
|
include Tracksperanto::SimpleExport
|
12
|
+
include Tracksperanto::Parameters
|
13
|
+
|
14
|
+
extend Forwardable
|
15
|
+
def_delegators :@exporter, :start_export, :start_tracker_segment, :end_tracker_segment, :export_point, :end_export
|
10
16
|
|
11
17
|
# Used to automatically register your middleware in Tracksperanto.middlewares
|
12
18
|
# Normally you wouldn't need to override this
|
@@ -15,15 +21,16 @@ class Tracksperanto::Middleware::Base
|
|
15
21
|
super
|
16
22
|
end
|
17
23
|
|
18
|
-
#
|
24
|
+
# Returns the human name of the action that the middleware will perform. The action is
|
25
|
+
# the in infinitive form, like "Remove all the invalid keyframes", "Crop the image" and so on
|
26
|
+
def self.action_description
|
27
|
+
"Base middleware class"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Constructor accepts the exporter that will be wrapped, followed by the optional options hash
|
31
|
+
# and the optional block that yields self
|
19
32
|
def initialize(*exporter_and_args_for_block_init)
|
20
33
|
@exporter = exporter_and_args_for_block_init.shift
|
21
34
|
super
|
22
35
|
end
|
23
|
-
|
24
|
-
%w( start_export start_tracker_segment end_tracker_segment
|
25
|
-
export_point end_export).each do | m |
|
26
|
-
define_method(m){|*a| @exporter.send(m, *a)}
|
27
|
-
end
|
28
|
-
|
29
36
|
end
|
data/lib/middleware/crop.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Does the same as the Pad middleware but with absolute pixel values instead of fractionals
|
3
3
|
class Tracksperanto::Middleware::Crop < Tracksperanto::Middleware::Base
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
parameter :top, :cast => :int, :desc => "Top crop amount in px"
|
6
|
+
parameter :left, :cast => :int, :desc => "Left crop amount in px"
|
7
|
+
parameter :right, :cast => :int, :desc => "Right crop amount in px"
|
8
|
+
parameter :bottom, :cast => :int, :desc => "Bottom crop amount in px"
|
9
|
+
|
10
|
+
def self.action_description
|
11
|
+
"Crop or pad the image by a specified number of pixels"
|
12
|
+
end
|
6
13
|
|
7
14
|
def start_export(w, h)
|
8
15
|
left_pad, right_pad, top_pad, bottom_pad = (left / w.to_f), (right / w.to_f), (top / h.to_f), (bottom / h.to_f)
|
data/lib/middleware/flip.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Flips the comp being exported horizontally
|
3
3
|
class Tracksperanto::Middleware::Flip < Tracksperanto::Middleware::Base
|
4
|
-
|
5
|
-
|
4
|
+
|
5
|
+
def self.action_description
|
6
|
+
"Mirrors all the tracker paths horizontally"
|
7
|
+
end
|
6
8
|
|
7
9
|
def start_export(w, h)
|
8
|
-
factor =
|
10
|
+
factor = -1
|
9
11
|
@exporter = Tracksperanto::Middleware::Scaler.new(@exporter, :x_factor => factor)
|
10
12
|
super
|
11
13
|
end
|
data/lib/middleware/flop.rb
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
# Flips the comp being exported vertically
|
3
3
|
class Tracksperanto::Middleware::Flop < Tracksperanto::Middleware::Base
|
4
4
|
|
5
|
-
|
5
|
+
def self.action_description
|
6
|
+
"Mirror all the tracker paths vertically"
|
7
|
+
end
|
6
8
|
|
7
9
|
def start_export(w, h)
|
8
|
-
factor =
|
10
|
+
factor = -1
|
9
11
|
@exporter = Tracksperanto::Middleware::Scaler.new(@exporter, :y_factor => factor)
|
10
12
|
super
|
11
13
|
end
|
data/lib/middleware/golden.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# This middleware marks all trackers as being 100% accurate
|
3
3
|
class Tracksperanto::Middleware::Golden < Tracksperanto::Middleware::Base
|
4
|
-
|
4
|
+
|
5
|
+
def self.action_description
|
6
|
+
"Reset residual of all the trackers to zero"
|
7
|
+
end
|
5
8
|
|
6
9
|
def export_point(frame, float_x, float_y, float_residual)
|
7
|
-
super(frame, float_x, float_y,
|
10
|
+
super(frame, float_x, float_y, 0.0)
|
8
11
|
end
|
9
12
|
|
10
13
|
end
|
@@ -2,8 +2,12 @@
|
|
2
2
|
# This middleware removes trackers that contain less than min_length keyframes
|
3
3
|
# from the exported batch
|
4
4
|
class Tracksperanto::Middleware::LengthCutoff < Tracksperanto::Middleware::Base
|
5
|
-
|
6
|
-
|
5
|
+
|
6
|
+
parameter :min_length, :cast => :int, :desc => "The minimum number of keyframes for the item to contain", :default => 100
|
7
|
+
|
8
|
+
def self.action_description
|
9
|
+
"Remove trackers that have less than the specified number of keyframes"
|
10
|
+
end
|
7
11
|
|
8
12
|
def start_tracker_segment(name)
|
9
13
|
@tracker = Tracksperanto::Tracker.new(:name => name)
|
data/lib/middleware/lerp.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# This middleware adds linearly interpolated keyframes BETWEEN the keyframes passing through the exporter
|
3
3
|
class Tracksperanto::Middleware::Lerp < Tracksperanto::Middleware::Base
|
4
|
-
|
4
|
+
|
5
|
+
def self.action_description
|
6
|
+
"Interpolate missing keyframes of all the trackers"
|
7
|
+
end
|
5
8
|
|
6
9
|
def end_tracker_segment
|
7
10
|
@last_f, @last_x, @last_y, @last_res = nil, nil, nil, nil
|
@@ -10,7 +13,7 @@ class Tracksperanto::Middleware::Lerp < Tracksperanto::Middleware::Base
|
|
10
13
|
|
11
14
|
def export_point(frame, float_x, float_y, float_residual)
|
12
15
|
|
13
|
-
if @
|
16
|
+
if @last_f && (frame - @last_f > 1) # Interpolate!
|
14
17
|
interpolated_frames = []
|
15
18
|
interpolated_x = []
|
16
19
|
lerp(@last_f, @last_x, frame, float_x) do | interp_f, interp_x |
|
data/lib/middleware/lint.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Prevents you from exporting invalid trackers
|
3
3
|
class Tracksperanto::Middleware::Lint < Tracksperanto::Middleware::Base
|
4
|
+
|
5
|
+
def self.action_description
|
6
|
+
"Verify all the exported trackers and check for errors"
|
7
|
+
end
|
8
|
+
|
4
9
|
class NoTrackersExportedError < RuntimeError
|
5
10
|
def message
|
6
11
|
"There were no trackers exported"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
# Sometimes your tracked sequence has been loaded from say frame 73282381, but you want to import into an application
|
3
|
+
# that expects the trackers to start at frame 1. This middleware autoslips everything so that your trackers start at frame 1.
|
4
|
+
class Tracksperanto::Middleware::MoveToFirst < Tracksperanto::Middleware::Base
|
5
|
+
|
6
|
+
def self.action_description
|
7
|
+
"Move all the keyframes in time so that the first frame is the first animated keyframe"
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_export(width, height)
|
11
|
+
@width, @height = width, height
|
12
|
+
@start_frames = []
|
13
|
+
@buf = Obuf.new
|
14
|
+
@registered = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_tracker_segment(tracker_name)
|
18
|
+
@current = Tracksperanto::Tracker.new(:name => tracker_name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def end_tracker_segment
|
22
|
+
@buf.push(@current)
|
23
|
+
@registered = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def export_point(frame, float_x, float_y, float_residual)
|
27
|
+
@current.keyframe!(:frame => frame, :abs_x => float_x, :abs_y => float_y, :residual => float_residual)
|
28
|
+
return if @registered
|
29
|
+
|
30
|
+
# Note where this tracker starts
|
31
|
+
@start_frames.push(frame)
|
32
|
+
@registered = true
|
33
|
+
end
|
34
|
+
|
35
|
+
def end_export
|
36
|
+
actual_start = @start_frames.sort.shift
|
37
|
+
|
38
|
+
@exporter.start_export(@width, @height)
|
39
|
+
@buf.each do | tracker |
|
40
|
+
@exporter.start_tracker_segment(tracker.name)
|
41
|
+
tracker.each do | kf |
|
42
|
+
@exporter.export_point(kf.frame - actual_start, kf.abs_x, kf.abs_y, kf.residual)
|
43
|
+
end
|
44
|
+
@exporter.end_tracker_segment
|
45
|
+
end
|
46
|
+
@exporter.end_export
|
47
|
+
|
48
|
+
@buf.clear
|
49
|
+
end
|
50
|
+
end
|
data/lib/middleware/pad.rb
CHANGED
@@ -3,9 +3,15 @@
|
|
3
3
|
# some fucked-up telecine transfers. The padding is in fractional units of the total width
|
4
4
|
# and height
|
5
5
|
class Tracksperanto::Middleware::Pad < Tracksperanto::Middleware::Base
|
6
|
-
attr_accessor :left_pad, :right_pad, :top_pad, :bottom_pad
|
7
6
|
|
8
|
-
|
7
|
+
parameter :top_pad, :cast => :float, :desc => "Top padding (fraction of original size)"
|
8
|
+
parameter :left_pad, :cast => :float, :desc => "Left padding (fraction of original size)"
|
9
|
+
parameter :right_pad, :cast => :float, :desc => "Right padding (fraction of original size)"
|
10
|
+
parameter :bottom_pad, :cast => :float, :desc => "Bottom padding (fraction of original size)"
|
11
|
+
|
12
|
+
def self.action_description
|
13
|
+
"Pad or crop the image by a fraction of it's original size"
|
14
|
+
end
|
9
15
|
|
10
16
|
def start_export(w, h)
|
11
17
|
@shift_left, @shift_bottom = w * left_pad, h * bottom_pad
|