1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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 translation each time, does not reduce itself
Sync,
/// Move mode, directly zeroes out the velocity (momentum is transferred to translation)
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 the 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);
}
}
}
}
|