diff options
Diffstat (limited to 'plugins/movement/src/reducer.rs')
| -rw-r--r-- | plugins/movement/src/reducer.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/plugins/movement/src/reducer.rs b/plugins/movement/src/reducer.rs new file mode 100644 index 0000000..334d37e --- /dev/null +++ b/plugins/movement/src/reducer.rs @@ -0,0 +1,62 @@ +use bevy::{ecs::component::Component, math::Vec3}; + +use crate::Velocity; + +/// Controls how Velocity is reduced +#[derive(Component)] +pub enum VelocityReducer { + /// Sync mode, only applies the current Velocity to Position each time, does not reduce itself + Sync, + + /// Move mode, directly zeroes out the velocity (momentum is transferred to Position) + Move, + + /// Constant reduction mode, reduces by a fixed amount each time until it becomes Vec3::ZERO + Reduce(Vec3), + + /// Lerp, reduces velocity using linear interpolation each time until it becomes Vec3::ZERO + Lerp(f32), + + /// Function, calls a custom function to process velocity + Func(Box<dyn Fn(Vec3) -> Vec3 + Send + Sync + 'static>), +} + +impl VelocityReducer { + /// Calculates velocity reduction, writing the result back to the Velocity component + pub fn calculate(&self, origin: &mut Velocity) { + self.calculate_vec(&mut *origin); + } + + /// Calculates velocity reduction, writing the result back to Vec3 + pub fn calculate_vec(&self, origin_vec: &mut Vec3) { + match self { + VelocityReducer::Sync => { + // DO NOTHING + } + VelocityReducer::Move => { + *origin_vec = Vec3::ZERO; + } + VelocityReducer::Reduce(vec3) => { + let mut vec = *origin_vec - *vec3; + // Handle direction: if sign flips, clamp to zero + if (origin_vec.x > 0.0 && vec.x < 0.0) || (origin_vec.x < 0.0 && vec.x > 0.0) { + vec.x = 0.0; + } + if (origin_vec.y > 0.0 && vec.y < 0.0) || (origin_vec.y < 0.0 && vec.y > 0.0) { + vec.y = 0.0; + } + if (origin_vec.z > 0.0 && vec.z < 0.0) || (origin_vec.z < 0.0 && vec.z > 0.0) { + vec.z = 0.0; + } + *origin_vec = vec; + } + VelocityReducer::Lerp(lerp) => { + let lerp = lerp.clamp(0., 1.); + *origin_vec = origin_vec.lerp(Vec3::ZERO, lerp); + } + VelocityReducer::Func(fn_mut) => { + *origin_vec = fn_mut(*origin_vec); + } + } + } +} |
