#!/usr/bin/env ruby # == Synopsis # # Translate a 2D track file from a single format to many others # # == Usage # # tracksperanto -f ShakeScript /Films/Blockbuster/Shots/001/script.shk -w 1920 -h 1080 # # == Author # Julik require File.dirname(__FILE__) + '/../lib/tracksperanto' require 'optparse' # Sane defaults reader_klass = nil width = nil height = nil reformat_w = nil reformat_h = nil scale_x = 1.0 scale_y = 1.0 slip = 0 golden_tracks = false x_shift = 0 y_shift = 0 set_prefix = '' sole_format = nil reader_name = "ShakeScript" readers = Tracksperanto.importer_names writers = Tracksperanto.exporter_names parser = OptionParser.new do | p | p.banner = "Usage: tracksperanto -f ShakeScript -w 1920 -h 1080 /Films/Blockbuster/Shots/001/script.shk" p.on("--code PATH_TO_SCRIPT", String, "Load custom Ruby code into tracksperanto") {|c| require c } p.on(" -f", "--from TRANSLATOR", String, "Use the specific import translator (will try to autodetect, but can be #{Tracksperanto.importer_names.join(', ')})") do | f | reader_name = f end p.on(" -p", "--prefix PREFIX", String, "A prefix to prepend to tracker names in bulk") { |w| set_prefix = w } p.on(" -w", "--width WIDTH_IN_PIXELS", Integer, "Absolute input comp width in pixels (will try to autodetect)") { |w| width = w } p.on(" -h", "--height HEIGHT_IN_PIXELS", Integer, "Absolute input comp height in pixels (will try to autodetect)") {|w| height = w } p.on(" -xs", "--xscale X_SCALING_FACTOR", Float, "Scale the result in X by this factor (1.0 is the default)") {|sx| scale_x = sx } p.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, "Scale the result in Y by this factor (1.0 is the default)") {|sy| scale_y = sy } p.on(" -s", "--slip FRAMES", Integer, "Slip the result by this number of frames, positive is 'later'") {|sy| slip = sy } p.on(" -g", "--golden", "Reset the residuals of all trackers to 0 (ignore correlation)") {|g_flag| golden_tracks = g_flag } p.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it") {|rw| reformat_w = rw } p.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it") {|rh| reformat_h = rh } p.on(" -o", "--only EXPORTER_NAME", String, "Only export the selected format, format must be one of #{writers.join(", ")}") {|f| sole_format = f } p.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right") {|sx| x_shift = sx } p.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down") {|sx| y_shift = sx } p.on("--version", "Show the version and exit") {|v| puts "#{Tracksperanto::VERSION} running on Ruby #{RUBY_VERSION} on #{RUBY_PLATFORM}" puts "Copyright 2008-#{Time.now.year} by Guerilla-DI (Julik Tarkhanov and contributors)" puts "For questions and support contact info at guerilla-di.org" exit(0) } end begin parser.parse! rescue OptionParser::MissingArgument => e STDERR.puts "Unknown argument: #{e.message}" puts parser exit(-1) end begin reader_klass = Tracksperanto.get_importer(reader_name) rescue NameError => e STDERR.puts "Unknown reader #{reader_name}, available readers: #{readers.join(', ')}" exit(-1) end input_file = ARGV.pop if !input_file STDERR.puts "No input file provided - should be the last argument" puts parser exit(-1) end class Spinner RING = ['|', '/', '-', '\\', '|', '/', '-', '\\'] def initialize @counter = 0 @last_message_length = 0 end def spin(percent, msg) current = RING[(@counter += 1) % RING.length] output = " [%s %d%%]" % [current, percent] STDOUT.write(output + "\r" * output.length) STDOUT.flush end end pipe = Tracksperanto::Pipeline::Base.new pipe.progress_block = Spinner.new.method(:spin).to_proc if sole_format begin pipe.exporters = [Tracksperanto::Export.get_exporter(sole_format)] rescue NameError STDERR.puts "Unknown exporter #{sole_format}. Available exporters: #{writers.join(", ")}" exit(-1) end end pipe.run(input_file, :pix_w => width, :pix_h => height, :parser => reader_klass) do | scaler, slipper, golden, reformat, shift, prefix | slipper.slip = slip scaler.x_factor = scale_x scaler.y_factor = scale_y golden.enabled = golden_tracks reformat.width = reformat_w if reformat_w reformat.height = reformat_h if reformat_h shift.x_shift = x_shift shift.y_shift = y_shift prefix.prefix = set_prefix end STDOUT.puts("\rConverted #{pipe.converted_points} trackers with #{pipe.converted_keyframes} keys")