Skip to content

Instantly share code, notes, and snippets.

@binzume
Created August 30, 2015 11:41
Show Gist options
  • Save binzume/fd47b969467a7f5921ea to your computer and use it in GitHub Desktop.
Save binzume/fd47b969467a7f5921ea to your computer and use it in GitHub Desktop.
mirror metasequoia bones
#!/usr/bin/env ruby
# -*- encoding: UTF-8 -*-
require 'rexml/document'
def fix_bone src_doc, mode = 'R'
if mode == 'R'
re = /(?<=_)R(?=\s|_|$)/
target = 'L'
elsif mode == 'L'
re = /(?<=_)L(?=\s|_|$)/
target = 'R'
else
raise "mode: R or L"
end
dst_doc = src_doc
bones = {}
src_doc.elements.each('//Bone') {|bone|
name = bone.attributes['name']
dst_name = name.dup
if dst_name.sub!(re, target)
bones[dst_name] = bone
end
}
attr = ['rtX', 'rtY', 'rtZ', 'tpX', 'tpY', 'tpZ', 'scX', 'scY', 'scZ',
'wMvX', 'wMvY', 'wMvZ','wScRootX', 'wScRootY', 'wScRootZ',
'wScTipX', 'wScTipY', 'wScTipZ', 'wRotB', 'wRotH', 'wRotP', 'wStRoot', 'wStTip', 'wWid']
neg = Set['rtX', 'tpX', 'scX', 'wMvX', 'wScRootX', 'wScTipX', 'wRotB', 'wRotH']
dst_doc.elements.each('//Bone') {|bone|
name = bone.attributes['name']
if bones[name]
puts "#{name} -> #{bones[name].attributes['name']}"
attr.each{|k|
if bone.attributes[k] && bones[name].attributes[k]
v = bones[name].attributes[k]
v = (-v.to_f).to_s if neg.include?(k)
bone.attributes[k] = v
end
}
end
}
dst_doc
end
def copy_bone src_doc, dst_doc
bones_all = {}
src_doc.elements.each('//Bone') {|bone|
name = bone.attributes['name']
bones_all[name] = bone
}
attr = ['rtX', 'rtY', 'rtZ', 'tpX', 'tpY', 'tpZ', 'scX', 'scY', 'scZ',
'wMvX', 'wMvY', 'wMvZ','wScRootX', 'wScRootY', 'wScRootZ',
'wScTipX', 'wScTipY', 'wScTipZ', 'wRotB', 'wRotH', 'wRotP', 'wStRoot', 'wStTip', 'wWid']
dst_doc.elements.each('//Bone') {|bone|
name = bone.attributes['name']
if bones_all[name]
attr.each{|k|
if bone.attributes[k] && bones_all[name].attributes[k]
v = bones_all[name].attributes[k]
bone.attributes[k] = v
end
}
end
}
dst_doc
end
if ARGV.length == 1
src = REXML::Document.new(open(ARGV[0]).read())
fix_bone(src, 'R')
file = ARGV[0]
dst = src
elsif ARGV.length == 2
src = REXML::Document.new(open(ARGV[0]).read())
dst = REXML::Document.new(open(ARGV[1]).read())
copy_bone(src, dst)
file = ARGV[1]
else
puts "usage: ruby fix_bone.rb hoge.mqx # mirror born params R -> L"
puts "usage: ruby fix_bone.rb src.mqx dst.mqx # copy born params src -> dst"
exit(1)
end
fmt = REXML::Formatters::Default.new
open(file, 'w') { |f|
fmt.write(dst, f)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment