Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How would I render Triangles linking nodes for my Triangle Terrain Generator?

Asked by
ZeroBits 142
9 years ago

Hello, I'm working on a triangle terrain generator, and already have node generation (using math.noise), but don't have the faintest clue how to go about creating triangles between nodes to create the actual terrain.

What should I do? Are there any tutorials I should read, any advice you have?

1 answer

Log in to vote
1
Answered by
adark 5487 Badge of Merit Moderation Voter Community Moderator
9 years ago

stravant wrote the original triangle fill code that most if not all triangle fill plugins use in some fashion:

local function setupPart(part)
    part.Anchored = true
    part.FormFactor = 'Custom'
    part.CanCollide = PolyDraw.CanCollide
    part.BrickColor = PolyDraw.BrickColor
    part.TopSurface = 'Smooth'
    part.BottomSurface = 'Smooth'
end

function CreateTriangle(parent, a, b, c)
    local this = {}
    local mPart1 = Instance.new('WedgePart')
    setupPart(mPart1)
    local mPart2 = Instance.new('WedgePart')
    setupPart(mPart2)
    function this:Set(a, b, c)
        --[[       edg1
            A ------|------>B  --.
            '\      |      /      \
              \part1|part2/       |
               \   cut   /       / Direction edges point in:
           edg3 \       / edg2  /        (clockwise)
                 \     /      |/
                  \<- /        `
                   \ /
                    C
        --]]
        local ab, bc, ca = b-a, c-b, a-c
        local abm, bcm, cam = ab.magnitude, bc.magnitude, ca.magnitude
        local edg1 = math.abs(0.5 + ca:Dot(ab)/(abm*abm))
        local edg2 = math.abs(0.5 + ab:Dot(bc)/(bcm*bcm))
        local edg3 = math.abs(0.5 + bc:Dot(ca)/(cam*cam))
        -- Idea: Find the edge onto which the vertex opposite that
        -- edge has the projection closest to 1/2 of the way along that 
        -- edge. That is the edge thatwe want to split on in order to 
        -- avoid ending up with small "sliver" triangles with one very
        -- small dimension relative to the other one.
        if edg1 < edg2 then
            if edg1 < edg3 then
                -- min is edg1: less than both
                -- nothing to change
            else            
                -- min is edg3: edg3 < edg1 < edg2
                -- "rotate" verts twice counterclockwise
                a, b, c = c, a, b
                ab, bc, ca = ca, ab, bc
                abm = cam
            end
        else
            if edg2 < edg3 then
                -- min is edg2: less than both
                -- "rotate" verts once counterclockwise
                a, b, c = b, c, a
                ab, bc, ca = bc, ca, ab
                abm = bcm
            else
                -- min is edg3: edg3 < edg2 < edg1
                -- "rotate" verts twice counterclockwise
                a, b, c = c, a, b
                ab, bc, ca = ca, ab, bc
                abm = cam
            end
        end

        --calculate lengths
        local len1 = -ca:Dot(ab)/abm
        local len2 = abm - len1
        local width = (ca + ab.unit*len1).magnitude

        --calculate "base" CFrame to pasition parts by
        local maincf = CFrameFromTopBack(a, ab:Cross(bc).unit, -ab.unit)

        --make parts
        if len1 > 0.2 then
            mPart1.Parent = parent
            mPart1.Size = Vector3.new(0.2, width, len1)
            mPart1.CFrame = maincf*CFrame.Angles(math.pi,0,math.pi/2)*CFrame.new(0,width/2,len1/2)
        else
            mPart1.Parent = nil
        end
        --
        if len2 > 0.2 then
            mPart2.Parent = parent
            mPart2.Size = Vector3.new(0.2, width, len2)
            mPart2.CFrame = maincf*CFrame.Angles(math.pi,math.pi,-math.pi/2)*CFrame.new(0,width/2,-len1 - len2/2)
        else
            mPart2.Parent = nil
        end 
    end
    function this:SetProperty(prop, value)
        mPart1[prop] = value
        mPart2[prop] = value
    end
    this:Set(a, b, c)
    function this:Destroy()
        mPart1:Destroy()
        mPart2:Destroy()
    end
    return this
end

If you want to recreate the features that a specific plugin has, look into its code to see how its modified stravant's fill.

2
...which you can do by going to C:\Users\user\AppData\Local\Roblox\InstalledPlugins, look at all of them (the folder names are random), and open the rbxm. unmiss 337 — 9y
Ad

Answer this question