1
- use crate :: components:: { GlobalTransform , Transform3d , TransformTreeChanged } ;
1
+ use crate :: components:: { GlobalTransform , Transform2d , Transform3d , TransformTreeChanged } ;
2
2
use bevy_ecs:: prelude:: * ;
3
3
#[ cfg( feature = "std" ) ]
4
4
pub use parallel:: propagate_parent_transforms;
@@ -9,33 +9,35 @@ pub use serial::propagate_parent_transforms;
9
9
///
10
10
/// Third party plugins should ensure that this is used in concert with
11
11
/// [`propagate_parent_transforms`] and [`mark_dirty_trees`].
12
- pub fn sync_simple_transforms (
12
+ pub fn sync_simple_transforms < T > (
13
13
mut query : ParamSet < (
14
14
Query <
15
- ( & Transform3d , & mut GlobalTransform ) ,
15
+ ( & T , & mut GlobalTransform ) ,
16
16
(
17
- Or < ( Changed < Transform3d > , Added < GlobalTransform > ) > ,
17
+ Or < ( Changed < T > , Added < GlobalTransform > ) > ,
18
18
Without < ChildOf > ,
19
19
Without < Children > ,
20
20
) ,
21
21
> ,
22
- Query < ( Ref < Transform3d > , & mut GlobalTransform ) , ( Without < ChildOf > , Without < Children > ) > ,
22
+ Query < ( Ref < T > , & mut GlobalTransform ) , ( Without < ChildOf > , Without < Children > ) > ,
23
23
) > ,
24
24
mut orphaned : RemovedComponents < ChildOf > ,
25
- ) {
25
+ ) where
26
+ T : Copy + Clone + Component + Into < GlobalTransform > ,
27
+ {
26
28
// Update changed entities.
27
29
query
28
30
. p0 ( )
29
31
. par_iter_mut ( )
30
32
. for_each ( |( transform, mut global_transform) | {
31
- * global_transform = GlobalTransform :: from ( * transform) ;
33
+ * global_transform = ( * transform) . into ( ) ;
32
34
} ) ;
33
35
// Update orphaned entities.
34
36
let mut query = query. p1 ( ) ;
35
37
let mut iter = query. iter_many_mut ( orphaned. read ( ) ) ;
36
38
while let Some ( ( transform, mut global_transform) ) = iter. fetch_next ( ) {
37
39
if !transform. is_changed ( ) && !global_transform. is_added ( ) {
38
- * global_transform = GlobalTransform :: from ( * transform) ;
40
+ * global_transform = ( * transform) . into ( ) ;
39
41
}
40
42
}
41
43
}
@@ -48,6 +50,7 @@ pub fn mark_dirty_trees(
48
50
Entity ,
49
51
Or < (
50
52
Changed < Transform3d > ,
53
+ Changed < Transform2d > ,
51
54
Changed < ChildOf > ,
52
55
Added < GlobalTransform > ,
53
56
) > ,
@@ -107,7 +110,11 @@ mod serial {
107
110
> ,
108
111
mut orphaned : RemovedComponents < ChildOf > ,
109
112
transform_query : Query <
110
- ( Ref < Transform3d > , & mut GlobalTransform , Option < & Children > ) ,
113
+ (
114
+ AnyOf < ( Ref < Transform3d > , Ref < Transform2d > ) > ,
115
+ & mut GlobalTransform ,
116
+ Option < & Children > ,
117
+ ) ,
111
118
With < ChildOf > ,
112
119
> ,
113
120
child_query : Query < ( Entity , Ref < ChildOf > ) , With < GlobalTransform > > ,
@@ -120,7 +127,7 @@ mod serial {
120
127
|( entity, children, transform, mut global_transform) | {
121
128
let changed = transform. is_changed ( ) || global_transform. is_added ( ) || orphaned_entities. binary_search ( & entity) . is_ok ( ) ;
122
129
if changed {
123
- * global_transform = GlobalTransform :: from ( * transform) ;
130
+ * global_transform = local_to_global ( transform) ;
124
131
}
125
132
126
133
for ( child, child_of) in child_query. iter_many ( children) {
@@ -175,7 +182,11 @@ mod serial {
175
182
unsafe fn propagate_recursive (
176
183
parent : & GlobalTransform ,
177
184
transform_query : & Query <
178
- ( Ref < Transform3d > , & mut GlobalTransform , Option < & Children > ) ,
185
+ (
186
+ AnyOf < ( Ref < Transform3d > , Ref < Transform2d > ) > ,
187
+ & mut GlobalTransform ,
188
+ Option < & Children > ,
189
+ ) ,
179
190
With < ChildOf > ,
180
191
> ,
181
192
child_query : & Query < ( Entity , Ref < ChildOf > ) , With < GlobalTransform > > ,
@@ -252,6 +263,7 @@ mod serial {
252
263
/// the serial version.
253
264
#[ cfg( feature = "std" ) ]
254
265
mod parallel {
266
+ use super :: local_to_global;
255
267
use crate :: prelude:: * ;
256
268
// TODO: this implementation could be used in no_std if there are equivalents of these.
257
269
use alloc:: { sync:: Arc , vec:: Vec } ;
@@ -273,7 +285,12 @@ mod parallel {
273
285
pub fn propagate_parent_transforms (
274
286
mut queue : Local < WorkQueue > ,
275
287
mut roots : Query <
276
- ( Entity , Ref < Transform3d > , & mut GlobalTransform , & Children ) ,
288
+ (
289
+ Entity ,
290
+ AnyOf < ( Ref < Transform3d > , Ref < Transform2d > ) > ,
291
+ & mut GlobalTransform ,
292
+ & Children ,
293
+ ) ,
277
294
( Without < ChildOf > , Changed < TransformTreeChanged > ) ,
278
295
> ,
279
296
nodes : NodeQuery ,
@@ -282,7 +299,7 @@ mod parallel {
282
299
roots. par_iter_mut ( ) . for_each_init (
283
300
|| queue. local_queue . borrow_local_mut ( ) ,
284
301
|outbox, ( parent, transform, mut parent_transform, children) | {
285
- * parent_transform = GlobalTransform :: from ( * transform) ;
302
+ * parent_transform = local_to_global ( transform) ;
286
303
287
304
// SAFETY: the parent entities passed into this function are taken from iterating
288
305
// over the root entity query. Queries iterate over disjoint entities, preventing
@@ -460,7 +477,8 @@ mod parallel {
460
477
461
478
// Transform prop is expensive - this helps avoid updating entire subtrees if
462
479
// the GlobalTransform is unchanged, at the cost of an added equality check.
463
- global_transform. set_if_neq ( p_global_transform. mul_transform ( * transform) ) ;
480
+ let child_global = local_to_global ( transform) ;
481
+ global_transform. set_if_neq ( * p_global_transform * child_global) ;
464
482
465
483
children. map ( |children| {
466
484
// Only continue propagation if the entity has children.
@@ -499,7 +517,7 @@ mod parallel {
499
517
(
500
518
Entity ,
501
519
(
502
- Ref < ' static , Transform3d > ,
520
+ AnyOf < ( Ref < ' static , Transform3d > , Ref < ' static , Transform2d > ) > ,
503
521
Mut < ' static , GlobalTransform > ,
504
522
Ref < ' static , TransformTreeChanged > ,
505
523
) ,
@@ -557,6 +575,16 @@ mod parallel {
557
575
}
558
576
}
559
577
578
+ fn local_to_global (
579
+ any_of : ( Option < Ref < ' _ , Transform3d > > , Option < Ref < ' _ , Transform2d > > ) ,
580
+ ) -> GlobalTransform {
581
+ match any_of {
582
+ ( Some ( transform_3d) , _) => GlobalTransform :: from ( * transform_3d) ,
583
+ ( _, Some ( transform_2d) ) => GlobalTransform :: from ( * transform_2d) ,
584
+ _ => unreachable ! ( ) ,
585
+ }
586
+ }
587
+
560
588
#[ cfg( test) ]
561
589
mod test {
562
590
use alloc:: { vec, vec:: Vec } ;
0 commit comments