rapier3d/pipeline/
user_changes.rs1use crate::dynamics::{
2 ImpulseJointSet, IslandManager, JointEnabled, MultibodyJointSet, RigidBodyChanges,
3 RigidBodyHandle, RigidBodySet,
4};
5use crate::geometry::{
6 ColliderChanges, ColliderEnabled, ColliderHandle, ColliderPosition, ColliderSet,
7 ModifiedColliders,
8};
9
10pub(crate) fn handle_user_changes_to_colliders(
11 bodies: &mut RigidBodySet,
12 colliders: &mut ColliderSet,
13 modified_colliders: &[ColliderHandle],
14) {
15 for handle in modified_colliders {
16 if let Some(co) = colliders.get_mut_internal(*handle) {
19 if co.changes.contains(ColliderChanges::PARENT) {
20 if let Some(co_parent) = co.parent {
21 let parent_rb = &bodies[co_parent.handle];
22
23 co.pos = ColliderPosition(parent_rb.pos.position * co_parent.pos_wrt_parent);
24 co.changes |= ColliderChanges::POSITION;
25 }
26 }
27
28 if co.changes.intersects(
29 ColliderChanges::SHAPE
30 | ColliderChanges::LOCAL_MASS_PROPERTIES
31 | ColliderChanges::ENABLED_OR_DISABLED
32 | ColliderChanges::PARENT,
33 ) {
34 if let Some(rb) = co
35 .parent
36 .and_then(|p| bodies.get_mut_internal_with_modification_tracking(p.handle))
37 {
38 rb.changes |= RigidBodyChanges::LOCAL_MASS_PROPERTIES;
39 }
40 }
41 }
42 }
43}
44
45pub(crate) fn handle_user_changes_to_rigid_bodies(
46 mut islands: Option<&mut IslandManager>,
47 bodies: &mut RigidBodySet,
48 colliders: &mut ColliderSet,
49 impulse_joints: &mut ImpulseJointSet,
50 _multibody_joints: &mut MultibodyJointSet, modified_bodies: &[RigidBodyHandle],
52 modified_colliders: &mut ModifiedColliders,
53) {
54 enum FinalAction {
55 RemoveFromIsland,
56 }
57
58 for handle in modified_bodies {
59 let mut final_action = None;
60
61 if !bodies.contains(*handle) {
62 continue;
64 }
65
66 {
67 let rb = bodies.index_mut_internal(*handle);
68 let changes = rb.changes;
69 let activation = rb.activation;
70
71 if rb.is_enabled() {
72 if let Some(islands) = islands.as_deref_mut() {
75 islands.rigid_body_updated(*handle, bodies);
76 }
77 }
78
79 let rb = bodies.index_mut_internal(*handle);
80
81 if changes.contains(RigidBodyChanges::POSITION)
83 || changes.contains(RigidBodyChanges::COLLIDERS)
84 {
85 rb.colliders
86 .update_positions(colliders, modified_colliders, &rb.pos.position);
87 }
88
89 if changes.contains(RigidBodyChanges::DOMINANCE)
90 || changes.contains(RigidBodyChanges::TYPE)
91 {
92 for handle in rb.colliders.0.iter() {
93 let co = colliders.index_mut_internal(*handle);
97 modified_colliders.push_once(*handle, co);
98 co.changes |= ColliderChanges::PARENT_EFFECTIVE_DOMINANCE;
99 }
100 }
101
102 if changes.contains(RigidBodyChanges::ENABLED_OR_DISABLED) {
103 for handle in rb.colliders.0.iter() {
105 let co = colliders.index_mut_internal(*handle);
109 modified_colliders.push_once(*handle, co);
110
111 if rb.enabled && co.flags.enabled == ColliderEnabled::DisabledByParent {
112 co.flags.enabled = ColliderEnabled::Enabled;
113 } else if !rb.enabled && co.flags.enabled == ColliderEnabled::Enabled {
114 co.flags.enabled = ColliderEnabled::DisabledByParent;
115 }
116
117 co.changes |= ColliderChanges::ENABLED_OR_DISABLED;
118 }
119
120 impulse_joints.map_attached_joints_mut(*handle, |_, _, _, joint| {
122 if rb.enabled && joint.data.enabled == JointEnabled::DisabledByAttachedBody {
123 joint.data.enabled = JointEnabled::Enabled;
124 } else if !rb.enabled && joint.data.enabled == JointEnabled::Enabled {
125 joint.data.enabled = JointEnabled::DisabledByAttachedBody;
126 }
127 });
128
129 if !rb.enabled {
133 final_action = Some(FinalAction::RemoveFromIsland);
134 }
135 }
136
137 if changes
141 .intersects(RigidBodyChanges::LOCAL_MASS_PROPERTIES | RigidBodyChanges::COLLIDERS)
142 {
143 rb.mprops.recompute_mass_properties_from_colliders(
144 colliders,
145 &rb.colliders,
146 rb.body_type,
147 &rb.pos.position,
148 );
149 }
150
151 rb.activation = activation;
152 }
153
154 if let Some(islands) = islands.as_deref_mut() {
156 if let Some(action) = final_action {
157 match action {
158 FinalAction::RemoveFromIsland => {
159 let rb = bodies.index_mut_internal(*handle);
160 let ids = rb.ids;
161 islands.rigid_body_removed_or_disabled(*handle, &ids, bodies);
162 }
163 };
164 }
165 }
166 }
167}