The block-mesh library provides two primary algorithms for generating meshes from voxel data:
visible_block_faces: A very fast algorithm that produces suboptimal meshes (more triangles).greedy_quads: A slightly slower algorithm that produces more optimal meshes by merging adjacent faces into larger quads, resulting in significantly fewer triangles.
To use these, you must implement the Voxel and MergeVoxel traits on your data type and provide a shape (using the ndshape crate) and a configuration (like RIGHT_HANDED_Y_UP_CONFIG).
use block_mesh::ndshape::{ConstShape, ConstShape3u32};
use block_mesh::{greedy_quads, GreedyQuadsBuffer, MergeVoxel, Voxel, VoxelVisibility, RIGHT_HANDED_Y_UP_CONFIG};
#[derive(Clone, Copy, Eq, PartialEq)]
struct BoolVoxel(bool);
const EMPTY: BoolVoxel = BoolVoxel(false);
const FULL: BoolVoxel = BoolVoxel(true);
impl Voxel for BoolVoxel {
fn get_visibility(&self) -> VoxelVisibility {
if *self == EMPTY {
VoxelVisibility::Empty
} else {
VoxelVisibility::Opaque
}
}
}
impl MergeVoxel for BoolVoxel {
type MergeValue = Self;
type MergeValueFacingNeighbour = Self;
fn merge_value(&self) -> Self::MergeValue {
*self
}
fn merge_value_facing_neighbour(&self) -> Self::MergeValueFacingNeighbour {
*self
}
}
// A 16^3 chunk with 1-voxel boundary padding.
type ChunkShape = ConstShape3u32<18, 18, 18>;
let mut voxels = [EMPTY; ChunkShape::SIZE as usize];
// ... populate voxels ...
let mut buffer = GreedyQuadsBuffer::new(voxels.len());
greedy_quads(
&voxels,
&ChunkShape {},
[0; 3], // min bounds
[17; 3], // max bounds
&RIGHT_HANDED_Y_UP_CONFIG.faces,
&mut buffer
);