local cellular = require(script.Parent.CellularModule) local module = {} local store = game.ReplicatedStorage:WaitForChild("Structure") local function put(model,x,y,z) model = model:Clone() model:PivotTo(CFrame.new(Vector3.new(x,y,z))) model.Parent = game.Workspace.Terrain end local function block(x,y,z,sx,sy,sz) local part = Instance.new("Part") part.Material = Enum.Material.Slate part.Parent = game.Workspace.Terrain part.Size = Vector3.new(sx,sy,sz) part.Position = Vector3.new(x,y,z) part.Transparency = 0 part.Anchored = true part.CanCollide = false return part end --[[ -- Create a list based tree for octree access local function create_octree_heap(s,l) local sum = 0 local s_ = l local amount = 1 repeat s_ = s_ * 2 sum = sum + amount amount = amount * 8 until s_ ~= s print(sum) local tab = table.create() end local function index_octree_heap(x,y,z) end ]] -- probably not actually fast enough than direct hash access?. optimise later... -- Create a list based tree for 6 bit access local function create_6way_heap() local tab = table.create(64) for index,_ in ipairs(tab) do tab[index] = {} end return tab end -- Index a 6way heap by wall values local function index_6way_heap(heap,px,py,pz,nx,ny,nz) return heap[1 + px * 1 + py * 2 + pz * 4 + nx * 8 + ny * 16 + nz * 32] end local function setindex_6way_heap(heap,px,py,pz,nx,ny,nz,v) heap[1 + px * 1 + py * 2 + pz * 4 + nx * 8 + ny * 16 + nz * 32] = v end local l = -10 -- Index a 6way heap by wall values from a noise function local function access_6way_heap(heap,x,y,z,f,n) f = f * 0.5 local px = 0 if n(x+f,y,z)>l then px = 1 end local py = 0 if n(x,y+f,z)>l then py = 1 end local pz = 0 if n(x,y,z+f)>l then pz = 1 end local nx = 0 if n(x-f,y,z)>l then nx = 1 end local ny = 0 if n(x,y-f,z)>l then ny = 1 end local nz = 0 if n(x,y,z-f)>l then nz = 1 end return index_6way_heap(heap,px,py,pz,nx,ny,nz) end local function preload_6way_heap(heap,stuff) for _,piece in pairs(stuff:GetChildren()) do local n = piece.Name local x = 0 if n:match("PZ") then x = 1 end local y = 0 if n:match("PY") then y = 1 end local z = 0 if n:match("PX") then z = 1 end local nx = 0 if n:match("NZ") then nx = 1 end local ny = 0 if n:match("NY") then ny = 1 end local nz = 0 if n:match("NX") then nz = 1 end piece.PrimaryPart = piece:FindFirstChild("Root") or piece:FindFirstChildWhichIsA("BasePart") piece.PrimaryPart:PivotTo(piece.PrimaryPart.CFrame * CFrame.Angles(0,math.pi * 0.5,0)) if not piece.PrimaryPart then print(piece) error() end local p0 = piece:Clone() p0.Name = p0.Name.."_0" --p0.PrimaryPart:PivotTo(p0.PrimaryPart.CFrame * CFrame.Angles(0,-math.pi*0.0,0)) setindex_6way_heap(heap,x,y,z,nx,ny,nz,p0) local p90 = piece:Clone() p90.Name = p90.Name.."_90" p90.PrimaryPart:PivotTo(p90.PrimaryPart.CFrame * CFrame.Angles(0,math.pi*0.5,0)) setindex_6way_heap(heap,nz,y,x,z,ny,nx,p90) local p180 = piece:Clone() p180.Name = p180.Name.."_180" p180.PrimaryPart:PivotTo(p180.PrimaryPart.CFrame * CFrame.Angles(0,math.pi*1.0,0)) setindex_6way_heap(heap,nx,y,nz,x,ny,z,p180) local p270 = piece:Clone() p270.Name = p270.Name.."_270" p270.PrimaryPart:PivotTo(p270.PrimaryPart.CFrame * CFrame.Angles(0,math.pi*1.5,0)) setindex_6way_heap(heap,z,y,nx,nz,ny,x,p270) -- Anchor the whole thing into one assembly for _,piece in pairs({p0,p90,p180,p270}) do for _,part in pairs(piece:GetChildren()) do if part:IsA("BasePart") and part ~= piece.PrimaryPart then local weld = Instance.new("WeldConstraint") weld.Parent = piece weld.Name = "BuildingWeld" weld.Part0 = part weld.Part1 = piece.PrimaryPart end end piece.PrimaryPart.Anchored = true end end end local heap_6way_32_bank = create_6way_heap() preload_6way_heap(heap_6way_32_bank,store.Bank) local heap_6way_64_slums = create_6way_heap() preload_6way_heap(heap_6way_64_slums,store.Slums) -- Rule: Any block only needs to support up to half away from any connected wall. -- Any block is allowed to protrude up to half into empty space from no wall. local function building_32(x,y,z,sx,sy,sz) local b = block(x,y,z,sx,sy,sz) b.Color = Color3.new(0.568627, 0.341176, 0.152941) b.Material = Enum.Material.WoodPlanks end local function support_32(x,y,z,sx,sy,sz) local b = block(x,y,z,sx,sy,sz) b.Color = Color3.new(0.6, 0.6, 0.6) b.Material = Enum.Material.Slate end local function cover_128_32(x,y,z,n) local s = 128 * 0.5 local f = 32 local f2 = f * 0.5 for ox = -s + f2 + x,s - f2 + x,f do for oy = -s + f2 + y,s - f2 + y,f do for oz = -s + f2 + z,s - f2 + z,f do local v = n(ox,oy,oz) if v > l then local jigsaw = access_6way_heap(heap_6way_32_bank,ox,oy,oz,32,n) if jigsaw then local blk = jigsaw:Clone() blk.Parent = game.Workspace blk:PivotTo(CFrame.new(ox,oy,oz)) end end end end end end local function compose_128_32(x,y,z,n) local rx = x - 64 + 16 local ry = y - 64 + 16 local rz = z - 64 + 16 local i = 128 local px = n(x+i,y,z)>l local py = n(x,y+i,z)>l local pz = n(x,y,z+i)>l local nx = n(x-i,y,z)>l local ny = n(x,y-i,z)>l local nz = n(x,y,z-i)>l local function p(x,y,z,...) -- px,py... local jigsaw = index_6way_heap(heap_6way_32_bank,...) if jigsaw then local blk = jigsaw:Clone() blk.Parent = game.Workspace blk:PivotTo(CFrame.new(x,y,z)) end end local s = 128 * 0.5 local f = 32 local f2 = f * 0.5 for dx = -3,3,2 do for dy = -3,3,2 do for dz = -3,3,2 do local _px = 1 if not px and dx == 1 then _px = 0 end local _py = 1 if not py and dy == 1 then _py = 0 end local _pz = 1 if not pz and dz == 1 then _pz = 0 end local _nx = 1 if not nx and dx == -1 then _nx = 0 end local _ny = 1 if not ny and dy == -1 then _ny = 0 end local _nz = 1 if not nz and dz == -1 then _nz = 0 end if (not px and dx == 3) or (not py and dy == 3) or (not pz and dz == 3) or (not nx and dx == -3) or (not ny and dy == -3) or (not nz and dz == -3) then continue end local jigsaw = index_6way_heap(heap_6way_32_bank,_px,_py,_pz,_nx,_ny,_nz) if jigsaw then local blk = jigsaw:Clone() blk.Parent = game.Workspace blk:PivotTo(CFrame.new(dx * f2 + x,dy * f2 + y,dz * f2 + z)) end end end end end local function cover_1024_128(x,y,z,n) local s = 1024 * 0.5 local f = 64 local f2 = f * 0.5 for ox = -s + f2 + x,s - f2 + x,f do for oy = -s + f2 + y,s - f2 + y,f do for oz = -s + f2 + z,s - f2 + z,f do local v = n(ox,oy,oz) --local blk = block(ox,oy,oz,128,128,128) if v > 0 then --put(store.Support1,ox,oy,oz) elseif v > l then local jigsaw = access_6way_heap(heap_6way_64_slums,ox,oy,oz,64,n) if jigsaw then local blk = jigsaw:Clone() blk.Parent = game.Workspace blk:PivotTo(CFrame.new(ox,oy,oz)) end --compose_128_32(ox,oy,oz,n) end end end end end function module.make_chunk(x,y,z,f,n) cover_1024_128(x,y,z,n) end return module