Merge pull request #358 from dimforge/misc
Add hepler function for building a contact force event from a contact pair
This commit is contained in:
@@ -278,17 +278,6 @@ impl GenericJoint {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Are contacts between the attached rigid-bodies enabled?
|
|
||||||
pub fn contacts_enabled(&self) -> bool {
|
|
||||||
self.contacts_enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets whether contacts between the attached rigid-bodies are enabled.
|
|
||||||
pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
|
|
||||||
self.contacts_enabled = enabled;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The principal (local X) axis of this joint, expressed in the first rigid-body’s local-space.
|
/// The principal (local X) axis of this joint, expressed in the first rigid-body’s local-space.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn local_axis1(&self) -> UnitVector<Real> {
|
pub fn local_axis1(&self) -> UnitVector<Real> {
|
||||||
@@ -337,6 +326,17 @@ impl GenericJoint {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Are contacts between the attached rigid-bodies enabled?
|
||||||
|
pub fn contacts_enabled(&self) -> bool {
|
||||||
|
self.contacts_enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets whether contacts between the attached rigid-bodies are enabled.
|
||||||
|
pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
|
||||||
|
self.contacts_enabled = enabled;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// The joint limits along the specified axis.
|
/// The joint limits along the specified axis.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
|
pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
|
||||||
|
|||||||
@@ -140,6 +140,42 @@ pub struct ContactForceEvent {
|
|||||||
pub max_force_magnitude: Real,
|
pub max_force_magnitude: Real,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ContactForceEvent {
|
||||||
|
/// Init a contact force event from a contact pair.
|
||||||
|
pub fn from_contact_pair(dt: Real, pair: &ContactPair, total_force_magnitude: Real) -> Self {
|
||||||
|
let mut result = ContactForceEvent {
|
||||||
|
collider1: pair.collider1,
|
||||||
|
collider2: pair.collider2,
|
||||||
|
total_force_magnitude,
|
||||||
|
..ContactForceEvent::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
for m in &pair.manifolds {
|
||||||
|
let mut total_manifold_impulse = 0.0;
|
||||||
|
for pt in m.contacts() {
|
||||||
|
total_manifold_impulse += pt.data.impulse;
|
||||||
|
|
||||||
|
if pt.data.impulse > result.max_force_magnitude {
|
||||||
|
result.max_force_magnitude = pt.data.impulse;
|
||||||
|
result.max_force_direction = m.data.normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.total_force += m.data.normal * total_manifold_impulse;
|
||||||
|
}
|
||||||
|
|
||||||
|
let inv_dt = crate::utils::inv(dt);
|
||||||
|
// NOTE: convert impulses to forces. Note that we
|
||||||
|
// don’t need to convert the `total_force_magnitude`
|
||||||
|
// because it’s an input of this function already
|
||||||
|
// assumed to be a force instead of an impulse.
|
||||||
|
result.total_force *= inv_dt;
|
||||||
|
result.max_force_direction *= inv_dt;
|
||||||
|
result.max_force_magnitude *= inv_dt;
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) use self::broad_phase_multi_sap::SAPProxyIndex;
|
pub(crate) use self::broad_phase_multi_sap::SAPProxyIndex;
|
||||||
pub(crate) use self::narrow_phase::ContactManifoldIndex;
|
pub(crate) use self::narrow_phase::ContactManifoldIndex;
|
||||||
pub(crate) use parry::partitioning::QBVH;
|
pub(crate) use parry::partitioning::QBVH;
|
||||||
|
|||||||
@@ -124,36 +124,7 @@ impl EventHandler for ChannelEventCollector {
|
|||||||
contact_pair: &ContactPair,
|
contact_pair: &ContactPair,
|
||||||
total_force_magnitude: Real,
|
total_force_magnitude: Real,
|
||||||
) {
|
) {
|
||||||
let mut result = ContactForceEvent {
|
let result = ContactForceEvent::from_contact_pair(dt, contact_pair, total_force_magnitude);
|
||||||
collider1: contact_pair.collider1,
|
|
||||||
collider2: contact_pair.collider2,
|
|
||||||
total_force_magnitude,
|
|
||||||
..ContactForceEvent::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
for m in &contact_pair.manifolds {
|
|
||||||
let mut total_manifold_impulse = 0.0;
|
|
||||||
for pt in m.contacts() {
|
|
||||||
total_manifold_impulse += pt.data.impulse;
|
|
||||||
|
|
||||||
if pt.data.impulse > result.max_force_magnitude {
|
|
||||||
result.max_force_magnitude = pt.data.impulse;
|
|
||||||
result.max_force_direction = m.data.normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.total_force += m.data.normal * total_manifold_impulse;
|
|
||||||
}
|
|
||||||
|
|
||||||
let inv_dt = crate::utils::inv(dt);
|
|
||||||
// NOTE: convert impulses to forces. Note that we
|
|
||||||
// don’t need to convert the `total_force_magnitude`
|
|
||||||
// because it’s an input of this function already
|
|
||||||
// assumed to be a force instead of an impulse.
|
|
||||||
result.total_force *= inv_dt;
|
|
||||||
result.max_force_direction *= inv_dt;
|
|
||||||
result.max_force_magnitude *= inv_dt;
|
|
||||||
|
|
||||||
let _ = self.contact_force_event_sender.send(result);
|
let _ = self.contact_force_event_sender.send(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,16 +103,16 @@ impl QueryFilterFlags {
|
|||||||
/// A filter tha describes what collider should be included or excluded from a scene query.
|
/// A filter tha describes what collider should be included or excluded from a scene query.
|
||||||
#[derive(Copy, Clone, Default)]
|
#[derive(Copy, Clone, Default)]
|
||||||
pub struct QueryFilter<'a> {
|
pub struct QueryFilter<'a> {
|
||||||
/// Flags indicating what particular type of colliders should be exclude.
|
/// Flags indicating what particular type of colliders should be excluded from the scene query.
|
||||||
pub flags: QueryFilterFlags,
|
pub flags: QueryFilterFlags,
|
||||||
/// If set, only colliders with collision groups compatible with this one will
|
/// If set, only colliders with collision groups compatible with this one will
|
||||||
/// be included in the scene query.
|
/// be included in the scene query.
|
||||||
pub groups: Option<InteractionGroups>,
|
pub groups: Option<InteractionGroups>,
|
||||||
/// If set, this collider will be excluded by the query.
|
/// If set, this collider will be excluded from the scene query.
|
||||||
pub exclude_collider: Option<ColliderHandle>,
|
pub exclude_collider: Option<ColliderHandle>,
|
||||||
/// If set, any collider attached to this rigid-body will be exclude by the query.
|
/// If set, any collider attached to this rigid-body will be excluded from the scene query.
|
||||||
pub exclude_rigid_body: Option<RigidBodyHandle>,
|
pub exclude_rigid_body: Option<RigidBodyHandle>,
|
||||||
/// If set, any collider for which this closure returns false
|
/// If set, any collider for which this closure returns false will be excluded from the scene query.
|
||||||
pub predicate: Option<&'a dyn Fn(ColliderHandle, &Collider) -> bool>,
|
pub predicate: Option<&'a dyn Fn(ColliderHandle, &Collider) -> bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user