Created
April 26, 2021 06:37
-
-
Save Aloroid/0703bc9e232c197fb5cc5ba642caf1cf to your computer and use it in GitHub Desktop.
Greedy mesher
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Performs greedy meshing on custom Voxel blocks | |
made by Megustral | |
]] | |
local RunService = game:GetService("RunService") | |
local Settings = require(script.Parent.Settings) | |
local Size = Vector3.new(1, 1, 1) | |
return function (Chunk) | |
local PartInstructions = {} | |
local IsMeshed = {} | |
for y = 1, Settings.ChunkSize.Y do | |
for z = 1, Settings.ChunkSize.Z do | |
for x = 1, Settings.ChunkSize.X do | |
-- Perform GreedyMeshing | |
local PositionStartingPart = Vector3.new(x, y, z) | |
-- Check if the part is already meshed | |
if IsMeshed[PositionStartingPart] then continue end | |
local Voxel = Chunk[PositionStartingPart] | |
-- If there is no voxel why bother | |
if not Voxel then continue end | |
-- A instruction that will be used for the renderer | |
local Part = { | |
Position = PositionStartingPart, | |
Size = Size, | |
Voxel = Voxel | |
} | |
-- Performs the greedy meshing | |
do | |
-- basically how it works: | |
-- we check the part next to it, if its valid, we increase the size and tell the system that that part is meshed | |
-- we do this on the x axis, but when we do it on the z axis its kinda different | |
-- we first go through every block on the x axis one stud farther from the z | |
-- if one of them is not the same and is air, cancel the operation | |
-- and break the loop. if it doesnt fail, we increase the size of the part | |
-- then we do that also for the y axis but check both z and x | |
for greedX = x+1, Settings.ChunkSize.X do | |
-- Check if the voxels are the same | |
local PositionMeshedPart = Vector3.new(greedX, y, z) | |
local VoxelMeshed = Chunk[PositionMeshedPart] | |
if Voxel == VoxelMeshed then | |
Part.Size += Vector3.new(1, 0, 0) | |
Part.Position += Vector3.new(0.5, 0, 0) | |
IsMeshed[PositionMeshedPart] = true | |
else | |
break | |
end | |
end | |
for greedZ = z+1, Settings.ChunkSize.Z do | |
local IsSame = true | |
for greedX = x, Part.Size.X do | |
local PositionMeshedPart = Vector3.new(greedX, y, greedZ) | |
local VoxelMeshed = Chunk[PositionMeshedPart] | |
if Voxel ~= VoxelMeshed then | |
IsSame = false | |
break | |
end | |
end | |
if not IsSame then break end | |
Part.Size += Vector3.new(0, 0, 1) | |
Part.Position += Vector3.new(0, 0, 0.5) | |
for greedX = x, Part.Size.X do | |
local PositionMeshedPart = Vector3.new(greedX, y, greedZ) | |
IsMeshed[PositionMeshedPart] = true | |
end | |
end | |
for greedY = y+1, Settings.ChunkSize.Y do | |
local IsSame = true | |
for greedZ = z, Part.Size.Z do | |
local IsSameZ = true | |
for greedX = x, Part.Size.X do | |
local PositionMeshedPart = Vector3.new(greedX, greedY, greedZ) | |
local VoxelMeshed = Chunk[PositionMeshedPart] | |
if Voxel ~= VoxelMeshed then | |
IsSameZ = false | |
break | |
end | |
end | |
-- Breaks the greedy meshing operation | |
if not IsSameZ then | |
IsSame = false | |
break | |
end | |
end | |
if IsSame then | |
Part.Size += Vector3.new(0, 1, 0) | |
Part.Position += Vector3.new(0, 0.5, 0) | |
-- Mark all these parts as greedy meshed | |
for greedZ = z, Part.Size.Z do | |
for greedX = x, Part.Size.X do | |
local PositionMeshedPart = Vector3.new(greedX, greedY, greedZ) | |
IsMeshed[PositionMeshedPart] = true | |
end | |
end | |
end | |
end | |
end | |
--Part.Position += Chunk.Position * Settings.ChunkSize | |
table.insert(PartInstructions, Part) | |
end | |
end | |
end | |
return PartInstructions | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment