aboutsummaryrefslogtreecommitdiff
path: root/src/dynamics/ccd/toi_entry.rs
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2021-04-26 17:59:25 +0200
committerCrozet Sébastien <developer@crozet.re>2021-04-26 18:00:50 +0200
commitc32da78f2a6014c491aa3e975fb83ddb7c80610e (patch)
treeedd20f23270baee1577c486f78d825eb93ea0de0 /src/dynamics/ccd/toi_entry.rs
parentaaf80bfa872c6f29b248cab8eb5658ab0d73cb4a (diff)
downloadrapier-c32da78f2a6014c491aa3e975fb83ddb7c80610e.tar.gz
rapier-c32da78f2a6014c491aa3e975fb83ddb7c80610e.tar.bz2
rapier-c32da78f2a6014c491aa3e975fb83ddb7c80610e.zip
Split rigid-bodies and colliders into multiple components
Diffstat (limited to 'src/dynamics/ccd/toi_entry.rs')
-rw-r--r--src/dynamics/ccd/toi_entry.rs112
1 files changed, 77 insertions, 35 deletions
diff --git a/src/dynamics/ccd/toi_entry.rs b/src/dynamics/ccd/toi_entry.rs
index f1066e0..4637940 100644
--- a/src/dynamics/ccd/toi_entry.rs
+++ b/src/dynamics/ccd/toi_entry.rs
@@ -1,5 +1,9 @@
-use crate::dynamics::{RigidBody, RigidBodyHandle};
-use crate::geometry::{Collider, ColliderHandle};
+use crate::dynamics::{
+ RigidBodyCcd, RigidBodyHandle, RigidBodyMassProps, RigidBodyPosition, RigidBodyVelocity,
+};
+use crate::geometry::{
+ ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, ColliderType,
+};
use crate::math::Real;
use parry::query::{NonlinearRigidMotion, QueryDispatcher};
@@ -7,9 +11,9 @@ use parry::query::{NonlinearRigidMotion, QueryDispatcher};
pub struct TOIEntry {
pub toi: Real,
pub c1: ColliderHandle,
- pub b1: RigidBodyHandle,
+ pub b1: Option<RigidBodyHandle>,
pub c2: ColliderHandle,
- pub b2: RigidBodyHandle,
+ pub b2: Option<RigidBodyHandle>,
pub is_intersection_test: bool,
pub timestamp: usize,
}
@@ -18,9 +22,9 @@ impl TOIEntry {
fn new(
toi: Real,
c1: ColliderHandle,
- b1: RigidBodyHandle,
+ b1: Option<RigidBodyHandle>,
c2: ColliderHandle,
- b2: RigidBodyHandle,
+ b2: Option<RigidBodyHandle>,
is_intersection_test: bool,
timestamp: usize,
) -> Self {
@@ -39,10 +43,30 @@ impl TOIEntry {
query_dispatcher: &QD,
ch1: ColliderHandle,
ch2: ColliderHandle,
- c1: &Collider,
- c2: &Collider,
- b1: &RigidBody,
- b2: &RigidBody,
+ c1: (
+ &ColliderType,
+ &ColliderShape,
+ &ColliderPosition,
+ Option<&ColliderParent>,
+ ),
+ c2: (
+ &ColliderType,
+ &ColliderShape,
+ &ColliderPosition,
+ Option<&ColliderParent>,
+ ),
+ b1: Option<(
+ &RigidBodyPosition,
+ &RigidBodyVelocity,
+ &RigidBodyMassProps,
+ &RigidBodyCcd,
+ )>,
+ b2: Option<(
+ &RigidBodyPosition,
+ &RigidBodyVelocity,
+ &RigidBodyMassProps,
+ &RigidBodyCcd,
+ )>,
frozen1: Option<Real>,
frozen2: Option<Real>,
start_time: Real,
@@ -50,35 +74,46 @@ impl TOIEntry {
smallest_contact_dist: Real,
) -> Option<Self> {
assert!(start_time <= end_time);
+ if b1.is_none() && b2.is_none() {
+ return None;
+ }
+
+ let (co_type1, co_shape1, co_pos1, co_parent1) = c1;
+ let (co_type2, co_shape2, co_pos2, co_parent2) = c2;
- let linvel1 = frozen1.is_none() as u32 as Real * b1.linvel();
- let linvel2 = frozen2.is_none() as u32 as Real * b2.linvel();
- let angvel1 = frozen1.is_none() as u32 as Real * b1.angvel();
- let angvel2 = frozen2.is_none() as u32 as Real * b2.angvel();
+ let linvel1 =
+ frozen1.is_none() as u32 as Real * b1.map(|b| b.1.linvel).unwrap_or(na::zero());
+ let linvel2 =
+ frozen2.is_none() as u32 as Real * b2.map(|b| b.1.linvel).unwrap_or(na::zero());
+ let angvel1 =
+ frozen1.is_none() as u32 as Real * b1.map(|b| b.1.angvel).unwrap_or(na::zero());
+ let angvel2 =
+ frozen2.is_none() as u32 as Real * b2.map(|b| b.1.angvel).unwrap_or(na::zero());
#[cfg(feature = "dim2")]
let vel12 = (linvel2 - linvel1).norm()
- + angvel1.abs() * b1.ccd_max_dist
- + angvel2.abs() * b2.ccd_max_dist;
+ + angvel1.abs() * b1.map(|b| b.3.ccd_max_dist).unwrap_or(0.0)
+ + angvel2.abs() * b2.map(|b| b.3.ccd_max_dist).unwrap_or(0.0);
#[cfg(feature = "dim3")]
let vel12 = (linvel2 - linvel1).norm()
- + angvel1.norm() * b1.ccd_max_dist
- + angvel2.norm() * b2.ccd_max_dist;
+ + angvel1.norm() * b1.map(|b| b.3.ccd_max_dist).unwrap_or(0.0)
+ + angvel2.norm() * b2.map(|b| b.3.ccd_max_dist).unwrap_or(0.0);
// We may be slightly over-conservative by taking the `max(0.0)` here.
// But removing the `max` doesn't really affect performances so let's
// keep it since more conservatism is good at this stage.
- let thickness = (c1.shape().ccd_thickness() + c2.shape().ccd_thickness())
+ let thickness = (co_shape1.0.ccd_thickness() + co_shape2.0.ccd_thickness())
+ smallest_contact_dist.max(0.0);
- let is_intersection_test = c1.is_sensor() || c2.is_sensor();
+ let is_intersection_test = co_type1.is_sensor() || co_type2.is_sensor();
if (end_time - start_time) * vel12 < thickness {
return None;
}
// Compute the TOI.
- let mut motion1 = Self::body_motion(b1);
- let mut motion2 = Self::body_motion(b2);
+ let identity = NonlinearRigidMotion::identity();
+ let mut motion1 = b1.map(Self::body_motion).unwrap_or(identity);
+ let mut motion2 = b2.map(Self::body_motion).unwrap_or(identity);
if let Some(t) = frozen1 {
motion1.freeze(t);
@@ -88,8 +123,8 @@ impl TOIEntry {
motion2.freeze(t);
}
- let motion_c1 = motion1.prepend(*c1.position_wrt_parent());
- let motion_c2 = motion2.prepend(*c2.position_wrt_parent());
+ let motion_c1 = motion1.prepend(co_parent1.map(|p| p.pos_wrt_parent).unwrap_or(co_pos1.0));
+ let motion_c2 = motion2.prepend(co_parent2.map(|p| p.pos_wrt_parent).unwrap_or(co_pos2.0));
// println!("start_time: {}", start_time);
@@ -105,9 +140,9 @@ impl TOIEntry {
let res_toi = query_dispatcher
.nonlinear_time_of_impact(
&motion_c1,
- c1.shape(),
+ co_shape1.as_ref(),
&motion_c2,
- c2.shape(),
+ co_shape2.as_ref(),
start_time,
end_time,
stop_at_penetration,
@@ -119,24 +154,31 @@ impl TOIEntry {
Some(Self::new(
toi.toi,
ch1,
- c1.parent(),
+ co_parent1.map(|p| p.handle),
ch2,
- c2.parent(),
+ co_parent2.map(|p| p.handle),
is_intersection_test,
0,
))
}
- fn body_motion(body: &RigidBody) -> NonlinearRigidMotion {
- if body.is_ccd_active() {
+ fn body_motion(
+ (poss, vels, mprops, ccd): (
+ &RigidBodyPosition,
+ &RigidBodyVelocity,
+ &RigidBodyMassProps,
+ &RigidBodyCcd,
+ ),
+ ) -> NonlinearRigidMotion {
+ if ccd.ccd_active {
NonlinearRigidMotion::new(
- body.position,
- body.mass_properties.local_com,
- body.linvel,
- body.angvel,
+ poss.position,
+ mprops.mass_properties.local_com,
+ vels.linvel,
+ vels.angvel,
)
} else {
- NonlinearRigidMotion::constant_position(body.next_position)
+ NonlinearRigidMotion::constant_position(poss.next_position)
}
}
}