Skip to main content

Crate block_mesh_bgm

Crate block_mesh_bgm 

Source
Expand description

block-mesh-compatible binary greedy meshing.

binary_greedy_quads mirrors the call shape of block_mesh::greedy_quads, but it reaches the same kind of QuadBuffer through a different internal pipeline:

  1. Validate the padded query extent and precompute a few indexing facts.
  2. Build packed occupancy columns, one u64 per orthogonal column.
  3. Turn those columns into visible-face rows with cheap bitwise tests.
  4. Merge each face slice into quads, either as unit quads or with a carry-based greedy row merger.

The implementation is split into the same stages in source:

  • context: query validation and precomputed layout facts
  • prep: occupancy columns and visible-face rows
  • merge: unit emission and carry-based greedy merging
  • ao: AO-safe alternate merge policy built on binary occupancy masks
  • face: face-orientation helpers shared by the other stages

The crate exposes two public entry points:

§AO-safe mode

AO-safe mode keeps the same prep pipeline as vanilla meshing. The difference is only in how face rows are merged:

  • vanilla merging only checks MergeVoxel::merge_value()
  • AO-safe merging also looks at opaque occupancy in the plane just outside the visible face
  • from that exterior plane it derives whole-row binary masks that prove which cells must stay unit, which may only merge in one direction, and which are still free to use the normal carry merge

That keeps the AO rule in terms of the same binary data the mesher already uses elsewhere, instead of carrying per-cell lighting data through the hot merge loop.

§Terminology

The source uses three axis names repeatedly:

  • n_axis: the face normal axis
  • outer_axis: the axis that advances from one row to the next within a face slice
  • bit_axis: the axis packed into the row’s u64 bitset

Every meshed query is also split into two nested boxes:

  • the query extent [min, max], which includes one voxel of padding on every side
  • the interior extent [min + 1, max - 1], whose faces may actually produce quads

The padding is never emitted. It only exists so the mesher can decide whether an interior face is visible.

§Why the 62-voxel limit exists

Each axis of the padded query is packed into one u64. That leaves room for at most 62 interior voxels plus the two required padding voxels.

§Example

use block_mesh::ndshape::{ConstShape, ConstShape3u32};
use block_mesh::{
    MergeVoxel, Voxel, VoxelVisibility, RIGHT_HANDED_Y_UP_CONFIG,
};
use block_mesh_bgm::{binary_greedy_quads, BinaryGreedyQuadsBuffer};

#[derive(Clone, Copy, Debug, 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;

    fn merge_value(&self) -> Self::MergeValue {
        *self
    }
}

type ChunkShape = ConstShape3u32<18, 18, 18>;

let mut voxels = [EMPTY; ChunkShape::SIZE as usize];
for i in 0..ChunkShape::SIZE {
    let [x, y, z] = ChunkShape::delinearize(i);
    voxels[i as usize] = if ((x * x + y * y + z * z) as f32).sqrt() < 15.0 {
        FULL
    } else {
        EMPTY
    };
}

let mut buffer = BinaryGreedyQuadsBuffer::new();
binary_greedy_quads(
    &voxels,
    &ChunkShape {},
    [0; 3],
    [17; 3],
    &RIGHT_HANDED_Y_UP_CONFIG.faces,
    &mut buffer,
);

assert!(buffer.quads.num_quads() > 0);

The AO-safe entry point uses the same buffer type:

let mut buffer = BinaryGreedyQuadsBuffer::new();
binary_greedy_quads_ao_safe(
    &voxels,
    &ChunkShape {},
    [0; 3],
    [3; 3],
    &RIGHT_HANDED_Y_UP_CONFIG.faces,
    &mut buffer,
);

Structs§

BinaryGreedyQuadsBuffer
Reusable output and scratch storage for binary_greedy_quads and binary_greedy_quads_ao_safe.

Functions§

binary_greedy_quads
Generates greedy quads using a binary-mask-backed implementation.
binary_greedy_quads_ao_safe
Generates greedy quads with AO-safe merge restrictions for opaque faces.