use bevy::math::{Quat, Vec3};
use bevy::prelude::{EventReader, Query, Res, Time, Transform, With, Without};
use crate::data::key_binding::{CameraRotationAction, CameraRotationEvents};
use crate::prelude::{CameraOrbitTag, CameraProperties, CameraTag};
pub fn update_orbit_rotation(
mut camera_transform_q: Query<&mut Transform, (With<CameraTag>, Without<CameraOrbitTag>)>,
target_transform_q: Query<&Transform, With<CameraOrbitTag>>,
properties: Res<CameraProperties>,
mut rotation_events: EventReader<CameraRotationEvents>,
time: Res<Time>,
) {
if rotation_events.is_empty() ||
target_transform_q.is_empty() ||
camera_transform_q.is_empty() {
return;
}
let mut yaw_rotation_delta: f32 = 0.;
let mut pitch_rotation_delta: f32 = 0.;
let mut camera_transform = camera_transform_q.single_mut();
let target_transform = target_transform_q.single();
for events in rotation_events.read() {
for event in &events.0 {
match event {
CameraRotationAction::Horizontal(delta) => yaw_rotation_delta += delta,
CameraRotationAction::Vertical(delta) => pitch_rotation_delta += delta,
}
}
}
let delta_time = time.delta_seconds();
let yaw = Quat::from_rotation_y(-yaw_rotation_delta * properties.rotation_speed * delta_time);
let pitch = Quat::from_rotation_x(-pitch_rotation_delta * properties.rotation_speed * delta_time);
camera_transform.rotation = yaw * camera_transform.rotation;
let new_rotation = camera_transform.rotation * pitch;
let up_vector = new_rotation * Vec3::Y;
if up_vector.y > 0.0 {
camera_transform.rotation = new_rotation;
}
let radius = camera_transform.translation.distance(target_transform.translation);
let offset = camera_transform.rotation * Vec3::new(0.0, 0.0, radius);
camera_transform.translation = target_transform.translation + offset;
}