#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PainterPass {
SkyAtmosphere,
TerrainData,
ShadowDepth,
OpaqueScene,
HeatmapAccumulation,
HeatmapColormap,
HillshadeOverlay,
}
#[derive(Debug, Clone, Default)]
pub struct PainterPlan {
passes: Vec<PainterPass>,
}
impl PainterPlan {
pub fn new(has_terrain_data: bool, has_hillshade_overlay: bool, has_heatmap: bool) -> Self {
Self::with_shadows(has_terrain_data, has_hillshade_overlay, has_heatmap, false)
}
pub fn with_shadows(
has_terrain_data: bool,
has_hillshade_overlay: bool,
has_heatmap: bool,
has_shadows: bool,
) -> Self {
let mut passes = vec![PainterPass::SkyAtmosphere];
if has_terrain_data {
passes.push(PainterPass::TerrainData);
}
if has_shadows {
passes.push(PainterPass::ShadowDepth);
}
passes.push(PainterPass::OpaqueScene);
if has_heatmap {
passes.push(PainterPass::HeatmapAccumulation);
passes.push(PainterPass::HeatmapColormap);
}
if has_hillshade_overlay {
passes.push(PainterPass::HillshadeOverlay);
}
Self { passes }
}
pub fn iter(&self) -> impl Iterator<Item = PainterPass> + '_ {
self.passes.iter().copied()
}
pub fn contains(&self, pass: PainterPass) -> bool {
self.passes.contains(&pass)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn opaque_is_always_present() {
let plan = PainterPlan::new(false, false, false);
assert_eq!(
plan.iter().collect::<Vec<_>>(),
vec![PainterPass::SkyAtmosphere, PainterPass::OpaqueScene]
);
}
#[test]
fn terrain_data_and_hillshade_are_appended_when_enabled() {
let plan = PainterPlan::new(true, true, false);
assert_eq!(
plan.iter().collect::<Vec<_>>(),
vec![
PainterPass::SkyAtmosphere,
PainterPass::TerrainData,
PainterPass::OpaqueScene,
PainterPass::HillshadeOverlay,
]
);
}
#[test]
fn heatmap_passes_inserted_after_opaque() {
let plan = PainterPlan::new(false, true, true);
assert_eq!(
plan.iter().collect::<Vec<_>>(),
vec![
PainterPass::SkyAtmosphere,
PainterPass::OpaqueScene,
PainterPass::HeatmapAccumulation,
PainterPass::HeatmapColormap,
PainterPass::HillshadeOverlay,
]
);
}
}