Last active
June 18, 2023 03:32
-
-
Save ALLAH-2/27b071e7f552c96580a2cd55fa5046e1 to your computer and use it in GitHub Desktop.
This file contains 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
--[[ | |
This mesher only handles 16x16x16 chunks! | |
Uses a more optimal approach towards creating | |
chunks. Checks plane intersections of the chunk | |
for greedy meshing. | |
This type of plane-intersection greedy meshing is | |
useful for fixing certain problems w/ voxel based | |
greedy meshing, where transparent objects may be | |
see through. | |
@author Magical_Noob | |
@submodule Mesh | |
]] | |
local Mesh = {}; | |
Mesh.__index = Mesh; | |
local function pack(vec) | |
-- cast a vector3in16 to an int | |
return vec.X*256 + vec.Y*16 + vec.Z; | |
end | |
function Mesh.plane( | |
chunk, | |
normal, | |
d,u,v | |
) | |
-- this case checks the voxel grid | |
-- with a plane. the plane's normal | |
-- will be used to check if a block | |
-- is obscured. | |
local out = {}; | |
local n = 0; | |
for i = 0, 15 do | |
for j = 0, 15 do | |
-- sweep through the cross section, | |
-- adding chunk indicies to everything | |
n += 1; | |
local position = d + u*i + v*j; | |
local id = chunk[pack(position)]; | |
if(not id)then | |
-- this is an air block | |
-- ie. should not greedy mesh! | |
continue; | |
elseif(chunk[pack(position + normal)])then | |
-- there is a block above | |
-- the given normal | |
continue; | |
end | |
out[n] = id; | |
end | |
end | |
return out; | |
end | |
function Mesh.meshPlane( | |
mesh, | |
d,u,v | |
) | |
-- greedy meshes a subsection | |
-- of the intersection plane | |
local quads = {}; | |
local n = 0; | |
for i = 0, 15 do -- u | |
for j = 0, 15 do -- v | |
-- now check every other index | |
-- memoized time is really slow though! | |
n += 1; | |
local id = mesh[n]; | |
if(not id)then | |
continue; | |
end | |
local sizeX = 1; | |
local sizeY = 1; | |
local done; | |
-- expand on the j or v direction | |
while(mesh[n + sizeX]==id and j+sizeX<16)do | |
sizeX += 1; | |
end | |
-- expand on the i or u direction | |
sizeX -= 1; | |
while(not done and i+sizeY<16)do | |
local offset = sizeY*16; | |
for sx = 0, sizeX do | |
if(mesh[n + sx + offset]~=id)then | |
done = true; | |
break; | |
end | |
end | |
if(not done)then | |
sizeY += 1; | |
end | |
end | |
-- clear out the size X & Y components | |
sizeY -= 1; | |
for sy = 0, sizeY do | |
for sx = 0, sizeX do | |
mesh[n + sx + sy*16] = nil; | |
end | |
end | |
-- append to triangle list | |
local start = d+(u*i)+(v*j); | |
table.insert(quads, { | |
-- a, b | |
start; | |
start | |
+((sizeX+1)*v) | |
+((sizeY+1)*u); | |
}); | |
end | |
end | |
return quads; | |
end | |
function Mesh.draw(chunk) | |
local quads = {}; | |
for _, face in { | |
-- iterate through the mesh's faces | |
{Vector3.new(0,0,1), Vector3.new(1,0,0), Vector3.new(0,1,0)}, | |
{Vector3.new(0,1,0), Vector3.new(0,0,1), Vector3.new(1,0,0)}, | |
{Vector3.new(1,0,0), Vector3.new(0,1,0), Vector3.new(0,0,1)}, | |
-- negative faces | |
{Vector3.new(0,0,-1), Vector3.new(1,0,0), Vector3.new(0,1,0)}, | |
{Vector3.new(0,-1,0), Vector3.new(0,0,1), Vector3.new(1,0,0)}, | |
{Vector3.new(-1,0,0), Vector3.new(0,1,0), Vector3.new(0,0,1)} | |
} do | |
local normal, u, v = unpack(face); | |
local abs = normal:Max(-normal); -- depths within range of chunk boundaries | |
local dataOff = normal:Max(Vector3.zero); -- positive offset from greedy mesh | |
for i = 0, 15 do | |
local d = abs*i; | |
local data = Mesh.meshPlane( | |
Mesh.plane(chunk, normal, d, u, v), -- create mesh information | |
d + dataOff, u, v -- upload depth and uv information | |
); | |
if(#data == 0)then | |
-- well its empty! | |
continue; | |
else | |
-- upload quad data | |
table.move( | |
data, | |
1, | |
#data, | |
#quads+1, | |
quads | |
); | |
end | |
end | |
end | |
-- returns a list of face pairs | |
-- { start, finish } | |
return quads; | |
end | |
Mesh.pack = pack; | |
return Mesh; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
k here nerds