Rust implementation of terrain processing libraries.
| crates.io name | Library name | Description |
|---|---|---|
martini |
martini |
RTIN mesh generation from heightmaps |
quantized-mesh |
quantized_mesh |
Cesium quantized-mesh-1.0 encoder/decoder |
terrain-codec |
terrain_codec |
Higher-level utilities (seamless halo normals) + re-exports of the two crates above |
Add to your Cargo.toml:
[dependencies]
# Pick what you need:
martini = "0.1" # mesh generation only
quantized-mesh = "0.1" # format only
terrain-codec = "0.1" # both, plus halo normalsuse martini::Martini;
use quantized_mesh::{
QuantizedMeshEncoder, QuantizedMeshHeader, QuantizedVertices,
EdgeIndices, EncodeOptions, TileBounds, QUANTIZED_MAX,
};
// 1. Generate mesh from heightmap
let mut martini = Martini::new(257);
let heightmap: Vec<f64> = load_heightmap(); // Your heightmap data
let tile = martini.create_terrain(|x, y| heightmap[y * 257 + x]);
let (vertices, indices, _uvs) = tile.construct_mesh(
&mut martini,
10.0,
&mut |(u, v)| (u, v, heightmap[(v * 256.0) as usize * 257 + (u * 256.0) as usize]),
);
// 2. Convert to quantized-mesh format
let bounds = TileBounds::new(west, south, east, north);
let header = QuantizedMeshHeader::from_bounds(&bounds, min_height, max_height);
// Quantize vertices to 0-32767 range
let quantized = QuantizedVertices {
u: vertices.iter().step_by(3).map(|&x| (x * QUANTIZED_MAX as f32) as u16).collect(),
v: vertices.iter().skip(1).step_by(3).map(|&y| (y * QUANTIZED_MAX as f32) as u16).collect(),
height: vertices.iter().skip(2).step_by(3).map(|&z| /* quantize height */).collect(),
};
let edge_indices = EdgeIndices::from_vertices(&quantized);
let encoder = QuantizedMeshEncoder::new(header, quantized, indices, edge_indices);
// 3. Write to file
let mut file = File::create("0/0/0.terrain")?;
encoder.encode_to_with_options(&mut file, &EncodeOptions {
compression_level: 6,
..Default::default()
})?;cargo build --releasecargo testMIT OR Apache-2.0