Spaces:
Running on Zero
Running on Zero
File size: 2,704 Bytes
3bf6e3e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | --- a/src/physics/collision.rs
+++ b/src/physics/collision.rs
@@ -329,6 +329,7 @@
contacts: &mut Vec<Contact>,
) {
contacts.clear();
+ scratch.collided_shapes.clear();
let (sx, sy) = cfg.shape_basis;
let basis_x = V2::from(body_basis.0 * sx.x + body_basis.1 * sx.y);
let basis_y = V2::from(body_basis.0 * sy.x + body_basis.1 * sy.y);
@@ -483,6 +484,8 @@
if separated || push == V2::ZERO {
continue;
}
+ // SAT overlap keeps cached contacts eligible even without a new contact.
+ scratch.collided_shapes.push(shape_index);
let support_car = rectangle_supports(&car, -push, basis_x, basis_y);
let support_wall = polygon_supports(wall, shape, push);
let mut pairs = [(V2::ZERO, V2::ZERO); 2];
@@ -601,11 +604,7 @@
}
find_contacts_with_basis(cfg, track, position, rotation, body_basis, scratch, contacts);
previous.retain(|c| scratch.broad_pairs.contains(&c.shape_index));
- scratch.collided_shapes.clear();
for new in contacts.iter() {
- if !scratch.collided_shapes.contains(&new.shape_index) {
- scratch.collided_shapes.push(new.shape_index);
- }
let radius2 = (cfg.contact_recycle_radius as f32).powi(2);
if let Some(old) = previous.iter_mut().find(|old| {
let a = F2::from(old.local_point) - F2::from(new.local_point);
--- a/gpu/sim/step.h
+++ b/gpu/sim/step.h
@@ -471,7 +471,8 @@
}
// The rest of `solve_wall_contacts` once this tick's contacts are merged;
-// `made_contacts` has a bit per broad pair that made contacts.
+// `made_contacts` has a bit per SAT-overlapping broad pair, including
+// overlaps with no new points but a valid retained contact.
__device__ inline SolveResult solve_contacts(const World& w, const VehicleDesc& v, Car& car, uint32_t made_contacts, Vec2 velocity,
float angular, Vec2 initial_velocity, float initial_angular) {
STEP_MARK(ts);
@@ -682,12 +683,13 @@
f = car_frame(v, car);
framed = true;
}
- uint32_t made = pair_contacts(w, v, car, f, ci, push, [&](const Contact& c) {
+ pair_contacts(w, v, car, f, ci, push, [&](const Contact& c) {
STEP_MARK(tm);
merge_contact(v, car, c);
STEP_SECTION(11, tm);
});
- made_contacts |= made ? 1u << ci : 0u;
+ // Keep cached contacts eligible when SAT overlaps but produces no new point.
+ made_contacts |= 1u << ci;
}
STEP_SECTION(2, tc);
SolveResult r = solve_contacts(w, v, car, made_contacts, k.velocity, k.angular, k.previous_velocity, k.previous_angular);
|