diff options
| author | Sébastien Crozet <developer@crozet.re> | 2020-09-01 14:02:59 +0200 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2020-09-01 14:02:59 +0200 |
| commit | 9622827dc6aadb391512b95381edb1efc26b1b90 (patch) | |
| tree | 3b15362d6f7736f8d30bc78b6e33ff51c893751f /src | |
| parent | 03b437f278bbcbd391acd23a4d8fa074915eb00c (diff) | |
| download | rapier-9622827dc6aadb391512b95381edb1efc26b1b90.tar.gz rapier-9622827dc6aadb391512b95381edb1efc26b1b90.tar.bz2 rapier-9622827dc6aadb391512b95381edb1efc26b1b90.zip | |
Fix constraints resolution with non-identity relative collider position.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynamics/solver/position_constraint.rs | 4 | ||||
| -rw-r--r-- | src/dynamics/solver/position_constraint_wide.rs | 7 | ||||
| -rw-r--r-- | src/dynamics/solver/position_ground_constraint.rs | 28 | ||||
| -rw-r--r-- | src/dynamics/solver/position_ground_constraint_wide.rs | 16 | ||||
| -rw-r--r-- | src/dynamics/solver/velocity_constraint.rs | 8 | ||||
| -rw-r--r-- | src/dynamics/solver/velocity_constraint_wide.rs | 18 | ||||
| -rw-r--r-- | src/dynamics/solver/velocity_ground_constraint.rs | 28 | ||||
| -rw-r--r-- | src/dynamics/solver/velocity_ground_constraint_wide.rs | 20 | ||||
| -rw-r--r-- | src/geometry/contact.rs | 24 | ||||
| -rw-r--r-- | src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs | 38 |
10 files changed, 117 insertions, 74 deletions
diff --git a/src/dynamics/solver/position_constraint.rs b/src/dynamics/solver/position_constraint.rs index 608a342..69fcf57 100644 --- a/src/dynamics/solver/position_constraint.rs +++ b/src/dynamics/solver/position_constraint.rs @@ -104,8 +104,8 @@ impl PositionConstraint { let mut local_p2 = [Point::origin(); MAX_MANIFOLD_POINTS]; for l in 0..manifold_points.len() { - local_p1[l] = manifold_points[l].local_p1 + shift1; - local_p2[l] = manifold_points[l].local_p2 + shift2; + local_p1[l] = manifold.delta1 * (manifold_points[l].local_p1 + shift1); + local_p2[l] = manifold.delta2 * (manifold_points[l].local_p2 + shift2); } let constraint = PositionConstraint { diff --git a/src/dynamics/solver/position_constraint_wide.rs b/src/dynamics/solver/position_constraint_wide.rs index 8828c3d..0633926 100644 --- a/src/dynamics/solver/position_constraint_wide.rs +++ b/src/dynamics/solver/position_constraint_wide.rs @@ -51,6 +51,9 @@ impl WPositionConstraint { let radius1 = SimdFloat::from(array![|ii| manifolds[ii].kinematics.radius1; SIMD_WIDTH]); let radius2 = SimdFloat::from(array![|ii| manifolds[ii].kinematics.radius2; SIMD_WIDTH]); + let delta1 = Isometry::from(array![|ii| manifolds[ii].delta1; SIMD_WIDTH]); + let delta2 = Isometry::from(array![|ii| manifolds[ii].delta2; SIMD_WIDTH]); + let rb1 = array![|ii| rbs1[ii].active_set_offset; SIMD_WIDTH]; let rb2 = array![|ii| rbs2[ii].active_set_offset; SIMD_WIDTH]; @@ -85,8 +88,8 @@ impl WPositionConstraint { let local_p2 = Point::from(array![|ii| manifold_points[ii][i].local_p2; SIMD_WIDTH]); - constraint.local_p1[i] = local_p1 + shift1; - constraint.local_p2[i] = local_p2 + shift2; + constraint.local_p1[i] = delta1 * (local_p1 + shift1); + constraint.local_p2[i] = delta2 * (local_p2 + shift2); } if push { diff --git a/src/dynamics/solver/position_ground_constraint.rs b/src/dynamics/solver/position_ground_constraint.rs index e6e83c6..dcd2d64 100644 --- a/src/dynamics/solver/position_ground_constraint.rs +++ b/src/dynamics/solver/position_ground_constraint.rs @@ -34,22 +34,30 @@ impl PositionGroundConstraint { let local_n1; let local_n2; + let delta1; + let delta2; if flip { std::mem::swap(&mut rb1, &mut rb2); local_n1 = manifold.local_n2; local_n2 = manifold.local_n1; + delta1 = &manifold.delta2; + delta2 = &manifold.delta1; } else { local_n1 = manifold.local_n1; local_n2 = manifold.local_n2; + delta1 = &manifold.delta1; + delta2 = &manifold.delta2; }; + let coll_pos1 = rb1.position * delta1; let shift1 = local_n1 * -manifold.kinematics.radius1; let shift2 = local_n2 * -manifold.kinematics.radius2; + let n1 = coll_pos1 * local_n1; let radius = manifold.kinematics.radius1 + manifold.kinematics.radius2 /* - params.allowed_linear_error */; - for (l, manifold_points) in manifold + for (l, manifold_contacts) in manifold .active_contacts() .chunks(MAX_MANIFOLD_POINTS) .enumerate() @@ -59,16 +67,16 @@ impl PositionGroundConstraint { if flip { // Don't forget that we already swapped rb1 and rb2 above. - // So if we flip, only manifold_points[k].{local_p1,local_p2} have to + // So if we flip, only manifold_contacts[k].{local_p1,local_p2} have to // be swapped. - for k in 0..manifold_points.len() { - p1[k] = rb1.predicted_position * (manifold_points[k].local_p2 + shift1); - local_p2[k] = manifold_points[k].local_p1 + shift2; + for k in 0..manifold_contacts.len() { + p1[k] = coll_pos1 * (manifold_contacts[k].local_p2 + shift1); + local_p2[k] = delta2 * (manifold_contacts[k].local_p1 + shift2); } } else { - for k in 0..manifold_points.len() { - p1[k] = rb1.predicted_position * (manifold_points[k].local_p1 + shift1); - local_p2[k] = manifold_points[k].local_p2 + shift2; + for k in 0..manifold_contacts.len() { + p1[k] = coll_pos1 * (manifold_contacts[k].local_p1 + shift1); + local_p2[k] = delta2 * (manifold_contacts[k].local_p2 + shift2); } } @@ -76,11 +84,11 @@ impl PositionGroundConstraint { rb2: rb2.active_set_offset, p1, local_p2, - n1: rb1.predicted_position * local_n1, + n1, radius, im2: rb2.mass_properties.inv_mass, ii2: rb2.world_inv_inertia_sqrt.squared(), - num_contacts: manifold_points.len() as u8, + num_contacts: manifold_contacts.len() as u8, erp: params.erp, max_linear_correction: params.max_linear_correction, }; diff --git a/src/dynamics/solver/position_ground_constraint_wide.rs b/src/dynamics/solver/position_ground_constraint_wide.rs index faa928b..e423c0a 100644 --- a/src/dynamics/solver/position_ground_constraint_wide.rs +++ b/src/dynamics/solver/position_ground_constraint_wide.rs @@ -54,16 +54,24 @@ impl WPositionGroundConstraint { array![|ii| if flipped[ii] { manifolds[ii].local_n1 } else { manifolds[ii].local_n2 }; SIMD_WIDTH], ); + let delta1 = Isometry::from( + array![|ii| if flipped[ii] { manifolds[ii].delta2 } else { manifolds[ii].delta1 }; SIMD_WIDTH], + ); + let delta2 = Isometry::from( + array![|ii| if flipped[ii] { manifolds[ii].delta1 } else { manifolds[ii].delta2 }; SIMD_WIDTH], + ); + let radius1 = SimdFloat::from(array![|ii| manifolds[ii].kinematics.radius1; SIMD_WIDTH]); let radius2 = SimdFloat::from(array![|ii| manifolds[ii].kinematics.radius2; SIMD_WIDTH]); - let position1 = Isometry::from(array![|ii| rbs1[ii].predicted_position; SIMD_WIDTH]); + let coll_pos1 = + delta1 * Isometry::from(array![|ii| rbs1[ii].predicted_position; SIMD_WIDTH]); let rb2 = array![|ii| rbs2[ii].active_set_offset; SIMD_WIDTH]; let radius = radius1 + radius2 /*- SimdFloat::splat(params.allowed_linear_error)*/; - let n1 = position1 * local_n1; + let n1 = coll_pos1 * local_n1; for l in (0..manifolds[0].num_active_contacts()).step_by(MAX_MANIFOLD_POINTS) { let manifold_points = array![|ii| &manifolds[ii].active_contacts()[l..]; SIMD_WIDTH]; @@ -90,8 +98,8 @@ impl WPositionGroundConstraint { array![|ii| if flipped[ii] { manifold_points[ii][i].local_p1 } else { manifold_points[ii][i].local_p2 }; SIMD_WIDTH], ); - constraint.p1[i] = position1 * local_p1 - n1 * radius1; - constraint.local_p2[i] = local_p2 - local_n2 * radius2; + constraint.p1[i] = coll_pos1 * local_p1 - n1 * radius1; + constraint.local_p2[i] = delta2 * (local_p2 - local_n2 * radius2); } if push { diff --git a/src/dynamics/solver/velocity_constraint.rs b/src/dynamics/solver/velocity_constraint.rs index eb80018..190076d 100644 --- a/src/dynamics/solver/velocity_constraint.rs +++ b/src/dynamics/solver/velocity_constraint.rs @@ -148,7 +148,9 @@ impl VelocityConstraint { let rb2 = &bodies[manifold.body_pair.body2]; let mj_lambda1 = rb1.active_set_offset; let mj_lambda2 = rb2.active_set_offset; - let force_dir1 = rb1.position * (-manifold.local_n1); + let pos_coll1 = rb1.position * manifold.delta1; + let pos_coll2 = rb2.position * manifold.delta2; + let force_dir1 = pos_coll1 * (-manifold.local_n1); let warmstart_coeff = manifold.warmstart_multiplier * params.warmstart_coeff; for (l, manifold_points) in manifold @@ -215,8 +217,8 @@ impl VelocityConstraint { for k in 0..manifold_points.len() { let manifold_point = &manifold_points[k]; - let dp1 = (rb1.position * manifold_point.local_p1) - rb1.world_com; - let dp2 = (rb2.position * manifold_point.local_p2) - rb2.world_com; + let dp1 = (pos_coll1 * manifold_point.local_p1) - rb1.world_com; + let dp2 = (pos_coll2 * manifold_point.local_p2) - rb2.world_com; let vel1 = rb1.linvel + rb1.angvel.gcross(dp1); let vel2 = rb2.linvel + rb2.angvel.gcross(dp2); diff --git a/src/dynamics/solver/velocity_constraint_wide.rs b/src/dynamics/solver/velocity_constraint_wide.rs index 4204e68..f515d5e 100644 --- a/src/dynamics/solver/velocity_constraint_wide.rs +++ b/src/dynamics/solver/velocity_constraint_wide.rs @@ -72,6 +72,9 @@ impl WVelocityConstraint { let rbs1 = array![|ii| &bodies[manifolds[ii].body_pair.body1]; SIMD_WIDTH]; let rbs2 = array![|ii| &bodies[manifolds[ii].body_pair.body2]; SIMD_WIDTH]; + let delta1 = Isometry::from(array![|ii| manifolds[ii].delta1; SIMD_WIDTH]); + let delta2 = Isometry::from(array![|ii| manifolds[ii].delta2; SIMD_WIDTH]); + let im1 = SimdFloat::from(array![|ii| rbs1[ii].mass_properties.inv_mass; SIMD_WIDTH]); let ii1: AngularInertia<SimdFloat> = AngularInertia::from(array![|ii| rbs1[ii].world_inv_inertia_sqrt; SIMD_WIDTH]); @@ -79,7 +82,7 @@ impl WVelocityConstraint { let linvel1 = Vector::from(array![|ii| rbs1[ii].linvel; SIMD_WIDTH]); let angvel1 = AngVector::<SimdFloat>::from(array![|ii| rbs1[ii].angvel; SIMD_WIDTH]); - let position1 = Isometry::from(array![|ii| rbs1[ii].position; SIMD_WIDTH]); + let pos1 = Isometry::from(array![|ii| rbs1[ii].position; SIMD_WIDTH]); let world_com1 = Point::from(array![|ii| rbs1[ii].world_com; SIMD_WIDTH]); let im2 = SimdFloat::from(array![|ii| rbs2[ii].mass_properties.inv_mass; SIMD_WIDTH]); @@ -89,10 +92,13 @@ impl WVelocityConstraint { let linvel2 = Vector::from(array![|ii| rbs2[ii].linvel; SIMD_WIDTH]); let angvel2 = AngVector::<SimdFloat>::from(array![|ii| rbs2[ii].angvel; SIMD_WIDTH]); - let position2 = Isometry::from(array![|ii| rbs2[ii].position; SIMD_WIDTH]); + let pos2 = Isometry::from(array![|ii| rbs2[ii].position; SIMD_WIDTH]); let world_com2 = Point::from(array![|ii| rbs2[ii].world_com; SIMD_WIDTH]); - let force_dir1 = position1 * -Vector::from(array![|ii| manifolds[ii].local_n1; SIMD_WIDTH]); + let coll_pos1 = pos1 * delta1; + let coll_pos2 = pos2 * delta2; + + let force_dir1 = coll_pos1 * -Vector::from(array![|ii| manifolds[ii].local_n1; SIMD_WIDTH]); let mj_lambda1 = array![|ii| rbs1[ii].active_set_offset; SIMD_WIDTH]; let mj_lambda2 = array![|ii| rbs2[ii].active_set_offset; SIMD_WIDTH]; @@ -120,11 +126,11 @@ impl WVelocityConstraint { }; for k in 0..num_points { - // FIXME: can we avoid the multiplications by position1/position2 here? + // FIXME: can we avoid the multiplications by coll_pos1/coll_pos2 here? // By working as much as possible in local-space. - let p1 = position1 + let p1 = coll_pos1 * Point::from(array![|ii| manifold_points[ii][k].local_p1; SIMD_WIDTH]); - let p2 = position2 + let p2 = coll_pos2 * Point::from(array![|ii| manifold_points[ii][k].local_p2; SIMD_WIDTH]); let dist = SimdFloat::from(array![|ii| manifold_points[ii][k].dist; SIMD_WIDTH]); diff --git a/src/dynamics/solver/velocity_ground_constraint.rs b/src/dynamics/solver/velocity_ground_constraint.rs index 65a61bd..d9229ff 100644 --- a/src/dynamics/solver/velocity_ground_constraint.rs +++ b/src/dynamics/solver/velocity_ground_constraint.rs @@ -66,20 +66,22 @@ impl VelocityGroundConstraint { let mut rb1 = &bodies[manifold.body_pair.body1]; let mut rb2 = &bodies[manifold.body_pair.body2]; let flipped = !rb2.is_dynamic(); + let force_dir1; + let coll_pos1; + let coll_pos2; if flipped { + coll_pos1 = rb2.position * manifold.delta2; + coll_pos2 = rb1.position * manifold.delta1; + force_dir1 = coll_pos1 * (-manifold.local_n2); std::mem::swap(&mut rb1, &mut rb2); + } else { + coll_pos1 = rb1.position * manifold.delta1; + coll_pos2 = rb2.position * manifold.delta2; + force_dir1 = coll_pos1 * (-manifold.local_n1); } let mj_lambda2 = rb2.active_set_offset; - let force_dir1 = if flipped { - // NOTE: we already swapped rb1 and rb2 - // so we multiply by rb1.position. - rb1.position * (-manifold.local_n2) - } else { - rb1.position * (-manifold.local_n1) - }; - let warmstart_coeff = manifold.warmstart_multiplier * params.warmstart_coeff; for (l, manifold_points) in manifold @@ -144,15 +146,15 @@ impl VelocityGroundConstraint { let manifold_point = &manifold_points[k]; let (p1, p2) = if flipped { // NOTE: we already swapped rb1 and rb2 - // so we multiply by rb2.position. + // so we multiply by coll_pos1/coll_pos2. ( - rb1.position * manifold_point.local_p2, - rb2.position * manifold_point.local_p1, + coll_pos1 * manifold_point.local_p2, + coll_pos2 * manifold_point.local_p1, ) } else { ( - rb1.position * manifold_point.local_p1, - rb2.position * manifold_point.local_p2, + coll_pos1 * manifold_point.local_p1, + coll_pos2 * manifold_point.local_p2, ) }; let dp2 = p2 - rb2.world_com; diff --git a/src/dynamics/solver/velocity_ground_constraint_wide.rs b/src/dynamics/solver/velocity_ground_constraint_wide.rs index af2e1e9..18e9257 100644 --- a/src/dynamics/solver/velocity_ground_constraint_wide.rs +++ b/src/dynamics/solver/velocity_ground_constraint_wide.rs @@ -86,13 +86,23 @@ impl WVelocityGroundConstraint { let linvel2 = Vector::from(array![|ii| rbs2[ii].linvel; SIMD_WIDTH]); let angvel2 = AngVector::<SimdFloat>::from(array![|ii| rbs2[ii].angvel; SIMD_WIDTH]); - let position1 = Isometry::from(array![|ii| rbs1[ii].position; SIMD_WIDTH]); - let position2 = Isometry::from(array![|ii| rbs2[ii].position; SIMD_WIDTH]); + let pos1 = Isometry::from(array![|ii| rbs1[ii].position; SIMD_WIDTH]); + let pos2 = Isometry::from(array![|ii| rbs2[ii].position; SIMD_WIDTH]); + + let delta1 = Isometry::from( + array![|ii| if flipped[ii] { manifolds[ii].delta2 } else { manifolds[ii].delta1 }; SIMD_WIDTH], + ); + let delta2 = Isometry::from( + array![|ii| if flipped[ii] { manifolds[ii].delta1 } else { manifolds[ii].delta2 }; SIMD_WIDTH], + ); + + let coll_pos1 = pos1 * delta1; + let coll_pos2 = pos2 * delta2; let world_com1 = Point::from(array![|ii| rbs1[ii].world_com; SIMD_WIDTH]); let world_com2 = Point::from(array![|ii| rbs2[ii].world_com; SIMD_WIDTH]); - let force_dir1 = position1 + let force_dir1 = coll_pos1 * -Vector::from( array![|ii| if flipped[ii] { manifolds[ii].local_n2 } else { manifolds[ii].local_n1 }; SIMD_WIDTH], ); @@ -120,11 +130,11 @@ impl WVelocityGroundConstraint { }; for k in 0..num_points { - let p1 = position1 + let p1 = coll_pos1 * Point::from( array![|ii| if flipped[ii] { manifold_points[ii][k].local_p2 } else { manifold_points[ii][k].local_p1 }; SIMD_WIDTH], ); - let p2 = position2 + let p2 = coll_pos2 * Point::from( array![|ii| if flipped[ii] { manifold_points[ii][k].local_p1 } else { manifold_points[ii][k].local_p2 }; SIMD_WIDTH], ); diff --git a/src/geometry/contact.rs b/src/geometry/contact.rs index 0beec0a..2cda3e0 100644 --- a/src/geometry/contact.rs +++ b/src/geometry/contact.rs @@ -273,16 +273,21 @@ pub struct ContactManifold { /// The pair of subshapes involved in this contact manifold. pub subshape_index_pair: (usize, usize), pub(crate) warmstart_multiplier: f32, - // We put the friction and restitution here because - // this avoids reading the colliders inside of the + // The two following are set by the constraints solver. + pub(crate) constraint_index: usize, + pub(crate) position_constraint_index: usize, + // We put the following fields here to avoids reading the colliders inside of the // contact preparation method. /// The friction coefficient for of all the contacts on this contact manifold. pub friction: f32, /// The restitution coefficient for all the contacts on this contact manifold. pub restitution: f32, - // The following are set by the constraints solver. - pub(crate) constraint_index: usize, - pub(crate) position_constraint_index: usize, + /// The relative position between the first collider and its parent at the time the + /// contact points were generated. + pub delta1: Isometry<f32>, + /// The relative position between the second collider and its parent at the time the + /// contact points were generated. + pub delta2: Isometry<f32>, } impl ContactManifold { @@ -290,6 +295,8 @@ impl ContactManifold { pair: ColliderPair, subshapes: (usize, usize), body_pair: BodyPair, + delta1: Isometry<f32>, + delta2: Isometry<f32>, friction: f32, restitution: f32, ) -> ContactManifold { @@ -308,6 +315,8 @@ impl ContactManifold { warmstart_multiplier: Self::min_warmstart_multiplier(), friction, restitution, + delta1, + delta2, constraint_index: 0, position_constraint_index: 0, } @@ -329,6 +338,8 @@ impl ContactManifold { warmstart_multiplier: self.warmstart_multiplier, friction: self.friction, restitution: self.restitution, + delta1: self.delta1, + delta2: self.delta2, constraint_index: self.constraint_index, position_constraint_index: self.position_constraint_index, } @@ -349,6 +360,8 @@ impl ContactManifold { pair, (subshape1, subshape2), BodyPair::new(coll1.parent, coll2.parent), + *coll1.delta(), + *coll2.delta(), (coll1.friction + coll2.friction) * 0.5, (coll1.restitution + coll2.restitution) * 0.5, ) @@ -391,6 +404,7 @@ impl ContactManifold { self.pair = self.pair.swap(); self.body_pair = self.body_pair.swap(); self.subshape_index_pair = (self.subshape_index_pair.1, self.subshape_index_pair.0); + std::mem::swap(&mut self.delta1, &mut self.delta2); } pub(crate) fn update_warmstart_multiplier(&mut self) { diff --git a/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs b/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs index 0d382ac..d879a22 100644 --- a/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs +++ b/src/geometry/contact_generator/cuboid_cuboid_contact_generator.rs @@ -10,10 +10,8 @@ pub fn generate_contacts_cuboid_cuboid(ctxt: &mut PrimitiveContactGenerationCont generate_contacts( ctxt.prediction_distance, cube1, - ctxt.collider1.position_wrt_parent(), ctxt.position1, cube2, - ctxt.collider2.position_wrt_parent(), ctxt.position2, ctxt.manifold, ); @@ -28,19 +26,15 @@ pub fn generate_contacts_cuboid_cuboid(ctxt: &mut PrimitiveContactGenerationCont pub fn generate_contacts<'a>( prediction_distance: f32, mut cube1: &'a Cuboid<f32>, - mut origin1: &'a Isometry<f32>, mut pos1: &'a Isometry<f32>, mut cube2: &'a Cuboid<f32>, - mut origin2: &'a Isometry<f32>, mut pos2: &'a Isometry<f32>, manifold: &mut ContactManifold, ) { let mut pos12 = pos1.inverse() * pos2; let mut pos21 = pos12.inverse(); - let mut orig_pos12 = origin1 * pos12 * origin2.inverse(); - let mut orig_pos21 = orig_pos12.inverse(); - if manifold.try_update_contacts(&orig_pos12) { + if manifold.try_update_contacts(&pos12) { return; } @@ -87,9 +81,8 @@ pub fn generate_contacts<'a>( if sep2.0 > sep1.0 && sep2.0 > sep3.0 { // The reference shape will be the second shape. std::mem::swap(&mut cube1, &mut cube2); + std::mem::swap(&mut pos1, &mut pos2); std::mem::swap(&mut pos12, &mut pos21); - std::mem::swap(&mut orig_pos12, &mut orig_pos21); - std::mem::swap(&mut origin1, &mut origin2); manifold.swap_identifiers(); best_sep = sep2; swapped = true; @@ -104,49 +97,46 @@ pub fn generate_contacts<'a>( // Now the reference feature is from `cube1` and the best separation is `best_sep`. // Everything must be expressed in the local-space of `cube1` for contact clipping. - let mut feature1 = cuboid::support_feature(cube1, best_sep.1); - feature1.transform_by(origin1); + let feature1 = cuboid::support_feature(cube1, best_sep.1); let mut feature2 = cuboid::support_feature(cube2, pos21 * -best_sep.1); feature2.transform_by(&pos12); - feature2.transform_by(origin1); - let n1 = origin1 * best_sep.1; match (&feature1, &feature2) { (CuboidFeature::Face(f1), CuboidFeature::Vertex(v2)) => { - CuboidFeature::face_vertex_contacts(f1, &n1, v2, &orig_pos21, manifold) + CuboidFeature::face_vertex_contacts(f1, &best_sep.1, v2, &pos21, manifold) } #[cfg(feature = "dim3")] (CuboidFeature::Face(f1), CuboidFeature::Edge(e2)) => CuboidFeature::face_edge_contacts( prediction_distance, f1, - &n1, + &best_sep.1, e2, - &orig_pos21, + &pos21, manifold, false, ), (CuboidFeature::Face(f1), CuboidFeature::Face(f2)) => CuboidFeature::face_face_contacts( prediction_distance, f1, - &n1, + &best_sep.1, f2, - &orig_pos21, + &pos21, manifold, ), #[cfg(feature = "dim3")] (CuboidFeature::Edge(e1), CuboidFeature::Edge(e2)) => { - CuboidFeature::edge_edge_contacts(e1, &n1, e2, &orig_pos21, manifold) + CuboidFeature::edge_edge_contacts(e1, &best_sep.1, e2, &pos21, manifold) } #[cfg(feature = "dim3")] (CuboidFeature::Edge(e1), CuboidFeature::Face(f2)) => { // Since f2 is also expressed in the local-space of the first - // feature, the position we provide here is orig_pos21. + // feature, the position we provide here is pos21. CuboidFeature::face_edge_contacts( prediction_distance, f2, - &-n1, + &-best_sep.1, e1, - &orig_pos21, + &pos21, manifold, true, ) @@ -154,8 +144,8 @@ pub fn generate_contacts<'a>( _ => unreachable!(), // The other cases are not possible. } - manifold.local_n1 = n1; - manifold.local_n2 = orig_pos21 * -n1; + manifold.local_n1 = best_sep.1; + manifold.local_n2 = pos21 * -best_sep.1; manifold.kinematics.category = KinematicsCategory::PlanePoint; manifold.kinematics.radius1 = 0.0; manifold.kinematics.radius2 = 0.0; |
