use bevy::prelude::*;
use crate::plugin::MapStateResource;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PainterPass {
SkyAtmosphere,
TerrainData,
OpaqueScene,
HillshadeOverlay,
}
#[derive(Resource, Debug, Clone, Default)]
pub struct PainterPlanResource {
passes: Vec<PainterPass>,
}
#[derive(Resource, Debug, Clone, Default)]
pub struct TerrainInteractionBuffersResource {
pub size: (u32, u32),
pub active: bool,
}
impl PainterPlanResource {
pub fn from_state(state: &rustial_engine::MapState) -> Self {
let mut passes = vec![PainterPass::SkyAtmosphere];
if state.terrain().enabled() && !state.terrain_meshes().is_empty() {
passes.push(PainterPass::TerrainData);
}
if state.terrain().enabled()
&& state.hillshade().is_some()
&& !state.hillshade_rasters().is_empty()
{
passes.push(PainterPass::OpaqueScene);
passes.push(PainterPass::HillshadeOverlay);
} else {
passes.push(PainterPass::OpaqueScene);
}
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)
}
}
#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PainterSet {
SkyAtmosphere,
TerrainData,
OpaqueScene,
HillshadeOverlay,
}
pub fn update_painter_plan(
state: Res<MapStateResource>,
mut plan: ResMut<PainterPlanResource>,
) {
*plan = PainterPlanResource::from_state(&state.0);
}
pub fn update_terrain_interaction_buffers(
state: Res<MapStateResource>,
mut buffers: ResMut<TerrainInteractionBuffersResource>,
) {
let camera = state.0.camera();
buffers.size = (camera.viewport_width().max(1), camera.viewport_height().max(1));
buffers.active = state.0.terrain().enabled() && !state.0.terrain_meshes().is_empty();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn opaque_is_always_present() {
let state = rustial_engine::MapState::new();
let plan = PainterPlanResource::from_state(&state);
assert_eq!(plan.iter().collect::<Vec<_>>(), vec![PainterPass::SkyAtmosphere, PainterPass::OpaqueScene]);
}
}