Smooth

Struct Smooth 

Source
pub struct Smooth<A: AxisBinding> {
    pub binding: A,
    pub tau: f32,
    /* private fields */
}
Expand description

A filter that smooths axis values using exponential smoothing.

tau is the time constant that controls the amount of smoothing. Small tau values result in less smoothing (more responsive), while large tau values result in more smoothing (less responsive).

Fields§

§binding: A§tau: f32

Implementations§

Source§

impl<A: AxisBinding> Smooth<A>

Source

pub fn new(binding: A, tau: f32) -> Self

Examples found in repository?
examples/smoothing.rs (line 13)
5fn main() {
6    let bindings = (
7        Pair(KeyCode::KeyA, KeyCode::KeyD),
8        Deadzone(GamepadAxis::LeftStickX, 0.1),
9    );
10    App::new()
11        .add_plugins(DefaultPlugins)
12        .add_axis::<Unsmoothed>(bindings)
13        .add_axis::<Smoothed>(Smooth::new(bindings, 0.1))
14        .add_systems(Startup, setup)
15        .add_systems(Update, test)
16        .run();
17}
More examples
Hide additional examples
examples/all_bindings.rs (lines 13-22)
9fn main() {
10    // Any type that implements AxisBinding can be used as an axis binding. A lot of bindings can be nested and combined
11    // to create more complex behaviors.
12    let _super_complex_axis_binding = WithTriggerBinding(
13        Smooth::new(
14            Deadzone(
15                (
16                    Pair(KeyCode::KeyA, GamepadAxis::LeftStickX),
17                    Multiply(32.0, GamepadAxis::LeftStickX),
18                ),
19                0.1,
20            ),
21            0.2,
22        ),
23        MouseButton::Left,
24    );
25
26    // The same complex axis binding can be built using the AxisBindingBuilder trait methods. AxisBindingBuilder is
27    // implemented for all AxisBinding types, so all bindings have access to these combinator methods. Triggers have the
28    // equivalent TriggerBindingBuilder trait.
29    let _super_complex_axis_binding_built_different = (
30        Pair(KeyCode::KeyA, GamepadAxis::LeftStickX),
31        32.0.mult(GamepadAxis::LeftStickX),
32    )
33        .deadzone(0.1)
34        .smooth(0.2)
35        .with_trigger_binding(MouseButton::Left);
36
37    //
38    // Bindings:
39    //
40    App::new()
41        .add_plugins(DefaultPlugins)
42        //
43        // Axis bindings:
44        //
45        // Basic axis bindings
46        .add_axis::<EmptyAxis>(()) // Empty binding that always returns and will not contribute to the axis value.
47        .add_axis::<ConstantAxis>(1.0) // AxisBinding is implemented for f32. It's a constant binding that always returns the given value.
48        .add_axis::<KeyCodeAxis>(KeyCode::Space) // Binding that returns 1.0 when the specified key is pressed.
49        .add_axis::<MouseButtonAxis>(MouseButton::Left) // Binding that returns 1.0 when the specified mouse button is pressed.
50        .add_axis::<GamepadButtonAxis>(GamepadButton::South) // Binding that returns the value of the specified gamepad button.
51        .add_axis::<GamepadAxisAxis>(GamepadAxis::LeftStickX) // Binding that returns the value of the specified gamepad axis.
52        .add_axis::<MouseMovementAxis>(MouseY) // Binding that returns the mouse movement delta. Also works for MouseX.
53        .add_axis::<MouseWheelAxis>(MouseWheel::default()) // Binding that returns the mouse wheel scroll delta.
54        .add_axis::<BoxedAxis>(Box::new(KeyCode::KeyW) as Box<dyn AxisBinding>) // Box<dyn AxisBinding> also implements the AxisBinding trait.
55        // Axis combinators
56        .add_axis::<TupleAxis>((KeyCode::KeyW, GamepadAxis::LeftStickX)) // Tuple of AxisBindings. All active bindings are averaged.
57        .add_axis::<VecAxis>(vec![KeyCode::KeyW, KeyCode::ArrowUp]) // Vec of AxisBindings. All active bindings are averaged.
58        .add_axis::<PairAxis>(Pair(KeyCode::KeyS, KeyCode::KeyW)) // Pair combinator that uses the first binding for negative direction and the second for positive.
59        .add_axis::<WithTriggerAxis>(WithTriggerBinding(MouseY, MouseButton::Left)) // Axis that is only active when the trigger binding is active.
60        // Axis filters
61        .add_axis::<DeadzoneAxis>(Deadzone(GamepadAxis::LeftStickX, 0.2)) // Deadzone filter that ignores small input values.
62        .add_axis::<SmoothAxis>(Smooth::new(GamepadAxis::LeftStickX, 0.1)) // Smooth filter that smooths input values over time.
63        .add_axis::<NormalizeAxis>(Normalize(GamepadAxis::LeftStickX, GamepadAxis::LeftStickY)) // Constrain the first given axis to a unit circle when combined with the second axis.
64        .add_axis::<RateLimitAxis>(RateLimit::new(GamepadAxis::LeftStickX, 1.0)) // Rate limit filter that limits how quickly the axis value can change over time.
65        .add_axis::<ClampAxis>(Clamp(GamepadAxis::LeftStickX, -0.5, 0.5)) // Clamp filter that clamps the axis value to the given min and max.
66        // Axis modifiers
67        .add_axis::<MultiplyAxis>(Multiply(GamepadAxis::LeftStickX, 0.5)) // Modifier that multiplies two axis values together.
68        .add_axis::<DivideAxis>(Divide(GamepadAxis::LeftStickX, 2.0)) // Modifier that divides the first axis by the second axis.
69        .add_axis::<AddAxis>(Add(GamepadAxis::LeftStickX, 0.5)) // Modifier that adds two axis values together.
70        .add_axis::<SubtractAxis>(Subtract(GamepadAxis::LeftStickX, 0.5)) // Modifier that subtracts the second axis from the first axis.
71        .add_axis::<InvertAxis>(Invert(GamepadAxis::LeftStickX)) // Invert modifier that negates the axis value.
72        .add_axis::<WithCurveAxis>(WithCurve(GamepadAxis::LeftStickX, EaseFunction::BounceIn)) // Modifier that applies a curve to the axis value.
73        .add_axis::<TransformationAxis>(Transformation(GamepadAxis::LeftStickX, |v| v * v)) // Modifier that applies a custom transformation function to the axis value.
74        .add_axis::<RemapAxis>(Remap(GamepadAxis::LeftStickX, -1.0, 1.0, 0.0, 1.0)) // Modifier that remaps the axis value from one range to another.
75        //
76        // Triggers:
77        //
78        // Basic trigger bindings
79        .add_trigger::<EmptyTrigger>(()) // Empty trigger that is never active.
80        .add_trigger::<ConstantTrigger>(true) // Constant trigger that reflects the given boolean value.
81        .add_trigger::<KeyCodeTrigger>(KeyCode::Space) // Trigger that is active when the specified key is pressed.
82        .add_trigger::<MouseButtonTrigger>(MouseButton::Left) // Trigger that is active when the specified mouse button is pressed.
83        .add_trigger::<GamepadButtonTrigger>(GamepadButton::South) // Trigger that is active when the specified gamepad button is pressed.
84        .add_trigger::<BoxedTrigger>(Box::new(KeyCode::KeyW) as Box<dyn TriggerBinding>) // Box<dyn TriggerBinding> also implements the TriggerBinding trait.
85        // Trigger combinators
86        .add_trigger::<TupleTrigger>((KeyCode::KeyW, GamepadButton::South)) // Tuple of TriggerBindings. Active if any binding is active.
87        .add_trigger::<VecTrigger>(vec![KeyCode::KeyW, KeyCode::ArrowUp]) // Vec of TriggerBindings. Active if any binding is active.
88        .add_trigger::<AndTrigger>(And(KeyCode::KeyW, GamepadButton::South)) // Combinator that is only active if both bindings are active.
89        // Trigger modifiers
90        .add_trigger::<NotTrigger>(Not(KeyCode::KeyW)) // Modifier that inverts the trigger state.
91        .add_systems(
92            Update,
93            (
94                visualize_basic,
95                visualize_combinators,
96                visualize_filters,
97                visualize_modifiers,
98                draw_triggers,
99            ),
100        )
101        .add_systems(Startup, setup)
102        .insert_resource(ClearColor(Color::WHITE))
103        .run();
104}

Trait Implementations§

Source§

impl<A: AxisBinding + Clone> AxisBinding for Smooth<A>

Source§

fn value(&mut self, inputs: &Inputs<'_>) -> Option<f32>

Source§

fn clone_axis(&self) -> Box<dyn AxisBinding>

Clones the inner value and returns it as a boxed trait object.
Source§

fn as_any(&self) -> Box<dyn Any>

Clones the inner value and returns it as a boxed Any trait object.
Source§

fn all_axes(&self) -> Vec<Box<dyn AxisBinding>>

If the binding is a “collection binding” (tuple, vec, etc.), this will split the binding into its components and return a vec of boxed bindings. Otherwise, returns a vector with a single binding. Read more
Source§

impl<A: Clone + AxisBinding> Clone for Smooth<A>

Source§

fn clone(&self) -> Smooth<A>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<A: Copy + AxisBinding> Copy for Smooth<A>

Auto Trait Implementations§

§

impl<A> Freeze for Smooth<A>
where A: Freeze,

§

impl<A> RefUnwindSafe for Smooth<A>
where A: RefUnwindSafe,

§

impl<A> Send for Smooth<A>

§

impl<A> Sync for Smooth<A>

§

impl<A> Unpin for Smooth<A>
where A: Unpin,

§

impl<A> UnwindSafe for Smooth<A>
where A: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<A> AxisBindingBuilder for A
where A: AxisBinding,

Source§

fn with_trigger_binding<TB: TriggerBinding>( self, trigger: TB, ) -> WithTriggerBinding<Self, TB>

Returns a new axis binding that is only active when the given trigger binding is active.
Source§

fn deadzone(self, threshold: f32) -> Deadzone<Self>

Returns a new axis binding that applies a deadzone filter with the given threshold.
Source§

fn smooth(self, tau: f32) -> Smooth<Self>

Returns a new axis binding that applies a smoothing filter with the given time constant.
Source§

fn normalize<A: AxisBinding>(self, perpendicular: A) -> Normalize<Self, A>

Source§

fn limit_rate(self, max_rate: f32) -> RateLimit<Self>

Returns a new axis binding that applies a rate limit filter with the given maximum rate of change.
Source§

fn clamp(self, min: f32, max: f32) -> Clamp<Self>

Clamps the axis binding to the given minimum and maximum values.
Source§

fn with_curve<C: Curve<f32>>(self, curve: C) -> WithCurve<Self, C>

Returns a new axis binding that applies the given curve to the axis value.
Source§

fn transform<F: Fn(f32) -> f32>(self, func: F) -> Transformation<Self, F>

Returns a new axis binding that applies the given transformation function to the axis value.
Source§

fn mult<A: AxisBinding>(self, other: A) -> Multiply<Self, A>

Returns a new axis binding that multiplies this axis value with another axis value.
Source§

fn div<A: AxisBinding>(self, other: A) -> Divide<Self, A>

Returns a new axis binding that divides this axis value by another axis value.
Source§

fn add<A: AxisBinding>(self, other: A) -> Add<Self, A>

Returns a new axis binding that adds another axis value to this axis value.
Source§

fn sub<A: AxisBinding>(self, other: A) -> Subtract<Self, A>

Return a new axis binding that subtracts another axis value from this axis value.
Source§

fn invert(self) -> Invert<Self>

Returns a new axis binding that inverts this axis value.
Source§

fn remap( self, in_min: f32, in_max: f32, out_min: f32, out_max: f32, ) -> Remap<Self>

Remaps the axis value from one range to another.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoResult<T> for T

Source§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
Source§

impl<A> Is for A
where A: Any,

Source§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

Source§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,