Port ImTriangulator + upstream AddConcavePolyFilled (AA fringe, no per-triangle seams); [Luau] handles CCW winding and duplicate/collinear points that upstream mis-triangulates
This commit is contained in:
@@ -1 +1 @@
|
|||||||
[[46, "imgui.lua"], [21466, "imgui_demo.lua"], [33318, "imgui_draw.lua"], [40827, "imgui_h.lua"], [43733, "imgui_impl_roblox.lua"], [45381, "imgui_impl_roblox_fonts.lua"], [51784, "imgui_internal.lua"], [55494, "imgui_tables.lua"], [60553, "imgui_widgets.lua"], [72529, "imstb_rectpack.lua"], [73193, "imstb_textedit.lua"], [74735, "imstb_truetype.lua"], [77523, "imstd_minstdio.lua"]]
|
[[46, "imgui.lua"], [21466, "imgui_demo.lua"], [33318, "imgui_draw.lua"], [41121, "imgui_h.lua"], [44027, "imgui_impl_roblox.lua"], [45675, "imgui_impl_roblox_fonts.lua"], [52078, "imgui_internal.lua"], [55800, "imgui_tables.lua"], [60859, "imgui_widgets.lua"], [72835, "imstb_rectpack.lua"], [73499, "imstb_textedit.lua"], [75041, "imstb_truetype.lua"], [77829, "imstd_minstdio.lua"]]
|
||||||
+344
-36
@@ -1,7 +1,7 @@
|
|||||||
--!optimize 2
|
--!optimize 2
|
||||||
-- GENERATED by tools/bundle.py from *.lua, backends/, fonts/ - do not edit
|
-- GENERATED by tools/bundle.py from *.lua, backends/, fonts/ - do not edit
|
||||||
|
|
||||||
local ImGui, ImVec2, ImVec4, ImRect, HelpMarker, ImVec2_Copy, IMGUI_DEMO_MARKER, ImGuiTableFlags, ImStd, ImVector, ImDrawFlags, ImGuiInputFlags, ImRect_Copy, ImGuiDataType, ImStb, IM_TRUNC, ImGuiKey, ImVec2_CopyV, ImGuiStyleVarInfo, IM_ASSERT_USER_ERROR, ImGuiHoveredFlags, ImFormatString, IM_ASSERT_USER_ERROR_RET, ImHashStr, ImS32, ImGuiColorEditFlags, ImIsPowerOfTwo, ImAbs, ImVec4_Copy, ExampleAppConsoleMT, IM_ROUND, ImGuiTableColumnFlags, ImGuiTreeNodeFlags, PopStyleCompact, PushStyleCompact, IM_ASSERT_PARANOID, ImU16, ExampleNames, ImGuiWindowFlags, ImGuiItemFlags, ImGui_ImplRoblox_GetBackendData, stbte, ImColor, ImCos, ImGuiButtonFlags, ImGuiDebugLogFlags, ImGuiLocKey, ImU32, ExampleTreeFuncs, ImGuiListClipper, ImS16, _PathArcToFastExXY, ImGuiMultiSelectFlags, ImSin, ImGuiTabBarFlags, ImUpperPowerOfTwo, IM_F32_TO_INT8_SAT, ImFontAtlasPackGetRect, DockSettingsRenameNodeReferences, ExampleDualListBoxMT, IM_DRAWLIST_TEX_LINES_WIDTH_MAX, ImCeil, ImGuiCol, ImGuiSelectionBasicStorage, ImLengthSqr, ImS8, ImU8, ExampleAppPropertyEditorMT, ImFabs, ImGuiChildFlags, ImGuiLastItemData_Copy, ImGuiScrollFlags, ImLog, ImMemchr, ImStrByte, ExampleSelectionWithDeletionMT, IMGUI_DEBUG_LOG_VIEWPORT, ImGuiInputEvent, ImGuiTextBuffer, ImPow, ImTrunc64, CustomConstraints, ExampleAppLogMT, IMGUI_DEBUG_LOG_FONT, IMGUI_DEBUG_LOG_SELECTION, ImAddClampOverflow, ImFontAtlasBuildInit, ImFontCalcWordWrapPositionEx, ImGuiComboFlags, ImGuiLastItemData, ImGuiPayload_IsDataType, ImGuiPopupFlags, ImGuiSliderFlags, ImGuiTextFilter, ImRotate, ImSqrt, ImSubClampOverflow, ImTextClassifierSetCharClass, MyDocument, ShowExampleMenuFile, CalcCornerArcStepAndCount, CalcNextScrollFromScrollTargetAndClamp, IMGUI_PAYLOAD_TYPE_WINDOW, IMGUI_VERSION, ImCharIsBlankW, ImCharIsSeparatorW, ImFmod, ImFontAtlasBakedAddFontGlyph, ImFontAtlasPackAddRect, ImFontBaked_BuildLoadGlyph, ImGuiInputTextFlags, ImGuiNavMoveFlags, ImGuiStyle_Copy, ImHashData, ImVec1_Copy, ExampleAsset_s_current_sort_specs, ExampleMemberInfo, ExampleTree_CreateNode, IMGUI_PAYLOAD_TYPE_COLOR_4F, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC, IM_F32_TO_INT8_UNBOUND, IM_PI, ImCharIsBlankA, ImFontAtlasBuildRenderBitmapFromString, ImFontAtlasFontDestroyOutput, ImFontAtlasFontDiscardBakes, ImFontAtlasFontSourceAddToFont, ImFontAtlasFontSourceInit, ImFontAtlasRectId_GetIndex, ImFontAtlasTextureAdd, ImFontAtlasTextureBlockQueueUpload, ImFontAtlasTextureGrow, ImFontBaked_BuildGrowIndex, ImFontConfig, ImFontGlyph, ImGuiTableColumn, ImGuiWindowClass, ImGui_ImplRoblox_RenderDrawData, ImParseFormatFindStart, ImRect_CopyFromV4, ImTextureRect, ImTextureRef, MyItem_s_current_sort_specs, stb_textedit_key, stbtt_GetGlyphBitmapBoxSubpixel, DockSettingsHandler_ClearAll, EditTableSizingFlags, ExampleSelectionWithDeletion, IMGUI_DEBUG_LOG_TABLE, IMGUI_PAYLOAD_TYPE_COLOR_3F, IM_FREE, ImDrawListSplitter, ImFontAtlasBakedDiscard, ImFontAtlasBuildDestroy, ImFontAtlasBuildNotifySetFont, ImFontAtlasBuildSetTexture, ImFontAtlasBuildSetupFontBakedFallback, ImFontAtlasFontDestroySourceData, ImFontAtlasPackInit, ImFontAtlasRect
|
local ImGui, ImVec2, ImVec4, ImRect, HelpMarker, ImVec2_Copy, IMGUI_DEMO_MARKER, ImGuiTableFlags, ImStd, ImVector, ImDrawFlags, ImGuiInputFlags, ImRect_Copy, ImGuiDataType, ImStb, IM_TRUNC, ImGuiKey, ImVec2_CopyV, ImGuiStyleVarInfo, IM_ASSERT_USER_ERROR, ImGuiHoveredFlags, ImFormatString, IM_ASSERT_USER_ERROR_RET, ImHashStr, ImS32, ImGuiColorEditFlags, ImIsPowerOfTwo, ImAbs, ImVec4_Copy, ExampleAppConsoleMT, IM_ROUND, ImGuiTableColumnFlags, ImGuiTreeNodeFlags, PopStyleCompact, PushStyleCompact, IM_ASSERT_PARANOID, ImU16, ExampleNames, ImGuiWindowFlags, ImGuiItemFlags, ImGui_ImplRoblox_GetBackendData, stbte, ImColor, ImCos, ImGuiButtonFlags, ImGuiDebugLogFlags, ImGuiLocKey, ImU32, ExampleTreeFuncs, ImGuiListClipper, ImS16, _PathArcToFastExXY, ImGuiMultiSelectFlags, ImSin, ImGuiTabBarFlags, ImUpperPowerOfTwo, IM_F32_TO_INT8_SAT, ImFontAtlasPackGetRect, DockSettingsRenameNodeReferences, ExampleDualListBoxMT, IM_DRAWLIST_TEX_LINES_WIDTH_MAX, ImCeil, ImFabs, ImGuiCol, ImGuiSelectionBasicStorage, ImLengthSqr, ImS8, ImU8, ExampleAppPropertyEditorMT, ImGuiChildFlags, ImGuiLastItemData_Copy, ImGuiScrollFlags, ImLog, ImMemchr, ImStrByte, ExampleSelectionWithDeletionMT, IMGUI_DEBUG_LOG_VIEWPORT, ImGuiInputEvent, ImGuiTextBuffer, ImPow, ImTrunc64, CustomConstraints, ExampleAppLogMT, IMGUI_DEBUG_LOG_FONT, IMGUI_DEBUG_LOG_SELECTION, ImAddClampOverflow, ImFontAtlasBuildInit, ImFontCalcWordWrapPositionEx, ImGuiComboFlags, ImGuiLastItemData, ImGuiPayload_IsDataType, ImGuiPopupFlags, ImGuiSliderFlags, ImGuiTextFilter, ImRotate, ImSqrt, ImSubClampOverflow, ImTextClassifierSetCharClass, MyDocument, ShowExampleMenuFile, CalcCornerArcStepAndCount, CalcNextScrollFromScrollTargetAndClamp, IMGUI_PAYLOAD_TYPE_WINDOW, IMGUI_VERSION, ImCharIsBlankW, ImCharIsSeparatorW, ImFmod, ImFontAtlasBakedAddFontGlyph, ImFontAtlasPackAddRect, ImFontBaked_BuildLoadGlyph, ImGuiInputTextFlags, ImGuiNavMoveFlags, ImGuiStyle_Copy, ImHashData, ImVec1_Copy, ExampleAsset_s_current_sort_specs, ExampleMemberInfo, ExampleTree_CreateNode, IMGUI_PAYLOAD_TYPE_COLOR_4F, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC, IM_F32_TO_INT8_UNBOUND, IM_PI, ImCharIsBlankA, ImFontAtlasBuildRenderBitmapFromString, ImFontAtlasFontDestroyOutput, ImFontAtlasFontDiscardBakes, ImFontAtlasFontSourceAddToFont, ImFontAtlasFontSourceInit, ImFontAtlasRectId_GetIndex, ImFontAtlasTextureAdd, ImFontAtlasTextureBlockQueueUpload, ImFontAtlasTextureGrow, ImFontBaked_BuildGrowIndex, ImFontConfig, ImFontGlyph, ImGuiTableColumn, ImGuiWindowClass, ImGui_ImplRoblox_RenderDrawData, ImParseFormatFindStart, ImRect_CopyFromV4, ImTextureRect, ImTextureRef, MyItem_s_current_sort_specs, stb_textedit_key, stbtt_GetGlyphBitmapBoxSubpixel, DockSettingsHandler_ClearAll, EditTableSizingFlags, ExampleSelectionWithDeletion, IMGUI_DEBUG_LOG_TABLE, IMGUI_PAYLOAD_TYPE_COLOR_3F, IM_FREE, ImDrawListSplitter, ImFontAtlasBakedDiscard, ImFontAtlasBuildDestroy, ImFontAtlasBuildNotifySetFont, ImFontAtlasBuildSetTexture, ImFontAtlasBuildSetupFontBakedFallback, ImFontAtlasFontDestroySourceData, ImFontAtlasPackInit, ImFontAtlasRect
|
||||||
local type, mathMin, mathMax, mathFloor, mathCeil, bitOr, bitLShift = type, math.min, math.max, math.floor, math.ceil, bit32.bor, bit32.lshift
|
local type, mathMin, mathMax, mathFloor, mathCeil, bitOr, bitLShift = type, math.min, math.max, math.floor, math.ceil, bit32.bor, bit32.lshift
|
||||||
local function IM_COL32(R, G, B, A) return (bitOr(bitLShift(A, 24 --[[IM_COL32_A_SHIFT]]), bitLShift(B, 16 --[[IM_COL32_B_SHIFT]]), bitLShift(G, 8 --[[IM_COL32_G_SHIFT]]), bitLShift(R, 0 --[[IM_COL32_R_SHIFT]]))) end
|
local function IM_COL32(R, G, B, A) return (bitOr(bitLShift(A, 24 --[[IM_COL32_A_SHIFT]]), bitLShift(B, 16 --[[IM_COL32_B_SHIFT]]), bitLShift(G, 8 --[[IM_COL32_G_SHIFT]]), bitLShift(R, 0 --[[IM_COL32_R_SHIFT]]))) end
|
||||||
@native
|
@native
|
||||||
@@ -40772,47 +40772,341 @@ function MT.ImDrawList:PathBezierQuadraticCurveTo(p2, p3, num_segments)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ponytail: ear-clipping, no anti-aliased fringe (upstream's AA triangulator not ported). O(n^2) is fine for UI polygons.
|
--------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] ImTriangulator, ImDrawList concave polygon fill
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity.
|
||||||
|
-- Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
|
||||||
|
-- Provided as a convenience for user but not used by main library.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- - ImTriangulator [Internal]
|
||||||
|
-- - AddConcavePolyFilled()
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local ImTriangulatorNodeType =
|
||||||
|
{
|
||||||
|
Convex = 0,
|
||||||
|
Ear = 1,
|
||||||
|
Reflex = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- [Luau] No pointers: a node is an int handle (1-based slot) into the parallel arrays of its ImTriangulator
|
||||||
|
-- (tri.Type[n], tri.Index[n], tri.Pos[n], tri.Next[n], tri.Prev[n]). node->Index (0-based, as upstream) == n - 1.
|
||||||
|
local function ImTriangulatorNode_Unlink(tri, n) tri.Prev[tri.Next[n]] = tri.Prev[n]; tri.Next[tri.Prev[n]] = tri.Next[n] end
|
||||||
|
|
||||||
|
-- [Luau] Deviation: upstream classifies a node as reflex when '!ImTriangleIsClockwise()', i.e. also when its corner is
|
||||||
|
-- degenerate (collinear or duplicate points). A duplicate point then sits as a reflex on top of every candidate ear's vertex
|
||||||
|
-- and blocks it, ending in the degenerate fallback with overlapping triangles. Only strictly counter-clockwise corners are
|
||||||
|
-- reflex here: degenerate corners are clipped as zero-area ears.
|
||||||
|
local function ImTriangulator_IsReflex(a, b, c) return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) < 0.0 end
|
||||||
|
|
||||||
|
local function ImTriangulatorNodeSpan()
|
||||||
|
return { Data = {}, Size = 0 } -- Data: node handles, 1-based
|
||||||
|
end
|
||||||
|
MT.ImTriangulatorNodeSpan = {}
|
||||||
|
MT.ImTriangulatorNodeSpan.__index = MT.ImTriangulatorNodeSpan
|
||||||
|
function MT.ImTriangulatorNodeSpan:push_back(node) self.Size = self.Size + 1; self.Data[self.Size] = node end
|
||||||
|
function MT.ImTriangulatorNodeSpan:find_erase_unsorted(idx) for i = self.Size, 1, -1 do if self.Data[i] - 1 == idx then self.Data[i] = self.Data[self.Size]; self.Size = self.Size - 1; return end end end
|
||||||
|
|
||||||
|
-- [Luau] The node/ears/reflexes storage (upstream: carved out of _Data->TempBuffer via scratch_buffer) is owned by the
|
||||||
|
-- triangulator itself and only ever grows. AddConcavePolyFilled() reuses a single module-level instance (no per-call allocations).
|
||||||
|
local function ImTriangulator()
|
||||||
|
return setmetatable({
|
||||||
|
_TrianglesLeft = 0,
|
||||||
|
_Nodes = 0, -- node handle (head of the circular list)
|
||||||
|
_Ears = setmetatable(ImTriangulatorNodeSpan(), MT.ImTriangulatorNodeSpan),
|
||||||
|
_Reflexes = setmetatable(ImTriangulatorNodeSpan(), MT.ImTriangulatorNodeSpan),
|
||||||
|
Type = {}, Index = {}, Pos = {}, Next = {}, Prev = {}, -- [Luau] ImTriangulatorNode fields, one array each
|
||||||
|
}, MT.ImTriangulator)
|
||||||
|
end
|
||||||
|
MT.ImTriangulator = {}
|
||||||
|
MT.ImTriangulator.__index = MT.ImTriangulator
|
||||||
|
|
||||||
|
function MT.ImTriangulator.EstimateTriangleCount(points_count) return (points_count < 3) and 0 or points_count - 2 end
|
||||||
|
-- [Luau] In elements (nodes + ears + reflexes) rather than bytes. Unused by the port: arrays grow on demand.
|
||||||
|
function MT.ImTriangulator.EstimateScratchBufferSize(points_count) return points_count + points_count * 2 end
|
||||||
|
|
||||||
|
-- Distribute storage for nodes, ears and reflexes.
|
||||||
|
-- FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer
|
||||||
|
-- (this would require first building reflexes to bail to convex if empty, without even building nodes)
|
||||||
--- @param points ImVec2[] # 1-based
|
--- @param points ImVec2[] # 1-based
|
||||||
function MT.ImDrawList:AddConcavePolyFilled(points, points_count, col)
|
function MT.ImTriangulator:Init(points, points_count)
|
||||||
if points_count < 3 or bit32.band(col, 4278190080 --[[IM_COL32_A_MASK]]) == 0 then return end
|
assert(points_count >= 3)
|
||||||
local idx = {}
|
self._TrianglesLeft = MT.ImTriangulator.EstimateTriangleCount(points_count)
|
||||||
local area = 0.0
|
self._Nodes = 1
|
||||||
|
self._Ears.Size = 0
|
||||||
|
self._Reflexes.Size = 0
|
||||||
|
self:BuildNodes(points, points_count)
|
||||||
|
|
||||||
|
-- [Luau] Deviation: upstream only flips the node list when no ear is found, so a counter-clockwise *concave* polygon
|
||||||
|
-- (whose reflex corners look like ears) yields triangles outside of it. Normalize to clockwise order up-front (O(N)).
|
||||||
|
local area2 = 0.0
|
||||||
|
local p0 = points[points_count]
|
||||||
for i = 1, points_count do
|
for i = 1, points_count do
|
||||||
idx[i] = i
|
local p1 = points[i]
|
||||||
local a, b = points[i], points[i % points_count + 1]
|
area2 = area2 + (p0.x * p1.y - p1.x * p0.y)
|
||||||
area = area + (a.x * b.y - b.x * a.y)
|
p0 = p1
|
||||||
end
|
end
|
||||||
local sign = (area >= 0) and 1 or -1
|
if area2 < 0.0 then
|
||||||
local function cross(o, a, b) return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x) end
|
self:FlipNodeList()
|
||||||
local guard = 0
|
end
|
||||||
while #idx > 3 and guard < points_count * points_count do
|
|
||||||
guard = guard + 1
|
self:BuildReflexes()
|
||||||
local n = #idx
|
self:BuildEars()
|
||||||
local clipped = false
|
end
|
||||||
for i = 1, n do
|
|
||||||
local ia, ib, ic = idx[(i - 2) % n + 1], idx[i], idx[i % n + 1]
|
function MT.ImTriangulator:BuildNodes(points, points_count)
|
||||||
local a, b, c = points[ia], points[ib], points[ic]
|
local Type, Index, Pos, Next, Prev = self.Type, self.Index, self.Pos, self.Next, self.Prev
|
||||||
if cross(a, b, c) * sign > 0 then
|
for i = 1, points_count do
|
||||||
local inside = false
|
Type[i] = ImTriangulatorNodeType.Convex
|
||||||
for j = 1, n do
|
Index[i] = i - 1
|
||||||
local p = idx[j]
|
Pos[i] = points[i] -- [Luau] reference, not a copy (points are not modified while triangulating)
|
||||||
if p ~= ia and p ~= ib and p ~= ic then
|
Next[i] = i + 1
|
||||||
local q = points[p]
|
Prev[i] = i - 1
|
||||||
if cross(a, b, q) * sign >= 0 and cross(b, c, q) * sign >= 0 and cross(c, a, q) * sign >= 0 then inside = true; break end
|
end
|
||||||
end
|
Prev[1] = points_count
|
||||||
end
|
Next[points_count] = 1
|
||||||
if not inside then
|
end
|
||||||
self:AddTriangleFilled(a, b, c, col)
|
|
||||||
table.remove(idx, i)
|
function MT.ImTriangulator:BuildReflexes()
|
||||||
clipped = true
|
local Pos, Next, Prev = self.Pos, self.Next, self.Prev
|
||||||
break
|
local n1 = self._Nodes
|
||||||
end
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
if ImTriangulator_IsReflex(Pos[Prev[n1]], Pos[n1], Pos[Next[n1]]) then
|
||||||
|
self.Type[n1] = ImTriangulatorNodeType.Reflex
|
||||||
|
self._Reflexes:push_back(n1)
|
||||||
|
end
|
||||||
|
n1 = Next[n1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:BuildEars()
|
||||||
|
local Index, Pos, Next, Prev = self.Index, self.Pos, self.Next, self.Prev
|
||||||
|
local n1 = self._Nodes
|
||||||
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
if self.Type[n1] == ImTriangulatorNodeType.Convex then
|
||||||
|
local n0, n2 = Prev[n1], Next[n1]
|
||||||
|
if self:IsEar(Index[n0], Index[n1], Index[n2], Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
self.Type[n1] = ImTriangulatorNodeType.Ear
|
||||||
|
self._Ears:push_back(n1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not clipped then break end
|
n1 = Next[n1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [Luau] out_triangle[3] is returned as 3 values (relative 0-based indexes)
|
||||||
|
function MT.ImTriangulator:GetNextTriangle()
|
||||||
|
if self._Ears.Size == 0 then
|
||||||
|
self:FlipNodeList()
|
||||||
|
|
||||||
|
local node = self._Nodes
|
||||||
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
self.Type[node] = ImTriangulatorNodeType.Convex
|
||||||
|
node = self.Next[node]
|
||||||
|
end
|
||||||
|
self._Reflexes.Size = 0
|
||||||
|
self:BuildReflexes()
|
||||||
|
self:BuildEars()
|
||||||
|
|
||||||
|
-- If we still don't have ears, it means geometry is degenerated.
|
||||||
|
if self._Ears.Size == 0 then
|
||||||
|
-- Return first triangle available, mimicking the behavior of convex fill.
|
||||||
|
assert(self._TrianglesLeft > 0) -- Geometry is degenerated
|
||||||
|
self._Ears.Data[1] = self._Nodes
|
||||||
|
self._Ears.Size = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ear = self._Ears.Data[self._Ears.Size]
|
||||||
|
self._Ears.Size = self._Ears.Size - 1
|
||||||
|
local Index, Next, Prev = self.Index, self.Next, self.Prev
|
||||||
|
local t0, t1, t2 = Index[Prev[ear]], Index[ear], Index[Next[ear]]
|
||||||
|
|
||||||
|
ImTriangulatorNode_Unlink(self, ear)
|
||||||
|
if ear == self._Nodes then
|
||||||
|
self._Nodes = Next[ear]
|
||||||
|
end
|
||||||
|
|
||||||
|
self:ReclassifyNode(Prev[ear])
|
||||||
|
self:ReclassifyNode(Next[ear])
|
||||||
|
self._TrianglesLeft = self._TrianglesLeft - 1
|
||||||
|
return t0, t1, t2
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:FlipNodeList()
|
||||||
|
local Next, Prev = self.Next, self.Prev
|
||||||
|
local nodes = self._Nodes
|
||||||
|
local prev = nodes
|
||||||
|
local temp = nodes
|
||||||
|
local current = Next[nodes]
|
||||||
|
Next[prev] = prev
|
||||||
|
Prev[prev] = prev
|
||||||
|
while current ~= nodes do
|
||||||
|
temp = Next[current]
|
||||||
|
|
||||||
|
Next[current] = prev
|
||||||
|
Prev[prev] = current
|
||||||
|
Next[nodes] = current
|
||||||
|
Prev[current] = nodes
|
||||||
|
|
||||||
|
prev = current
|
||||||
|
current = temp
|
||||||
|
end
|
||||||
|
self._Nodes = prev
|
||||||
|
end
|
||||||
|
|
||||||
|
-- A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm)
|
||||||
|
function MT.ImTriangulator:IsEar(i0, i1, i2, v0, v1, v2)
|
||||||
|
local Index, Pos = self.Index, self.Pos
|
||||||
|
local data = self._Reflexes.Data
|
||||||
|
for p = 1, self._Reflexes.Size do
|
||||||
|
local reflex = data[p]
|
||||||
|
local idx = Index[reflex]
|
||||||
|
if idx ~= i0 and idx ~= i1 and idx ~= i2 then
|
||||||
|
if ImStd.ImTriangleContainsPoint(v0, v1, v2, Pos[reflex]) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:ReclassifyNode(n1)
|
||||||
|
-- Classify node
|
||||||
|
local type
|
||||||
|
local n0 = self.Prev[n1]
|
||||||
|
local n2 = self.Next[n1]
|
||||||
|
local Index, Pos = self.Index, self.Pos
|
||||||
|
if ImTriangulator_IsReflex(Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
type = ImTriangulatorNodeType.Reflex
|
||||||
|
elseif self:IsEar(Index[n0], Index[n1], Index[n2], Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
type = ImTriangulatorNodeType.Ear
|
||||||
|
else
|
||||||
|
type = ImTriangulatorNodeType.Convex
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update lists when a type changes
|
||||||
|
local n1_type = self.Type[n1]
|
||||||
|
if type == n1_type then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if n1_type == ImTriangulatorNodeType.Reflex then
|
||||||
|
self._Reflexes:find_erase_unsorted(Index[n1])
|
||||||
|
elseif n1_type == ImTriangulatorNodeType.Ear then
|
||||||
|
self._Ears:find_erase_unsorted(Index[n1])
|
||||||
|
end
|
||||||
|
if type == ImTriangulatorNodeType.Reflex then
|
||||||
|
self._Reflexes:push_back(n1)
|
||||||
|
elseif type == ImTriangulatorNodeType.Ear then
|
||||||
|
self._Ears:push_back(n1)
|
||||||
|
end
|
||||||
|
self.Type[n1] = type
|
||||||
|
end
|
||||||
|
|
||||||
|
local concave_triangulator = ImTriangulator() -- [Luau] reused scratch (see ImTriangulator())
|
||||||
|
|
||||||
|
-- Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes).
|
||||||
|
-- (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer!
|
||||||
|
-- It is up to caller to ensure not making costly calls that will be outside of visible area.
|
||||||
|
-- As concave fill is noticeably more expensive than other primitives, be mindful of this...
|
||||||
|
-- Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false')
|
||||||
|
--- @param points ImVec2[] # 1-based
|
||||||
|
--- @param points_count int
|
||||||
|
--- @param col ImU32
|
||||||
|
@native
|
||||||
|
function MT.ImDrawList:AddConcavePolyFilled(points, points_count, col)
|
||||||
|
if points_count < 3 or bit32.band(col, 4278190080 --[[IM_COL32_A_MASK]]) == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local uv = self._Data.TexUvWhitePixel
|
||||||
|
local uv_x, uv_y = uv.x, uv.y
|
||||||
|
local triangulator = concave_triangulator
|
||||||
|
if bit32.band(self.Flags, 4096 --[[ImDrawFlags.AAFill]]) ~= 0 then
|
||||||
|
-- Anti-aliased Fill
|
||||||
|
local AA_SIZE = self._FringeScale
|
||||||
|
local col_trans = bit32.band(col, bit32.bnot(4278190080 --[[IM_COL32_A_MASK]]))
|
||||||
|
local idx_count = (points_count - 2) * 3 + points_count * 6
|
||||||
|
local vtx_count = (points_count * 2)
|
||||||
|
PrimReserve(self, idx_count, vtx_count)
|
||||||
|
local vb = self.VtxBuffer.Buf
|
||||||
|
local ib = self.IdxBuffer.Data
|
||||||
|
local vw = self._VtxWritePtr
|
||||||
|
local iw = self._IdxWritePtr
|
||||||
|
|
||||||
|
-- Add indexes for fill
|
||||||
|
local vtx_inner_idx = self._VtxCurrentIdx
|
||||||
|
local vtx_outer_idx = self._VtxCurrentIdx + 1
|
||||||
|
|
||||||
|
triangulator:Init(points, points_count)
|
||||||
|
while triangulator._TrianglesLeft > 0 do
|
||||||
|
local t0, t1, t2 = triangulator:GetNextTriangle()
|
||||||
|
ib[iw + 0] = vtx_inner_idx + t0 * 2; ib[iw + 1] = vtx_inner_idx + t1 * 2; ib[iw + 2] = vtx_inner_idx + t2 * 2
|
||||||
|
iw = iw + 3
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Compute normals
|
||||||
|
-- [Luau] scratch arrays (see AddPolyline) instead of _Data->TempBuffer. Indexes below are 1-based.
|
||||||
|
local temp_normals_x, temp_normals_y = poly_normals_x, poly_normals_y
|
||||||
|
local i0 = points_count
|
||||||
|
for i1 = 1, points_count do
|
||||||
|
local p0 = points[i0]
|
||||||
|
local p1 = points[i1]
|
||||||
|
local dx, dy = IM_NORMALIZE2F_OVER_ZERO(p1.x - p0.x, p1.y - p0.y)
|
||||||
|
temp_normals_x[i0] = dy
|
||||||
|
temp_normals_y[i0] = -dx
|
||||||
|
i0 = i1
|
||||||
|
end
|
||||||
|
|
||||||
|
i0 = points_count
|
||||||
|
for i1 = 1, points_count do
|
||||||
|
-- Average normals
|
||||||
|
local dm_x, dm_y = IM_FIXNORMAL2F((temp_normals_x[i0] + temp_normals_x[i1]) * 0.5, (temp_normals_y[i0] + temp_normals_y[i1]) * 0.5)
|
||||||
|
dm_x = dm_x * AA_SIZE * 0.5
|
||||||
|
dm_y = dm_y * AA_SIZE * 0.5
|
||||||
|
|
||||||
|
-- Add vertices
|
||||||
|
local p1 = points[i1]
|
||||||
|
WV(vb, vw, p1.x - dm_x, p1.y - dm_y, uv_x, uv_y, col) -- Inner
|
||||||
|
WV(vb, vw + 1, p1.x + dm_x, p1.y + dm_y, uv_x, uv_y, col_trans) -- Outer
|
||||||
|
vw = vw + 2
|
||||||
|
|
||||||
|
-- Add indexes for fringes
|
||||||
|
local e0, e1 = (i0 - 1) * 2, (i1 - 1) * 2
|
||||||
|
ib[iw + 0] = vtx_inner_idx + e1; ib[iw + 1] = vtx_inner_idx + e0; ib[iw + 2] = vtx_outer_idx + e0
|
||||||
|
ib[iw + 3] = vtx_outer_idx + e0; ib[iw + 4] = vtx_outer_idx + e1; ib[iw + 5] = vtx_inner_idx + e1
|
||||||
|
iw = iw + 6
|
||||||
|
i0 = i1
|
||||||
|
end
|
||||||
|
self._VtxWritePtr = vw
|
||||||
|
self._IdxWritePtr = iw
|
||||||
|
self._VtxCurrentIdx = self._VtxCurrentIdx + vtx_count
|
||||||
|
else
|
||||||
|
-- Non Anti-aliased Fill
|
||||||
|
local idx_count = (points_count - 2) * 3
|
||||||
|
local vtx_count = points_count
|
||||||
|
PrimReserve(self, idx_count, vtx_count)
|
||||||
|
local vb = self.VtxBuffer.Buf
|
||||||
|
local ib = self.IdxBuffer.Data
|
||||||
|
local vw = self._VtxWritePtr
|
||||||
|
local iw = self._IdxWritePtr
|
||||||
|
for i = 1, vtx_count do
|
||||||
|
local p = points[i]
|
||||||
|
WV(vb, vw, p.x, p.y, uv_x, uv_y, col)
|
||||||
|
vw = vw + 1
|
||||||
|
end
|
||||||
|
local base_idx = self._VtxCurrentIdx
|
||||||
|
triangulator:Init(points, points_count)
|
||||||
|
while triangulator._TrianglesLeft > 0 do
|
||||||
|
local t0, t1, t2 = triangulator:GetNextTriangle()
|
||||||
|
ib[iw + 0] = base_idx + t0; ib[iw + 1] = base_idx + t1; ib[iw + 2] = base_idx + t2
|
||||||
|
iw = iw + 3
|
||||||
|
end
|
||||||
|
self._VtxWritePtr = vw
|
||||||
|
self._IdxWritePtr = iw
|
||||||
|
self._VtxCurrentIdx = base_idx + vtx_count
|
||||||
end
|
end
|
||||||
if #idx == 3 then self:AddTriangleFilled(points[idx[1]], points[idx[2]], points[idx[3]], col) end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function MT.ImDrawList:PathFillConcave(col)
|
function MT.ImDrawList:PathFillConcave(col)
|
||||||
@@ -52244,6 +52538,18 @@ function ImMul(lhs, rhs)
|
|||||||
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
|
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param a ImVec2
|
||||||
|
--- @param b ImVec2
|
||||||
|
--- @param c ImVec2
|
||||||
|
--- @return float
|
||||||
|
function ImTriangleArea(a, b, c) return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5 end
|
||||||
|
|
||||||
|
--- @param a ImVec2
|
||||||
|
--- @param b ImVec2
|
||||||
|
--- @param c ImVec2
|
||||||
|
--- @return boolean
|
||||||
|
function ImTriangleIsClockwise(a, b, c) return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) > 0.0 end
|
||||||
|
|
||||||
--- @param str char[]
|
--- @param str char[]
|
||||||
--- @param begin? int
|
--- @param begin? int
|
||||||
function ImStd.ImStrlen(str, begin)
|
function ImStd.ImStrlen(str, begin)
|
||||||
@@ -78237,6 +78543,8 @@ return {
|
|||||||
ImTextureRef = ImTextureRef,
|
ImTextureRef = ImTextureRef,
|
||||||
ImTextureStatus = ImTextureStatus,
|
ImTextureStatus = ImTextureStatus,
|
||||||
ImToUpper = ImToUpper,
|
ImToUpper = ImToUpper,
|
||||||
|
ImTriangleArea = ImTriangleArea,
|
||||||
|
ImTriangleIsClockwise = ImTriangleIsClockwise,
|
||||||
ImTrunc = ImTrunc,
|
ImTrunc = ImTrunc,
|
||||||
ImTrunc64 = ImTrunc64,
|
ImTrunc64 = ImTrunc64,
|
||||||
ImU16 = ImU16,
|
ImU16 = ImU16,
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[[183, "imgui.lua"], [21603, "imgui_demo.lua"], [33455, "imgui_draw.lua"], [40964, "imgui_h.lua"], [43870, "imgui_impl_love.lua"], [44410, "imgui_internal.lua"], [48120, "imgui_tables.lua"], [53179, "imgui_widgets.lua"], [65155, "imstb_rectpack.lua"], [65819, "imstb_textedit.lua"], [67361, "imstb_truetype.lua"], [70149, "imstd_minstdio.lua"]]
|
[[183, "imgui.lua"], [21603, "imgui_demo.lua"], [33455, "imgui_draw.lua"], [41258, "imgui_h.lua"], [44164, "imgui_impl_love.lua"], [44704, "imgui_internal.lua"], [48426, "imgui_tables.lua"], [53485, "imgui_widgets.lua"], [65461, "imstb_rectpack.lua"], [66125, "imstb_textedit.lua"], [67667, "imstb_truetype.lua"], [70455, "imstd_minstdio.lua"]]
|
||||||
+344
-36
@@ -138,7 +138,7 @@ if not utf8 then
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local ImGui, ImVec2, ImVec4, ImRect, HelpMarker, ImVec2_Copy, IMGUI_DEMO_MARKER, ImGuiTableFlags, ImStd, ImVector, ImGuiKey, ImDrawFlags, ImGuiInputFlags, ImRect_Copy, ImGuiDataType, ImStb, IM_TRUNC, ImVec2_CopyV, ImGuiStyleVarInfo, IM_ASSERT_USER_ERROR, ImGuiHoveredFlags, ImFormatString, IM_ASSERT_USER_ERROR_RET, ImHashStr, ImS32, ImGuiColorEditFlags, ImIsPowerOfTwo, ImAbs, ImVec4_Copy, ExampleAppConsoleMT, IM_ROUND, ImGuiTableColumnFlags, ImGuiTreeNodeFlags, PopStyleCompact, PushStyleCompact, IM_ASSERT_PARANOID, ImU16, ExampleNames, ImGuiWindowFlags, ImGuiItemFlags, stbte, ImColor, ImCos, ImGuiButtonFlags, ImGuiDebugLogFlags, ImGuiLocKey, ImU32, ExampleTreeFuncs, ImGuiListClipper, ImS16, _PathArcToFastExXY, ImGuiMultiSelectFlags, ImSin, ImGuiTabBarFlags, ImUpperPowerOfTwo, IM_F32_TO_INT8_SAT, ImFontAtlasPackGetRect, ImGuiMouseCursor, DockSettingsRenameNodeReferences, ExampleDualListBoxMT, IM_DRAWLIST_TEX_LINES_WIDTH_MAX, ImCeil, ImGuiCol, ImGuiSelectionBasicStorage, ImLengthSqr, ImS8, ImU8, ExampleAppPropertyEditorMT, ImFabs, ImGuiScrollFlags, ImGui_ImplLOVE_GetBackendData, ImLog, ExampleSelectionWithDeletionMT, CustomConstraints, ExampleAppLogMT, ImFontAtlasBuildInit, ImGuiComboFlags, ImGuiPopupFlags, ImGuiSliderFlags, ImTextClassifierSetCharClass, MyDocument, ShowExampleMenuFile, CalcCornerArcStepAndCount, ImFontAtlasBakedAddFontGlyph, ImFontAtlasPackAddRect, ImFontBaked_BuildLoadGlyph, ImGuiInputTextFlags, ImGuiStyle_Copy, ExampleAsset_s_current_sort_specs, ExampleMemberInfo, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC, ImFontAtlasBuildRenderBitmapFromString, ImFontAtlasFontDestroyOutput, ImFontAtlasFontSourceAddToFont, ImFontAtlasFontSourceInit, ImFontAtlasTextureAdd, ImFontAtlasTextureBlockQueueUpload, ImFontBaked_BuildGrowIndex, ImGuiTableColumn, stb_textedit_key, stbtt_GetGlyphBitmapBoxSubpixel, IM_FREE, ImDrawListSplitter, ImGuiDragDropFlags, ImGuiFocusedFlags, stb_text_locate_coord, stb_text_makeundo_insert, stb_text_makeundo_replace, stb_textedit_find_charpos, stbtt_GetGlyphShape, IM_ALLOC, ImGuiTableColumnSortSpecs, ImGuiTableInstanceData, ImGuiTableSettings, stb_text_makeundo_delete, stb_text_redo, stb_text_undo, stb_textedit_click, stb_textedit_drag, stbtt_FindGlyphIndex, stbtt_GetFontOffsetForIndex, stbtt_GetFontVMetrics, stbtt_GetGlyphBitmapBox, stbtt_GetGlyphHMetrics, stbtt_InitFont, stbtt_MakeGlyphBitmapSubpixelPrefilter, stbtt_ScaleForPixelHeight, stbtt__GetGlyphInfoT2, stbtt__GetGlyphShapeT2, stbtt_fontinfo, ImGuiOldColumnData, ImGuiOldColumnFlags, ImGuiOldColumns, ImGuiTable, ImGuiTableColumnSettings, ImGuiTableSortSpecs, ImGuiTableTempData, ImGui_ImplLOVE_CreateTexture, ImGui_ImplLOVE_DestroyTexture, ImGui_ImplLOVE_Init, ImGui_ImplLOVE_NewFrame, ImGui_ImplLOVE_RenderDrawData, ImGui_ImplLOVE_Shutdown, ImGui_ImplLOVE_UpdateTexture, stbrp_init_target, IMGUI_TABLE_MAX_COLUMNS, IMSTB_TEXTEDIT_UNDOSTATECOUNT, IM_COL32_DISABLE, ImGui_ImplLove, STB_TEXTEDIT_K_BACKSPACE, STB_TEXTEDIT_K_DELETE, STB_TEXTEDIT_K_DOWN, STB_TEXTEDIT_K_LEFT, STB_TEXTEDIT_K_LINEEND, STB_TEXTEDIT_K_LINESTART, STB_TEXTEDIT_K_PGDOWN, STB_TEXTEDIT_K_PGUP, STB_TEXTEDIT_K_REDO, STB_TEXTEDIT_K_RIGHT, STB_TEXTEDIT_K_SHIFT
|
local ImGui, ImVec2, ImVec4, ImRect, HelpMarker, ImVec2_Copy, IMGUI_DEMO_MARKER, ImGuiTableFlags, ImStd, ImVector, ImGuiKey, ImDrawFlags, ImGuiInputFlags, ImRect_Copy, ImGuiDataType, ImStb, IM_TRUNC, ImVec2_CopyV, ImGuiStyleVarInfo, IM_ASSERT_USER_ERROR, ImGuiHoveredFlags, ImFormatString, IM_ASSERT_USER_ERROR_RET, ImHashStr, ImS32, ImGuiColorEditFlags, ImIsPowerOfTwo, ImAbs, ImVec4_Copy, ExampleAppConsoleMT, IM_ROUND, ImGuiTableColumnFlags, ImGuiTreeNodeFlags, PopStyleCompact, PushStyleCompact, IM_ASSERT_PARANOID, ImU16, ExampleNames, ImGuiWindowFlags, ImGuiItemFlags, stbte, ImColor, ImCos, ImGuiButtonFlags, ImGuiDebugLogFlags, ImGuiLocKey, ImU32, ExampleTreeFuncs, ImGuiListClipper, ImS16, _PathArcToFastExXY, ImGuiMultiSelectFlags, ImSin, ImGuiTabBarFlags, ImUpperPowerOfTwo, IM_F32_TO_INT8_SAT, ImFontAtlasPackGetRect, ImGuiMouseCursor, DockSettingsRenameNodeReferences, ExampleDualListBoxMT, IM_DRAWLIST_TEX_LINES_WIDTH_MAX, ImCeil, ImFabs, ImGuiCol, ImGuiSelectionBasicStorage, ImLengthSqr, ImS8, ImU8, ExampleAppPropertyEditorMT, ImGuiScrollFlags, ImGui_ImplLOVE_GetBackendData, ImLog, ExampleSelectionWithDeletionMT, CustomConstraints, ExampleAppLogMT, ImFontAtlasBuildInit, ImGuiComboFlags, ImGuiPopupFlags, ImGuiSliderFlags, ImTextClassifierSetCharClass, MyDocument, ShowExampleMenuFile, CalcCornerArcStepAndCount, ImFontAtlasBakedAddFontGlyph, ImFontAtlasPackAddRect, ImFontBaked_BuildLoadGlyph, ImGuiInputTextFlags, ImGuiStyle_Copy, ExampleAsset_s_current_sort_specs, ExampleMemberInfo, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC, ImFontAtlasBuildRenderBitmapFromString, ImFontAtlasFontDestroyOutput, ImFontAtlasFontSourceAddToFont, ImFontAtlasFontSourceInit, ImFontAtlasTextureAdd, ImFontAtlasTextureBlockQueueUpload, ImFontBaked_BuildGrowIndex, ImGuiTableColumn, stb_textedit_key, stbtt_GetGlyphBitmapBoxSubpixel, IM_FREE, ImDrawListSplitter, ImGuiDragDropFlags, ImGuiFocusedFlags, stb_text_locate_coord, stb_text_makeundo_insert, stb_text_makeundo_replace, stb_textedit_find_charpos, stbtt_GetGlyphShape, IM_ALLOC, ImGuiTableColumnSortSpecs, ImGuiTableInstanceData, ImGuiTableSettings, stb_text_makeundo_delete, stb_text_redo, stb_text_undo, stb_textedit_click, stb_textedit_drag, stbtt_FindGlyphIndex, stbtt_GetFontOffsetForIndex, stbtt_GetFontVMetrics, stbtt_GetGlyphBitmapBox, stbtt_GetGlyphHMetrics, stbtt_InitFont, stbtt_MakeGlyphBitmapSubpixelPrefilter, stbtt_ScaleForPixelHeight, stbtt__GetGlyphInfoT2, stbtt__GetGlyphShapeT2, stbtt_fontinfo, ImGuiOldColumnData, ImGuiOldColumnFlags, ImGuiOldColumns, ImGuiTable, ImGuiTableColumnSettings, ImGuiTableSortSpecs, ImGuiTableTempData, ImGui_ImplLOVE_CreateTexture, ImGui_ImplLOVE_DestroyTexture, ImGui_ImplLOVE_Init, ImGui_ImplLOVE_NewFrame, ImGui_ImplLOVE_RenderDrawData, ImGui_ImplLOVE_Shutdown, ImGui_ImplLOVE_UpdateTexture, stbrp_init_target, IMGUI_TABLE_MAX_COLUMNS, IMSTB_TEXTEDIT_UNDOSTATECOUNT, IM_COL32_DISABLE, ImGui_ImplLove, STB_TEXTEDIT_K_BACKSPACE, STB_TEXTEDIT_K_DELETE, STB_TEXTEDIT_K_DOWN, STB_TEXTEDIT_K_LEFT, STB_TEXTEDIT_K_LINEEND, STB_TEXTEDIT_K_LINESTART, STB_TEXTEDIT_K_PGDOWN, STB_TEXTEDIT_K_PGUP, STB_TEXTEDIT_K_REDO, STB_TEXTEDIT_K_RIGHT, STB_TEXTEDIT_K_SHIFT
|
||||||
local type, mathMin, mathMax, mathFloor, mathCeil, bitOr, bitLShift = type, math.min, math.max, math.floor, math.ceil, bit32.bor, bit32.lshift
|
local type, mathMin, mathMax, mathFloor, mathCeil, bitOr, bitLShift = type, math.min, math.max, math.floor, math.ceil, bit32.bor, bit32.lshift
|
||||||
local function IM_COL32(R, G, B, A) return (bitOr(bitLShift(A, 24 --[[IM_COL32_A_SHIFT]]), bitLShift(B, 16 --[[IM_COL32_B_SHIFT]]), bitLShift(G, 8 --[[IM_COL32_G_SHIFT]]), bitLShift(R, 0 --[[IM_COL32_R_SHIFT]]))) end
|
local function IM_COL32(R, G, B, A) return (bitOr(bitLShift(A, 24 --[[IM_COL32_A_SHIFT]]), bitLShift(B, 16 --[[IM_COL32_B_SHIFT]]), bitLShift(G, 8 --[[IM_COL32_G_SHIFT]]), bitLShift(R, 0 --[[IM_COL32_R_SHIFT]]))) end
|
||||||
|
|
||||||
@@ -40909,47 +40909,341 @@ function MT.ImDrawList:PathBezierQuadraticCurveTo(p2, p3, num_segments)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ponytail: ear-clipping, no anti-aliased fringe (upstream's AA triangulator not ported). O(n^2) is fine for UI polygons.
|
--------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] ImTriangulator, ImDrawList concave polygon fill
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity.
|
||||||
|
-- Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
|
||||||
|
-- Provided as a convenience for user but not used by main library.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- - ImTriangulator [Internal]
|
||||||
|
-- - AddConcavePolyFilled()
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local ImTriangulatorNodeType =
|
||||||
|
{
|
||||||
|
Convex = 0,
|
||||||
|
Ear = 1,
|
||||||
|
Reflex = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- [Luau] No pointers: a node is an int handle (1-based slot) into the parallel arrays of its ImTriangulator
|
||||||
|
-- (tri.Type[n], tri.Index[n], tri.Pos[n], tri.Next[n], tri.Prev[n]). node->Index (0-based, as upstream) == n - 1.
|
||||||
|
local function ImTriangulatorNode_Unlink(tri, n) tri.Prev[tri.Next[n]] = tri.Prev[n]; tri.Next[tri.Prev[n]] = tri.Next[n] end
|
||||||
|
|
||||||
|
-- [Luau] Deviation: upstream classifies a node as reflex when '!ImTriangleIsClockwise()', i.e. also when its corner is
|
||||||
|
-- degenerate (collinear or duplicate points). A duplicate point then sits as a reflex on top of every candidate ear's vertex
|
||||||
|
-- and blocks it, ending in the degenerate fallback with overlapping triangles. Only strictly counter-clockwise corners are
|
||||||
|
-- reflex here: degenerate corners are clipped as zero-area ears.
|
||||||
|
local function ImTriangulator_IsReflex(a, b, c) return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) < 0.0 end
|
||||||
|
|
||||||
|
local function ImTriangulatorNodeSpan()
|
||||||
|
return { Data = {}, Size = 0 } -- Data: node handles, 1-based
|
||||||
|
end
|
||||||
|
MT.ImTriangulatorNodeSpan = {}
|
||||||
|
MT.ImTriangulatorNodeSpan.__index = MT.ImTriangulatorNodeSpan
|
||||||
|
function MT.ImTriangulatorNodeSpan:push_back(node) self.Size = self.Size + 1; self.Data[self.Size] = node end
|
||||||
|
function MT.ImTriangulatorNodeSpan:find_erase_unsorted(idx) for i = self.Size, 1, -1 do if self.Data[i] - 1 == idx then self.Data[i] = self.Data[self.Size]; self.Size = self.Size - 1; return end end end
|
||||||
|
|
||||||
|
-- [Luau] The node/ears/reflexes storage (upstream: carved out of _Data->TempBuffer via scratch_buffer) is owned by the
|
||||||
|
-- triangulator itself and only ever grows. AddConcavePolyFilled() reuses a single module-level instance (no per-call allocations).
|
||||||
|
local function ImTriangulator()
|
||||||
|
return setmetatable({
|
||||||
|
_TrianglesLeft = 0,
|
||||||
|
_Nodes = 0, -- node handle (head of the circular list)
|
||||||
|
_Ears = setmetatable(ImTriangulatorNodeSpan(), MT.ImTriangulatorNodeSpan),
|
||||||
|
_Reflexes = setmetatable(ImTriangulatorNodeSpan(), MT.ImTriangulatorNodeSpan),
|
||||||
|
Type = {}, Index = {}, Pos = {}, Next = {}, Prev = {}, -- [Luau] ImTriangulatorNode fields, one array each
|
||||||
|
}, MT.ImTriangulator)
|
||||||
|
end
|
||||||
|
MT.ImTriangulator = {}
|
||||||
|
MT.ImTriangulator.__index = MT.ImTriangulator
|
||||||
|
|
||||||
|
function MT.ImTriangulator.EstimateTriangleCount(points_count) return (points_count < 3) and 0 or points_count - 2 end
|
||||||
|
-- [Luau] In elements (nodes + ears + reflexes) rather than bytes. Unused by the port: arrays grow on demand.
|
||||||
|
function MT.ImTriangulator.EstimateScratchBufferSize(points_count) return points_count + points_count * 2 end
|
||||||
|
|
||||||
|
-- Distribute storage for nodes, ears and reflexes.
|
||||||
|
-- FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer
|
||||||
|
-- (this would require first building reflexes to bail to convex if empty, without even building nodes)
|
||||||
--- @param points ImVec2[] # 1-based
|
--- @param points ImVec2[] # 1-based
|
||||||
function MT.ImDrawList:AddConcavePolyFilled(points, points_count, col)
|
function MT.ImTriangulator:Init(points, points_count)
|
||||||
if points_count < 3 or bit32.band(col, 4278190080 --[[IM_COL32_A_MASK]]) == 0 then return end
|
assert(points_count >= 3)
|
||||||
local idx = {}
|
self._TrianglesLeft = MT.ImTriangulator.EstimateTriangleCount(points_count)
|
||||||
local area = 0.0
|
self._Nodes = 1
|
||||||
|
self._Ears.Size = 0
|
||||||
|
self._Reflexes.Size = 0
|
||||||
|
self:BuildNodes(points, points_count)
|
||||||
|
|
||||||
|
-- [Luau] Deviation: upstream only flips the node list when no ear is found, so a counter-clockwise *concave* polygon
|
||||||
|
-- (whose reflex corners look like ears) yields triangles outside of it. Normalize to clockwise order up-front (O(N)).
|
||||||
|
local area2 = 0.0
|
||||||
|
local p0 = points[points_count]
|
||||||
for i = 1, points_count do
|
for i = 1, points_count do
|
||||||
idx[i] = i
|
local p1 = points[i]
|
||||||
local a, b = points[i], points[i % points_count + 1]
|
area2 = area2 + (p0.x * p1.y - p1.x * p0.y)
|
||||||
area = area + (a.x * b.y - b.x * a.y)
|
p0 = p1
|
||||||
end
|
end
|
||||||
local sign = (area >= 0) and 1 or -1
|
if area2 < 0.0 then
|
||||||
local function cross(o, a, b) return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x) end
|
self:FlipNodeList()
|
||||||
local guard = 0
|
end
|
||||||
while #idx > 3 and guard < points_count * points_count do
|
|
||||||
guard = guard + 1
|
self:BuildReflexes()
|
||||||
local n = #idx
|
self:BuildEars()
|
||||||
local clipped = false
|
end
|
||||||
for i = 1, n do
|
|
||||||
local ia, ib, ic = idx[(i - 2) % n + 1], idx[i], idx[i % n + 1]
|
function MT.ImTriangulator:BuildNodes(points, points_count)
|
||||||
local a, b, c = points[ia], points[ib], points[ic]
|
local Type, Index, Pos, Next, Prev = self.Type, self.Index, self.Pos, self.Next, self.Prev
|
||||||
if cross(a, b, c) * sign > 0 then
|
for i = 1, points_count do
|
||||||
local inside = false
|
Type[i] = ImTriangulatorNodeType.Convex
|
||||||
for j = 1, n do
|
Index[i] = i - 1
|
||||||
local p = idx[j]
|
Pos[i] = points[i] -- [Luau] reference, not a copy (points are not modified while triangulating)
|
||||||
if p ~= ia and p ~= ib and p ~= ic then
|
Next[i] = i + 1
|
||||||
local q = points[p]
|
Prev[i] = i - 1
|
||||||
if cross(a, b, q) * sign >= 0 and cross(b, c, q) * sign >= 0 and cross(c, a, q) * sign >= 0 then inside = true; break end
|
end
|
||||||
end
|
Prev[1] = points_count
|
||||||
end
|
Next[points_count] = 1
|
||||||
if not inside then
|
end
|
||||||
self:AddTriangleFilled(a, b, c, col)
|
|
||||||
table.remove(idx, i)
|
function MT.ImTriangulator:BuildReflexes()
|
||||||
clipped = true
|
local Pos, Next, Prev = self.Pos, self.Next, self.Prev
|
||||||
break
|
local n1 = self._Nodes
|
||||||
end
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
if ImTriangulator_IsReflex(Pos[Prev[n1]], Pos[n1], Pos[Next[n1]]) then
|
||||||
|
self.Type[n1] = ImTriangulatorNodeType.Reflex
|
||||||
|
self._Reflexes:push_back(n1)
|
||||||
|
end
|
||||||
|
n1 = Next[n1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:BuildEars()
|
||||||
|
local Index, Pos, Next, Prev = self.Index, self.Pos, self.Next, self.Prev
|
||||||
|
local n1 = self._Nodes
|
||||||
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
if self.Type[n1] == ImTriangulatorNodeType.Convex then
|
||||||
|
local n0, n2 = Prev[n1], Next[n1]
|
||||||
|
if self:IsEar(Index[n0], Index[n1], Index[n2], Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
self.Type[n1] = ImTriangulatorNodeType.Ear
|
||||||
|
self._Ears:push_back(n1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not clipped then break end
|
n1 = Next[n1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [Luau] out_triangle[3] is returned as 3 values (relative 0-based indexes)
|
||||||
|
function MT.ImTriangulator:GetNextTriangle()
|
||||||
|
if self._Ears.Size == 0 then
|
||||||
|
self:FlipNodeList()
|
||||||
|
|
||||||
|
local node = self._Nodes
|
||||||
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
self.Type[node] = ImTriangulatorNodeType.Convex
|
||||||
|
node = self.Next[node]
|
||||||
|
end
|
||||||
|
self._Reflexes.Size = 0
|
||||||
|
self:BuildReflexes()
|
||||||
|
self:BuildEars()
|
||||||
|
|
||||||
|
-- If we still don't have ears, it means geometry is degenerated.
|
||||||
|
if self._Ears.Size == 0 then
|
||||||
|
-- Return first triangle available, mimicking the behavior of convex fill.
|
||||||
|
assert(self._TrianglesLeft > 0) -- Geometry is degenerated
|
||||||
|
self._Ears.Data[1] = self._Nodes
|
||||||
|
self._Ears.Size = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ear = self._Ears.Data[self._Ears.Size]
|
||||||
|
self._Ears.Size = self._Ears.Size - 1
|
||||||
|
local Index, Next, Prev = self.Index, self.Next, self.Prev
|
||||||
|
local t0, t1, t2 = Index[Prev[ear]], Index[ear], Index[Next[ear]]
|
||||||
|
|
||||||
|
ImTriangulatorNode_Unlink(self, ear)
|
||||||
|
if ear == self._Nodes then
|
||||||
|
self._Nodes = Next[ear]
|
||||||
|
end
|
||||||
|
|
||||||
|
self:ReclassifyNode(Prev[ear])
|
||||||
|
self:ReclassifyNode(Next[ear])
|
||||||
|
self._TrianglesLeft = self._TrianglesLeft - 1
|
||||||
|
return t0, t1, t2
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:FlipNodeList()
|
||||||
|
local Next, Prev = self.Next, self.Prev
|
||||||
|
local nodes = self._Nodes
|
||||||
|
local prev = nodes
|
||||||
|
local temp = nodes
|
||||||
|
local current = Next[nodes]
|
||||||
|
Next[prev] = prev
|
||||||
|
Prev[prev] = prev
|
||||||
|
while current ~= nodes do
|
||||||
|
temp = Next[current]
|
||||||
|
|
||||||
|
Next[current] = prev
|
||||||
|
Prev[prev] = current
|
||||||
|
Next[nodes] = current
|
||||||
|
Prev[current] = nodes
|
||||||
|
|
||||||
|
prev = current
|
||||||
|
current = temp
|
||||||
|
end
|
||||||
|
self._Nodes = prev
|
||||||
|
end
|
||||||
|
|
||||||
|
-- A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm)
|
||||||
|
function MT.ImTriangulator:IsEar(i0, i1, i2, v0, v1, v2)
|
||||||
|
local Index, Pos = self.Index, self.Pos
|
||||||
|
local data = self._Reflexes.Data
|
||||||
|
for p = 1, self._Reflexes.Size do
|
||||||
|
local reflex = data[p]
|
||||||
|
local idx = Index[reflex]
|
||||||
|
if idx ~= i0 and idx ~= i1 and idx ~= i2 then
|
||||||
|
if ImStd.ImTriangleContainsPoint(v0, v1, v2, Pos[reflex]) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:ReclassifyNode(n1)
|
||||||
|
-- Classify node
|
||||||
|
local type
|
||||||
|
local n0 = self.Prev[n1]
|
||||||
|
local n2 = self.Next[n1]
|
||||||
|
local Index, Pos = self.Index, self.Pos
|
||||||
|
if ImTriangulator_IsReflex(Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
type = ImTriangulatorNodeType.Reflex
|
||||||
|
elseif self:IsEar(Index[n0], Index[n1], Index[n2], Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
type = ImTriangulatorNodeType.Ear
|
||||||
|
else
|
||||||
|
type = ImTriangulatorNodeType.Convex
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update lists when a type changes
|
||||||
|
local n1_type = self.Type[n1]
|
||||||
|
if type == n1_type then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if n1_type == ImTriangulatorNodeType.Reflex then
|
||||||
|
self._Reflexes:find_erase_unsorted(Index[n1])
|
||||||
|
elseif n1_type == ImTriangulatorNodeType.Ear then
|
||||||
|
self._Ears:find_erase_unsorted(Index[n1])
|
||||||
|
end
|
||||||
|
if type == ImTriangulatorNodeType.Reflex then
|
||||||
|
self._Reflexes:push_back(n1)
|
||||||
|
elseif type == ImTriangulatorNodeType.Ear then
|
||||||
|
self._Ears:push_back(n1)
|
||||||
|
end
|
||||||
|
self.Type[n1] = type
|
||||||
|
end
|
||||||
|
|
||||||
|
local concave_triangulator = ImTriangulator() -- [Luau] reused scratch (see ImTriangulator())
|
||||||
|
|
||||||
|
-- Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes).
|
||||||
|
-- (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer!
|
||||||
|
-- It is up to caller to ensure not making costly calls that will be outside of visible area.
|
||||||
|
-- As concave fill is noticeably more expensive than other primitives, be mindful of this...
|
||||||
|
-- Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false')
|
||||||
|
--- @param points ImVec2[] # 1-based
|
||||||
|
--- @param points_count int
|
||||||
|
--- @param col ImU32
|
||||||
|
|
||||||
|
function MT.ImDrawList:AddConcavePolyFilled(points, points_count, col)
|
||||||
|
if points_count < 3 or bit32.band(col, 4278190080 --[[IM_COL32_A_MASK]]) == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local uv = self._Data.TexUvWhitePixel
|
||||||
|
local uv_x, uv_y = uv.x, uv.y
|
||||||
|
local triangulator = concave_triangulator
|
||||||
|
if bit32.band(self.Flags, 4096 --[[ImDrawFlags.AAFill]]) ~= 0 then
|
||||||
|
-- Anti-aliased Fill
|
||||||
|
local AA_SIZE = self._FringeScale
|
||||||
|
local col_trans = bit32.band(col, bit32.bnot(4278190080 --[[IM_COL32_A_MASK]]))
|
||||||
|
local idx_count = (points_count - 2) * 3 + points_count * 6
|
||||||
|
local vtx_count = (points_count * 2)
|
||||||
|
PrimReserve(self, idx_count, vtx_count)
|
||||||
|
local vb = self.VtxBuffer.Buf
|
||||||
|
local ib = self.IdxBuffer.Data
|
||||||
|
local vw = self._VtxWritePtr
|
||||||
|
local iw = self._IdxWritePtr
|
||||||
|
|
||||||
|
-- Add indexes for fill
|
||||||
|
local vtx_inner_idx = self._VtxCurrentIdx
|
||||||
|
local vtx_outer_idx = self._VtxCurrentIdx + 1
|
||||||
|
|
||||||
|
triangulator:Init(points, points_count)
|
||||||
|
while triangulator._TrianglesLeft > 0 do
|
||||||
|
local t0, t1, t2 = triangulator:GetNextTriangle()
|
||||||
|
ib[iw + 0] = vtx_inner_idx + t0 * 2; ib[iw + 1] = vtx_inner_idx + t1 * 2; ib[iw + 2] = vtx_inner_idx + t2 * 2
|
||||||
|
iw = iw + 3
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Compute normals
|
||||||
|
-- [Luau] scratch arrays (see AddPolyline) instead of _Data->TempBuffer. Indexes below are 1-based.
|
||||||
|
local temp_normals_x, temp_normals_y = poly_normals_x, poly_normals_y
|
||||||
|
local i0 = points_count
|
||||||
|
for i1 = 1, points_count do
|
||||||
|
local p0 = points[i0]
|
||||||
|
local p1 = points[i1]
|
||||||
|
local dx, dy = IM_NORMALIZE2F_OVER_ZERO(p1.x - p0.x, p1.y - p0.y)
|
||||||
|
temp_normals_x[i0] = dy
|
||||||
|
temp_normals_y[i0] = -dx
|
||||||
|
i0 = i1
|
||||||
|
end
|
||||||
|
|
||||||
|
i0 = points_count
|
||||||
|
for i1 = 1, points_count do
|
||||||
|
-- Average normals
|
||||||
|
local dm_x, dm_y = IM_FIXNORMAL2F((temp_normals_x[i0] + temp_normals_x[i1]) * 0.5, (temp_normals_y[i0] + temp_normals_y[i1]) * 0.5)
|
||||||
|
dm_x = dm_x * AA_SIZE * 0.5
|
||||||
|
dm_y = dm_y * AA_SIZE * 0.5
|
||||||
|
|
||||||
|
-- Add vertices
|
||||||
|
local p1 = points[i1]
|
||||||
|
WV(vb, vw, p1.x - dm_x, p1.y - dm_y, uv_x, uv_y, col) -- Inner
|
||||||
|
WV(vb, vw + 1, p1.x + dm_x, p1.y + dm_y, uv_x, uv_y, col_trans) -- Outer
|
||||||
|
vw = vw + 2
|
||||||
|
|
||||||
|
-- Add indexes for fringes
|
||||||
|
local e0, e1 = (i0 - 1) * 2, (i1 - 1) * 2
|
||||||
|
ib[iw + 0] = vtx_inner_idx + e1; ib[iw + 1] = vtx_inner_idx + e0; ib[iw + 2] = vtx_outer_idx + e0
|
||||||
|
ib[iw + 3] = vtx_outer_idx + e0; ib[iw + 4] = vtx_outer_idx + e1; ib[iw + 5] = vtx_inner_idx + e1
|
||||||
|
iw = iw + 6
|
||||||
|
i0 = i1
|
||||||
|
end
|
||||||
|
self._VtxWritePtr = vw
|
||||||
|
self._IdxWritePtr = iw
|
||||||
|
self._VtxCurrentIdx = self._VtxCurrentIdx + vtx_count
|
||||||
|
else
|
||||||
|
-- Non Anti-aliased Fill
|
||||||
|
local idx_count = (points_count - 2) * 3
|
||||||
|
local vtx_count = points_count
|
||||||
|
PrimReserve(self, idx_count, vtx_count)
|
||||||
|
local vb = self.VtxBuffer.Buf
|
||||||
|
local ib = self.IdxBuffer.Data
|
||||||
|
local vw = self._VtxWritePtr
|
||||||
|
local iw = self._IdxWritePtr
|
||||||
|
for i = 1, vtx_count do
|
||||||
|
local p = points[i]
|
||||||
|
WV(vb, vw, p.x, p.y, uv_x, uv_y, col)
|
||||||
|
vw = vw + 1
|
||||||
|
end
|
||||||
|
local base_idx = self._VtxCurrentIdx
|
||||||
|
triangulator:Init(points, points_count)
|
||||||
|
while triangulator._TrianglesLeft > 0 do
|
||||||
|
local t0, t1, t2 = triangulator:GetNextTriangle()
|
||||||
|
ib[iw + 0] = base_idx + t0; ib[iw + 1] = base_idx + t1; ib[iw + 2] = base_idx + t2
|
||||||
|
iw = iw + 3
|
||||||
|
end
|
||||||
|
self._VtxWritePtr = vw
|
||||||
|
self._IdxWritePtr = iw
|
||||||
|
self._VtxCurrentIdx = base_idx + vtx_count
|
||||||
end
|
end
|
||||||
if #idx == 3 then self:AddTriangleFilled(points[idx[1]], points[idx[2]], points[idx[3]], col) end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function MT.ImDrawList:PathFillConcave(col)
|
function MT.ImDrawList:PathFillConcave(col)
|
||||||
@@ -44870,6 +45164,18 @@ function ImMul(lhs, rhs)
|
|||||||
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
|
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param a ImVec2
|
||||||
|
--- @param b ImVec2
|
||||||
|
--- @param c ImVec2
|
||||||
|
--- @return float
|
||||||
|
function ImTriangleArea(a, b, c) return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5 end
|
||||||
|
|
||||||
|
--- @param a ImVec2
|
||||||
|
--- @param b ImVec2
|
||||||
|
--- @param c ImVec2
|
||||||
|
--- @return boolean
|
||||||
|
function ImTriangleIsClockwise(a, b, c) return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) > 0.0 end
|
||||||
|
|
||||||
--- @param str char[]
|
--- @param str char[]
|
||||||
--- @param begin? int
|
--- @param begin? int
|
||||||
function ImStd.ImStrlen(str, begin)
|
function ImStd.ImStrlen(str, begin)
|
||||||
@@ -70856,6 +71162,8 @@ return {
|
|||||||
ImTextureRef = ImTextureRef,
|
ImTextureRef = ImTextureRef,
|
||||||
ImTextureStatus = ImTextureStatus,
|
ImTextureStatus = ImTextureStatus,
|
||||||
ImToUpper = ImToUpper,
|
ImToUpper = ImToUpper,
|
||||||
|
ImTriangleArea = ImTriangleArea,
|
||||||
|
ImTriangleIsClockwise = ImTriangleIsClockwise,
|
||||||
ImTrunc = ImTrunc,
|
ImTrunc = ImTrunc,
|
||||||
ImTrunc64 = ImTrunc64,
|
ImTrunc64 = ImTrunc64,
|
||||||
ImU16 = ImU16,
|
ImU16 = ImU16,
|
||||||
|
|||||||
+133
-133
@@ -14,18 +14,18 @@ polyline stroker (AddPolyline), Lua-native replacements (ImGuiStorage, ImStr*, I
|
|||||||
upstream file funcs ported by size similarity stubs
|
upstream file funcs ported by size similarity stubs
|
||||||
imgui.cpp 786 87.4% 93.5% 75.1% 2
|
imgui.cpp 786 87.4% 93.5% 75.1% 2
|
||||||
imgui_widgets.cpp 308 93.8% 98.7% 78.4% 1
|
imgui_widgets.cpp 308 93.8% 98.7% 78.4% 1
|
||||||
imgui_draw.cpp 258 81.8% 92.3% 61.1% 2
|
imgui_draw.cpp 258 86.8% 94.4% 61.2% 2
|
||||||
imgui_tables.cpp 113 96.5% 99.0% 74.0% 0
|
imgui_tables.cpp 113 96.5% 99.0% 74.0% 0
|
||||||
imgui_demo.cpp 56 100.0% 100.0% 55.8% 0
|
imgui_demo.cpp 56 100.0% 100.0% 55.8% 0
|
||||||
imgui.h 110 53.6% 37.4% 60.0% 0
|
imgui.h 110 53.6% 37.4% 60.0% 0
|
||||||
imgui_internal.h 269 62.5% 65.7% 67.6% 1
|
imgui_internal.h 269 63.2% 67.5% 68.5% 1
|
||||||
TOTAL 1900 83.1% 95.3% 70.4% 6
|
TOTAL 1900 83.9% 95.6% 70.4% 6
|
||||||
|
|
||||||
upstream code reproduced (similarity x ported size / all upstream size): 67.0%
|
upstream code reproduced (similarity x ported size / all upstream size): 67.2%
|
||||||
Public API (imgui.h, namespace ImGui) 368 / 376 97.9%
|
Public API (imgui.h, namespace ImGui) 368 / 376 97.9%
|
||||||
Internal API (imgui_internal.h, namespace ImGui) 417 / 443 94.1%
|
Internal API (imgui_internal.h, namespace ImGui) 417 / 443 94.1%
|
||||||
Enum values (imgui.h + imgui_internal.h) 1034 / 1078 95.9%
|
Enum values (imgui.h + imgui_internal.h) 1037 / 1078 96.2%
|
||||||
Struct fields (imgui.h + imgui_internal.h) 1833 / 1926 95.2%
|
Struct fields (imgui.h + imgui_internal.h) 1839 / 1926 95.5%
|
||||||
|
|
||||||
Legend: [x] ported (sim %) [~] stub [ ] not ported [-] excluded (c++-only / obsolete / os-specific / #if 0 / test-engine)
|
Legend: [x] ported (sim %) [~] stub [ ] not ported [-] excluded (c++-only / obsolete / os-specific / #if 0 / test-engine)
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ imgui.cpp
|
|||||||
[ ] FreeWrapper
|
[ ] FreeWrapper
|
||||||
|
|
||||||
-- USER FACING STRUCTURES (ImGuiStyle, ImGuiIO, ImGuiPlatformIO)
|
-- USER FACING STRUCTURES (ImGuiStyle, ImGuiIO, ImGuiPlatformIO)
|
||||||
[x] 33% ImGuiStyle::ImGuiStyle imgui_internal.lua:1518
|
[x] 33% ImGuiStyle::ImGuiStyle imgui_internal.lua:1530
|
||||||
[x] 83% ImGuiStyle::ScaleAllSizes imgui.lua:4779
|
[x] 83% ImGuiStyle::ScaleAllSizes imgui.lua:4779
|
||||||
[x] 12% ImGuiIO::ImGuiIO imgui_h.lua:1187
|
[x] 12% ImGuiIO::ImGuiIO imgui_h.lua:1187
|
||||||
[x] 83% ImGuiIO::AddInputCharacter imgui.lua:7983
|
[x] 83% ImGuiIO::AddInputCharacter imgui.lua:7983
|
||||||
@@ -200,7 +200,7 @@ imgui.cpp
|
|||||||
[ ] ImGui::GetAllocatorFunctions
|
[ ] ImGui::GetAllocatorFunctions
|
||||||
[x] 87% ImGui::CreateContext imgui.lua:5580
|
[x] 87% ImGui::CreateContext imgui.lua:5580
|
||||||
[x] 83% ImGui::DestroyContext imgui.lua:5592
|
[x] 83% ImGui::DestroyContext imgui.lua:5592
|
||||||
[x] 6% ImGuiContext::ImGuiContext imgui_internal.lua:2239
|
[x] 6% ImGuiContext::ImGuiContext imgui_internal.lua:2251
|
||||||
[-] ImGuiContext::~ImGuiContext c++-only
|
[-] ImGuiContext::~ImGuiContext c++-only
|
||||||
[x] 78% ImGui::Initialize imgui.lua:5538
|
[x] 78% ImGui::Initialize imgui.lua:5538
|
||||||
[x] 44% ImGui::Shutdown imgui.lua:14315
|
[x] 44% ImGui::Shutdown imgui.lua:14315
|
||||||
@@ -210,7 +210,7 @@ imgui.cpp
|
|||||||
[ ] ImGui::CallContextHooks
|
[ ] ImGui::CallContextHooks
|
||||||
|
|
||||||
-- MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
-- MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||||
[x] 11% ImGuiWindow::ImGuiWindow imgui_internal.lua:2843
|
[x] 11% ImGuiWindow::ImGuiWindow imgui_internal.lua:2855
|
||||||
[-] ImGuiWindow::~ImGuiWindow c++-only
|
[-] ImGuiWindow::~ImGuiWindow c++-only
|
||||||
[x] 74% SetCurrentWindow imgui.lua:10805
|
[x] 74% SetCurrentWindow imgui.lua:10805
|
||||||
[x] 85% ImGui::GcCompactTransientMiscBuffers imgui.lua:10826
|
[x] 85% ImGui::GcCompactTransientMiscBuffers imgui.lua:10826
|
||||||
@@ -1076,7 +1076,7 @@ imgui_widgets.cpp
|
|||||||
[x] 79% STB_TEXTEDIT_DELETECHARS imgui_widgets.lua:4712
|
[x] 79% STB_TEXTEDIT_DELETECHARS imgui_widgets.lua:4712
|
||||||
[x] 87% STB_TEXTEDIT_INSERTCHARS imgui_widgets.lua:4726
|
[x] 87% STB_TEXTEDIT_INSERTCHARS imgui_widgets.lua:4726
|
||||||
[x] 81% stb_textedit_replace imgui_widgets.lua:4769
|
[x] 81% stb_textedit_replace imgui_widgets.lua:4769
|
||||||
[x] 12% ImGuiInputTextState::ImGuiInputTextState imgui_internal.lua:1705
|
[x] 12% ImGuiInputTextState::ImGuiInputTextState imgui_internal.lua:1717
|
||||||
[-] ImGuiInputTextState::~ImGuiInputTextState c++-only
|
[-] ImGuiInputTextState::~ImGuiInputTextState c++-only
|
||||||
[x] 93% ImGuiInputTextState::OnKeyPressed imgui_widgets.lua:4797
|
[x] 93% ImGuiInputTextState::OnKeyPressed imgui_widgets.lua:4797
|
||||||
[x] 63% ImGuiInputTextState::OnCharPressed imgui_widgets.lua:4812
|
[x] 63% ImGuiInputTextState::OnCharPressed imgui_widgets.lua:4812
|
||||||
@@ -1219,7 +1219,7 @@ imgui_widgets.cpp
|
|||||||
|
|
||||||
-- Widgets: BeginTabBar, EndTabBar, etc.
|
-- Widgets: BeginTabBar, EndTabBar, etc.
|
||||||
[x] 19% ImGuiTabBarSection::ImGuiTabBarSection imgui_widgets.lua:10678
|
[x] 19% ImGuiTabBarSection::ImGuiTabBarSection imgui_widgets.lua:10678
|
||||||
[x] 16% ImGuiTabBar::ImGuiTabBar imgui_internal.lua:2210
|
[x] 16% ImGuiTabBar::ImGuiTabBar imgui_internal.lua:2222
|
||||||
[x] 65% TabItemGetSectionIdx imgui_widgets.lua:10645
|
[x] 65% TabItemGetSectionIdx imgui_widgets.lua:10645
|
||||||
[ ] TabItemComparerBySection
|
[ ] TabItemComparerBySection
|
||||||
[ ] TabItemComparerByBeginOrder
|
[ ] TabItemComparerByBeginOrder
|
||||||
@@ -1273,7 +1273,7 @@ imgui_draw.cpp
|
|||||||
[x] 82% ImGui::StyleColorsLight imgui_draw.lua:270
|
[x] 82% ImGui::StyleColorsLight imgui_draw.lua:270
|
||||||
|
|
||||||
-- ImDrawList
|
-- ImDrawList
|
||||||
[x] 30% ImDrawListSharedData::ImDrawListSharedData imgui_internal.lua:1120
|
[x] 30% ImDrawListSharedData::ImDrawListSharedData imgui_internal.lua:1132
|
||||||
[-] ImDrawListSharedData::~ImDrawListSharedData c++-only
|
[-] ImDrawListSharedData::~ImDrawListSharedData c++-only
|
||||||
[x] 57% ImDrawListSharedData::SetCircleTessellationMaxError imgui_draw.lua:3918
|
[x] 57% ImDrawListSharedData::SetCircleTessellationMaxError imgui_draw.lua:3918
|
||||||
[x] 6% ImDrawList::ImDrawList imgui_h.lua:657
|
[x] 6% ImDrawList::ImDrawList imgui_h.lua:657
|
||||||
@@ -1351,20 +1351,20 @@ imgui_draw.cpp
|
|||||||
[x] 84% ImDrawList::AddImageRounded imgui_draw.lua:6549
|
[x] 84% ImDrawList::AddImageRounded imgui_draw.lua:6549
|
||||||
|
|
||||||
-- ImTriangulator, ImDrawList concave polygon fill
|
-- ImTriangulator, ImDrawList concave polygon fill
|
||||||
[ ] ImTriangulatorNode::Unlink
|
[x] 35% ImTriangulatorNode::Unlink imgui_draw.lua:7478
|
||||||
[ ] ImTriangulatorNodeSpan::push_back
|
[x] 50% ImTriangulatorNodeSpan::push_back imgui_draw.lua:7491
|
||||||
[ ] ImTriangulatorNodeSpan::find_erase_unsorted
|
[x] 66% ImTriangulatorNodeSpan::find_erase_unsorted imgui_draw.lua:7492
|
||||||
[ ] ImTriangulator::EstimateTriangleCount
|
[x] 84% ImTriangulator::EstimateTriangleCount imgui_draw.lua:7508
|
||||||
[ ] ImTriangulator::EstimateScratchBufferSize
|
[x] 71% ImTriangulator::EstimateScratchBufferSize imgui_draw.lua:7510
|
||||||
[ ] ImTriangulator::Init
|
[x] 38% ImTriangulator::Init imgui_draw.lua:7516
|
||||||
[ ] ImTriangulator::BuildNodes
|
[x] 45% ImTriangulator::BuildNodes imgui_draw.lua:7541
|
||||||
[ ] ImTriangulator::BuildReflexes
|
[x] 32% ImTriangulator::BuildReflexes imgui_draw.lua:7554
|
||||||
[ ] ImTriangulator::BuildEars
|
[x] 38% ImTriangulator::BuildEars imgui_draw.lua:7566
|
||||||
[ ] ImTriangulator::GetNextTriangle
|
[x] 53% ImTriangulator::GetNextTriangle imgui_draw.lua:7582
|
||||||
[ ] ImTriangulator::FlipNodeList
|
[x] 65% ImTriangulator::FlipNodeList imgui_draw.lua:7620
|
||||||
[ ] ImTriangulator::IsEar
|
[x] 56% ImTriangulator::IsEar imgui_draw.lua:7643
|
||||||
[ ] ImTriangulator::ReclassifyNode
|
[x] 58% ImTriangulator::ReclassifyNode imgui_draw.lua:7658
|
||||||
[x] 17% ImDrawList::AddConcavePolyFilled imgui_draw.lua:7460
|
[x] 39% ImDrawList::AddConcavePolyFilled imgui_draw.lua:7701
|
||||||
|
|
||||||
-- ImDrawListSplitter
|
-- ImDrawListSplitter
|
||||||
[x] 58% ImDrawListSplitter::ClearFreeMemory imgui_draw.lua:4201
|
[x] 58% ImDrawListSplitter::ClearFreeMemory imgui_draw.lua:4201
|
||||||
@@ -1964,13 +1964,13 @@ imgui.h
|
|||||||
[x] 92% ImDrawListSplitter::Clear imgui_draw.lua:4196
|
[x] 92% ImDrawListSplitter::Clear imgui_draw.lua:4196
|
||||||
[ ] ImDrawList::GetClipRectMin
|
[ ] ImDrawList::GetClipRectMin
|
||||||
[ ] ImDrawList::GetClipRectMax
|
[ ] ImDrawList::GetClipRectMax
|
||||||
[x] 80% ImDrawList::AddPolyline imgui_internal.lua:1077
|
[x] 80% ImDrawList::AddPolyline imgui_internal.lua:1089
|
||||||
[x] 100% ImDrawList::PathClear imgui_internal.lua:1029
|
[x] 100% ImDrawList::PathClear imgui_internal.lua:1041
|
||||||
[x] 16% ImDrawList::PathLineTo imgui_internal.lua:1033
|
[x] 16% ImDrawList::PathLineTo imgui_internal.lua:1045
|
||||||
[x] 48% ImDrawList::PathLineToMergeDuplicate imgui_internal.lua:1043
|
[x] 48% ImDrawList::PathLineToMergeDuplicate imgui_internal.lua:1055
|
||||||
[x] 94% ImDrawList::PathFillConvex imgui_internal.lua:1053
|
[x] 94% ImDrawList::PathFillConvex imgui_internal.lua:1065
|
||||||
[x] 94% ImDrawList::PathFillConcave imgui_draw.lua:7501
|
[x] 94% ImDrawList::PathFillConcave imgui_draw.lua:7795
|
||||||
[x] 75% ImDrawList::PathStroke imgui_internal.lua:1061
|
[x] 75% ImDrawList::PathStroke imgui_internal.lua:1073
|
||||||
[x] 89% ImDrawList::ChannelsSplit imgui_draw.lua:4377
|
[x] 89% ImDrawList::ChannelsSplit imgui_draw.lua:4377
|
||||||
[x] 80% ImDrawList::ChannelsMerge imgui_draw.lua:4378
|
[x] 80% ImDrawList::ChannelsMerge imgui_draw.lua:4378
|
||||||
[x] 89% ImDrawList::ChannelsSetCurrent imgui_draw.lua:4380
|
[x] 89% ImDrawList::ChannelsSetCurrent imgui_draw.lua:4380
|
||||||
@@ -2040,8 +2040,8 @@ imgui_internal.h
|
|||||||
[x] 35% ImUpperPowerOfTwo imgui_internal.lua:280
|
[x] 35% ImUpperPowerOfTwo imgui_internal.lua:280
|
||||||
[x] 82% ImCountSetBits imgui_internal.lua:295
|
[x] 82% ImCountSetBits imgui_internal.lua:295
|
||||||
[x] 62% ImToUpper imgui_internal.lua:403
|
[x] 62% ImToUpper imgui_internal.lua:403
|
||||||
[x] 75% ImCharIsBlankA imgui_internal.lua:692
|
[x] 75% ImCharIsBlankA imgui_internal.lua:704
|
||||||
[x] 83% ImCharIsBlankW imgui_internal.lua:695
|
[x] 83% ImCharIsBlankW imgui_internal.lua:707
|
||||||
[ ] ImCharIsXdigitA
|
[ ] ImCharIsXdigitA
|
||||||
[x] 0% ImFileOpen imgui.lua:4702
|
[x] 0% ImFileOpen imgui.lua:4702
|
||||||
[x] 0% ImFileClose imgui.lua:4719
|
[x] 0% ImFileClose imgui.lua:4719
|
||||||
@@ -2080,41 +2080,41 @@ imgui_internal.h
|
|||||||
[x] 71% ImExponentialMovingAverage imgui_internal.lua:308
|
[x] 71% ImExponentialMovingAverage imgui_internal.lua:308
|
||||||
[x] 60% ImIsTruncated imgui_internal.lua:264
|
[x] 60% ImIsTruncated imgui_internal.lua:264
|
||||||
[x] 60% ImIsTruncated4 imgui_internal.lua:266
|
[x] 60% ImIsTruncated4 imgui_internal.lua:266
|
||||||
[ ] ImTriangleArea
|
[x] 100% ImTriangleArea imgui_internal.lua:468
|
||||||
[ ] ImTriangleIsClockwise
|
[x] 100% ImTriangleIsClockwise imgui_internal.lua:474
|
||||||
[x] 0% IM_MSVC_RUNTIME_CHECKS_OFF::ImVec1 imgui_internal.lua:797
|
[x] 0% IM_MSVC_RUNTIME_CHECKS_OFF::ImVec1 imgui_internal.lua:809
|
||||||
[ ] ImVec2i::ImVec2i
|
[ ] ImVec2i::ImVec2i
|
||||||
[ ] ImVec2ih::ImVec2ih
|
[ ] ImVec2ih::ImVec2ih
|
||||||
[x] 0% ImRect::ImRect imgui_internal.lua:827
|
[x] 0% ImRect::ImRect imgui_internal.lua:839
|
||||||
[x] 90% ImRect::GetCenter imgui_internal.lua:857
|
[x] 90% ImRect::GetCenter imgui_internal.lua:869
|
||||||
[x] 89% ImRect::GetSize imgui_internal.lua:862
|
[x] 89% ImRect::GetSize imgui_internal.lua:874
|
||||||
[x] 94% ImRect::GetWidth imgui_internal.lua:858
|
[x] 94% ImRect::GetWidth imgui_internal.lua:870
|
||||||
[x] 94% ImRect::GetHeight imgui_internal.lua:859
|
[x] 94% ImRect::GetHeight imgui_internal.lua:871
|
||||||
[x] 91% ImRect::GetArea imgui_internal.lua:951
|
[x] 91% ImRect::GetArea imgui_internal.lua:963
|
||||||
[x] 33% ImRect::GetTL imgui_internal.lua:865
|
[x] 33% ImRect::GetTL imgui_internal.lua:877
|
||||||
[x] 89% ImRect::GetTR imgui_internal.lua:867
|
[x] 89% ImRect::GetTR imgui_internal.lua:879
|
||||||
[x] 89% ImRect::GetBL imgui_internal.lua:869
|
[x] 89% ImRect::GetBL imgui_internal.lua:881
|
||||||
[x] 33% ImRect::GetBR imgui_internal.lua:871
|
[x] 33% ImRect::GetBR imgui_internal.lua:883
|
||||||
[x] 43% ImRect::Contains imgui_internal.lua:834
|
[x] 43% ImRect::Contains imgui_internal.lua:846
|
||||||
[x] 96% ImRect::ContainsWithPad imgui_internal.lua:846
|
[x] 96% ImRect::ContainsWithPad imgui_internal.lua:858
|
||||||
[x] 14% ImRect::Overlaps imgui_internal.lua:852
|
[x] 14% ImRect::Overlaps imgui_internal.lua:864
|
||||||
[x] 59% ImRect::Add imgui_internal.lua:896
|
[x] 59% ImRect::Add imgui_internal.lua:908
|
||||||
[x] 96% ImRect::AddX imgui_internal.lua:912
|
[x] 96% ImRect::AddX imgui_internal.lua:924
|
||||||
[x] 96% ImRect::AddY imgui_internal.lua:913
|
[x] 96% ImRect::AddY imgui_internal.lua:925
|
||||||
[x] 38% ImRect::Expand imgui_internal.lua:917
|
[x] 38% ImRect::Expand imgui_internal.lua:929
|
||||||
[x] 64% ImRect::Translate imgui_internal.lua:934
|
[x] 64% ImRect::Translate imgui_internal.lua:946
|
||||||
[x] 55% ImRect::TranslateX imgui_internal.lua:940
|
[x] 55% ImRect::TranslateX imgui_internal.lua:952
|
||||||
[x] 55% ImRect::TranslateY imgui_internal.lua:945
|
[x] 55% ImRect::TranslateY imgui_internal.lua:957
|
||||||
[x] 22% ImRect::ClipWith imgui_internal.lua:876
|
[x] 22% ImRect::ClipWith imgui_internal.lua:888
|
||||||
[x] 20% ImRect::ClipWithFull imgui_internal.lua:886
|
[x] 20% ImRect::ClipWithFull imgui_internal.lua:898
|
||||||
[x] 91% ImRect::IsInverted imgui_internal.lua:949
|
[x] 91% ImRect::IsInverted imgui_internal.lua:961
|
||||||
[x] 94% ImRect::ToVec4 imgui_internal.lua:928
|
[x] 94% ImRect::ToVec4 imgui_internal.lua:940
|
||||||
[x] 36% ImRect::AsVec4 imgui_internal.lua:954
|
[x] 36% ImRect::AsVec4 imgui_internal.lua:966
|
||||||
[ ] ImBitArrayGetStorageSizeInBytes
|
[ ] ImBitArrayGetStorageSizeInBytes
|
||||||
[ ] ImBitArrayClearAllBits
|
[ ] ImBitArrayClearAllBits
|
||||||
[ ] ImBitArrayTestBit
|
[ ] ImBitArrayTestBit
|
||||||
[ ] ImBitArrayClearBit
|
[ ] ImBitArrayClearBit
|
||||||
[x] 34% ImBitArraySetBit imgui_internal.lua:989
|
[x] 34% ImBitArraySetBit imgui_internal.lua:1001
|
||||||
[ ] ImBitArraySetBitRange
|
[ ] ImBitArraySetBitRange
|
||||||
[ ] ImBitVector::Create
|
[ ] ImBitVector::Create
|
||||||
[ ] ImBitVector::Clear
|
[ ] ImBitVector::Clear
|
||||||
@@ -2166,10 +2166,10 @@ imgui_internal.h
|
|||||||
[ ] template::offset_from_ptr
|
[ ] template::offset_from_ptr
|
||||||
[ ] template::ptr_from_offset
|
[ ] template::ptr_from_offset
|
||||||
[ ] template::swap
|
[ ] template::swap
|
||||||
[x] 83% ImGuiTextIndex::clear imgui_internal.lua:1819
|
[x] 83% ImGuiTextIndex::clear imgui_internal.lua:1831
|
||||||
[x] 100% ImGuiTextIndex::size imgui_internal.lua:1821
|
[x] 100% ImGuiTextIndex::size imgui_internal.lua:1833
|
||||||
[x] 71% ImGuiTextIndex::get_line_begin imgui_internal.lua:1823
|
[x] 71% ImGuiTextIndex::get_line_begin imgui_internal.lua:1835
|
||||||
[x] 76% ImGuiTextIndex::get_line_end imgui_internal.lua:1827
|
[x] 76% ImGuiTextIndex::get_line_end imgui_internal.lua:1839
|
||||||
[ ] ImGuiTextFilterItem::ImGuiTextFilterItem
|
[ ] ImGuiTextFilterItem::ImGuiTextFilterItem
|
||||||
[ ] ImGuiPackedDate::ImGuiPackedDate
|
[ ] ImGuiPackedDate::ImGuiPackedDate
|
||||||
[ ] ImGuiPackedDate::IsValid
|
[ ] ImGuiPackedDate::IsValid
|
||||||
@@ -2177,37 +2177,37 @@ imgui_internal.h
|
|||||||
[ ] ImGuiPackedDate::SubtractMonths
|
[ ] ImGuiPackedDate::SubtractMonths
|
||||||
|
|
||||||
-- ImDrawList support
|
-- ImDrawList support
|
||||||
[x] 27% ImDrawDataBuilder::ImDrawDataBuilder imgui_internal.lua:3016
|
[x] 27% ImDrawDataBuilder::ImDrawDataBuilder imgui_internal.lua:3028
|
||||||
|
|
||||||
-- Style support
|
-- Style support
|
||||||
[ ] ImGuiStyleVarInfo::GetVarPtr
|
[ ] ImGuiStyleVarInfo::GetVarPtr
|
||||||
[x] 39% ImGuiStyleMod::ImGuiStyleMod imgui_internal.lua:1268
|
[x] 39% ImGuiStyleMod::ImGuiStyleMod imgui_internal.lua:1280
|
||||||
|
|
||||||
-- Widgets support: flags, enums, data structures
|
-- Widgets support: flags, enums, data structures
|
||||||
[x] 21% ImGuiComboPreviewData::ImGuiComboPreviewData imgui_internal.lua:1665
|
[x] 21% ImGuiComboPreviewData::ImGuiComboPreviewData imgui_internal.lua:1677
|
||||||
[x] 12% ImGuiMenuColumns::ImGuiMenuColumns imgui_internal.lua:2683
|
[x] 12% ImGuiMenuColumns::ImGuiMenuColumns imgui_internal.lua:2695
|
||||||
[x] 20% ImGuiInputTextDeactivatedState::ImGuiInputTextDeactivatedState imgui_internal.lua:1751
|
[x] 20% ImGuiInputTextDeactivatedState::ImGuiInputTextDeactivatedState imgui_internal.lua:1763
|
||||||
[ ] ImGuiInputTextDeactivatedState::ClearFreeMemory
|
[ ] ImGuiInputTextDeactivatedState::ClearFreeMemory
|
||||||
[ ] ImGuiInputTextState::ClearText
|
[ ] ImGuiInputTextState::ClearText
|
||||||
[ ] ImGuiInputTextState::ClearFreeMemory
|
[ ] ImGuiInputTextState::ClearFreeMemory
|
||||||
[ ] ImGuiInputTextState::GetText
|
[ ] ImGuiInputTextState::GetText
|
||||||
[x] 3% ImGuiNextWindowData::ImGuiNextWindowData imgui_internal.lua:1433
|
[x] 3% ImGuiNextWindowData::ImGuiNextWindowData imgui_internal.lua:1445
|
||||||
[ ] ImGuiNextWindowData::ClearFlags
|
[ ] ImGuiNextWindowData::ClearFlags
|
||||||
[x] 20% ImGuiNextItemData::ImGuiNextItemData imgui_internal.lua:1385
|
[x] 20% ImGuiNextItemData::ImGuiNextItemData imgui_internal.lua:1397
|
||||||
[ ] ImGuiNextItemData::ClearFlags
|
[ ] ImGuiNextItemData::ClearFlags
|
||||||
[x] 11% ImGuiLastItemData::ImGuiLastItemData imgui_internal.lua:1305
|
[x] 11% ImGuiLastItemData::ImGuiLastItemData imgui_internal.lua:1317
|
||||||
[x] 8% ImGuiErrorRecoveryState::ImGuiErrorRecoveryState imgui.lua:19808
|
[x] 8% ImGuiErrorRecoveryState::ImGuiErrorRecoveryState imgui.lua:19808
|
||||||
[ ] ImGuiPtrOrIndex::ImGuiPtrOrIndex
|
[ ] ImGuiPtrOrIndex::ImGuiPtrOrIndex
|
||||||
|
|
||||||
-- Popup support
|
-- Popup support
|
||||||
[x] 36% ImGuiPopupData::ImGuiPopupData imgui_internal.lua:3570
|
[x] 36% ImGuiPopupData::ImGuiPopupData imgui_internal.lua:3582
|
||||||
|
|
||||||
-- Inputs support
|
-- Inputs support
|
||||||
[x] 9% ImGuiInputEvent::ImGuiInputEvent imgui_internal.lua:3364
|
[x] 9% ImGuiInputEvent::ImGuiInputEvent imgui_internal.lua:3376
|
||||||
[x] 73% ImGuiKeyRoutingData::ImGuiKeyRoutingData imgui_internal.lua:1772
|
[x] 73% ImGuiKeyRoutingData::ImGuiKeyRoutingData imgui_internal.lua:1784
|
||||||
[x] 10% ImGuiKeyRoutingTable::ImGuiKeyRoutingTable imgui_internal.lua:1799
|
[x] 10% ImGuiKeyRoutingTable::ImGuiKeyRoutingTable imgui_internal.lua:1811
|
||||||
[ ] ImGuiKeyRoutingTable::Clear
|
[ ] ImGuiKeyRoutingTable::Clear
|
||||||
[x] 64% ImGuiKeyOwnerData::ImGuiKeyOwnerData imgui_internal.lua:647
|
[x] 64% ImGuiKeyOwnerData::ImGuiKeyOwnerData imgui_internal.lua:659
|
||||||
|
|
||||||
-- Clipper support
|
-- Clipper support
|
||||||
[ ] ImGuiListClipperRange::FromIndices
|
[ ] ImGuiListClipperRange::FromIndices
|
||||||
@@ -2216,25 +2216,25 @@ imgui_internal.h
|
|||||||
[ ] ImGuiListClipperData::Reset
|
[ ] ImGuiListClipperData::Reset
|
||||||
|
|
||||||
-- Navigation support
|
-- Navigation support
|
||||||
[x] 13% ImGuiNavItemData::ImGuiNavItemData imgui_internal.lua:1905
|
[x] 13% ImGuiNavItemData::ImGuiNavItemData imgui_internal.lua:1917
|
||||||
[ ] ImGuiNavItemData::Clear
|
[ ] ImGuiNavItemData::Clear
|
||||||
|
|
||||||
-- Typing-select support
|
-- Typing-select support
|
||||||
[x] 7% ImGuiTypingSelectState::ImGuiTypingSelectState imgui_internal.lua:1949
|
[x] 7% ImGuiTypingSelectState::ImGuiTypingSelectState imgui_internal.lua:1961
|
||||||
[x] 71% ImGuiTypingSelectState::Clear imgui_internal.lua:1952
|
[x] 71% ImGuiTypingSelectState::Clear imgui_internal.lua:1964
|
||||||
|
|
||||||
-- Columns support
|
-- Columns support
|
||||||
[x] 19% ImGuiOldColumnData::ImGuiOldColumnData imgui_tables.lua:340
|
[x] 19% ImGuiOldColumnData::ImGuiOldColumnData imgui_tables.lua:340
|
||||||
[x] 5% ImGuiOldColumns::ImGuiOldColumns imgui_tables.lua:345
|
[x] 5% ImGuiOldColumns::ImGuiOldColumns imgui_tables.lua:345
|
||||||
|
|
||||||
-- Box-select support
|
-- Box-select support
|
||||||
[x] 6% ImGuiBoxSelectState::ImGuiBoxSelectState imgui_internal.lua:1976
|
[x] 6% ImGuiBoxSelectState::ImGuiBoxSelectState imgui_internal.lua:1988
|
||||||
|
|
||||||
-- Multi-select support
|
-- Multi-select support
|
||||||
[x] 9% ImGuiMultiSelectTempData::ImGuiMultiSelectTempData imgui_internal.lua:2022
|
[x] 9% ImGuiMultiSelectTempData::ImGuiMultiSelectTempData imgui_internal.lua:2034
|
||||||
[x] 10% ImGuiMultiSelectTempData::Clear imgui_internal.lua:2028
|
[x] 10% ImGuiMultiSelectTempData::Clear imgui_internal.lua:2040
|
||||||
[x] 67% ImGuiMultiSelectTempData::ClearIO imgui_internal.lua:2046
|
[x] 67% ImGuiMultiSelectTempData::ClearIO imgui_internal.lua:2058
|
||||||
[x] 72% ImGuiMultiSelectState::ImGuiMultiSelectState imgui_internal.lua:2059
|
[x] 72% ImGuiMultiSelectState::ImGuiMultiSelectState imgui_internal.lua:2071
|
||||||
|
|
||||||
-- Docking support
|
-- Docking support
|
||||||
[x] 100% ImGuiDockNode::IsRootNode imgui.lua:1095
|
[x] 100% ImGuiDockNode::IsRootNode imgui.lua:1095
|
||||||
@@ -2252,23 +2252,23 @@ imgui_internal.h
|
|||||||
[x] 20% ImGuiDockContext::ImGuiDockContext imgui.lua:1040
|
[x] 20% ImGuiDockContext::ImGuiDockContext imgui.lua:1040
|
||||||
|
|
||||||
-- Viewport support
|
-- Viewport support
|
||||||
[x] 36% ImGuiViewportP::ImGuiViewportP imgui_internal.lua:3103
|
[x] 36% ImGuiViewportP::ImGuiViewportP imgui_internal.lua:3115
|
||||||
[-] ImGuiViewportP::~ImGuiViewportP c++-only
|
[-] ImGuiViewportP::~ImGuiViewportP c++-only
|
||||||
[x] 78% ImGuiViewportP::ClearRequestFlags imgui_internal.lua:3058
|
[x] 78% ImGuiViewportP::ClearRequestFlags imgui_internal.lua:3070
|
||||||
[x] 94% ImGuiViewportP::CalcWorkRectPos imgui_internal.lua:3065
|
[x] 94% ImGuiViewportP::CalcWorkRectPos imgui_internal.lua:3077
|
||||||
[x] 98% ImGuiViewportP::CalcWorkRectSize imgui_internal.lua:3069
|
[x] 98% ImGuiViewportP::CalcWorkRectSize imgui_internal.lua:3081
|
||||||
[x] 87% ImGuiViewportP::UpdateWorkRect imgui_internal.lua:3074
|
[x] 87% ImGuiViewportP::UpdateWorkRect imgui_internal.lua:3086
|
||||||
[x] 92% ImGuiViewportP::GetMainRect imgui_internal.lua:3081
|
[x] 92% ImGuiViewportP::GetMainRect imgui_internal.lua:3093
|
||||||
[x] 92% ImGuiViewportP::GetWorkRect imgui_internal.lua:3088
|
[x] 92% ImGuiViewportP::GetWorkRect imgui_internal.lua:3100
|
||||||
[x] 96% ImGuiViewportP::GetBuildWorkRect imgui_internal.lua:3095
|
[x] 96% ImGuiViewportP::GetBuildWorkRect imgui_internal.lua:3107
|
||||||
|
|
||||||
-- Settings support
|
-- Settings support
|
||||||
[x] 18% ImGuiWindowSettings::ImGuiWindowSettings imgui_internal.lua:2650
|
[x] 18% ImGuiWindowSettings::ImGuiWindowSettings imgui_internal.lua:2662
|
||||||
[ ] ImGuiWindowSettings::GetName
|
[ ] ImGuiWindowSettings::GetName
|
||||||
[x] 13% ImGuiSettingsHandler::ImGuiSettingsHandler imgui_h.lua:2898
|
[x] 13% ImGuiSettingsHandler::ImGuiSettingsHandler imgui_h.lua:2898
|
||||||
|
|
||||||
-- Metrics, Debug Tools
|
-- Metrics, Debug Tools
|
||||||
[x] 7% ImGuiDebugAllocInfo::ImGuiDebugAllocInfo imgui_internal.lua:1853
|
[x] 7% ImGuiDebugAllocInfo::ImGuiDebugAllocInfo imgui_internal.lua:1865
|
||||||
[ ] ImGuiStackLevelInfo::ImGuiStackLevelInfo
|
[ ] ImGuiStackLevelInfo::ImGuiStackLevelInfo
|
||||||
[ ] ImGuiDebugItemPathQuery::ImGuiDebugItemPathQuery
|
[ ] ImGuiDebugItemPathQuery::ImGuiDebugItemPathQuery
|
||||||
[ ] ImGuiIDStackTool::ImGuiIDStackTool
|
[ ] ImGuiIDStackTool::ImGuiIDStackTool
|
||||||
@@ -2277,12 +2277,12 @@ imgui_internal.h
|
|||||||
[ ] ImGuiContextHook::ImGuiContextHook
|
[ ] ImGuiContextHook::ImGuiContextHook
|
||||||
|
|
||||||
-- ImGuiWindowTempData, ImGuiWindow
|
-- ImGuiWindowTempData, ImGuiWindow
|
||||||
[x] 92% ImGuiWindow::Rect imgui_internal.lua:2824
|
[x] 92% ImGuiWindow::Rect imgui_internal.lua:2836
|
||||||
[x] 84% ImGuiWindow::TitleBarRect imgui_internal.lua:2830
|
[x] 84% ImGuiWindow::TitleBarRect imgui_internal.lua:2842
|
||||||
[x] 91% ImGuiWindow::MenuBarRect imgui_internal.lua:2836
|
[x] 91% ImGuiWindow::MenuBarRect imgui_internal.lua:2848
|
||||||
|
|
||||||
-- Tab bar, Tab item support
|
-- Tab bar, Tab item support
|
||||||
[x] 50% ImGuiTabItem::ImGuiTabItem imgui_internal.lua:2191
|
[x] 50% ImGuiTabItem::ImGuiTabItem imgui_internal.lua:2203
|
||||||
|
|
||||||
-- Table support + internal API
|
-- Table support + internal API
|
||||||
[x] 28% ImGuiTableColumn::ImGuiTableColumn imgui_tables.lua:240
|
[x] 28% ImGuiTableColumn::ImGuiTableColumn imgui_tables.lua:240
|
||||||
@@ -2302,32 +2302,32 @@ imgui_internal.h
|
|||||||
[x] 100% GetCurrentWindowRead imgui.lua:13592
|
[x] 100% GetCurrentWindowRead imgui.lua:13592
|
||||||
[x] 100% GetCurrentWindow imgui.lua:13599
|
[x] 100% GetCurrentWindow imgui.lua:13599
|
||||||
[ ] SetWindowParentWindowForFocusRoute
|
[ ] SetWindowParentWindowForFocusRoute
|
||||||
[x] 99% WindowRectAbsToRel imgui_internal.lua:664
|
[x] 99% WindowRectAbsToRel imgui_internal.lua:676
|
||||||
[x] 99% WindowRectRelToAbs imgui_internal.lua:669
|
[x] 99% WindowRectRelToAbs imgui_internal.lua:681
|
||||||
[x] 98% WindowPosAbsToRel imgui_internal.lua:682
|
[x] 98% WindowPosAbsToRel imgui_internal.lua:694
|
||||||
[x] 98% WindowPosRelToAbs imgui_internal.lua:688
|
[x] 98% WindowPosRelToAbs imgui_internal.lua:700
|
||||||
[ ] GetPixelDensity
|
[ ] GetPixelDensity
|
||||||
[x] 55% GetRoundedFontSize imgui_internal.lua:658
|
[x] 55% GetRoundedFontSize imgui_internal.lua:670
|
||||||
[x] 15% GetForegroundDrawList imgui.lua:13675
|
[x] 15% GetForegroundDrawList imgui.lua:13675
|
||||||
[x] 80% LocalizeGetMsg imgui_internal.lua:3674
|
[x] 80% LocalizeGetMsg imgui_internal.lua:3686
|
||||||
[ ] ScrollToBringRectIntoView
|
[ ] ScrollToBringRectIntoView
|
||||||
[ ] GetItemStatusFlags
|
[ ] GetItemStatusFlags
|
||||||
[ ] GetActiveID
|
[ ] GetActiveID
|
||||||
[ ] GetFocusID
|
[ ] GetFocusID
|
||||||
[x] 2% ItemSize imgui.lua:6492
|
[x] 2% ItemSize imgui.lua:6492
|
||||||
[x] 100% IsNamedKey imgui_internal.lua:572
|
[x] 100% IsNamedKey imgui_internal.lua:584
|
||||||
[x] 75% IsNamedKeyOrMod imgui_internal.lua:603
|
[x] 75% IsNamedKeyOrMod imgui_internal.lua:615
|
||||||
[ ] IsLegacyKey
|
[ ] IsLegacyKey
|
||||||
[x] 60% IsKeyboardKey imgui_internal.lua:577
|
[x] 60% IsKeyboardKey imgui_internal.lua:589
|
||||||
[x] 60% IsGamepadKey imgui_internal.lua:582
|
[x] 60% IsGamepadKey imgui_internal.lua:594
|
||||||
[x] 60% IsMouseKey imgui_internal.lua:587
|
[x] 60% IsMouseKey imgui_internal.lua:599
|
||||||
[x] 60% IsAliasKey imgui_internal.lua:592
|
[x] 60% IsAliasKey imgui_internal.lua:604
|
||||||
[x] 100% IsLRModKey imgui_internal.lua:597
|
[x] 100% IsLRModKey imgui_internal.lua:609
|
||||||
[x] 76% ConvertSingleModFlagToKey imgui_internal.lua:609
|
[x] 76% ConvertSingleModFlagToKey imgui_internal.lua:621
|
||||||
[x] 17% GetKeyData imgui.lua:8440
|
[x] 17% GetKeyData imgui.lua:8440
|
||||||
[x] 97% MouseButtonToKey imgui_internal.lua:569
|
[x] 97% MouseButtonToKey imgui_internal.lua:581
|
||||||
[x] 81% IsActiveIdUsingNavDir imgui_internal.lua:673
|
[x] 81% IsActiveIdUsingNavDir imgui_internal.lua:685
|
||||||
[x] 88% GetKeyOwnerData imgui_internal.lua:635
|
[x] 88% GetKeyOwnerData imgui_internal.lua:647
|
||||||
[x] 100% DockNodeGetRootNode imgui.lua:4488
|
[x] 100% DockNodeGetRootNode imgui.lua:4488
|
||||||
[x] 100% DockNodeIsInHierarchyOf imgui.lua:4493
|
[x] 100% DockNodeIsInHierarchyOf imgui.lua:4493
|
||||||
[x] 86% DockNodeGetDepth imgui.lua:4501
|
[x] 86% DockNodeGetDepth imgui.lua:4501
|
||||||
@@ -2335,26 +2335,26 @@ imgui_internal.h
|
|||||||
[ ] GetWindowDockNode
|
[ ] GetWindowDockNode
|
||||||
[x] 97% DockBuilderGetCentralNode imgui.lua:3661
|
[x] 97% DockBuilderGetCentralNode imgui.lua:3661
|
||||||
[ ] GetCurrentFocusScope
|
[ ] GetCurrentFocusScope
|
||||||
[x] 91% GetBoxSelectState imgui_internal.lua:2065
|
[x] 91% GetBoxSelectState imgui_internal.lua:2077
|
||||||
[x] 95% GetMultiSelectState imgui_internal.lua:2068
|
[x] 95% GetMultiSelectState imgui_internal.lua:2080
|
||||||
[ ] GetCurrentTabBar
|
[ ] GetCurrentTabBar
|
||||||
[x] 35% TabBarGetTabOrder imgui_widgets.lua:11197
|
[x] 35% TabBarGetTabOrder imgui_widgets.lua:11197
|
||||||
[-] RenderNavHighlight obsolete
|
[-] RenderNavHighlight obsolete
|
||||||
[x] 100% TempInputIsActive imgui_internal.lua:3681
|
[x] 100% TempInputIsActive imgui_internal.lua:3693
|
||||||
[x] 88% GetInputTextState imgui_internal.lua:3689
|
[x] 88% GetInputTextState imgui_internal.lua:3701
|
||||||
[ ] IsItemActiveAsInputText
|
[ ] IsItemActiveAsInputText
|
||||||
[x] 80% SetNextItemColorMarker imgui_internal.lua:1083
|
[x] 80% SetNextItemColorMarker imgui_internal.lua:1095
|
||||||
|
|
||||||
-- ImFontLoader
|
-- ImFontLoader
|
||||||
[x] 6% ImFontLoader::ImFontLoader imgui_internal.lua:3165
|
[x] 6% ImFontLoader::ImFontLoader imgui_internal.lua:3177
|
||||||
|
|
||||||
-- ImFontAtlas internal API
|
-- ImFontAtlas internal API
|
||||||
[-] operator== c++-only
|
[-] operator== c++-only
|
||||||
[-] operator!= c++-only
|
[-] operator!= c++-only
|
||||||
[x] 75% ImFontAtlasRectId_GetIndex imgui_internal.lua:3217
|
[x] 75% ImFontAtlasRectId_GetIndex imgui_internal.lua:3229
|
||||||
[x] 62% ImFontAtlasRectId_GetGeneration imgui_internal.lua:3221
|
[x] 62% ImFontAtlasRectId_GetGeneration imgui_internal.lua:3233
|
||||||
[x] 77% ImFontAtlasRectId_Make imgui_internal.lua:3226
|
[x] 77% ImFontAtlasRectId_Make imgui_internal.lua:3238
|
||||||
[x] 18% ImFontAtlasBuilder::ImFontAtlasBuilder imgui_internal.lua:1184
|
[x] 18% ImFontAtlasBuilder::ImFontAtlasBuilder imgui_internal.lua:1196
|
||||||
|
|
||||||
====================================================================================================
|
====================================================================================================
|
||||||
API declarations not ported (by upstream line)
|
API declarations not ported (by upstream line)
|
||||||
@@ -2489,7 +2489,7 @@ Enums (values ported / total; missing listed)
|
|||||||
ImGuiWindowRefreshFlags_ 4 / 4
|
ImGuiWindowRefreshFlags_ 4 / 4
|
||||||
ImTextureFormat 2 / 2
|
ImTextureFormat 2 / 2
|
||||||
ImTextureStatus 5 / 5
|
ImTextureStatus 5 / 5
|
||||||
ImTriangulatorNodeType 0 / 3 missing: ImTriangulatorNodeType_Convex, ImTriangulatorNodeType_Ear, ImTriangulatorNodeType_Reflex
|
ImTriangulatorNodeType 3 / 3
|
||||||
ImWcharClass 3 / 3
|
ImWcharClass 3 / 3
|
||||||
MyItemColumnID 5 / 5
|
MyItemColumnID 5 / 5
|
||||||
|
|
||||||
@@ -2635,8 +2635,8 @@ Struct fields (name found in the port / total; missing listed). Field names are
|
|||||||
ImRect 2 / 2
|
ImRect 2 / 2
|
||||||
ImTextureData 16 / 17 missing: QueueUserData
|
ImTextureData 16 / 17 missing: QueueUserData
|
||||||
ImTextureRect 4 / 4
|
ImTextureRect 4 / 4
|
||||||
ImTriangulator 0 / 4 missing: _TrianglesLeft, _Nodes, _Ears, _Reflexes
|
ImTriangulator 4 / 4
|
||||||
ImTriangulatorNode 3 / 5 missing: Next, Prev
|
ImTriangulatorNode 5 / 5
|
||||||
ImTriangulatorNodeSpan 2 / 2
|
ImTriangulatorNodeSpan 2 / 2
|
||||||
ImVec2i 2 / 2
|
ImVec2i 2 / 2
|
||||||
ImVec2ih 2 / 2
|
ImVec2ih 2 / 2
|
||||||
|
|||||||
+329
-35
@@ -7455,47 +7455,341 @@ function MT.ImDrawList:PathBezierQuadraticCurveTo(p2, p3, num_segments)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ponytail: ear-clipping, no anti-aliased fringe (upstream's AA triangulator not ported). O(n^2) is fine for UI polygons.
|
--------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] ImTriangulator, ImDrawList concave polygon fill
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity.
|
||||||
|
-- Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
|
||||||
|
-- Provided as a convenience for user but not used by main library.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- - ImTriangulator [Internal]
|
||||||
|
-- - AddConcavePolyFilled()
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local ImTriangulatorNodeType =
|
||||||
|
{
|
||||||
|
Convex = 0,
|
||||||
|
Ear = 1,
|
||||||
|
Reflex = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- [Luau] No pointers: a node is an int handle (1-based slot) into the parallel arrays of its ImTriangulator
|
||||||
|
-- (tri.Type[n], tri.Index[n], tri.Pos[n], tri.Next[n], tri.Prev[n]). node->Index (0-based, as upstream) == n - 1.
|
||||||
|
local function ImTriangulatorNode_Unlink(tri, n) tri.Prev[tri.Next[n]] = tri.Prev[n]; tri.Next[tri.Prev[n]] = tri.Next[n] end
|
||||||
|
|
||||||
|
-- [Luau] Deviation: upstream classifies a node as reflex when '!ImTriangleIsClockwise()', i.e. also when its corner is
|
||||||
|
-- degenerate (collinear or duplicate points). A duplicate point then sits as a reflex on top of every candidate ear's vertex
|
||||||
|
-- and blocks it, ending in the degenerate fallback with overlapping triangles. Only strictly counter-clockwise corners are
|
||||||
|
-- reflex here: degenerate corners are clipped as zero-area ears.
|
||||||
|
local function ImTriangulator_IsReflex(a, b, c) return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) < 0.0 end
|
||||||
|
|
||||||
|
local function ImTriangulatorNodeSpan()
|
||||||
|
return { Data = {}, Size = 0 } -- Data: node handles, 1-based
|
||||||
|
end
|
||||||
|
MT.ImTriangulatorNodeSpan = {}
|
||||||
|
MT.ImTriangulatorNodeSpan.__index = MT.ImTriangulatorNodeSpan
|
||||||
|
function MT.ImTriangulatorNodeSpan:push_back(node) self.Size = self.Size + 1; self.Data[self.Size] = node end
|
||||||
|
function MT.ImTriangulatorNodeSpan:find_erase_unsorted(idx) for i = self.Size, 1, -1 do if self.Data[i] - 1 == idx then self.Data[i] = self.Data[self.Size]; self.Size = self.Size - 1; return end end end
|
||||||
|
|
||||||
|
-- [Luau] The node/ears/reflexes storage (upstream: carved out of _Data->TempBuffer via scratch_buffer) is owned by the
|
||||||
|
-- triangulator itself and only ever grows. AddConcavePolyFilled() reuses a single module-level instance (no per-call allocations).
|
||||||
|
local function ImTriangulator()
|
||||||
|
return setmetatable({
|
||||||
|
_TrianglesLeft = 0,
|
||||||
|
_Nodes = 0, -- node handle (head of the circular list)
|
||||||
|
_Ears = setmetatable(ImTriangulatorNodeSpan(), MT.ImTriangulatorNodeSpan),
|
||||||
|
_Reflexes = setmetatable(ImTriangulatorNodeSpan(), MT.ImTriangulatorNodeSpan),
|
||||||
|
Type = {}, Index = {}, Pos = {}, Next = {}, Prev = {}, -- [Luau] ImTriangulatorNode fields, one array each
|
||||||
|
}, MT.ImTriangulator)
|
||||||
|
end
|
||||||
|
MT.ImTriangulator = {}
|
||||||
|
MT.ImTriangulator.__index = MT.ImTriangulator
|
||||||
|
|
||||||
|
function MT.ImTriangulator.EstimateTriangleCount(points_count) return (points_count < 3) and 0 or points_count - 2 end
|
||||||
|
-- [Luau] In elements (nodes + ears + reflexes) rather than bytes. Unused by the port: arrays grow on demand.
|
||||||
|
function MT.ImTriangulator.EstimateScratchBufferSize(points_count) return points_count + points_count * 2 end
|
||||||
|
|
||||||
|
-- Distribute storage for nodes, ears and reflexes.
|
||||||
|
-- FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer
|
||||||
|
-- (this would require first building reflexes to bail to convex if empty, without even building nodes)
|
||||||
--- @param points ImVec2[] # 1-based
|
--- @param points ImVec2[] # 1-based
|
||||||
function MT.ImDrawList:AddConcavePolyFilled(points, points_count, col)
|
function MT.ImTriangulator:Init(points, points_count)
|
||||||
if points_count < 3 or bit32.band(col, IM_COL32_A_MASK) == 0 then return end
|
IM_ASSERT(points_count >= 3)
|
||||||
local idx = {}
|
self._TrianglesLeft = MT.ImTriangulator.EstimateTriangleCount(points_count)
|
||||||
local area = 0.0
|
self._Nodes = 1
|
||||||
|
self._Ears.Size = 0
|
||||||
|
self._Reflexes.Size = 0
|
||||||
|
self:BuildNodes(points, points_count)
|
||||||
|
|
||||||
|
-- [Luau] Deviation: upstream only flips the node list when no ear is found, so a counter-clockwise *concave* polygon
|
||||||
|
-- (whose reflex corners look like ears) yields triangles outside of it. Normalize to clockwise order up-front (O(N)).
|
||||||
|
local area2 = 0.0
|
||||||
|
local p0 = points[points_count]
|
||||||
for i = 1, points_count do
|
for i = 1, points_count do
|
||||||
idx[i] = i
|
local p1 = points[i]
|
||||||
local a, b = points[i], points[i % points_count + 1]
|
area2 = area2 + (p0.x * p1.y - p1.x * p0.y)
|
||||||
area = area + (a.x * b.y - b.x * a.y)
|
p0 = p1
|
||||||
end
|
end
|
||||||
local sign = (area >= 0) and 1 or -1
|
if area2 < 0.0 then
|
||||||
local function cross(o, a, b) return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x) end
|
self:FlipNodeList()
|
||||||
local guard = 0
|
end
|
||||||
while #idx > 3 and guard < points_count * points_count do
|
|
||||||
guard = guard + 1
|
self:BuildReflexes()
|
||||||
local n = #idx
|
self:BuildEars()
|
||||||
local clipped = false
|
end
|
||||||
for i = 1, n do
|
|
||||||
local ia, ib, ic = idx[(i - 2) % n + 1], idx[i], idx[i % n + 1]
|
function MT.ImTriangulator:BuildNodes(points, points_count)
|
||||||
local a, b, c = points[ia], points[ib], points[ic]
|
local Type, Index, Pos, Next, Prev = self.Type, self.Index, self.Pos, self.Next, self.Prev
|
||||||
if cross(a, b, c) * sign > 0 then
|
for i = 1, points_count do
|
||||||
local inside = false
|
Type[i] = ImTriangulatorNodeType.Convex
|
||||||
for j = 1, n do
|
Index[i] = i - 1
|
||||||
local p = idx[j]
|
Pos[i] = points[i] -- [Luau] reference, not a copy (points are not modified while triangulating)
|
||||||
if p ~= ia and p ~= ib and p ~= ic then
|
Next[i] = i + 1
|
||||||
local q = points[p]
|
Prev[i] = i - 1
|
||||||
if cross(a, b, q) * sign >= 0 and cross(b, c, q) * sign >= 0 and cross(c, a, q) * sign >= 0 then inside = true; break end
|
end
|
||||||
end
|
Prev[1] = points_count
|
||||||
end
|
Next[points_count] = 1
|
||||||
if not inside then
|
end
|
||||||
self:AddTriangleFilled(a, b, c, col)
|
|
||||||
table.remove(idx, i)
|
function MT.ImTriangulator:BuildReflexes()
|
||||||
clipped = true
|
local Pos, Next, Prev = self.Pos, self.Next, self.Prev
|
||||||
break
|
local n1 = self._Nodes
|
||||||
end
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
if ImTriangulator_IsReflex(Pos[Prev[n1]], Pos[n1], Pos[Next[n1]]) then
|
||||||
|
self.Type[n1] = ImTriangulatorNodeType.Reflex
|
||||||
|
self._Reflexes:push_back(n1)
|
||||||
|
end
|
||||||
|
n1 = Next[n1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:BuildEars()
|
||||||
|
local Index, Pos, Next, Prev = self.Index, self.Pos, self.Next, self.Prev
|
||||||
|
local n1 = self._Nodes
|
||||||
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
if self.Type[n1] == ImTriangulatorNodeType.Convex then
|
||||||
|
local n0, n2 = Prev[n1], Next[n1]
|
||||||
|
if self:IsEar(Index[n0], Index[n1], Index[n2], Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
self.Type[n1] = ImTriangulatorNodeType.Ear
|
||||||
|
self._Ears:push_back(n1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not clipped then break end
|
n1 = Next[n1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [Luau] out_triangle[3] is returned as 3 values (relative 0-based indexes)
|
||||||
|
function MT.ImTriangulator:GetNextTriangle()
|
||||||
|
if self._Ears.Size == 0 then
|
||||||
|
self:FlipNodeList()
|
||||||
|
|
||||||
|
local node = self._Nodes
|
||||||
|
for _ = self._TrianglesLeft, 0, -1 do
|
||||||
|
self.Type[node] = ImTriangulatorNodeType.Convex
|
||||||
|
node = self.Next[node]
|
||||||
|
end
|
||||||
|
self._Reflexes.Size = 0
|
||||||
|
self:BuildReflexes()
|
||||||
|
self:BuildEars()
|
||||||
|
|
||||||
|
-- If we still don't have ears, it means geometry is degenerated.
|
||||||
|
if self._Ears.Size == 0 then
|
||||||
|
-- Return first triangle available, mimicking the behavior of convex fill.
|
||||||
|
IM_ASSERT(self._TrianglesLeft > 0) -- Geometry is degenerated
|
||||||
|
self._Ears.Data[1] = self._Nodes
|
||||||
|
self._Ears.Size = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ear = self._Ears.Data[self._Ears.Size]
|
||||||
|
self._Ears.Size = self._Ears.Size - 1
|
||||||
|
local Index, Next, Prev = self.Index, self.Next, self.Prev
|
||||||
|
local t0, t1, t2 = Index[Prev[ear]], Index[ear], Index[Next[ear]]
|
||||||
|
|
||||||
|
ImTriangulatorNode_Unlink(self, ear)
|
||||||
|
if ear == self._Nodes then
|
||||||
|
self._Nodes = Next[ear]
|
||||||
|
end
|
||||||
|
|
||||||
|
self:ReclassifyNode(Prev[ear])
|
||||||
|
self:ReclassifyNode(Next[ear])
|
||||||
|
self._TrianglesLeft = self._TrianglesLeft - 1
|
||||||
|
return t0, t1, t2
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:FlipNodeList()
|
||||||
|
local Next, Prev = self.Next, self.Prev
|
||||||
|
local nodes = self._Nodes
|
||||||
|
local prev = nodes
|
||||||
|
local temp = nodes
|
||||||
|
local current = Next[nodes]
|
||||||
|
Next[prev] = prev
|
||||||
|
Prev[prev] = prev
|
||||||
|
while current ~= nodes do
|
||||||
|
temp = Next[current]
|
||||||
|
|
||||||
|
Next[current] = prev
|
||||||
|
Prev[prev] = current
|
||||||
|
Next[nodes] = current
|
||||||
|
Prev[current] = nodes
|
||||||
|
|
||||||
|
prev = current
|
||||||
|
current = temp
|
||||||
|
end
|
||||||
|
self._Nodes = prev
|
||||||
|
end
|
||||||
|
|
||||||
|
-- A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm)
|
||||||
|
function MT.ImTriangulator:IsEar(i0, i1, i2, v0, v1, v2)
|
||||||
|
local Index, Pos = self.Index, self.Pos
|
||||||
|
local data = self._Reflexes.Data
|
||||||
|
for p = 1, self._Reflexes.Size do
|
||||||
|
local reflex = data[p]
|
||||||
|
local idx = Index[reflex]
|
||||||
|
if idx ~= i0 and idx ~= i1 and idx ~= i2 then
|
||||||
|
if ImStd.ImTriangleContainsPoint(v0, v1, v2, Pos[reflex]) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function MT.ImTriangulator:ReclassifyNode(n1)
|
||||||
|
-- Classify node
|
||||||
|
local type
|
||||||
|
local n0 = self.Prev[n1]
|
||||||
|
local n2 = self.Next[n1]
|
||||||
|
local Index, Pos = self.Index, self.Pos
|
||||||
|
if ImTriangulator_IsReflex(Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
type = ImTriangulatorNodeType.Reflex
|
||||||
|
elseif self:IsEar(Index[n0], Index[n1], Index[n2], Pos[n0], Pos[n1], Pos[n2]) then
|
||||||
|
type = ImTriangulatorNodeType.Ear
|
||||||
|
else
|
||||||
|
type = ImTriangulatorNodeType.Convex
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update lists when a type changes
|
||||||
|
local n1_type = self.Type[n1]
|
||||||
|
if type == n1_type then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if n1_type == ImTriangulatorNodeType.Reflex then
|
||||||
|
self._Reflexes:find_erase_unsorted(Index[n1])
|
||||||
|
elseif n1_type == ImTriangulatorNodeType.Ear then
|
||||||
|
self._Ears:find_erase_unsorted(Index[n1])
|
||||||
|
end
|
||||||
|
if type == ImTriangulatorNodeType.Reflex then
|
||||||
|
self._Reflexes:push_back(n1)
|
||||||
|
elseif type == ImTriangulatorNodeType.Ear then
|
||||||
|
self._Ears:push_back(n1)
|
||||||
|
end
|
||||||
|
self.Type[n1] = type
|
||||||
|
end
|
||||||
|
|
||||||
|
local concave_triangulator = ImTriangulator() -- [Luau] reused scratch (see ImTriangulator())
|
||||||
|
|
||||||
|
-- Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes).
|
||||||
|
-- (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer!
|
||||||
|
-- It is up to caller to ensure not making costly calls that will be outside of visible area.
|
||||||
|
-- As concave fill is noticeably more expensive than other primitives, be mindful of this...
|
||||||
|
-- Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false')
|
||||||
|
--- @param points ImVec2[] # 1-based
|
||||||
|
--- @param points_count int
|
||||||
|
--- @param col ImU32
|
||||||
|
@native
|
||||||
|
function MT.ImDrawList:AddConcavePolyFilled(points, points_count, col)
|
||||||
|
if points_count < 3 or bit32.band(col, IM_COL32_A_MASK) == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local uv = self._Data.TexUvWhitePixel
|
||||||
|
local uv_x, uv_y = uv.x, uv.y
|
||||||
|
local triangulator = concave_triangulator
|
||||||
|
if bit32.band(self.Flags, ImDrawFlags.AAFill) ~= 0 then
|
||||||
|
-- Anti-aliased Fill
|
||||||
|
local AA_SIZE = self._FringeScale
|
||||||
|
local col_trans = bit32.band(col, bit32.bnot(IM_COL32_A_MASK))
|
||||||
|
local idx_count = (points_count - 2) * 3 + points_count * 6
|
||||||
|
local vtx_count = (points_count * 2)
|
||||||
|
PrimReserve(self, idx_count, vtx_count)
|
||||||
|
local vb = self.VtxBuffer.Buf
|
||||||
|
local ib = self.IdxBuffer.Data
|
||||||
|
local vw = self._VtxWritePtr
|
||||||
|
local iw = self._IdxWritePtr
|
||||||
|
|
||||||
|
-- Add indexes for fill
|
||||||
|
local vtx_inner_idx = self._VtxCurrentIdx
|
||||||
|
local vtx_outer_idx = self._VtxCurrentIdx + 1
|
||||||
|
|
||||||
|
triangulator:Init(points, points_count)
|
||||||
|
while triangulator._TrianglesLeft > 0 do
|
||||||
|
local t0, t1, t2 = triangulator:GetNextTriangle()
|
||||||
|
ib[iw + 0] = vtx_inner_idx + t0 * 2; ib[iw + 1] = vtx_inner_idx + t1 * 2; ib[iw + 2] = vtx_inner_idx + t2 * 2
|
||||||
|
iw = iw + 3
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Compute normals
|
||||||
|
-- [Luau] scratch arrays (see AddPolyline) instead of _Data->TempBuffer. Indexes below are 1-based.
|
||||||
|
local temp_normals_x, temp_normals_y = poly_normals_x, poly_normals_y
|
||||||
|
local i0 = points_count
|
||||||
|
for i1 = 1, points_count do
|
||||||
|
local p0 = points[i0]
|
||||||
|
local p1 = points[i1]
|
||||||
|
local dx, dy = IM_NORMALIZE2F_OVER_ZERO(p1.x - p0.x, p1.y - p0.y)
|
||||||
|
temp_normals_x[i0] = dy
|
||||||
|
temp_normals_y[i0] = -dx
|
||||||
|
i0 = i1
|
||||||
|
end
|
||||||
|
|
||||||
|
i0 = points_count
|
||||||
|
for i1 = 1, points_count do
|
||||||
|
-- Average normals
|
||||||
|
local dm_x, dm_y = IM_FIXNORMAL2F((temp_normals_x[i0] + temp_normals_x[i1]) * 0.5, (temp_normals_y[i0] + temp_normals_y[i1]) * 0.5)
|
||||||
|
dm_x = dm_x * AA_SIZE * 0.5
|
||||||
|
dm_y = dm_y * AA_SIZE * 0.5
|
||||||
|
|
||||||
|
-- Add vertices
|
||||||
|
local p1 = points[i1]
|
||||||
|
WV(vb, vw, p1.x - dm_x, p1.y - dm_y, uv_x, uv_y, col) -- Inner
|
||||||
|
WV(vb, vw + 1, p1.x + dm_x, p1.y + dm_y, uv_x, uv_y, col_trans) -- Outer
|
||||||
|
vw = vw + 2
|
||||||
|
|
||||||
|
-- Add indexes for fringes
|
||||||
|
local e0, e1 = (i0 - 1) * 2, (i1 - 1) * 2
|
||||||
|
ib[iw + 0] = vtx_inner_idx + e1; ib[iw + 1] = vtx_inner_idx + e0; ib[iw + 2] = vtx_outer_idx + e0
|
||||||
|
ib[iw + 3] = vtx_outer_idx + e0; ib[iw + 4] = vtx_outer_idx + e1; ib[iw + 5] = vtx_inner_idx + e1
|
||||||
|
iw = iw + 6
|
||||||
|
i0 = i1
|
||||||
|
end
|
||||||
|
self._VtxWritePtr = vw
|
||||||
|
self._IdxWritePtr = iw
|
||||||
|
self._VtxCurrentIdx = self._VtxCurrentIdx + vtx_count
|
||||||
|
else
|
||||||
|
-- Non Anti-aliased Fill
|
||||||
|
local idx_count = (points_count - 2) * 3
|
||||||
|
local vtx_count = points_count
|
||||||
|
PrimReserve(self, idx_count, vtx_count)
|
||||||
|
local vb = self.VtxBuffer.Buf
|
||||||
|
local ib = self.IdxBuffer.Data
|
||||||
|
local vw = self._VtxWritePtr
|
||||||
|
local iw = self._IdxWritePtr
|
||||||
|
for i = 1, vtx_count do
|
||||||
|
local p = points[i]
|
||||||
|
WV(vb, vw, p.x, p.y, uv_x, uv_y, col)
|
||||||
|
vw = vw + 1
|
||||||
|
end
|
||||||
|
local base_idx = self._VtxCurrentIdx
|
||||||
|
triangulator:Init(points, points_count)
|
||||||
|
while triangulator._TrianglesLeft > 0 do
|
||||||
|
local t0, t1, t2 = triangulator:GetNextTriangle()
|
||||||
|
ib[iw + 0] = base_idx + t0; ib[iw + 1] = base_idx + t1; ib[iw + 2] = base_idx + t2
|
||||||
|
iw = iw + 3
|
||||||
|
end
|
||||||
|
self._VtxWritePtr = vw
|
||||||
|
self._IdxWritePtr = iw
|
||||||
|
self._VtxCurrentIdx = base_idx + vtx_count
|
||||||
end
|
end
|
||||||
if #idx == 3 then self:AddTriangleFilled(points[idx[1]], points[idx[2]], points[idx[3]], col) end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function MT.ImDrawList:PathFillConcave(col)
|
function MT.ImDrawList:PathFillConcave(col)
|
||||||
|
|||||||
@@ -461,6 +461,18 @@ function ImMul(lhs, rhs)
|
|||||||
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
|
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- @param a ImVec2
|
||||||
|
--- @param b ImVec2
|
||||||
|
--- @param c ImVec2
|
||||||
|
--- @return float
|
||||||
|
function ImTriangleArea(a, b, c) return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5 end
|
||||||
|
|
||||||
|
--- @param a ImVec2
|
||||||
|
--- @param b ImVec2
|
||||||
|
--- @param c ImVec2
|
||||||
|
--- @return boolean
|
||||||
|
function ImTriangleIsClockwise(a, b, c) return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) > 0.0 end
|
||||||
|
|
||||||
--- @param str char[]
|
--- @param str char[]
|
||||||
--- @param begin? int
|
--- @param begin? int
|
||||||
function ImStd.ImStrlen(str, begin)
|
function ImStd.ImStrlen(str, begin)
|
||||||
|
|||||||
Reference in New Issue
Block a user