use std::collections::HashMap;
use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use bevy_solari::prelude::SolariLighting;
use big_space::prelude::{BigSpace, BigSpaceSystems, CellCoord};
#[cfg(feature = "dlss")]
use bevy_anti_alias::dlss::{Dlss, DlssRayReconstructionFeature};
#[cfg(feature = "scale-bias")]
mod ray_bias;
#[cfg(feature = "scale-bias")]
pub use ray_bias::{SolariRayBias, SolariRayBiasPlugin};
pub struct BigSpaceSolariPlugin;
impl Plugin for BigSpaceSolariPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PostUpdate,
reset_on_recenter.after(BigSpaceSystems::RecenterLargeTransforms),
);
}
}
fn reset_on_recenter(
mut last: Local<HashMap<Entity, CellCoord>>,
spaces: Query<(Entity, &BigSpace)>,
origins: Query<&CellCoord>,
mut solari: Query<&mut SolariLighting>,
#[cfg(feature = "dlss")] mut dlss: Query<&mut Dlss<DlssRayReconstructionFeature>>,
) {
let mut recentered = false;
for (root, space) in &spaces {
let Some(origin) = space.floating_origin else {
continue;
};
let Ok(cell) = origins.get(origin) else {
continue;
};
if recentered_since_last(&mut last, root, *cell) {
recentered = true;
}
}
if !recentered {
return;
}
for mut solari in &mut solari {
solari.reset = true;
}
#[cfg(feature = "dlss")]
for mut dlss in &mut dlss {
dlss.reset = true;
}
}
fn recentered_since_last(
last: &mut HashMap<Entity, CellCoord>,
root: Entity,
cell: CellCoord,
) -> bool {
last.insert(root, cell).is_some_and(|prev| prev != cell)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reset_fires_only_on_a_changed_cell() {
let mut world = World::new();
let a = world.spawn_empty().id();
let b = world.spawn_empty().id();
let mut last = HashMap::new();
let origin = CellCoord::new(0, 0, 0);
let moved = CellCoord::new(0, 1, 0);
assert!(!recentered_since_last(&mut last, a, origin));
assert!(!recentered_since_last(&mut last, a, origin));
assert!(recentered_since_last(&mut last, a, moved));
assert!(!recentered_since_last(&mut last, b, origin));
}
}