Skip to main content

ranim_core/traits/transform/
shift.rs

1use glam::DVec3;
2
3use crate::anchor::{Aabb, AabbPoint, Locate};
4
5/// Shifting operations.
6///
7/// This trait is blanket-implemented for all `T: ApplyTransform<Translation>`
8/// (see [`super::ApplyTransform`]).
9pub trait ShiftTransform {
10    /// Shift the item by a given vector.
11    fn shift(&mut self, offset: DVec3) -> &mut Self;
12}
13
14/// Useful extensions for shifting operations.
15///
16/// This trait is implemented automatically for types that implement [`ShiftTransform`], you should not implement it yourself.
17pub trait ShiftTransformExt: ShiftTransform {
18    /// Do something with the origin of the item.
19    ///
20    /// See [`crate::anchor`]'s [`Locate`] for more details.
21    fn with_origin(&mut self, p: impl Locate<Self>, f: impl FnOnce(&mut Self)) -> &mut Self {
22        let p = p.locate(self);
23        self.shift(-p);
24        f(self);
25        self.shift(p)
26    }
27    /// Put anchor at a given point.
28    ///
29    /// See [`crate::anchor`]'s [`Locate`] for more details.
30    fn move_anchor_to<A>(&mut self, anchor: A, point: DVec3) -> &mut Self
31    where
32        A: Locate<Self>,
33    {
34        self.shift(point - anchor.locate(self));
35        self
36    }
37    /// Put pivot at a given point.
38    fn move_to(&mut self, point: DVec3) -> &mut Self
39    where
40        AabbPoint: Locate<Self>,
41    {
42        self.move_anchor_to(AabbPoint::CENTER, point)
43    }
44    /// Put negative anchor of self on anchor of target
45    fn move_next_to<T: Aabb + ?Sized>(&mut self, target: &T, anchor: AabbPoint) -> &mut Self
46    where
47        AabbPoint: Locate<Self>,
48    {
49        self.move_next_to_padded(target, anchor, 0.0)
50    }
51    /// Put negative anchor of self on anchor of target, with a distance of `padding`
52    fn move_next_to_padded<T: Aabb + ?Sized>(
53        &mut self,
54        target: &T,
55        anchor: AabbPoint,
56        padding: f64,
57    ) -> &mut Self
58    where
59        AabbPoint: Locate<Self>,
60    {
61        let neg_anchor = AabbPoint(-anchor.0);
62        self.move_anchor_to(
63            neg_anchor,
64            Locate::<T>::locate(&anchor, target) + anchor.0.normalize() * padding,
65        )
66    }
67}
68
69impl<T: ShiftTransform + ?Sized> ShiftTransformExt for T {}