feat: wire shell placeholders to backend actions #12
@@ -13,6 +13,7 @@ This repository currently contains:
|
||||
- An implementation roadmap under `docs/plans/`.
|
||||
- Legal and reference-material hygiene notes under `docs/legal/` and `docs/research/`.
|
||||
- A clean-room terrain import boundary with project-owned `ovp-text` fixtures and an SRTM/HGT byte importer behind the `hgt` Cargo feature.
|
||||
- A clean-room procedural terrain generator module (`src/terrain_gen.rs`) that produces deterministic, seeded synthetic landscapes.
|
||||
|
||||
## Development
|
||||
|
||||
@@ -50,6 +51,27 @@ cargo run --features import-geotiff --bin openvistapro -- info
|
||||
cargo test --all-features
|
||||
```
|
||||
|
||||
## Terrain generation
|
||||
|
||||
OpenVistaPro includes a clean-room procedural terrain generator in
|
||||
`src/terrain_gen.rs`. Its public surface is intentionally small:
|
||||
`TerrainGenerationSpec` captures the seed and dimensions of a generation
|
||||
request, the `TerrainGenerator` trait defines the `generate` boundary, and
|
||||
`DeterministicTerrainGenerator` implements it with a seeded value-noise fBm
|
||||
stack that returns a plain `HeightGrid` — generator state never leaks into the
|
||||
grid or renderer.
|
||||
|
||||
Generation is seeded and deterministic: an identical spec always yields an
|
||||
identical grid, and different seeds diverge. As with the importers, the
|
||||
generator tests use only tiny synthetic, project-owned fixtures — no committed
|
||||
binaries and no real geodata.
|
||||
|
||||
To verify the terrain-generation surface:
|
||||
|
||||
```bash
|
||||
cargo test terrain_gen -- --nocapture
|
||||
```
|
||||
|
||||
The default `render` mode writes a deterministic top-down elevation preview.
|
||||
Passing `--camera-demo` switches to the current CPU perspective renderer spike:
|
||||
a simple pinhole-camera raymarcher with bilinear height sampling, fixed step
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
Start simple, then split into crates when module boundaries stabilize.
|
||||
|
||||
- `src/terrain.rs`: height grid, bounds, sampling, normals, terrain transforms.
|
||||
- `src/terrain_gen.rs`: procedural terrain generator boundary. `TerrainGenerationSpec`
|
||||
captures a request's seed and dimensions, and `DeterministicTerrainGenerator`
|
||||
(a seeded value-noise fBm generator behind the `TerrainGenerator` trait)
|
||||
consumes that spec and returns a plain `HeightGrid` — generator state never
|
||||
leaks into the grid or renderer. Generation is seeded and deterministic: an
|
||||
identical spec always yields an identical grid. Its tests use only tiny
|
||||
synthetic, project-owned fixtures, never committed binaries or real geodata,
|
||||
and run via `cargo test terrain_gen -- --nocapture`.
|
||||
- `src/import/`: importers for open/safe formats; historical compatibility later. Implemented so far: the project-owned `ovp-text` heightfield, an SRTM/HGT byte parser behind the `hgt` feature, and an optional single-band GeoTIFF importer (`src/import/geotiff.rs`) behind the `import-geotiff` feature. Each importer yields the same internal `HeightGrid` plus `TerrainSourceMetadata`, keeping source formats out of renderer code.
|
||||
- `src/scene.rs`: camera, target, light, atmosphere, water, vegetation parameters.
|
||||
- `src/render/`: CPU reference renderer first, then WGPU renderer.
|
||||
|
||||
@@ -9,18 +9,19 @@ Define the next terrain-generation workstream so future slices stay small, deter
|
||||
OpenVistaPro already has:
|
||||
|
||||
- `src/terrain.rs` with immutable `HeightGrid` storage, safe indexing, min/max, and deterministic `plane` / `radial_hill` fixtures.
|
||||
- `src/terrain_gen.rs` with the procedural terrain generator slice: `TerrainGenerationSpec` (seed plus dimensions), the `TerrainGenerator` trait, and `DeterministicTerrainGenerator`, a deterministic seeded value-noise fBm generator that returns a plain `HeightGrid`.
|
||||
- `src/render.rs` with a deterministic top-down preview and a CPU perspective spike that only depends on `HeightGrid` + `Scene`.
|
||||
- `src/scene.rs` and `src/app_state.rs` for scene controls and preview wiring.
|
||||
- `src/import.rs` for the open-format import boundary.
|
||||
- `docs/plans/initial-roadmap.md` and `docs/plans/phase-4-formats-scripts-ui.md` for the broader project sequence.
|
||||
|
||||
The missing piece is a dedicated procedural terrain generator pipeline that can produce richer synthetic landscapes without mixing algorithm state into `HeightGrid`.
|
||||
The first procedural slice has now landed in `src/terrain_gen.rs`: it produces richer synthetic landscapes without mixing algorithm state into `HeightGrid`. The remaining work is preset profiles and the later enhancements tracked in the roadmap slices below.
|
||||
|
||||
## Decision summary
|
||||
|
||||
### First generator family: seeded 2D value-noise fBm
|
||||
### First generator family: seeded 2D value-noise fBm (landed)
|
||||
|
||||
Implement a deterministic, seedable fractal terrain family first, built from 2D value noise with fBm-style octaves.
|
||||
This family has landed as `DeterministicTerrainGenerator` in `src/terrain_gen.rs`: a deterministic, seedable fractal terrain generator built from 2D value noise with fBm-style octaves.
|
||||
|
||||
Why this first:
|
||||
|
||||
@@ -38,7 +39,7 @@ Keep `HeightGrid` as pure data plus basic helpers.
|
||||
Recommended split:
|
||||
|
||||
- `src/terrain.rs`: immutable grid storage, validation, indexing, min/max, and tiny deterministic fixtures like `plane` and `radial_hill`.
|
||||
- New generator module, e.g. `src/terrain/generation.rs` or `src/generation.rs`: procedural generation logic, seed handling, interpolation/noise helpers, and generator presets.
|
||||
- Generator module (landed as `src/terrain_gen.rs`): procedural generation logic, seed handling, interpolation/noise helpers, and generator presets.
|
||||
- Public API should return `HeightGrid` and nothing renderer-specific.
|
||||
- Any generator metadata should live in a separate spec/config type, not in the grid itself.
|
||||
|
||||
@@ -53,6 +54,8 @@ If the implementation later needs richer provenance, add a lightweight wrapper b
|
||||
|
||||
### Slice 1: generator module skeleton
|
||||
|
||||
Status: landed in `src/terrain_gen.rs`.
|
||||
|
||||
Goal: introduce the procedural terrain namespace without changing renderer behavior.
|
||||
|
||||
Deliverables:
|
||||
@@ -68,6 +71,8 @@ Acceptance:
|
||||
|
||||
### Slice 2: deterministic value-noise core
|
||||
|
||||
Status: landed in `src/terrain_gen.rs`.
|
||||
|
||||
Goal: implement the smallest reusable noise primitive.
|
||||
|
||||
Deliverables:
|
||||
@@ -84,6 +89,8 @@ Acceptance:
|
||||
|
||||
### Slice 3: fBm terrain composition
|
||||
|
||||
Status: landed in `src/terrain_gen.rs`.
|
||||
|
||||
Goal: layer octaves into usable synthetic landscapes.
|
||||
|
||||
Deliverables:
|
||||
@@ -99,6 +106,8 @@ Acceptance:
|
||||
|
||||
### Slice 4: preset profiles
|
||||
|
||||
Status: not started — the next slice.
|
||||
|
||||
Goal: provide a few named generator presets for common shapes.
|
||||
|
||||
Suggested first presets:
|
||||
@@ -149,12 +158,16 @@ Run these for each generator slice:
|
||||
|
||||
```bash
|
||||
cargo fmt --check
|
||||
cargo test terrain
|
||||
cargo test terrain_gen -- --nocapture
|
||||
cargo test
|
||||
cargo clippy --all-targets -- -D warnings
|
||||
```
|
||||
|
||||
Add one feature-specific smoke command for the slice once the generator has a public entry point, for example a tiny render or sample-generation command that writes to `/tmp` and proves the generated grid is usable end-to-end.
|
||||
`cargo test terrain_gen -- --nocapture` is the feature-specific smoke command for
|
||||
the landed generator slice: it exercises `DeterministicTerrainGenerator` against
|
||||
the `TerrainGenerationSpec` surface in `src/terrain_gen.rs` and proves a seeded
|
||||
grid is reproducible. Future slices should add their own targeted smoke command
|
||||
once they expose a new public entry point.
|
||||
|
||||
## Definition of done for the workstream
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
//! Docs-sync guard for the terrain-generation surface.
|
||||
//!
|
||||
//! The terrain generator has landed in `src/terrain_gen.rs` (see
|
||||
//! `tests/terrain_gen.rs`), but the docs have not been updated to describe it.
|
||||
//! This test fails by design until README, the terrain-generation plan, and
|
||||
//! the architecture notes mention the new surface.
|
||||
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
/// Substrings every terrain-aware doc should mention now that the
|
||||
/// terrain-generation module has landed.
|
||||
const REQUIRED_TERMS: &[&str] = &[
|
||||
"src/terrain_gen.rs",
|
||||
"TerrainGenerationSpec",
|
||||
"DeterministicTerrainGenerator",
|
||||
"cargo test terrain_gen",
|
||||
];
|
||||
|
||||
fn read_doc(relative: &str) -> String {
|
||||
let path = Path::new(env!("CARGO_MANIFEST_DIR")).join(relative);
|
||||
fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read {}: {e}", path.display()))
|
||||
}
|
||||
|
||||
/// Returns the required terrain-generation terms that `doc` fails to mention.
|
||||
fn missing_terms(doc: &str) -> Vec<&'static str> {
|
||||
let mut missing: Vec<&'static str> = REQUIRED_TERMS
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|term| !doc.contains(term))
|
||||
.collect();
|
||||
|
||||
// A determinism/seed note: the docs should say generation is seeded and
|
||||
// reproducible, not just reuse the word "deterministic" elsewhere.
|
||||
let lower = doc.to_lowercase();
|
||||
if !(lower.contains("seed") && lower.contains("determin")) {
|
||||
missing.push("a determinism/seed note");
|
||||
}
|
||||
|
||||
missing
|
||||
}
|
||||
|
||||
fn assert_doc_mentions_terrain_gen(relative: &str) {
|
||||
let doc = read_doc(relative);
|
||||
let missing = missing_terms(&doc);
|
||||
assert!(
|
||||
missing.is_empty(),
|
||||
"{relative} does not mention the landed terrain-generation surface: {missing:?}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn readme_mentions_terrain_generation_surface() {
|
||||
assert_doc_mentions_terrain_gen("README.md");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn terrain_generation_plan_mentions_terrain_generation_surface() {
|
||||
assert_doc_mentions_terrain_gen("docs/plans/terrain-generation.md");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn architecture_notes_mention_terrain_generation_surface() {
|
||||
assert_doc_mentions_terrain_gen("docs/knowledgebase/architecture-notes.md");
|
||||
}
|
||||
Reference in New Issue
Block a user