Created
November 4, 2012 01:17
-
-
Save ioquatix/4009698 to your computer and use it in GitHub Desktop.
Collada to TaggedFormat conversion tool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'collada/parser/library' | |
path = ARGV[0] | |
doc = REXML::Document.new(File.open(path)) | |
library = Collada::Parser::Library.parse(doc) | |
class Mesh | |
def initialize(name) | |
@name = name | |
@indices = [] | |
# vertex -> index | |
@vertices = {} | |
# index -> vertex | |
@indexed = {} | |
@count = 0 | |
@axes = [] | |
end | |
attr :name | |
attr :indices | |
attr :vertices | |
attr :indexed | |
attr :axes | |
attr :count | |
def << vertex | |
if (index = vertices[vertex]) | |
@indices << index | |
else | |
@vertices[vertex] = @count | |
@indexed[@count] = vertex | |
@indices << @count | |
@count += 1 | |
end | |
end | |
def write(buffer) | |
buffer.puts "#{@name}: mesh triangles" | |
buffer.puts " indices: array u2" | |
@indices.each_slice(12) do |slice| | |
buffer.puts " #{slice.collect{|i| i.to_s.rjust(5)}.join}" | |
end | |
buffer.puts " end" | |
buffer.puts " vertices: array p3n3m2" | |
@count.times do |index| | |
buffer.puts " #{@indexed[index].collect{|v| v.to_s.rjust(12)}.join(' ')}" | |
end | |
buffer.puts " end" | |
if @axes.size | |
buffer.puts " axes: array axis" | |
@axes.each do |axis| | |
buffer.puts " #{axis.collect{|i| i.to_s.rjust(12)}.join(' ')}" | |
end | |
buffer.puts " end" | |
end | |
buffer.puts "end" | |
end | |
end | |
class VertexFormat | |
def initialize(format) | |
@format = format | |
@filters = {} | |
end | |
attr :filters | |
def extract(attributes) | |
attributes = attributes.inject({}){|hash, attribute| hash[attribute.semantic] = attribute.value; hash} | |
@format.collect do |(name, components)| | |
filter = @filters[name] | |
value = attributes[name] | |
vector = components.collect{|key| value[key]} | |
filter ? filter.call(vector) : vector | |
end.flatten | |
end | |
end | |
top = [] | |
library[:visual_scene].each do |scene| | |
scene.nodes.each do |node| | |
next unless node.instance | |
geometry = node.instance.lookup(library) | |
next unless geometry | |
output_mesh = Mesh.new(node.id) | |
output_format = VertexFormat.new [[:position, [:X, :Y, :Z]], [:normal, [:X, :Y, :Z]], [:texcoord, [:S, :T]]] | |
output_format.filters[:texcoord] = lambda {|(s, t)| [s, -t + 1.0]} | |
#output_format.filters[:position] = lambda {|value| (transform * Vector[*(value << 1)])[0..2]} | |
#output_format.filters[:normal] = lambda {|value| (transform * Vector[*(value << 0)])[0..2]} | |
geometry.mesh.polygons.each do |polygon| | |
polygon.each do |vertex| | |
output_mesh << output_format.extract(vertex) | |
end | |
end | |
node.children.each do |child| | |
translation = child.translation_vector | |
rotation = Collada::Transforms.rotation_matrix_to_quaternion(child.rotation_matrix) | |
output_mesh.axes << ([child.id] + translation.to_a + rotation.to_a) | |
end | |
top << output_mesh | |
end | |
end | |
top.each do |mesh| | |
mesh.write($stdout) | |
end | |
puts | |
puts "top: offset-table" | |
top.each do |mesh| | |
puts " #{mesh.name}: $#{mesh.name}" | |
end | |
puts "end" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You use like this:
You can check conversion like so:
You should get output like so: