use bevy::{
math::{Dir3, EulerRot, Quat, Vec3},
transform::components::Transform,
};
#[derive(Default, Debug)]
pub struct RotateAction {
pub rotation: RotationType,
}
impl RotateAction {
pub fn new(rotation: RotationType) -> Self {
Self { rotation }
}
pub(super) fn apply(&mut self, transform: &mut Transform) {
match self.rotation {
RotationType::LookingTo(looking_fields) => {
transform.rotation = transform
.looking_to(looking_fields.look, looking_fields.up)
.rotation;
}
RotationType::LookingAt(looking_fields) => {
transform.rotation = transform
.looking_at(looking_fields.look, looking_fields.up)
.rotation;
}
RotationType::RotationVec(rotation) => {
let delta_yaw = -rotation.x; let delta_pitch = -rotation.y;
let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ);
let yaw = yaw + delta_yaw;
const PITCH_LIMIT: f32 = std::f32::consts::FRAC_PI_2 - 0.01; let pitch = (pitch + delta_pitch).clamp(-PITCH_LIMIT, PITCH_LIMIT);
transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll);
}
}
}
}
#[derive(Debug)]
pub enum RotationType {
RotationVec(Vec3),
LookingTo(LookingFields),
LookingAt(LookingFields),
}
impl Default for RotationType {
fn default() -> Self {
RotationType::RotationVec(Vec3::ZERO)
}
}
#[derive(Debug, Copy, Clone)]
pub struct LookingFields {
look: Vec3,
up: Dir3,
}
impl LookingFields {
pub fn new(look: Vec3, up: Dir3) -> Self {
Self { look, up }
}
}