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?
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.