Skip to main content

basic_3d/
basic_3d.rs

1use primback::prelude::*;
2
3struct Basic3DApp {
4    rotation_angle: f32,
5}
6
7impl PrimbackApp for Basic3DApp {
8    fn init(&mut self, update_ctx: &mut UpdateContext) {
9        // Set the camera position and direction
10        let camera = Camera::look_at(
11            vec3(0.0, 5.0, 10.0), // Eye position
12            vec3(0.0, 0.5, 0.0),  // Look-at target
13            Vec3::Y,              // Up vector
14        );
15        update_ctx.set_camera(camera);
16
17        // Configure the directional light direction and colors
18        let light = Light {
19            direction: vec3(1.0, -1.0, -1.0).normalize(),
20            color: Color::new(1.0, 0.95, 0.9),
21            ambient: Color::new(0.2, 0.2, 0.25),
22        };
23        update_ctx.set_light(light);
24    }
25
26    fn update(&mut self, update_ctx: &mut UpdateContext) {
27        // Rotate shapes over time
28        self.rotation_angle += update_ctx.delta_time() * 0.5;
29
30        // Close the application if Escape key is pressed
31        if update_ctx.is_key_pressed(KeyCode::Escape) {
32            update_ctx.exit();
33        }
34    }
35
36    fn draw(&mut self, draw_ctx: &mut DrawContext) {
37        // Clear the screen with a dark background color
38        draw_ctx.clear(Color::new(0.05, 0.05, 0.08));
39
40        // Draw a green grid at the bottom
41        let plane_transform =
42            Transform::new_position(vec3(0.0, -1.0, 0.0)).scale(vec3(15.0, 1.0, 15.0));
43        draw_ctx.draw_shape_wire(
44            Shape::plane().subdivisions(10),
45            plane_transform,
46            Color::new(0.2, 0.3, 0.2),
47        );
48
49        // 1. Red Cube on the left
50        let cube_rot = Quat::from_rotation_y(self.rotation_angle);
51        let cube_transform = Transform::new_position(vec3(-3.0, 0.5, 0.0)).rotation(cube_rot);
52        draw_ctx.draw_shape(
53            Shape::cube().size(vec3(1.5, 1.5, 1.5)),
54            cube_transform,
55            Color::new(0.8, 0.2, 0.2),
56        );
57
58        // 2. Blue Sphere in the middle
59        let sphere_transform = Transform::new_position(vec3(0.0, 0.5, 0.0));
60        draw_ctx.draw_shape(
61            Shape::sphere().radius(0.8),
62            sphere_transform,
63            Color::new(0.2, 0.4, 0.8),
64        );
65
66        // 3. Yellow Cone on the right
67        let cone_rot = Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)
68            * Quat::from_rotation_z(self.rotation_angle);
69        let cone_transform = Transform::new(vec3(3.0, 0.5, 0.0), cone_rot, Vec3::ONE);
70        draw_ctx.draw_shape(
71            Shape::cone().radius(0.6).height(1.2),
72            cone_transform,
73            Color::new(0.8, 0.8, 0.2),
74        );
75
76        // 4. Cyan Torus in the front (Wireframe mode to show off structure)
77        let torus_rot = Quat::from_rotation_x(self.rotation_angle)
78            * Quat::from_rotation_y(self.rotation_angle * 0.5);
79        let torus_transform = Transform::new(vec3(0.0, 0.5, 3.0), torus_rot, Vec3::ONE);
80        draw_ctx.draw_shape_wire(
81            Shape::torus().major_radius(0.8).minor_radius(0.2),
82            torus_transform,
83            Color::new(0.2, 0.8, 0.8),
84        );
85
86        // 5. Magenta Cylinder in the back (Unlit mode to show differences in lighting)
87        let cylinder_rot = Quat::from_rotation_z(self.rotation_angle);
88        let cylinder_transform = Transform::new(vec3(0.0, 0.8, -3.0), cylinder_rot, Vec3::ONE);
89        draw_ctx.draw_shape(
90            Shape::cylinder().radius(0.5).height(1.4).unlit(),
91            cylinder_transform,
92            Color::new(0.8, 0.2, 0.8),
93        );
94    }
95}
96
97fn main() {
98    let config = PrimbackConfig {
99        window_title: "Primback - Basic 3D Demo".to_string(),
100        ..Default::default()
101    };
102
103    Primback::run(
104        config,
105        Basic3DApp {
106            rotation_angle: 0.0,
107        },
108    );
109}