Skip to main content

blast_stress_solver/rapier/
resimulation.rs

1use rapier3d::prelude::*;
2
3use super::destructible::SplitCohort;
4
5#[derive(Clone, Copy, Debug)]
6pub struct ResimulationOptions {
7    pub enabled: bool,
8    pub max_passes: usize,
9}
10
11impl Default for ResimulationOptions {
12    fn default() -> Self {
13        Self {
14            enabled: false,
15            max_passes: 0,
16        }
17    }
18}
19
20#[derive(Clone, Copy, Debug)]
21struct BodySnapshot {
22    handle: RigidBodyHandle,
23    position: Isometry<Real>,
24    linvel: Vector<Real>,
25    angvel: AngVector<Real>,
26    linear_damping: Real,
27    angular_damping: Real,
28    user_force: Vector<Real>,
29    user_torque: AngVector<Real>,
30    sleeping: bool,
31    enabled: bool,
32}
33
34#[derive(Clone, Debug, Default)]
35pub struct BodySnapshots {
36    bodies: Vec<BodySnapshot>,
37}
38
39impl BodySnapshots {
40    pub fn capture(set: &RigidBodySet) -> Self {
41        let bodies = set
42            .iter()
43            .map(|(handle, body)| BodySnapshot {
44                handle,
45                position: *body.position(),
46                linvel: *body.linvel(),
47                angvel: *body.angvel(),
48                linear_damping: body.linear_damping(),
49                angular_damping: body.angular_damping(),
50                user_force: body.user_force(),
51                user_torque: body.user_torque(),
52                sleeping: body.is_sleeping(),
53                enabled: body.is_enabled(),
54            })
55            .collect();
56        Self { bodies }
57    }
58
59    pub fn restore(&self, set: &mut RigidBodySet) {
60        for snapshot in &self.bodies {
61            let Some(body) = set.get_mut(snapshot.handle) else {
62                continue;
63            };
64            body.set_enabled(snapshot.enabled);
65            body.set_position(snapshot.position, true);
66            if !body.is_fixed() {
67                body.set_linvel(snapshot.linvel, true);
68                body.set_angvel(snapshot.angvel, true);
69                body.set_linear_damping(snapshot.linear_damping);
70                body.set_angular_damping(snapshot.angular_damping);
71                body.reset_forces(true);
72                body.reset_torques(true);
73                if snapshot.user_force.norm_squared() > 0.0 {
74                    body.add_force(snapshot.user_force, true);
75                }
76                if snapshot.user_torque.norm_squared() > 0.0 {
77                    body.add_torque(snapshot.user_torque, true);
78                }
79            }
80            if snapshot.sleeping {
81                body.sleep();
82            } else {
83                body.wake_up(true);
84            }
85        }
86    }
87
88    pub fn restore_split_children(&self, set: &mut RigidBodySet, split_cohorts: &[SplitCohort]) {
89        for cohort in split_cohorts {
90            for &target_handle in &cohort.target_bodies {
91                let Some(source_handle) = cohort
92                    .target_sources
93                    .iter()
94                    .find_map(|(target, source)| (*target == target_handle).then_some(*source))
95                else {
96                    continue;
97                };
98                let Some(source_snapshot) = self
99                    .bodies
100                    .iter()
101                    .find(|snapshot| snapshot.handle == source_handle)
102                    .copied()
103                else {
104                    continue;
105                };
106                let Some(target_body) = set.get_mut(target_handle) else {
107                    continue;
108                };
109                target_body.set_enabled(source_snapshot.enabled);
110                target_body.set_position(source_snapshot.position, true);
111                if !target_body.is_fixed() {
112                    target_body.set_linvel(source_snapshot.linvel, true);
113                    target_body.set_angvel(source_snapshot.angvel, true);
114                    target_body.set_linear_damping(source_snapshot.linear_damping);
115                    target_body.set_angular_damping(source_snapshot.angular_damping);
116                    target_body.reset_forces(true);
117                    target_body.reset_torques(true);
118                    if source_snapshot.user_force.norm_squared() > 0.0 {
119                        target_body.add_force(source_snapshot.user_force, true);
120                    }
121                    if source_snapshot.user_torque.norm_squared() > 0.0 {
122                        target_body.add_torque(source_snapshot.user_torque, true);
123                    }
124                }
125                if source_snapshot.sleeping {
126                    target_body.sleep();
127                } else {
128                    target_body.wake_up(true);
129                }
130            }
131        }
132    }
133}