forked from securas/EdgeNormals
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathedge_normal_sequence.lua
159 lines (131 loc) · 5.01 KB
/
edge_normal_sequence.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
-- Based on the script from ericoporto
-- https://gist.github.com/ericoporto/f4b3553bb9bcb666c6113fe084198261
if app.apiVersion < 1 then
return app.alert("This script requires Aseprite v1.2.10-beta3")
end
function runOnCell(cel, data, activeLayer)
if not cel then
return app.alert("There is no active image")
end
local img0 = cel.image:clone()
local img = cel.image:clone()
local position = cel.position
local height = 1
print(cel.frameNumber)
print(activeLayer.name)
if img.colorMode == ColorMode.RGB then
local rgba = app.pixelColor.rgba
local rgbaA = app.pixelColor.rgbaA
for it in img:pixels() do
local x = it.x
local y = it.y
local top = 2
local left = 2
local right = 2
local bottom = 2
local maxx = img.width - 1
local maxy = img.height - 1
it(rgba(0, 0, 0, 0))
-- only works on pixels with color
if rgbaA(img0:getPixel(x, y)) == 255 then
-- Detect Edges around pixel
local topleft = 0
local top = 0
local x_dir = 0
local y_dir = 0
-- top left
if (x == 0 and y == 0) or (x == 0) or (y == 0) or (rgbaA(img0:getPixel(x - 1, y - 1)) < 255) then
x_dir = x_dir - 1
y_dir = y_dir - 1
end
-- top
if (y == 0) or (rgbaA(img0:getPixel(x, y - 1)) < 255) then
y_dir = y_dir - 1
end
-- top right
if (x == maxx and y == 0) or (x == maxx) or (y == 0) or (rgbaA(img0:getPixel(x + 1, y - 1)) < 255) then
x_dir = x_dir + 1
y_dir = y_dir - 1
end
-- left
if (x == 0) or (rgbaA(img0:getPixel(x - 1, y)) < 255) then
x_dir = x_dir - 1
end
-- right
if (x == maxx) or (rgbaA(img0:getPixel(x + 1, y)) < 255) then
x_dir = x_dir + 1
end
-- bottom left
if (x == 0 and y == maxy) or (x == 0) or (y == maxy) or (rgbaA(img0:getPixel(x - 1, y + 1)) < 255) then
x_dir = x_dir - 1
y_dir = y_dir + 1
end
-- bottom
if (y == maxy) or (rgbaA(img0:getPixel(x, y + 1)) < 255) then
y_dir = y_dir + 1
end
-- bottom right
if (x == maxx and y == maxy) or (x == maxx) or (y == maxy) or (rgbaA(img0:getPixel(x + 1, y + 1)) < 255) then
x_dir = x_dir + 1
y_dir = y_dir + 1
end
--if math.abs( x_dir ) > 0 or math.abs( y_dir ) > 0 then
-- process pixels that have a valid direction
local normalization = math.sqrt(x_dir * x_dir + y_dir * y_dir + height * height)
x_dir = x_dir / normalization
y_dir = -y_dir / normalization
if data.Invert_Y then
y_dir = -y_dir
end
local z_dir = height / normalization
--print( x_dir, y_dir, z_dir )
-- convert direction into color
local color_dir = rgba(
math.floor((x_dir * 0.5 + 0.5) * 255),
math.floor((y_dir * 0.5 + 0.5) * 255),
math.floor((z_dir * 0.5 + 0.5) * 255), 255)
it(color_dir)
--end
end
end
elseif img.colorMode == ColorMode.GRAY then
return app.alert("This script is only for RGB Color Mode")
elseif img.colorMode == ColorMode.INDEXED then
return app.alert("This script is only for RGB Color Mode")
end
local sprite = cel.sprite
local frame = cel.frame
local currentLayer = activeLayer
local newLayerName = currentLayer.name .. "_NormalGenerated"
local newLayer = nil
for i, layer in ipairs(sprite.layers) do
if layer.name == newLayerName then
-- the layer to write normal on is already exists
newLayer = layer
end
end
if newLayer == nil then
newLayer = sprite:newLayer()
newLayer.name = newLayerName
end
local newCel = sprite:newCel(newLayer, frame, img, position)
end
function runOnCells(cells, data, activeLayer)
for i, cell in ipairs(cells) do
runOnCell(cell, data, activeLayer)
end
app.refresh()
end
if (app.range.isEmpty) then
return app.alert("No Selection")
else
local d = Dialog("Edge Normal Map")
d:check { id = "Invert_Y", label = "Invert Y:", text = "", selected = true, focus = true }
:button { id = "ok", text = "&OK", focus = true }
:button { text = "&Cancel" }
:show()
data = d.data
if data.ok then
runOnCells(app.range.cels, data, app.activeLayer)
end
end