exponential_map/exponential_map.rs
1//! A simple 3D scene with light shining over a cube sitting on a plane and a trackball camera
2//! waiting for your input to orbit around.
3//!
4//! This is an alternative trackball technique using exponential map and parallel transport to
5//! preserve distances and angles for inducing coherent and intuitive trackball rotations. For
6//! instance, displacements on straight radial lines through the screen's center are carried to arcs
7//! of the same length on great circles of the trackball (e.g., dragging the mouse along an eights
8//! of the trackball's circumference rolls the camera by 360/8=45 degrees, dragging the mouse from
9//! the screen's center to its further edge *linearly* rotates the camera by 1 [radian], where the
10//! trackball's diameter is the maximum of the screen's width and height). This is in contrast to
11//! state-of-the-art techniques using orthogonal projection which distorts radial distances further
12//! away from the screen's center (e.g., the rotation accelerates towards the edge).
13//!
14//! [radian]: https://en.wikipedia.org/wiki/Radian
15
16use bevy::prelude::*;
17use bevy_trackball::prelude::*;
18
19fn main() {
20 App::new()
21 .add_plugins(DefaultPlugins.set(WindowPlugin {
22 primary_window: Some(Window {
23 canvas: Some("#bevy".to_owned()),
24 ..default()
25 }),
26 ..default()
27 }))
28 .add_plugins(TrackballPlugin)
29 .add_systems(Startup, setup)
30 .run();
31}
32
33/// set up a simple 3D scene
34fn setup(
35 mut commands: Commands,
36 mut meshes: ResMut<Assets<Mesh>>,
37 mut materials: ResMut<Assets<StandardMaterial>>,
38) {
39 // circular base
40 commands.spawn((
41 Mesh3d(meshes.add(Circle::new(4.0))),
42 MeshMaterial3d(materials.add(Color::WHITE)),
43 Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
44 ));
45 // cube
46 commands.spawn((
47 Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
48 MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
49 Transform::from_xyz(0.0, 0.5, 0.0),
50 ));
51 // light
52 commands.spawn((
53 PointLight {
54 shadows_enabled: true,
55 ..default()
56 },
57 Transform::from_xyz(4.0, 8.0, 4.0),
58 ));
59 // camera
60 commands.spawn((
61 TrackballController::default(),
62 TrackballCamera::look_at(Vec3::Y * 0.5, Vec3::new(-2.5, 4.5, 9.0), Vec3::Y),
63 Camera3d::default(),
64 ));
65}