I have been trying to do this for a few solid months now and I still can’t get my head around expanding my 1D greedy mesher into a 2D or 3D one.
I have read several posts on greedy meshing and yet I can’t seem to get my head around it as I cannot find any good code samples or tutorials for lua or roblox greedy meshers. I fully understand the concept and how it works, I have even read a simple tutorial from @Elttob but I just simply have no idea how to do it in code.
Here’s my current poor 1D implementation:
local Module = {}
-- 'Voxels' are an array of voxel data which is structed like this:
-- Voxel = {Position = Vector3, Visited = boolean}
function Module.GreedyMeshVoxels(Voxels, VoxelGroupSize, VoxelSize)
local MeshedVoxels = {}
local function CreateMeshedVoxelData(StartPos, EndPos)
local NewPos = (StartPos + EndPos)/2
local NewSize = (EndPos - StartPos) + (Vector3.new(1, 1, 1) * VoxelSize)
local Voxel = {Position = NewPos, Size = NewSize} -- CFrame, Size
table.insert(MeshedVoxels, Voxel)
end
local function FindVoxel(X, Y, Z) -- Get voxel based on position
for i, Voxel in pairs(Voxels) do
-- Im using Voxel.Position to identify if the voxel is empty or not (nil or Vector3)
if Voxel.Position and Voxel.Position.X == X and Voxel.Position.Y == Y and Voxel.Position.Z == Z then
return Voxel
end
end
end
local IsInEmptyRegion = false -- Make sure we aren't creating voxels in empty regions
for Z = VoxelSize, VoxelGroupSize.Z, VoxelSize do
local PosZ = Z - (VoxelGroupSize.Z / 2) - (VoxelSize/2) -- Origin
for Y = VoxelSize, VoxelGroupSize.Y, VoxelSize do
local PosY = Y - (VoxelGroupSize.Y / 2) - (VoxelSize/2) -- Origin
local StartPos = nil
local EndPos = nil
for X = VoxelSize, VoxelGroupSize.X, VoxelSize do
local PosX = X - (VoxelGroupSize.X / 2) - (VoxelSize/2) -- Origin
local Voxel = FindVoxel(PosX, PosY, PosZ)
if Voxel then
if not StartPos then
StartPos = Vector3.new(PosX, PosY, PosZ)
end
EndPos = Vector3.new(PosX, PosY, PosZ)
end
if (not Voxel or Voxel.Visited) and not IsInEmptyRegion and StartPos and EndPos then
IsInEmptyRegion = true
CreateMeshedVoxelData(StartPos, EndPos) -- Create the new voxel according to the starting and ending positions
end
if Voxel and not Voxel.Visited then -- Check if the voxel is not empty and it hasn't been visited before
if IsInEmptyRegion then -- We are no longer in an empty region. Reset the starting position to the current position
IsInEmptyRegion = false
StartPos = Vector3.new(PosX, PosY, PosZ)
end
Voxel.Visited = true
end
end
if StartPos and EndPos and not IsInEmptyRegion then
CreateMeshedVoxelData(StartPos, EndPos) -- Create the new voxel according to the starting and ending positions
end
end
end
return MeshedVoxels
end
return Module