From 5205dc34c161c016da89e6d9a41887971ab0359e Mon Sep 17 00:00:00 2001 From: yoseij <72367202+yoseij@users.noreply.github.com> Date: Thu, 8 Oct 2026 20:19:59 -0700 Subject: [PATCH] Fix certain multi-convex primitive clipping behavior Some multi-convex primitives failed to build when being clipped, this should fix it. --- lua/primitive/core/construct.lua | 33 +++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/lua/primitive/core/construct.lua b/lua/primitive/core/construct.lua index 0da54b4..b76f48c 100644 --- a/lua/primitive/core/construct.lua +++ b/lua/primitive/core/construct.lua @@ -201,20 +201,31 @@ do -- Force the unitary render mesh's cut open when multi-convex, since its cross-section is concave and the cap fan only works on a convex loop. local clipped = result:ApplyClips( clips, multiConvex ) - if clipped then - result = clipped + -- Multi-convex physics is built from each piece's own simpleton, so the pieces decide whether anything is left. + local newConvexes + if istable( preConvexSimpletons ) then + newConvexes = {} + + for i = 1, #preConvexSimpletons do + local clippedSub = preConvexSimpletons[i]:ApplyClips( clips ) + if clippedSub then + newConvexes[#newConvexes + 1] = clippedSub.verts + end + end - if istable( preConvexSimpletons ) then - -- Multi-convex shapes: clip each piece's own triangulated simpleton individually. - local newConvexes = {} + -- The unitary mesh has no triangle index when physics are built without a render mesh (the server), so + -- bisecting it only discards vertices, and it reports "removed" when none lies inside every plane. A shape + -- whose pieces overshoot the clips (e.g. a ladder cut to a rotated outline) has no such vertex, yet most of + -- its pieces survive: keep the uncut mesh rather than throwing the physics away. + if not clipped and #newConvexes > 0 then + clipped = result + end + end - for i = 1, #preConvexSimpletons do - local clippedSub = preConvexSimpletons[i]:ApplyClips( clips ) - if clippedSub then - newConvexes[#newConvexes + 1] = clippedSub.verts - end - end + if clipped then + result = clipped + if newConvexes then result.convexes = newConvexes elseif istable( preConvexes ) and preConvexes[1] == preVerts then -- Single-convex shapes whose convex hull literally is their vertex table can be re-derived directly.