tracksperanto 1.9.9 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ === 2.0.0 / 2011-01-27
2
+ * Bugfix for PFTrack exports to contain cross-platform linebreaks (rn instead of n)
3
+
4
+ === 1.9.9 / 2010-08-11
5
+
6
+ * Buffer the parsed trackers on disk or in a stream (all backwards-compatible). Substantially reduces conversion times and memory
7
+ usage on huge files.
8
+
1
9
  === 1.9.8 / 2010-08-11
2
10
 
3
11
  * Very minor changes and improvements
data/bin/tracksperanto CHANGED
@@ -71,8 +71,8 @@ op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &m
71
71
  op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &mw("Shift", :y_shift))
72
72
  op.on(" -p", "--prefix PREFIX", String, "A prefix to prepend to tracker names in bulk", &mw("Prefix", :prefix))
73
73
  op.on("--lerp", "Linearly interpolate missing keyframes", &mw("Lerp", :enabled, true))
74
- op.on("--flip", "Flip the comp horizontally", &mw("Flip", :flip, true))
75
- op.on("--flop", "Flop the comp vertically", &mw("Flip", :flop, true))
74
+ op.on("--flip", "Flip the comp horizontally", &mw("Flip", :enabled, true))
75
+ op.on("--flop", "Flop the comp vertically", &mw("Flop", :enabled, true))
76
76
 
77
77
  op.on("--version", "Show the version and exit") do |v|
78
78
  puts "Tracksperanto v.#{Tracksperanto::VERSION} running on Ruby #{RUBY_VERSION} on #{RUBY_PLATFORM}"
@@ -31,6 +31,7 @@ class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
31
31
  def export_point(frame, abs_float_x, abs_float_y, float_residual)
32
32
  @frame_count += 1
33
33
  line = KEYFRAME_TEMPLATE % [frame, abs_float_x, abs_float_y, float_residual / 8]
34
- @tracker_io.puts(line)
34
+ @tracker_io.write(line)
35
+ @tracker_io.write("\r\n")
35
36
  end
36
37
  end
@@ -10,10 +10,13 @@ class Tracksperanto::Export::PFTrack5 < Tracksperanto::Export::PFTrack4
10
10
  end
11
11
 
12
12
  def end_tracker_segment
13
- @io.write("\n\n")
14
- @io.puts(@tracker_name.inspect) # autoquotes
15
- @io.puts("Primary".inspect) # For primary/secondary cam in stereo pair
16
- @io.puts(@frame_count)
13
+ @io.write("\r\n\r\n")
14
+ @io.write(@tracker_name.inspect) # autoquotes
15
+ @io.write("\r\n")
16
+ @io.write("Primary".inspect) # For primary/secondary cam in stereo pair
17
+ @io.write("\r\n")
18
+ @io.write(@frame_count)
19
+ @io.write("\r\n")
17
20
 
18
21
  @tracker_io.rewind
19
22
  @io.write(@tracker_io.read) until @tracker_io.eof?
data/lib/import/base.rb CHANGED
@@ -8,7 +8,8 @@ class Tracksperanto::Import::Base
8
8
  include Tracksperanto::ZipTuples
9
9
  include Tracksperanto::ConstName
10
10
 
11
- # Every time the importer accumulates a tracker this block will be called
11
+ # Every time the importer accumulates a tracker this object's #push method will be called.
12
+ # Can be an array or a more full-featured buffer
12
13
  attr_accessor :receiver
13
14
 
14
15
  # Tracksperanto will assign a proc that reports the status of the import to the caller.
@@ -67,12 +68,6 @@ class Tracksperanto::Import::Base
67
68
  # and then send it to the caller. Used in tests.
68
69
  def parse(track_file_io)
69
70
  @receiver = []
70
- class << @receiver
71
- def call(with)
72
- push(with)
73
- end
74
- end
75
-
76
71
  stream_parse(track_file_io)
77
72
  @receiver
78
73
  end
@@ -87,6 +82,10 @@ class Tracksperanto::Import::Base
87
82
 
88
83
  # When a tracker has been detected completely (all keyframes) call this method with the tracker object as argument
89
84
  def send_tracker(tracker_obj)
90
- @receiver.call(tracker_obj) if @receiver
85
+ if @receiver
86
+ @receiver.push(tracker_obj)
87
+ else
88
+ raise "Tracker received but no @receiver has been set for #{self.inspect}"
89
+ end
91
90
  end
92
91
  end
@@ -26,7 +26,7 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
26
26
  TRACK_PATTERN = /^track(\d) \{/
27
27
  NODENAME = /^name ([^\n]+)/
28
28
 
29
-
29
+ # Scans a tracker node and return all tracks within that node (no more than 4)
30
30
  def scan_tracker_node(io)
31
31
  tracks_in_tracker = []
32
32
  while line = io.gets_and_strip
@@ -1,7 +1,7 @@
1
- # Flips the comp being exported horizontally or vertically
1
+ # Flips the comp being exported horizontally
2
2
  class Tracksperanto::Middleware::Flip < Tracksperanto::Middleware::Base
3
3
 
4
- attr_accessor :flip, :flop
4
+ attr_accessor :enabled
5
5
 
6
6
  def start_export(w, h)
7
7
  @w, @h = w, h
@@ -9,8 +9,7 @@ class Tracksperanto::Middleware::Flip < Tracksperanto::Middleware::Base
9
9
  end
10
10
 
11
11
  def export_point(frame, float_x, float_y, float_residual)
12
- x = @flip ? (@w - float_x) : float_x
13
- y = @flop ? (@h - float_y) : float_y
14
- super(frame, x, y, float_residual)
12
+ x = @enabled ? (@w - float_x) : float_x
13
+ super(frame, x, float_y, float_residual)
15
14
  end
16
15
  end
data/lib/pipeline/base.rb CHANGED
@@ -157,14 +157,13 @@ class Tracksperanto::Pipeline::Base
157
157
  # that replays to all of them
158
158
  def setup_outputs_for(input_file_path)
159
159
  file_name = File.basename(input_file_path).gsub(EXTENSION, '')
160
- export_klasses = exporters || Tracksperanto.exporters
161
- Tracksperanto::Export::Mux.new(
162
- export_klasses.map do | exporter_class |
163
- export_name = [file_name, exporter_class.desc_and_extension].join("_")
164
- export_path = File.join(File.dirname(input_file_path), export_name)
165
- exporter = exporter_class.new(open_owned_export_file(export_path))
166
- end
167
- )
160
+ outputs = (exporters || Tracksperanto.exporters).map do | exporter_class |
161
+ export_name = [file_name, exporter_class.desc_and_extension].join("_")
162
+ export_path = File.join(File.dirname(input_file_path), export_name)
163
+ exporter_class.new(open_owned_export_file(export_path))
164
+ end
165
+
166
+ Tracksperanto::Export::Mux.new(outputs)
168
167
  end
169
168
 
170
169
  # Open the file for writing and register it to be closed automatically
data/lib/tracksperanto.rb CHANGED
@@ -4,7 +4,7 @@ require 'tempfile'
4
4
 
5
5
  module Tracksperanto
6
6
  PATH = File.expand_path(File.dirname(__FILE__))
7
- VERSION = '1.9.9'
7
+ VERSION = '2.0.0'
8
8
 
9
9
  module Import; end
10
10
  module Export; end
@@ -1,16 +1,22 @@
1
+ # An accumulator buffer for Ruby objects. Use it to sequentially store a shitload
2
+ # of objects on disk and then retreive them one by one. Make sure to call #close! when done with it to
3
+ # discard the stored blob. This object is intended to be used as a Tracksperanto::Import::Base#receiver
1
4
  class Tracksperanto::Accumulator < DelegateClass(IO)
2
5
 
6
+ # Stores the number of objects stored so far
3
7
  attr_reader :numt
8
+
4
9
  def initialize
5
10
  __setobj__(Tracksperanto::BufferIO.new)
6
11
  @numt = 0
7
12
  end
8
13
 
9
- def call(with_arrived_tracker)
14
+ # Store an object
15
+ def push(object_to_store)
10
16
 
11
17
  @numt += 1
12
18
 
13
- d = Marshal.dump(with_arrived_tracker)
19
+ d = Marshal.dump(object_to_store)
14
20
  bytelen = d.size
15
21
  write(bytelen)
16
22
  write("\t")
@@ -18,16 +24,18 @@ class Tracksperanto::Accumulator < DelegateClass(IO)
18
24
  write("\n")
19
25
  end
20
26
 
27
+ # Retreive each stored object in succession
21
28
  def each_object_with_index
22
29
  rewind
23
- @numt.times { |i| yield(recover_tracker, i - 1) }
30
+ @numt.times { |i| yield(recover_object, i - 1) }
24
31
  end
25
32
 
26
33
  private
27
34
 
28
- def recover_tracker
29
- # Read everything upto the tab
35
+ def recover_object
36
+ # Up to the tab is the amount of bytes to read
30
37
  demarshal_bytes = gets("\t").strip.to_i
38
+ # Then read the bytes and unmarshal it
31
39
  Marshal.load(read(demarshal_bytes))
32
40
  end
33
41
  end
@@ -2,50 +2,50 @@
2
2
 
3
3
  "Parabolic_1_from_top_left"
4
4
  19
5
- 0 0.000 1080.000 0.000
6
- 1 96.000 874.800 0.006
7
- 2 192.000 691.200 0.012
8
- 3 288.000 529.200 0.018
9
- 4 384.000 388.800 0.024
10
- 5 480.000 270.000 0.030
11
- 6 576.000 172.800 0.036
12
- 7 672.000 97.200 0.042
13
- 8 768.000 43.200 0.048
14
- 9 864.000 10.800 0.054
15
- 12 1152.000 43.200 0.071
16
- 13 1248.000 97.200 0.077
17
- 14 1344.000 172.800 0.083
18
- 15 1440.000 270.000 0.089
19
- 16 1536.000 388.800 0.095
20
- 17 1632.000 529.200 0.101
21
- 18 1728.000 691.200 0.107
22
- 19 1824.000 874.800 0.113
23
- 20 1920.000 1080.000 0.119
5
+ 0 0.000 1080.000 0.000
6
+ 1 96.000 874.800 0.006
7
+ 2 192.000 691.200 0.012
8
+ 3 288.000 529.200 0.018
9
+ 4 384.000 388.800 0.024
10
+ 5 480.000 270.000 0.030
11
+ 6 576.000 172.800 0.036
12
+ 7 672.000 97.200 0.042
13
+ 8 768.000 43.200 0.048
14
+ 9 864.000 10.800 0.054
15
+ 12 1152.000 43.200 0.071
16
+ 13 1248.000 97.200 0.077
17
+ 14 1344.000 172.800 0.083
18
+ 15 1440.000 270.000 0.089
19
+ 16 1536.000 388.800 0.095
20
+ 17 1632.000 529.200 0.101
21
+ 18 1728.000 691.200 0.107
22
+ 19 1824.000 874.800 0.113
23
+ 20 1920.000 1080.000 0.119
24
24
 
25
25
 
26
26
  "Parabolic_2_from_bottom_right"
27
27
  19
28
- 0 1920.000 0.000 0.000
29
- 1 1824.000 205.200 0.006
30
- 2 1728.000 388.800 0.012
31
- 3 1632.000 550.800 0.018
32
- 4 1536.000 691.200 0.024
33
- 5 1440.000 810.000 0.030
34
- 6 1344.000 907.200 0.036
35
- 7 1248.000 982.800 0.042
36
- 8 1152.000 1036.800 0.048
37
- 9 1056.000 1069.200 0.054
38
- 12 768.000 1036.800 0.071
39
- 13 672.000 982.800 0.077
40
- 14 576.000 907.200 0.083
41
- 15 480.000 810.000 0.089
42
- 16 384.000 691.200 0.095
43
- 17 288.000 550.800 0.101
44
- 18 192.000 388.800 0.107
45
- 19 96.000 205.200 0.113
46
- 20 0.000 0.000 0.119
28
+ 0 1920.000 0.000 0.000
29
+ 1 1824.000 205.200 0.006
30
+ 2 1728.000 388.800 0.012
31
+ 3 1632.000 550.800 0.018
32
+ 4 1536.000 691.200 0.024
33
+ 5 1440.000 810.000 0.030
34
+ 6 1344.000 907.200 0.036
35
+ 7 1248.000 982.800 0.042
36
+ 8 1152.000 1036.800 0.048
37
+ 9 1056.000 1069.200 0.054
38
+ 12 768.000 1036.800 0.071
39
+ 13 672.000 982.800 0.077
40
+ 14 576.000 907.200 0.083
41
+ 15 480.000 810.000 0.089
42
+ 16 384.000 691.200 0.095
43
+ 17 288.000 550.800 0.101
44
+ 18 192.000 388.800 0.107
45
+ 19 96.000 205.200 0.113
46
+ 20 0.000 0.000 0.119
47
47
 
48
48
 
49
49
  "SingleFrame"
50
50
  1
51
- 0 970.000 550.000 0.000
51
+ 0 970.000 550.000 0.000
@@ -1,54 +1,54 @@
1
-
2
-
3
- "Parabolic_1_from_top_left"
4
- "Primary"
5
- 19
6
- 0 0.000 1080.000 0.000
7
- 1 96.000 874.800 0.006
8
- 2 192.000 691.200 0.012
9
- 3 288.000 529.200 0.018
10
- 4 384.000 388.800 0.024
11
- 5 480.000 270.000 0.030
12
- 6 576.000 172.800 0.036
13
- 7 672.000 97.200 0.042
14
- 8 768.000 43.200 0.048
15
- 9 864.000 10.800 0.054
16
- 12 1152.000 43.200 0.071
17
- 13 1248.000 97.200 0.077
18
- 14 1344.000 172.800 0.083
19
- 15 1440.000 270.000 0.089
20
- 16 1536.000 388.800 0.095
21
- 17 1632.000 529.200 0.101
22
- 18 1728.000 691.200 0.107
23
- 19 1824.000 874.800 0.113
24
- 20 1920.000 1080.000 0.119
25
-
26
-
27
- "Parabolic_2_from_bottom_right"
28
- "Primary"
29
- 19
30
- 0 1920.000 0.000 0.000
31
- 1 1824.000 205.200 0.006
32
- 2 1728.000 388.800 0.012
33
- 3 1632.000 550.800 0.018
34
- 4 1536.000 691.200 0.024
35
- 5 1440.000 810.000 0.030
36
- 6 1344.000 907.200 0.036
37
- 7 1248.000 982.800 0.042
38
- 8 1152.000 1036.800 0.048
39
- 9 1056.000 1069.200 0.054
40
- 12 768.000 1036.800 0.071
41
- 13 672.000 982.800 0.077
42
- 14 576.000 907.200 0.083
43
- 15 480.000 810.000 0.089
44
- 16 384.000 691.200 0.095
45
- 17 288.000 550.800 0.101
46
- 18 192.000 388.800 0.107
47
- 19 96.000 205.200 0.113
48
- 20 0.000 0.000 0.119
49
-
50
-
51
- "SingleFrame"
52
- "Primary"
53
- 1
54
- 0 970.000 550.000 0.000
1
+
2
+
3
+ "Parabolic_1_from_top_left"
4
+ "Primary"
5
+ 19
6
+ 0 0.000 1080.000 0.000
7
+ 1 96.000 874.800 0.006
8
+ 2 192.000 691.200 0.012
9
+ 3 288.000 529.200 0.018
10
+ 4 384.000 388.800 0.024
11
+ 5 480.000 270.000 0.030
12
+ 6 576.000 172.800 0.036
13
+ 7 672.000 97.200 0.042
14
+ 8 768.000 43.200 0.048
15
+ 9 864.000 10.800 0.054
16
+ 12 1152.000 43.200 0.071
17
+ 13 1248.000 97.200 0.077
18
+ 14 1344.000 172.800 0.083
19
+ 15 1440.000 270.000 0.089
20
+ 16 1536.000 388.800 0.095
21
+ 17 1632.000 529.200 0.101
22
+ 18 1728.000 691.200 0.107
23
+ 19 1824.000 874.800 0.113
24
+ 20 1920.000 1080.000 0.119
25
+
26
+
27
+ "Parabolic_2_from_bottom_right"
28
+ "Primary"
29
+ 19
30
+ 0 1920.000 0.000 0.000
31
+ 1 1824.000 205.200 0.006
32
+ 2 1728.000 388.800 0.012
33
+ 3 1632.000 550.800 0.018
34
+ 4 1536.000 691.200 0.024
35
+ 5 1440.000 810.000 0.030
36
+ 6 1344.000 907.200 0.036
37
+ 7 1248.000 982.800 0.042
38
+ 8 1152.000 1036.800 0.048
39
+ 9 1056.000 1069.200 0.054
40
+ 12 768.000 1036.800 0.071
41
+ 13 672.000 982.800 0.077
42
+ 14 576.000 907.200 0.083
43
+ 15 480.000 810.000 0.089
44
+ 16 384.000 691.200 0.095
45
+ 17 288.000 550.800 0.101
46
+ 18 192.000 388.800 0.107
47
+ 19 96.000 205.200 0.113
48
+ 20 0.000 0.000 0.119
49
+
50
+
51
+ "SingleFrame"
52
+ "Primary"
53
+ 1
54
+ 0 970.000 550.000 0.000
@@ -10,10 +10,7 @@ class SyntheyesImportTest < Test::Unit::TestCase
10
10
 
11
11
  def test_parsing_from_importable
12
12
  fixture = File.open(File.dirname(__FILE__) + '/samples/syntheyes_2d_paths/shake_tracker_nodes_to_syntheyes.txt')
13
-
14
- parser = Tracksperanto::Import::Syntheyes.new
15
- parser.width = 2560
16
- parser.height = 1080
13
+ parser = Tracksperanto::Import::Syntheyes.new(:width => 2560, :height => 1080)
17
14
 
18
15
  trackers = parser.parse(fixture)
19
16
  assert_equal 50, trackers.length
@@ -30,9 +27,7 @@ class SyntheyesImportTest < Test::Unit::TestCase
30
27
 
31
28
  def test_parsing_cola_plate
32
29
  fixture = File.open(File.dirname(__FILE__) + '/samples/syntheyes_2d_paths/cola_plate.txt')
33
- parser = Tracksperanto::Import::Syntheyes.new
34
- parser.width = 1920
35
- parser.height = 1080
30
+ parser = Tracksperanto::Import::Syntheyes.new(:width => 1920, :height => 1080)
36
31
 
37
32
  trackers = parser.parse(fixture)
38
33
  assert_equal 6, trackers.length
@@ -40,12 +35,16 @@ class SyntheyesImportTest < Test::Unit::TestCase
40
35
 
41
36
  def test_parsing_with_one_tracker
42
37
  fixture = File.open(File.dirname(__FILE__) + '/samples/syntheyes_2d_paths/one_tracker.txt')
43
- parser = Tracksperanto::Import::Syntheyes.new
44
- parser.width = 1920
45
- parser.height = 1080
38
+ parser = Tracksperanto::Import::Syntheyes.new(:width => 1920, :height => 1080)
46
39
  trackers = parser.parse(fixture)
47
40
  assert_equal 1, trackers.length
48
41
  assert_equal 49, trackers[0].length
49
42
  end
50
43
 
44
+ def test_parsing_from_sy_2010
45
+ fixture = File.open(File.dirname(__FILE__) + '/samples/syntheyes_2d_paths/morePoints_sy2010.txt')
46
+ parser = Tracksperanto::Import::Syntheyes.new(:width => 1920, :height => 1080)
47
+ trackers = parser.parse(fixture)
48
+ assert_equal 26, trackers.length
49
+ end
51
50
  end
@@ -1,18 +1,14 @@
1
1
  require File.dirname(__FILE__) + '/../helper'
2
2
 
3
- class ShiftMiddlewareTest < Test::Unit::TestCase
3
+ class FlipMiddlewareTest < Test::Unit::TestCase
4
4
  def test_shift_supports_hash_init
5
5
  receiver = flexmock
6
6
 
7
7
  m = Tracksperanto::Middleware::Flip.new(receiver)
8
- assert !m.flip
9
- assert !m.flop
8
+ assert !m.enabled
10
9
 
11
- m = Tracksperanto::Middleware::Flip.new(receiver, :flip => true)
12
- assert m.flip
13
-
14
- m = Tracksperanto::Middleware::Flip.new(receiver, :flop => true)
15
- assert m.flop
10
+ m = Tracksperanto::Middleware::Flip.new(receiver, :enabled => true)
11
+ assert m.enabled
16
12
  end
17
13
 
18
14
  def test_export_flip_and_flop
@@ -21,10 +17,10 @@ class ShiftMiddlewareTest < Test::Unit::TestCase
21
17
  receiver.should_receive(:export_point).once.with(1, 100, 95, 0)
22
18
  receiver.should_receive(:export_point).once.with(1, 10, 95, 0)
23
19
 
24
- m = Tracksperanto::Middleware::Flip.new(receiver, :flip => true)
20
+ m = Tracksperanto::Middleware::Flip.new(receiver, :enabled => true)
25
21
  m.start_export(110, 120)
26
22
  m.export_point(1, 10, 95, 0)
27
- m.flip = false
23
+ m.enabled = false
28
24
  m.export_point(1, 10, 95, 0)
29
25
  end
30
26
  end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../helper'
2
+
3
+ class FlopMiddlewareTest < Test::Unit::TestCase
4
+ def test_shift_supports_hash_init
5
+ receiver = flexmock
6
+
7
+ m = Tracksperanto::Middleware::Flop.new(receiver)
8
+ assert !m.enabled
9
+
10
+ m = Tracksperanto::Middleware::Flop.new(receiver, :enabled => true)
11
+ assert m.enabled
12
+ end
13
+
14
+ def test_export_flip_and_flop
15
+ receiver = flexmock(:exporter)
16
+ receiver.should_receive(:start_export).once.with(110, 120)
17
+ receiver.should_receive(:export_point).once.with(1, 10, 25, 0)
18
+
19
+ m = Tracksperanto::Middleware::Flop.new(receiver, :enabled => true)
20
+ m.start_export(110, 120)
21
+ m.export_point(1, 10, 95, 0)
22
+ end
23
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracksperanto
3
3
  version: !ruby/object:Gem::Version
4
- hash: 33
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
- - 1
8
- - 9
9
- - 9
10
- version: 1.9.9
7
+ - 2
8
+ - 0
9
+ - 0
10
+ version: 2.0.0
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: 2010-11-29 00:00:00 +01:00
18
+ date: 2011-01-27 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -232,6 +232,7 @@ files:
232
232
  - test/test_simple_export.rb
233
233
  - test/test_tracker.rb
234
234
  - test/test_tracksperanto.rb
235
+ - test/middleware/test_flop_middleware.rb
235
236
  - test/middleware/test_lens_distort_middleware.rb
236
237
  has_rdoc: true
237
238
  homepage: http://guerilla-di.org/tracksperanto
@@ -295,6 +296,7 @@ test_files:
295
296
  - test/import/test_shake_text_import.rb
296
297
  - test/import/test_syntheyes_import.rb
297
298
  - test/middleware/test_flip_middleware.rb
299
+ - test/middleware/test_flop_middleware.rb
298
300
  - test/middleware/test_golden_middleware.rb
299
301
  - test/middleware/test_length_cutoff_middleware.rb
300
302
  - test/middleware/test_lens_distort_middleware.rb