Hi, I came across a Triangle Terrain generator that I’m trying to deconstruct and learn from;- Right now the Script uses Positions to determine a joining point.
I’m looking to create and use Nodes as opposed to these joining points - However, I only need 1 node for each joining segment.
Does anyone have any suggestions?
--------------------------------------
-- READ THE READ-ME SCRIPT FOR HELP --
-- EDIT BELOW --
--------------------------------------
--
local center = Vector3.new(0,0,0) -- The center position of the terrain.
--
local xLength = 250 -- How long the length of the terrain is.
local zLength = 250 -- How long the width of the terrain is.
--
local spacing = 30 -- How big the size of each terrain segment is.
--
local persistence = 5 -- How steep hills/craters can be.
local amplitude = 15 -- How high hills/craters can be.
local frequency = 15 -- How often hills/craters occur.
--
local octaves = 2 -- How much turbulence in the terrain. Higher = More
local wavelength = 100 -- How flat the terrain is. Higher = Flatter
--
local colour = "Dark green" -- Color of the whole terrain.
local material = "Grass" -- Texture of the whole terrain.
--
local Wedges = {}
local Nodes = {}
-----------------------------------------------------------------------------------------------
-- DON'T EDIT BELOW --
--------------------------------------
local randomseed = math.floor(tick())
local PerlinNoise2D = {
p = {},
gx = {},
gy = {}
}
function PerlinNoise2D:noise(x,y)
local p = self.p
local gx = self.gx
local gy = self.gy
local qx0 = math.floor(x)
local qx1 = qx0 + 1
local qy0 = math.floor(y)
local qy1 = qy0 + 1
local q00 = p[(qy0 + p[qx0])]
local q01 = p[(qy0 + p[qx1])]
local q10 = p[(qy1 + p[qx0])]
local q11 = p[(qy1 + p[qx1])]
local tx0 = x - math.floor(x)
local tx1 = tx0 - 1
local ty0 = y - math.floor(y)
local ty1 = ty0 - 1
local v00 = gx[q00]*tx0 + gy[q00]*ty0
local v01 = gx[q01]*tx1 + gy[q01]*ty0
local v10 = gx[q10]*tx0 + gy[q10]*ty1
local v11 = gx[q11]*tx1 + gy[q11]*ty1
local wx = (3 - 2*tx0)*tx0*tx0
local v0 = v00 - wx*(v00 - v01)
local v1 = v10 - wx*(v10 - v11)
local wy = (3 - 2*ty0)*ty0*ty0
local v = v0 - wy*(v0 - v1)
return v
end
function PerlinNoise2D:getValue(x,y)
local per = persistence
local amp = 1
local frq = frequency
local total = 0
for i = 0,octaves-1 do
amp = per^i
frq = frq^i
total = total + self:noise(x*frq,y*frq)*amp
end
return total*amplitude
end
function PerlinNoise2D:init(seed)
local this = {}
setmetatable(this,self)
self.__index = self
local p = this.p
local gx = this.gx
local gy = this.gy
math.randomseed(seed or 1)
math.random() math.random() math.random()
for i = 0,255 do
p[i] = i
end
for i = 0,255 do
local j = math.random(0,255)
p[i],p[j] = p[j],p[i]
end
p.__index = function(t,k)
return rawget(t,k%255)
end
setmetatable(p,p)
for i = 0,255 do
gx[i] = math.random() + math.random() - 1
gy[i] = math.random() + math.random() - 1
end
return this
end
function spawnTrianglePart(parent)
local p = Instance.new("WedgePart")
p.Anchored = true
p.BottomSurface = 0
p.TopSurface = 0
p.formFactor = "Custom"
p.Size = Vector3.new(1,1,1)
p.Parent = parent or game.Workspace
p.BrickColor = (colour) and BrickColor.new(colour) or BrickColor.new(194)
p.Material = (material) and material or Enum.Material.Plastic
return p
end
function drawTriangle(a,b,c,parent)
local len_AB = (b - a).magnitude
local len_BC = (c - b).magnitude
local len_CA = (a - c).magnitude
if (len_AB > len_BC) and (len_AB > len_CA) then
a,c = c,a
b,c = c,b
elseif (len_CA > len_AB) and (len_CA > len_BC) then
a,b = b,a
b,c = c,b
end
local dot = (a - b):Dot(c - b)
local split = b + (c-b).unit*dot/(c - b).magnitude
local xA = 0.2
local yA = (split - a).magnitude
local zA = (split - b).magnitude
local xB = 0.2
local yB = (split - a).magnitude
local zB = (split - c).magnitude
local diry = (a - split).unit
local dirz = (c - split).unit
local dirx = diry:Cross(dirz).unit
local posA = split + diry*yA/2 - dirz*zA/2
local posB = split + diry*yB/2 + dirz*zB/2
local Model = Instance.new("Model", parent)
local partA = spawnTrianglePart(Model)
partA.Name = "Part"
partA.Size = Vector3.new(xA,yA,zA)
partA.CFrame = CFrame.new(posA.x,posA.y,posA.z, dirx.x,diry.x,dirz.x, dirx.y,diry.y,dirz.y, dirx.z,diry.z,dirz.z)*CFrame.new(-0.1,0,0)
dirx = dirx * -1
dirz = dirz * -1
local partB = spawnTrianglePart(Model)
partB.Name = "Part"
partB.Size = Vector3.new(xB,yB,zB)
partB.CFrame = CFrame.new(posB.x,posB.y,posB.z, dirx.x,diry.x,dirz.x, dirx.y,diry.y,dirz.y, dirx.z,diry.z,dirz.z)*CFrame.new(0.1,0,0)
end
local model = Instance.new("Model",game.Workspace)
model.Name = "Terrain"
local pn2D = PerlinNoise2D:init(randomseed)
local terrain = {}
for z = 0,zLength,spacing do
local t = {}
for x = 0,xLength,spacing do
local n = pn2D:getValue(x/wavelength,z/wavelength)
local a = center.X + (x - xLength/2)
local b = math.max(0,center.Y + n)
local c = center.Z + (z - zLength/2)
table.insert(t,Vector3.new(a,b,c))
end
table.insert(terrain,t)
end
for z = 1,#terrain-1 do
for x = 1,#terrain[z]-1 do
local r = terrain[z][x]
local s = terrain[z][x+1]
local t = terrain[z+1][x]
drawTriangle(r,s,t,model)
local u = terrain[z+1][x+1]
local v = terrain[z+1][x]
local w = terrain[z][x+1]
drawTriangle(u,v,w,model)
local Part = Instance.new("Part")
Part.Parent = workspace
Part.Anchored = true
Part.Position = r
end
end
print("Terrain Complete...")