blast_stress_solver/rapier/
resimulation.rs1use 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}