-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcl_melons_rounded_boxes.lua
More file actions
139 lines (122 loc) · 3.99 KB
/
cl_melons_rounded_boxes.lua
File metadata and controls
139 lines (122 loc) · 3.99 KB
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
--[[
[Melon's Rounded Boxes]
Want a rounded box that has a material?
Want it to look nice?
Want also to be able to draw any form of rounded polygons?
WELL YOURE IN LUCK!
Remember to cache your polygons
and to credit me :) (https://github.com/garryspins)
This doesnt stop you from doing stupid stuff, so dont be stupid
]]--
local boxes = {}
----
---@name boxes.RoundedBox
----
---@arg (radius: number) Radius of the rounded box
---@arg (x: number) X position of the box
---@arg (y: number) Y position of the box
---@arg (w: number) W of the box
---@arg (h: number) H of the box
---@arg (bl: number) Should the bottom left be rounded independently, if so how much
---@arg (tl: number) Should the top left be rounded independently, if so how much
---@arg (tr: number) Should the top right be rounded independently, if so how much
---@arg (br: number) Should the bottom right be rounded independently, if so how much
---@arg (detail: number) Number of vertices to put on edges, defaults to 1 for perfect quality, raise this number for how many vertices to skip.
----
---@return (poly: table) Polygon to be drawn with surface.DrawPoly
----
---- Generates a rounded box polygon
----
---`
---` local mat = Material("vgui/gradient-l")
---` local PANEL = vgui.Register("RoundedGradient", {}, "Panel")
---`
---` function PANEL:PerformLayout(w, h)
---` self.background = boxes.RoundedBox(w / 4, 0, 0, w, h)
---` end
---`
---` function PANEL:Paint(w, h)
---` draw.NoTexture()
---` surface.SetDrawColor(0, 89, 161)
---` surface.DrawPoly(self.background)
---`
---` surface.SetMaterial(mat)
---` surface.SetDrawColor(0, 140, 255)
---` surface.DrawPoly(self.background)
---` end
---`
function boxes.RoundedBox(radius, x, y, w, h, bl, tl, tr, br, detail)
local unround = {
{
x = x,
y = y + h,
u = 0,
v = 1,
radius = isnumber(bl) and bl
},
{
x = x,
y = y,
u = 0,
v = 0,
radius = isnumber(tl) and tl
},
{
x = x + w,
y = y,
u = 1,
v = 0,
radius = isnumber(tr) and tr
},
{
x = x + w,
y = y + h,
u = 1,
v = 1,
radius = isnumber(br) and br
},
}
return boxes.RoundedPolygonUV(unround, radius, x, y, w, h, detail)
end
function boxes.RoundedPolygonUV(poly, default_radius, x,y,w,h, detail)
poly = boxes.RoundedPolygon(poly, default_radius, detail)
for k,v in pairs(poly) do
v.u = (v.x-x) / w
v.v = (v.y-y) / h
end
return poly
end
function boxes.RoundedPolygon(poly, default_radius, detail)
local points = {}
for k,v in pairs(poly) do
local last = poly[k - 1] or poly[#poly]
local curr = v
local next = poly[k + 1] or poly[1]
local radius = curr.radius or default_radius
if radius == 0 then
table.insert(points, curr)
continue end
local ltc_ang = math.atan2(curr.y - last.y, curr.x - last.x) + math.rad(180)
local ntc_ang = math.atan2(curr.y - next.y, curr.x - next.x) + math.rad(180)
local lex, ley = math.cos(ltc_ang) * radius, math.sin(ltc_ang) * radius
local nex, ney = math.cos(ntc_ang) * radius, math.sin(ntc_ang) * radius
local cx, cy = curr.x + nex + lex, curr.y + ney + ley,
table.insert(points, {
x = curr.x + lex,
y = curr.y + ley,
})
local range = math.deg(ltc_ang - ntc_ang) % 360
for i = 1, range - 1, detail or 1 do
table.insert(points, {
x = cx + math.cos(ntc_ang + math.rad(i + 180)) * radius,
y = cy + math.sin(ntc_ang + math.rad(i + 180)) * radius,
})
end
table.insert(points, {
x = curr.x + nex,
y = curr.y + ney,
})
end
return points
end
return boxes