236 lines
6.9 KiB
Plaintext
236 lines
6.9 KiB
Plaintext
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
|