Skip to main content

steel_core/entity/pushing/
impulse.rs

1//! Vanilla `Entity.push` impulse math.
2
3use std::simd::f64x2;
4
5use glam::DVec3;
6
7use super::EntityPush;
8
9const MIN_PUSH_DISTANCE: f32 = 0.01;
10const PUSH_STRENGTH: f32 = 0.05;
11
12impl EntityPush {
13    pub(crate) fn impulse(source: DVec3, target: DVec3) -> Option<DVec3> {
14        let x = target.x - source.x;
15        let z = target.z - source.z;
16
17        let distance = x.abs().max(z.abs());
18
19        if distance < f64::from(MIN_PUSH_DISTANCE) {
20            return None;
21        }
22
23        let distance = distance.sqrt();
24        let mut horizontal = f64x2::from_array([x, z]) / f64x2::splat(distance);
25
26        let scale = if distance > 1.0 { 1.0 / distance } else { 1.0 };
27        horizontal *= f64x2::splat(scale);
28        horizontal *= f64x2::splat(f64::from(PUSH_STRENGTH));
29        let [x, z] = horizontal.to_array();
30
31        Some(DVec3::new(x, 0.0, z))
32    }
33}