avian2d/dynamics/rigid_body/
world_query.rs1#![allow(missing_docs)]
2
3use crate::prelude::*;
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 linear_velocity: &'static mut LinearVelocity,
18 pub angular_velocity: &'static mut AngularVelocity,
19 pub mass: &'static mut ComputedMass,
20 pub angular_inertia: &'static mut ComputedAngularInertia,
21 pub center_of_mass: &'static mut ComputedCenterOfMass,
22 pub friction: Option<&'static Friction>,
23 pub restitution: Option<&'static Restitution>,
24 pub locked_axes: Option<&'static LockedAxes>,
25 pub dominance: Option<&'static Dominance>,
26 pub is_sleeping: Has<Sleeping>,
27 pub is_sensor: Has<Sensor>,
28}
29
30impl RigidBodyQueryItem<'_, '_> {
31 pub fn velocity_at_point(&self, point: Vector) -> Vector {
33 #[cfg(feature = "2d")]
34 {
35 self.linear_velocity.0 + self.angular_velocity.0 * point.perp()
36 }
37 #[cfg(feature = "3d")]
38 {
39 self.linear_velocity.0 + self.angular_velocity.cross(point)
40 }
41 }
42
43 pub fn effective_inverse_mass(&self) -> Vector {
45 if !self.rb.is_dynamic() {
46 return Vector::ZERO;
47 }
48
49 let mut inv_mass = Vector::splat(self.mass.inverse());
50
51 if let Some(locked_axes) = self.locked_axes {
52 inv_mass = locked_axes.apply_to_vec(inv_mass);
53 }
54
55 inv_mass
56 }
57
58 pub fn angular_inertia(&self) -> ComputedAngularInertia {
60 if self.rb.is_dynamic() {
61 *self.angular_inertia
62 } else {
63 ComputedAngularInertia::INFINITY
64 }
65 }
66
67 pub fn effective_global_angular_inertia(&self) -> ComputedAngularInertia {
69 if !self.rb.is_dynamic() {
70 return ComputedAngularInertia::INFINITY;
71 }
72
73 #[cfg(feature = "2d")]
74 let mut angular_inertia = *self.angular_inertia;
75 #[cfg(feature = "3d")]
76 let mut angular_inertia = self.angular_inertia.rotated(self.rotation.0);
77
78 if let Some(locked_axes) = self.locked_axes {
79 angular_inertia = locked_axes.apply_to_angular_inertia(angular_inertia);
80 }
81
82 angular_inertia
83 }
84
85 pub fn dominance(&self) -> i16 {
90 if !self.rb.is_dynamic() {
91 i8::MAX as i16 + 1
92 } else {
93 self.dominance.map_or(0, |dominance| dominance.0) as i16
94 }
95 }
96}
97
98impl RigidBodyQueryReadOnlyItem<'_, '_> {
99 pub fn velocity_at_point(&self, point: Vector) -> Vector {
101 #[cfg(feature = "2d")]
102 {
103 self.linear_velocity.0 + self.angular_velocity.0 * point.perp()
104 }
105 #[cfg(feature = "3d")]
106 {
107 self.linear_velocity.0 + self.angular_velocity.cross(point)
108 }
109 }
110
111 pub fn mass(&self) -> ComputedMass {
113 if self.rb.is_dynamic() {
114 *self.mass
115 } else {
116 ComputedMass::INFINITY
117 }
118 }
119
120 pub fn effective_inverse_mass(&self) -> Vector {
122 if !self.rb.is_dynamic() {
123 return Vector::ZERO;
124 }
125
126 let mut inv_mass = Vector::splat(self.mass.inverse());
127
128 if let Some(locked_axes) = self.locked_axes {
129 inv_mass = locked_axes.apply_to_vec(inv_mass);
130 }
131
132 inv_mass
133 }
134
135 pub fn angular_inertia(&self) -> ComputedAngularInertia {
137 if self.rb.is_dynamic() {
138 *self.angular_inertia
139 } else {
140 ComputedAngularInertia::INFINITY
141 }
142 }
143
144 pub fn effective_global_angular_inertia(&self) -> ComputedAngularInertia {
146 if !self.rb.is_dynamic() {
147 return ComputedAngularInertia::INFINITY;
148 }
149
150 #[cfg(feature = "2d")]
151 let mut angular_inertia = *self.angular_inertia;
152 #[cfg(feature = "3d")]
153 let mut angular_inertia = self.angular_inertia.rotated(self.rotation.0);
154
155 if let Some(locked_axes) = self.locked_axes {
156 angular_inertia = locked_axes.apply_to_angular_inertia(angular_inertia);
157 }
158
159 angular_inertia
160 }
161
162 pub fn dominance(&self) -> i16 {
167 if !self.rb.is_dynamic() {
168 i8::MAX as i16 + 1
169 } else {
170 self.dominance.map_or(0, |dominance| dominance.0) as i16
171 }
172 }
173}