Skip to main content

solar_system/
solar_system.rs

1//! # Solar System
2//!
3//! A three-level parent-child hierarchy: **Sun → Planet → Moon**.
4//! The Sun drives the entire system — rotating the Sun automatically
5//! carries the Planet (and Moon) around it, demonstrating how Vertra
6//! propagates world transforms down the object tree.
7//!
8//! Editor mode is enabled on startup so you can inspect and manipulate
9//! any object with the gizmo.  The `on_editor_event` callback logs every
10//! gizmo mode change and axis drag to stdout.
11//!
12//! **Run:**
13//! ```sh
14//! cargo run --example solar_system
15//! ```
16//!
17//! **Editor keybinds:**
18//! | Key        | Action                               |
19//! |------------|--------------------------------------|
20//! | `T`        | Switch to Translate gizmo            |
21//! | `R`        | Switch to Rotate gizmo               |
22//! | `E`        | Switch to Scale gizmo                |
23//! | `F`        | Frame / focus on selected object     |
24//! | `Escape`   | Exit editor mode (enter play mode)   |
25//! | `RMB drag` | Orbit camera                         |
26//! | `MMB drag` | Pan camera                           |
27//! | Scroll     | Dolly in / out                       |
28
29use vertra::camera::Camera;
30use vertra::window::Window;
31use vertra::transform::Transform;
32use vertra::geometry::Geometry;
33use vertra::objects::Object;
34
35struct AppState {
36    sun_id: Option<usize>,
37    earth_id: Option<usize>,
38    moon_id: Option<usize>,
39}
40
41fn main() {
42    let initial_state = AppState {
43        sun_id: None,
44        earth_id: None,
45        moon_id: None,
46    };
47
48    Window::new(initial_state)
49        .with_title("Simple Solar Simulation")
50        .with_camera(
51            Camera::new()
52                .with_position([0.0, 8.0, -12.0])
53                .with_rotation(90.0, -30.0)
54        )
55        .on_startup(|state, scene, _| {
56            // 1. The Sun (Center)
57            let sun = Object {
58                name: "Sun".to_string(),
59                str_id: "sun".to_string (),
60                transform: Transform::from_position(0.0, 0.0, 0.0),
61                geometry: Some(Geometry::Cube { size: 2.0 }),
62                color: [1.0, 0.9, 0.2, 1.0],
63                ..Default::default()
64            };
65            let sun_id = scene.spawn(sun, None);
66
67            // 2. The Planet (Child)
68            let planet = Object {
69                name: "Planet".to_string(),
70                str_id: "earth".to_string(),
71                transform: Transform::from_position(6.0, 0.0, 0.0),
72                geometry: Some(Geometry::Sphere { radius: 0.8, subdivisions: 24 }),
73                color: [0.2, 0.5, 1.0, 1.0],
74                ..Default::default()
75            };
76            let planet_id = scene.spawn(planet, Some(sun_id));
77
78            // 3. The Moon (Grandchild)
79            let moon = Object {
80                name: "Moon".to_string(),
81                str_id: "moon".to_string(),
82                transform: Transform::from_position(1.5, 0.0, 0.0),
83                geometry: Some(Geometry::Sphere { radius: 0.3, subdivisions: 16 }),
84                color: [0.7, 0.7, 0.7, 1.0],
85                ..Default::default()
86            };
87            scene.spawn(moon, Some(planet_id));
88
89            state.sun_id    = scene.world.get_id("sun");
90            state.earth_id  = scene.world.get_id("earth");
91            state.moon_id   = scene.world.get_id("moon");
92            scene.enable_editor_mode();
93        })
94        .on_update(|state, scene, ctx| {
95            // Rotate the Sun (the planet will orbit automatically)
96            if let Some(sun) = state.sun_id.and_then(|id| scene.world.get_mut(id)) {
97                sun.transform.rotation[1] += 30.0 * ctx.dt;
98            }
99
100            // Rotate the Planet (Earth)
101            if let Some(planet) = state.earth_id.and_then(|id| scene.world.get_mut(id)) {
102                planet.transform.rotation[1] += 100.0 * ctx.dt;
103            }
104        })
105        .create();
106}