Advertisement
SneakySquid

[GMod] Lines!

May 16th, 2024 (edited)
651
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.61 KB | None | 0 0
  1. LINE_CORNER_NONE = 0
  2. LINE_CORNER_MITER = 1
  3. LINE_CORNER_ROUND = 2
  4.  
  5. do
  6.     local plotting = false
  7.     local plots, quads = {}, {}
  8.     local plot_count, quad_count = 0, 0
  9.  
  10.     local thickness = 0
  11.     local min_angle = 0
  12.     local corner_type = 0
  13.  
  14.     function draw.StartLine(_thickness, _min_angle, _corner_type)
  15.         assert(not plotting, "how come your mom lets you have 2 lines")
  16.  
  17.         plotting = true
  18.         plot_count, quad_count = 0, 0
  19.  
  20.         thickness = (tonumber(_thickness) or 10) / 2
  21.         min_angle = math.pi - math.rad(tonumber(_min_angle) or 20)
  22.         corner_type = tonumber(_corner_type) or 0
  23.     end
  24.  
  25.     function draw.AddLinePoint(x, y)
  26.         assert(plotting, "better start a line boy")
  27.  
  28.         if not y then
  29.             y = x.y
  30.             x = x.x
  31.         end
  32.  
  33.         plot_count = plot_count + 1
  34.         plots[plot_count] = Vector(x, y)
  35.     end
  36.  
  37.     function draw.EndLine()
  38.         assert(plotting, "cut me point 2 g fam")
  39.         plotting = false
  40.  
  41.         assert(plot_count > 1, "A minimum of 2 points are required to draw a line.")
  42.  
  43.         for i = 1, plot_count - 1 do
  44.             local a, b = plots[i], plots[i + 1]
  45.  
  46.             local ab = b - a
  47.             ab:Normalize()
  48.  
  49.             local ab_right = Vector(-ab.y, ab.x)
  50.  
  51.             quad_count = quad_count + 1
  52.             quads[quad_count] = {
  53.                 a + ab_right * thickness,
  54.                 a - ab_right * thickness,
  55.                 b - ab_right * thickness,
  56.                 b + ab_right * thickness,
  57.             }
  58.         end
  59.  
  60.         if plot_count >= 3 then
  61.             for i = 2, plot_count - 1 do
  62.                 local a, b, c = unpack(plots, i - 1, i + 1)
  63.  
  64.                 local left_quad = quads[i - 1]
  65.                 local right_quad = quads[i]
  66.  
  67.                 local ab, bc do
  68.                     ab = b - a
  69.                     bc = c - b
  70.  
  71.                     ab:Normalize()
  72.                     bc:Normalize()
  73.                 end
  74.  
  75.                 local angle = math.acos(ab:Dot(bc))
  76.                 local bc_right = Vector(-bc.y, bc.x)
  77.  
  78.                 local is_left = false
  79.                 if ab:Dot(bc_right) > 0 then
  80.                     is_left = true
  81.                 end
  82.  
  83.                 if corner_type == LINE_CORNER_MITER then
  84.                     local height = thickness / math.cos(angle / 2)
  85.                     local joint_direction = bc - ab
  86.                     joint_direction:Normalize()
  87.  
  88.                     if is_left then
  89.                         joint_direction = -joint_direction
  90.                     end
  91.  
  92.                     if angle <= min_angle then
  93.                         left_quad[3] = b - joint_direction * height
  94.                         left_quad[4] = b + joint_direction * height
  95.  
  96.                         right_quad[1] = left_quad[4]
  97.                         right_quad[2] = left_quad[3]
  98.                     end
  99.                 elseif corner_type == LINE_CORNER_ROUND then
  100.                     local bd = (is_left and left_quad[4] or right_quad[2]) - b
  101.                     bd:Normalize()
  102.  
  103.                     local step = 1 / thickness
  104.                     local theta = (0.5 * math.pi - math.atan2(bd.y, bd.x)) % math.tau
  105.  
  106.                     mesh.Begin(MATERIAL_POLYGON, 1)
  107.                         for a = theta, theta + angle + step, step do
  108.                             local sin, cos = math.sin(a), math.cos(a)
  109.                             local pos = b + Vector(sin, cos) * thickness
  110.  
  111.                             mesh.Position(pos)
  112.                             mesh.AdvanceVertex()
  113.                         end
  114.  
  115.                         mesh.Position(b)
  116.                         mesh.AdvanceVertex()
  117.                     mesh.End()
  118.                 end
  119.             end
  120.         end
  121.  
  122.         mesh.Begin(MATERIAL_QUADS, quad_count)
  123.             for i, quad in ipairs(quads) do
  124.                 mesh.Quad(unpack(quad))
  125.             end
  126.         mesh.End()
  127.     end
  128. end
  129.  
  130.  
  131. --[[
  132.  
  133.     EXAMPLE
  134.  
  135. ]]--
  136.  
  137.  
  138. local plots = {}
  139. for i = 1, 20 do
  140.     if #plots == 0 then
  141.         table.insert(plots, Vector(ScrW() / 2, ScrH() / 2))
  142.     else
  143.         local rand_direction = Vector(math.Rand(-1, 1), math.Rand(-1, 1))
  144.         rand_direction:Normalize()
  145.  
  146.         local last_plot = plots[#plots]
  147.         table.insert(plots, last_plot + rand_direction * math.random(100, 400))
  148.     end
  149. end
  150.  
  151. hook.Add("PostRender", "", function()
  152.     cam.Start2D()
  153.         surface.SetDrawColor(255, 255 ,255)
  154.         render.SetMaterial(Material("vgui/white"))
  155.  
  156.         draw.StartLine(50, 15, math.floor(CurTime() % 3))
  157.             for i, plot in ipairs(plots) do
  158.                 draw.AddLinePoint(plot)
  159.             end
  160.         draw.EndLine()
  161.     cam.End2D()
  162. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement