Files
PlaneBuilding/scratch/dct2/ChunkModule
T

266 lines
8.9 KiB
Plaintext

local slate_color = Color3.fromRGB(124, 124, 124)
local grass_color = Color3.fromRGB(58, 125, 21) -- Color3.fromRGB(58, 125, 21)
local part = Instance.new("Part")
part.Anchored = true
part.CanCollide = true
part.Parent = game.Workspace
part.Material = Enum.Material.Slate
part.Shape = Enum.PartType.Block
part.Color = slate_color
local boom = 10
local math_abs = math.abs
local math_max = math.max
local math_min = math.min
local math_noise = math.noise
local table_create = table.create
local chunks = {}
local function _n(x,y,z) -- Legacy noise
local h = (math_noise(x*0.00015,y*0.00015,z*0.00015)*2)^3
local m = math_noise(x*0.00005,y*0.00005,z*0.00005)
local s = math_noise(x*0.03,y*0.03,z*0.03)
local n = math_noise(x*0.0015,y*0.0015*h,z*0.0015)
y = y - 512 + h * 512
return ((n)*h-y*0.0005)*boom
--[[local h = math_noise(x*0.0005,0.123,z*0.0005)*4
return (math_noise(x*0.0015,y*0.0015*h,z*0.0015)*2*h+math_noise(x*0.005,y*0.005*h,z*0.005)*h-(y+h*10)*0.005)*boom]]
end
local function n_cloud(x,y,z)
return math_noise(x*0.0002,y*0.0002,z*0.0002)
end
local function n_imaginarium(x,y,z) -- Current noise terrain profile
x = x * 2
y = y * 2 + 1024
z = z * 2
local conduit = (1-math_abs(math_noise(x*0.00005,y*0.00005,z*0.00005)))^4 + 0.05
local hillsong = math_noise(x*0.0015,y*0.0015,z*0.0015)*2
local titans = math_noise(x*0.0002,y*0.0002,z*0.0002)*16
return ((titans + hillsong) * conduit - y * 0.00075) * boom
end
local function n_tranquility(x,y,z) -- Fields and hills
y = y - 512
local tranquility = math_noise(x*0.0001,y*0.0001,z*0.0001)
local turbulence = math_noise(x*0.0008,y*0.0008,z*0.0008)
local atmosphere = math_noise(x*0.0005,y*0.0005,z*0.0005)
return ((atmosphere + turbulence) * tranquility - y * 0.0001) * boom
end
local function n_satisfaction(x,y,z) --
return 0
end
--[[local function fol(x,y,z)
local density = math_noise(x*0.0001,y*0.0001,z*0.0001)
local b = math_noise(x*0.001,y*0.001,z*0.001) > 0.5
--local t = math_noise(x*0.001,y*0.001,z*0.001) > 0.3
return b
end]]
local function p(x,y,z,f,parent) -- Create a part at a size
local p = part:Clone()
p.Parent = parent
p.Size = Vector3.one*f
p.Position = Vector3.new(x,y,z)
return p
end
local compensate = 4 -- Make terrain puffy so the octree system can see it clearly
local function m(f)
return boom*compensate
end
-- Preinitialise a data structure to hold game.Workspace.Terrain form of terrain data
local base = 4
local mat
local occ
do
local _otx = table_create(8)
for _x=1,8 do
local _oty = table_create(8)
for _y=1,8 do
_oty[_y] = table_create(8)
end
_otx[_x] = _oty
end
local _mtx = table_create(8)
for _x=1,8 do
local _mty = table_create(8)
for _y=1,8 do
_mty[_y] = table_create(8)
end
_mtx[_x] = _mty
end
occ = _otx
mat = _mtx
end
-- Use the preinitialised data structure from above to render in a chunk of roblox style terrain
local function ter(x,y,z,f)
for ix=1,8 do
for iy=1,8 do
for iz=1,8 do
occ[ix][iy][iz] = n(x+(ix-4)*4,y+(iy-4)*4,z+(iz-4)*4)
mat[ix][iy][iz] = Enum.Material.Grass
end
end
end
workspace.Terrain:WriteVoxels(Region3.new(Vector3.new(x,y,z)-Vector3.one*f*0.5,Vector3.new(x,y,z)+Vector3.one*f*0.5),4,mat,occ)
end
local voro = require(script.Parent.CellularModule) -- Voronoi noise library
local man = voro.man
local mag = voro.mag
local che = voro.che
local cheman = voro.cheman
local vor = voro.vor
local squir = voro.squircle
local function fol(x,y,z)
x = x - x % 32
y = y - y % 32
z = z - z % 32
return math_noise(x*0.00025,y*0.00025-2,z*0.00025)
end
local function act(x)
if x > -5 then return 0.8 end
--if x > -0.1 then return 0.4 end
return 0
end
--local pieces = require(script.Parent.TownPieceModule)
--local block = pieces.block
road = function(x,y,z)
local n1,c1 = vor(x*0.01,y*0.01,z*0.01,che)
local n2,c2 = vor(x*0.002,y*0.002,z*0.002,che) -- 1 = crowded, 0 = empty
local c1x = c1.X*100
local c1y = c1.Y*100
local c1z = c1.Z*100
local d = n(c1x,c1y,c1z)*0.025 -- 0 = surface, -1 = air
if n1 > -d and d > -0.3 --[[and n2 < 0.5]] then
-- Is centre near ground, is building (thinning towards top), is not road, is centre within bounds
return c1x,c1y,c1z
end
--return vor(x*0.002,y*0.002,z*0.002,cheman) + d + 0.3
end
local surf = require(script.Parent.SurfaceNetModule) -- Surface terrain library
local vox = surf.voxel
local rand = Random.new()
local na = Vector3.new(-1,-1,-1) -- Vectors for cardinal directions (corners of a cube)
local nb = Vector3.new(-1,1,1)
local nc = Vector3.new(1,-1,1)
local nd = Vector3.new(1,1,-1)
local ne = Vector3.new(-1,-1,1)
local nf = Vector3.new(-1,1,-1)
local ng = Vector3.new(1,-1,-1)
local nh = Vector3.new(-1,-1,-1)
local trees = game.ReplicatedStorage.Foliage:GetChildren()
local no_trees = #trees
local rand = Random.new()
local struct = require(script.Parent.StructureModule)
@native
local function chunk(x,y,z,f,b,stuff,v,n)
struct.make_chunk(x,y,z,f,n)
local vf = 1/4096
local parent = stuff.parent
local n1,c2 = vor(x*vf,y*vf,z*vf,man)
local val = n(x,y,z)
local grass = stuff.grass.make_quad -- Quad making function from the surface factory for each material
local slate = stuff.slate.make_quad
local bd
local function s(x,y,z,f)
if not b then b = 32 end
local fr = f * 0.25
-- Shift of positions (XYZ axes)
local lx = x+fr
local ly = y+fr
local lz = z+fr
local hx = x-fr
local hy = y-fr
local hz = z-fr
-- Noise values (corners)
local _a,_b,_c,_d,_e,_f,_g,_h = n(lx,ly,lz),n(hx,ly,lz),n(lx,hy,lz),n(lx,ly,hz),n(hx,hy,lz),n(hx,ly,hz),n(lx,hy,hz),n(hx,hy,hz)
local o,dx,dy,dz = n(x,y,z),n(x+1,y,z),n(x,y+1,z),n(x,y,z+1) -- Gradient of surface noises
local norm = Vector3.new(o-dx,o-dy,o-dz).Unit---((_a)*(na)+(_b)*(nb)+(_c)*(nc)+(_d)*(nd)+(_e)*(ne)+(_f)*(nf)+(_g)*(ng)+(_h)*(nh)).Unit --GRAD
local sum = (_a+_b+_c+_d+_e+_f+_g+_h)*0.125 -- Average noise from sample
--[[if f == b and fol(x,y,z) > 0.62 and sum < 0 then
local fs = fr * 2 - 16
for bx = x-fs,x+fs,32 do
for by = y-fs,y+fs,32 do
for bz = z-fs,z+fs,32 do
local cx,cy,cz = road(bx,by,bz)
if cx then pieces.block(bx,by,bz,32,road,cx,cy,cz) end
end
end
end
--vox(x,y,z,b,brick,road)
end]]
if math_max(_a,_b,_c,_d,_e,_f,_g,_h) < -m(f) then -- Nothing to do
return
elseif math_min(_a,_b,_c,_d,_e,_f,_g,_h) > m(f) then --
--[[if b == 4 and f == 32 then
workspace.Terrain:FillRegion(Region3.new(Vector3.new(x,y,z)-Vector3.one*f*0.5,Vector3.new(x,y,z)+Vector3.one*f*0.5),4,Enum.Material.Grass)
else]]
--if b ~= 4 then p(x,y,z,f) end
--end
else -- We are near the surface
--[[if math_abs(norm.Y) < 0.4 and math_abs(sum) < 0.1 and f <= b then
local part = p(x,y,z,f)
part.CFrame = CFrame.lookAlong(part.Position,norm)
part.Size = Vector3.new(part.Size.X*(rand:NextNumber()+2),part.Size.Y*(rand:NextNumber()+2),part.Size.Z*(rand:NextNumber()+1))*2
part.Position = part.Position + norm * f * 0.5
return
end]]
if f == v then
if norm.Y < 0.5 then
vox(x,y,z,v,slate,n,parent)
else
vox(x,y,z,v,grass,n,parent)
end
end
if f == b then -- We are at the rendering level for this chunk
-- Broad building check
if math_abs(sum) < 0.5 and f >= 256 then -- If
if norm.Y < 0.7 then -- Rock
local part = p(x,y,z,math.clamp(f*2.5,0,512),parent)
part.CFrame = CFrame.lookAlong(part.Position-norm*f,norm)
part.Size = Vector3.one * f * 2
else -- Foliage (why does this never run?)
if f > 256 then
local part = p(x,y,z,f*2.5,parent)
part.Material = Enum.Material.Grass
part.Color = grass_color
part.Shape = Enum.PartType.Ball
end
end
elseif f == 512 and rand:NextInteger(1,5) == 5 and n_cloud(x,y,z) > 0 then
local part = p(x,y,z,2048*(rand:NextNumber()+1),parent)
part.Material = Enum.Material.SmoothPlastic
part.Transparency = 0.7
part.Shape = Enum.PartType.Ball
part.Size = part.Size * rand:NextInteger(1,4) * 0.5
end
else -- We are too large, recurse into lower octrees
f = f * 0.5
s(lx,ly,lz,f) s(hx,ly,lz,f) s(lx,hy,lz,f) s(lx,ly,hz,f) s(hx,hy,lz,f) s(hx,ly,hz,f) s(lx,hy,hz,f) s(hx,hy,hz,f)
end
end
end
s(x,y,z,f)
end
local grass = surf.make_wedges(nil,{Material = Enum.Material.Grass, Color = grass_color}) -- Terrain constructors??? WedgePart?
local slate = surf.make_wedges(nil,{Material = Enum.Material.Slate, Color = slate_color})
local function write_chunk(x,y,z,r)
local town_folder = Instance.new("Folder")
town_folder.Parent = game.Workspace.Terrain
local folder = Instance.new("Folder")
folder.Parent = game.Workspace.Terrain
local root = Vector3.new(x,y,z)*512
local b = 512
r = math.floor(r)
if r == 1 then b = 512
elseif r == 2 then b = 256
elseif r >= 3 then b = 128
--elseif r >= 4 then b = 64
end
--task.desynchronize() -- enter parallel and generate the chunk
chunk(x*1024,y*1024,z*1024,1024,b,{grass = grass, slate = slate, parent = folder, town_parent = town_folder},b,n_imaginarium)
--task.synchronize() -- come back to us
return folder,town_folder
end
return {write_chunk = write_chunk}