-
Notifications
You must be signed in to change notification settings - Fork 6
/
isometric helper.lua
202 lines (170 loc) · 5.59 KB
/
isometric helper.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
local downscale = false
function CopyImage(fromImage, rect, newImageSize)
local pixelsFromSelection = fromImage:pixels(rect)
local selectedImage = Image(newImageSize.x, newImageSize.y)
for it in pixelsFromSelection do
local pixelValue = it()
selectedImage:putPixel(it.x - rect.x, it.y - rect.y, pixelValue)
end
return selectedImage
end
function SlideImage(fromImage, rect, isFront)
local pixelsFromSelection = fromImage:pixels(rect)
local slidedImage = Image(rect.width, rect.height + rect.width/2)
local yOffset = 0
local yStartOffset = 0
local walker = 1
if(isFront) then
yStartOffset = rect.width / 2
yOffset = yStartOffset
walker = -1
end
for it in pixelsFromSelection do
local pixelValue = it()
local newX = it.x - rect.x
local newY = it.y - rect.y
if(newX % 2 == 0) then
yOffset = yOffset + walker
end
if(newX == 0) then
yOffset = yStartOffset
end
slidedImage:putPixel(newX, newY + yOffset, pixelValue)
end
return slidedImage
end
--loop through x texture coords
function ToIso(fromImage, rect, newImageSize)
local pixelsFromSelection = fromImage:pixels(rect)
local selectedImage = Image(newImageSize.x, newImageSize.y)
for it in pixelsFromSelection do
local pixelValue = it()
local newx = (newImageSize.x/2-2)+it.x*2-it.y*2
local newy = it.x+it.y
local stopx = newx+3
for tempx=newx,stopx,1 do
--add one to y axis so the resize would work
selectedImage:putPixel(tempx, newy+1, pixelValue)
end
end
return selectedImage
end
function RefreshCanvas()
--should be a nicer solution
app.command.Undo()
app.command.Redo()
end
function ValidateSelection(sprite, selection)
-- bail if there's no active sprite
if not sprite then
print("No sprite")
return false
end
-- bail if nothing's selected
if selection.isEmpty then
print("Missing selection")
return false
end
if selection.bounds.width % 2 ~= 0 then
print("The width must be an even number")
return false
end
if selection.bounds.width ~= selection.bounds.height then
print("The selection must be a square")
return false
end
return true
end
function ToogleDownscale()
downscale = not downscale
end
function ConvertToSide()
local currentCel = app.activeCel
local sprite = app.activeSprite
local selection = sprite.selection
local originPoint = selection.origin
if(not ValidateSelection(sprite, selection)) then
return
end
local currentImage = Image(sprite.width, sprite.height)
currentImage:drawSprite(sprite, currentCel.frameNumber)
local selectedImage = SlideImage(currentImage, selection.bounds, false)
app.transaction(
function()
local outputLayer = sprite:newLayer()
outputLayer.name = "IsometricSide"
local outputSprite = outputLayer.sprite
local cel = sprite:newCel(outputLayer, currentCel.frameNumber)
local backToOriginImage = Image(outputSprite.width,outputSprite.height)
backToOriginImage:drawImage(selectedImage, originPoint)
cel.image = backToOriginImage
end
)
RefreshCanvas()
end
function ConvertToFront()
local currentCel = app.activeCel
local sprite = app.activeSprite
local selection = sprite.selection
local originPoint = selection.origin
if(not ValidateSelection(sprite, selection)) then
return
end
local currentImage = Image(sprite.width, sprite.height)
currentImage:drawSprite(sprite, currentCel.frameNumber)
local selectedImage = SlideImage(currentImage, selection.bounds, true)
app.transaction(
function()
local outputLayer = sprite:newLayer()
outputLayer.name = "IsometricFront"
local outputSprite = outputLayer.sprite
local cel = sprite:newCel(outputLayer, currentCel.frameNumber)
local backToOriginImage = Image(outputSprite.width,outputSprite.height)
backToOriginImage:drawImage(selectedImage, originPoint)
cel.image = backToOriginImage
end
)
RefreshCanvas()
end
function ConvertToTile()
local currentCel = app.activeCel
local sprite = app.activeSprite
local selection = sprite.selection
local originPoint = selection.origin
if(not ValidateSelection(sprite, selection)) then
return
end
local isometricTile
local currentImage = Image(sprite.width, sprite.height)
currentImage:drawSprite(sprite, currentCel.frameNumber)
local oneSide = selection.bounds.width
local selectedImage = CopyImage(currentImage, selection.bounds, Point(oneSide, oneSide))
isometricTile = ToIso(selectedImage, Rectangle(0,0,oneSide,oneSide), Point(oneSide * 4,oneSide * 2))
if downscale then
isometricTile:resize{width=(oneSide*2),height=oneSide}
isometricTile = CopyImage(isometricTile, Rectangle(0,1,oneSide*2,oneSide), Point(oneSide*2,oneSide))
else
isometricTile = CopyImage(isometricTile, Rectangle(0,1,oneSide*4,oneSide*2), Point(oneSide*4,oneSide*2))
end
app.transaction(
function()
local outputLayer = sprite:newLayer()
outputLayer.name = "IsometricTile"
local outputSprite = outputLayer.sprite
local backToOriginImage = Image(outputSprite.width,outputSprite.height)
backToOriginImage:drawImage(isometricTile, originPoint)
local cel = outputSprite:newCel(outputLayer, currentCel.frameNumber)
cel.image = backToOriginImage
end
)
RefreshCanvas()
end
local dialog = Dialog("Isometric Toolbar")
dialog
:button{text="Side",onclick=ConvertToSide}
:button{text="Front",onclick=ConvertToFront}
:separator()
:button{text="Tile",onclick=ConvertToTile}
:newrow()
:check{id="downscale", text="downscale", onclick=ToogleDownscale}
:show{wait=false}