Skip to content

Instantly share code, notes, and snippets.

@IcyTv
Created July 17, 2021 11:50
Show Gist options
  • Save IcyTv/7408523d21b8cccbfb29f927d4e098b2 to your computer and use it in GitHub Desktop.
Save IcyTv/7408523d21b8cccbfb29f927d4e098b2 to your computer and use it in GitHub Desktop.
Greedy meshing algorithm for rust
/*
The original algorithm comes from https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/
and the code is almost a straight adaptation of that code (https://github.com/mikolalysenko/mikolalysenko.github.com/blob/gh-pages/MinecraftMeshes/js/greedy.js)
*/
fn greedy_meshing(
is_voxel_present: &dyn Fn(i32, i32, i32) -> bool,
dims: &[i32; 3],
) -> Vec<[[i32; 3]; 4]> {
let mut quads = Vec::new();
for d in 0..3 {
let u = (d + 1) % 3;
let v = (d + 2) % 3;
println!("Walking {} {} {}", d, u, v);
let mut x = [0i32, 0i32, 0i32];
let mut q = [0i32, 0i32, 0i32];
let mask_size = dims[u] * dims[v];
let mut mask = vec![false; mask_size as usize];
mask.fill(false);
q[d] = 1;
x[d] = -1;
//YEs, this is a bit of a hack, but it works.
while x[d] < dims[d] {
let mut n = 0i32;
//Compute mask
x[v] = 0;
while x[v] < dims[v] {
x[u] = 0;
while x[u] < dims[u] {
let mut mask1 = false;
if 0 <= x[d] {
mask1 = is_voxel_present(x[0], x[1], x[2]);
}
let mut mask2 = false;
if x[d] < dims[d] - 1 {
mask2 = is_voxel_present(x[0] + q[0], x[1] + q[1], x[2] + q[2]);
}
if n < 0 {
panic!("Negative array access")
}
mask[n as usize] = mask1 != mask2;
n += 1;
x[u] += 1;
}
x[v] += 1;
}
//Increment x[d]
x[d] += 1;
//Generate mesh for mask using lexicographic ordering
n = 0;
for j in 0..dims[v] {
let mut i = 0;
while i < dims[u] {
if n < 0 {
panic!("Negative array access")
}
if mask[n as usize] {
//Compute width
let mut w = 1i32;
if ((n + w) as usize) as i32 != n + w {
panic!("Lost data in transformation!")
}
//Compute width
while i + w < dims[u] && mask[(n + w) as usize] {
w += 1;
}
//Compute height
let mut h = 1;
'outer: while j + h < dims[v] {
for k in 0..w {
if ((n + k + h * dims[u]) as usize) as i32 != n + k + h * dims[u] {
panic!("Lost data in transformation!")
}
if !mask[(n + k + h * dims[u]) as usize] {
break 'outer;
}
}
h += 1;
}
//Add quad
x[u] = i;
x[v] = j;
let mut du = [0, 0, 0];
let mut dv = [0, 0, 0];
du[u] = w;
dv[v] = h;
quads.push([
[x[0], x[1], x[2]],
[x[0] + du[0], x[1] + du[1], x[2] + du[2]],
[
x[0] + du[0] + dv[0],
x[1] + du[1] + dv[1],
x[2] + du[2] + dv[2],
],
[x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]],
]);
//Zero out mask
for l in 0..h {
for k in 0..w {
mask[(n + k + l * dims[u]) as usize] = false;
}
}
//Increment counters and continue
i += w;
n += w;
} else {
n += 1;
i += 1;
}
}
}
}
}
quads
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment