-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdynamicSize.lua
96 lines (82 loc) · 3.12 KB
/
dynamicSize.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
-- Copyright (c) 2021 EngineerSmith
-- Under the MIT license, see license suppiled with this file
local path = select(1, ...):match("(.-)[^%.]+$")
local util = require(path .. "util")
local baseAtlas = require(path .. "baseAtlas")
local dynamicSizeTA = setmetatable({}, baseAtlas)
dynamicSizeTA.__index = dynamicSizeTA
-- Custom algorithm, see the file for more information
local grid = require(path .. "packing")
local lg = love.graphics
local newImageData = love.image.newImageData
local sort = table.sort
dynamicSizeTA.new = function(padding, extrude, spacing)
return setmetatable(baseAtlas.new(padding, extrude, spacing), dynamicSizeTA)
end
local area = function(a, b)
local aW, aH = util.getImageDimensions(a.image)
local bW, bH = util.getImageDimensions(b.image)
return aW * aH > bW * bH
end
local height = function(a, b)
local aH = select(2, util.getImageDimensions(a.image))
local bH = select(2, util.getImageDimensions(b.image))
return aH > bH
end
local width = function(a, b)
local aW = util.getImageDimensions(a.image)
local bW = util.getImageDimensions(b.image)
return aW > bW
end
-- sortBy options: "height"(default), "area", "width", "none"
dynamicSizeTA.bake = function(self, sortBy)
if self._dirty and not self._hardBake then
local shallowCopy = {unpack(self.images)}
if sortBy == "height" then
sort(shallowCopy, height)
elseif sortBy == "area" or sortBy == nil then
sort(shallowCopy, area)
elseif sortBy == "width" then
sort(shallowCopy, width)
end
-- Calculate positions and size of canvas
local grid = grid.new(self.maxWidth or self._maxCanvasSize, self.maxHeight or self._maxCanvasSize)
for _, image in ipairs(shallowCopy) do
local img = image.image
local width, height = util.getImageDimensions(img)
width = width + self.spacing + self.extrude * 2 + self.padding * 2
height = height + self.spacing + self.extrude * 2 + self.padding * 2
grid:insert(width, height, image) -- will always be successful or will error
end
local maxWidth, maxHeight = grid.currentWidth - self.spacing, grid.currentHeight - self.spacing
if self.bakeAsPow2 then
maxWidth = math.pow(2, math.ceil(math.log(maxWidth)/math.log(2)))
maxHeight = math.pow(2, math.ceil(math.log(maxHeight)/math.log(2)))
end
local data
if self._pureImageMode then
data = newImageData(maxWidth, maxHeight, "rgba8")
grid:draw(self.quads, maxWidth, maxHeight, self.extrude, self.padding, data)
self.image = data
else
local canvas = lg.newCanvas(maxWidth, maxHeight, self._canvasSettings)
lg.push("all")
lg.setBlendMode("replace")
lg.setCanvas(canvas)
grid:draw(self.quads, maxWidth, maxHeight, self.extrude, self.padding)
lg.pop()
local major = love.getVersion()
if major == 12 and lg.readbackTexture then
data = lg.readbackTexture(canvas)
else
data = canvas:newImageData()
end
self.image = lg.newImage(data)
self.image:setFilter(self.filterMin, self.filterMag)
end
self._dirty = false
return self, data
end
return self
end
return dynamicSizeTA