/** * Viewer abstraction to control multiple off-axis cameras */ use bevy::{math::Vec4Swizzles, prelude::*, transform}; use crate::{ offaxis::OffAxisProjection, projection::create_offaxis_matrices, screeninfo::ScreenInfo, }; #[derive(Component, Default)] pub struct Viewer { pub position: Vec3, pub orientation: Quat, pub alpha: f32, } impl Viewer { pub fn new(position: Vec3) -> Self { Self { position, orientation: Quat::IDENTITY, alpha: 0.0, } } pub fn default() -> Self { Self { position: Vec3::ZERO, orientation: Quat::IDENTITY, alpha: 0.0, } } } pub fn apply_viewer_to_projections( mut query: Query<(&Viewer, &ScreenInfo, &mut OffAxisProjection, &mut Transform)>, ) { query.for_each_mut(|(viewer, screen_info, mut offaxis, mut transform)| { let eye = viewer.position; let (lower_left, lower_right, upper_left, _) = screen_info.corner_points(); // let lower_left = Vec3::new(screen_info.center.x - screen_info.width / 2.0,screen_info.center.y - screen_info.height / 2.0,screen_info.center.z); // let upper_left = Vec3::new(screen_info.center.x - screen_info.width / 2.0,screen_info.center.y + screen_info.height / 2.0,screen_info.center.z); // let lower_right = Vec3::new(screen_info.center.x + screen_info.width / 2.0,screen_info.center.y - screen_info.height / 2.0,screen_info.center.z); let (view, projection) = create_offaxis_matrices(lower_left, lower_right, upper_left, eye, 1000.0f32); offaxis.projection_matrix = projection; *transform = Transform::from_matrix(view.inverse()); // info!("Viewer {:?}", viewer.position); // *transform = Transform::from_translation(eye).looking_at(Vec3::ZERO, Vec3::Y); }); } pub fn simulate_viewer_with_circle(mut query: Query<&mut Viewer>, time: Res<Time>) { for mut v in query.iter_mut() { let radius = 1.3; let offset = Vec3::new(0.0,0.0,8f32); let speed = 1.0f32; v.alpha += speed * time.delta_seconds(); v.position = Vec3::new( v.alpha.sin() * radius, v.alpha.cos() * radius, 0.0, ) + offset; // info!("Viewer {:?}", v.position); } } pub fn simulate_viewer_with_keyboard( mut query: Query<&mut Viewer>, input: Res<Input<KeyCode>>, time: Res<Time>, ) { let offset = Vec3::new(0.0,0.0,8f32); for mut viewer in query.iter_mut() { if input.pressed(KeyCode::W) { viewer.position += Vec3::Z * time.delta_seconds(); } else if input.pressed(KeyCode::S) { viewer.position -= Vec3::Z * time.delta_seconds(); } else if input.pressed(KeyCode::A) { viewer.position -= Vec3::X * time.delta_seconds(); } else if input.pressed(KeyCode::D) { viewer.position += Vec3::X * time.delta_seconds(); } else if input.pressed(KeyCode::Up) { viewer.position += Vec3::Y * time.delta_seconds(); } else if input.pressed(KeyCode::Down) { viewer.position -= Vec3::Y * time.delta_seconds(); } } }