avian3d/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::{
205 Forces, ForcesItem, NonWakingForcesItem, ReadRigidBodyForces, RigidBodyForces,
206 WriteRigidBodyForces,
207};
208
209use crate::prelude::*;
210use bevy::prelude::*;
211
212#[cfg(feature = "2d")]
213pub(crate) trait FloatZero {
214 const ZERO: Self;
215}
216
217#[cfg(feature = "2d")]
218impl FloatZero for Scalar {
219 const ZERO: Self = 0.0;
220}
221
222/// A component for applying a constant force to a dynamic rigid body in world space.
223/// The unit is typically N or kg⋅m/s².
224///
225/// The force persists across time steps, and is accumulated with other forces.
226/// This can be useful for simulating constant forces like gravity, force fields, wind,
227/// or other environmental effects.
228///
229/// See the [module-level documentation](self) for more general information about forces in Avian.
230///
231/// # Example
232///
233/// ```
234#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
235#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
236/// # use bevy::prelude::*;
237/// #
238/// # fn setup(mut commands: Commands) {
239/// commands.spawn((
240/// RigidBody::Dynamic,
241/// Collider::capsule(0.5, 1.0),
242/// // Apply a constant force of 10 N in the positive Y direction.
243#[cfg_attr(feature = "2d", doc = " ConstantForce::new(0.0, 10.0),")]
244#[cfg_attr(feature = "3d", doc = " ConstantForce::new(0.0, 10.0, 0.0),")]
245/// ));
246/// # }
247/// ```
248///
249/// # Related Types
250///
251/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
252/// - [`ConstantLocalForce`]: Applies a constant force in local space.
253/// - [`ConstantTorque`]: Applies a constant torque in world space.
254/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
255/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
256#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
257#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
258#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
259#[reflect(Component, Debug, Default, PartialEq)]
260pub struct ConstantForce(pub Vector);
261
262impl ConstantForce {
263 /// Creates a new [`ConstantForce`] with the given `x` and `y` components.
264 #[cfg(feature = "2d")]
265 pub fn new(x: Scalar, y: Scalar) -> Self {
266 Self(Vector::new(x, y))
267 }
268
269 /// Creates a new [`ConstantForce`] with the given `x`, `y`, and `z` components.
270 #[cfg(feature = "3d")]
271 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
272 Self(Vector::new(x, y, z))
273 }
274}
275
276/// A component for applying a constant torque to a dynamic rigid body in world space.
277/// The unit is typically N⋅m or kg⋅m²/s².
278///
279/// The torque persists across time steps, and is accumulated with other torques.
280/// This can be useful for simulating constant torques like the torque from a motor,
281/// or other rotational effects.
282///
283/// See the [module-level documentation](self) for more general information about forces in Avian.
284///
285/// # Example
286///
287/// ```
288#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
289#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
290/// # use bevy::prelude::*;
291/// #
292/// # fn setup(mut commands: Commands) {
293/// commands.spawn((
294/// RigidBody::Dynamic,
295/// Collider::capsule(0.5, 1.0),
296/// // Apply a constant torque of 5 N⋅m in the positive Z direction.
297#[cfg_attr(feature = "2d", doc = " ConstantTorque(5.0),")]
298#[cfg_attr(feature = "3d", doc = " ConstantTorque::new(0.0, 0.0, 5.0),")]
299/// ));
300/// # }
301/// ```
302///
303/// # Related Types
304///
305/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
306#[cfg_attr(
307 feature = "3d",
308 doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
309)]
310/// - [`ConstantForce`]: Applies a constant force in world space.
311/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
312/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
313#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
314#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
315#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
316#[reflect(Component, Debug, Default, PartialEq)]
317pub struct ConstantTorque(pub AngularVector);
318
319#[cfg(feature = "3d")]
320impl ConstantTorque {
321 /// Creates a new [`ConstantTorque`] with the given `x`, `y`, and `z` components.
322 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
323 Self(Vector::new(x, y, z))
324 }
325}
326
327/// A component for applying a constant force to a dynamic rigid body in local space.
328/// The unit is typically N or kg⋅m/s².
329///
330/// The force persists across time steps, and is accumulated with other forces.
331/// This can be useful for simulating constant forces like rocket thrust,
332/// or other local force effects.
333///
334/// See the [module-level documentation](self) for more general information about forces in Avian.
335///
336/// # Example
337///
338/// ```
339#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
340#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
341/// # use bevy::prelude::*;
342/// #
343/// # fn setup(mut commands: Commands) {
344/// commands.spawn((
345/// RigidBody::Dynamic,
346/// Collider::capsule(0.5, 1.0),
347/// // Apply a constant force of 10 N in the positive Y direction in local space.
348#[cfg_attr(feature = "2d", doc = " ConstantLocalForce::new(0.0, 10.0),")]
349#[cfg_attr(feature = "3d", doc = " ConstantLocalForce::new(0.0, 10.0, 0.0),")]
350/// ));
351/// # }
352/// ```
353///
354/// # Related Types
355///
356/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
357/// - [`ConstantForce`]: Applies a constant force in world space.
358#[cfg_attr(
359 feature = "3d",
360 doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
361)]
362/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
363#[cfg_attr(
364 feature = "3d",
365 doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
366)]
367#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
368#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
369#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
370#[reflect(Component, Debug, Default, PartialEq)]
371pub struct ConstantLocalForce(pub Vector);
372
373impl ConstantLocalForce {
374 /// Creates a new [`ConstantLocalForce`] with the given `x` and `y` components.
375 #[cfg(feature = "2d")]
376 pub fn new(x: Scalar, y: Scalar) -> Self {
377 Self(Vector::new(x, y))
378 }
379
380 /// Creates a new [`ConstantLocalForce`] with the given `x`, `y`, and `z` components.
381 #[cfg(feature = "3d")]
382 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
383 Self(Vector::new(x, y, z))
384 }
385}
386
387/// A component for applying a constant torque to a dynamic rigid body in local space.
388/// The unit is typically N⋅m or kg⋅m²/s²
389///
390/// The torque persists across time steps, and is accumulated with other torques.
391/// This can be useful for simulating constant torques like torque from a motor,
392/// or other rotational effects in local space.
393///
394/// See the [module-level documentation](self) for more general information about forces in Avian.
395///
396/// # Example
397///
398/// ```
399/// # use avian3d::prelude::*;
400/// # use bevy::prelude::*;
401/// #
402/// # fn setup(mut commands: Commands) {
403/// commands.spawn((
404/// RigidBody::Dynamic,
405/// Collider::capsule(0.5, 1.0),
406/// // Apply a constant torque of 5 N⋅m in the positive Z direction in local space.
407/// ConstantLocalTorque::new(0.0, 0.0, 5.0),
408/// ));
409/// # }
410/// ```
411///
412/// # Related Types
413///
414/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
415/// - [`ConstantTorque`]: Applies a constant torque in world space.
416/// - [`ConstantLocalForce`]: Applies a constant force in local space.
417/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
418/// - [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space.
419#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
420#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
421#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
422#[reflect(Component, Debug, Default, PartialEq)]
423#[cfg(feature = "3d")]
424pub struct ConstantLocalTorque(pub AngularVector);
425
426#[cfg(feature = "3d")]
427impl ConstantLocalTorque {
428 /// Creates a new [`ConstantLocalTorque`] with the given `x`, `y`, and `z` components.
429 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
430 Self(Vector::new(x, y, z))
431 }
432}
433
434/// A component for applying a constant linear acceleration to a dynamic rigid body in world space.
435/// The unit is typically m/s².
436///
437/// The acceleration persists across time steps, and is accumulated with other accelerations.
438/// This can be useful for simulating constant accelerations like per-body gravity.
439///
440/// See the [module-level documentation](self) for more general information about forces in Avian.
441///
442/// # Example
443///
444/// ```
445#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
446#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
447/// # use bevy::prelude::*;
448/// #
449/// # fn setup(mut commands: Commands) {
450/// commands.spawn((
451/// RigidBody::Dynamic,
452/// Collider::capsule(0.5, 1.0),
453/// // Apply a constant linear acceleration of 9.81 m/s² in the negative Y direction.
454/// // This is equivalent to using the `Gravity` resource, but only for this entity.
455#[cfg_attr(
456 feature = "2d",
457 doc = " ConstantLinearAcceleration::new(0.0, -9.81),"
458)]
459#[cfg_attr(
460 feature = "3d",
461 doc = " ConstantLinearAcceleration::new(0.0, -9.81, 0.0),"
462)]
463/// ));
464/// # }
465/// ```
466///
467/// # Related Types
468///
469/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
470/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
471/// - [`ConstantForce`]: Applies a constant force in world space.
472/// - [`ConstantTorque`]: Applies a constant torque in world space.
473/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
474#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
475#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
476#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
477#[reflect(Component, Debug, Default, PartialEq)]
478pub struct ConstantLinearAcceleration(pub Vector);
479
480impl ConstantLinearAcceleration {
481 /// Creates a new [`ConstantLinearAcceleration`] with the given `x` and `y` components.
482 #[cfg(feature = "2d")]
483 pub fn new(x: Scalar, y: Scalar) -> Self {
484 Self(Vector::new(x, y))
485 }
486
487 /// Creates a new [`ConstantLinearAcceleration`] with the given `x`, `y`, and `z` components.
488 #[cfg(feature = "3d")]
489 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
490 Self(Vector::new(x, y, z))
491 }
492}
493
494/// A component for applying a constant angular acceleration to a dynamic rigid body in world space.
495/// The unit is typically rad/s².
496///
497/// The acceleration persists across time steps, and is accumulated with other accelerations.
498/// This can be useful for simulating constant angular accelerations like rotation from a motor,
499/// or other rotational effects.
500///
501/// See the [module-level documentation](self) for more general information about forces in Avian.
502///
503/// # Example
504///
505/// ```
506#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
507#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
508/// # use bevy::prelude::*;
509/// #
510/// # fn setup(mut commands: Commands) {
511/// commands.spawn((
512/// RigidBody::Dynamic,
513/// Collider::capsule(0.5, 1.0),
514/// // Apply a constant angular acceleration of 1.0 rad/s² in the positive Z direction.
515#[cfg_attr(feature = "2d", doc = " ConstantAngularAcceleration(1.0),")]
516#[cfg_attr(
517 feature = "3d",
518 doc = " ConstantAngularAcceleration::new(0.0, 0.0, 1.0),"
519)]
520/// ));
521/// # }
522/// ```
523///
524/// # Related Types
525///
526/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
527#[cfg_attr(
528 feature = "3d",
529 doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
530)]
531/// - [`ConstantForce`]: Applies a constant force in world space.
532/// - [`ConstantTorque`]: Applies a constant torque in world space.
533/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
534#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
535#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
536#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
537#[reflect(Component, Debug, Default, PartialEq)]
538pub struct ConstantAngularAcceleration(pub AngularVector);
539
540#[cfg(feature = "3d")]
541impl ConstantAngularAcceleration {
542 /// Creates a new [`ConstantAngularAcceleration`] with the given `x`, `y`, and `z` components.
543 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
544 Self(Vector::new(x, y, z))
545 }
546}
547
548/// A component for applying a constant linear acceleration to a dynamic rigid body in local space.
549/// The unit is typically m/s².
550///
551/// The acceleration persists across time steps, and is accumulated with other accelerations.
552/// This can be useful for simulating constant linear accelerations like rocket thrust,
553/// or other local acceleration effects.
554///
555/// See the [module-level documentation](self) for more general information about forces in Avian.
556///
557/// # Example
558///
559/// ```
560#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
561#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
562/// # use bevy::prelude::*;
563/// #
564/// # fn setup(mut commands: Commands) {
565/// commands.spawn((
566/// RigidBody::Dynamic,
567/// Collider::capsule(0.5, 1.0),
568/// // Apply a constant linear acceleration of 10.0 m/s² in the positive Y direction in local space.
569#[cfg_attr(
570 feature = "2d",
571 doc = " ConstantLocalLinearAcceleration::new(0.0, 10.0),"
572)]
573#[cfg_attr(
574 feature = "3d",
575 doc = " ConstantLocalLinearAcceleration::new(0.0, 10.0, 0.0),"
576)]
577/// ));
578/// # }
579/// ```
580///
581/// # Related Types
582///
583/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
584/// - [`ConstantLinearAcceleration`]: Applies a constant linear acceleration in world space.
585/// - [`ConstantLocalForce`]: Applies a constant force in local space.
586#[cfg_attr(
587 feature = "3d",
588 doc = "- [`ConstantLocalTorque`]: Applies a constant torque in local space."
589)]
590#[cfg_attr(
591 feature = "3d",
592 doc = "- [`ConstantLocalAngularAcceleration`]: Applies a constant angular acceleration in local space."
593)]
594#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
595#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
596#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
597#[reflect(Component, Debug, Default, PartialEq)]
598pub struct ConstantLocalLinearAcceleration(pub Vector);
599
600impl ConstantLocalLinearAcceleration {
601 /// Creates a new [`ConstantLocalLinearAcceleration`] with the given `x` and `y` components.
602 #[cfg(feature = "2d")]
603 pub fn new(x: Scalar, y: Scalar) -> Self {
604 Self(Vector::new(x, y))
605 }
606
607 /// Creates a new [`ConstantLocalLinearAcceleration`] with the given `x`, `y`, and `z` components.
608 #[cfg(feature = "3d")]
609 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
610 Self(Vector::new(x, y, z))
611 }
612}
613
614/// A component for applying a constant angular acceleration to a dynamic rigid body in local space.
615/// The unit is typically rad/s².
616///
617/// The acceleration persists across time steps, and is accumulated with other accelerations.
618/// This can be useful for simulating constant angular accelerations like rotation from a motor,
619/// or other rotational effects in local space.
620///
621/// See the [module-level documentation](self) for more general information about forces in Avian.
622///
623/// # Example
624///
625/// ```
626/// # use avian3d::prelude::*;
627/// # use bevy::prelude::*;
628/// #
629/// # fn setup(mut commands: Commands) {
630/// commands.spawn((
631/// RigidBody::Dynamic,
632/// Collider::capsule(0.5, 1.0),
633/// // Apply a constant angular acceleration of 1.0 rad/s² in the positive Z direction in local space.
634/// ConstantLocalAngularAcceleration::new(0.0, 0.0, 1.0),
635/// ));
636/// # }
637/// ```
638///
639/// # Related Types
640///
641/// - [`Forces`]: A helper [`QueryData`](bevy::ecs::query::QueryData) for applying forces, impulses, and acceleration to entities.
642/// - [`ConstantAngularAcceleration`]: Applies a constant angular acceleration in world space.
643/// - [`ConstantLocalForce`]: Applies a constant force in local space.
644/// - [`ConstantLocalTorque`]: Applies a constant torque in local space.
645/// - [`ConstantLocalLinearAcceleration`]: Applies a constant linear acceleration in local space.
646#[derive(Component, Clone, Debug, Default, Deref, DerefMut, PartialEq, Reflect)]
647#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
648#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
649#[reflect(Component, Debug, Default, PartialEq)]
650#[cfg(feature = "3d")]
651pub struct ConstantLocalAngularAcceleration(pub AngularVector);
652
653#[cfg(feature = "3d")]
654impl ConstantLocalAngularAcceleration {
655 /// Creates a new [`ConstantLocalAngularAcceleration`] with the given `x`, `y`, and `z` components.
656 pub fn new(x: Scalar, y: Scalar, z: Scalar) -> Self {
657 Self(Vector::new(x, y, z))
658 }
659}
660
661/// A component with the user-applied local acceleration
662/// accumulated for a rigid body before the physics step.
663#[derive(Component, Clone, Debug, Default, PartialEq, Reflect)]
664#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
665#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
666#[reflect(Component, Debug, Default, PartialEq)]
667pub struct AccumulatedLocalAcceleration {
668 /// The accumulated linear acceleration in local space.
669 pub linear: Vector,
670 /// The accumulated angular acceleration in local space.
671 #[cfg(feature = "3d")]
672 pub angular: Vector,
673}