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