SneakySquid

Ellipses!

May 27th, 2024 (edited)
878
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.90 KB | None | 0 0
  1. local _R = debug.getregistry()
  2. _R.EllipseCache = {}
  3.  
  4. local VMatrix = _R.VMatrix
  5. local VMatrix_SetUnpacked = VMatrix.SetUnpacked
  6.  
  7. local IMesh = _R.IMesh
  8. local IMesh_Draw = IMesh.Draw
  9. local IMesh_Destroy = IMesh.Destroy
  10. local IMesh_IsValid = IMesh.IsValid
  11. local IMesh_BuildFromTriangles = IMesh.BuildFromTriangles
  12.  
  13. local Ellipse do
  14.     local ellipse_matrix = Matrix()
  15.  
  16.     local anchor_vertex = {
  17.         pos = Vector(0, 0),
  18.         u = 0.5, v = 0.5,
  19.     }
  20.  
  21.     local function RenderEllipse(ellipse_mesh, scale_x, scale_y)
  22.         return function(self, x, y, rotation)
  23.             if not self:IsValid() then return false end
  24.  
  25.             x, y = tonumber(x) or 0, tonumber(y) or 0
  26.             rotation = tonumber(rotation) or 0
  27.  
  28.             if rotation ~= 0 then
  29.                 local rotation = math.rad(rotation)
  30.                 local cos, sin = math.cos(rotation), math.sin(rotation)
  31.  
  32.                 VMatrix_SetUnpacked(ellipse_matrix,
  33.                     cos * scale_x, -sin * scale_y, 0, x,
  34.                     sin * scale_x,  cos * scale_y, 0, y,
  35.                     0, 0, 1, 0,
  36.                     0, 0, 0, 1
  37.                 )
  38.             else
  39.                 VMatrix_SetUnpacked(ellipse_matrix,
  40.                     scale_x, 0, 0, x,
  41.                     0, scale_y, 0, y,
  42.                     0, 0, 1, 0,
  43.                     0, 0, 0, 1
  44.                 )
  45.             end
  46.  
  47.             cam.PushModelMatrix(ellipse_matrix)
  48.                 IMesh_Draw(ellipse_mesh)
  49.             cam.PopModelMatrix()
  50.  
  51.             return true
  52.         end
  53.     end
  54.  
  55.     function Ellipse(width, height, start_angle, end_angle, distance, color)
  56.         local width, height = width / 2, height / 2
  57.         local radius = math.max(width, height)
  58.         local start_angle, end_angle = math.Clamp(start_angle, 0, 360), math.Clamp(end_angle, 0, 360)
  59.  
  60.         local id = string.format("%i-%i-%i-%.2f-%s", radius, start_angle, end_angle, distance, color or color_white)
  61.  
  62.         if not _R.EllipseCache[id] then
  63.             local vertices = {}
  64.             local vertex_count = 0
  65.             local step = distance / radius
  66.             local start_angle, end_angle = math.rad(start_angle), math.rad(end_angle)
  67.  
  68.             for angle = start_angle, end_angle, step do
  69.                 local a, b = angle, angle + step
  70.                 b = math.min(b, end_angle)
  71.  
  72.                 local a_cos, a_sin = math.cos(a), math.sin(a)
  73.                 local b_cos, b_sin = math.cos(b), math.sin(b)
  74.  
  75.                 vertices[vertex_count + 1] = anchor_vertex
  76.  
  77.                 vertices[vertex_count + 2] = {
  78.                     pos = Vector(a_cos * radius, a_sin * radius),
  79.                     u = 0.5 + a_cos / 2, v = 0.5 + a_sin / 2,
  80.                 }
  81.  
  82.                 vertices[vertex_count + 3] = {
  83.                     pos = Vector(b_cos * radius, b_sin * radius),
  84.                     u = 0.5 + b_cos / 2, v = 0.5 + b_sin / 2,
  85.                 }
  86.  
  87.                 vertex_count = vertex_count + 3
  88.             end
  89.  
  90.             local ellipse_mesh = Mesh()
  91.             IMesh_BuildFromTriangles(ellipse_mesh, vertices)
  92.  
  93.             _R.EllipseCache[id] = setmetatable(
  94.                 {
  95.                     Destroy = function()
  96.                         _R.EllipseCache[id] = nil
  97.                         return IMesh_Destroy(ellipse_mesh)
  98.                     end,
  99.  
  100.                     IsValid = function()
  101.                         return IMesh_IsValid(ellipse_mesh)
  102.                     end,
  103.                 },
  104.  
  105.                 {
  106.                     __call = RenderEllipse(ellipse_mesh, width / radius, height / radius),
  107.                 }
  108.             )
  109.         end
  110.  
  111.         return _R.EllipseCache[id]
  112.     end
  113. end
  114.  
  115. return Ellipse
  116.  
Advertisement
Comments
  • SneakySquid
    2 years
    # Lua 0.41 KB | 0 0
    1. local Ellipse = include("ellipse.lua")
    2.  
    3. local x, y = ScrW() / 2, ScrH() / 2
    4. local ellipse_test = Ellipse(600, 400, 0, 360, 1, color_white)
    5.  
    6. hook.Add("PostRender", ellipse_test, function()
    7.     cam.Start2D()
    8.         render.SetMaterial(Material("vgui/white"))
    9.         ellipse_test(x, y, (1 + math.sin(CurTime())) / 2 * 360)
    10.     cam.End2D()
    11. end)
    12.  
    13. timer.Simple(1, function()
    14.     ellipse_test:Destroy()
    15.     print("Removed ellipse.")
    16. end)
    17.  
Add Comment
Please, Sign In to add comment