Skip to main content

box2d_rust/manifold/
mod.rs

1// Port of box2d-cpp-reference/src/manifold.c — contact manifold generation.
2//
3// Split to satisfy the 800-line file limit:
4// - circles.rs — circle-vs-{circle, capsule, polygon, segment}
5// - capsules.rs — capsule-vs-capsule and its segment/polygon wrappers
6// - polygons.rs — SAT polygon clipper and polygon-vs-polygon
7// - chain.rs   — one-sided chain segment collisions (Gauss map ghost logic)
8//
9// The manifold types (LocalManifold and friends) live in collision.rs.
10// The dead `#else` branch inside b2CollidePolygons (`#if 1`) is not ported.
11//
12// SPDX-FileCopyrightText: 2023 Erin Catto
13// SPDX-License-Identifier: MIT
14
15mod capsules;
16mod chain;
17mod circles;
18mod polygons;
19
20pub use capsules::{collide_capsules, collide_polygon_and_capsule, collide_segment_and_capsule};
21pub use chain::{
22    collide_chain_segment_and_capsule, collide_chain_segment_and_circle,
23    collide_chain_segment_and_polygon,
24};
25pub use circles::{
26    collide_capsule_and_circle, collide_circles, collide_polygon_and_circle,
27    collide_segment_and_circle,
28};
29pub use polygons::{collide_polygons, collide_segment_and_polygon};
30
31use crate::collision::Polygon;
32use crate::math_functions::{length_squared, lerp, neg, normalize, right_perp, sub, Vec2};
33
34/// C: B2_MAKE_ID(A, B) — pack two feature indices into a contact id.
35pub(crate) fn make_id(a: i32, b: i32) -> u16 {
36    ((a as u8 as u16) << 8) | (b as u8 as u16)
37}
38
39/// Build a 2-vertex polygon representing a capsule. (static b2MakeCapsule)
40pub(crate) fn make_capsule_polygon(p1: Vec2, p2: Vec2, radius: f32) -> Polygon {
41    let mut shape = Polygon {
42        centroid: lerp(p1, p2, 0.5),
43        count: 2,
44        radius,
45        ..Default::default()
46    };
47    shape.vertices[0] = p1;
48    shape.vertices[1] = p2;
49
50    let d = sub(p2, p1);
51    debug_assert!(length_squared(d) > f32::EPSILON);
52    let axis = normalize(d);
53    let normal = right_perp(axis);
54
55    shape.normals[0] = normal;
56    shape.normals[1] = neg(normal);
57
58    shape
59}