use crate::dynamics::{BodyPair, RigidBodyHandle};
use crate::geometry::{ColliderPair, ContactManifold};
use crate::math::{Point, Real, Vector};
use parry::query::ContactManifoldsWorkspace;
bitflags::bitflags! {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct SolverFlags: u32 {
const COMPUTE_IMPULSES = 0b01;
}
}
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct ContactData {
pub impulse: Real,
#[cfg(feature = "dim2")]
pub tangent_impulse: Real,
#[cfg(feature = "dim3")]
pub tangent_impulse: [Real; 2],
}
impl ContactData {
#[cfg(feature = "dim2")]
pub(crate) fn zero_tangent_impulse() -> Real {
0.0
}
#[cfg(feature = "dim3")]
pub(crate) fn zero_tangent_impulse() -> [Real; 2] {
[0.0, 0.0]
}
}
impl Default for ContactData {
fn default() -> Self {
Self {
impulse: 0.0,
tangent_impulse: Self::zero_tangent_impulse(),
}
}
}
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub struct ContactPair {
pub pair: ColliderPair,
pub manifolds: Vec<ContactManifold>,
pub has_any_active_contact: bool,
pub(crate) workspace: Option<ContactManifoldsWorkspace>,
}
impl ContactPair {
pub(crate) fn new(pair: ColliderPair) -> Self {
Self {
pair,
has_any_active_contact: false,
manifolds: Vec::new(),
workspace: None,
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct ContactManifoldData {
pub body_pair: BodyPair,
pub(crate) warmstart_multiplier: Real,
pub(crate) constraint_index: usize,
pub(crate) position_constraint_index: usize,
pub solver_flags: SolverFlags,
pub normal: Vector<Real>,
pub solver_contacts: Vec<SolverContact>,
}
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct SolverContact {
pub point: Point<Real>,
pub dist: Real,
pub friction: Real,
pub restitution: Real,
pub surface_velocity: Vector<Real>,
pub data: ContactData,
}
impl Default for ContactManifoldData {
fn default() -> Self {
Self::new(
BodyPair::new(RigidBodyHandle::invalid(), RigidBodyHandle::invalid()),
SolverFlags::empty(),
)
}
}
impl ContactManifoldData {
pub(crate) fn new(body_pair: BodyPair, solver_flags: SolverFlags) -> ContactManifoldData {
Self {
body_pair,
warmstart_multiplier: Self::min_warmstart_multiplier(),
constraint_index: 0,
position_constraint_index: 0,
solver_flags,
normal: Vector::zeros(),
solver_contacts: Vec::new(),
}
}
#[inline]
pub fn num_active_contacts(&self) -> usize {
self.solver_contacts.len()
}
pub(crate) fn min_warmstart_multiplier() -> Real {
1.0 }
}