use std::time::Duration;
use bevy_math::{prelude::*, DVec2};
use bevy_reflect::prelude::*;
use super::smoothing::InputQueue;
#[derive(Debug, Clone, Reflect)]
pub enum MotionInputs {
OrbitZoom {
screenspace_inputs: InputQueue<Vec2>,
zoom_inputs: InputQueue<f32>,
},
PanZoom {
screenspace_inputs: InputQueue<Vec2>,
zoom_inputs: InputQueue<f32>,
},
Zoom {
zoom_inputs: InputQueue<f32>,
},
}
impl MotionInputs {
pub fn smooth_orbit_velocity(&self) -> DVec2 {
if let Self::OrbitZoom {
screenspace_inputs, ..
} = self
{
let value = screenspace_inputs
.latest_smoothed()
.unwrap_or(Vec2::ZERO)
.as_dvec2();
if value.is_finite() {
value
} else {
DVec2::ZERO
}
} else {
DVec2::ZERO
}
}
pub fn smooth_pan_velocity(&self) -> DVec2 {
if let Self::PanZoom {
screenspace_inputs, ..
} = self
{
let value = screenspace_inputs
.latest_smoothed()
.unwrap_or(Vec2::ZERO)
.as_dvec2();
if value.is_finite() {
value
} else {
DVec2::ZERO
}
} else {
DVec2::ZERO
}
}
pub fn orbit_momentum(&self, window: Duration) -> DVec2 {
if let Self::OrbitZoom {
screenspace_inputs, ..
} = self
{
let velocity = screenspace_inputs.average_smoothed_value(window).as_dvec2();
if !velocity.is_finite() {
DVec2::ZERO
} else {
velocity
}
} else {
DVec2::ZERO
}
}
pub fn pan_momentum(&self, window: Duration) -> DVec2 {
if let Self::PanZoom {
screenspace_inputs, ..
} = self
{
let velocity = screenspace_inputs.average_smoothed_value(window).as_dvec2();
if !velocity.is_finite() {
DVec2::ZERO
} else {
velocity
}
} else {
DVec2::ZERO
}
}
pub fn smooth_zoom_velocity(&self) -> f64 {
let velocity = self.zoom_inputs().latest_smoothed().unwrap_or(0.0) as f64;
if !velocity.is_finite() {
0.0
} else {
velocity
}
}
pub fn zoom_inputs(&self) -> &InputQueue<f32> {
match self {
MotionInputs::OrbitZoom { zoom_inputs, .. } => zoom_inputs,
MotionInputs::PanZoom { zoom_inputs, .. } => zoom_inputs,
MotionInputs::Zoom { zoom_inputs } => zoom_inputs,
}
}
pub fn zoom_inputs_mut(&mut self) -> &mut InputQueue<f32> {
match self {
MotionInputs::OrbitZoom { zoom_inputs, .. } => zoom_inputs,
MotionInputs::PanZoom { zoom_inputs, .. } => zoom_inputs,
MotionInputs::Zoom { zoom_inputs } => zoom_inputs,
}
}
pub fn zoom_velocity_abs(&self, window: Duration) -> f64 {
let zoom_inputs = match self {
MotionInputs::OrbitZoom { zoom_inputs, .. } => zoom_inputs,
MotionInputs::PanZoom { zoom_inputs, .. } => zoom_inputs,
MotionInputs::Zoom { zoom_inputs } => zoom_inputs,
};
let velocity = zoom_inputs.approx_smoothed(window, |v| {
*v = v.abs();
}) as f64;
if !velocity.is_finite() {
0.0
} else {
velocity
}
}
}