Skip to main content

box3d_rust/contact_solver/
mod.rs

1//! Contact constraint kernels from contact_solver.c.
2//!
3//! Graph-color convex contacts use the Convex kernels (scalar form of the
4//! wide SIMD path). Mesh and overflow contacts use the Mesh kernels.
5//!
6//! SPDX-FileCopyrightText: 2025 Erin Catto
7//! SPDX-License-Identifier: MIT
8
9mod prepare;
10mod restitution;
11mod solve;
12mod solve_convex;
13mod store;
14mod warm_start;
15
16use crate::constants::MAX_MANIFOLD_POINTS;
17use crate::core::NULL_INDEX;
18use crate::math_functions::{
19    Mat2, Matrix3, Vec2, Vec3, MAT2_ZERO, MAT3_ZERO, VEC2_ZERO, VEC3_ZERO,
20};
21use crate::solver::Softness;
22
23pub use prepare::prepare_color_contacts;
24pub use restitution::{apply_restitution, apply_restitution_convex};
25pub use solve::solve_contacts;
26pub use solve_convex::solve_contacts_convex;
27pub use store::{flag_hit_events, store_impulses};
28pub use warm_start::{warm_start_contacts, warm_start_contacts_convex};
29
30/// (b3ManifoldConstraintPoint)
31#[derive(Debug, Clone, Copy, PartialEq, Default)]
32pub struct ManifoldConstraintPoint {
33    pub r_a: Vec3,
34    pub r_b: Vec3,
35    pub base_separation: f32,
36    pub relative_velocity: f32,
37    pub normal_impulse: f32,
38    pub total_normal_impulse: f32,
39    pub normal_mass: f32,
40    pub lever_arm: f32,
41}
42
43/// (b3ManifoldConstraint)
44#[derive(Debug, Clone, Copy, PartialEq)]
45pub struct ManifoldConstraint {
46    pub points: [ManifoldConstraintPoint; MAX_MANIFOLD_POINTS],
47    pub point_count: i32,
48    pub normal: Vec3,
49    pub tangent1: Vec3,
50    pub tangent2: Vec3,
51    pub origin_a: Vec3,
52    pub origin_b: Vec3,
53    pub twist_mass: f32,
54    pub twist_impulse: f32,
55    pub tangent_mass: Mat2,
56    pub friction_impulse: Vec2,
57    pub rolling_impulse: Vec3,
58    pub tangent_velocity1: f32,
59    pub tangent_velocity2: f32,
60}
61
62impl Default for ManifoldConstraint {
63    fn default() -> Self {
64        ManifoldConstraint {
65            points: [ManifoldConstraintPoint::default(); MAX_MANIFOLD_POINTS],
66            point_count: 0,
67            normal: VEC3_ZERO,
68            tangent1: VEC3_ZERO,
69            tangent2: VEC3_ZERO,
70            origin_a: VEC3_ZERO,
71            origin_b: VEC3_ZERO,
72            twist_mass: 0.0,
73            twist_impulse: 0.0,
74            tangent_mass: MAT2_ZERO,
75            friction_impulse: VEC2_ZERO,
76            rolling_impulse: VEC3_ZERO,
77            tangent_velocity1: 0.0,
78            tangent_velocity2: 0.0,
79        }
80    }
81}
82
83/// (b3ContactConstraint)
84///
85/// C holds `b3ManifoldConstraint* constraints` and `b3Contact* contact`. The
86/// Rust data model stores the manifold constraints inline and the contact id;
87/// the solver wires slices at step time.
88#[derive(Debug, Clone, PartialEq)]
89pub struct ContactConstraint {
90    pub constraints: Vec<ManifoldConstraint>,
91    pub contact_id: i32,
92    pub index_a: i32,
93    pub index_b: i32,
94    pub inv_mass_a: f32,
95    pub inv_mass_b: f32,
96    pub inv_i_a: Matrix3,
97    pub inv_i_b: Matrix3,
98    pub softness: Softness,
99    pub rolling_mass: Matrix3,
100    pub friction: f32,
101    pub restitution: f32,
102    pub rolling_resistance: f32,
103    pub manifold_count: i32,
104}
105
106impl Default for ContactConstraint {
107    fn default() -> Self {
108        ContactConstraint {
109            constraints: Vec::new(),
110            contact_id: NULL_INDEX,
111            index_a: NULL_INDEX,
112            index_b: NULL_INDEX,
113            inv_mass_a: 0.0,
114            inv_mass_b: 0.0,
115            inv_i_a: MAT3_ZERO,
116            inv_i_b: MAT3_ZERO,
117            softness: Softness::default(),
118            rolling_mass: MAT3_ZERO,
119            friction: 0.0,
120            restitution: 0.0,
121            rolling_resistance: 0.0,
122            manifold_count: 0,
123        }
124    }
125}