use bevy_math::{Quat, Vec3};
use bevy_transform::prelude::Transform;
use crate::dolly::{
driver::RigDriver,
rig::RigUpdateParams,
util::{ExpSmoothed, ExpSmoothingParams},
};
#[derive(Debug)]
pub struct Smooth {
pub position_smoothness: f32,
pub rotation_smoothness: f32,
output_offset_scale: f32,
smoothed_position: ExpSmoothed<Vec3>,
smoothed_rotation: ExpSmoothed<Quat>,
}
impl Default for Smooth {
fn default() -> Self {
Self {
position_smoothness: 1.0,
rotation_smoothness: 1.0,
output_offset_scale: 1.0,
smoothed_position: Default::default(),
smoothed_rotation: Default::default(),
}
}
}
impl Smooth {
pub fn new_position(position_smoothness: f32) -> Self {
Self {
position_smoothness,
rotation_smoothness: 0.0,
..Default::default()
}
}
pub fn new_rotation(rotation_smoothness: f32) -> Self {
Self {
rotation_smoothness,
position_smoothness: 0.0,
..Default::default()
}
}
pub fn new_position_rotation(position_smoothness: f32, rotation_smoothness: f32) -> Self {
Self {
position_smoothness,
rotation_smoothness,
..Default::default()
}
}
pub fn predictive(mut self, predictive: bool) -> Self {
self.output_offset_scale = if predictive { -1.0 } else { 1.0 };
self
}
}
impl RigDriver for Smooth {
fn update(&mut self, params: RigUpdateParams) -> Transform {
let translation = self.smoothed_position.exp_smooth_towards(
¶ms.parent.translation,
ExpSmoothingParams {
smoothness: self.position_smoothness,
output_offset_scale: self.output_offset_scale,
delta_time_seconds: params.delta_time_seconds,
},
);
let rotation = self.smoothed_rotation.exp_smooth_towards(
¶ms.parent.rotation,
ExpSmoothingParams {
smoothness: self.rotation_smoothness,
output_offset_scale: self.output_offset_scale,
delta_time_seconds: params.delta_time_seconds,
},
);
Transform {
translation,
rotation,
scale: Vec3::ONE,
}
}
}