box2d_rust/solver/mod.rs
1// Solver module: b2Softness/b2MakeSoft and the step context from solver.h.
2// The solver stages land in the solver bring-up commit.
3//
4// The C b2StepContext carries multithreading scratch (solver stages, sync
5// blocks, atomics, per-color wide-constraint arrays and interior pointers to
6// world data). The single-threaded port keeps only the step parameters here;
7// solver scratch is owned locally by the solve pass and world data is passed
8// as separate arguments to avoid aliasing &mut World.
9//
10// SPDX-FileCopyrightText: 2023 Erin Catto
11// SPDX-License-Identifier: MIT
12
13use crate::math_functions::PI;
14
15/// Soft constraint coefficients. (b2Softness)
16#[derive(Debug, Clone, Copy, PartialEq, Default)]
17pub struct Softness {
18 pub bias_rate: f32,
19 pub mass_scale: f32,
20 pub impulse_scale: f32,
21}
22
23/// (static inline b2MakeSoft)
24pub fn make_soft(hertz: f32, zeta: f32, h: f32) -> Softness {
25 if hertz == 0.0 {
26 return Softness {
27 bias_rate: 0.0,
28 mass_scale: 0.0,
29 impulse_scale: 0.0,
30 };
31 }
32
33 let omega = 2.0 * PI * hertz;
34 let a1 = 2.0 * zeta + h * omega;
35 let a2 = h * omega * a1;
36 let a3 = 1.0 / (1.0 + a2);
37
38 // bias = w / (2 * z + hw)
39 // massScale = hw * (2 * z + hw) / (1 + hw * (2 * z + hw))
40 // impulseScale = 1 / (1 + hw * (2 * z + hw))
41 //
42 // If z == 0
43 // bias = 1/h
44 // massScale = hw^2 / (1 + hw^2)
45 // impulseScale = 1 / (1 + hw^2)
46 //
47 // w -> inf
48 // bias = 1/h
49 // massScale = 1
50 // impulseScale = 0
51 //
52 // In all cases:
53 // massScale + impulseScale == 1
54 Softness {
55 bias_rate: omega / a1,
56 mass_scale: a2 * a3,
57 impulse_scale: a3,
58 }
59}
60
61/// Context for a time step. Recreated each time step. (b2StepContext — step
62/// parameters only; see the module header for what the serial port drops)
63#[derive(Debug, Clone, Copy, PartialEq, Default)]
64pub struct StepContext {
65 /// time step
66 pub dt: f32,
67
68 /// inverse time step (0 if dt == 0).
69 pub inv_dt: f32,
70
71 /// sub-step
72 pub h: f32,
73 pub inv_h: f32,
74
75 pub sub_step_count: i32,
76
77 pub contact_softness: Softness,
78 pub static_softness: Softness,
79
80 pub restitution_threshold: f32,
81 pub max_linear_velocity: f32,
82
83 /// Copied from World::contact_speed (the C reads it through
84 /// context->world).
85 pub contact_speed: f32,
86
87 pub enable_warm_starting: bool,
88}
89
90mod continuous;
91mod integrate;
92mod solve;
93
94pub use solve::*;