avian3d/dynamics/rigid_body/
sleeping.rs

1//! Components and resources for [`Sleeping`] rigid bodies to reduce CPU overhead.
2//!
3//! See the [`Sleeping`] documentation for more information.
4
5use bevy::prelude::*;
6
7/// A marker component indicating that a [`RigidBody`] is sleeping and not simulated until woken up again.
8///
9/// # What is Sleeping?
10///
11/// Simulating a large number of bodies can be expensive. To reduce CPU overhead, bodies that come to rest
12/// enter a low-cost "sleeping" state where they are not simulated until woken up again.
13///
14/// To start sleeping, the [`LinearVelocity`] and [`AngularVelocity`] of a body must remain below the [`SleepThreshold`]
15/// for a time specified by the [`TimeToSleep`] resource. All bodies that are either directly or indirectly connected
16/// to the body through contacts or joints must also be allowed to sleep.
17///
18/// A body is woken up when any of the following happens:
19///
20/// - An awake body collides with a sleeping body.
21/// - A joint is created between an awake body and a sleeping body.
22/// - A joint or contact is removed from a sleeping body.
23/// - The [`Transform`], [`LinearVelocity`], or [`AngularVelocity`] of a sleeping body is modified.
24/// - The [`RigidBody`] type of a body is changed.
25/// - A [constant force component](super::forces#constant-forces) of a sleeping body is modified.
26/// - A force, impulse, or acceleration is applied via [`Forces`], without using [`non_waking`].
27/// - The [`Gravity`] resource or [`GravityScale`] component is modified.
28///
29/// A body and all bodies connected to it can also be forced to sleep or wake up
30/// by manually adding or removing the [`Sleeping`] component, or by using
31/// the [`SleepBody`] and [`WakeBody`] commands.
32///
33/// Sleeping can be disabled for an entity by adding the [`SleepingDisabled`] component.
34///
35/// [`RigidBody`]: super::RigidBody
36/// [`LinearVelocity`]: super::LinearVelocity
37/// [`AngularVelocity`]: super::AngularVelocity
38/// [`Forces`]: super::forces::Forces
39/// [`non_waking`]: super::forces::ForcesItem::non_waking
40/// [`Gravity`]: super::Gravity
41/// [`GravityScale`]: super::GravityScale
42/// [`SleepBody`]: crate::dynamics::solver::islands::SleepBody
43/// [`WakeBody`]: crate::dynamics::solver::islands::WakeBody
44///
45/// # Implementation Details
46///
47/// Sleeping in Avian is handled using [simulation islands]. Each island is a collection of bodies
48/// that are connected through contacts or joints. An island is only allowed to sleep if all of its bodies are resting,
49/// and if any body in a sleeping island is woken up, the entire island is woken up with it.
50///
51/// The [`IslandPlugin`] is responsible for managing islands, and the [`IslandSleepingPlugin`]
52/// is responsible for island sleeping and waking.
53///
54/// [simulation islands]: crate::dynamics::solver::islands
55/// [`IslandPlugin`]: crate::dynamics::solver::islands::IslandPlugin
56/// [`IslandSleepingPlugin`]: crate::dynamics::solver::islands::IslandSleepingPlugin
57#[derive(Component, Clone, Copy, Debug, Default, PartialEq, Reflect)]
58#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
59#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
60#[reflect(Component, Debug, Default)]
61pub struct Sleeping;
62
63/// A marker component indicating that [`Sleeping`] is disabled for a [`RigidBody`].
64///
65/// [`RigidBody`]: super::RigidBody
66#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
67#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
68#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
69#[reflect(Component, Debug, Default)]
70pub struct SleepingDisabled;
71
72/// A component for the maximum [`LinearVelocity`] and [`AngularVelocity`]
73/// for a body to be allowed to be [`Sleeping`].
74///
75/// Setting a negative sleeping threshold disables sleeping entirely,
76/// similar to [`SleepingDisabled`].
77///
78/// [`LinearVelocity`]: super::LinearVelocity
79/// [`AngularVelocity`]: super::AngularVelocity
80#[derive(Component, Clone, Copy, PartialEq, PartialOrd, Debug, Reflect)]
81#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
82#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
83#[reflect(Component, Debug, PartialEq)]
84pub struct SleepThreshold {
85    /// The maximum linear velocity for the body to be allowed to be [`Sleeping`].
86    ///
87    /// This is implicitly scaled by the [`PhysicsLengthUnit`].
88    ///
89    /// Default: `0.15`
90    ///
91    /// [`PhysicsLengthUnit`]: crate::dynamics::solver::PhysicsLengthUnit
92    pub linear: f32,
93    /// The maximum angular velocity for the body to be allowed to be [`Sleeping`].
94    ///
95    /// Default: `0.15`
96    pub angular: f32,
97}
98
99/// Deprecated alias for [`SleepThreshold`].
100#[deprecated(note = "Renamed to `SleepThreshold`")]
101pub type SleepingThreshold = SleepThreshold;
102
103impl Default for SleepThreshold {
104    fn default() -> Self {
105        Self {
106            linear: 0.15,
107            angular: 0.15,
108        }
109    }
110}
111
112/// A component storing the time in seconds that a [`RigidBody`] has been resting
113/// with its [`LinearVelocity`] and [`AngularVelocity`] below the [`SleepThreshold`].
114///
115/// When this time exceeds the [`TimeToSleep`], the body is allowed to be [`Sleeping`].
116///
117/// [`RigidBody`]: super::RigidBody
118/// [`LinearVelocity`]: super::LinearVelocity
119/// [`AngularVelocity`]: super::AngularVelocity
120#[derive(Component, Clone, Copy, Debug, Default, PartialEq, Reflect)]
121#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
122#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
123#[reflect(Debug, Component, Default, PartialEq)]
124pub struct SleepTimer(pub f32);
125
126/// Deprecated alias for [`SleepTimer`].
127#[deprecated(note = "Renamed to `SleepTimer`")]
128pub type TimeSleeping = SleepTimer;
129
130/// A resource that specifies the time in seconds that a [`RigidBody`] must rest
131/// with its [`LinearVelocity`] and [`AngularVelocity`] below the [`SleepThreshold`]
132/// before it is allowed to be [`Sleeping`].
133///
134/// Default: `0.5`
135///
136/// [`RigidBody`]: super::RigidBody
137/// [`LinearVelocity`]: super::LinearVelocity
138/// [`AngularVelocity`]: super::AngularVelocity
139#[derive(Resource, Clone, Copy, Debug, PartialEq, PartialOrd, Reflect)]
140#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
141#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
142#[reflect(Debug, Default, PartialEq)]
143pub struct TimeToSleep(pub f32);
144
145/// Deprecated alias for [`TimeToSleep`].
146#[deprecated(note = "Renamed to `TimeToSleep`")]
147pub type DeactivationTime = TimeToSleep;
148
149impl Default for TimeToSleep {
150    fn default() -> Self {
151        Self(0.5)
152    }
153}