|
local spineLoader = {} |
|
|
|
local json = require "json" |
|
|
|
|
|
local function parseAtlasFile( atlasPath ) |
|
|
|
local function parseIntTuple4( l ) |
|
local a,b,c,d = string.match( l , " ? ?%a+: ([+-]?%d+), ?([+-]?%d+), ?([+-]?%d+), ?([+-]?%d+)" ) |
|
local a,b,c,d = tonumber( a ), tonumber( b ), tonumber( c ), tonumber( d ) |
|
return a and b and c and d and {a, b, c ,d} |
|
end |
|
|
|
local function parseIntTuple2( l ) |
|
local a,b = string.match( l , " ? ?%a+: ([+-]?%d+), ?([+-]?%d+)" ) |
|
local a,b = tonumber( a ), tonumber( b ) |
|
return a and b and {a, b} |
|
end |
|
|
|
if not atlasPath then |
|
print("Error: " .. path .. ".atlas" .. " doesn't exist!") |
|
return nil |
|
end |
|
|
|
local atlasFile = io.open( atlasPath, "r" ) |
|
if not atlasFile then |
|
print("Error: " .. path .. ".atlas" .. " doesn't exist!") |
|
return nil |
|
end |
|
|
|
local pages = {} |
|
|
|
local it = atlasFile:lines() |
|
for l in it do |
|
if #l == 0 then |
|
l = it() |
|
if l then |
|
local page = { name = l } |
|
l = it() |
|
page.size = parseIntTuple2( l ) |
|
if page.size then |
|
l = it() |
|
end |
|
page.format = string.match( l, "%a+: (.+)" ) |
|
page.filter = {string.match( it(), "%a+: (.+),(.+)" )} |
|
page.wrap = string.match( it(), "%a+: (.+)" ) |
|
page.regions = {} |
|
table.insert( pages, page ) |
|
else |
|
break |
|
end |
|
else |
|
local region = {name = l} |
|
|
|
region.rotate = string.match( it(), "%a+: (.+)" ) == "true" |
|
region.xy = parseIntTuple2( it() ) |
|
region.size = parseIntTuple2( it() ) |
|
l = it() |
|
region.splits = parseIntTuple4(l) |
|
if region.splits then |
|
l = it() |
|
region.pad = parseIntTuple4(l) |
|
if region.pad then |
|
l = it() |
|
end |
|
end |
|
region.orig = parseIntTuple2( l ) |
|
region.offset = parseIntTuple2( it() ) |
|
region.index = tonumber( string.match( it() , "%a+: ([+-]?%d+)" ) ) |
|
|
|
table.insert( pages[#pages].regions, region ) |
|
end |
|
end |
|
atlasFile:close( ) |
|
|
|
return pages |
|
end |
|
|
|
|
|
function spineLoader.load( name, dir ) |
|
dir = dir or "/" |
|
if string.sub(dir, -1) ~= "/" then |
|
dir = dir .. "/" |
|
end |
|
|
|
local pages = parseAtlasFile( system.pathForFile( dir .. name ) ) |
|
|
|
local sprites = {} |
|
|
|
for _,page in ipairs(pages) do |
|
local options = { frames={} } |
|
if page.size then |
|
options.sheetContentWidth, options.sheetContentHeight = unpack( page.size ) |
|
end |
|
for i,region in ipairs(page.regions) do |
|
sprites[region.name] = { frame=i, region=region, page=page } |
|
local frame = { } |
|
frame.x, frame.y = unpack(region.xy) |
|
frame.width, frame.height = unpack(region.size) |
|
if region.rotate then |
|
frame.width, frame.height = frame.height, frame.width |
|
end |
|
if region.offset[1] ~= 0 or region.offset[2] ~= 0 or region.size[1] ~= region.orig[1] or region.size[2] ~= region.orig[2] then |
|
print("WARNING: Corona currently does not srtipping whitespaces in Spine atlases") |
|
end |
|
table.insert( options.frames, frame ) |
|
end |
|
|
|
local oldMag, oldMin = display.getDefault( "magTextureFilter" ), display.getDefault( "minTextureFilter" ) |
|
local newMag, newMin = "linear", "linear" |
|
if string.find("Nearest", page.filter[1]) then |
|
newMin = "nearest" |
|
end |
|
if string.find("Nearest", page.filter[2]) then |
|
newMag = "nearest" |
|
end |
|
display.setDefault( "magTextureFilter", newMag ) |
|
display.setDefault( "minTextureFilter", newMin ) |
|
page.sheet = graphics.newImageSheet( dir..page.name, options ) |
|
display.setDefault( "magTextureFilter", oldMag ) |
|
display.setDefault( "minTextureFilter", oldMin ) |
|
end |
|
|
|
function sprites.createImage(_, attachment) |
|
local sprite = sprites[attachment.name] |
|
local obj = display.newRect( 0, 0, 100, 100 ) |
|
if sprite then |
|
obj.fill = { type="image", sheet=sprite.page.sheet, frame=sprite.frame} |
|
if sprite.region.rotate then |
|
obj.fill.rotation = 90 |
|
end |
|
end |
|
return obj |
|
end |
|
function sprites.createMesh(_, attachment, meshParameters) |
|
local sprite = sprites[attachment.name] |
|
local obj = display.newMesh(meshParameters) |
|
if sprite then |
|
obj.fill = { type="image", sheet=sprite.page.sheet, frame=sprite.frame} |
|
if sprite.region.rotate then |
|
obj.fill.rotation = 90 |
|
end |
|
end |
|
return obj |
|
end |
|
|
|
function sprites.setupImageFunctions(skeleton) |
|
skeleton.createImage = sprites.createImage |
|
skeleton.createMesh = sprites.createMesh |
|
end |
|
|
|
return sprites |
|
end |
|
|
|
|
|
return spineLoader |