1use std::collections::HashMap;
23
24use bevy_app::prelude::*;
25use bevy_ecs::prelude::*;
26use bevy_solari::prelude::SolariLighting;
27use big_space::prelude::{BigSpace, BigSpaceSystems, CellCoord};
28
29#[cfg(feature = "dlss")]
30use bevy_anti_alias::dlss::{Dlss, DlssRayReconstructionFeature};
31
32#[cfg(feature = "scale-bias")]
33mod ray_bias;
34#[cfg(feature = "scale-bias")]
35pub use ray_bias::{SolariRayBias, SolariRayBiasPlugin};
36
37pub struct BigSpaceSolariPlugin;
39
40impl Plugin for BigSpaceSolariPlugin {
41 fn build(&self, app: &mut App) {
42 app.add_systems(
43 PostUpdate,
44 reset_on_recenter.after(BigSpaceSystems::RecenterLargeTransforms),
45 );
46 }
47}
48
49fn reset_on_recenter(
50 mut last: Local<HashMap<Entity, CellCoord>>,
51 spaces: Query<(Entity, &BigSpace)>,
52 origins: Query<&CellCoord>,
53 mut solari: Query<&mut SolariLighting>,
54 #[cfg(feature = "dlss")] mut dlss: Query<&mut Dlss<DlssRayReconstructionFeature>>,
55) {
56 let mut recentered = false;
57 for (root, space) in &spaces {
58 let Some(origin) = space.floating_origin else {
59 continue;
60 };
61 let Ok(cell) = origins.get(origin) else {
62 continue;
63 };
64 if recentered_since_last(&mut last, root, *cell) {
65 recentered = true;
66 }
67 }
68
69 if !recentered {
70 return;
71 }
72
73 for mut solari in &mut solari {
74 solari.reset = true;
75 }
76 #[cfg(feature = "dlss")]
77 for mut dlss in &mut dlss {
78 dlss.reset = true;
79 }
80}
81
82fn recentered_since_last(
83 last: &mut HashMap<Entity, CellCoord>,
84 root: Entity,
85 cell: CellCoord,
86) -> bool {
87 last.insert(root, cell).is_some_and(|prev| prev != cell)
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn reset_fires_only_on_a_changed_cell() {
96 let mut world = World::new();
97 let a = world.spawn_empty().id();
98 let b = world.spawn_empty().id();
99
100 let mut last = HashMap::new();
101 let origin = CellCoord::new(0, 0, 0);
102 let moved = CellCoord::new(0, 1, 0);
103
104 assert!(!recentered_since_last(&mut last, a, origin));
105 assert!(!recentered_since_last(&mut last, a, origin));
106 assert!(recentered_since_last(&mut last, a, moved));
107 assert!(!recentered_since_last(&mut last, b, origin));
108 }
109}