Greedy Mesher Not Working

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:image

Without greedy meshing
image

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 :slight_smile:

1 Like