#!/usr/bin/env ruby # == Synopsis # # Translate a 2D track file from a single format to many others # # == Usage # # tracksperanto -w 1920 -h 1080 /Films/Blockbuster/Shots/001/script.shk --only flamestabilizer # # == Author # Julik require File.dirname(__FILE__) + '/../lib/tracksperanto' unless defined?(Tracksperanto) require 'optparse' require 'rubygems' require 'progressbar' require "net/http" require "open-uri" require "timeout" def version_check begin version_info = open("http://rubygems.org/api/v1/gems/tracksperanto.xml").string.scan(/(.+)<\/version>/).to_s int_available, int_present = [version_info, Tracksperanto::VERSION].map{|v| v.scan(/(\d+)/).to_s.to_i } if int_available > int_present puts "Your version of Tracksperanto is probably out of date (the current version is #{version_info}, but you have #{Tracksperanto::VERSION})." puts "Please consider updating (run 'gem update tracksperanto')" end rescue Exception end end options = {} $notice = "Please consider a small donation to keep Tracksperanto going. http://guerilla-di.org/source-and-license/" $middlewares = [] writer_klass_name = nil readers = Tracksperanto.importer_names writers = Tracksperanto.exporter_names op = OptionParser.new def mw(name, option, default_value = nil) Proc.new do |value| v = value.nil? ? default_value : value $middlewares.push([name, {option => v}]) end end class CodeLoaded < RuntimeError; end op.banner = "Usage: tracksperanto -f ShakeScript -w 1920 -h 1080 /Films/Blockbuster/Shots/001/script.shk" op.on("--code PATH_TO_SCRIPT", String, "Load custom Ruby code into tracksperanto") do |c| unless $code require(c) raise CodeLoaded end end op.on(" -f", "--from TRANSLATOR", String, "Use the specific import translator") { |f| options[:importer] = f } op.on(" -w", "--width WIDTH_IN_PIXELS", Integer, "Absolute input comp width in pixels (will try to autodetect)") { |w| options[:width] = w } op.on(" -h", "--height HEIGHT_IN_PIXELS", Integer, "Absolute input comp height in pixels (will try to autodetect)") {|w| options[:height] = w } op.on(" -o", "--only EXPORTER_NAME", String, "Only export the selected format, format must be one of #{writers.join(", ")}") { |f| writer_klass_name = f } op.on(" -xs", "--xscale X_SCALING_FACTOR", Float, "Scale the result in X by this factor (1.0 is the default)", &mw("Scaler", :x_factor)) op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, "Scale the result in Y by this factor (1.0 is the default)", &mw("Scaler", :y_factor)) op.on(" -s", "--slip FRAMES", Integer, "Slip the result by this number of frames, positive is 'later'", &mw("Slipper", :slip)) op.on(" -g", "--golden", "Reset the residuals of all trackers to 0 (ignore correlation)", &mw("Golden", :enabled, true)) op.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it", &mw("Reformat", :width)) op.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it", &mw("Reformat", :height)) op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer, "Only export trackers having more than X keyframes", &mw("LengthCutoff", :min_length)) op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &mw("Shift", :x_shift)) op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &mw("Shift", :y_shift)) op.on(" -p", "--prefix PREFIX", String, "A prefix to prepend to tracker names in bulk", &mw("Prefix", :prefix)) op.on("--lerp", "Linearly interpolate missing keyframes", &mw("Lerp", :enabled, true)) op.on("--flip", "Flip the comp horizontally", &mw("Flip", :enabled, true)) op.on("--flop", "Flop the comp vertically", &mw("Flop", :enabled, true)) op.on("--version", "Show the version and exit") do |v| puts "Tracksperanto v.#{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#{64.chr}guerilla-di.org" puts $notice version_check() exit(0) end begin op.parse! rescue CodeLoaded $code = true retry end input_file = ARGV.pop unless input_file $stderr.puts "No input file provided - should be the last argument. Also use the --help option." exit(-1) end unless File.exist?(input_file) $stderr.puts "Input file #{input_file} does not exist" exit(-1) end pbar = ProgressBar.new("Converting", 100, $stderr) pipe = Tracksperanto::Pipeline::Base.new(:progress_block => lambda{|p,m| pbar.set(p) }, :middleware_tuples => $middlewares) pipe.exporters = [Tracksperanto.get_exporter(writer_klass_name)] if writer_klass_name pipe.run(input_file, options) pbar.finish puts "Converted #{pipe.converted_points} trackers with #{pipe.converted_keyframes} keys. #{$notice}" version_check()