@@ -3,13 +3,14 @@ mod render_layers;
3
3
pub use render_layers:: * ;
4
4
5
5
use bevy_app:: { CoreSet , Plugin } ;
6
- use bevy_asset:: { Assets , Handle } ;
6
+ use bevy_asset:: { AssetEvent , Assets , Handle , HandleId } ;
7
7
use bevy_ecs:: prelude:: * ;
8
8
use bevy_hierarchy:: { Children , Parent } ;
9
9
use bevy_reflect:: Reflect ;
10
10
use bevy_reflect:: { std_traits:: ReflectDefault , FromReflect } ;
11
11
use bevy_transform:: components:: GlobalTransform ;
12
12
use bevy_transform:: TransformSystem ;
13
+ use bevy_utils:: { HashMap , HashSet } ;
13
14
use std:: cell:: Cell ;
14
15
use thread_local:: ThreadLocal ;
15
16
@@ -224,6 +225,7 @@ impl Plugin for VisibilityPlugin {
224
225
. configure_set ( CheckVisibility . in_base_set ( CoreSet :: PostUpdate ) )
225
226
. configure_set ( VisibilityPropagate . in_base_set ( CoreSet :: PostUpdate ) )
226
227
. add_system ( calculate_bounds. in_set ( CalculateBounds ) )
228
+ . add_system ( update_bounds. in_set ( CalculateBounds ) )
227
229
. add_system (
228
230
update_frusta :: < OrthographicProjection >
229
231
. in_set ( UpdateOrthographicFrusta )
@@ -269,12 +271,52 @@ pub fn calculate_bounds(
269
271
mut commands : Commands ,
270
272
meshes : Res < Assets < Mesh > > ,
271
273
without_aabb : Query < ( Entity , & Handle < Mesh > ) , ( Without < Aabb > , Without < NoFrustumCulling > ) > ,
274
+ without_handle : Query < Entity , ( With < Aabb > , Without < Handle < Mesh > > , Without < NoFrustumCulling > ) > ,
272
275
) {
273
276
for ( entity, mesh_handle) in & without_aabb {
274
- if let Some ( mesh) = meshes. get ( mesh_handle) {
275
- if let Some ( aabb) = mesh. compute_aabb ( ) {
276
- commands. entity ( entity) . insert ( aabb) ;
277
+ let Some ( mesh) = meshes. get ( mesh_handle) else { continue } ;
278
+ let Some ( aabb) = mesh. compute_aabb ( ) else { continue } ;
279
+ commands. entity ( entity) . insert ( aabb) ;
280
+ }
281
+ for entity in & without_handle {
282
+ commands. entity ( entity) . remove :: < Aabb > ( ) ;
283
+ }
284
+ }
285
+
286
+ pub fn update_bounds (
287
+ mut commands : Commands ,
288
+ meshes : Res < Assets < Mesh > > ,
289
+ mut events : EventReader < AssetEvent < Mesh > > ,
290
+ mut with_aabb : Query < ( Entity , & Handle < Mesh > , & mut Aabb ) , Without < NoFrustumCulling > > ,
291
+ mut changed : Local < HashMap < HandleId , Aabb > > ,
292
+ mut removed : Local < HashSet < HandleId > > ,
293
+ ) {
294
+ changed. clear ( ) ;
295
+ removed. clear ( ) ;
296
+
297
+ for mesh_event in & mut events {
298
+ match mesh_event {
299
+ AssetEvent :: Created { handle } | AssetEvent :: Modified { handle } => {
300
+ let Some ( mesh) = meshes. get ( & handle) else { continue } ;
301
+ let Some ( aabb) = mesh. compute_aabb ( ) else { continue } ;
302
+ changed. insert ( handle. id ( ) , aabb) ;
277
303
}
304
+ AssetEvent :: Removed { handle } => {
305
+ removed. insert ( handle. id ( ) ) ;
306
+ }
307
+ } ;
308
+ }
309
+
310
+ if changed. is_empty ( ) && removed. is_empty ( ) {
311
+ return ;
312
+ }
313
+
314
+ // FIXME: Include entities that have changed their Handle<Mesh> component
315
+ for ( entity, mesh_handle, mut entity_aabb) in & mut with_aabb {
316
+ if let Some ( aabb) = changed. get ( & mesh_handle. id ( ) ) {
317
+ * entity_aabb = * aabb;
318
+ } else if removed. contains ( & mesh_handle. id ( ) ) {
319
+ commands. entity ( entity) . remove :: < Aabb > ( ) ;
278
320
}
279
321
}
280
322
}
0 commit comments