hello_cube/hello_cube.rs
1//! # Hello Cube
2//!
3//! The simplest possible Vertra scene: a single orange cube that slowly
4//! rotates in place. This example shows the minimum boilerplate required
5//! to open a window and render geometry.
6//!
7//! **Run:**
8//! ```sh
9//! cargo run --example hello_cube
10//! ```
11//!
12//! **Controls:** close the window to exit.
13
14use vertra::camera::Camera;
15use vertra::geometry::Geometry;
16use vertra::objects::Object;
17use vertra::transform::Transform;
18use vertra::window::Window;
19
20/// Application state — we cache the numeric ID resolved during startup so that
21/// `on_update` never pays the cost of a string-hash lookup every frame.
22struct AppState {
23 cube_id: Option<usize>,
24}
25
26fn main() {
27 Window::new(AppState { cube_id: None })
28 .with_title("Hello, Cube!")
29 .with_camera(
30 Camera::new()
31 .with_position([0.0, 2.0, -5.0])
32 .with_rotation(90.0, -15.0),
33 )
34 .on_startup(|state, scene, _| {
35 // Spawn a single cube at the world origin.
36 let id = scene.spawn(
37 Object {
38 name: "Cube".to_string(),
39 str_id: "cube".to_string(),
40 geometry: Some(Geometry::Cube { size: 1.5 }),
41 color: [0.9, 0.5, 0.2, 1.0], // warm orange
42 transform: Transform::default(),
43 ..Default::default()
44 },
45 None, // no parent — this is a root object
46 );
47 // Cache the ID so on_update can find it cheaply.
48 state.cube_id = Some(id);
49 })
50 .on_update(|state, scene, ctx| {
51 // Rotate 45° per second around the Y-axis.
52 if let Some(cube) = state.cube_id.and_then(|id| scene.world.get_mut(id)) {
53 cube.transform.rotation[1] += 45.0 * ctx.dt;
54 }
55 })
56 .create();
57}
58