use super::camera::CameraPlugin;
use super::controls::{
calculate_all_luminaire_transforms, sync_viewer_to_lights, viewer_controls_system,
};
use super::scenes::ScenePlugin;
use super::wasm_sync::{load_default_ldt, LdtTimestamp, ViewerSettingsTimestamp};
use super::ViewerSettings;
use crate::eulumdat_impl::EulumdatLightBundle;
use crate::photometric::PhotometricPlugin;
use bevy::prelude::*;
use eulumdat::Eulumdat;
pub struct EulumdatViewerPlugin {
pub initial_ldt: Option<Eulumdat>,
pub enable_keyboard_controls: bool,
pub enable_local_storage_sync: bool,
}
impl Default for EulumdatViewerPlugin {
fn default() -> Self {
Self {
initial_ldt: None,
enable_keyboard_controls: true,
enable_local_storage_sync: cfg!(feature = "wasm-sync"),
}
}
}
impl EulumdatViewerPlugin {
pub fn new() -> Self {
Self::default()
}
pub fn with_ldt(ldt: Eulumdat) -> Self {
Self {
initial_ldt: Some(ldt),
enable_keyboard_controls: true,
enable_local_storage_sync: cfg!(feature = "wasm-sync"),
}
}
}
impl Plugin for EulumdatViewerPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(PhotometricPlugin::<Eulumdat>::new());
app.add_plugins((CameraPlugin, ScenePlugin));
let settings = ViewerSettings {
ldt_data: self.initial_ldt.clone(),
..default()
};
app.insert_resource(settings);
app.insert_resource(LdtTimestamp::default());
app.insert_resource(ViewerSettingsTimestamp::default());
app.add_systems(Startup, setup_viewer_light);
if self.enable_keyboard_controls {
app.add_systems(Update, viewer_controls_system);
}
#[cfg(feature = "wasm-sync")]
if self.enable_local_storage_sync {
app.add_systems(
Update,
(
super::wasm_sync::poll_ldt_changes,
super::wasm_sync::poll_viewer_settings_changes,
sync_ldt_to_light,
ApplyDeferred,
sync_viewer_to_lights,
)
.chain(),
);
}
#[cfg(not(feature = "wasm-sync"))]
app.add_systems(Update, sync_viewer_to_lights);
#[cfg(all(feature = "egui-ui", not(target_arch = "wasm32")))]
{
app.add_plugins(super::egui_panel::EguiSettingsPlugin);
}
}
}
fn setup_viewer_light(mut commands: Commands, settings: Res<ViewerSettings>) {
let ldt = settings.ldt_data.clone().or_else(load_default_ldt);
if let Some(ldt_data) = ldt {
let transforms = calculate_all_luminaire_transforms(&settings, &ldt_data);
for transform in transforms {
commands.spawn(
EulumdatLightBundle::new(ldt_data.clone())
.with_transform(
Transform::from_translation(transform.position)
.with_rotation(transform.rotation),
)
.with_solid(settings.show_photometric_solid)
.with_model(settings.show_luminaire)
.with_shadows(settings.show_shadows),
);
}
}
}
#[cfg(feature = "wasm-sync")]
fn sync_ldt_to_light(
mut commands: Commands,
settings: Res<ViewerSettings>,
lights: Query<Entity, With<crate::photometric::PhotometricLight<Eulumdat>>>,
) {
if !settings.is_changed() {
return;
}
if let Some(ref new_ldt) = settings.ldt_data {
for entity in lights.iter() {
commands.entity(entity).despawn();
}
let transforms = calculate_all_luminaire_transforms(&settings, new_ldt);
#[cfg(target_arch = "wasm32")]
web_sys::console::log_1(&format!("[Bevy] Spawning {} luminaires", transforms.len()).into());
for transform in transforms {
commands.spawn(
EulumdatLightBundle::new(new_ldt.clone())
.with_transform(
Transform::from_translation(transform.position)
.with_rotation(transform.rotation),
)
.with_solid(settings.show_photometric_solid)
.with_model(settings.show_luminaire)
.with_shadows(settings.show_shadows),
);
}
}
}