use bevy::prelude::*; use bevy_brp_extras::BrpExtrasPlugin; use bevy_hanabi::HanabiPlugin; use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin}; mod db; mod event_card; mod helix; mod ingest; mod interaction; mod net; mod particles; pub mod slides; fn main() { App::new() .add_plugins(DefaultPlugins.set(bevy::log::LogPlugin { filter: "bevy_asset::server::loaders=error".to_string(), ..default() })) .add_plugins(HanabiPlugin) .add_plugins(PanOrbitCameraPlugin) .add_plugins(BrpExtrasPlugin) .add_plugins(bevy_tokio_tasks::TokioTasksPlugin::default()) .init_resource::() .init_resource::() .insert_resource(helix::HelixState { focal_time: 0.0, active_level: 0, target_level: 0.0, interpolated_level: 0.0, auto_follow: true, time_scale: 1.0, }) .init_resource::() .init_resource::() .init_resource::() .init_resource::() .init_resource::() .init_resource::() .init_resource::() .init_resource::() .init_resource::() .insert_resource(ingest::TimeWindow { anchor_us: 0, latest_t: 0.0, is_initialized: false, }) .init_resource::() .init_resource::() .init_resource::() .init_asset::() .init_asset_loader::() .init_resource::() .init_resource::() .insert_resource(ClearColor(Color::BLACK)) .add_systems( Startup, ( setup, ingest::setup_event_dots, helix::setup_helix_geometry, net::setup_atp_client, db::spawn_db_thread, ingest::spawn_jetstream_consumer.after(db::spawn_db_thread), ingest::load_historical_events .after(db::spawn_db_thread) .before(ingest::spawn_jetstream_consumer), particles::setup_particle_effects, event_card::setup_detail_card, slides::load_slide_deck, ), ) .add_systems( Update, ( ingest::drain_jetstream_events, ingest::poll_history_responses.after(ingest::drain_jetstream_events), particles::spawn_event_particles.after(ingest::poll_history_responses), particles::adjust_particle_zoom, particles::cleanup_expired_events.after(particles::spawn_event_particles), interaction::scroll_zoom_level, interaction::button_zoom_level, interaction::drag_pan_time, interaction::check_pan_triggers_history_load.after(interaction::drag_pan_time), interaction::toggle_pause, interaction::toggle_slow_time, slides::sync_slide_deck, slides::slide_navigation, interaction::auto_follow_latest, interaction::interpolate_zoom_level, interaction::update_camera_focus, ), ) .add_systems( Update, ( interaction::track_cursor, interaction::pick_event.after(interaction::track_cursor), event_card::update_detail_card.after(interaction::pick_event), interaction::highlight_selected.after(interaction::pick_event), event_card::request_profile_for_selected.after(event_card::update_detail_card), event_card::request_enrichment_for_selected.after(event_card::update_detail_card), helix::extend_helix_geometry, helix::draw_helix, ), ) .run(); } #[derive(Resource)] pub struct UiFont { pub primary: bevy::asset::Handle, pub bold: bevy::asset::Handle, pub italic: bevy::asset::Handle, pub emoji: bevy::asset::Handle, } impl FromWorld for UiFont { fn from_world(world: &mut World) -> Self { let asset_server = world.resource::(); UiFont { primary: asset_server.load("fonts/IosevkaIoskeley-Regular.ttf"), bold: asset_server.load("fonts/IosevkaIoskeley-Bold.ttf"), italic: asset_server.load("fonts/IosevkaIoskeley-Italic.ttf"), emoji: asset_server.load("fonts/NotoColorEmoji.ttf"), } } } fn setup(mut commands: Commands) { // Orbiting camera commands.spawn(( Camera3d::default(), Camera { clear_color: ClearColorConfig::Custom(Color::BLACK), ..default() }, bevy::render::view::Hdr, bevy::post_process::bloom::Bloom { intensity: 0.08, low_frequency_boost: 0.3, low_frequency_boost_curvature: 0.3, ..default() }, Transform::from_translation(Vec3::new(0.0, 2.0, 8.0)).looking_at(Vec3::ZERO, Vec3::Y), PanOrbitCamera { focus: Vec3::ZERO, button_zoom: Some(MouseButton::Middle), modifier_pan: Some(KeyCode::ShiftLeft), ..default() }, )); // Ambient light so gizmos are visible commands.spawn(AmbientLight { color: Color::WHITE, brightness: 300.0, affects_lightmapped_meshes: false, }); }