Skip to content

Instantly share code, notes, and snippets.

@ioquatix
Created November 4, 2012 01:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ioquatix/4009698 to your computer and use it in GitHub Desktop.
Save ioquatix/4009698 to your computer and use it in GitHub Desktop.
Collada to TaggedFormat conversion tool.
#!/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"
@ioquatix
Copy link
Author

ioquatix commented Nov 4, 2012

You use like this:

./convert.rb sample.dae > sample.tft
./tf-convert --text-to-binary sample.tft sample.tfb

You can check conversion like so:

./tf-convert --dump-binary

You should get output like so:

<tmv2; 24 bytes; magic = 42>
[oftb; 52 bytes; offset = 15496]
    ball:
    [mesh; 48 bytes; offset = 24]
        layout = triangles
        indices:
        [ind2; 2604 bytes; offset = 72]
            0 1 2 3 4 5 5 6 3 7 8 9 9 10 <snip>
        vertices:
        [3320; 12748 bytes; offset = 2676]
            P=(0.911829, -3.06488, -1.57933) N=(0.166692, -0.885884, -0.432924) M=(0.344138, 0.744129)
            P=(1.57933, -3.06488, -0.911829) N=(0.306136, -0.927349, -0.215187) M=(0.344138, 0.663349)
            P=(0.471997, -3.41843, -0.817523) N=(0.215187, -0.927349, -0.306136) M=(0.452776, 0.744129)
            P=(-0.642596, 0, -3.9154) N=(-0.321429, 0, -0.946934) M=(0.490512, 0.091337)
            <snip>
        axes:
        [axes; 72 bytes; offset = 15424]
            origin T=(0, 0, 0) R=(0, 0, 0, 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment