feat: wire vertical exaggeration through the shell #13

Merged
moldybits merged 25 commits from feat/terrain-gen-abstraction into main 2026-05-20 23:00:29 -04:00
2 changed files with 27 additions and 17 deletions
Showing only changes of commit 5dd0a6fb25 - Show all commits
+2 -2
View File
@@ -27,7 +27,7 @@ Notes:
| Rivers and lakes | VistaPro manuals explicitly mention rivers and lakes as adjustable landscape features. | Planned | Not yet represented in `Scene` or renderer code. | Add hydrology controls/data model before claiming this family. | | Rivers and lakes | VistaPro manuals explicitly mention rivers and lakes as adjustable landscape features. | Planned | Not yet represented in `Scene` or renderer code. | Add hydrology controls/data model before claiming this family. |
| Light direction and custom lighting | Manuals discuss sunlight placement and lighting experiments. | Partial | `src/scene.rs` (`Light`), `src/render.rs`, `src/app.rs` (light state exists in the scene model even if UI is minimal). | The current model is much simpler than VistaPros lighting workflow and lacks richer light controls. | | Light direction and custom lighting | Manuals discuss sunlight placement and lighting experiments. | Partial | `src/scene.rs` (`Light`), `src/render.rs`, `src/app.rs` (light state exists in the scene model even if UI is minimal). | The current model is much simpler than VistaPros lighting workflow and lacks richer light controls. |
| Vertical exaggeration | VistaPro manuals describe vertical scaling / scene exaggeration controls. | Implemented | `src/scene.rs` (`Scene.vertical_exaggeration`), `src/app.rs`, `src/app_state.rs`, `src/render.rs`, tests in `src/render.rs`, and scene-file round-trips in `src/scene_file.rs`. | The basic scene-level exaggeration slice is now wired through the shell, renderer, and scene files; future work can explore per-tool or legacy-style exaggeration workflows. | | Vertical exaggeration | VistaPro manuals describe vertical scaling / scene exaggeration controls. | Implemented | `src/scene.rs` (`Scene.vertical_exaggeration`), `src/app.rs`, `src/app_state.rs`, `src/render.rs`, tests in `src/render.rs`, and scene-file round-trips in `src/scene_file.rs`. | The basic scene-level exaggeration slice is now wired through the shell, renderer, and scene files; future work can explore per-tool or legacy-style exaggeration workflows. |
| Color maps / palettes / texture image loading | VistaPro 3 manual includes loading PCX images, adding texture, and saving/loading color maps. | Partial | `src/colormap.rs` fixed bands, `src/render.rs` uses scene thresholds. | No color-map editor, no palette import/export, and no PCX/texture loading yet. | | Color maps / palettes / texture image loading | VistaPro 3 manual includes loading PCX images, adding texture, and saving/loading color maps. | Implemented | `src/scene.rs` (`Palette` thresholds/bands + colors), `src/app.rs` color-map editor, `src/colormap.rs`, `src/render.rs`, `src/script_exec.rs`, `src/scene_file.rs`. | Palette import/export and PCX/texture loading remain future clean-room work. |
| Preview / final render workflow | VistaPro manuals describe rough preview rendering and full render output. | Implemented | `src/render.rs` (`render_top_down`, `render_perspective`), `src/cli.rs` (`render`), tests in `src/render.rs`. | The preview/final split is still simplified, but the core render outputs are working. | | Preview / final render workflow | VistaPro manuals describe rough preview rendering and full render output. | Implemented | `src/render.rs` (`render_top_down`, `render_perspective`), `src/cli.rs` (`render`), tests in `src/render.rs`. | The preview/final split is still simplified, but the core render outputs are working. |
| Render quality presets / smoothing / detail tradeoffs | VistaPro manuals describe quality menus and poly/detail tradeoffs. | Planned | No dedicated quality preset system in current code. | Add explicit quality presets or a render-quality profile object. | | Render quality presets / smoothing / detail tradeoffs | VistaPro manuals describe quality menus and poly/detail tradeoffs. | Planned | No dedicated quality preset system in current code. | Add explicit quality presets or a render-quality profile object. |
| Scene file save/load (`.ovp.toml`) | Not a VistaPro legacy format; this is the clean-room OpenVistaPro scene format. | Implemented | `src/scene_file.rs`, `src/cli.rs` (`scene export`), tests in `src/scene_file.rs`. | No gap for the project-owned scene format slice. | | Scene file save/load (`.ovp.toml`) | Not a VistaPro legacy format; this is the clean-room OpenVistaPro scene format. | Implemented | `src/scene_file.rs`, `src/cli.rs` (`scene export`), tests in `src/scene_file.rs`. | No gap for the project-owned scene format slice. |
@@ -39,4 +39,4 @@ Notes:
## Current reconciliation summary ## Current reconciliation summary
OpenVistaPro already covers the core clean-room pipeline: terrain grids, open importers, scene state, preview/final rendering, project-owned scene files, script execution, MakePath-style path generation, and scene-level vertical exaggeration. The remaining VistaPro-specific gaps cluster around legacy compatibility, richer scene controls, animation-frame export, and the old dense UI/menu workflow. OpenVistaPro already covers the core clean-room pipeline: terrain grids, open importers, scene state, preview/final rendering, project-owned scene files, script execution, MakePath-style path generation, editable color-map thresholds/bands, and scene-level vertical exaggeration. The remaining VistaPro-specific gaps cluster around legacy compatibility, richer scene controls, animation-frame export, and the old dense UI/menu workflow.
+25 -15
View File
@@ -261,6 +261,7 @@ impl AppData {
self.last_script_run = None; self.last_script_run = None;
self.terrain_preset = TerrainPreset::RadialHill; self.terrain_preset = TerrainPreset::RadialHill;
self.renderer_mode = RendererMode::TopDown; self.renderer_mode = RendererMode::TopDown;
self.render_quality = RenderQuality::Preview;
} }
pub fn open_scene(&mut self, path: &Path) -> Result<(), SceneFileError> { pub fn open_scene(&mut self, path: &Path) -> Result<(), SceneFileError> {
@@ -371,6 +372,7 @@ impl AppData {
pub enum AppAction { pub enum AppAction {
SetTerrainPreset(TerrainPreset), SetTerrainPreset(TerrainPreset),
SetRendererMode(RendererMode), SetRendererMode(RendererMode),
SetRenderQuality(RenderQuality),
SetWaterLevel(f32), SetWaterLevel(f32),
SetTreeLine(f32), SetTreeLine(f32),
SetSnowLine(f32), SetSnowLine(f32),
@@ -435,29 +437,37 @@ mod tests {
assert_eq!(app.scene.water_level, 2.5); assert_eq!(app.scene.water_level, 2.5);
assert_eq!(app.scene.tree_line, 5.5); assert_eq!(app.scene.tree_line, 5.5);
assert_eq!(app.scene.snow_line, 8.5); assert_eq!(app.scene.snow_line, 8.5);
assert_eq!(app.scene.palette.water_level, 2.5);
assert_eq!(app.scene.palette.tree_line, 5.5);
assert_eq!(app.scene.palette.snow_line, 8.5);
assert_eq!(app.scene.haze, 0.75); assert_eq!(app.scene.haze, 0.75);
assert_eq!(app.scene.camera, original_camera); assert_eq!(app.scene.camera, original_camera);
} }
#[test] #[test]
fn reducer_syncs_palette_thresholds_back_into_scene_state() { fn reducer_updates_hydrology_shapes_and_reset() {
let mut app = AppData::default(); let mut app = AppData::default();
let mut palette = app.scene.palette; app.apply(AppAction::SetHydrology {
palette.water_level = 0.25; river_level: 0.25,
palette.tree_line = 2.75; lake_level: 0.5,
palette.snow_line = 6.5; drainage: 0.1,
palette.water = [1, 2, 3]; lake_center_x: 1.3,
lake_center_z: -0.2,
lake_radius: 0.3,
river_center_x: -0.4,
river_width: 0.12,
river_bend: 0.9,
});
app.apply(AppAction::SetPalette(palette)); assert_eq!(app.scene.hydrology.river_level, 0.25);
assert_eq!(app.scene.hydrology.lake_level, 0.5);
assert_eq!(app.scene.hydrology.drainage, 0.1);
assert_eq!(app.scene.hydrology.lake_center_x, 1.0);
assert_eq!(app.scene.hydrology.lake_center_z, 0.0);
assert_eq!(app.scene.hydrology.lake_radius, 0.3);
assert_eq!(app.scene.hydrology.river_center_x, 0.0);
assert_eq!(app.scene.hydrology.river_width, 0.12);
assert_eq!(app.scene.hydrology.river_bend, 0.5);
assert_eq!(app.scene.water_level, 0.25); app.apply(AppAction::ResetHydrology);
assert_eq!(app.scene.tree_line, 2.75); assert_eq!(app.scene.hydrology, crate::scene::Hydrology::default());
assert_eq!(app.scene.snow_line, 6.5);
assert_eq!(app.scene.palette, palette);
assert_eq!(app.scene.palette.water, [1, 2, 3]);
} }
#[test] #[test]