Hello! I am currently trying to make a greedy mesher in my block placement game. I am going based off of this tutorial, but it does not explain the placement, so I tried making it so it places on it’s own. The grid size is 3x3x3. When I tried making my version, it does not work and the parts end up like this:
Without greedy meshing
Script:
local blockSize = script.TestBlock.Size
local worldSize = 16
local seed = math.random(-4365072,4365072)
local frequency = 1/16
local amplitude = 8
local baseHeight = 4 + amplitude/2
local cuboids = {}
local isVisited = {}
local map = {}
local maxHeight = 250
function isEmpty(block)
return block == nil
end
function greedyMesh(chunkX,chunkZ)
if not chunkX or not chunkZ then return end
local chunkKey = chunkX..","..chunkZ
for x = 1,worldSize do
for z = 1,worldSize do
for y = 1,maxHeight do
local startX = x
local startZ = z
local startY = y
local endX = x
local endZ = z
local endY = y
local updated = false
isVisited[chunkKey][x][z][y] = true
while endX < worldSize do
local newEndX = endX + 1
if isVisited[chunkKey][newEndX][z][y] == nil then
isVisited[chunkKey][newEndX][z][y] = true
end
local isUseable = not isVisited[chunkKey][newEndX][z][y] and not isEmpty(map[chunkKey][newEndX][z][y])
if not isUseable then
break
end
isVisited[chunkKey][newEndX][z][y] = true
endX = newEndX
updated = true
end
while endZ < worldSize do
local newEndZ = endZ + 1
local isRowUseable = true
for dx = startX,endX do
if isVisited[chunkKey][dx][newEndZ][y] == nil then
isVisited[chunkKey][dx][newEndZ][y] = true
end
local isUseable = not isVisited[chunkKey][dx][newEndZ][y] and not isEmpty(map[chunkKey][dx][newEndZ][y])
if not isUseable then
isRowUseable = false
break
end
end
if not isRowUseable then
break
end
for dx = startX,endX do
isVisited[chunkKey][dx][newEndZ][y] = true
end
endZ = newEndZ
updated = true
end
while endY < maxHeight do
local newEndY = endY + 1
local isRowUseable = true
local isUseable
for dx = startX,endX do
for dz = startZ,endZ do
if isVisited[chunkKey][dx][dz][newEndY] == nil then
isVisited[chunkKey][dx][dz][newEndY] = true
end
isUseable = not isVisited[chunkKey][dx][dz][newEndY] and not isEmpty(map[chunkKey][dx][dz][newEndY])
if not isUseable then
isRowUseable = false
break
end
end
if not isUseable then
isRowUseable = false
break
end
end
if not isRowUseable then
break
end
for dx = startX,endX do
for dz = startZ,endZ do
isVisited[chunkKey][dx][dz][newEndY] = true
end
end
endY = newEndY
updated = true
end
if updated == true then
table.insert(cuboids,{
startX = startX,
startZ = startZ,
startY = startY,
endX = endX,
endZ = endZ,
endY = endY
})
end
end
end
end
for i,v in pairs(cuboids) do
local region = Region3.new(Vector3.new(v.startX*3,v.startY*3,v.startZ*3),Vector3.new(v.endX*3,v.endY*3,v.endZ*3))
print(v.startX,v.startY,v.startZ,v.endX,v.endY,v.endZ)
local pt = script.TestBlock:Clone()
pt.Parent = workspace
pt.Size = region.Size
pt.CFrame = region.CFrame
wait()
end
end
function loadChunk(frequency,amplitude,chunkX,chunkZ)
local chunkKey = chunkX..","..chunkZ
if not map[chunkKey] then map[chunkKey] = {} end
if not isVisited[chunkKey] then isVisited[chunkKey] = {} end
local maxHeight = 0
for x = 1, worldSize do
map[chunkKey][x] = {}
isVisited[chunkKey][x] = {}
for z = 1, worldSize do
local height = baseHeight + math.noise(
((x+seed)+(chunkX*16)) * frequency,
0,
((z+seed)+(chunkZ*16)) * frequency
) * amplitude
map[chunkKey][x][z] = {}
isVisited[chunkKey][x][z] = {}
if maxHeight < math.floor(height) then
maxHeight = math.floor(height)
end
for y = 1, math.floor(height) do
local poscalc = Vector3.new(x, y, z) * blockSize
poscalc = poscalc + Vector3.new((16*3)*chunkX,0,(16*3)*chunkZ) -- Calculates Position
map[chunkKey][x][z][y] = 1
isVisited[chunkKey][x][z][y] = false
end
end
wait()
end
greedyMesh(chunkX,chunkZ)
end
loadChunk(1/16,16,0,0)
Thanks for reading and hope you can help