avian3d/dynamics/rigid_body/
world_query.rs1#![allow(missing_docs)]
2
3use crate::{prelude::*, utils::get_pos_translation};
4use bevy::{
5 ecs::query::QueryData,
6 prelude::{Entity, Has, Ref},
7};
8
9#[derive(QueryData)]
11#[query_data(mutable)]
12pub struct RigidBodyQuery {
13 pub entity: Entity,
14 pub rb: Ref<'static, RigidBody>,
15 pub position: &'static mut Position,
16 pub rotation: &'static mut Rotation,
17 pub previous_rotation: &'static mut PreviousRotation,
18 pub accumulated_translation: &'static mut AccumulatedTranslation,
19 pub linear_velocity: &'static mut LinearVelocity,
20 pub(crate) pre_solve_linear_velocity: &'static mut PreSolveLinearVelocity,
21 pub angular_velocity: &'static mut AngularVelocity,
22 pub(crate) pre_solve_angular_velocity: &'static mut PreSolveAngularVelocity,
23 pub mass: &'static mut ComputedMass,
24 pub angular_inertia: &'static mut ComputedAngularInertia,
25 #[cfg(feature = "3d")]
26 pub global_angular_inertia: &'static mut GlobalAngularInertia,
27 pub center_of_mass: &'static mut ComputedCenterOfMass,
28 pub friction: Option<&'static Friction>,
29 pub restitution: Option<&'static Restitution>,
30 pub locked_axes: Option<&'static LockedAxes>,
31 pub dominance: Option<&'static Dominance>,
32 pub time_sleeping: Option<&'static mut TimeSleeping>,
33 pub is_sleeping: Has<Sleeping>,
34 pub is_sensor: Has<Sensor>,
35}
36
37impl RigidBodyQueryItem<'_> {
38 pub fn velocity_at_point(&self, point: Vector) -> Vector {
40 #[cfg(feature = "2d")]
41 {
42 self.linear_velocity.0 + self.angular_velocity.0 * point.perp()
43 }
44 #[cfg(feature = "3d")]
45 {
46 self.linear_velocity.0 + self.angular_velocity.cross(point)
47 }
48 }
49
50 pub fn effective_inverse_mass(&self) -> Vector {
52 if !self.rb.is_dynamic() {
53 return Vector::ZERO;
54 }
55
56 let mut inv_mass = Vector::splat(self.mass.inverse());
57
58 if let Some(locked_axes) = self.locked_axes {
59 inv_mass = locked_axes.apply_to_vec(inv_mass);
60 }
61
62 inv_mass
63 }
64
65 pub fn angular_inertia(&self) -> ComputedAngularInertia {
67 if self.rb.is_dynamic() {
68 *self.angular_inertia
69 } else {
70 ComputedAngularInertia::INFINITY
71 }
72 }
73
74 pub fn effective_global_angular_inertia(&self) -> ComputedAngularInertia {
76 if !self.rb.is_dynamic() {
77 return ComputedAngularInertia::INFINITY;
78 }
79
80 #[cfg(feature = "2d")]
81 let mut angular_inertia = *self.angular_inertia;
82 #[cfg(feature = "3d")]
83 let mut angular_inertia = **self.global_angular_inertia;
84
85 if let Some(locked_axes) = self.locked_axes {
86 angular_inertia = locked_axes.apply_to_angular_inertia(angular_inertia);
87 }
88
89 angular_inertia
90 }
91
92 pub fn current_position(&self) -> Vector {
95 self.position.0
96 + get_pos_translation(
97 &self.accumulated_translation,
98 &self.previous_rotation,
99 &self.rotation,
100 &self.center_of_mass,
101 )
102 }
103
104 pub fn dominance(&self) -> i8 {
109 if !self.rb.is_dynamic() {
110 i8::MAX
111 } else {
112 self.dominance.map_or(0, |dominance| dominance.0)
113 }
114 }
115}
116
117impl RigidBodyQueryReadOnlyItem<'_> {
118 pub fn velocity_at_point(&self, point: Vector) -> Vector {
120 #[cfg(feature = "2d")]
121 {
122 self.linear_velocity.0 + self.angular_velocity.0 * point.perp()
123 }
124 #[cfg(feature = "3d")]
125 {
126 self.linear_velocity.0 + self.angular_velocity.cross(point)
127 }
128 }
129
130 pub fn mass(&self) -> ComputedMass {
132 if self.rb.is_dynamic() {
133 *self.mass
134 } else {
135 ComputedMass::INFINITY
136 }
137 }
138
139 pub fn effective_inverse_mass(&self) -> Vector {
141 if !self.rb.is_dynamic() {
142 return Vector::ZERO;
143 }
144
145 let mut inv_mass = Vector::splat(self.mass.inverse());
146
147 if let Some(locked_axes) = self.locked_axes {
148 inv_mass = locked_axes.apply_to_vec(inv_mass);
149 }
150
151 inv_mass
152 }
153
154 pub fn angular_inertia(&self) -> ComputedAngularInertia {
156 if self.rb.is_dynamic() {
157 *self.angular_inertia
158 } else {
159 ComputedAngularInertia::INFINITY
160 }
161 }
162
163 pub fn effective_global_angular_inertia(&self) -> ComputedAngularInertia {
165 if !self.rb.is_dynamic() {
166 return ComputedAngularInertia::INFINITY;
167 }
168
169 #[cfg(feature = "2d")]
170 let mut angular_inertia = *self.angular_inertia;
171 #[cfg(feature = "3d")]
172 let mut angular_inertia = **self.global_angular_inertia;
173
174 if let Some(locked_axes) = self.locked_axes {
175 angular_inertia = locked_axes.apply_to_angular_inertia(angular_inertia);
176 }
177
178 angular_inertia
179 }
180
181 pub fn current_position(&self) -> Vector {
184 self.position.0
185 + get_pos_translation(
186 self.accumulated_translation,
187 self.previous_rotation,
188 self.rotation,
189 self.center_of_mass,
190 )
191 }
192
193 pub fn dominance(&self) -> i8 {
198 if !self.rb.is_dynamic() {
199 i8::MAX
200 } else {
201 self.dominance.map_or(0, |dominance| dominance.0)
202 }
203 }
204}