local _R = debug.getregistry() _R.EllipseCache = {} local VMatrix = _R.VMatrix local VMatrix_SetUnpacked = VMatrix.SetUnpacked local IMesh = _R.IMesh local IMesh_Draw = IMesh.Draw local IMesh_Destroy = IMesh.Destroy local IMesh_IsValid = IMesh.IsValid local IMesh_BuildFromTriangles = IMesh.BuildFromTriangles local Ellipse do local ellipse_matrix = Matrix() local anchor_vertex = { pos = Vector(0, 0), u = 0.5, v = 0.5, } local function RenderEllipse(ellipse_mesh, scale_x, scale_y) return function(self, x, y, rotation) if not self:IsValid() then return false end x, y = tonumber(x) or 0, tonumber(y) or 0 rotation = tonumber(rotation) or 0 if rotation ~= 0 then local rotation = math.rad(rotation) local cos, sin = math.cos(rotation), math.sin(rotation) VMatrix_SetUnpacked(ellipse_matrix, cos * scale_x, -sin * scale_y, 0, x, sin * scale_x, cos * scale_y, 0, y, 0, 0, 1, 0, 0, 0, 0, 1 ) else VMatrix_SetUnpacked(ellipse_matrix, scale_x, 0, 0, x, 0, scale_y, 0, y, 0, 0, 1, 0, 0, 0, 0, 1 ) end cam.PushModelMatrix(ellipse_matrix) IMesh_Draw(ellipse_mesh) cam.PopModelMatrix() return true end end function Ellipse(width, height, start_angle, end_angle, distance, color) local width, height = width / 2, height / 2 local radius = math.max(width, height) local start_angle, end_angle = math.Clamp(start_angle, 0, 360), math.Clamp(end_angle, 0, 360) local id = string.format("%i-%i-%i-%.2f-%s", radius, start_angle, end_angle, distance, color or color_white) if not _R.EllipseCache[id] then local vertices = {} local vertex_count = 0 local step = distance / radius local start_angle, end_angle = math.rad(start_angle), math.rad(end_angle) for angle = start_angle, end_angle, step do local a, b = angle, angle + step b = math.min(b, end_angle) local a_cos, a_sin = math.cos(a), math.sin(a) local b_cos, b_sin = math.cos(b), math.sin(b) vertices[vertex_count + 1] = anchor_vertex vertices[vertex_count + 2] = { pos = Vector(a_cos * radius, a_sin * radius), u = 0.5 + a_cos / 2, v = 0.5 + a_sin / 2, } vertices[vertex_count + 3] = { pos = Vector(b_cos * radius, b_sin * radius), u = 0.5 + b_cos / 2, v = 0.5 + b_sin / 2, } vertex_count = vertex_count + 3 end local ellipse_mesh = Mesh() IMesh_BuildFromTriangles(ellipse_mesh, vertices) _R.EllipseCache[id] = setmetatable( { Destroy = function() _R.EllipseCache[id] = nil return IMesh_Destroy(ellipse_mesh) end, IsValid = function() return IMesh_IsValid(ellipse_mesh) end, }, { __call = RenderEllipse(ellipse_mesh, width / radius, height / radius), } ) end return _R.EllipseCache[id] end end return Ellipse