Better FillWedge

Better alternative to Roblox’s FillWedge. A problem I have with Terrain:FillWedge is that it can result in a lot of unwanted artefacts / holes. As a result, I made my own custom FillWedge function that performs better in my opinion (where I cannot get Roblox’s to look better).

Roblox’s
My version
Bunny as wedges
Converted

I used OBJ Collision Generator Plugin for the bunny and figure it was also useful for importing custom terrain as wedges (where instead of a heightmap, I can import 3D terrain with caves and then convert to terrain using my function.)

The function if anybody wants is,

function FillWedge(wedgeCFrame, wedgeSize, material)
    local terrain = workspace.Terrain
    local Zlen, Ylen = wedgeSize.Z, wedgeSize.Y
    local longerSide, shorterSide, isZlonger
    if Zlen > Ylen then
        longerSide, shorterSide, isZlonger = Zlen, Ylen, true
    else
        longerSide, shorterSide, isZlonger = Ylen, Zlen, false
    end
    
    local closestIntDivisor = math.max(1, math.floor(shorterSide/3))
    local closestQuotient = shorterSide/closestIntDivisor
    local scaledLength = closestQuotient*longerSide/shorterSide    
    local cornerPos = Vector3.new(0, -Ylen, Zlen)/2
    
    for i = 1, closestIntDivisor - 1 do
        local longest_baselen = (closestIntDivisor-i)*scaledLength
        local size, cf = Vector3.new(math.max(3, wedgeSize.X), closestQuotient, longest_baselen)
        if isZlonger then
            cf = wedgeCFrame:toWorldSpace(CFrame.new(cornerPos) + Vector3.new(0, (i-0.5)*closestQuotient, -longest_baselen/2))
        else
            cf = wedgeCFrame:toWorldSpace(CFrame.Angles(math.pi/2, 0, 0) + cornerPos + Vector3.new(0, longest_baselen/2, -(i-0.5)*closestQuotient))
        end
        terrain:FillBlock(cf, size, material)
    end
    
    local diagSize = Vector3.new(math.max(3, wedgeSize.X), closestQuotient*scaledLength/math.sqrt(closestQuotient^2 + scaledLength^2), math.sqrt(Zlen^2 + Ylen^2)) --Vector3.new(3, 3, math.sqrt(Zlen^2 + Ylen^2))
    local rv, bv = wedgeCFrame.RightVector, -(Zlen*wedgeCFrame.LookVector - Ylen*wedgeCFrame.UpVector).Unit
    local uv = bv:Cross(rv).Unit
    local diagPos = wedgeCFrame.p - uv*diagSize.Y/2
    local diagCf = CFrame.fromMatrix(diagPos, rv, uv, bv)
    terrain:FillBlock(diagCf, diagSize, material)
end

There is a great resource on a significant use case of FillWedge where it talks about importing terrain from other 3D software as wedges to then apply FillWedge too. Instead of using a heightmap to import terrain, you can instead use my above custom function to import 3D terrain where you can include underground caves or overhangs not possible with just a heightmap.

Demo which turns a map made of triangles [WedgeParts] into Terrain:
(You can also re-use this code on your own maps and it will paint different terrain materials based on slope angle. Credit.)

CustomFillWedgeDemo.rbxl (340.8 KB)

15 Likes

Very cool. Although I never use the FillWedge feature and probably never will, its cool how you improve on a roblox feature like that.

1 Like