97 lines
2.9 KiB
Ruby
Executable File
97 lines
2.9 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
require 'mikunyan'
|
|
require 'mikunyan/decoders'
|
|
require 'fileutils'
|
|
require 'json'
|
|
|
|
opts = {:as_asset => false, :outputdir => nil, :sprite => false, :pretty => false}
|
|
arg = nil
|
|
i = 0
|
|
while i < ARGV.count
|
|
if ARGV[i].start_with?('-')
|
|
case ARGV[i]
|
|
when '--as-asset', '-a'
|
|
opts[:as_asset] = true
|
|
when '--outputdir', '-o'
|
|
i += 1
|
|
opts[:outputdir] = ARGV[i]
|
|
when '--sprite', '-s'
|
|
opts[:sprite] = true
|
|
when '--pretty', '-p'
|
|
opts[:pretty] = true
|
|
else
|
|
warn("Unknown option: #{ARGV[i]}")
|
|
end
|
|
else
|
|
arg = ARGV[i] unless arg
|
|
end
|
|
i += 1
|
|
end
|
|
|
|
unless arg
|
|
warn("Input file is not specified")
|
|
exit(1)
|
|
end
|
|
|
|
unless File.file?(arg)
|
|
warn("File not found: #{arg}")
|
|
exit(1)
|
|
end
|
|
|
|
assets = []
|
|
|
|
if opts[:as_asset]
|
|
assets = [Mikunyan::Asset.file(arg, File.basename(arg, '.*'))]
|
|
else
|
|
assets = Mikunyan::AssetBundle.file(arg).assets
|
|
end
|
|
|
|
outdir = opts[:outputdir] || File.basename(arg, '.*')
|
|
FileUtils.mkpath(outdir)
|
|
|
|
assets.each do |asset|
|
|
if opts[:sprite]
|
|
json = {}
|
|
textures = {}
|
|
|
|
asset.objects.select{|o| asset.object_type(o) == 'Sprite'}.each do |o|
|
|
obj = asset.parse_object(o)
|
|
next unless obj
|
|
name = obj.m_Name.value
|
|
tex_id = obj.m_RD.texture.m_PathID.value
|
|
|
|
unless textures[tex_id]
|
|
tex_obj = asset.parse_object(tex_id)
|
|
if tex_obj
|
|
textures[tex_id] = Mikunyan::ImageDecoder.decode_object(tex_obj) if tex_obj
|
|
json[tex_id] = {:name => tex_obj.m_Name.value, :width => textures[tex_id].width, :height => textures[tex_id].height, :path_id => tex_id, :sprites => []}
|
|
end
|
|
end
|
|
|
|
if textures[tex_id]
|
|
x = obj.m_Rect.x.value
|
|
y = obj.m_Rect.y.value
|
|
width = obj.m_Rect.width.value
|
|
height = obj.m_Rect.height.value
|
|
|
|
json[tex_id][:sprites] << {:name => name, :x => x, :y => y, :width => width, :height => height, :path_id => o.path_id}
|
|
textures[tex_id].crop(x.round, (textures[tex_id].height - height - y).round, width.round, height.round).save("#{outdir}/#{name}.png")
|
|
end
|
|
end
|
|
puts opts[:pretty] ? JSON.pretty_generate(json.values) : JSON.generate(json.values)
|
|
else
|
|
json = []
|
|
asset.objects.select{|o| asset.object_type(o) == 'Texture2D'}.each do |o|
|
|
obj = asset.parse_object(o)
|
|
next unless obj
|
|
name = obj.m_Name.value
|
|
image = Mikunyan::ImageDecoder.decode_object(obj)
|
|
if image
|
|
json << {:name => name, :width => image.width, :height => image.height, :path_id => o.path_id}
|
|
image.save("#{outdir}/#{name}.png")
|
|
end
|
|
end
|
|
puts opts[:pretty] ? JSON.pretty_generate(json) : JSON.generate(json)
|
|
end
|
|
end
|