103 lines
2.8 KiB
Ruby
Executable File
103 lines
2.8 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
require 'mikunyan'
|
|
require 'fileutils'
|
|
begin
|
|
require 'usamin'
|
|
require 'usamin/overwrite'
|
|
rescue LoadError
|
|
require 'json'
|
|
end
|
|
|
|
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]
|
|
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 = opts[:as_asset] ? [Mikunyan::Asset.file(arg)] : Mikunyan::AssetBundle.file(arg).assets
|
|
|
|
outdir = opts[:outputdir] || File.basename(arg, '.*')
|
|
FileUtils.mkpath(outdir)
|
|
|
|
assets.each do |asset|
|
|
if opts[:sprite]
|
|
json = {}
|
|
textures = {}
|
|
|
|
asset.each_object do |obj|
|
|
next unless obj.type == 'Sprite'
|
|
obj = obj.parse
|
|
next unless obj
|
|
texture_id = obj.m_RD&.texture&.m_PathID&.value
|
|
next unless texture_id
|
|
|
|
unless textures.key?(texture_id)
|
|
texture_obj = asset.parse_object(texture_id)
|
|
if texture_obj.is_a?(Mikunyan::CustomTypes::Texture2D)
|
|
textures[texture_id] = texture_obj.generate_png
|
|
json[texture_id] = {
|
|
name: texture_obj.m_Name&.value, width: texture_obj.m_Width&.value, height: texture_obj.m_Height&.value,
|
|
format: texture_obj.m_TextureFormat&.value, path_id: texture_id, sprites: []
|
|
}
|
|
end
|
|
end
|
|
|
|
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[texture_id][:sprites] << { name: obj.object_name, x: x, y: y, width: width, height: height, path_id: obj.path_id }
|
|
|
|
next unless textures[texture_id] && x && y && width && height
|
|
textures[texture_id].crop(
|
|
x.round, (textures[texture_id].height - height - y).round, width.round, height.round
|
|
).save("#{outdir}/#{obj.object_name}.png")
|
|
end
|
|
puts opts[:pretty] ? JSON.pretty_generate(json.values) : JSON.generate(json.values)
|
|
else
|
|
json = []
|
|
asset.each_object do |obj|
|
|
next unless obj.type == 'Texture2D'
|
|
obj = obj.parse
|
|
next unless obj.is_a?(Mikunyan::CustomTypes::Texture2D)
|
|
json << {
|
|
name: obj.object_name, width: obj.width, height: obj.height,
|
|
format: obj.texture_format, path_id: obj.path_id
|
|
}
|
|
obj.generate_png&.save("#{outdir}/#{obj.object_name}.png")
|
|
end
|
|
puts opts[:pretty] ? JSON.pretty_generate(json) : JSON.generate(json)
|
|
end
|
|
end
|