avian3d/dynamics/rigid_body/
world_query.rs#![allow(missing_docs)]
use crate::{prelude::*, utils::get_pos_translation};
use bevy::{
ecs::query::QueryData,
prelude::{Entity, Has, Ref},
};
#[derive(QueryData)]
#[query_data(mutable)]
pub struct RigidBodyQuery {
pub entity: Entity,
pub rb: Ref<'static, RigidBody>,
pub position: &'static mut Position,
pub rotation: &'static mut Rotation,
pub previous_rotation: &'static mut PreviousRotation,
pub accumulated_translation: &'static mut AccumulatedTranslation,
pub linear_velocity: &'static mut LinearVelocity,
pub(crate) pre_solve_linear_velocity: &'static mut PreSolveLinearVelocity,
pub angular_velocity: &'static mut AngularVelocity,
pub(crate) pre_solve_angular_velocity: &'static mut PreSolveAngularVelocity,
pub mass: &'static mut ComputedMass,
pub angular_inertia: &'static mut ComputedAngularInertia,
#[cfg(feature = "3d")]
pub global_angular_inertia: &'static mut GlobalAngularInertia,
pub center_of_mass: &'static mut ComputedCenterOfMass,
pub friction: Option<&'static Friction>,
pub restitution: Option<&'static Restitution>,
pub locked_axes: Option<&'static LockedAxes>,
pub dominance: Option<&'static Dominance>,
pub time_sleeping: &'static mut TimeSleeping,
pub is_sleeping: Has<Sleeping>,
pub is_sensor: Has<Sensor>,
}
impl RigidBodyQueryItem<'_> {
pub fn velocity_at_point(&self, point: Vector) -> Vector {
#[cfg(feature = "2d")]
{
self.linear_velocity.0 + self.angular_velocity.0 * point.perp()
}
#[cfg(feature = "3d")]
{
self.linear_velocity.0 + self.angular_velocity.cross(point)
}
}
pub fn effective_inverse_mass(&self) -> Vector {
if !self.rb.is_dynamic() {
return Vector::ZERO;
}
let mut inv_mass = Vector::splat(self.mass.inverse());
if let Some(locked_axes) = self.locked_axes {
inv_mass = locked_axes.apply_to_vec(inv_mass);
}
inv_mass
}
pub fn angular_inertia(&self) -> ComputedAngularInertia {
if self.rb.is_dynamic() {
*self.angular_inertia
} else {
ComputedAngularInertia::INFINITY
}
}
pub fn effective_global_angular_inertia(&self) -> ComputedAngularInertia {
if !self.rb.is_dynamic() {
return ComputedAngularInertia::INFINITY;
}
#[cfg(feature = "2d")]
let mut angular_inertia = *self.angular_inertia;
#[cfg(feature = "3d")]
let mut angular_inertia = **self.global_angular_inertia;
if let Some(locked_axes) = self.locked_axes {
angular_inertia = locked_axes.apply_to_angular_inertia(angular_inertia);
}
angular_inertia
}
pub fn current_position(&self) -> Vector {
self.position.0
+ get_pos_translation(
&self.accumulated_translation,
&self.previous_rotation,
&self.rotation,
&self.center_of_mass,
)
}
pub fn dominance(&self) -> i8 {
if !self.rb.is_dynamic() {
i8::MAX
} else {
self.dominance.map_or(0, |dominance| dominance.0)
}
}
}
impl RigidBodyQueryReadOnlyItem<'_> {
pub fn velocity_at_point(&self, point: Vector) -> Vector {
#[cfg(feature = "2d")]
{
self.linear_velocity.0 + self.angular_velocity.0 * point.perp()
}
#[cfg(feature = "3d")]
{
self.linear_velocity.0 + self.angular_velocity.cross(point)
}
}
pub fn mass(&self) -> ComputedMass {
if self.rb.is_dynamic() {
*self.mass
} else {
ComputedMass::INFINITY
}
}
pub fn effective_inverse_mass(&self) -> Vector {
if !self.rb.is_dynamic() {
return Vector::ZERO;
}
let mut inv_mass = Vector::splat(self.mass.inverse());
if let Some(locked_axes) = self.locked_axes {
inv_mass = locked_axes.apply_to_vec(inv_mass);
}
inv_mass
}
pub fn angular_inertia(&self) -> ComputedAngularInertia {
if self.rb.is_dynamic() {
*self.angular_inertia
} else {
ComputedAngularInertia::INFINITY
}
}
pub fn effective_global_angular_inertia(&self) -> ComputedAngularInertia {
if !self.rb.is_dynamic() {
return ComputedAngularInertia::INFINITY;
}
#[cfg(feature = "2d")]
let mut angular_inertia = *self.angular_inertia;
#[cfg(feature = "3d")]
let mut angular_inertia = **self.global_angular_inertia;
if let Some(locked_axes) = self.locked_axes {
angular_inertia = locked_axes.apply_to_angular_inertia(angular_inertia);
}
angular_inertia
}
pub fn current_position(&self) -> Vector {
self.position.0
+ get_pos_translation(
self.accumulated_translation,
self.previous_rotation,
self.rotation,
self.center_of_mass,
)
}
pub fn dominance(&self) -> i8 {
if !self.rb.is_dynamic() {
i8::MAX
} else {
self.dominance.map_or(0, |dominance| dominance.0)
}
}
}