sim_core/
lib.rs

1use bevy::prelude::*;
2use bevy_rapier3d::prelude::{NoUserData, RapierPhysicsPlugin};
3use std::path::PathBuf;
4
5/// High-level run mode for the sim runtime (detector-free).
6#[derive(Resource, Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
7pub enum SimRunMode {
8    #[default]
9    Sim,
10    Datagen,
11    Inference,
12}
13
14/// Common configuration for the sim runtime.
15#[derive(Resource, Debug, Clone)]
16pub struct SimConfig {
17    pub mode: SimRunMode,
18    pub headless: bool,
19    pub capture_output_root: PathBuf,
20    pub prune_empty: bool,
21    pub prune_output_root: Option<PathBuf>,
22    pub max_frames: Option<u32>,
23    pub capture_interval_secs: Option<f32>,
24}
25
26impl Default for SimConfig {
27    fn default() -> Self {
28        Self {
29            mode: SimRunMode::Sim,
30            headless: false,
31            capture_output_root: PathBuf::from("assets/datasets/captures"),
32            prune_empty: false,
33            prune_output_root: None,
34            max_frames: None,
35            capture_interval_secs: None,
36        }
37    }
38}
39
40/// System sets for the core sim scheduling.
41#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
42pub enum ModeSet {
43    Common,
44    SimDatagen,
45    Inference,
46}
47
48/// Core sim plugin: registers mode-based system sets and injects default config.
49pub struct SimPlugin;
50
51impl Plugin for SimPlugin {
52    fn build(&self, app: &mut App) {
53        app.insert_resource(SimConfig::default()).configure_sets(
54            Update,
55            (ModeSet::Common, ModeSet::SimDatagen, ModeSet::Inference),
56        );
57    }
58}
59
60pub mod prelude {
61    pub use super::{ModeSet, SimConfig, SimPlugin, SimRunMode};
62    pub use crate::autopilot_types::{AutoDir, AutoDrive, AutoStage, DataRun, DatagenInit};
63    pub use crate::camera::{
64        camera_controller, pov_toggle_system, setup_camera, Flycam, PovState, ProbePovCamera,
65        UiOverlayCamera,
66    };
67    pub use crate::controls::ControlParams;
68    pub use crate::hooks::{AutopilotHook, ControlsHook, SimHooks};
69    pub use crate::probe_types::{ProbeSegment, SegmentSpring};
70    pub use crate::recorder_meta::{
71        BasicRecorderMeta, RecorderMetaProvider, RecorderMetadataProvider, RecorderSink,
72        RecorderWorldState,
73    };
74    pub use crate::recorder_types::{
75        AutoRecordTimer, RecorderConfig, RecorderMotion, RecorderState,
76    };
77    pub use crate::runtime::{register_runtime_systems, SimRuntimePlugin};
78}
79
80/// Build a base Bevy `App` with sim mode sets and config. Detector wiring is intentionally omitted.
81pub fn build_app(sim_config: SimConfig) -> App {
82    let mut app = App::new();
83    let headless = sim_config.headless;
84    app.insert_resource(sim_config)
85        .add_plugins(DefaultPlugins.set(WindowPlugin {
86            primary_window: Some(Window {
87                visible: !headless,
88                fit_canvas_to_parent: true,
89                ..default()
90            }),
91            ..default()
92        }))
93        .add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
94        .configure_sets(
95            Update,
96            (ModeSet::Common, ModeSet::SimDatagen, ModeSet::Inference),
97        );
98    app
99}
100
101pub mod autopilot_types;
102pub mod camera;
103pub mod controls;
104pub mod hooks;
105pub mod probe_types;
106pub mod recorder_meta;
107pub mod recorder_types;
108pub mod runtime;