tracksperanto 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/History.txt +11 -0
- data/Manifest.txt +64 -20
- data/README.txt +82 -30
- data/Rakefile +1 -0
- data/bin/tracksperanto +21 -14
- data/lib/export/base.rb +16 -6
- data/lib/export/match_mover.rb +40 -0
- data/lib/export/nuke_script.rb +78 -0
- data/lib/export/pftrack.rb +14 -14
- data/lib/export/shake_text.rb +7 -8
- data/lib/export/syntheyes.rb +9 -5
- data/lib/import/base.rb +45 -12
- data/lib/import/flame_stabilizer.rb +17 -32
- data/lib/import/match_mover.rb +65 -0
- data/lib/import/nuke_script.rb +96 -0
- data/lib/import/pftrack.rb +9 -2
- data/lib/import/shake_grammar/catcher.rb +56 -0
- data/lib/import/shake_grammar/lexer.rb +95 -0
- data/lib/import/shake_script.rb +189 -103
- data/lib/import/shake_text.rb +5 -3
- data/lib/import/syntheyes.rb +9 -2
- data/lib/middleware/base.rb +6 -1
- data/lib/middleware/golden.rb +7 -0
- data/lib/middleware/reformat.rb +10 -3
- data/lib/middleware/scaler.rb +14 -4
- data/lib/middleware/shift.rb +10 -0
- data/lib/middleware/slipper.rb +3 -0
- data/lib/pipeline/base.rb +111 -37
- data/lib/tracksperanto/block_init.rb +7 -0
- data/lib/tracksperanto/casts.rb +31 -0
- data/lib/tracksperanto/format_detector.rb +35 -0
- data/lib/tracksperanto/keyframe.rb +31 -0
- data/lib/tracksperanto/safety.rb +20 -0
- data/lib/tracksperanto/tracker.rb +38 -0
- data/lib/tracksperanto/zip_tuples.rb +20 -0
- data/lib/tracksperanto.rb +13 -100
- data/test/.DS_Store +0 -0
- data/test/export/.DS_Store +0 -0
- data/test/export/README_EXPORT_TESTS.txt +15 -0
- data/test/export/samples/ref_NukeScript.nk +25 -0
- data/test/export/samples/ref_NukeScript.nk.autosave +77 -0
- data/test/export/samples/ref_PFTrack.2dt +50 -0
- data/test/export/samples/ref_ShakeText.txt +48 -0
- data/test/export/samples/ref_Syntheyes.txt +42 -0
- data/test/export/samples/ref_matchmover.rz2 +52 -0
- data/test/export/test_match_mover_export.rb +16 -0
- data/test/export/test_mux.rb +23 -0
- data/test/export/test_nuke_export.rb +22 -0
- data/test/export/test_pftrack_export.rb +19 -0
- data/test/export/test_shake_export.rb +15 -0
- data/test/export/test_syntheyes_export.rb +15 -0
- data/test/helper.rb +85 -2
- data/test/import/.DS_Store +0 -0
- data/test/{samples → import/samples}/.DS_Store +0 -0
- data/test/{samples → import/samples}/flyover2DP_syntheyes.txt +0 -0
- data/test/import/samples/four_tracks_in_one_matchmove.shk +323 -0
- data/test/import/samples/four_tracks_in_one_stabilizer.shk +321 -0
- data/test/{samples → import/samples}/fromCombustion_fromMidClip_wSnap.stabilizer +0 -0
- data/test/{samples → import/samples}/hugeFlameSetup.stabilizer +0 -0
- data/test/import/samples/kipPointsMatchmover.rz2 +523 -0
- data/test/{samples → import/samples}/megaTrack.action.3dtrack.stabilizer +0 -0
- data/test/{samples → import/samples}/one_shake_tracker.txt +0 -0
- data/test/{samples → import/samples}/one_shake_tracker_from_first.txt +0 -0
- data/test/import/samples/one_tracker_with_break.nk +71 -0
- data/test/import/samples/one_tracker_with_break_in_grp.nk +91 -0
- data/test/{samples → import/samples}/shake_tracker_nodes.shk +0 -0
- data/test/{samples → import/samples}/shake_tracker_nodes_to_syntheyes.txt +0 -0
- data/test/{samples → import/samples}/sourcefile_pftrack.2dt +0 -0
- data/test/{samples → import/samples}/three_tracks_in_one_stabilizer.shk +0 -0
- data/test/{samples → import/samples}/two_shake_trackers.txt +0 -0
- data/test/{samples → import/samples}/two_tracks_in_one_tracker.shk +0 -0
- data/test/{test_flame_import.rb → import/test_flame_import.rb} +15 -9
- data/test/import/test_match_mover_import.rb +44 -0
- data/test/import/test_nuke_import.rb +63 -0
- data/test/{test_pftrack_import.rb → import/test_pftrack_import.rb} +10 -4
- data/test/import/test_shake_catcher.rb +72 -0
- data/test/import/test_shake_lexer.rb +95 -0
- data/test/import/test_shake_script_import.rb +75 -0
- data/test/{test_shake_text_import.rb → import/test_shake_text_import.rb} +10 -3
- data/test/{test_syntheyes_import.rb → import/test_syntheyes_import.rb} +8 -3
- data/test/middleware/test_golden_middleware.rb +32 -0
- data/test/middleware/test_reformat_middleware.rb +35 -0
- data/test/middleware/test_scaler_middleware.rb +51 -0
- data/test/middleware/test_shift_middleware.rb +26 -0
- data/test/middleware/test_slip_middleware.rb +31 -0
- data/test/pipeline/test_pipeline_base.rb +14 -0
- data/test/test_format_detector.rb +39 -0
- data/test/test_tracker.rb +48 -0
- data/tracksperanto.gemspec +9 -7
- metadata +101 -30
- data/lib/middleware/close.rb +0 -6
- data/test/test_shake_export.rb +0 -58
- data/test/test_shake_script_import.rb +0 -50
@@ -0,0 +1,31 @@
|
|
1
|
+
# Helps to define things that will forcibly become floats, integers or strings
|
2
|
+
module Tracksperanto::Casts
|
3
|
+
def self.included(into)
|
4
|
+
into.extend(self)
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
# Same as attr_accessor but will always convert to Float internally
|
9
|
+
def cast_to_float(*attributes)
|
10
|
+
attributes.each do | an_attr |
|
11
|
+
define_method(an_attr) { instance_variable_get("@#{an_attr}").to_f }
|
12
|
+
define_method("#{an_attr}=") { |to| instance_variable_set("@#{an_attr}", to.to_f) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Same as attr_accessor but will always convert to Integer/Bignum internally
|
17
|
+
def cast_to_int(*attributes)
|
18
|
+
attributes.each do | an_attr |
|
19
|
+
define_method(an_attr) { instance_variable_get("@#{an_attr}").to_i }
|
20
|
+
define_method("#{an_attr}=") { |to| instance_variable_set("@#{an_attr}", to.to_i) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Same as attr_accessor but will always convert to String internally
|
25
|
+
def cast_to_string(*attributes)
|
26
|
+
attributes.each do | an_attr |
|
27
|
+
define_method(an_attr) { instance_variable_get("@#{an_attr}").to_s }
|
28
|
+
define_method("#{an_attr}=") { |to| instance_variable_set("@#{an_attr}", to.to_s) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Finds a suitable importer for the chosen file path. Or at least tries to, based on the file extension.
|
2
|
+
# Will then examine all the importers and ask them if they can handle the specified file
|
3
|
+
class Tracksperanto::FormatDetector
|
4
|
+
def initialize(with_path)
|
5
|
+
perform_detection(with_path)
|
6
|
+
freeze
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
def perform_detection(for_path)
|
11
|
+
ext = File.extname(for_path.downcase)
|
12
|
+
@importer_klass = Tracksperanto.importers.find{ |i| i.distinct_file_ext == ext }
|
13
|
+
end
|
14
|
+
public
|
15
|
+
|
16
|
+
# Tells if an importer has been found for this extension
|
17
|
+
def match?
|
18
|
+
!!@importer_klass
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the importer if there is one
|
22
|
+
def importer_klass
|
23
|
+
@importer_klass
|
24
|
+
end
|
25
|
+
|
26
|
+
# Tells if comp size needs to be provided
|
27
|
+
def auto_size?
|
28
|
+
match? ? importer_klass.autodetects_size? : false
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the human name of the importer
|
32
|
+
def human_importer_name
|
33
|
+
match? ? importer_klass.human_name : "Unknown format"
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Internal representation of a keyframe, that carries info on the frame location in the clip, x y and residual
|
2
|
+
# Frame numbers start from zero (frame 0 is first frame of the clip).
|
3
|
+
# Tracksperanto uses Shake coordinates as base. Image is Y-positive, X-positive, absolute
|
4
|
+
# pixel values up and right (zero is in the lower left corner). Some apps use a different
|
5
|
+
# coordinate system so translation will take place on import or on export, respectively.
|
6
|
+
# We also use residual and not correlation (residual is how far the tracker strolls away,
|
7
|
+
# correlation is how sure the tracker is about what it's doing). Residual is the inverse of
|
8
|
+
# correlation (with total correlation of one the residual excursion becomes zero).
|
9
|
+
class Tracksperanto::Keyframe
|
10
|
+
include Tracksperanto::Casts
|
11
|
+
include Tracksperanto::BlockInit
|
12
|
+
|
13
|
+
# Absolute integer frame where this keyframe is placed, 0 based
|
14
|
+
attr_accessor :frame
|
15
|
+
|
16
|
+
# Absolute float X value of the point, zero is lower left
|
17
|
+
attr_accessor :abs_x
|
18
|
+
|
19
|
+
# Absolute float Y value of the point, zero is lower left
|
20
|
+
attr_accessor :abs_y
|
21
|
+
|
22
|
+
# Absolute float residual (0 is "spot on")
|
23
|
+
attr_accessor :residual
|
24
|
+
|
25
|
+
cast_to_float :abs_x, :abs_y, :residual
|
26
|
+
cast_to_int :frame
|
27
|
+
|
28
|
+
def inspect
|
29
|
+
[frame, abs_x, abs_y].inspect
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Implements the +safe_reader+ class method which will define (or override) readers that
|
2
|
+
# raise if ivar is nil
|
3
|
+
module Tracksperanto::Safety
|
4
|
+
def self.included(into)
|
5
|
+
into.extend(self)
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
# Inject a reader that checks for nil
|
10
|
+
def safe_reader(*attributes)
|
11
|
+
attributes.each do | an_attr |
|
12
|
+
alias_method "#{an_attr}_without_nil_protection", an_attr
|
13
|
+
define_method(an_attr) do
|
14
|
+
val = send("#{an_attr}_without_nil_protection")
|
15
|
+
raise "Expected #{an_attr} on #{self} not to be nil" if val.nil?
|
16
|
+
val
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Internal representation of a tracker point with keyframes. A Tracker is an array of Keyframe objects and should act and work like one
|
2
|
+
class Tracksperanto::Tracker < DelegateClass(Array)
|
3
|
+
include Tracksperanto::Casts
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
# Contains the name of the tracker
|
7
|
+
attr_accessor :name
|
8
|
+
cast_to_string :name
|
9
|
+
|
10
|
+
def initialize(object_attribute_hash = {})
|
11
|
+
@name = "Tracker"
|
12
|
+
__setobj__(Array.new)
|
13
|
+
object_attribute_hash.map { |(k, v)| send("#{k}=", v) }
|
14
|
+
yield(self) if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def keyframes=(new_kf_array)
|
18
|
+
__setobj__(new_kf_array.dup)
|
19
|
+
end
|
20
|
+
|
21
|
+
def keyframes
|
22
|
+
__getobj__
|
23
|
+
end
|
24
|
+
|
25
|
+
# Trackers sort by the position of the first keyframe
|
26
|
+
def <=>(other_tracker)
|
27
|
+
self[0].frame <=> other_tracker[0].frame
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create and save a keyframe in this tracker
|
31
|
+
def keyframe!(options)
|
32
|
+
push(Tracksperanto::Keyframe.new(options))
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
"<T #{name.inspect} with #{length} keyframes>"
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Implements the zip_curve_tuples method
|
2
|
+
module Tracksperanto::ZipTuples
|
3
|
+
# Zip arrays of "value at" tuples into an array of "values at" tuples.
|
4
|
+
# The first value of each tuple will be the frame number
|
5
|
+
# and keyframes which are not present in all arrays will be discarded. For example:
|
6
|
+
#
|
7
|
+
# zip_curve_tuples( [[0, 12], [1, 23]], [[1, 12]]) #=> [[1, 23, 12]]
|
8
|
+
#
|
9
|
+
def zip_curve_tuples(*curves)
|
10
|
+
tuples = []
|
11
|
+
curves.each do | curve |
|
12
|
+
curve.each do | keyframe |
|
13
|
+
frame, value = keyframe
|
14
|
+
tuples[frame] ? tuples[frame].push(value) : (tuples[frame] = [frame, value])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
tuples.compact.reject{|e| e.length < (curves.length + 1) }
|
19
|
+
end
|
20
|
+
end
|
data/lib/tracksperanto.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'delegate'
|
3
|
+
|
4
|
+
|
1
5
|
module Tracksperanto
|
2
|
-
|
6
|
+
PATH = File.expand_path(File.dirname(__FILE__))
|
7
|
+
VERSION = '1.2.0'
|
3
8
|
|
4
9
|
module Import; end
|
5
10
|
module Export; end
|
@@ -15,110 +20,18 @@ module Tracksperanto
|
|
15
20
|
|
16
21
|
# Returns the array of all available middlewares
|
17
22
|
attr_accessor :middlewares
|
18
|
-
end
|
19
|
-
self.exporters, self.importers, self.middlewares = [], [], []
|
20
|
-
|
21
|
-
# Helps to define things that will forcibly become floats, integers or strings
|
22
|
-
module Casts
|
23
|
-
def self.included(into)
|
24
|
-
into.extend(self)
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
28
|
-
# Same as attr_accessor but will always convert to Float internally
|
29
|
-
def cast_to_float(*attributes)
|
30
|
-
attributes.each do | an_attr |
|
31
|
-
define_method(an_attr) { instance_variable_get("@#{an_attr}").to_f }
|
32
|
-
define_method("#{an_attr}=") { |to| instance_variable_set("@#{an_attr}", to.to_f) }
|
33
|
-
end
|
34
|
-
end
|
35
23
|
|
36
|
-
#
|
37
|
-
def
|
38
|
-
|
39
|
-
define_method(an_attr) { instance_variable_get("@#{an_attr}").to_i }
|
40
|
-
define_method("#{an_attr}=") { |to| instance_variable_set("@#{an_attr}", to.to_i) }
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Same as attr_accessor but will always convert to String internally
|
45
|
-
def cast_to_string(*attributes)
|
46
|
-
attributes.each do | an_attr |
|
47
|
-
define_method(an_attr) { instance_variable_get("@#{an_attr}").to_s }
|
48
|
-
define_method("#{an_attr}=") { |to| instance_variable_set("@#{an_attr}", to.to_s) }
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
module Safety
|
54
|
-
def self.included(into)
|
55
|
-
into.extend(self)
|
56
|
-
super
|
57
|
-
end
|
58
|
-
|
59
|
-
# Inject a reader that checks for nil
|
60
|
-
def safe_reader(*attributes)
|
61
|
-
attributes.each do | an_attr |
|
62
|
-
alias_method "#{an_attr}_without_nil_protection", an_attr
|
63
|
-
define_method(an_attr) do
|
64
|
-
val = send("#{an_attr}_without_nil_protection")
|
65
|
-
raise "Expected #{an_attr} on #{self} not to be nil" if val.nil?
|
66
|
-
val
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
module BlockInit
|
73
|
-
def initialize(evt_hash = {})
|
74
|
-
evt_hash.map { |(k, v)| send("#{k}=", v) }
|
75
|
-
yield(self) if block_given?
|
24
|
+
# Returns the names of all the importers
|
25
|
+
def importer_names
|
26
|
+
importers.map{|e| e.to_s.split('::').pop }
|
76
27
|
end
|
77
28
|
end
|
29
|
+
self.exporters, self.importers, self.middlewares = [], [], []
|
78
30
|
|
79
|
-
|
80
|
-
class Tracker
|
81
|
-
include Casts
|
82
|
-
include BlockInit
|
31
|
+
end
|
83
32
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
# Contains the array of all Keyframe objects for this tracker
|
88
|
-
attr_accessor :keyframes
|
89
|
-
|
90
|
-
cast_to_string :name
|
91
|
-
|
92
|
-
def initialize(h = {})
|
93
|
-
@name, @keyframes = 'Tracker', []
|
94
|
-
super
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# Internal representation of a keyframe
|
99
|
-
class Keyframe
|
100
|
-
include Casts
|
101
|
-
include BlockInit
|
102
|
-
|
103
|
-
# Absolute integer frame where this keyframe is placed, 0 based
|
104
|
-
attr_accessor :frame
|
105
|
-
|
106
|
-
# Absolute float X value of the point, zero is lower left
|
107
|
-
attr_accessor :abs_x
|
108
|
-
|
109
|
-
# Absolute float Y value of the point, zero is lower left
|
110
|
-
attr_accessor :abs_y
|
111
|
-
|
112
|
-
# Absolute float residual (0 is "spot on")
|
113
|
-
attr_accessor :residual
|
114
|
-
|
115
|
-
cast_to_float :abs_x, :abs_y, :residual
|
116
|
-
cast_to_int :frame
|
117
|
-
|
118
|
-
def inspect
|
119
|
-
[frame, abs_x, abs_y].inspect
|
120
|
-
end
|
121
|
-
end
|
33
|
+
%w( casts block_init safety zip_tuples keyframe tracker format_detector).each do | submodule |
|
34
|
+
require File.join(Tracksperanto::PATH, "tracksperanto", submodule)
|
122
35
|
end
|
123
36
|
|
124
37
|
# Load importers
|
data/test/.DS_Store
CHANGED
Binary file
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Export tests are conformance tests. That means that:
|
2
|
+
|
3
|
+
1) An export is made using Tracksperanto
|
4
|
+
2) This export gets checked by importing it into the main app
|
5
|
+
that accepts such files
|
6
|
+
3) The export is compared with Tracksperanto output in the test
|
7
|
+
|
8
|
+
This means that unless you own an app that accepts this particular format
|
9
|
+
you cannot overwrite the export with your own since you got no way to verify
|
10
|
+
that the export works
|
11
|
+
|
12
|
+
The current test set consists of the two parabolic curves that cross. The second
|
13
|
+
parabolic curve goes left, the first one - right, and they start at opposite
|
14
|
+
corners of the reference 1920x1080 export. At the first point the track has the residual of 0,
|
15
|
+
at the end of the curve - the biggest residual (PFTrack marks it red exactly at the last keyframe)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
version 5.1200
|
3
|
+
Constant {
|
4
|
+
inputs 0
|
5
|
+
channels rgb
|
6
|
+
format "1920 1080 0 0 1920 1080 1"
|
7
|
+
name CompSize_1920x1080
|
8
|
+
postage_stamp false
|
9
|
+
xpos 0
|
10
|
+
ypos -60
|
11
|
+
}
|
12
|
+
|
13
|
+
Tracker3 {
|
14
|
+
track1 {{curve i x1 0.0000 96.0000 192.0000 288.0000 384.0000 480.0000 576.0000 672.0000 768.0000 864.0000 960.0000 1056.0000 1152.0000 1248.0000 1344.0000 1440.0000 1536.0000 1632.0000 1728.0000 1824.0000 1920.0000} {curve i x1 1080.0000 874.8000 691.2000 529.2000 388.8000 270.0000 172.8000 97.2000 43.2000 10.8000 0.0000 10.8000 43.2000 97.2000 172.8000 270.0000 388.8000 529.2000 691.2000 874.8000 1080.0000}}
|
15
|
+
name Parabolic_1_from_top_left
|
16
|
+
xpos 0
|
17
|
+
ypos 30
|
18
|
+
}
|
19
|
+
|
20
|
+
Tracker3 {
|
21
|
+
track1 {{curve i x1 1920.0000 1824.0000 1728.0000 1632.0000 1536.0000 1440.0000 1344.0000 1248.0000 1152.0000 1056.0000 960.0000 864.0000 768.0000 672.0000 576.0000 480.0000 384.0000 288.0000 192.0000 96.0000 0.0000} {curve i x1 0.0000 205.2000 388.8000 550.8000 691.2000 810.0000 907.2000 982.8000 1036.8000 1069.2000 1080.0000 1069.2000 1036.8000 982.8000 907.2000 810.0000 691.2000 550.8000 388.8000 205.2000 0.0000}}
|
22
|
+
name Parabolic_2_from_bottom_right
|
23
|
+
xpos 0
|
24
|
+
ypos 60
|
25
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#! /Applications/Nuke5.1v2/Nuke5.1v2.app/Contents/MacOS/Nuke5.1v2 -nx
|
2
|
+
version 5.1200
|
3
|
+
define_window_layout_xml {<?xml version="1.0" encoding="UTF-8"?>
|
4
|
+
<layout version="1.0">
|
5
|
+
<window x="0" y="22" w="1680" h="1024" screen="0">
|
6
|
+
<splitter orientation="1">
|
7
|
+
<split size="1062"></split>
|
8
|
+
<splitter orientation="1">
|
9
|
+
<split size="40"></split>
|
10
|
+
<dock id="" hideTitles="1" activePageId="Toolbar.1">
|
11
|
+
<page id="Toolbar.1"></page>
|
12
|
+
</dock>
|
13
|
+
<split size="1018"></split>
|
14
|
+
<splitter orientation="2">
|
15
|
+
<split size="499"></split>
|
16
|
+
<dock id="" activePageId="Viewer.1">
|
17
|
+
<page id="Viewer.1"></page>
|
18
|
+
</dock>
|
19
|
+
<split size="499"></split>
|
20
|
+
<dock id="" activePageId="Curve Editor.1">
|
21
|
+
<page id="DAG.1"></page>
|
22
|
+
<page id="Curve Editor.1"></page>
|
23
|
+
</dock>
|
24
|
+
</splitter>
|
25
|
+
</splitter>
|
26
|
+
<split size="614"></split>
|
27
|
+
<dock id="" activePageId="Properties.1">
|
28
|
+
<page id="Properties.1"></page>
|
29
|
+
</dock>
|
30
|
+
</splitter>
|
31
|
+
</window>
|
32
|
+
</layout>
|
33
|
+
}
|
34
|
+
Root {
|
35
|
+
inputs 0
|
36
|
+
name /Code/apps/tracksperanto/test/export/samples/ref_NukeScript.nk
|
37
|
+
frame 11
|
38
|
+
format "640 480 0 0 640 480 1 PC_Video"
|
39
|
+
proxy_format "640 480 0 0 640 480 1 PC_Video"
|
40
|
+
}
|
41
|
+
Constant {
|
42
|
+
inputs 0
|
43
|
+
channels rgb
|
44
|
+
format "1920 1080 0 0 1920 1080 1 HD"
|
45
|
+
name CompSize_1920x1080
|
46
|
+
xpos 0
|
47
|
+
ypos -60
|
48
|
+
postage_stamp false
|
49
|
+
}
|
50
|
+
Tracker3 {
|
51
|
+
track1 {{curve x1 0 96 192 288 384 480 576 672 768 864 960 1056 1152 1248 1344 1440 1536 1632 1728 1824 1920} {curve x1 1080 874.8 691.2 529.2 388.8 270 172.8 97.2 43.2 10.8 0 10.8 43.2 97.2 172.8 270 388.8 529.2 691.2 874.8 1080}}
|
52
|
+
translate {{curve x1 0 96 192 288 384 480 576 672 768 864 960 1056 1152 1248 1344 1440 1536 1632 1728 1824 1920} {curve x1 0 -205.2000122 -388.7999878 -550.7999878 -691.2000122 -810 -907.2000122 -982.7999878 -1036.800049 -1069.199951 -1080 -1069.199951 -1036.800049 -982.7999878 -907.2000122 -810 -691.2000122 -550.7999878 -388.7999878 -205.2000122 0}}
|
53
|
+
center {{curve x1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0} {curve x1 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080 1080}}
|
54
|
+
name Parabolic_1_from_top_left
|
55
|
+
xpos 0
|
56
|
+
ypos 30
|
57
|
+
}
|
58
|
+
Tracker3 {
|
59
|
+
track1 {{curve i x1 1920 1824 1728 1632 1536 1440 1344 1248 1152 1056 960 864 768 672 576 480 384 288 192 96 0} {curve i x1 0 205.2 388.8 550.8 691.2 810 907.2 982.8 1036.8 1069.2 1080 1069.2 1036.8 982.8 907.2 810 691.2 550.8 388.8 205.2 0}}
|
60
|
+
center {320 240}
|
61
|
+
name Parabolic_2_from_bottom_right
|
62
|
+
xpos 0
|
63
|
+
ypos 60
|
64
|
+
}
|
65
|
+
Viewer {
|
66
|
+
frame 11
|
67
|
+
name Viewer1
|
68
|
+
xpos 0
|
69
|
+
ypos 87
|
70
|
+
}
|
71
|
+
Viewer {
|
72
|
+
inputs 0
|
73
|
+
name Viewer2
|
74
|
+
selected true
|
75
|
+
xpos 22
|
76
|
+
ypos 67
|
77
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
"Parabolic_1_from_top_left"
|
4
|
+
21
|
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
|
+
10 960.000 0.000 0.060
|
16
|
+
11 1056.000 10.800 0.065
|
17
|
+
12 1152.000 43.200 0.071
|
18
|
+
13 1248.000 97.200 0.077
|
19
|
+
14 1344.000 172.800 0.083
|
20
|
+
15 1440.000 270.000 0.089
|
21
|
+
16 1536.000 388.800 0.095
|
22
|
+
17 1632.000 529.200 0.101
|
23
|
+
18 1728.000 691.200 0.107
|
24
|
+
19 1824.000 874.800 0.113
|
25
|
+
20 1920.000 1080.000 0.119
|
26
|
+
|
27
|
+
|
28
|
+
"Parabolic_2_from_bottom_right"
|
29
|
+
21
|
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
|
+
10 960.000 1080.000 0.060
|
41
|
+
11 864.000 1069.200 0.065
|
42
|
+
12 768.000 1036.800 0.071
|
43
|
+
13 672.000 982.800 0.077
|
44
|
+
14 576.000 907.200 0.083
|
45
|
+
15 480.000 810.000 0.089
|
46
|
+
16 384.000 691.200 0.095
|
47
|
+
17 288.000 550.800 0.101
|
48
|
+
18 192.000 388.800 0.107
|
49
|
+
19 96.000 205.200 0.113
|
50
|
+
20 0.000 0.000 0.119
|
@@ -0,0 +1,48 @@
|
|
1
|
+
TrackName Parabolic_1_from_top_left
|
2
|
+
Frame X Y Correlation
|
3
|
+
1.00 0.000 1080.000 1.000
|
4
|
+
2.00 96.000 874.800 0.952
|
5
|
+
3.00 192.000 691.200 0.905
|
6
|
+
4.00 288.000 529.200 0.857
|
7
|
+
5.00 384.000 388.800 0.810
|
8
|
+
6.00 480.000 270.000 0.762
|
9
|
+
7.00 576.000 172.800 0.714
|
10
|
+
8.00 672.000 97.200 0.667
|
11
|
+
9.00 768.000 43.200 0.619
|
12
|
+
10.00 864.000 10.800 0.571
|
13
|
+
11.00 960.000 0.000 0.524
|
14
|
+
12.00 1056.000 10.800 0.476
|
15
|
+
13.00 1152.000 43.200 0.429
|
16
|
+
14.00 1248.000 97.200 0.381
|
17
|
+
15.00 1344.000 172.800 0.333
|
18
|
+
16.00 1440.000 270.000 0.286
|
19
|
+
17.00 1536.000 388.800 0.238
|
20
|
+
18.00 1632.000 529.200 0.190
|
21
|
+
19.00 1728.000 691.200 0.143
|
22
|
+
20.00 1824.000 874.800 0.095
|
23
|
+
21.00 1920.000 1080.000 0.048
|
24
|
+
|
25
|
+
TrackName Parabolic_2_from_bottom_right
|
26
|
+
Frame X Y Correlation
|
27
|
+
1.00 1920.000 0.000 1.000
|
28
|
+
2.00 1824.000 205.200 0.952
|
29
|
+
3.00 1728.000 388.800 0.905
|
30
|
+
4.00 1632.000 550.800 0.857
|
31
|
+
5.00 1536.000 691.200 0.810
|
32
|
+
6.00 1440.000 810.000 0.762
|
33
|
+
7.00 1344.000 907.200 0.714
|
34
|
+
8.00 1248.000 982.800 0.667
|
35
|
+
9.00 1152.000 1036.800 0.619
|
36
|
+
10.00 1056.000 1069.200 0.571
|
37
|
+
11.00 960.000 1080.000 0.524
|
38
|
+
12.00 864.000 1069.200 0.476
|
39
|
+
13.00 768.000 1036.800 0.429
|
40
|
+
14.00 672.000 982.800 0.381
|
41
|
+
15.00 576.000 907.200 0.333
|
42
|
+
16.00 480.000 810.000 0.286
|
43
|
+
17.00 384.000 691.200 0.238
|
44
|
+
18.00 288.000 550.800 0.190
|
45
|
+
19.00 192.000 388.800 0.143
|
46
|
+
20.00 96.000 205.200 0.095
|
47
|
+
21.00 0.000 0.000 0.048
|
48
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Parabolic_1_from_top_left 0 -1.000000 -1.000000 30
|
2
|
+
Parabolic_1_from_top_left 1 -0.900000 -0.620000 30
|
3
|
+
Parabolic_1_from_top_left 2 -0.800000 -0.280000 30
|
4
|
+
Parabolic_1_from_top_left 3 -0.700000 0.020000 30
|
5
|
+
Parabolic_1_from_top_left 4 -0.600000 0.280000 30
|
6
|
+
Parabolic_1_from_top_left 5 -0.500000 0.500000 30
|
7
|
+
Parabolic_1_from_top_left 6 -0.400000 0.680000 30
|
8
|
+
Parabolic_1_from_top_left 7 -0.300000 0.820000 30
|
9
|
+
Parabolic_1_from_top_left 8 -0.200000 0.920000 30
|
10
|
+
Parabolic_1_from_top_left 9 -0.100000 0.980000 30
|
11
|
+
Parabolic_1_from_top_left 10 0.000000 1.000000 30
|
12
|
+
Parabolic_1_from_top_left 11 0.100000 0.980000 30
|
13
|
+
Parabolic_1_from_top_left 12 0.200000 0.920000 30
|
14
|
+
Parabolic_1_from_top_left 13 0.300000 0.820000 30
|
15
|
+
Parabolic_1_from_top_left 14 0.400000 0.680000 30
|
16
|
+
Parabolic_1_from_top_left 15 0.500000 0.500000 30
|
17
|
+
Parabolic_1_from_top_left 16 0.600000 0.280000 30
|
18
|
+
Parabolic_1_from_top_left 17 0.700000 0.020000 30
|
19
|
+
Parabolic_1_from_top_left 18 0.800000 -0.280000 30
|
20
|
+
Parabolic_1_from_top_left 19 0.900000 -0.620000 30
|
21
|
+
Parabolic_1_from_top_left 20 1.000000 -1.000000 30
|
22
|
+
Parabolic_2_from_bottom_right 0 1.000000 1.000000 30
|
23
|
+
Parabolic_2_from_bottom_right 1 0.900000 0.620000 30
|
24
|
+
Parabolic_2_from_bottom_right 2 0.800000 0.280000 30
|
25
|
+
Parabolic_2_from_bottom_right 3 0.700000 -0.020000 30
|
26
|
+
Parabolic_2_from_bottom_right 4 0.600000 -0.280000 30
|
27
|
+
Parabolic_2_from_bottom_right 5 0.500000 -0.500000 30
|
28
|
+
Parabolic_2_from_bottom_right 6 0.400000 -0.680000 30
|
29
|
+
Parabolic_2_from_bottom_right 7 0.300000 -0.820000 30
|
30
|
+
Parabolic_2_from_bottom_right 8 0.200000 -0.920000 30
|
31
|
+
Parabolic_2_from_bottom_right 9 0.100000 -0.980000 30
|
32
|
+
Parabolic_2_from_bottom_right 10 0.000000 -1.000000 30
|
33
|
+
Parabolic_2_from_bottom_right 11 -0.100000 -0.980000 30
|
34
|
+
Parabolic_2_from_bottom_right 12 -0.200000 -0.920000 30
|
35
|
+
Parabolic_2_from_bottom_right 13 -0.300000 -0.820000 30
|
36
|
+
Parabolic_2_from_bottom_right 14 -0.400000 -0.680000 30
|
37
|
+
Parabolic_2_from_bottom_right 15 -0.500000 -0.500000 30
|
38
|
+
Parabolic_2_from_bottom_right 16 -0.600000 -0.280000 30
|
39
|
+
Parabolic_2_from_bottom_right 17 -0.700000 -0.020000 30
|
40
|
+
Parabolic_2_from_bottom_right 18 -0.800000 0.280000 30
|
41
|
+
Parabolic_2_from_bottom_right 19 -0.900000 0.620000 30
|
42
|
+
Parabolic_2_from_bottom_right 20 -1.000000 1.000000 30
|
@@ -0,0 +1,52 @@
|
|
1
|
+
imageSequence "Sequence 01"
|
2
|
+
{
|
3
|
+
1920 1080 f( "D:/temp/sequence.%04d.dpx" ) b( 1 211 1 )
|
4
|
+
}
|
5
|
+
pointTrack "Parabolic_1_from_top_left" rgb( 255 0 0 )
|
6
|
+
{
|
7
|
+
1 0.000 1080.000 ki( 0.8 ) s( 66 66 64 64 ) p( 24 24 25 25 )
|
8
|
+
2 96.000 874.800 p+( 0.952381 )
|
9
|
+
3 192.000 691.200 p+( 0.904762 )
|
10
|
+
4 288.000 529.200 p+( 0.857143 )
|
11
|
+
5 384.000 388.800 p+( 0.809524 )
|
12
|
+
6 480.000 270.000 p+( 0.761905 )
|
13
|
+
7 576.000 172.800 p+( 0.714286 )
|
14
|
+
8 672.000 97.200 p+( 0.666667 )
|
15
|
+
9 768.000 43.200 p+( 0.619048 )
|
16
|
+
10 864.000 10.800 p+( 0.571429 )
|
17
|
+
11 960.000 0.000 p+( 0.523810 )
|
18
|
+
12 1056.000 10.800 p+( 0.476190 )
|
19
|
+
13 1152.000 43.200 p+( 0.428571 )
|
20
|
+
14 1248.000 97.200 p+( 0.380952 )
|
21
|
+
15 1344.000 172.800 p+( 0.333333 )
|
22
|
+
16 1440.000 270.000 p+( 0.285714 )
|
23
|
+
17 1536.000 388.800 p+( 0.238095 )
|
24
|
+
18 1632.000 529.200 p+( 0.190476 )
|
25
|
+
19 1728.000 691.200 p+( 0.142857 )
|
26
|
+
20 1824.000 874.800 p+( 0.095238 )
|
27
|
+
21 1920.000 1080.000 p+( 0.047619 )
|
28
|
+
}
|
29
|
+
pointTrack "Parabolic_2_from_bottom_right" rgb( 255 0 0 )
|
30
|
+
{
|
31
|
+
1 1920.000 0.000 ki( 0.8 ) s( 66 66 64 64 ) p( 24 24 25 25 )
|
32
|
+
2 1824.000 205.200 p+( 0.952381 )
|
33
|
+
3 1728.000 388.800 p+( 0.904762 )
|
34
|
+
4 1632.000 550.800 p+( 0.857143 )
|
35
|
+
5 1536.000 691.200 p+( 0.809524 )
|
36
|
+
6 1440.000 810.000 p+( 0.761905 )
|
37
|
+
7 1344.000 907.200 p+( 0.714286 )
|
38
|
+
8 1248.000 982.800 p+( 0.666667 )
|
39
|
+
9 1152.000 1036.800 p+( 0.619048 )
|
40
|
+
10 1056.000 1069.200 p+( 0.571429 )
|
41
|
+
11 960.000 1080.000 p+( 0.523810 )
|
42
|
+
12 864.000 1069.200 p+( 0.476190 )
|
43
|
+
13 768.000 1036.800 p+( 0.428571 )
|
44
|
+
14 672.000 982.800 p+( 0.380952 )
|
45
|
+
15 576.000 907.200 p+( 0.333333 )
|
46
|
+
16 480.000 810.000 p+( 0.285714 )
|
47
|
+
17 384.000 691.200 p+( 0.238095 )
|
48
|
+
18 288.000 550.800 p+( 0.190476 )
|
49
|
+
19 192.000 388.800 p+( 0.142857 )
|
50
|
+
20 96.000 205.200 p+( 0.095238 )
|
51
|
+
21 0.000 0.000 p+( 0.047619 )
|
52
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
class MatchmoverExportTest < Test::Unit::TestCase
|
4
|
+
include ParabolicTracks
|
5
|
+
P = File.dirname(__FILE__) + "/samples/ref_matchmover.rz2"
|
6
|
+
|
7
|
+
def test_export_output_written
|
8
|
+
ensure_same_output Tracksperanto::Export::MatchMover, P
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_exporter_meta
|
12
|
+
assert_equal "matchmover.rz2", Tracksperanto::Export::MatchMover.desc_and_extension
|
13
|
+
assert_equal "Matchmover 2D export .rz2 file", Tracksperanto::Export::MatchMover.human_name
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
class MuxTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_mux_replays
|
6
|
+
outs = (0..25).map do
|
7
|
+
o = flexmock
|
8
|
+
o.should_receive(:start_export).once.with(720, 576)
|
9
|
+
o.should_receive(:start_tracker_segment).once.with("FooT")
|
10
|
+
o.should_receive(:export_point).once.with(0, 45.0, 67.0, 0.3)
|
11
|
+
o.should_receive(:end_tracker_segment).once
|
12
|
+
o.should_receive(:end_export).once
|
13
|
+
o
|
14
|
+
end
|
15
|
+
|
16
|
+
mux = Tracksperanto::Export::Mux.new(outs)
|
17
|
+
mux.start_export(720, 576)
|
18
|
+
mux.start_tracker_segment("FooT")
|
19
|
+
mux.export_point(0, 45.0, 67.0, 0.3)
|
20
|
+
mux.end_tracker_segment
|
21
|
+
mux.end_export
|
22
|
+
end
|
23
|
+
end
|