Perf: ImVec2/ImVec4/ImRect store named fields (no metamethod per .x/.Min), bench flags --roblox/--open-only

This commit is contained in:
4DBug
2026-10-08 10:16:40 -05:00
parent 7a20710b65
commit 623dc5b936
9 changed files with 299 additions and 419 deletions
+1 -1
View File
@@ -1 +1 @@
[[12, "imgui.lua"], [13741, "imgui_demo.lua"], [14674, "imgui_demo_2.lua"], [17749, "imgui_demo_apps.lua"], [19008, "imgui_demo_tools.lua"], [20334, "imgui_demo_widgets.lua"], [22258, "imgui_docking.lua"], [25386, "imgui_dragdrop.lua"], [25678, "imgui_draw.lua"], [30900, "imgui_h.lua"], [33113, "imgui_impl_roblox.lua"], [33937, "imgui_impl_roblox_fonts.lua"], [40340, "imgui_internal.lua"], [43510, "imgui_tables.lua"], [47857, "imgui_tabs.lua"], [49024, "imgui_widgets.lua"], [57548, "imstb_rectpack.lua"], [57994, "imstb_textedit.lua"], [59235, "imstb_truetype.lua"], [61703, "imstd_minstdio.lua"]] [[12, "imgui.lua"], [13741, "imgui_demo.lua"], [14674, "imgui_demo_2.lua"], [17749, "imgui_demo_apps.lua"], [19008, "imgui_demo_tools.lua"], [20334, "imgui_demo_widgets.lua"], [22258, "imgui_docking.lua"], [25386, "imgui_dragdrop.lua"], [25678, "imgui_draw.lua"], [30900, "imgui_h.lua"], [33066, "imgui_impl_roblox.lua"], [33890, "imgui_impl_roblox_fonts.lua"], [40293, "imgui_internal.lua"], [43449, "imgui_tables.lua"], [47796, "imgui_tabs.lua"], [48963, "imgui_widgets.lua"], [57487, "imstb_rectpack.lua"], [57933, "imstb_textedit.lua"], [59174, "imstb_truetype.lua"], [61642, "imstd_minstdio.lua"]]
+146 -207
View File
@@ -21962,7 +21962,7 @@ local function StyleCopy(dst, src)
elseif type(v) == "table" and getmetatable(v) ~= nil and type(v[1]) == "number" then elseif type(v) == "table" and getmetatable(v) ~= nil and type(v[1]) == "number" then
local c = dst[k] local c = dst[k]
if type(c) ~= "table" then c = setmetatable({}, getmetatable(v)); dst[k] = c end if type(c) ~= "table" then c = setmetatable({}, getmetatable(v)); dst[k] = c end
for i = 1, #v do rawset(c, i, v[i]) end for _, key in ipairs({ "x", "y", "z", "w" }) do if rawget(v, key) ~= nil then c[key] = v[key] end end
else else
dst[k] = v dst[k] = v
end end
@@ -26017,9 +26017,9 @@ function ImGui.ShadeVertsTransformPos(draw_list, vert_start_idx, vert_end_idx, p
local pix, piy, pox, poy = pivot_in.x, pivot_in.y, pivot_out.x, pivot_out.y local pix, piy, pox, poy = pivot_in.x, pivot_in.y, pivot_out.x, pivot_out.y
for i = vert_start_idx, vert_end_idx - 1 do for i = vert_start_idx, vert_end_idx - 1 do
local pos = data[i][1] local pos = data[i][1]
local x, y = pos[1] - pix, pos[2] - piy local x, y = pos.x - pix, pos.y - piy
pos[1] = x * cos_a - y * sin_a + pox pos.x = x * cos_a - y * sin_a + pox
pos[2] = x * sin_a + y * cos_a + poy pos.y = x * sin_a + y * cos_a + poy
end end
end end
@@ -29387,7 +29387,7 @@ function MT.ImDrawList:PrimRect(a, c, col)
ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv)
vtx_data[vtx_write_ptr + 0][3] = col vtx_data[vtx_write_ptr + 0][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c[1], a[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c.x, a.y)
ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], uv)
vtx_data[vtx_write_ptr + 1][3] = col vtx_data[vtx_write_ptr + 1][3] = col
@@ -29395,7 +29395,7 @@ function MT.ImDrawList:PrimRect(a, c, col)
ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv)
vtx_data[vtx_write_ptr + 2][3] = col vtx_data[vtx_write_ptr + 2][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a[1], c[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a.x, c.y)
ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], uv)
vtx_data[vtx_write_ptr + 3][3] = col vtx_data[vtx_write_ptr + 3][3] = col
@@ -29427,16 +29427,16 @@ function MT.ImDrawList:PrimRectUV(a, c, uv_a, uv_c, col)
ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv_a) ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv_a)
vtx_data[vtx_write_ptr + 0][3] = col vtx_data[vtx_write_ptr + 0][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c[1], a[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c.x, a.y)
ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][2], uv_c[1], uv_a[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][2], uv_c.x, uv_a.y)
vtx_data[vtx_write_ptr + 1][3] = col vtx_data[vtx_write_ptr + 1][3] = col
ImVec2_Copy(vtx_data[vtx_write_ptr + 2][1], c) ImVec2_Copy(vtx_data[vtx_write_ptr + 2][1], c)
ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv_c) ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv_c)
vtx_data[vtx_write_ptr + 2][3] = col vtx_data[vtx_write_ptr + 2][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a[1], c[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a.x, c.y)
ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][2], uv_a[1], uv_c[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][2], uv_a.x, uv_c.y)
vtx_data[vtx_write_ptr + 3][3] = col vtx_data[vtx_write_ptr + 3][3] = col
self._VtxWritePtr = vtx_write_ptr + 4 self._VtxWritePtr = vtx_write_ptr + 4
@@ -29492,11 +29492,11 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local i2 = (i1 == points_count) and 1 or i1 + 1 local i2 = (i1 == points_count) and 1 or i1 + 1
local p1 = points[i1] local p1 = points[i1]
local p2 = points[i2] local p2 = points[i2]
local dx = p2[1] - p1[1] local dx = p2.x - p1.x
local dy = p2[2] - p1[2] local dy = p2.y - p1.y
dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy) dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy)
temp_normals[i1][1] = dy temp_normals[i1].x = dy
temp_normals[i1][2] = -dx temp_normals[i1].y = -dx
end end
if not closed then if not closed then
ImVec2_Copy(temp_normals[points_count], temp_normals[points_count - 1]) ImVec2_Copy(temp_normals[points_count], temp_normals[points_count - 1])
@@ -29524,18 +29524,18 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + (use_texture and 2 or 3)) local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + (use_texture and 2 or 3))
-- Average normals -- Average normals
local dm_x = (temp_normals[i1][1] + temp_normals[i2][1]) * 0.5 local dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5
local dm_y = (temp_normals[i1][2] + temp_normals[i2][2]) * 0.5 local dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5
dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y) dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y)
dm_x = dm_x * half_draw_size dm_x = dm_x * half_draw_size
dm_y = dm_y * half_draw_size dm_y = dm_y * half_draw_size
-- Add temporary vertices for the outer edges -- Add temporary vertices for the outer edges
local out_off = (i2 - 1) * 2 local out_off = (i2 - 1) * 2
temp_points[temp_points_start + out_off + 0][1] = points[i2][1] + dm_x temp_points[temp_points_start + out_off + 0].x = points[i2].x + dm_x
temp_points[temp_points_start + out_off + 0][2] = points[i2][2] + dm_y temp_points[temp_points_start + out_off + 0].y = points[i2].y + dm_y
temp_points[temp_points_start + out_off + 1][1] = points[i2][1] - dm_x temp_points[temp_points_start + out_off + 1].x = points[i2].x - dm_x
temp_points[temp_points_start + out_off + 1][2] = points[i2][2] - dm_y temp_points[temp_points_start + out_off + 1].y = points[i2].y - dm_y
if use_texture then if use_texture then
-- Add indices for two triangles -- Add indices for two triangles
@@ -29603,8 +29603,8 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + 4) local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + 4)
-- Average normals -- Average normals
local dm_x = (temp_normals[i1][1] + temp_normals[i2][1]) * 0.5 local dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5
local dm_y = (temp_normals[i1][2] + temp_normals[i2][2]) * 0.5 local dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5
dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y) dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y)
local dm_out_x = dm_x * (half_inner_thickness + AA_SIZE) local dm_out_x = dm_x * (half_inner_thickness + AA_SIZE)
local dm_out_y = dm_y * (half_inner_thickness + AA_SIZE) local dm_out_y = dm_y * (half_inner_thickness + AA_SIZE)
@@ -29613,14 +29613,14 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
-- Add temporary vertices -- Add temporary vertices
local out_off = (i2 - 1) * 4 local out_off = (i2 - 1) * 4
temp_points[temp_points_start + out_off + 0][1] = points[i2][1] + dm_out_x temp_points[temp_points_start + out_off + 0].x = points[i2].x + dm_out_x
temp_points[temp_points_start + out_off + 0][2] = points[i2][2] + dm_out_y temp_points[temp_points_start + out_off + 0].y = points[i2].y + dm_out_y
temp_points[temp_points_start + out_off + 1][1] = points[i2][1] + dm_in_x temp_points[temp_points_start + out_off + 1].x = points[i2].x + dm_in_x
temp_points[temp_points_start + out_off + 1][2] = points[i2][2] + dm_in_y temp_points[temp_points_start + out_off + 1].y = points[i2].y + dm_in_y
temp_points[temp_points_start + out_off + 2][1] = points[i2][1] - dm_in_x temp_points[temp_points_start + out_off + 2].x = points[i2].x - dm_in_x
temp_points[temp_points_start + out_off + 2][2] = points[i2][2] - dm_in_y temp_points[temp_points_start + out_off + 2].y = points[i2].y - dm_in_y
temp_points[temp_points_start + out_off + 3][1] = points[i2][1] - dm_out_x temp_points[temp_points_start + out_off + 3].x = points[i2].x - dm_out_x
temp_points[temp_points_start + out_off + 3][2] = points[i2][2] - dm_out_y temp_points[temp_points_start + out_off + 3].y = points[i2].y - dm_out_y
-- Add indices -- Add indices
local idx_write_ptr = self._IdxWritePtr local idx_write_ptr = self._IdxWritePtr
@@ -29658,17 +29658,17 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local p1 = points[i1] local p1 = points[i1]
local p2 = points[i2] local p2 = points[i2]
local dx = p2[1] - p1[1] local dx = p2.x - p1.x
local dy = p2[2] - p1[2] local dy = p2.y - p1.y
dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy) dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy)
dx = dx * (thickness * 0.5) dx = dx * (thickness * 0.5)
dy = dy * (thickness * 0.5) dy = dy * (thickness * 0.5)
local vtx_write_ptr = self._VtxWritePtr local vtx_write_ptr = self._VtxWritePtr
vtx_data[vtx_write_ptr + 0][1][1] = p1[1] + dy; vtx_data[vtx_write_ptr + 0][1][2] = p1[2] - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], opaque_uv); vtx_data[vtx_write_ptr + 0][3] = col vtx_data[vtx_write_ptr + 0][1].x = p1.x + dy; vtx_data[vtx_write_ptr + 0][1].y = p1.y - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], opaque_uv); vtx_data[vtx_write_ptr + 0][3] = col
vtx_data[vtx_write_ptr + 1][1][1] = p2[1] + dy; vtx_data[vtx_write_ptr + 1][1][2] = p2[2] - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], opaque_uv); vtx_data[vtx_write_ptr + 1][3] = col vtx_data[vtx_write_ptr + 1][1].x = p2.x + dy; vtx_data[vtx_write_ptr + 1][1].y = p2.y - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], opaque_uv); vtx_data[vtx_write_ptr + 1][3] = col
vtx_data[vtx_write_ptr + 2][1][1] = p2[1] - dy; vtx_data[vtx_write_ptr + 2][1][2] = p2[2] + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], opaque_uv); vtx_data[vtx_write_ptr + 2][3] = col vtx_data[vtx_write_ptr + 2][1].x = p2.x - dy; vtx_data[vtx_write_ptr + 2][1].y = p2.y + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], opaque_uv); vtx_data[vtx_write_ptr + 2][3] = col
vtx_data[vtx_write_ptr + 3][1][1] = p1[1] - dy; vtx_data[vtx_write_ptr + 3][1][2] = p1[2] + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], opaque_uv); vtx_data[vtx_write_ptr + 3][3] = col vtx_data[vtx_write_ptr + 3][1].x = p1.x - dy; vtx_data[vtx_write_ptr + 3][1].y = p1.y + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], opaque_uv); vtx_data[vtx_write_ptr + 3][3] = col
self._VtxWritePtr = vtx_write_ptr + 4 self._VtxWritePtr = vtx_write_ptr + 4
local idx_write_ptr = self._IdxWritePtr local idx_write_ptr = self._IdxWritePtr
@@ -30405,10 +30405,10 @@ function MT.ImFont:RenderText(draw_list, size, pos, col, clip_rect, text, text_b
local glyph_col = glyph.Colored and color_untinted or col local glyph_col = glyph.Colored and color_untinted or col
do do
local vtx0 = vtx_data[vtx_write + 0]; vtx0[1][1] = x1; vtx0[1][2] = y1; vtx0[3] = glyph_col; vtx0[2][1] = u1; vtx0[2][2] = v1; local vtx0 = vtx_data[vtx_write + 0]; vtx0[1].x = x1; vtx0[1].y = y1; vtx0[3] = glyph_col; vtx0[2].x = u1; vtx0[2].y = v1;
local vtx1 = vtx_data[vtx_write + 1]; vtx1[1][1] = x2; vtx1[1][2] = y1; vtx1[3] = glyph_col; vtx1[2][1] = u2; vtx1[2][2] = v1; local vtx1 = vtx_data[vtx_write + 1]; vtx1[1].x = x2; vtx1[1].y = y1; vtx1[3] = glyph_col; vtx1[2].x = u2; vtx1[2].y = v1;
local vtx2 = vtx_data[vtx_write + 2]; vtx2[1][1] = x2; vtx2[1][2] = y2; vtx2[3] = glyph_col; vtx2[2][1] = u2; vtx2[2][2] = v2; local vtx2 = vtx_data[vtx_write + 2]; vtx2[1].x = x2; vtx2[1].y = y2; vtx2[3] = glyph_col; vtx2[2].x = u2; vtx2[2].y = v2;
local vtx3 = vtx_data[vtx_write + 3]; vtx3[1][1] = x1; vtx3[1][2] = y2; vtx3[3] = glyph_col; vtx3[2][1] = u1; vtx3[2][2] = v2; local vtx3 = vtx_data[vtx_write + 3]; vtx3[1].x = x1; vtx3[1].y = y2; vtx3[3] = glyph_col; vtx3[2].x = u1; vtx3[2].y = v2;
idx_data[idx_write + 0] = vtx_index; idx_data[idx_write + 1] = vtx_index + 1; idx_data[idx_write + 2] = vtx_index + 2; idx_data[idx_write + 0] = vtx_index; idx_data[idx_write + 1] = vtx_index + 1; idx_data[idx_write + 2] = vtx_index + 2;
idx_data[idx_write + 3] = vtx_index; idx_data[idx_write + 4] = vtx_index + 2; idx_data[idx_write + 5] = vtx_index + 3; idx_data[idx_write + 3] = vtx_index; idx_data[idx_write + 4] = vtx_index + 2; idx_data[idx_write + 5] = vtx_index + 3;
vtx_write = vtx_write + 4 vtx_write = vtx_write + 4
@@ -31092,8 +31092,8 @@ ImGuiMouseCursor =
--- @return ImTextureRect --- @return ImTextureRect
function ImTextureRect(x, y, w, h) return { x = x, y = y, w = w, h = h } end function ImTextureRect(x, y, w, h) return { x = x, y = y, w = w, h = h } end
-- This structure supports indexing on string keys `x`, `y` and number keys 1, 2. -- [Luau] Stored as named fields {x=, y=} so the common `.x`/`.y` access is a plain table read (no metamethod call).
-- But note that the former is likely to be more expensive. -- Numeric keys 1, 2 still work through the metatable, but are slower: prefer .x/.y in hot code.
--- @class ImVec2 --- @class ImVec2
--- @operator add(ImVec2): ImVec2 --- @operator add(ImVec2): ImVec2
--- @operator sub(ImVec2): ImVec2 --- @operator sub(ImVec2): ImVec2
@@ -31101,146 +31101,97 @@ function ImTextureRect(x, y, w, h) return { x = x, y = y, w = w, h = h } end
--- @operator mul(ImVec2): ImVec2 --- @operator mul(ImVec2): ImVec2
--- @operator div(number): ImVec2 --- @operator div(number): ImVec2
--- @operator div(ImVec2): ImVec2 --- @operator div(ImVec2): ImVec2
--- @field [1] number
--- @field [2] number
--- @field x number --- @field x number
--- @field y number --- @field y number
local IM_VEC2 = {} local IM_VEC2 = {}
local VEC2_KEYS = { "x", "y" }
--- @param t ImVec2
--- @param k string
IM_VEC2.__index = function(t, k) IM_VEC2.__index = function(t, k)
if k == "x" then return rawget(t, 1) local n = VEC2_KEYS[k]
elseif k == "y" then return rawget(t, 2) if n then return rawget(t, n) end
end
end end
--- @param t ImVec2
--- @param k string
--- @param v number
IM_VEC2.__newindex = function(t, k, v) IM_VEC2.__newindex = function(t, k, v)
if k == "x" then rawset(t, 1, v) local n = VEC2_KEYS[k]
elseif k == "y" then rawset(t, 2, v) IM_ASSERT(n ~= nil)
else IM_ASSERT(false) rawset(t, n, v)
end
end end
--- @param x? number --- @param x? number
--- @param y? number --- @param y? number
--- @return ImVec2 --- @return ImVec2
--- @nodiscard --- @nodiscard
function ImVec2(x, y) return setmetatable({x or 0, y or 0}, IM_VEC2) end function ImVec2(x, y) return setmetatable({ x = x or 0, y = y or 0 }, IM_VEC2) end
function IM_VEC2.__add(lhs, rhs) return ImVec2(lhs[1] + rhs[1], lhs[2] + rhs[2]) end function IM_VEC2.__add(lhs, rhs) return setmetatable({ x = lhs.x + rhs.x, y = lhs.y + rhs.y }, IM_VEC2) end
function IM_VEC2.__sub(lhs, rhs) return ImVec2(lhs[1] - rhs[1], lhs[2] - rhs[2]) end function IM_VEC2.__sub(lhs, rhs) return setmetatable({ x = lhs.x - rhs.x, y = lhs.y - rhs.y }, IM_VEC2) end
--- @overload fun(lhs: ImVec2, rhs: number): ImVec2
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function IM_VEC2.__mul(lhs, rhs) function IM_VEC2.__mul(lhs, rhs)
if type(lhs) == "table" and type(rhs) == "number" then return ImVec2(lhs[1] * rhs, lhs[2] * rhs) if type(rhs) == "number" then return setmetatable({ x = lhs.x * rhs, y = lhs.y * rhs }, IM_VEC2) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(lhs[1] * rhs[1], lhs[2] * rhs[2]) return setmetatable({ x = lhs.x * rhs.x, y = lhs.y * rhs.y }, IM_VEC2)
end
end end
--- @overload fun(lhs: ImVec2, rhs: number): ImVec2
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function IM_VEC2.__div(lhs, rhs) function IM_VEC2.__div(lhs, rhs)
if type(lhs) == "table" and type(rhs) == "number" then return ImVec2(lhs[1] / rhs, lhs[2] / rhs) if type(rhs) == "number" then return setmetatable({ x = lhs.x / rhs, y = lhs.y / rhs }, IM_VEC2) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(lhs[1] / rhs[1], lhs[2] / rhs[2]) return setmetatable({ x = lhs.x / rhs.x, y = lhs.y / rhs.y }, IM_VEC2)
end
end end
function IM_VEC2.__eq(lhs, rhs) return lhs[1] == rhs[1] and lhs[2] == rhs[2] end function IM_VEC2.__eq(lhs, rhs) return lhs.x == rhs.x and lhs.y == rhs.y end
function IM_VEC2:__tostring() return string.format("ImVec2(%g, %g)", self.x, self.y) end function IM_VEC2:__tostring() return string.format("ImVec2(%g, %g)", self.x, self.y) end
--- @param dest ImVec2 --- @param dest ImVec2
--- @param src ImVec2 --- @param src ImVec2
function ImVec2_Copy(dest, src) dest[1] = src[1]; dest[2] = src[2] end function ImVec2_Copy(dest, src) dest.x = src.x; dest.y = src.y end
--- @param dest ImVec2 function ImVec2_CopyV(dest, src_x, src_y) dest.x = src_x; dest.y = src_y end
--- @param src_x number
--- @param src_y number
function ImVec2_CopyV(dest, src_x, src_y) dest[1] = src_x; dest[2] = src_y end
--- @param v ImVec2 function ImVec2_AddVA(v, add_x, add_y) return v.x + add_x, v.y + add_y end
--- @param add_x number
--- @param add_y number
function ImVec2_AddVA(v, add_x, add_y) return v[1] + add_x, v[2] + add_y end
--- @param v ImVec2 function ImVec2_SubVA(v, sub_x, sub_y) return v.x - sub_x, v.y - sub_y end
--- @param sub_x number
--- @param sub_y number
function ImVec2_SubVA(v, sub_x, sub_y) return v[1] - sub_x, v[2] - sub_y end
--- @param a ImVec2 function ImVec2_MulVX(a, scalar) return a.x * scalar, a.y * scalar end
--- @param scalar number
function ImVec2_MulVX(a, scalar)
return a[1] * scalar, a[2] * scalar
end
--- An inlined version of `ImVec2_Copy` currently for use in certain ImVector<ImVec2> `push_back` --- An inlined version of `ImVec2_Copy` currently for use in certain ImVector<ImVec2> `push_back`
--- @param t ImVec2[] local function ImVec2_TCopy(t, k, v) local dest = t[k]; dest.x = v.x; dest.y = v.y; end
--- @param k int
--- @param v ImVec2
local function ImVec2_TCopy(t, k, v) local dest = t[k]; dest[1] = v[1]; dest[2] = v[2]; end
-- This structure supports indexing on string keys `x`, `y`, `z`, `w` and number keys 1, 2, 3, 4. -- [Luau] Same layout as ImVec2: named fields x, y, z, w; numeric keys 1..4 go through the metatable.
-- But note that the former is likely to be more expensive.
--- @class ImVec4 --- @class ImVec4
--- @operator add(ImVec4): ImVec4 --- @operator add(ImVec4): ImVec4
--- @operator sub(ImVec4): ImVec4 --- @operator sub(ImVec4): ImVec4
--- @operator mul(number): ImVec4 --- @operator mul(number): ImVec4
--- @field [1] number
--- @field [2] number
--- @field [3] number
--- @field [4] number
--- @field x number --- @field x number
--- @field y number --- @field y number
--- @field z number --- @field z number
--- @field w number --- @field w number
local IM_VEC4 = {} local IM_VEC4 = {}
local VEC4_KEYS = { "x", "y", "z", "w" }
--- @param t ImVec4
--- @param k string
IM_VEC4.__index = function(t, k) IM_VEC4.__index = function(t, k)
if k == "x" then return rawget(t, 1) local n = VEC4_KEYS[k]
elseif k == "y" then return rawget(t, 2) if n then return rawget(t, n) end
elseif k == "z" then return rawget(t, 3)
elseif k == "w" then return rawget(t, 4)
end
end end
--- @param t ImVec4
--- @param k string
--- @param v number
IM_VEC4.__newindex = function(t, k, v) IM_VEC4.__newindex = function(t, k, v)
if k == "x" then rawset(t, 1, v) local n = VEC4_KEYS[k]
elseif k == "y" then rawset(t, 2, v) IM_ASSERT(n ~= nil)
elseif k == "z" then rawset(t, 3, v) rawset(t, n, v)
elseif k == "w" then rawset(t, 4, v)
else IM_ASSERT(false)
end
end end
--- @param x? number
--- @param y? number
--- @param z? number
--- @param w? number
--- @return ImVec4 --- @return ImVec4
--- @nodiscard --- @nodiscard
function ImVec4(x, y, z, w) return setmetatable({x or 0, y or 0, z or 0, w or 0}, IM_VEC4) end function ImVec4(x, y, z, w) return setmetatable({ x = x or 0, y = y or 0, z = z or 0, w = w or 0 }, IM_VEC4) end
function IM_VEC4.__add(lhs, rhs) return ImVec4(lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3], lhs[4] + rhs[4]) end function IM_VEC4.__add(lhs, rhs) return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w) end
function IM_VEC4.__sub(lhs, rhs) return ImVec4(lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3], lhs[4] - rhs[4]) end function IM_VEC4.__sub(lhs, rhs) return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w) end
function IM_VEC4.__mul(lhs, rhs) return ImVec4(lhs[1] * rhs, lhs[2] * rhs, lhs[3] * rhs, lhs[4] * rhs) end function IM_VEC4.__mul(lhs, rhs) return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs) end
function IM_VEC4.__eq(lhs, rhs) return lhs[1] == rhs[1] and lhs[2] == rhs[2] and lhs[3] == rhs[3] and lhs[4] == rhs[4] end function IM_VEC4.__eq(lhs, rhs) return lhs.x == rhs.x and lhs.y == rhs.y and lhs.z == rhs.z and lhs.w == rhs.w end
function IM_VEC4:__tostring() return string.format("ImVec4(%g, %g, %g, %g)", self.x, self.y, self.z, self.w) end function IM_VEC4:__tostring() return string.format("ImVec4(%g, %g, %g, %g)", self.x, self.y, self.z, self.w) end
--- @param dest ImVec4 --- @param dest ImVec4
--- @param src ImVec4 --- @param src ImVec4
function ImVec4_Copy(dest, src) dest[1] = src[1]; dest[2] = src[2]; dest[3] = src[3]; dest[4] = src[4] end function ImVec4_Copy(dest, src) dest.x = src.x; dest.y = src.y; dest.z = src.z; dest.w = src.w end
--- A compact ImVector clone --- A compact ImVector clone
--- @class ImVector<T> --- @class ImVector<T>
@@ -31255,8 +31206,10 @@ local IM_VECTOR = {}
--- @param k string|int --- @param k string|int
--- @return any --- @return any
IM_VECTOR.__index = function(t, k) IM_VECTOR.__index = function(t, k)
local m = IM_VECTOR[k] -- methods first (hot path)
if m ~= nil then return m end
if k == "Data" then return nil end -- Data has already been discarded if k == "Data" then return nil end -- Data has already been discarded
return IM_VECTOR[k] or t.Data[IM_ASSERT(k >= 1 and k <= t.Size) or k] -- if the mt access turns out nil, the k must be int index into Data return t.Data[IM_ASSERT(k >= 1 and k <= t.Size) or k] -- if the mt access turns out nil, the k must be int index into Data
end end
--- @param t ImVector --- @param t ImVector
@@ -33455,9 +33408,9 @@ end
-- Generic triangle: per-vertex colour + uv, top-left fill rule, clipped to [cx0, cx1) x [cy0, cy1) -- Generic triangle: per-vertex colour + uv, top-left fill rule, clipped to [cx0, cx1) x [cy0, cy1)
@native @native
local function DrawTriangle(va, vb, vc, t, cx0, cy0, cx1, cy1, ox, oy) local function DrawTriangle(va, vb, vc, t, cx0, cy0, cx1, cy1, ox, oy)
local x0, y0 = va[1][1] - ox, va[1][2] - oy local x0, y0 = va[1].x - ox, va[1].y - oy
local x1, y1 = vb[1][1] - ox, vb[1][2] - oy local x1, y1 = vb[1].x - ox, vb[1].y - oy
local x2, y2 = vc[1][1] - ox, vc[1][2] - oy local x2, y2 = vc[1].x - ox, vc[1].y - oy
local area = (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0) local area = (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)
if area == 0 then return end if area == 0 then return end
if area < 0 then -- make the winding consistent so "inside" means all edge functions >= 0 if area < 0 then -- make the winding consistent so "inside" means all edge functions >= 0
@@ -33482,7 +33435,7 @@ local function DrawTriangle(va, vb, vc, t, cx0, cy0, cx1, cy1, ox, oy)
local ra, ga, ba, aa = UnpackColor(va[3]) local ra, ga, ba, aa = UnpackColor(va[3])
local rb, gb, bb, ab = UnpackColor(vb[3]) local rb, gb, bb, ab = UnpackColor(vb[3])
local rc, gc, bc, ac = UnpackColor(vc[3]) local rc, gc, bc, ac = UnpackColor(vc[3])
local ua, vva, ub, vvb, uc, vvc = va[2][1], va[2][2], vb[2][1], vb[2][2], vc[2][1], vc[2][2] local ua, vva, ub, vvb, uc, vvc = va[2].x, va[2].y, vb[2].x, vb[2].y, vc[2].x, vc[2].y
local textured = t and not (ua == ub and ua == uc and vva == vvb and vva == vvc) local textured = t and not (ua == ub and ua == uc and vva == vvb and vva == vvc)
if t and not textured then -- constant uv (e.g. the atlas white pixel): fold the texel into the vertex colours if t and not textured then -- constant uv (e.g. the atlas white pixel): fold the texel into the vertex colours
@@ -33533,12 +33486,12 @@ end
@native @native
local function TryDrawRect(va, vb, vc, vd, t, cx0, cy0, cx1, cy1, ox, oy) local function TryDrawRect(va, vb, vc, vd, t, cx0, cy0, cx1, cy1, ox, oy)
local pa, pb, pc, pd = va[1], vb[1], vc[1], vd[1] local pa, pb, pc, pd = va[1], vb[1], vc[1], vd[1]
if not (pa[2] == pb[2] and pb[1] == pc[1] and pc[2] == pd[2] and pd[1] == pa[1] and pa[1] < pb[1] and pa[2] < pd[2]) then return false end if not (pa.y == pb.y and pb.x == pc.x and pc.y == pd.y and pd.x == pa.x and pa.x < pb.x and pa.y < pd.y) then return false end
local col = va[3] local col = va[3]
if vb[3] ~= col or vc[3] ~= col or vd[3] ~= col then return false end if vb[3] ~= col or vc[3] ~= col or vd[3] ~= col then return false end
local ta, tb, tc, td = va[2], vb[2], vc[2], vd[2] local ta, tb, tc, td = va[2], vb[2], vc[2], vd[2]
if not (tb[1] == tc[1] and tb[2] == ta[2] and td[1] == ta[1] and td[2] == tc[2]) then return false end if not (tb.x == tc.x and tb.y == ta.y and td.x == ta.x and td.y == tc.y) then return false end
DrawRect(pa[1] - ox, pa[2] - oy, pc[1] - ox, pc[2] - oy, ta[1], ta[2], tc[1], tc[2], col, t, cx0, cy0, cx1, cy1) DrawRect(pa.x - ox, pa.y - oy, pc.x - ox, pc.y - oy, ta.x, ta.y, tc.x, tc.y, col, t, cx0, cy0, cx1, cy1)
return true return true
end end
@@ -33557,8 +33510,8 @@ local pr_cx0, pr_cy0, pr_cx1, pr_cy1 = {}, {}, {}, {} -- clip (screen pixels)
@native @native
local function HashVertex(h1, h2, v) local function HashVertex(h1, h2, v)
local p, u, c = v[1], v[2], v[3] local p, u, c = v[1], v[2], v[3]
local x, y = p[1], p[2] local x, y = p.x, p.y
local uv = u[1] * 8192 + u[2] local uv = u.x * 8192 + u.y
h1 = (h1 * 48271 + x * 4096 + y) % P1 h1 = (h1 * 48271 + x * 4096 + y) % P1
h1 = (h1 * 48271 + uv * 4096) % P1 h1 = (h1 * 48271 + uv * 4096) % P1
h1 = (h1 * 48271 + c) % P1 h1 = (h1 * 48271 + c) % P1
@@ -33670,22 +33623,22 @@ function ImGui_ImplRoblox_RenderDrawData(draw_data)
local d = vtx[vo + idx[i + 5]] local d = vtx[vo + idx[i + 5]]
local pd = d[1] local pd = d[1]
-- axis aligned quad (TL, TR, BR, BL) with one colour and a matching uv rect -- axis aligned quad (TL, TR, BR, BL) with one colour and a matching uv rect
if pa[2] == pb[2] and pb[1] == pc[1] and pc[2] == pd[2] and pd[1] == pa[1] and pa[1] < pb[1] and pa[2] < pd[2] then if pa.y == pb.y and pb.x == pc.x and pc.y == pd.y and pd.x == pa.x and pa.x < pb.x and pa.y < pd.y then
local col = va[3] local col = va[3]
local ta, tb, tc, td = va[2], vb[2], vc[2], d[2] local ta, tb, tc, td = va[2], vb[2], vc[2], d[2]
if vb[3] == col and vc[3] == col and d[3] == col if vb[3] == col and vc[3] == col and d[3] == col
and tb[1] == tc[1] and tb[2] == ta[2] and td[1] == ta[1] and td[2] == tc[2] then and tb.x == tc.x and tb.y == ta.y and td.x == ta.x and td.y == tc.y then
vd = d vd = d
bx0, by0 = ceil(pa[1] - ox - 0.5), ceil(pa[2] - oy - 0.5) bx0, by0 = ceil(pa.x - ox - 0.5), ceil(pa.y - oy - 0.5)
bx1, by1 = ceil(pc[1] - ox - 0.5), ceil(pc[2] - oy - 0.5) bx1, by1 = ceil(pc.x - ox - 0.5), ceil(pc.y - oy - 0.5)
end end
end end
end end
if vd then if vd then
i = i + 6 i = i + 6
else else
bx0, by0 = floor(min(pa[1], pb[1], pc[1]) - ox), floor(min(pa[2], pb[2], pc[2]) - oy) bx0, by0 = floor(min(pa.x, pb.x, pc.x) - ox), floor(min(pa.y, pb.y, pc.y) - oy)
bx1, by1 = ceil(max(pa[1], pb[1], pc[1]) - ox) + 1, ceil(max(pa[2], pb[2], pc[2]) - oy) + 1 bx1, by1 = ceil(max(pa.x, pb.x, pc.x) - ox) + 1, ceil(max(pa.y, pb.y, pc.y) - oy) + 1
i = i + 3 i = i + 3
end end
if bx0 < cx0 then bx0 = cx0 end if bx0 < cx0 then bx0 = cx0 end
@@ -33751,7 +33704,7 @@ function ImGui_ImplRoblox_RenderDrawData(draw_data)
local va, vc, vd = pr_a[p], pr_c[p], pr_d[p] local va, vc, vd = pr_a[p], pr_c[p], pr_d[p]
if vd then if vd then
local pa, pc, ta, tc = va[1], vc[1], va[2], vc[2] local pa, pc, ta, tc = va[1], vc[1], va[2], vc[2]
DrawRect(pa[1] - tox, pa[2] - toy, pc[1] - tox, pc[2] - toy, ta[1], ta[2], tc[1], tc[2], va[3], pr_t[p], cx0, cy0, cx1, cy1) DrawRect(pa.x - tox, pa.y - toy, pc.x - tox, pc.y - toy, ta.x, ta.y, tc.x, tc.y, va[3], pr_t[p], cx0, cy0, cx1, cy1)
else else
DrawTriangle(va, pr_b[p], vc, pr_t[p], cx0, cy0, cx1, cy1, tox, toy) DrawTriangle(va, pr_b[p], vc, pr_t[p], cx0, cy0, cx1, cy1, tox, toy)
end end
@@ -40480,17 +40433,15 @@ end
--- @overload fun(lhs: number, rhs: number): number --- @overload fun(lhs: number, rhs: number): number
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2 --- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function ImMin(lhs, rhs) function ImMin(lhs, rhs)
if type(lhs) == "number" and type(rhs) == "number" then return mathMin(lhs, rhs) if type(lhs) == "number" then return mathMin(lhs, rhs) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(mathMin(lhs[1], rhs[1]), mathMin(lhs[2], rhs[2])) return ImVec2(mathMin(lhs.x, rhs.x), mathMin(lhs.y, rhs.y))
end
end end
--- @overload fun(lhs: number, rhs: number): number --- @overload fun(lhs: number, rhs: number): number
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2 --- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function ImMax(lhs, rhs) function ImMax(lhs, rhs)
if type(lhs) == "number" and type(rhs) == "number" then return mathMax(lhs, rhs) if type(lhs) == "number" then return mathMax(lhs, rhs) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(mathMax(lhs[1], rhs[1]), mathMax(lhs[2], rhs[2])) return ImVec2(mathMax(lhs.x, rhs.x), mathMax(lhs.y, rhs.y))
end
end end
--- @param base table --- @param base table
@@ -40502,7 +40453,7 @@ ImStd.ImQsort = function(base, count, cmp_func) if count > 0 then t_sort(base, c
--- @overload fun(v: ImVec2, mn: ImVec2, mx: ImVec2): ImVec2 --- @overload fun(v: ImVec2, mn: ImVec2, mx: ImVec2): ImVec2
function ImClamp(v, mn, mx) function ImClamp(v, mn, mx)
if type(v) == "number" and type(mn) == "number" and type(mx) == "number" then return mathMin(mathMax(v, mn), mx) if type(v) == "number" and type(mn) == "number" and type(mx) == "number" then return mathMin(mathMax(v, mn), mx)
elseif type(v) == "table" and type(mn) == "table" and type(mx) == "table" then return ImVec2(mathMax(mn[1], mathMin(v[1], mx[1])), mathMax(mn[2], mathMin(v[2], mx[2]))) elseif type(v) == "table" and type(mn) == "table" and type(mx) == "table" then return ImVec2(mathMax(mn.x, mathMin(v.x, mx.x)), mathMax(mn.y, mathMin(v.y, mx.y)))
end end
end end
@@ -40511,8 +40462,8 @@ end
--- @overload fun(a: ImVec2, b: ImVec2, t: ImVec2): ImVec2 --- @overload fun(a: ImVec2, b: ImVec2, t: ImVec2): ImVec2
function ImLerp(a, b, t) function ImLerp(a, b, t)
if type(a) == "number" and type(b) == "number" and type(t) == "number" then return ((a) + ((b) - (a)) * (t)) if type(a) == "number" and type(b) == "number" and type(t) == "number" then return ((a) + ((b) - (a)) * (t))
elseif type(a) == "table" and type(b) == "table" and type(t) == "number" then return ImVec2(a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t) elseif type(a) == "table" and type(b) == "table" and type(t) == "number" then return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t)
elseif type(a) == "table" and type(b) == "table" and type(t) == "table" then return ImVec2(a[1] + (b[1] - a[1]) * t[1], a[2] + (b[2] - a[2]) * t[2]) elseif type(a) == "table" and type(b) == "table" and type(t) == "table" then return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y)
end end
end end
@@ -40522,7 +40473,7 @@ local function _Trunc(val) if val >= 0 then return mathFloor(val) else return ma
--- @overload fun(v: ImVec2): ImVec2 --- @overload fun(v: ImVec2): ImVec2
function ImTrunc(v) function ImTrunc(v)
if type(v) == "number" then return _Trunc(v) if type(v) == "number" then return _Trunc(v)
elseif type(v) == "table" then return ImVec2(_Trunc(v[1]), _Trunc(v[2])) elseif type(v) == "table" then return ImVec2(_Trunc(v.x), _Trunc(v.y))
end end
end end
@@ -41012,150 +40963,138 @@ end
--- @field Min ImVec2 --- @field Min ImVec2
--- @field Max ImVec2 --- @field Max ImVec2
local IM_RECT = {} local IM_RECT = {}
setmetatable(IM_RECT, { __index = function(_, k) if k ~= "Min" and k ~= "Max" then error("ImRect: unknown key " .. tostring(k), 2) end end })
--- @param t ImRect --- @param t ImRect
--- @param k string --- @param k string
IM_RECT.__index = function(t, k) IM_RECT.__index = IM_RECT -- [Luau] plain table: fast method lookup. Use r.Min / r.Max (numeric r[1]/r[2] are not supported)
local method = IM_RECT[k]
if method ~= nil then return method end
if k == "Min" then return rawget(t, 1)
elseif k == "Max" then return rawget(t, 2)
end
end
--- @param t ImRect -- [Luau] Min/Max are named fields, so `r.Min = v` assigns the reference: use ImVec2_Copy(r.Min, v) to keep copy semantics
--- @param k string IM_RECT.__newindex = function(t, k, v) IM_ASSERT(false, "ImRect: unknown field " .. tostring(k)) end
--- @param v ImVec2
IM_RECT.__newindex = function(t, k, v)
if k == "Min" then ImVec2_Copy(rawget(t, 1), v)
elseif k == "Max" then ImVec2_Copy(rawget(t, 2), v)
else IM_ASSERT(false)
end
end
--- @return ImRect --- @return ImRect
--- @nodiscard --- @nodiscard
function ImRect(a, b, c, d) if c and d then return setmetatable({ ImVec2(a, b), ImVec2(c, d) }, IM_RECT) end return setmetatable({ ImVec2(a and a.x or 0, a and a.y or 0), ImVec2(b and b.x or 0, b and b.y or 0) }, IM_RECT) end function ImRect(a, b, c, d) if c and d then return setmetatable({ Min = ImVec2(a, b), Max = ImVec2(c, d) }, IM_RECT) end return setmetatable({ Min = ImVec2(a and a.x or 0, a and a.y or 0), Max = ImVec2(b and b.x or 0, b and b.y or 0) }, IM_RECT) end
function IM_RECT:__eq(other) return self[1] == other[1] and self[2] == other[2] end function IM_RECT:__eq(other) return self.Min == other.Min and self.Max == other.Max end
function IM_RECT:__tostring() return string.format("ImRect(Min: %g,%g, Max: %g,%g)", self.Min.x, self.Min.y, self.Max.x, self.Max.y) end function IM_RECT:__tostring() return string.format("ImRect(Min: %g,%g, Max: %g,%g)", self.Min.x, self.Min.y, self.Max.x, self.Max.y) end
--- @param p ImRect|ImVec2 --- @param p ImRect|ImVec2
function IM_RECT:Contains(p) function IM_RECT:Contains(p)
if p.Min then if p.Min then
--- @cast p ImRect --- @cast p ImRect
return p[1][1] >= self[1][1] and p[2][1] <= self[2][1] and p[1][2] >= self[1][2] and p[2][2] <= self[2][2] return p.Min.x >= self.Min.x and p.Max.x <= self.Max.x and p.Min.y >= self.Min.y and p.Max.y <= self.Max.y
else else
--- @cast p ImVec2 --- @cast p ImVec2
return p[1] >= self[1][1] and p[2] >= self[1][2] and p[1] < self[2][1] and p[2] < self[2][2] return p.x >= self.Min.x and p.y >= self.Min.y and p.x < self.Max.x and p.y < self.Max.y
end end
end end
--- @param p ImVec2 --- @param p ImVec2
--- @param pad ImVec2 --- @param pad ImVec2
function IM_RECT:ContainsWithPad(p, pad) function IM_RECT:ContainsWithPad(p, pad)
return p[1] >= self[1][1] - pad[1] and p[2] >= self[1][2] - pad[2] and p[1] < self[2][1] + pad[1] and p[2] < self[2][2] + pad[2] return p.x >= self.Min.x - pad.x and p.y >= self.Min.y - pad.y and p.x < self.Max.x + pad.x and p.y < self.Max.y + pad.y
end end
--- @param r ImRect --- @param r ImRect
function IM_RECT:Overlaps(r) function IM_RECT:Overlaps(r)
return self[1][1] <= r[2][1] and self[2][1] >= r[1][1] and self[1][2] <= r[2][2] and self[2][2] >= r[1][2] return self.Min.x <= r.Max.x and self.Max.x >= r.Min.x and self.Min.y <= r.Max.y and self.Max.y >= r.Min.y
end end
--- @nodiscard --- @nodiscard
function IM_RECT:GetCenter() return ImVec2((self[1][1] + self[2][1]) * 0.5, (self[1][2] + self[2][2]) * 0.5) end function IM_RECT:GetCenter() return ImVec2((self.Min.x + self.Max.x) * 0.5, (self.Min.y + self.Max.y) * 0.5) end
function IM_RECT:GetWidth() return self[2][1] - self[1][1] end function IM_RECT:GetWidth() return self.Max.x - self.Min.x end
function IM_RECT:GetHeight() return self[2][2] - self[1][2] end function IM_RECT:GetHeight() return self.Max.y - self.Min.y end
--- @nodiscard --- @nodiscard
function IM_RECT:GetSize() return ImVec2(self[2][1] - self[1][1], self[2][2] - self[1][2]) end function IM_RECT:GetSize() return ImVec2(self.Max.x - self.Min.x, self.Max.y - self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetTL() return ImVec2(self[1][1], self[1][2]) end function IM_RECT:GetTL() return ImVec2(self.Min.x, self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetTR() return ImVec2(self[2][1], self[1][2]) end function IM_RECT:GetTR() return ImVec2(self.Max.x, self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetBL() return ImVec2(self[1][1], self[2][2]) end function IM_RECT:GetBL() return ImVec2(self.Min.x, self.Max.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetBR() return ImVec2(self[2][1], self[2][2]) end function IM_RECT:GetBR() return ImVec2(self.Max.x, self.Max.y) end
--- @param r ImRect --- @param r ImRect
function IM_RECT:ClipWith(r) function IM_RECT:ClipWith(r)
ImVec2_Copy(self[1], ImMax(self[1], r[1])); ImVec2_Copy(self[2], ImMin(self[2], r[2])) ImVec2_Copy(self.Min, ImMax(self.Min, r.Min)); ImVec2_Copy(self.Max, ImMin(self.Max, r.Max))
end end
--- @param r ImRect --- @param r ImRect
function IM_RECT:ClipWithFull(r) function IM_RECT:ClipWithFull(r)
ImVec2_Copy(self[1], ImClamp(self[1], r[1], r[2])); ImVec2_Copy(self[2], ImClamp(self[2], r[1], r[2])) ImVec2_Copy(self.Min, ImClamp(self.Min, r.Min, r.Max)); ImVec2_Copy(self.Max, ImClamp(self.Max, r.Min, r.Max))
end end
--- @param p ImRect|ImVec2 --- @param p ImRect|ImVec2
function IM_RECT:Add(p) function IM_RECT:Add(p)
if p.Min then if p.Min then
--- @cast p ImRect --- @cast p ImRect
if (self[1][1] > p[1][1]) then self[1][1] = p[1][1] end if (self.Min.x > p.Min.x) then self.Min.x = p.Min.x end
if (self[1][2] > p[1][2]) then self[1][2] = p[1][2] end if (self.Min.y > p.Min.y) then self.Min.y = p.Min.y end
if (self[2][1] < p[2][1]) then self[2][1] = p[2][1] end if (self.Max.x < p.Max.x) then self.Max.x = p.Max.x end
if (self[2][2] < p[2][2]) then self[2][2] = p[2][2] end if (self.Max.y < p.Max.y) then self.Max.y = p.Max.y end
else else
--- @cast p ImVec2 --- @cast p ImVec2
if p[1] < self[1][1] then self[1][1] = p[1] end if p.x < self.Min.x then self.Min.x = p.x end
if p[2] < self[1][2] then self[1][2] = p[2] end if p.y < self.Min.y then self.Min.y = p.y end
if p[1] > self[2][1] then self[2][1] = p[1] end if p.x > self.Max.x then self.Max.x = p.x end
if p[2] > self[2][2] then self[2][2] = p[2] end if p.y > self.Max.y then self.Max.y = p.y end
end end
end end
--- @param amount float|ImVec2 --- @param amount float|ImVec2
function IM_RECT:Expand(amount) function IM_RECT:Expand(amount)
if type(amount) == "number" then if type(amount) == "number" then
self[1][1] = self[1][1] - amount; self[1][2] = self[1][2] - amount self.Min.x = self.Min.x - amount; self.Min.y = self.Min.y - amount
self[2][1] = self[2][1] + amount; self[2][2] = self[2][2] + amount self.Max.x = self.Max.x + amount; self.Max.y = self.Max.y + amount
elseif type(amount) == "table" then elseif type(amount) == "table" then
self[1][1] = self[1][1] - amount[1]; self[1][2] = self[1][2] - amount[2] self.Min.x = self.Min.x - amount.x; self.Min.y = self.Min.y - amount.y
self[2][1] = self[2][1] + amount[1]; self[2][2] = self[2][2] + amount[2] self.Max.x = self.Max.x + amount.x; self.Max.y = self.Max.y + amount.y
end end
end end
--- @nodiscard --- @nodiscard
function IM_RECT:ToVec4() function IM_RECT:ToVec4()
return ImVec4(self[1][1], self[1][2], self[2][1], self[2][2]) return ImVec4(self.Min.x, self.Min.y, self.Max.x, self.Max.y)
end end
--- @param d ImVec2 --- @param d ImVec2
function IM_RECT:Translate(d) function IM_RECT:Translate(d)
self[1][1] = self[1][1] + d[1]; self[1][2] = self[1][2] + d[2] self.Min.x = self.Min.x + d.x; self.Min.y = self.Min.y + d.y
self[2][1] = self[2][1] + d[1]; self[2][2] = self[2][2] + d[2] self.Max.x = self.Max.x + d.x; self.Max.y = self.Max.y + d.y
end end
--- @param dx float --- @param dx float
function IM_RECT:TranslateX(dx) function IM_RECT:TranslateX(dx)
self[1][1] = self[1][1] + dx; self[2][1] = self[2][1] + dx self.Min.x = self.Min.x + dx; self.Max.x = self.Max.x + dx
end end
--- @param dy float --- @param dy float
function IM_RECT:TranslateY(dy) function IM_RECT:TranslateY(dy)
self[1][2] = self[1][2] + dy; self[2][2] = self[2][2] + dy self.Min.y = self.Min.y + dy; self.Max.y = self.Max.y + dy
end end
function IM_RECT:IsInverted() return self[1][1] > self[2][1] or self[1][2] > self[2][2] end function IM_RECT:IsInverted() return self.Min.x > self.Max.x or self.Min.y > self.Max.y end
function IM_RECT:GetArea() return (self[2][1] - self[1][1]) * (self[2][2] - self[1][2]) end function IM_RECT:GetArea() return (self.Max.x - self.Min.x) * (self.Max.y - self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:AsVec4() return ImVec4(self[1][1], self[1][2], self[2][1], self[2][2]) end function IM_RECT:AsVec4() return ImVec4(self.Min.x, self.Min.y, self.Max.x, self.Max.y) end
--- @param dest ImRect --- @param dest ImRect
--- @param src ImRect --- @param src ImRect
function ImRect_Copy(dest, src) function ImRect_Copy(dest, src)
dest[1][1] = src[1][1]; dest[1][2] = src[1][2] dest.Min.x = src.Min.x; dest.Min.y = src.Min.y
dest[2][1] = src[2][1]; dest[2][2] = src[2][2] dest.Max.x = src.Max.x; dest.Max.y = src.Max.y
end end
--- @param dest ImRect --- @param dest ImRect
--- @param src ImVec4 --- @param src ImVec4
function ImRect_CopyFromV4(dest, src) function ImRect_CopyFromV4(dest, src)
dest[1][1] = src[1]; dest[1][2] = src[2] dest.Min.x = src.x; dest.Min.y = src.y
dest[2][1] = src[3]; dest[2][2] = src[4] dest.Max.x = src.z; dest.Max.y = src.w
end end
--- @param _ARRAY ImU32[] --- @param _ARRAY ImU32[]
+16 -16
View File
@@ -343,9 +343,9 @@ end
-- Generic triangle: per-vertex colour + uv, top-left fill rule, clipped to [cx0, cx1) x [cy0, cy1) -- Generic triangle: per-vertex colour + uv, top-left fill rule, clipped to [cx0, cx1) x [cy0, cy1)
@native @native
local function DrawTriangle(va, vb, vc, t, cx0, cy0, cx1, cy1, ox, oy) local function DrawTriangle(va, vb, vc, t, cx0, cy0, cx1, cy1, ox, oy)
local x0, y0 = va[1][1] - ox, va[1][2] - oy local x0, y0 = va[1].x - ox, va[1].y - oy
local x1, y1 = vb[1][1] - ox, vb[1][2] - oy local x1, y1 = vb[1].x - ox, vb[1].y - oy
local x2, y2 = vc[1][1] - ox, vc[1][2] - oy local x2, y2 = vc[1].x - ox, vc[1].y - oy
local area = (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0) local area = (x1 - x0) * (y2 - y0) - (y1 - y0) * (x2 - x0)
if area == 0 then return end if area == 0 then return end
if area < 0 then -- make the winding consistent so "inside" means all edge functions >= 0 if area < 0 then -- make the winding consistent so "inside" means all edge functions >= 0
@@ -370,7 +370,7 @@ local function DrawTriangle(va, vb, vc, t, cx0, cy0, cx1, cy1, ox, oy)
local ra, ga, ba, aa = UnpackColor(va[3]) local ra, ga, ba, aa = UnpackColor(va[3])
local rb, gb, bb, ab = UnpackColor(vb[3]) local rb, gb, bb, ab = UnpackColor(vb[3])
local rc, gc, bc, ac = UnpackColor(vc[3]) local rc, gc, bc, ac = UnpackColor(vc[3])
local ua, vva, ub, vvb, uc, vvc = va[2][1], va[2][2], vb[2][1], vb[2][2], vc[2][1], vc[2][2] local ua, vva, ub, vvb, uc, vvc = va[2].x, va[2].y, vb[2].x, vb[2].y, vc[2].x, vc[2].y
local textured = t and not (ua == ub and ua == uc and vva == vvb and vva == vvc) local textured = t and not (ua == ub and ua == uc and vva == vvb and vva == vvc)
if t and not textured then -- constant uv (e.g. the atlas white pixel): fold the texel into the vertex colours if t and not textured then -- constant uv (e.g. the atlas white pixel): fold the texel into the vertex colours
@@ -421,12 +421,12 @@ end
@native @native
local function TryDrawRect(va, vb, vc, vd, t, cx0, cy0, cx1, cy1, ox, oy) local function TryDrawRect(va, vb, vc, vd, t, cx0, cy0, cx1, cy1, ox, oy)
local pa, pb, pc, pd = va[1], vb[1], vc[1], vd[1] local pa, pb, pc, pd = va[1], vb[1], vc[1], vd[1]
if not (pa[2] == pb[2] and pb[1] == pc[1] and pc[2] == pd[2] and pd[1] == pa[1] and pa[1] < pb[1] and pa[2] < pd[2]) then return false end if not (pa.y == pb.y and pb.x == pc.x and pc.y == pd.y and pd.x == pa.x and pa.x < pb.x and pa.y < pd.y) then return false end
local col = va[3] local col = va[3]
if vb[3] ~= col or vc[3] ~= col or vd[3] ~= col then return false end if vb[3] ~= col or vc[3] ~= col or vd[3] ~= col then return false end
local ta, tb, tc, td = va[2], vb[2], vc[2], vd[2] local ta, tb, tc, td = va[2], vb[2], vc[2], vd[2]
if not (tb[1] == tc[1] and tb[2] == ta[2] and td[1] == ta[1] and td[2] == tc[2]) then return false end if not (tb.x == tc.x and tb.y == ta.y and td.x == ta.x and td.y == tc.y) then return false end
DrawRect(pa[1] - ox, pa[2] - oy, pc[1] - ox, pc[2] - oy, ta[1], ta[2], tc[1], tc[2], col, t, cx0, cy0, cx1, cy1) DrawRect(pa.x - ox, pa.y - oy, pc.x - ox, pc.y - oy, ta.x, ta.y, tc.x, tc.y, col, t, cx0, cy0, cx1, cy1)
return true return true
end end
@@ -445,8 +445,8 @@ local pr_cx0, pr_cy0, pr_cx1, pr_cy1 = {}, {}, {}, {} -- clip (screen pixels)
@native @native
local function HashVertex(h1, h2, v) local function HashVertex(h1, h2, v)
local p, u, c = v[1], v[2], v[3] local p, u, c = v[1], v[2], v[3]
local x, y = p[1], p[2] local x, y = p.x, p.y
local uv = u[1] * 8192 + u[2] local uv = u.x * 8192 + u.y
h1 = (h1 * 48271 + x * 4096 + y) % P1 h1 = (h1 * 48271 + x * 4096 + y) % P1
h1 = (h1 * 48271 + uv * 4096) % P1 h1 = (h1 * 48271 + uv * 4096) % P1
h1 = (h1 * 48271 + c) % P1 h1 = (h1 * 48271 + c) % P1
@@ -558,22 +558,22 @@ function ImGui_ImplRoblox_RenderDrawData(draw_data)
local d = vtx[vo + idx[i + 5]] local d = vtx[vo + idx[i + 5]]
local pd = d[1] local pd = d[1]
-- axis aligned quad (TL, TR, BR, BL) with one colour and a matching uv rect -- axis aligned quad (TL, TR, BR, BL) with one colour and a matching uv rect
if pa[2] == pb[2] and pb[1] == pc[1] and pc[2] == pd[2] and pd[1] == pa[1] and pa[1] < pb[1] and pa[2] < pd[2] then if pa.y == pb.y and pb.x == pc.x and pc.y == pd.y and pd.x == pa.x and pa.x < pb.x and pa.y < pd.y then
local col = va[3] local col = va[3]
local ta, tb, tc, td = va[2], vb[2], vc[2], d[2] local ta, tb, tc, td = va[2], vb[2], vc[2], d[2]
if vb[3] == col and vc[3] == col and d[3] == col if vb[3] == col and vc[3] == col and d[3] == col
and tb[1] == tc[1] and tb[2] == ta[2] and td[1] == ta[1] and td[2] == tc[2] then and tb.x == tc.x and tb.y == ta.y and td.x == ta.x and td.y == tc.y then
vd = d vd = d
bx0, by0 = ceil(pa[1] - ox - 0.5), ceil(pa[2] - oy - 0.5) bx0, by0 = ceil(pa.x - ox - 0.5), ceil(pa.y - oy - 0.5)
bx1, by1 = ceil(pc[1] - ox - 0.5), ceil(pc[2] - oy - 0.5) bx1, by1 = ceil(pc.x - ox - 0.5), ceil(pc.y - oy - 0.5)
end end
end end
end end
if vd then if vd then
i = i + 6 i = i + 6
else else
bx0, by0 = floor(min(pa[1], pb[1], pc[1]) - ox), floor(min(pa[2], pb[2], pc[2]) - oy) bx0, by0 = floor(min(pa.x, pb.x, pc.x) - ox), floor(min(pa.y, pb.y, pc.y) - oy)
bx1, by1 = ceil(max(pa[1], pb[1], pc[1]) - ox) + 1, ceil(max(pa[2], pb[2], pc[2]) - oy) + 1 bx1, by1 = ceil(max(pa.x, pb.x, pc.x) - ox) + 1, ceil(max(pa.y, pb.y, pc.y) - oy) + 1
i = i + 3 i = i + 3
end end
if bx0 < cx0 then bx0 = cx0 end if bx0 < cx0 then bx0 = cx0 end
@@ -639,7 +639,7 @@ function ImGui_ImplRoblox_RenderDrawData(draw_data)
local va, vc, vd = pr_a[p], pr_c[p], pr_d[p] local va, vc, vd = pr_a[p], pr_c[p], pr_d[p]
if vd then if vd then
local pa, pc, ta, tc = va[1], vc[1], va[2], vc[2] local pa, pc, ta, tc = va[1], vc[1], va[2], vc[2]
DrawRect(pa[1] - tox, pa[2] - toy, pc[1] - tox, pc[2] - toy, ta[1], ta[2], tc[1], tc[2], va[3], pr_t[p], cx0, cy0, cx1, cy1) DrawRect(pa.x - tox, pa.y - toy, pc.x - tox, pc.y - toy, ta.x, ta.y, tc.x, tc.y, va[3], pr_t[p], cx0, cy0, cx1, cy1)
else else
DrawTriangle(va, pr_b[p], vc, pr_t[p], cx0, cy0, cx1, cy1, tox, toy) DrawTriangle(va, pr_b[p], vc, pr_t[p], cx0, cy0, cx1, cy1, tox, toy)
end end
+1 -1
View File
@@ -1629,7 +1629,7 @@ local function StyleCopy(dst, src)
elseif type(v) == "table" and getmetatable(v) ~= nil and type(v[1]) == "number" then elseif type(v) == "table" and getmetatable(v) ~= nil and type(v[1]) == "number" then
local c = dst[k] local c = dst[k]
if type(c) ~= "table" then c = setmetatable({}, getmetatable(v)); dst[k] = c end if type(c) ~= "table" then c = setmetatable({}, getmetatable(v)); dst[k] = c end
for i = 1, #v do rawset(c, i, v[i]) end for _, key in ipairs({ "x", "y", "z", "w" }) do if rawget(v, key) ~= nil then c[key] = v[key] end end
else else
dst[k] = v dst[k] = v
end end
+39 -39
View File
@@ -340,9 +340,9 @@ function ImGui.ShadeVertsTransformPos(draw_list, vert_start_idx, vert_end_idx, p
local pix, piy, pox, poy = pivot_in.x, pivot_in.y, pivot_out.x, pivot_out.y local pix, piy, pox, poy = pivot_in.x, pivot_in.y, pivot_out.x, pivot_out.y
for i = vert_start_idx, vert_end_idx - 1 do for i = vert_start_idx, vert_end_idx - 1 do
local pos = data[i][1] local pos = data[i][1]
local x, y = pos[1] - pix, pos[2] - piy local x, y = pos.x - pix, pos.y - piy
pos[1] = x * cos_a - y * sin_a + pox pos.x = x * cos_a - y * sin_a + pox
pos[2] = x * sin_a + y * cos_a + poy pos.y = x * sin_a + y * cos_a + poy
end end
end end
@@ -3710,7 +3710,7 @@ function MT.ImDrawList:PrimRect(a, c, col)
ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv)
vtx_data[vtx_write_ptr + 0][3] = col vtx_data[vtx_write_ptr + 0][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c[1], a[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c.x, a.y)
ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], uv)
vtx_data[vtx_write_ptr + 1][3] = col vtx_data[vtx_write_ptr + 1][3] = col
@@ -3718,7 +3718,7 @@ function MT.ImDrawList:PrimRect(a, c, col)
ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv)
vtx_data[vtx_write_ptr + 2][3] = col vtx_data[vtx_write_ptr + 2][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a[1], c[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a.x, c.y)
ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], uv) ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], uv)
vtx_data[vtx_write_ptr + 3][3] = col vtx_data[vtx_write_ptr + 3][3] = col
@@ -3750,16 +3750,16 @@ function MT.ImDrawList:PrimRectUV(a, c, uv_a, uv_c, col)
ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv_a) ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], uv_a)
vtx_data[vtx_write_ptr + 0][3] = col vtx_data[vtx_write_ptr + 0][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c[1], a[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][1], c.x, a.y)
ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][2], uv_c[1], uv_a[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 1][2], uv_c.x, uv_a.y)
vtx_data[vtx_write_ptr + 1][3] = col vtx_data[vtx_write_ptr + 1][3] = col
ImVec2_Copy(vtx_data[vtx_write_ptr + 2][1], c) ImVec2_Copy(vtx_data[vtx_write_ptr + 2][1], c)
ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv_c) ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], uv_c)
vtx_data[vtx_write_ptr + 2][3] = col vtx_data[vtx_write_ptr + 2][3] = col
ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a[1], c[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][1], a.x, c.y)
ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][2], uv_a[1], uv_c[2]) ImVec2_CopyV(vtx_data[vtx_write_ptr + 3][2], uv_a.x, uv_c.y)
vtx_data[vtx_write_ptr + 3][3] = col vtx_data[vtx_write_ptr + 3][3] = col
self._VtxWritePtr = vtx_write_ptr + 4 self._VtxWritePtr = vtx_write_ptr + 4
@@ -3815,11 +3815,11 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local i2 = (i1 == points_count) and 1 or i1 + 1 local i2 = (i1 == points_count) and 1 or i1 + 1
local p1 = points[i1] local p1 = points[i1]
local p2 = points[i2] local p2 = points[i2]
local dx = p2[1] - p1[1] local dx = p2.x - p1.x
local dy = p2[2] - p1[2] local dy = p2.y - p1.y
dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy) dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy)
temp_normals[i1][1] = dy temp_normals[i1].x = dy
temp_normals[i1][2] = -dx temp_normals[i1].y = -dx
end end
if not closed then if not closed then
ImVec2_Copy(temp_normals[points_count], temp_normals[points_count - 1]) ImVec2_Copy(temp_normals[points_count], temp_normals[points_count - 1])
@@ -3847,18 +3847,18 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + (use_texture and 2 or 3)) local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + (use_texture and 2 or 3))
-- Average normals -- Average normals
local dm_x = (temp_normals[i1][1] + temp_normals[i2][1]) * 0.5 local dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5
local dm_y = (temp_normals[i1][2] + temp_normals[i2][2]) * 0.5 local dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5
dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y) dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y)
dm_x = dm_x * half_draw_size dm_x = dm_x * half_draw_size
dm_y = dm_y * half_draw_size dm_y = dm_y * half_draw_size
-- Add temporary vertices for the outer edges -- Add temporary vertices for the outer edges
local out_off = (i2 - 1) * 2 local out_off = (i2 - 1) * 2
temp_points[temp_points_start + out_off + 0][1] = points[i2][1] + dm_x temp_points[temp_points_start + out_off + 0].x = points[i2].x + dm_x
temp_points[temp_points_start + out_off + 0][2] = points[i2][2] + dm_y temp_points[temp_points_start + out_off + 0].y = points[i2].y + dm_y
temp_points[temp_points_start + out_off + 1][1] = points[i2][1] - dm_x temp_points[temp_points_start + out_off + 1].x = points[i2].x - dm_x
temp_points[temp_points_start + out_off + 1][2] = points[i2][2] - dm_y temp_points[temp_points_start + out_off + 1].y = points[i2].y - dm_y
if use_texture then if use_texture then
-- Add indices for two triangles -- Add indices for two triangles
@@ -3926,8 +3926,8 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + 4) local idx2 = (i1 == points_count) and self._VtxCurrentIdx or (idx1 + 4)
-- Average normals -- Average normals
local dm_x = (temp_normals[i1][1] + temp_normals[i2][1]) * 0.5 local dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5
local dm_y = (temp_normals[i1][2] + temp_normals[i2][2]) * 0.5 local dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5
dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y) dm_x, dm_y = IM_FIXNORMAL2F(dm_x, dm_y)
local dm_out_x = dm_x * (half_inner_thickness + AA_SIZE) local dm_out_x = dm_x * (half_inner_thickness + AA_SIZE)
local dm_out_y = dm_y * (half_inner_thickness + AA_SIZE) local dm_out_y = dm_y * (half_inner_thickness + AA_SIZE)
@@ -3936,14 +3936,14 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
-- Add temporary vertices -- Add temporary vertices
local out_off = (i2 - 1) * 4 local out_off = (i2 - 1) * 4
temp_points[temp_points_start + out_off + 0][1] = points[i2][1] + dm_out_x temp_points[temp_points_start + out_off + 0].x = points[i2].x + dm_out_x
temp_points[temp_points_start + out_off + 0][2] = points[i2][2] + dm_out_y temp_points[temp_points_start + out_off + 0].y = points[i2].y + dm_out_y
temp_points[temp_points_start + out_off + 1][1] = points[i2][1] + dm_in_x temp_points[temp_points_start + out_off + 1].x = points[i2].x + dm_in_x
temp_points[temp_points_start + out_off + 1][2] = points[i2][2] + dm_in_y temp_points[temp_points_start + out_off + 1].y = points[i2].y + dm_in_y
temp_points[temp_points_start + out_off + 2][1] = points[i2][1] - dm_in_x temp_points[temp_points_start + out_off + 2].x = points[i2].x - dm_in_x
temp_points[temp_points_start + out_off + 2][2] = points[i2][2] - dm_in_y temp_points[temp_points_start + out_off + 2].y = points[i2].y - dm_in_y
temp_points[temp_points_start + out_off + 3][1] = points[i2][1] - dm_out_x temp_points[temp_points_start + out_off + 3].x = points[i2].x - dm_out_x
temp_points[temp_points_start + out_off + 3][2] = points[i2][2] - dm_out_y temp_points[temp_points_start + out_off + 3].y = points[i2].y - dm_out_y
-- Add indices -- Add indices
local idx_write_ptr = self._IdxWritePtr local idx_write_ptr = self._IdxWritePtr
@@ -3981,17 +3981,17 @@ function MT.ImDrawList:AddPolyline(points, points_count, col, thickness, flags)
local p1 = points[i1] local p1 = points[i1]
local p2 = points[i2] local p2 = points[i2]
local dx = p2[1] - p1[1] local dx = p2.x - p1.x
local dy = p2[2] - p1[2] local dy = p2.y - p1.y
dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy) dx, dy = IM_NORMALIZE2F_OVER_ZERO(dx, dy)
dx = dx * (thickness * 0.5) dx = dx * (thickness * 0.5)
dy = dy * (thickness * 0.5) dy = dy * (thickness * 0.5)
local vtx_write_ptr = self._VtxWritePtr local vtx_write_ptr = self._VtxWritePtr
vtx_data[vtx_write_ptr + 0][1][1] = p1[1] + dy; vtx_data[vtx_write_ptr + 0][1][2] = p1[2] - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], opaque_uv); vtx_data[vtx_write_ptr + 0][3] = col vtx_data[vtx_write_ptr + 0][1].x = p1.x + dy; vtx_data[vtx_write_ptr + 0][1].y = p1.y - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 0][2], opaque_uv); vtx_data[vtx_write_ptr + 0][3] = col
vtx_data[vtx_write_ptr + 1][1][1] = p2[1] + dy; vtx_data[vtx_write_ptr + 1][1][2] = p2[2] - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], opaque_uv); vtx_data[vtx_write_ptr + 1][3] = col vtx_data[vtx_write_ptr + 1][1].x = p2.x + dy; vtx_data[vtx_write_ptr + 1][1].y = p2.y - dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 1][2], opaque_uv); vtx_data[vtx_write_ptr + 1][3] = col
vtx_data[vtx_write_ptr + 2][1][1] = p2[1] - dy; vtx_data[vtx_write_ptr + 2][1][2] = p2[2] + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], opaque_uv); vtx_data[vtx_write_ptr + 2][3] = col vtx_data[vtx_write_ptr + 2][1].x = p2.x - dy; vtx_data[vtx_write_ptr + 2][1].y = p2.y + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 2][2], opaque_uv); vtx_data[vtx_write_ptr + 2][3] = col
vtx_data[vtx_write_ptr + 3][1][1] = p1[1] - dy; vtx_data[vtx_write_ptr + 3][1][2] = p1[2] + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], opaque_uv); vtx_data[vtx_write_ptr + 3][3] = col vtx_data[vtx_write_ptr + 3][1].x = p1.x - dy; vtx_data[vtx_write_ptr + 3][1].y = p1.y + dx; ImVec2_Copy(vtx_data[vtx_write_ptr + 3][2], opaque_uv); vtx_data[vtx_write_ptr + 3][3] = col
self._VtxWritePtr = vtx_write_ptr + 4 self._VtxWritePtr = vtx_write_ptr + 4
local idx_write_ptr = self._IdxWritePtr local idx_write_ptr = self._IdxWritePtr
@@ -4728,10 +4728,10 @@ function MT.ImFont:RenderText(draw_list, size, pos, col, clip_rect, text, text_b
local glyph_col = glyph.Colored and color_untinted or col local glyph_col = glyph.Colored and color_untinted or col
do do
local vtx0 = vtx_data[vtx_write + 0]; vtx0[1][1] = x1; vtx0[1][2] = y1; vtx0[3] = glyph_col; vtx0[2][1] = u1; vtx0[2][2] = v1; local vtx0 = vtx_data[vtx_write + 0]; vtx0[1].x = x1; vtx0[1].y = y1; vtx0[3] = glyph_col; vtx0[2].x = u1; vtx0[2].y = v1;
local vtx1 = vtx_data[vtx_write + 1]; vtx1[1][1] = x2; vtx1[1][2] = y1; vtx1[3] = glyph_col; vtx1[2][1] = u2; vtx1[2][2] = v1; local vtx1 = vtx_data[vtx_write + 1]; vtx1[1].x = x2; vtx1[1].y = y1; vtx1[3] = glyph_col; vtx1[2].x = u2; vtx1[2].y = v1;
local vtx2 = vtx_data[vtx_write + 2]; vtx2[1][1] = x2; vtx2[1][2] = y2; vtx2[3] = glyph_col; vtx2[2][1] = u2; vtx2[2][2] = v2; local vtx2 = vtx_data[vtx_write + 2]; vtx2[1].x = x2; vtx2[1].y = y2; vtx2[3] = glyph_col; vtx2[2].x = u2; vtx2[2].y = v2;
local vtx3 = vtx_data[vtx_write + 3]; vtx3[1][1] = x1; vtx3[1][2] = y2; vtx3[3] = glyph_col; vtx3[2][1] = u1; vtx3[2][2] = v2; local vtx3 = vtx_data[vtx_write + 3]; vtx3[1].x = x1; vtx3[1].y = y2; vtx3[3] = glyph_col; vtx3[2].x = u1; vtx3[2].y = v2;
idx_data[idx_write + 0] = vtx_index; idx_data[idx_write + 1] = vtx_index + 1; idx_data[idx_write + 2] = vtx_index + 2; idx_data[idx_write + 0] = vtx_index; idx_data[idx_write + 1] = vtx_index + 1; idx_data[idx_write + 2] = vtx_index + 2;
idx_data[idx_write + 3] = vtx_index; idx_data[idx_write + 4] = vtx_index + 2; idx_data[idx_write + 5] = vtx_index + 3; idx_data[idx_write + 3] = vtx_index; idx_data[idx_write + 4] = vtx_index + 2; idx_data[idx_write + 5] = vtx_index + 3;
vtx_write = vtx_write + 4 vtx_write = vtx_write + 4
+38 -85
View File
@@ -193,8 +193,8 @@ ImGuiMouseCursor =
--- @return ImTextureRect --- @return ImTextureRect
function ImTextureRect(x, y, w, h) return { x = x, y = y, w = w, h = h } end function ImTextureRect(x, y, w, h) return { x = x, y = y, w = w, h = h } end
-- This structure supports indexing on string keys `x`, `y` and number keys 1, 2. -- [Luau] Stored as named fields {x=, y=} so the common `.x`/`.y` access is a plain table read (no metamethod call).
-- But note that the former is likely to be more expensive. -- Numeric keys 1, 2 still work through the metatable, but are slower: prefer .x/.y in hot code.
--- @class ImVec2 --- @class ImVec2
--- @operator add(ImVec2): ImVec2 --- @operator add(ImVec2): ImVec2
--- @operator sub(ImVec2): ImVec2 --- @operator sub(ImVec2): ImVec2
@@ -202,146 +202,97 @@ function ImTextureRect(x, y, w, h) return { x = x, y = y, w = w, h = h } end
--- @operator mul(ImVec2): ImVec2 --- @operator mul(ImVec2): ImVec2
--- @operator div(number): ImVec2 --- @operator div(number): ImVec2
--- @operator div(ImVec2): ImVec2 --- @operator div(ImVec2): ImVec2
--- @field [1] number
--- @field [2] number
--- @field x number --- @field x number
--- @field y number --- @field y number
local IM_VEC2 = {} local IM_VEC2 = {}
local VEC2_KEYS = { "x", "y" }
--- @param t ImVec2
--- @param k string
IM_VEC2.__index = function(t, k) IM_VEC2.__index = function(t, k)
if k == "x" then return rawget(t, 1) local n = VEC2_KEYS[k]
elseif k == "y" then return rawget(t, 2) if n then return rawget(t, n) end
end
end end
--- @param t ImVec2
--- @param k string
--- @param v number
IM_VEC2.__newindex = function(t, k, v) IM_VEC2.__newindex = function(t, k, v)
if k == "x" then rawset(t, 1, v) local n = VEC2_KEYS[k]
elseif k == "y" then rawset(t, 2, v) IM_ASSERT(n ~= nil)
else IM_ASSERT(false) rawset(t, n, v)
end
end end
--- @param x? number --- @param x? number
--- @param y? number --- @param y? number
--- @return ImVec2 --- @return ImVec2
--- @nodiscard --- @nodiscard
function ImVec2(x, y) return setmetatable({x or 0, y or 0}, IM_VEC2) end function ImVec2(x, y) return setmetatable({ x = x or 0, y = y or 0 }, IM_VEC2) end
function IM_VEC2.__add(lhs, rhs) return ImVec2(lhs[1] + rhs[1], lhs[2] + rhs[2]) end function IM_VEC2.__add(lhs, rhs) return setmetatable({ x = lhs.x + rhs.x, y = lhs.y + rhs.y }, IM_VEC2) end
function IM_VEC2.__sub(lhs, rhs) return ImVec2(lhs[1] - rhs[1], lhs[2] - rhs[2]) end function IM_VEC2.__sub(lhs, rhs) return setmetatable({ x = lhs.x - rhs.x, y = lhs.y - rhs.y }, IM_VEC2) end
--- @overload fun(lhs: ImVec2, rhs: number): ImVec2
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function IM_VEC2.__mul(lhs, rhs) function IM_VEC2.__mul(lhs, rhs)
if type(lhs) == "table" and type(rhs) == "number" then return ImVec2(lhs[1] * rhs, lhs[2] * rhs) if type(rhs) == "number" then return setmetatable({ x = lhs.x * rhs, y = lhs.y * rhs }, IM_VEC2) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(lhs[1] * rhs[1], lhs[2] * rhs[2]) return setmetatable({ x = lhs.x * rhs.x, y = lhs.y * rhs.y }, IM_VEC2)
end
end end
--- @overload fun(lhs: ImVec2, rhs: number): ImVec2
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function IM_VEC2.__div(lhs, rhs) function IM_VEC2.__div(lhs, rhs)
if type(lhs) == "table" and type(rhs) == "number" then return ImVec2(lhs[1] / rhs, lhs[2] / rhs) if type(rhs) == "number" then return setmetatable({ x = lhs.x / rhs, y = lhs.y / rhs }, IM_VEC2) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(lhs[1] / rhs[1], lhs[2] / rhs[2]) return setmetatable({ x = lhs.x / rhs.x, y = lhs.y / rhs.y }, IM_VEC2)
end
end end
function IM_VEC2.__eq(lhs, rhs) return lhs[1] == rhs[1] and lhs[2] == rhs[2] end function IM_VEC2.__eq(lhs, rhs) return lhs.x == rhs.x and lhs.y == rhs.y end
function IM_VEC2:__tostring() return string.format("ImVec2(%g, %g)", self.x, self.y) end function IM_VEC2:__tostring() return string.format("ImVec2(%g, %g)", self.x, self.y) end
--- @param dest ImVec2 --- @param dest ImVec2
--- @param src ImVec2 --- @param src ImVec2
function ImVec2_Copy(dest, src) dest[1] = src[1]; dest[2] = src[2] end function ImVec2_Copy(dest, src) dest.x = src.x; dest.y = src.y end
--- @param dest ImVec2 function ImVec2_CopyV(dest, src_x, src_y) dest.x = src_x; dest.y = src_y end
--- @param src_x number
--- @param src_y number
function ImVec2_CopyV(dest, src_x, src_y) dest[1] = src_x; dest[2] = src_y end
--- @param v ImVec2 function ImVec2_AddVA(v, add_x, add_y) return v.x + add_x, v.y + add_y end
--- @param add_x number
--- @param add_y number
function ImVec2_AddVA(v, add_x, add_y) return v[1] + add_x, v[2] + add_y end
--- @param v ImVec2 function ImVec2_SubVA(v, sub_x, sub_y) return v.x - sub_x, v.y - sub_y end
--- @param sub_x number
--- @param sub_y number
function ImVec2_SubVA(v, sub_x, sub_y) return v[1] - sub_x, v[2] - sub_y end
--- @param a ImVec2 function ImVec2_MulVX(a, scalar) return a.x * scalar, a.y * scalar end
--- @param scalar number
function ImVec2_MulVX(a, scalar)
return a[1] * scalar, a[2] * scalar
end
--- An inlined version of `ImVec2_Copy` currently for use in certain ImVector<ImVec2> `push_back` --- An inlined version of `ImVec2_Copy` currently for use in certain ImVector<ImVec2> `push_back`
--- @param t ImVec2[] local function ImVec2_TCopy(t, k, v) local dest = t[k]; dest.x = v.x; dest.y = v.y; end
--- @param k int
--- @param v ImVec2
local function ImVec2_TCopy(t, k, v) local dest = t[k]; dest[1] = v[1]; dest[2] = v[2]; end
-- This structure supports indexing on string keys `x`, `y`, `z`, `w` and number keys 1, 2, 3, 4. -- [Luau] Same layout as ImVec2: named fields x, y, z, w; numeric keys 1..4 go through the metatable.
-- But note that the former is likely to be more expensive.
--- @class ImVec4 --- @class ImVec4
--- @operator add(ImVec4): ImVec4 --- @operator add(ImVec4): ImVec4
--- @operator sub(ImVec4): ImVec4 --- @operator sub(ImVec4): ImVec4
--- @operator mul(number): ImVec4 --- @operator mul(number): ImVec4
--- @field [1] number
--- @field [2] number
--- @field [3] number
--- @field [4] number
--- @field x number --- @field x number
--- @field y number --- @field y number
--- @field z number --- @field z number
--- @field w number --- @field w number
local IM_VEC4 = {} local IM_VEC4 = {}
local VEC4_KEYS = { "x", "y", "z", "w" }
--- @param t ImVec4
--- @param k string
IM_VEC4.__index = function(t, k) IM_VEC4.__index = function(t, k)
if k == "x" then return rawget(t, 1) local n = VEC4_KEYS[k]
elseif k == "y" then return rawget(t, 2) if n then return rawget(t, n) end
elseif k == "z" then return rawget(t, 3)
elseif k == "w" then return rawget(t, 4)
end
end end
--- @param t ImVec4
--- @param k string
--- @param v number
IM_VEC4.__newindex = function(t, k, v) IM_VEC4.__newindex = function(t, k, v)
if k == "x" then rawset(t, 1, v) local n = VEC4_KEYS[k]
elseif k == "y" then rawset(t, 2, v) IM_ASSERT(n ~= nil)
elseif k == "z" then rawset(t, 3, v) rawset(t, n, v)
elseif k == "w" then rawset(t, 4, v)
else IM_ASSERT(false)
end
end end
--- @param x? number
--- @param y? number
--- @param z? number
--- @param w? number
--- @return ImVec4 --- @return ImVec4
--- @nodiscard --- @nodiscard
function ImVec4(x, y, z, w) return setmetatable({x or 0, y or 0, z or 0, w or 0}, IM_VEC4) end function ImVec4(x, y, z, w) return setmetatable({ x = x or 0, y = y or 0, z = z or 0, w = w or 0 }, IM_VEC4) end
function IM_VEC4.__add(lhs, rhs) return ImVec4(lhs[1] + rhs[1], lhs[2] + rhs[2], lhs[3] + rhs[3], lhs[4] + rhs[4]) end function IM_VEC4.__add(lhs, rhs) return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w) end
function IM_VEC4.__sub(lhs, rhs) return ImVec4(lhs[1] - rhs[1], lhs[2] - rhs[2], lhs[3] - rhs[3], lhs[4] - rhs[4]) end function IM_VEC4.__sub(lhs, rhs) return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w) end
function IM_VEC4.__mul(lhs, rhs) return ImVec4(lhs[1] * rhs, lhs[2] * rhs, lhs[3] * rhs, lhs[4] * rhs) end function IM_VEC4.__mul(lhs, rhs) return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs) end
function IM_VEC4.__eq(lhs, rhs) return lhs[1] == rhs[1] and lhs[2] == rhs[2] and lhs[3] == rhs[3] and lhs[4] == rhs[4] end function IM_VEC4.__eq(lhs, rhs) return lhs.x == rhs.x and lhs.y == rhs.y and lhs.z == rhs.z and lhs.w == rhs.w end
function IM_VEC4:__tostring() return string.format("ImVec4(%g, %g, %g, %g)", self.x, self.y, self.z, self.w) end function IM_VEC4:__tostring() return string.format("ImVec4(%g, %g, %g, %g)", self.x, self.y, self.z, self.w) end
--- @param dest ImVec4 --- @param dest ImVec4
--- @param src ImVec4 --- @param src ImVec4
function ImVec4_Copy(dest, src) dest[1] = src[1]; dest[2] = src[2]; dest[3] = src[3]; dest[4] = src[4] end function ImVec4_Copy(dest, src) dest.x = src.x; dest.y = src.y; dest.z = src.z; dest.w = src.w end
--- A compact ImVector clone --- A compact ImVector clone
--- @class ImVector<T> --- @class ImVector<T>
@@ -356,8 +307,10 @@ local IM_VECTOR = {}
--- @param k string|int --- @param k string|int
--- @return any --- @return any
IM_VECTOR.__index = function(t, k) IM_VECTOR.__index = function(t, k)
local m = IM_VECTOR[k] -- methods first (hot path)
if m ~= nil then return m end
if k == "Data" then return nil end -- Data has already been discarded if k == "Data" then return nil end -- Data has already been discarded
return IM_VECTOR[k] or t.Data[IM_ASSERT(k >= 1 and k <= t.Size) or k] -- if the mt access turns out nil, the k must be int index into Data return t.Data[IM_ASSERT(k >= 1 and k <= t.Size) or k] -- if the mt access turns out nil, the k must be int index into Data
end end
--- @param t ImVector --- @param t ImVector
+52 -66
View File
@@ -141,17 +141,15 @@ end
--- @overload fun(lhs: number, rhs: number): number --- @overload fun(lhs: number, rhs: number): number
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2 --- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function ImMin(lhs, rhs) function ImMin(lhs, rhs)
if type(lhs) == "number" and type(rhs) == "number" then return mathMin(lhs, rhs) if type(lhs) == "number" then return mathMin(lhs, rhs) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(mathMin(lhs[1], rhs[1]), mathMin(lhs[2], rhs[2])) return ImVec2(mathMin(lhs.x, rhs.x), mathMin(lhs.y, rhs.y))
end
end end
--- @overload fun(lhs: number, rhs: number): number --- @overload fun(lhs: number, rhs: number): number
--- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2 --- @overload fun(lhs: ImVec2, rhs: ImVec2): ImVec2
function ImMax(lhs, rhs) function ImMax(lhs, rhs)
if type(lhs) == "number" and type(rhs) == "number" then return mathMax(lhs, rhs) if type(lhs) == "number" then return mathMax(lhs, rhs) end
elseif type(lhs) == "table" and type(rhs) == "table" then return ImVec2(mathMax(lhs[1], rhs[1]), mathMax(lhs[2], rhs[2])) return ImVec2(mathMax(lhs.x, rhs.x), mathMax(lhs.y, rhs.y))
end
end end
--- @param base table --- @param base table
@@ -163,7 +161,7 @@ ImStd.ImQsort = function(base, count, cmp_func) if count > 0 then t_sort(base, c
--- @overload fun(v: ImVec2, mn: ImVec2, mx: ImVec2): ImVec2 --- @overload fun(v: ImVec2, mn: ImVec2, mx: ImVec2): ImVec2
function ImClamp(v, mn, mx) function ImClamp(v, mn, mx)
if type(v) == "number" and type(mn) == "number" and type(mx) == "number" then return mathMin(mathMax(v, mn), mx) if type(v) == "number" and type(mn) == "number" and type(mx) == "number" then return mathMin(mathMax(v, mn), mx)
elseif type(v) == "table" and type(mn) == "table" and type(mx) == "table" then return ImVec2(mathMax(mn[1], mathMin(v[1], mx[1])), mathMax(mn[2], mathMin(v[2], mx[2]))) elseif type(v) == "table" and type(mn) == "table" and type(mx) == "table" then return ImVec2(mathMax(mn.x, mathMin(v.x, mx.x)), mathMax(mn.y, mathMin(v.y, mx.y)))
end end
end end
@@ -172,8 +170,8 @@ end
--- @overload fun(a: ImVec2, b: ImVec2, t: ImVec2): ImVec2 --- @overload fun(a: ImVec2, b: ImVec2, t: ImVec2): ImVec2
function ImLerp(a, b, t) function ImLerp(a, b, t)
if type(a) == "number" and type(b) == "number" and type(t) == "number" then return ((a) + ((b) - (a)) * (t)) if type(a) == "number" and type(b) == "number" and type(t) == "number" then return ((a) + ((b) - (a)) * (t))
elseif type(a) == "table" and type(b) == "table" and type(t) == "number" then return ImVec2(a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t) elseif type(a) == "table" and type(b) == "table" and type(t) == "number" then return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t)
elseif type(a) == "table" and type(b) == "table" and type(t) == "table" then return ImVec2(a[1] + (b[1] - a[1]) * t[1], a[2] + (b[2] - a[2]) * t[2]) elseif type(a) == "table" and type(b) == "table" and type(t) == "table" then return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y)
end end
end end
@@ -183,7 +181,7 @@ local function _Trunc(val) if val >= 0 then return mathFloor(val) else return ma
--- @overload fun(v: ImVec2): ImVec2 --- @overload fun(v: ImVec2): ImVec2
function ImTrunc(v) function ImTrunc(v)
if type(v) == "number" then return _Trunc(v) if type(v) == "number" then return _Trunc(v)
elseif type(v) == "table" then return ImVec2(_Trunc(v[1]), _Trunc(v[2])) elseif type(v) == "table" then return ImVec2(_Trunc(v.x), _Trunc(v.y))
end end
end end
@@ -673,150 +671,138 @@ end
--- @field Min ImVec2 --- @field Min ImVec2
--- @field Max ImVec2 --- @field Max ImVec2
local IM_RECT = {} local IM_RECT = {}
setmetatable(IM_RECT, { __index = function(_, k) if k ~= "Min" and k ~= "Max" then error("ImRect: unknown key " .. tostring(k), 2) end end })
--- @param t ImRect --- @param t ImRect
--- @param k string --- @param k string
IM_RECT.__index = function(t, k) IM_RECT.__index = IM_RECT -- [Luau] plain table: fast method lookup. Use r.Min / r.Max (numeric r[1]/r[2] are not supported)
local method = IM_RECT[k]
if method ~= nil then return method end
if k == "Min" then return rawget(t, 1)
elseif k == "Max" then return rawget(t, 2)
end
end
--- @param t ImRect -- [Luau] Min/Max are named fields, so `r.Min = v` assigns the reference: use ImVec2_Copy(r.Min, v) to keep copy semantics
--- @param k string IM_RECT.__newindex = function(t, k, v) IM_ASSERT(false, "ImRect: unknown field " .. tostring(k)) end
--- @param v ImVec2
IM_RECT.__newindex = function(t, k, v)
if k == "Min" then ImVec2_Copy(rawget(t, 1), v)
elseif k == "Max" then ImVec2_Copy(rawget(t, 2), v)
else IM_ASSERT(false)
end
end
--- @return ImRect --- @return ImRect
--- @nodiscard --- @nodiscard
function ImRect(a, b, c, d) if c and d then return setmetatable({ ImVec2(a, b), ImVec2(c, d) }, IM_RECT) end return setmetatable({ ImVec2(a and a.x or 0, a and a.y or 0), ImVec2(b and b.x or 0, b and b.y or 0) }, IM_RECT) end function ImRect(a, b, c, d) if c and d then return setmetatable({ Min = ImVec2(a, b), Max = ImVec2(c, d) }, IM_RECT) end return setmetatable({ Min = ImVec2(a and a.x or 0, a and a.y or 0), Max = ImVec2(b and b.x or 0, b and b.y or 0) }, IM_RECT) end
function IM_RECT:__eq(other) return self[1] == other[1] and self[2] == other[2] end function IM_RECT:__eq(other) return self.Min == other.Min and self.Max == other.Max end
function IM_RECT:__tostring() return string.format("ImRect(Min: %g,%g, Max: %g,%g)", self.Min.x, self.Min.y, self.Max.x, self.Max.y) end function IM_RECT:__tostring() return string.format("ImRect(Min: %g,%g, Max: %g,%g)", self.Min.x, self.Min.y, self.Max.x, self.Max.y) end
--- @param p ImRect|ImVec2 --- @param p ImRect|ImVec2
function IM_RECT:Contains(p) function IM_RECT:Contains(p)
if p.Min then if p.Min then
--- @cast p ImRect --- @cast p ImRect
return p[1][1] >= self[1][1] and p[2][1] <= self[2][1] and p[1][2] >= self[1][2] and p[2][2] <= self[2][2] return p.Min.x >= self.Min.x and p.Max.x <= self.Max.x and p.Min.y >= self.Min.y and p.Max.y <= self.Max.y
else else
--- @cast p ImVec2 --- @cast p ImVec2
return p[1] >= self[1][1] and p[2] >= self[1][2] and p[1] < self[2][1] and p[2] < self[2][2] return p.x >= self.Min.x and p.y >= self.Min.y and p.x < self.Max.x and p.y < self.Max.y
end end
end end
--- @param p ImVec2 --- @param p ImVec2
--- @param pad ImVec2 --- @param pad ImVec2
function IM_RECT:ContainsWithPad(p, pad) function IM_RECT:ContainsWithPad(p, pad)
return p[1] >= self[1][1] - pad[1] and p[2] >= self[1][2] - pad[2] and p[1] < self[2][1] + pad[1] and p[2] < self[2][2] + pad[2] return p.x >= self.Min.x - pad.x and p.y >= self.Min.y - pad.y and p.x < self.Max.x + pad.x and p.y < self.Max.y + pad.y
end end
--- @param r ImRect --- @param r ImRect
function IM_RECT:Overlaps(r) function IM_RECT:Overlaps(r)
return self[1][1] <= r[2][1] and self[2][1] >= r[1][1] and self[1][2] <= r[2][2] and self[2][2] >= r[1][2] return self.Min.x <= r.Max.x and self.Max.x >= r.Min.x and self.Min.y <= r.Max.y and self.Max.y >= r.Min.y
end end
--- @nodiscard --- @nodiscard
function IM_RECT:GetCenter() return ImVec2((self[1][1] + self[2][1]) * 0.5, (self[1][2] + self[2][2]) * 0.5) end function IM_RECT:GetCenter() return ImVec2((self.Min.x + self.Max.x) * 0.5, (self.Min.y + self.Max.y) * 0.5) end
function IM_RECT:GetWidth() return self[2][1] - self[1][1] end function IM_RECT:GetWidth() return self.Max.x - self.Min.x end
function IM_RECT:GetHeight() return self[2][2] - self[1][2] end function IM_RECT:GetHeight() return self.Max.y - self.Min.y end
--- @nodiscard --- @nodiscard
function IM_RECT:GetSize() return ImVec2(self[2][1] - self[1][1], self[2][2] - self[1][2]) end function IM_RECT:GetSize() return ImVec2(self.Max.x - self.Min.x, self.Max.y - self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetTL() return ImVec2(self[1][1], self[1][2]) end function IM_RECT:GetTL() return ImVec2(self.Min.x, self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetTR() return ImVec2(self[2][1], self[1][2]) end function IM_RECT:GetTR() return ImVec2(self.Max.x, self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetBL() return ImVec2(self[1][1], self[2][2]) end function IM_RECT:GetBL() return ImVec2(self.Min.x, self.Max.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:GetBR() return ImVec2(self[2][1], self[2][2]) end function IM_RECT:GetBR() return ImVec2(self.Max.x, self.Max.y) end
--- @param r ImRect --- @param r ImRect
function IM_RECT:ClipWith(r) function IM_RECT:ClipWith(r)
ImVec2_Copy(self[1], ImMax(self[1], r[1])); ImVec2_Copy(self[2], ImMin(self[2], r[2])) ImVec2_Copy(self.Min, ImMax(self.Min, r.Min)); ImVec2_Copy(self.Max, ImMin(self.Max, r.Max))
end end
--- @param r ImRect --- @param r ImRect
function IM_RECT:ClipWithFull(r) function IM_RECT:ClipWithFull(r)
ImVec2_Copy(self[1], ImClamp(self[1], r[1], r[2])); ImVec2_Copy(self[2], ImClamp(self[2], r[1], r[2])) ImVec2_Copy(self.Min, ImClamp(self.Min, r.Min, r.Max)); ImVec2_Copy(self.Max, ImClamp(self.Max, r.Min, r.Max))
end end
--- @param p ImRect|ImVec2 --- @param p ImRect|ImVec2
function IM_RECT:Add(p) function IM_RECT:Add(p)
if p.Min then if p.Min then
--- @cast p ImRect --- @cast p ImRect
if (self[1][1] > p[1][1]) then self[1][1] = p[1][1] end if (self.Min.x > p.Min.x) then self.Min.x = p.Min.x end
if (self[1][2] > p[1][2]) then self[1][2] = p[1][2] end if (self.Min.y > p.Min.y) then self.Min.y = p.Min.y end
if (self[2][1] < p[2][1]) then self[2][1] = p[2][1] end if (self.Max.x < p.Max.x) then self.Max.x = p.Max.x end
if (self[2][2] < p[2][2]) then self[2][2] = p[2][2] end if (self.Max.y < p.Max.y) then self.Max.y = p.Max.y end
else else
--- @cast p ImVec2 --- @cast p ImVec2
if p[1] < self[1][1] then self[1][1] = p[1] end if p.x < self.Min.x then self.Min.x = p.x end
if p[2] < self[1][2] then self[1][2] = p[2] end if p.y < self.Min.y then self.Min.y = p.y end
if p[1] > self[2][1] then self[2][1] = p[1] end if p.x > self.Max.x then self.Max.x = p.x end
if p[2] > self[2][2] then self[2][2] = p[2] end if p.y > self.Max.y then self.Max.y = p.y end
end end
end end
--- @param amount float|ImVec2 --- @param amount float|ImVec2
function IM_RECT:Expand(amount) function IM_RECT:Expand(amount)
if type(amount) == "number" then if type(amount) == "number" then
self[1][1] = self[1][1] - amount; self[1][2] = self[1][2] - amount self.Min.x = self.Min.x - amount; self.Min.y = self.Min.y - amount
self[2][1] = self[2][1] + amount; self[2][2] = self[2][2] + amount self.Max.x = self.Max.x + amount; self.Max.y = self.Max.y + amount
elseif type(amount) == "table" then elseif type(amount) == "table" then
self[1][1] = self[1][1] - amount[1]; self[1][2] = self[1][2] - amount[2] self.Min.x = self.Min.x - amount.x; self.Min.y = self.Min.y - amount.y
self[2][1] = self[2][1] + amount[1]; self[2][2] = self[2][2] + amount[2] self.Max.x = self.Max.x + amount.x; self.Max.y = self.Max.y + amount.y
end end
end end
--- @nodiscard --- @nodiscard
function IM_RECT:ToVec4() function IM_RECT:ToVec4()
return ImVec4(self[1][1], self[1][2], self[2][1], self[2][2]) return ImVec4(self.Min.x, self.Min.y, self.Max.x, self.Max.y)
end end
--- @param d ImVec2 --- @param d ImVec2
function IM_RECT:Translate(d) function IM_RECT:Translate(d)
self[1][1] = self[1][1] + d[1]; self[1][2] = self[1][2] + d[2] self.Min.x = self.Min.x + d.x; self.Min.y = self.Min.y + d.y
self[2][1] = self[2][1] + d[1]; self[2][2] = self[2][2] + d[2] self.Max.x = self.Max.x + d.x; self.Max.y = self.Max.y + d.y
end end
--- @param dx float --- @param dx float
function IM_RECT:TranslateX(dx) function IM_RECT:TranslateX(dx)
self[1][1] = self[1][1] + dx; self[2][1] = self[2][1] + dx self.Min.x = self.Min.x + dx; self.Max.x = self.Max.x + dx
end end
--- @param dy float --- @param dy float
function IM_RECT:TranslateY(dy) function IM_RECT:TranslateY(dy)
self[1][2] = self[1][2] + dy; self[2][2] = self[2][2] + dy self.Min.y = self.Min.y + dy; self.Max.y = self.Max.y + dy
end end
function IM_RECT:IsInverted() return self[1][1] > self[2][1] or self[1][2] > self[2][2] end function IM_RECT:IsInverted() return self.Min.x > self.Max.x or self.Min.y > self.Max.y end
function IM_RECT:GetArea() return (self[2][1] - self[1][1]) * (self[2][2] - self[1][2]) end function IM_RECT:GetArea() return (self.Max.x - self.Min.x) * (self.Max.y - self.Min.y) end
--- @nodiscard --- @nodiscard
function IM_RECT:AsVec4() return ImVec4(self[1][1], self[1][2], self[2][1], self[2][2]) end function IM_RECT:AsVec4() return ImVec4(self.Min.x, self.Min.y, self.Max.x, self.Max.y) end
--- @param dest ImRect --- @param dest ImRect
--- @param src ImRect --- @param src ImRect
function ImRect_Copy(dest, src) function ImRect_Copy(dest, src)
dest[1][1] = src[1][1]; dest[1][2] = src[1][2] dest.Min.x = src.Min.x; dest.Min.y = src.Min.y
dest[2][1] = src[2][1]; dest[2][2] = src[2][2] dest.Max.x = src.Max.x; dest.Max.y = src.Max.y
end end
--- @param dest ImRect --- @param dest ImRect
--- @param src ImVec4 --- @param src ImVec4
function ImRect_CopyFromV4(dest, src) function ImRect_CopyFromV4(dest, src)
dest[1][1] = src[1]; dest[1][2] = src[2] dest.Min.x = src.x; dest.Min.y = src.y
dest[2][1] = src[3]; dest[2][2] = src[4] dest.Max.x = src.z; dest.Max.y = src.w
end end
--- @param _ARRAY ImU32[] --- @param _ARRAY ImU32[]
+2 -2
View File
@@ -167,12 +167,12 @@ local render_time = 0
local realDemo = G.ImGui.ShowDemoWindow local realDemo = G.ImGui.ShowDemoWindow
local realCH = G.ImGui.CollapsingHeader local realCH = G.ImGui.CollapsingHeader
G.ImGui.CollapsingHeader = function(...) G.ImGui.CollapsingHeader = function(...)
if ARG_OPEN then G.ImGui.SetNextItemOpen(true, G.ImGuiCond.Always) end if ARG_OPEN == true or (type(ARG_OPEN) == "table" and ARG_OPEN[(...)]) then G.ImGui.SetNextItemOpen(true, G.ImGuiCond.Always) end
return realCH(...) return realCH(...)
end end
local realTN = G.ImGui.TreeNode local realTN = G.ImGui.TreeNode
G.ImGui.TreeNode = function(...) G.ImGui.TreeNode = function(...)
if ARG_OPEN then G.ImGui.SetNextItemOpen(true, G.ImGuiCond.Always) end if ARG_OPEN == true or (type(ARG_OPEN) == "table" and ARG_OPEN[(...)]) then G.ImGui.SetNextItemOpen(true, G.ImGuiCond.Always) end
return realTN(...) return realTN(...)
end end
G.ImGui.ShowDemoWindow = function(...) G.ImGui.ShowDemoWindow = function(...)
+4 -2
View File
@@ -16,7 +16,7 @@ G = "game, workspace, Instance, Enum, Vector2, Vector3, UDim2, Color3, Content,
def build_run(args, flags): def build_run(args, flags):
subprocess.run([sys.executable, os.path.join(ROOT, "tools", "bundle.py"), TMP], check=True, stdout=subprocess.DEVNULL) subprocess.run([sys.executable, os.path.join(ROOT, "tools", "bundle.py"), TMP], check=True, stdout=subprocess.DEVNULL)
out = ["--!native", "--!optimize 2", flags, "local SOURCE_FNS = {}"] out = ["--" if args.roblox else "--!native", "--!optimize 2", flags, "local SOURCE_FNS = {}"]
def add(key, path): def add(key, path):
s = "\n".join(l for l in open(path).read().split("\n") if not l.startswith("--!")) s = "\n".join(l for l in open(path).read().split("\n") if not l.startswith("--!"))
out.append("SOURCE_FNS[%r] = function(%s)\n%s\nend" % (key, G, s)) out.append("SOURCE_FNS[%r] = function(%s)\n%s\nend" % (key, G, s))
@@ -31,7 +31,7 @@ def build_run(args, flags):
return path return path
def run(args, extra=""): def run(args, extra=""):
flags = "ARG_FRAMES=%d; ARG_BIG=%s; ARG_OPEN=%s; ARG_QUIET=%s; %s" % (args.frames, str(args.big).lower(), str(args.open).lower(), str(args.quiet).lower(), extra) flags = "ARG_FRAMES=%d; ARG_BIG=%s; ARG_OPEN=%s; ARG_QUIET=%s; %s" % (args.frames, str(args.big).lower(), ("{%s}" % ",".join("[%r]=true" % x for x in args.open_only.split(",")) if args.open_only else str(args.open).lower()), str(args.quiet).lower(), extra)
try: try:
p = subprocess.run([LUAU, "-O2"] + (["--profile=2000"] if args.profile else ["--codegen"]) + [build_run(args, flags)], capture_output=True, text=True, timeout=args.timeout) p = subprocess.run([LUAU, "-O2"] + (["--profile=2000"] if args.profile else ["--codegen"]) + [build_run(args, flags)], capture_output=True, text=True, timeout=args.timeout)
except subprocess.TimeoutExpired as e: except subprocess.TimeoutExpired as e:
@@ -58,6 +58,8 @@ def main():
ap.add_argument("--frames", type=int, default=400) ap.add_argument("--frames", type=int, default=400)
ap.add_argument("--main", default=os.path.join(ROOT, "main.client.luau")) ap.add_argument("--main", default=os.path.join(ROOT, "main.client.luau"))
ap.add_argument("--big", action="store_true", help="demo window forced to 900x1000") ap.add_argument("--big", action="store_true", help="demo window forced to 900x1000")
ap.add_argument("--roblox", action="store_true", help="like Studio: only @native functions get native code (default: whole bundle native)")
ap.add_argument("--open-only", default="", help="comma list of CollapsingHeader/TreeNode labels to force open, e.g. Widgets,Basic")
ap.add_argument("--profile", action="store_true", help="sampling profile (no codegen) -> profile.out; see tools/test/prof.py") ap.add_argument("--profile", action="store_true", help="sampling profile (no codegen) -> profile.out; see tools/test/prof.py")
ap.add_argument("--open", action="store_true", help="force all CollapsingHeader/TreeNode open") ap.add_argument("--open", action="store_true", help="force all CollapsingHeader/TreeNode open")
ap.add_argument("--timeout", type=int, default=120) ap.add_argument("--timeout", type=int, default=120)