use crate::dynamics::MassProperties;
use crate::geometry::{
Collider, ColliderHandle, ColliderSet, InteractionGraph, RigidBodyGraphIndex,
};
use crate::math::{
AngVector, AngularInertia, Isometry, Point, Real, Rotation, Translation, Vector,
};
use crate::utils::{self, WAngularInertia, WCross, WDot};
use na::ComplexField;
use num::Zero;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// The status of a body, governing the way it is affected by external forces.
pub enum BodyStatus {
/// A `BodyStatus::Dynamic` body can be affected by all external forces.
Dynamic,
/// A `BodyStatus::Static` body cannot be affected by external forces.
Static,
/// A `BodyStatus::Kinematic` body cannot be affected by any external forces but can be controlled
/// by the user at the position level while keeping realistic one-way interaction with dynamic bodies.
///
/// One-way interaction means that a kinematic body can push a dynamic body, but a kinematic body
/// cannot be pushed by anything. In other words, the trajectory of a kinematic body can only be
/// modified by the user and is independent from any contact or joint it is involved in.
Kinematic,
// Semikinematic, // A kinematic that performs automatic CCD with the static environment to avoid traversing it?
// Disabled,
}
bitflags::bitflags! {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// Flags affecting the behavior of the constraints solver for a given contact manifold.
pub(crate) struct RigidBodyFlags: u8 {
const TRANSLATION_LOCKED = 1 << 0;
const ROTATION_LOCKED_X = 1 << 1;
const ROTATION_LOCKED_Y = 1 << 2;
const ROTATION_LOCKED_Z = 1 << 3;
const CCD_ENABLED = 1 << 4;
const CCD_ACTIVE = 1 << 5;
}
}
bitflags::bitflags! {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// Flags describing how the rigid-body has been modified by the user.
pub(crate) struct RigidBodyChanges: u32 {
const MODIFIED = 1 << 0;
const POSITION = 1 << 1;
const SLEEP = 1 << 2;
const COLLIDERS = 1 << 3;
const BODY_STATUS = 1 << 4;
}
}
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// A rigid body.
///
/// To create a new rigid-body, use the `RigidBodyBuilder` structure.
#[derive(Debug, Clone)]
pub struct RigidBody {
/// The world-space position of the rigid-body.
pub(crate) position: Isometry<Real>,
/// The next position of the rigid-body.
///
/// At the beginning of the timestep, and when the
/// timestep is complete we must have position == next_position
/// except for kinematic bodies.
///
/// The next_position is updated after the velocity and position
/// resolution. Then it is either validated (ie. we set position := set_position)
/// or clamped by CCD.
pub(crate) next_position: Isometry<Real>,
/// The local mass properties of the rigid-body.
pub(crate) mass_properties: MassProperties,
/// The world-space center of mass of the rigid-body.
pub world_com: Point<Real>,
/// The inverse mass taking into account translation locking.
pub effective_inv_mass: Real,
/// The square-root of the world-space inverse angular inertia tensor of the rigid-body,
/// taking into account rotation locking.
pub effective_world_inv_inertia_sqrt: AngularInertia<Real>,
/// The linear velocity of the rigid-body.
pub(crate) linvel: Vector<Real>,
/// The angular velocity of the rigid-body.
pub(crate) angvel: AngVector<Real>,
/// Damping factor for gradually slowing down the translational motion of the rigid-body.
pub linear_damping: Real,
/// Damping factor for gradually slowing down the angular motion of the rigid-body.
pub angular_damping: Real,
/// Accumulation of external forces (only for dynamic bodies).
pub(crate) force: Vector<Real>,
/// Accumulation of external torques (only for dynamic bodies).
pub(crate) torque: AngVector<Real>,
pub(crate) colliders: Vec<ColliderHandle>,
pub(crate) gravity_scale: Real,
/// Whether or not this rigid-body is sleeping.
pub activation: ActivationStatus,
pub(crate) joint_graph_index: RigidBodyGraphIndex,
pub(crate)