Skip to main content

Color-Block Mesh Geometry

Phase 2A turns the Phase 1 Scene into a deterministic mesh. It uses an original color palette and built-in full-cube geometry. No Minecraft textures, models, or resource packs are required.

Pipeline

Coordinate System

  • Scene world coordinates are signed i64 block coordinates.
  • A mesh page covers a 16x16x16 block region.
  • MeshPage.origin is the page’s world block origin as i32.
  • Vertex positions are local to the page and stay in 0.0..=16.0.
  • This keeps f32 precision stable even when the scene is far from the origin.
  • Page assignment uses div_euclid, so negative coordinates work correctly.

Mesh Contract

Vertices are ordered counter-clockwise when viewed from outside the block. The quad normal must agree with the winding; tests assert this with a cross product.

Face Culling

For a face that lies on the block boundary:
  1. If the neighbor position is outside the scene, keep the face.
  2. If the neighbor is air, keep the face.
  3. If the neighbor model fully occludes (full cube + opaque), cull the face.
  4. If the neighbor is the same canonical block state, including partial shapes, cull the face. This removes internal faces between adjacent glass, water, ice, leaves, and matching partial shapes. The check is state-based, not a per-face coplanarity test.
  5. Otherwise keep the face. Different translucent materials keep their interface faces.
Partial models use per-face cull directions and voxelized model occupancy.

Color Catalog

ColorBlockCatalog resolves a canonical BlockStateKey:
  • exact embedded palette entry;
  • family heuristic (dye colors, wood types, ores, plants, glass, stairs/slab suffixes);
  • magenta fallback with known = false.
The fallback is intentional: unknown blocks stay visible and are counted in mesh statistics. Air resolves to an empty non-occluding model. Default layers:
  • translucent: water, glass, stained glass, ice, slime, honey;
  • cutout: leaves, saplings, flowers, plants, rails, torches, ladders, panes, iron bars, chains, crops;
  • opaque: everything else.
The palette is original approximate data under crates/mesh/data/color-palette.json. It is not copied from Minecraft assets.

Limits

MeshLimits defaults: Exceeding a limit returns MESH_LIMIT_EXCEEDED or PAGE_LIMIT_EXCEEDED and exits with code 2 in the CLI.

Exports

  • OBJ: page-origin-adjusted vertices, normals, and quad faces.
  • PLY: ASCII vertices with RGBA colors and quad faces. Useful for MeshLab, Blender, or other viewers.
Both exporters are deterministic: the same mesh produces identical bytes.

CLI

For CLI invocation and mesh export options (--obj, --ply, --json), see CLI Reference - mesh.

Partial Shapes

Phase 2B adds box-based shapes. Block state properties are read from the canonical key: These are deliberately approximate. They preserve the silhouette and material color; they do not try to reproduce every vanilla micro-detail. Block-entity text, item contents, banner patterns, and skull skins are not rendered yet.

Voxel Mesher

Model boxes are voxelized into a cached 16^3 occupancy grid. For each face plane, exposed 1x1 cells are greedily merged into the largest rectangles. This:
  • removes interior faces between overlapping or touching boxes;
  • merges coplanar faces across box boundaries;
  • emits cullface only for faces on the block boundary;
  • caches the resulting model per canonical block state.
Full cubes bypass the voxel path and reuse the six-quad fast model. A model whose boxes fill the complete 16^3 volume also collapses to the full cube.

Same-State Culling

A boundary face is culled when the neighbor is:
  • a full opaque cube;
  • the same canonical block state, including partial shapes.
The second rule removes shared boundary faces of adjacent slabs, stairs, fences, panes, glass, and water. It is state-based: stacked partial models can lose an exposed face when their geometry does not meet at the same plane. Different partial states keep their interface faces.

Resource Packs

The BlockCatalog trait is implemented by both the original color catalog and the resource-pack catalog (litematic-material). Pack models replace the built-in shape when their blockstate/model resolves to elements; otherwise the Phase 2 shape, the model particle texture, or the color palette is used. Pack quads carry explicit UVs, a texture id, a tint, an optional per-quad layer, and a shade flag. Texture coordinates follow Minecraft’s face convention; chest entity textures use the standard box unwrap. See docs/textures.md for the full asset and fallback contract. Block-entity text/icons, entity models beyond the built-in chest, and dynamic item contents remain future work.