1
- use crate :: data:: Arena ;
1
+ use crate :: data:: { Arena , HasModifiedFlag , ModifiedObjects } ;
2
2
use crate :: dynamics:: {
3
3
ImpulseJointSet , IslandManager , MultibodyJointSet , RigidBody , RigidBodyChanges , RigidBodyHandle ,
4
4
} ;
@@ -22,6 +22,20 @@ impl BodyPair {
22
22
}
23
23
}
24
24
25
+ pub ( crate ) type ModifiedRigidBodies = ModifiedObjects < RigidBodyHandle , RigidBody > ;
26
+
27
+ impl HasModifiedFlag for RigidBody {
28
+ #[ inline]
29
+ fn has_modified_flag ( & self ) -> bool {
30
+ self . changes . contains ( RigidBodyChanges :: MODIFIED )
31
+ }
32
+
33
+ #[ inline]
34
+ fn set_modified_flag ( & mut self ) {
35
+ self . changes |= RigidBodyChanges :: MODIFIED ;
36
+ }
37
+ }
38
+
25
39
#[ cfg_attr( feature = "serde-serialize" , derive( Serialize , Deserialize ) ) ]
26
40
#[ derive( Clone , Default , Debug ) ]
27
41
/// A set of rigid bodies that can be handled by a physics pipeline.
@@ -31,27 +45,27 @@ pub struct RigidBodySet {
31
45
// parallelism because the `Receiver` breaks the Sync impl.
32
46
// Could we avoid this?
33
47
pub ( crate ) bodies : Arena < RigidBody > ,
34
- pub ( crate ) modified_bodies : Vec < RigidBodyHandle > ,
48
+ pub ( crate ) modified_bodies : ModifiedRigidBodies ,
35
49
}
36
50
37
51
impl RigidBodySet {
38
52
/// Create a new empty set of rigid bodies.
39
53
pub fn new ( ) -> Self {
40
54
RigidBodySet {
41
55
bodies : Arena :: new ( ) ,
42
- modified_bodies : Vec :: new ( ) ,
56
+ modified_bodies : ModifiedObjects :: default ( ) ,
43
57
}
44
58
}
45
59
46
60
/// Create a new set of rigid bodies, with an initial capacity.
47
61
pub fn with_capacity ( capacity : usize ) -> Self {
48
62
RigidBodySet {
49
63
bodies : Arena :: with_capacity ( capacity) ,
50
- modified_bodies : Vec :: with_capacity ( capacity) ,
64
+ modified_bodies : ModifiedRigidBodies :: with_capacity ( capacity) ,
51
65
}
52
66
}
53
67
54
- pub ( crate ) fn take_modified ( & mut self ) -> Vec < RigidBodyHandle > {
68
+ pub ( crate ) fn take_modified ( & mut self ) -> ModifiedRigidBodies {
55
69
std:: mem:: take ( & mut self . modified_bodies )
56
70
}
57
71
@@ -79,7 +93,10 @@ impl RigidBodySet {
79
93
rb. changes . set ( RigidBodyChanges :: all ( ) , true ) ;
80
94
81
95
let handle = RigidBodyHandle ( self . bodies . insert ( rb) ) ;
82
- self . modified_bodies . push ( handle) ;
96
+ // Using push_unchecked because this is a brand new rigid-body with the MODIFIED
97
+ // flags set but isn’t in the modified_bodies yet.
98
+ self . modified_bodies
99
+ . push_unchecked ( handle, & mut self . bodies [ handle. 0 ] ) ;
83
100
handle
84
101
}
85
102
@@ -152,7 +169,7 @@ impl RigidBodySet {
152
169
pub fn get_unknown_gen_mut ( & mut self , i : u32 ) -> Option < ( & mut RigidBody , RigidBodyHandle ) > {
153
170
let ( rb, handle) = self . bodies . get_unknown_gen_mut ( i) ?;
154
171
let handle = RigidBodyHandle ( handle) ;
155
- Self :: mark_as_modified ( handle, rb, & mut self . modified_bodies ) ;
172
+ self . modified_bodies . push_once ( handle, rb) ;
156
173
Some ( ( rb, handle) )
157
174
}
158
175
@@ -161,22 +178,11 @@ impl RigidBodySet {
161
178
self . bodies . get ( handle. 0 )
162
179
}
163
180
164
- pub ( crate ) fn mark_as_modified (
165
- handle : RigidBodyHandle ,
166
- rb : & mut RigidBody ,
167
- modified_bodies : & mut Vec < RigidBodyHandle > ,
168
- ) {
169
- if !rb. changes . contains ( RigidBodyChanges :: MODIFIED ) {
170
- rb. changes = RigidBodyChanges :: MODIFIED ;
171
- modified_bodies. push ( handle) ;
172
- }
173
- }
174
-
175
181
/// Gets a mutable reference to the rigid-body with the given handle.
176
182
#[ cfg( not( feature = "dev-remove-slow-accessors" ) ) ]
177
183
pub fn get_mut ( & mut self , handle : RigidBodyHandle ) -> Option < & mut RigidBody > {
178
184
let result = self . bodies . get_mut ( handle. 0 ) ?;
179
- Self :: mark_as_modified ( handle, result, & mut self . modified_bodies ) ;
185
+ self . modified_bodies . push_once ( handle, result) ;
180
186
Some ( result)
181
187
}
182
188
@@ -195,7 +201,7 @@ impl RigidBodySet {
195
201
handle : RigidBodyHandle ,
196
202
) -> Option < & mut RigidBody > {
197
203
let result = self . bodies . get_mut ( handle. 0 ) ?;
198
- Self :: mark_as_modified ( handle, result, & mut self . modified_bodies ) ;
204
+ self . modified_bodies . push_once ( handle, result) ;
199
205
Some ( result)
200
206
}
201
207
@@ -210,7 +216,9 @@ impl RigidBodySet {
210
216
self . modified_bodies . clear ( ) ;
211
217
let modified_bodies = & mut self . modified_bodies ;
212
218
self . bodies . iter_mut ( ) . map ( move |( h, b) | {
213
- modified_bodies. push ( RigidBodyHandle ( h) ) ;
219
+ // NOTE: using `push_unchecked` because we just cleared `modified_bodies`
220
+ // before iterating.
221
+ modified_bodies. push_unchecked ( RigidBodyHandle ( h) , b) ;
214
222
( RigidBodyHandle ( h) , b)
215
223
} )
216
224
}
@@ -256,7 +264,7 @@ impl Index<crate::data::Index> for RigidBodySet {
256
264
impl IndexMut < RigidBodyHandle > for RigidBodySet {
257
265
fn index_mut ( & mut self , handle : RigidBodyHandle ) -> & mut RigidBody {
258
266
let rb = & mut self . bodies [ handle. 0 ] ;
259
- Self :: mark_as_modified ( handle, rb, & mut self . modified_bodies ) ;
267
+ self . modified_bodies . push_once ( handle, rb) ;
260
268
rb
261
269
}
262
270
}
0 commit comments