avian2d/dynamics/rigid_body/forces/
mod.rs

1//! External forces, impulses, and acceleration for dynamic [rigid bodies](RigidBody).
2//!
3//! # Overview
4//!
5//! In addition to [`Gravity`], it is possible to apply your own forces, impulses, and acceleration
6//! to dynamic rigid bodies to simulate various effects such as force fields, motors, and thrusters.
7//! They have the following relationships:
8//!
9//! | Type             | Formula      | Relation to Velocity | Unit        |
10//! | ---------------- | ------------ | -------------------- | ----------- |
11//! | **Force**        | `F = m * a`  | `Δa = F / m`         | kg⋅m/s² (N) |
12//! | **Impulse**      | `J = F * Δt` | `Δv = J / m`         | kg⋅m/s (N⋅s) |
13//! | **Acceleration** | `a = F / m`  | `Δv = a * Δt`        | m/s²        |
14//!
15//! A force applies an acceleration to a body, which in turn modifies its velocity over time,
16//! while an impulse applies an immediate change in velocity. Both forces and impulses consider [mass properties],
17//! while acceleration by itself is independent of mass.
18//!
19//! The rotational equivalents are torques, angular impulses, and angular acceleration, which work similarly.
20//!
21//! [mass properties]: crate::dynamics::rigid_body::mass_properties
22//!
23//! ## Constant Forces
24//!
25//! Constant forces and accelerations that persist across time steps can be applied using the following components:
26//!
27//! - [`ConstantForce`]: Applies a constant force in world space.
28//! - [`ConstantTorque`]: Applies a constant torque in world space.
29//! - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
30//! - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
31//!
32//! They also have local space equivalents:
33//!
34//! - [`ConstantLocalForce`]: Applies a constant force in local space.
35#![cfg_attr(
36    feature = "3d",
37    doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
38)]
39//! - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
40#![cfg_attr(
41    feature = "3d",
42    doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
43)]
44//!
45//! These components are useful for simulating continuously applied forces that are expected
46//! to remain the same across time steps, such as per-body gravity or force fields.
47//!
48//! You can use constant forces by adding the components to your entities:
49//!
50//! ```
51#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
52#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
53//! # use bevy::prelude::*;
54//! #
55//! # fn setup(mut commands: Commands) {
56//! commands.spawn((
57//!     RigidBody::Dynamic,
58//!     Collider::capsule(0.5, 1.0),
59//!     // Apply a constant force of 10 N in the positive Y direction.
60#![cfg_attr(feature = "2d", doc = "    ConstantForce::new(0.0, 10.0),")]
61#![cfg_attr(feature = "3d", doc = "    ConstantForce::new(0.0, 10.0, 0.0),")]
62//! ));
63//! # }
64//! ```
65//!
66//! The forces are only constant in the sense that they persist across time steps.
67//! They can still be modified in systems like normal.
68//!
69//! ## One-Time Forces and Impulses
70//!
71//! It is common to apply many individual forces and impulses to dynamic rigid bodies,
72//! and to clear them afterwards. This can be done using the [`Forces`] helper [`QueryData`](bevy::ecs::query::QueryData).
73//!
74//! To use [`Forces`], add it to a [`Query`] (without `&` or `&mut`), and use the associated methods
75//! to apply forces, impulses, and accelerations to the rigid bodies.
76//!
77//! ```
78#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
79#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
80//! # use bevy::prelude::*;
81//! #
82//! # #[cfg(feature = "f32")]
83//! fn apply_forces(mut query: Query<Forces>) {
84//!     for mut forces in &mut query {
85//!         // Apply a force of 10 N in the positive Y direction to the entity.
86#![cfg_attr(
87    feature = "2d",
88    doc = "        forces.apply_force(Vec2::new(0.0, 10.0));"
89)]
90#![cfg_attr(
91    feature = "3d",
92    doc = "        forces.apply_force(Vec3::new(0.0, 10.0, 0.0));"
93)]
94//!     }
95//! }
96//! ```
97//!
98//! The force is applied continuously during the physics step, and cleared automatically after the step is complete.
99//!
100//! By default, applying forces to [sleeping](Sleeping) bodies will wake them up. If this is not desired,
101//! the [`non_waking`](ForcesItem::non_waking) method can be used to fetch a [`NonWakingForcesItem`]
102//! that allows applying forces to a body without waking it up.
103//!
104//! ```
105#![cfg_attr(feature = "2d", doc = "# use avian2d::{math::Vector, prelude::*};")]
106#![cfg_attr(feature = "3d", doc = "# use avian3d::{math::Vector, prelude::*};")]
107//! # use bevy::prelude::*;
108//! #
109//! # fn apply_forces(mut query: Query<Forces>) {
110//! #     for mut forces in &mut query {
111//! #         let force = Vector::default();
112//! // Apply a force without waking up the body if it is sleeping.
113//! forces.non_waking().apply_force(force);
114//! #     }
115//! # }
116//! ```
117//!
118//! [`Forces`] can also apply forces and impulses at a specific point in the world. If the point is not aligned
119//! with the [center of mass](CenterOfMass), it will apply a torque to the body.
120//!
121//! ```
122#![cfg_attr(feature = "2d", doc = "# use avian2d::{math::Vector, prelude::*};")]
123#![cfg_attr(feature = "3d", doc = "# use avian3d::{math::Vector, prelude::*};")]
124//! # use bevy::prelude::*;
125//! #
126//! # fn apply_impulses(mut query: Query<Forces>) {
127//! #     for mut forces in &mut query {
128//! #         let force = Vector::default();
129//! #         let point = Vector::default();
130//! // Apply an impulse at a specific point in the world.
131//! // Unlike forces, impulses are applied immediately to the velocity.
132//! forces.apply_linear_impulse_at_point(force, point);
133//! #     }
134//! # }
135//! ```
136//!
137//! As an example, you could implement radial gravity that pulls rigid bodies towards the world origin
138//! with a system like the following:
139//!
140//! ```
141#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
142#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
143//! # use bevy::prelude::*;
144//! #
145//! # #[cfg(feature = "f32")]
146//! fn radial_gravity(mut query: Query<(Forces, &GlobalTransform)>) {
147//!     for (mut forces, global_transform) in &mut query {
148//!         // Compute the direction towards the center of the world.
149//!         let direction = -global_transform.translation().normalize_or_zero();
150//!         // Apply a linear acceleration of 9.81 m/s² towards the center of the world.
151#![cfg_attr(
152    feature = "2d",
153    doc = "        forces.apply_linear_acceleration(direction.truncate() * 9.81);"
154)]
155#![cfg_attr(
156    feature = "3d",
157    doc = "        forces.apply_linear_acceleration(direction * 9.81);"
158)]
159//!     }
160//! }
161//! ```
162//!
163//! # Applying Forces vs. Modifying Velocity
164//!
165//! It is possible to achieve similar effects by directly modifying the [`LinearVelocity`]
166//! or [`AngularVelocity`] components instead of using the force APIs. For example, you could
167//! implement gravity by simply modifying the velocity of the rigid bodies in a system:
168//!
169//! ```
170#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
171#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
172//! # use bevy::prelude::*;
173//! #
174//! // In `FixedUpdate`
175//! # #[cfg(feature = "f32")]
176//! fn gravity(mut bodies: Query<&mut LinearVelocity>, time: Res<Time>) {
177//!     for mut velocity in &mut bodies {
178//!         // Apply a constant acceleration of 9.81 m/s² in the negative Y direction.
179//!         velocity.y -= 9.81 * time.delta_secs();
180//!     }
181//! }
182//! ```
183//!
184//! However, using the force APIs has several advantages:
185//!
186//! - Forces and accelerations are spread out over several [substeps](SubstepCount),
187//!   which provides higher simulation fidelity than modifying velocity once per time step.
188//! - Forces and impulses consider mass properties and delta time for you, simplifying code.
189//! - The force APIs make it straightforward to apply forces at specific points in the world.
190//!
191//! Modifying velocity directly can still be useful and simpler in some cases,
192//! and the difference in simulation fidelity tends to be small for most applications.
193//! Notably, it is currently not possible to apply forces to kinematic bodies, as they have infinite mass.
194//!
195//! Still, for convenience and best results, it is generally recommended to use the force APIs
196//! for most cases where you want to apply forces, impulses, or acceleration to dynamic rigid bodies.
197
198mod plugin;
199mod query_data;
200#[cfg(test)]
201mod tests;
202
203pub use plugin::{ForcePlugin, ForceSystems};
204pub use query_data::{Forces, ForcesItem, NonWakingForcesItem, RigidBodyForces};
205
206use crate::prelude::*;
207use bevy::prelude::*;
208
209#[cfg(feature = "2d")]
210pub(crate) trait FloatZero {
211    const ZERO: Self;
212}
213
214#[cfg(feature = "2d")]
215impl FloatZero for Scalar {
216    const ZERO: Self = 0.0;
217}
218
219/// A component for applying a constant force to a dynamic rigid body in world space.
220/// The unit is typically N or kg⋅m/s².
221///
222/// The force persists across time steps, and is accumulated with other forces.
223/// This can be useful for simulating constant forces like gravity, force fields, wind,
224/// or other environmental effects.
225///
226/// See the [module-level documentation](self) for more general information about forces in Avian.
227///
228/// # Example
229///
230/// ```
231#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
232#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
233/// # use bevy::prelude::*;
234/// #
235/// # fn setup(mut commands: Commands) {
236/// commands.spawn((
237///     RigidBody::Dynamic,
238///     Collider::capsule(0.5, 1.0),
239///     // Apply a constant force of 10 N in the positive Y direction.
240#[cfg_attr(feature = "2d", doc = "    ConstantForce::new(0.0, 10.0),")]
241#[cfg_attr(feature = "3d", doc = "    ConstantForce::new(0.0, 10.0, 0.0),")]
242/// ));
243/// # }
244/// ```
245///
246/// # Related Types
247///
248/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
249/// - [`ConstantLocalForce`]: Applies a constant force in local space.
250/// - [`ConstantTorque`]: Applies a constant torque in world space.
251/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
252/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
253#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
254#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
255#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
256#[reflect(Component, Debug, Default, PartialEq)]
257pub struct ConstantForce(pub Vector);
258
259impl ConstantForce {
260    /// Creates a new [`ConstantForce`] with the given `x` and `y` components.
261    #[cfg(feature = "2d")]
262    pub fn new(x: Scalar, y: Scalar) -> Self {
263        Self(Vector::new(x, y))
264    }
265
266    /// Creates a new [`ConstantForce`] with the given `x`, `y`, and `z` components.
267    #[cfg(feature = "3d")]
268    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
269        Self(Vector::new(x, y, z))
270    }
271}
272
273/// A component for applying a constant torque to a dynamic rigid body in world space.
274/// The unit is typically N⋅m or kg⋅m²/s².
275///
276/// The torque persists across time steps, and is accumulated with other torques.
277/// This can be useful for simulating constant torques like the torque from a motor,
278/// or other rotational effects.
279///
280/// See the [module-level documentation](self) for more general information about forces in Avian.
281///
282/// # Example
283///
284/// ```
285#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
286#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
287/// # use bevy::prelude::*;
288/// #
289/// # fn setup(mut commands: Commands) {
290/// commands.spawn((
291///     RigidBody::Dynamic,
292///     Collider::capsule(0.5, 1.0),
293///     // Apply a constant torque of 5 N⋅m in the positive Z direction.
294#[cfg_attr(feature = "2d", doc = "    ConstantTorque(5.0),")]
295#[cfg_attr(feature = "3d", doc = "    ConstantTorque::new(0.0, 0.0, 5.0),")]
296/// ));
297/// # }
298/// ```
299///
300/// # Related Types
301///
302/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
303#[cfg_attr(
304    feature = "3d",
305    doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
306)]
307/// - [`ConstantForce`]: Applies a constant force in world space.
308/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
309/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
310#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
311#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
312#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
313#[reflect(Component, Debug, Default, PartialEq)]
314pub struct ConstantTorque(pub AngularVector);
315
316#[cfg(feature = "3d")]
317impl ConstantTorque {
318    /// Creates a new [`ConstantTorque`] with the given `x`, `y`, and `z` components.
319    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
320        Self(Vector::new(x, y, z))
321    }
322}
323
324/// A component for applying a constant force to a dynamic rigid body in local space.
325/// The unit is typically N or kg⋅m/s².
326///
327/// The force persists across time steps, and is accumulated with other forces.
328/// This can be useful for simulating constant forces like rocket thrust,
329/// or other local force effects.
330///
331/// See the [module-level documentation](self) for more general information about forces in Avian.
332///
333/// # Example
334///
335/// ```
336#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
337#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
338/// # use bevy::prelude::*;
339/// #
340/// # fn setup(mut commands: Commands) {
341/// commands.spawn((
342///     RigidBody::Dynamic,
343///     Collider::capsule(0.5, 1.0),
344///     // Apply a constant force of 10 N in the positive Y direction in local space.
345#[cfg_attr(feature = "2d", doc = "    ConstantLocalForce::new(0.0, 10.0),")]
346#[cfg_attr(feature = "3d", doc = "    ConstantLocalForce::new(0.0, 10.0, 0.0),")]
347/// ));
348/// # }
349/// ```
350///
351/// # Related Types
352///
353/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
354/// - [`ConstantForce`]: Applies a constant force in world space.
355#[cfg_attr(
356    feature = "3d",
357    doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
358)]
359/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
360#[cfg_attr(
361    feature = "3d",
362    doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
363)]
364#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
365#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
366#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
367#[reflect(Component, Debug, Default, PartialEq)]
368pub struct ConstantLocalForce(pub Vector);
369
370impl ConstantLocalForce {
371    /// Creates a new [`ConstantLocalForce`] with the given `x` and `y` components.
372    #[cfg(feature = "2d")]
373    pub fn new(x: Scalar, y: Scalar) -> Self {
374        Self(Vector::new(x, y))
375    }
376
377    /// Creates a new [`ConstantLocalForce`] with the given `x`, `y`, and `z` components.
378    #[cfg(feature = "3d")]
379    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
380        Self(Vector::new(x, y, z))
381    }
382}
383
384/// A component for applying a constant torque to a dynamic rigid body in local space.
385/// The unit is typically N⋅m or kg⋅m²/s²
386///
387/// The torque persists across time steps, and is accumulated with other torques.
388/// This can be useful for simulating constant torques like torque from a motor,
389/// or other rotational effects in local space.
390///
391/// See the [module-level documentation](self) for more general information about forces in Avian.
392///
393/// # Example
394///
395/// ```
396/// # use avian3d::prelude::*;
397/// # use bevy::prelude::*;
398/// #
399/// # fn setup(mut commands: Commands) {
400/// commands.spawn((
401///     RigidBody::Dynamic,
402///     Collider::capsule(0.5, 1.0),
403///     // Apply a constant torque of 5 N⋅m in the positive Z direction in local space.
404///     ConstantLocalTorque::new(0.0, 0.0, 5.0),
405/// ));
406/// # }
407/// ```
408///
409/// # Related Types
410///
411/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
412/// - [`ConstantTorque`]: Applies a constant torque in world space.
413/// - [`ConstantLocalForce`]: Applies a constant force in local space.
414/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
415/// - [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space.
416#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
417#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
418#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
419#[reflect(Component, Debug, Default, PartialEq)]
420#[cfg(feature = "3d")]
421pub struct ConstantLocalTorque(pub AngularVector);
422
423#[cfg(feature = "3d")]
424impl ConstantLocalTorque {
425    /// Creates a new [`ConstantLocalTorque`] with the given `x`, `y`, and `z` components.
426    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
427        Self(Vector::new(x, y, z))
428    }
429}
430
431/// A component for applying a constant linear acceleration to a dynamic rigid body in world space.
432/// The unit is typically m/s².
433///
434/// The acceleration persists across time steps, and is accumulated with other accelerations.
435/// This can be useful for simulating constant accelerations like per-body gravity.
436///
437/// See the [module-level documentation](self) for more general information about forces in Avian.
438///
439/// # Example
440///
441/// ```
442#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
443#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
444/// # use bevy::prelude::*;
445/// #
446/// # fn setup(mut commands: Commands) {
447/// commands.spawn((
448///     RigidBody::Dynamic,
449///     Collider::capsule(0.5, 1.0),
450///     // Apply a constant linear acceleration of 9.81 m/s² in the negative Y direction.
451///     // This is equivalent to using the `Gravity` resource, but only for this entity.
452#[cfg_attr(
453    feature = "2d",
454    doc = "    ConstantLinearAcceleration::new(0.0, -9.81),"
455)]
456#[cfg_attr(
457    feature = "3d",
458    doc = "    ConstantLinearAcceleration::new(0.0, -9.81, 0.0),"
459)]
460/// ));
461/// # }
462/// ```
463///
464/// # Related Types
465///
466/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
467/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
468/// - [`ConstantForce`]: Applies a constant force in world space.
469/// - [`ConstantTorque`]: Applies a constant torque in world space.
470/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
471#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
472#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
473#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
474#[reflect(Component, Debug, Default, PartialEq)]
475pub struct ConstantLinearAcceleration(pub Vector);
476
477impl ConstantLinearAcceleration {
478    /// Creates a new [`ConstantLinearAcceleration`] with the given `x` and `y` components.
479    #[cfg(feature = "2d")]
480    pub fn new(x: Scalar, y: Scalar) -> Self {
481        Self(Vector::new(x, y))
482    }
483
484    /// Creates a new [`ConstantLinearAcceleration`] with the given `x`, `y`, and `z` components.
485    #[cfg(feature = "3d")]
486    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
487        Self(Vector::new(x, y, z))
488    }
489}
490
491/// A component for applying a constant angular acceleration to a dynamic rigid body in world space.
492/// The unit is typically rad/s².
493///
494/// The acceleration persists across time steps, and is accumulated with other accelerations.
495/// This can be useful for simulating constant angular accelerations like rotation from a motor,
496/// or other rotational effects.
497///
498/// See the [module-level documentation](self) for more general information about forces in Avian.
499///
500/// # Example
501///
502/// ```
503#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
504#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
505/// # use bevy::prelude::*;
506/// #
507/// # fn setup(mut commands: Commands) {
508/// commands.spawn((
509///     RigidBody::Dynamic,
510///     Collider::capsule(0.5, 1.0),
511///     // Apply a constant angular acceleration of 1.0 rad/s² in the positive Z direction.
512#[cfg_attr(feature = "2d", doc = "    ConstantAngularAcceleration(1.0),")]
513#[cfg_attr(
514    feature = "3d",
515    doc = "    ConstantAngularAcceleration::new(0.0, 0.0, 1.0),"
516)]
517/// ));
518/// # }
519/// ```
520///
521/// # Related Types
522///
523/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
524#[cfg_attr(
525    feature = "3d",
526    doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
527)]
528/// - [`ConstantForce`]: Applies a constant force in world space.
529/// - [`ConstantTorque`]: Applies a constant torque in world space.
530/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
531#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
532#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
533#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
534#[reflect(Component, Debug, Default, PartialEq)]
535pub struct ConstantAngularAcceleration(pub AngularVector);
536
537#[cfg(feature = "3d")]
538impl ConstantAngularAcceleration {
539    /// Creates a new [`ConstantAngularAcceleration`] with the given `x`, `y`, and `z` components.
540    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
541        Self(Vector::new(x, y, z))
542    }
543}
544
545/// A component for applying a constant linear acceleration to a dynamic rigid body in local space.
546/// The unit is typically m/s².
547///
548/// The acceleration persists across time steps, and is accumulated with other accelerations.
549/// This can be useful for simulating constant linear accelerations like rocket thrust,
550/// or other local acceleration effects.
551///
552/// See the [module-level documentation](self) for more general information about forces in Avian.
553///
554/// # Example
555///
556/// ```
557#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
558#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
559/// # use bevy::prelude::*;
560/// #
561/// # fn setup(mut commands: Commands) {
562/// commands.spawn((
563///     RigidBody::Dynamic,
564///     Collider::capsule(0.5, 1.0),
565///     // Apply a constant linear acceleration of 10.0 m/s² in the positive Y direction in local space.
566#[cfg_attr(
567    feature = "2d",
568    doc = "    ConstantLocalLinearAcceleration::new(0.0, 10.0),"
569)]
570#[cfg_attr(
571    feature = "3d",
572    doc = "    ConstantLocalLinearAcceleration::new(0.0, 10.0, 0.0),"
573)]
574/// ));
575/// # }
576/// ```
577///
578/// # Related Types
579///
580/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
581/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
582/// - [`ConstantLocalForce`]: Applies a constant force in local space.
583#[cfg_attr(
584    feature = "3d",
585    doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
586)]
587#[cfg_attr(
588    feature = "3d",
589    doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
590)]
591#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
592#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
593#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
594#[reflect(Component, Debug, Default, PartialEq)]
595pub struct ConstantLocalLinearAcceleration(pub Vector);
596
597impl ConstantLocalLinearAcceleration {
598    /// Creates a new [`ConstantLocalLinearAcceleration`] with the given `x` and `y` components.
599    #[cfg(feature = "2d")]
600    pub fn new(x: Scalar, y: Scalar) -> Self {
601        Self(Vector::new(x, y))
602    }
603
604    /// Creates a new [`ConstantLocalLinearAcceleration`] with the given `x`, `y`, and `z` components.
605    #[cfg(feature = "3d")]
606    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
607        Self(Vector::new(x, y, z))
608    }
609}
610
611/// A component for applying a constant angular acceleration to a dynamic rigid body in local space.
612/// The unit is typically rad/s².
613///
614/// The acceleration persists across time steps, and is accumulated with other accelerations.
615/// This can be useful for simulating constant angular accelerations like rotation from a motor,
616/// or other rotational effects in local space.
617///
618/// See the [module-level documentation](self) for more general information about forces in Avian.
619///
620/// # Example
621///
622/// ```
623/// # use avian3d::prelude::*;
624/// # use bevy::prelude::*;
625/// #
626/// # fn setup(mut commands: Commands) {
627/// commands.spawn((
628///     RigidBody::Dynamic,
629///     Collider::capsule(0.5, 1.0),
630///     // Apply a constant angular acceleration of 1.0 rad/s² in the positive Z direction in local space.
631///     ConstantLocalAngularAcceleration::new(0.0, 0.0, 1.0),
632/// ));
633/// # }
634/// ```
635///
636/// # Related Types
637///
638/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
639/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
640/// - [`ConstantLocalForce`]: Applies a constant force in local space.
641/// - [`ConstantLocalTorque`]: Applies a constant torque in local space.
642/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
643#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
644#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
645#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
646#[reflect(Component, Debug, Default, PartialEq)]
647#[cfg(feature = "3d")]
648pub struct ConstantLocalAngularAcceleration(pub AngularVector);
649
650#[cfg(feature = "3d")]
651impl ConstantLocalAngularAcceleration {
652    /// Creates a new [`ConstantLocalAngularAcceleration`] with the given `x`, `y`, and `z` components.
653    pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
654        Self(Vector::new(x, y, z))
655    }
656}
657
658/// A component with the user-applied local acceleration
659/// accumulated for a rigid body before the physics step.
660#[derive(Component, Clone, Debug, Default, PartialEq, Reflect)]
661#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
662#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
663#[reflect(Component, Debug, Default, PartialEq)]
664pub struct AccumulatedLocalAcceleration {
665    /// The accumulated linear acceleration in local space.
666    pub linear: Vector,
667    /// The accumulated angular acceleration in local space.
668    #[cfg(feature = "3d")]
669    pub angular: Vector,
670}