avian2d/dynamics/rigid_body/mod.rs
1//! Common components and bundles for rigid bodies.
2
3pub mod forces;
4pub mod mass_properties;
5pub mod sleeping;
6
7// Components
8mod locked_axes;
9mod physics_material;
10mod world_query;
11
12pub use locked_axes::LockedAxes;
13pub use physics_material::{
14 CoefficientCombine, DefaultFriction, DefaultRestitution, Friction, Restitution,
15};
16pub use world_query::*;
17
18#[cfg(feature = "2d")]
19pub(crate) use forces::FloatZero;
20
21use crate::{
22 physics_transform::init_physics_transform,
23 prelude::{forces::AccumulatedLocalAcceleration, *},
24};
25use bevy::{
26 ecs::{lifecycle::HookContext, world::DeferredWorld},
27 prelude::*,
28};
29use derive_more::From;
30
31/// A non-deformable body used for the simulation of most physics objects.
32///
33/// # Rigid Body Types
34///
35/// A rigid body can be either dynamic, kinematic or static.
36///
37/// - **Dynamic bodies** are similar to real life objects and are affected by forces and contacts.
38/// - **Kinematic bodies** can only be moved programmatically, which is useful for things like character controllers and moving platforms.
39/// - **Static bodies** can not move, so they can be good for objects in the environment like the ground and walls.
40///
41/// # Creation
42///
43/// Creating a rigid body is as simple as adding the [`RigidBody`] component,
44/// and an optional [`Collider`]:
45///
46/// ```
47#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
48#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
49/// use bevy::prelude::*;
50///
51/// fn setup(mut commands: Commands) {
52/// // Spawn a dynamic rigid body and specify its position.
53/// commands.spawn((
54/// RigidBody::Dynamic,
55/// Collider::capsule(0.5, 1.5),
56/// Transform::from_xyz(0.0, 3.0, 0.0),
57/// ));
58/// }
59/// ```
60///
61/// By default, dynamic rigid bodies will have mass properties computed based on the attached colliders
62/// and their [`ColliderDensity`]. See the [Mass properties](#mass-properties) section for more information.
63///
64/// # Movement
65///
66/// A rigid body can be moved in three ways: by modifying its position directly,
67/// by changing its velocity, or by applying forces or impulses.
68///
69/// To change the position of a rigid body, you can simply modify its `Transform`:
70///
71/// ```
72#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
73#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
74/// use bevy::prelude::*;
75///
76/// fn move_bodies(mut query: Query<&mut Transform, With<RigidBody>>) {
77/// for mut transform in &mut query {
78/// transform.translation.x += 0.1;
79/// }
80/// }
81/// ```
82///
83/// However, moving a dynamic body by changing its position directly is similar
84/// to teleporting the body, which can result in unexpected behavior since the body can move
85/// inside walls.
86///
87/// You can instead change the velocity of a dynamic or kinematic body with the [`LinearVelocity`]
88/// and [`AngularVelocity`] components:
89///
90/// ```
91#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
92#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
93/// use bevy::prelude::*;
94///
95/// # #[cfg(feature = "f32")]
96/// fn accelerate_bodies(
97/// mut query: Query<(&mut LinearVelocity, &mut AngularVelocity)>,
98/// time: Res<Time>,
99/// ) {
100/// let delta_secs = time.delta_secs();
101/// for (mut linear_velocity, mut angular_velocity) in &mut query {
102/// linear_velocity.x += 2.0 * delta_secs;
103#[cfg_attr(
104 feature = "2d",
105 doc = " angular_velocity.0 += 0.5 * delta_secs;"
106)]
107#[cfg_attr(
108 feature = "3d",
109 doc = " angular_velocity.z += 0.5 * delta_secs;"
110)]
111/// }
112/// }
113/// # #[cfg(feature = "f64")]
114/// # fn main() {}
115/// ```
116///
117/// For applying forces, impulses, and acceleration to dynamic bodies, see the [`forces`] module.
118///
119/// Avian does not have a built-in character controller, so if you need one,
120/// you will need to implement it yourself or use a third party option.
121/// You can take a look at the [3D Examples] for implementations of basic kinematic and dynamic character controllers.
122///
123/// [3D Examples]: https://github.com/avianphysics/avian/tree/081d2de15f526ada89bf642e3c3277c2c7784488/crates/avian3d/examples
124///
125/// # Mass Properties
126///
127/// Every dynamic rigid body has [mass], [angular inertia], and a [center of mass].
128/// These mass properties determine how the rigid body responds to forces and torques.
129///
130/// - **Mass**: Represents resistance to linear acceleration. A higher mass requires more force for the same acceleration.
131/// - **Angular Inertia**: Represents resistance to angular acceleration. A higher angular inertia requires more torque for the same angular acceleration.
132/// - **Center of Mass**: The average position of mass in the body. Applying forces at this point produces no torque.
133///
134/// Static and kinematic rigid bodies have infinite mass and angular inertia,
135/// and do not respond to forces or torques. Zero mass for a dynamic body is also
136/// treated as a special case, and corresponds to infinite mass.
137///
138/// If no mass properties are set, they are computed automatically from attached colliders
139/// based on their shape and density.
140///
141/// ```
142#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
143#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
144/// # use bevy::prelude::*;
145/// #
146/// # fn setup(mut commands: Commands) {
147/// // Note: `ColliderDensity` is optional, and defaults to `1.0` if not present.
148/// commands.spawn((
149/// RigidBody::Dynamic,
150/// Collider::capsule(0.5, 1.5),
151/// ColliderDensity(2.0),
152/// ));
153/// # }
154/// ```
155///
156/// If mass properties are set with the [`Mass`], [`AngularInertia`], and [`CenterOfMass`] components,
157/// they override the values computed from colliders.
158///
159/// ```
160#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
161#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
162/// # use bevy::prelude::*;
163/// #
164/// # fn setup(mut commands: Commands) {
165/// // Override mass and the center of mass, but use the collider's angular inertia.
166/// commands.spawn((
167/// RigidBody::Dynamic,
168/// Collider::capsule(0.5, 1.5),
169/// Mass(5.0),
170#[cfg_attr(feature = "2d", doc = " CenterOfMass::new(0.0, -0.5),")]
171#[cfg_attr(feature = "3d", doc = " CenterOfMass::new(0.0, -0.5, 0.0),")]
172/// ));
173/// # }
174/// ```
175///
176/// If the rigid body has child colliders, their mass properties will be combined for
177/// the total [`ComputedMass`], [`ComputedAngularInertia`], and [`ComputedCenterOfMass`].
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/// # fn setup(mut commands: Commands) {
185/// // Total mass: 10.0 + 5.0 = 15.0
186#[cfg_attr(
187 feature = "2d",
188 doc = "// Total center of mass: (10.0 * [0.0, -0.5] + 5.0 * [0.0, 4.0]) / (10.0 + 5.0) = [0.0, 1.0]"
189)]
190#[cfg_attr(
191 feature = "3d",
192 doc = "// Total center of mass: (10.0 * [0.0, -0.5, 0.0] + 5.0 * [0.0, 4.0, 0.0]) / (10.0 + 5.0) = [0.0, 1.0, 0.0]"
193)]
194/// commands.spawn((
195/// RigidBody::Dynamic,
196/// Collider::capsule(0.5, 1.5),
197/// Mass(10.0),
198#[cfg_attr(feature = "2d", doc = " CenterOfMass::new(0.0, -0.5),")]
199#[cfg_attr(feature = "3d", doc = " CenterOfMass::new(0.0, -0.5, 0.0),")]
200/// Transform::default(),
201/// ))
202/// .with_child((
203#[cfg_attr(feature = "2d", doc = " Collider::circle(1.0),")]
204#[cfg_attr(feature = "3d", doc = " Collider::sphere(1.0),")]
205/// Mass(5.0),
206/// Transform::from_xyz(0.0, 4.0, 0.0),
207/// ));
208/// # }
209/// ```
210///
211/// To prevent child entities from contributing to the total mass properties, use the [`NoAutoMass`],
212/// [`NoAutoAngularInertia`], and [`NoAutoCenterOfMass`] marker components.
213///
214/// ```
215#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
216#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
217/// # use bevy::prelude::*;
218/// #
219/// # fn setup(mut commands: Commands) {
220/// // Total mass: 10.0
221#[cfg_attr(feature = "2d", doc = "// Total center of mass: [0.0, -0.5]")]
222#[cfg_attr(feature = "3d", doc = "// Total center of mass: [0.0, -0.5, 0.0]")]
223/// commands.spawn((
224/// RigidBody::Dynamic,
225/// Collider::capsule(0.5, 1.5),
226/// Mass(10.0),
227#[cfg_attr(feature = "2d", doc = " CenterOfMass::new(0.0, -0.5),")]
228#[cfg_attr(feature = "3d", doc = " CenterOfMass::new(0.0, -0.5, 0.0),")]
229/// NoAutoMass,
230/// NoAutoCenterOfMass,
231/// Transform::default(),
232/// ))
233/// .with_child((
234#[cfg_attr(feature = "2d", doc = " Collider::circle(1.0),")]
235#[cfg_attr(feature = "3d", doc = " Collider::sphere(1.0),")]
236/// Mass(5.0),
237/// Transform::from_xyz(0.0, 4.0, 0.0),
238/// ));
239/// # }
240/// ```
241///
242/// See the [`mass_properties`] module for more information.
243///
244/// [mass]: mass_properties::components::Mass
245/// [angular inertia]: mass_properties::components::AngularInertia
246/// [center of mass]: mass_properties::components::CenterOfMass
247/// [mass properties]: mass_properties
248///
249/// # See More
250///
251/// - [Colliders](Collider)
252/// - [Gravity] and [gravity scale](GravityScale)
253/// - [Linear](LinearDamping) and [angular](AngularDamping) velocity damping
254/// - [Friction] and [restitution](Restitution) (bounciness)
255/// - [Lock translational and rotational axes](LockedAxes)
256/// - [Dominance]
257/// - [Continuous Collision Detection](dynamics::ccd)
258/// - [Speculative collision](dynamics::ccd#speculative-collision)
259/// - [Swept CCD](dynamics::ccd#swept-ccd)
260/// - [`Transform` interpolation and extrapolation](PhysicsInterpolationPlugin)
261/// - [Temporarily disabling a rigid body](RigidBodyDisabled)
262/// - [Automatic deactivation with sleeping](Sleeping)
263#[derive(Reflect, Clone, Copy, Component, Debug, Default, PartialEq, Eq)]
264#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
265#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
266#[reflect(Debug, Component, Default, PartialEq)]
267#[require(
268 // TODO: Only dynamic and kinematic bodies need velocity,
269 // and only dynamic bodies need mass and angular inertia.
270 Position::PLACEHOLDER,
271 Rotation::PLACEHOLDER,
272 LinearVelocity,
273 AngularVelocity,
274 ComputedMass,
275 ComputedAngularInertia,
276 ComputedCenterOfMass,
277 // Required for local forces and acceleration.
278 AccumulatedLocalAcceleration,
279 // TODO: We can remove these pre-solve deltas once joints don't use XPBD.
280 PreSolveDeltaPosition,
281 PreSolveDeltaRotation,
282)]
283#[component(immutable, on_add = RigidBody::on_add)]
284pub enum RigidBody {
285 /// Dynamic bodies are bodies that are affected by forces, velocity and collisions.
286 #[default]
287 Dynamic,
288
289 /// Static bodies are not affected by any forces, collisions or velocity, and they act as if they have an infinite mass and moment of inertia.
290 /// The only way to move a static body is to manually change its position.
291 ///
292 /// Collisions with static bodies will affect dynamic bodies, but not other static bodies or kinematic bodies.
293 ///
294 /// Static bodies are typically used for things like the ground, walls and any other objects that you don't want to move.
295 Static,
296
297 /// Kinematic bodies are bodies that are not affected by any external forces or collisions.
298 /// They will realistically affect colliding dynamic bodies, but not other kinematic bodies.
299 ///
300 /// Unlike static bodies, kinematic bodies can have velocity.
301 /// The engine doesn't modify the values of a kinematic body's components,
302 /// so you have full control of them.
303 Kinematic,
304}
305
306impl RigidBody {
307 /// Checks if the rigid body is dynamic.
308 pub fn is_dynamic(&self) -> bool {
309 *self == Self::Dynamic
310 }
311
312 /// Checks if the rigid body is static.
313 pub fn is_static(&self) -> bool {
314 *self == Self::Static
315 }
316
317 /// Checks if the rigid body is kinematic.
318 pub fn is_kinematic(&self) -> bool {
319 *self == Self::Kinematic
320 }
321
322 fn on_add(mut world: DeferredWorld, ctx: HookContext) {
323 // Initialize the global physics transform for the rigid body.
324 init_physics_transform(&mut world, &ctx);
325 }
326}
327
328/// A query filter that selects rigid bodies that are neither disabled nor sleeping.
329pub(crate) type RigidBodyActiveFilter = (Without<RigidBodyDisabled>, Without<Sleeping>);
330
331/// A marker component that indicates that a [rigid body](RigidBody) is disabled
332/// and should not participate in the simulation. Disables velocity, forces, contact response,
333/// and attached joints.
334///
335/// This is useful for temporarily disabling a body without removing it from the world.
336/// To re-enable the body, simply remove this component.
337///
338/// Note that this component does *not* disable collision detection or spatial queries for colliders
339/// attached to the rigid body.
340///
341/// # Example
342///
343/// ```
344#[cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
345#[cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
346/// # use bevy::prelude::*;
347/// #
348/// #[derive(Component)]
349/// pub struct Character;
350///
351/// /// Disables physics for all rigid body characters, for example during cutscenes.
352/// fn disable_character_physics(
353/// mut commands: Commands,
354/// query: Query<Entity, (With<RigidBody>, With<Character>)>,
355/// ) {
356/// for entity in &query {
357/// commands.entity(entity).insert(RigidBodyDisabled);
358/// }
359/// }
360///
361/// /// Enables physics for all rigid body characters.
362/// fn enable_character_physics(
363/// mut commands: Commands,
364/// query: Query<Entity, (With<RigidBody>, With<Character>)>,
365/// ) {
366/// for entity in &query {
367/// commands.entity(entity).remove::<RigidBodyDisabled>();
368/// }
369/// }
370/// ```
371///
372/// # Related Components
373///
374/// - [`ColliderDisabled`]: Disables a collider.
375/// - [`JointDisabled`]: Disables a joint constraint.
376#[derive(Clone, Copy, Component, Reflect, Debug, Default)]
377#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
378#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
379#[reflect(Debug, Component, Default)]
380pub struct RigidBodyDisabled;
381
382/// The linear velocity of a [rigid body](RigidBody), typically in meters per second.
383///
384/// # Example
385///
386/// ```
387#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
388#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
389/// use bevy::prelude::*;
390///
391/// # #[cfg(feature = "f32")]
392/// fn accelerate_linear(mut query: Query<&mut LinearVelocity>, time: Res<Time>) {
393/// let delta_secs = time.delta_secs();
394/// for mut linear_velocity in &mut query {
395/// // Accelerate the entity towards +X at `2.0` units per second squared.
396/// linear_velocity.x += 2.0 * delta_secs;
397/// }
398/// }
399/// # #[cfg(feature = "f64")]
400/// # fn main() {}
401/// ```
402///
403/// # Related Components
404///
405/// - [`AngularVelocity`]: The angular velocity of a body.
406/// - [`LinearDamping`]: Reduces the linear velocity of a body over time, similar to air resistance.
407/// - [`MaxLinearSpeed`]: Clamps the linear velocity of a body.
408#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
409#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
410#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
411#[reflect(Debug, Component, Default, PartialEq)]
412pub struct LinearVelocity(pub Vector);
413
414impl LinearVelocity {
415 /// Zero linear velocity.
416 pub const ZERO: LinearVelocity = LinearVelocity(Vector::ZERO);
417}
418
419/// The maximum linear speed of a [rigid body](RigidBody), clamping the [`LinearVelocity`],
420/// typically in meters per second.
421///
422/// This can be useful for limiting how fast bodies can move, and can help control behavior and prevent instability.
423///
424/// # Example
425///
426/// ```
427#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
428#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
429/// use bevy::prelude::*;
430///
431/// // Spawn a dynamic body with linear velocity clamped to `100.0` units per second.
432/// fn setup(mut commands: Commands) {
433/// commands.spawn((RigidBody::Dynamic, MaxLinearSpeed(100.0)));
434/// }
435/// ```
436#[derive(Reflect, Clone, Copy, Component, Debug, Deref, DerefMut, PartialEq, From)]
437#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
438#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
439#[reflect(Debug, Component, Default, PartialEq)]
440#[doc(alias = "MaxLinearVelocity")]
441pub struct MaxLinearSpeed(pub Scalar);
442
443impl Default for MaxLinearSpeed {
444 fn default() -> Self {
445 Self(Scalar::INFINITY)
446 }
447}
448
449/// The maximum angular speed of a [rigid body](RigidBody), clamping the [`AngularVelocity`],
450/// in radians per second.
451///
452/// This can be useful for limiting how fast bodies can rotate, and can help control behavior and prevent instability.
453///
454/// # Example
455///
456/// ```
457#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
458#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
459/// use bevy::prelude::*;
460///
461/// // Spawn a dynamic body with angular velocity clamped to `20.0` radians per second.
462/// fn setup(mut commands: Commands) {
463/// commands.spawn((RigidBody::Dynamic, MaxAngularSpeed(20.0)));
464/// }
465/// ```
466#[derive(Reflect, Clone, Copy, Component, Debug, Deref, DerefMut, PartialEq, From)]
467#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
468#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
469#[reflect(Debug, Component, Default, PartialEq)]
470#[doc(alias = "MaxAngularVelocity")]
471pub struct MaxAngularSpeed(pub Scalar);
472
473impl Default for MaxAngularSpeed {
474 fn default() -> Self {
475 Self(Scalar::INFINITY)
476 }
477}
478
479/// The angular velocity of a [rigid body](RigidBody) in radians per second.
480/// Positive values will result in counterclockwise rotation.
481///
482/// # Example
483///
484/// ```
485/// use avian2d::prelude::*;
486/// use bevy::prelude::*;
487///
488/// # #[cfg(feature = "f32")]
489/// fn accelerate_angular(mut query: Query<&mut AngularVelocity>, time: Res<Time>) {
490/// let delta_secs = time.delta_secs();
491/// for mut angular_velocity in &mut query {
492/// // Accelerate rotation counterclockwise at `0.5` radians per second squared.
493/// angular_velocity.0 += 0.5 * delta_secs;
494/// }
495/// }
496/// # #[cfg(feature = "f64")]
497/// # fn main() {}
498/// ```
499///
500/// # Related Components
501///
502/// - [`LinearVelocity`]: The linear velocity of a body.
503/// - [`AngularDamping`]: Reduces the angular velocity of a body over time, similar to air resistance.
504/// - [`MaxAngularSpeed`]: Clamps the angular velocity of a body.
505#[cfg(feature = "2d")]
506#[derive(Reflect, Clone, Copy, Deref, DerefMut, Component, Debug, Default, PartialEq, From)]
507#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
508#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
509#[reflect(Debug, Component, Default, PartialEq)]
510pub struct AngularVelocity(pub Scalar);
511
512/// The angular velocity of a [rigid body](RigidBody), represented as a rotation axis
513/// multiplied by the angular speed in radians per second.
514///
515/// # Example
516///
517/// ```
518/// use avian3d::prelude::*;
519/// use bevy::prelude::*;
520///
521/// # #[cfg(feature = "f32")]
522/// fn accelerate_angular(mut query: Query<&mut AngularVelocity>, time: Res<Time>) {
523/// let delta_secs = time.delta_secs();
524/// for mut angular_velocity in &mut query {
525/// // Accelerate rotation about the Z axis at `0.5` radians per second squared.
526/// angular_velocity.z += 0.5 * delta_secs;
527/// }
528/// }
529/// # #[cfg(feature = "f64")]
530/// # fn main() {}
531/// ```
532///
533/// # Related Components
534///
535/// - [`LinearVelocity`]: The linear velocity of a body.
536/// - [`AngularDamping`]: Reduces the angular velocity of a body over time, similar to air resistance.
537/// - [`MaxAngularSpeed`]: Clamps the angular velocity of a body.
538#[cfg(feature = "3d")]
539#[derive(Reflect, Clone, Copy, Component, Debug, Default, Deref, DerefMut, PartialEq, From)]
540#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
541#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
542#[reflect(Debug, Component, Default, PartialEq)]
543pub struct AngularVelocity(pub Vector);
544
545impl AngularVelocity {
546 /// Zero angular velocity.
547 #[cfg(feature = "2d")]
548 pub const ZERO: AngularVelocity = AngularVelocity(0.0);
549 /// Zero angular velocity.
550 #[cfg(feature = "3d")]
551 pub const ZERO: AngularVelocity = AngularVelocity(Vector::ZERO);
552}
553
554/// Controls how [gravity](Gravity) affects a specific [rigid body](RigidBody).
555///
556/// A gravity scale of `0.0` will disable gravity, while `2.0` will double the gravity.
557/// Using a negative value will flip the direction of the gravity.
558///
559/// # Example
560///
561/// ```
562#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
563#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
564/// use bevy::prelude::*;
565///
566/// // Spawn a dynamic body with `1.5` times the normal gravity.
567/// fn setup(mut commands: Commands) {
568/// commands.spawn((RigidBody::Dynamic, GravityScale(1.5)));
569/// }
570/// ```
571#[derive(Component, Reflect, Debug, Clone, Copy, PartialEq, PartialOrd, Deref, DerefMut, From)]
572#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
573#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
574#[reflect(Debug, Component, Default, PartialEq)]
575pub struct GravityScale(pub Scalar);
576
577impl Default for GravityScale {
578 fn default() -> Self {
579 Self(1.0)
580 }
581}
582
583/// Automatically slows down a dynamic [rigid body](RigidBody), decreasing its
584/// [linear velocity](LinearVelocity) each frame. This can be used to simulate air resistance.
585///
586/// The default linear damping coefficient is `0.0`, which corresponds to no damping.
587///
588/// # Example
589///
590/// ```
591#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
592#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
593/// use bevy::prelude::*;
594///
595/// fn setup(mut commands: Commands) {
596/// commands.spawn((RigidBody::Dynamic, LinearDamping(0.8)));
597/// }
598/// ```
599#[derive(
600 Component, Reflect, Debug, Clone, Copy, PartialEq, PartialOrd, Default, Deref, DerefMut, From,
601)]
602#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
603#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
604#[reflect(Debug, Component, Default, PartialEq)]
605pub struct LinearDamping(pub Scalar);
606
607/// Automatically slows down a dynamic [rigid body](RigidBody), decreasing its
608/// [angular velocity](AngularVelocity) each frame. This can be used to simulate air resistance.
609///
610/// The default angular damping coefficient is `0.0`, which corresponds to no damping.
611///
612/// # Example
613///
614/// ```
615#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
616#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
617/// use bevy::prelude::*;
618///
619/// fn setup(mut commands: Commands) {
620/// commands.spawn((RigidBody::Dynamic, AngularDamping(1.6)));
621/// }
622/// ```
623#[derive(
624 Component, Reflect, Debug, Clone, Copy, PartialEq, PartialOrd, Default, Deref, DerefMut, From,
625)]
626#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
627#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
628#[reflect(Debug, Component, Default, PartialEq)]
629pub struct AngularDamping(pub Scalar);
630
631/// **Dominance** allows [dynamic rigid bodies](RigidBody::Dynamic) to dominate
632/// each other during physical interactions.
633///
634/// The body with a higher dominance acts as if it had infinite mass, and will be unaffected during
635/// collisions and other interactions, while the other body will be affected normally.
636///
637/// The dominance must be between `-127` and `127`, and the default value is `0`.
638/// Note that static and kinematic bodies will always have a higher dominance value
639/// than dynamic bodies regardless of the value of this component.
640///
641/// # Example
642///
643/// ```
644#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
645#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
646/// use bevy::prelude::*;
647///
648/// // Player dominates all dynamic bodies with a dominance lower than `5`.
649/// fn spawn_player(mut commands: Commands) {
650/// commands.spawn((
651/// RigidBody::Dynamic,
652/// Collider::capsule(0.4, 1.0),
653/// Dominance(5),
654/// ));
655/// }
656/// ```
657#[rustfmt::skip]
658#[derive(Component, Reflect, Debug, Clone, Copy, Default, Deref, DerefMut, From, PartialEq, PartialOrd, Eq, Ord)]
659#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
660#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
661#[reflect(Debug, Component, Default, PartialEq)]
662pub struct Dominance(pub i8);