@@ -8,13 +8,16 @@ use bevy::{
88use serde:: { Deserialize , Serialize } ;
99use uuid:: Uuid ;
1010
11- use crate :: core:: colliders:: core:: ColliderShape ;
11+ use crate :: { core:: colliders:: core:: ColliderShape , prelude :: config :: SymmertryMode } ;
1212
1313#[ derive( Asset , Debug , Clone , Reflect , Serialize , Deserialize ) ]
1414pub struct Ragdoll {
1515 pub bodies : HashMap < BodyId , Body > ,
1616 pub colliders : HashMap < ColliderId , Collider > ,
1717 pub joints : HashMap < JointId , Joint > ,
18+
19+ #[ serde( default ) ]
20+ pub suffixes : SymmetrySuffixes ,
1821}
1922
2023impl Ragdoll {
@@ -54,11 +57,39 @@ impl Ragdoll {
5457 self . bodies . values ( )
5558 }
5659
60+ pub fn iter_bodies_mut ( & mut self ) -> impl Iterator < Item = & mut Body > {
61+ self . bodies . values_mut ( )
62+ }
63+
64+ pub fn iter_body_ids ( & self ) -> impl Iterator < Item = BodyId > {
65+ self . bodies . keys ( ) . copied ( )
66+ }
67+
68+ pub fn iter_colliders ( & self ) -> impl Iterator < Item = & Collider > {
69+ self . colliders . values ( )
70+ }
71+
5772 pub fn iter_joints ( & self ) -> impl Iterator < Item = & Joint > {
5873 self . joints . values ( )
5974 }
6075}
6176
77+ /// Determines which suffixes to apply to labels of elements that make use of symmetry
78+ #[ derive( Debug , Clone , Reflect , Serialize , Deserialize ) ]
79+ pub struct SymmetrySuffixes {
80+ pub original : String ,
81+ pub mirror : String ,
82+ }
83+
84+ impl Default for SymmetrySuffixes {
85+ fn default ( ) -> Self {
86+ Self {
87+ original : ".R" . into ( ) ,
88+ mirror : ".L" . into ( ) ,
89+ }
90+ }
91+ }
92+
6293#[ derive( Reflect , Debug , Clone , Serialize , Deserialize ) ]
6394pub struct Body {
6495 pub id : BodyId ,
@@ -67,6 +98,13 @@ pub struct Body {
6798 pub isometry : Isometry3d ,
6899 pub colliders : Vec < ColliderId > ,
69100 pub default_mode : BodyMode ,
101+
102+ #[ serde( default ) ]
103+ pub use_symmetry : bool ,
104+ /// If symmetry is enabled and this body was created as the image under the symmetry of another
105+ /// body, which body is it?
106+ #[ serde( default ) ]
107+ pub created_from : Option < BodyId > ,
70108}
71109
72110impl Body {
@@ -79,8 +117,39 @@ impl Body {
79117 isometry : default ( ) ,
80118 colliders : default ( ) ,
81119 default_mode : BodyMode :: Kinematic ,
120+
121+ use_symmetry : false ,
122+ created_from : None ,
82123 }
83124 }
125+
126+ pub fn mirror_onto (
127+ & self ,
128+ target : & mut Self ,
129+ suffixes : & SymmetrySuffixes ,
130+ mode : & SymmertryMode ,
131+ ) {
132+ let original_label = self
133+ . label
134+ . strip_suffix ( & suffixes. original )
135+ . unwrap_or ( & self . label )
136+ . to_owned ( ) ;
137+
138+ let mirrored_label = format ! ( "{}{}" , original_label, suffixes. mirror) ;
139+ target. label = mirrored_label;
140+
141+ let mirrored_isometry = Isometry3d {
142+ rotation : mode. apply_quat ( self . isometry . rotation ) ,
143+ translation : mode. apply_position ( self . isometry . translation . into ( ) ) . into ( ) ,
144+ } ;
145+ target. isometry = mirrored_isometry;
146+
147+ todo ! ( "What do we do about colliders?" ) ;
148+
149+ target. default_mode = self . default_mode ;
150+ target. use_symmetry = false ;
151+ target. created_from = Some ( self . id ) ;
152+ }
84153}
85154
86155#[ derive( Reflect , Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
@@ -100,6 +169,10 @@ pub struct Collider {
100169 pub override_layers : bool ,
101170 /// Label that will be attached to the created collider in a [`ColliderLabel`] component.
102171 pub label : String ,
172+ /// If symmetry is enabled and this body was created as the image under the symmetry of another
173+ /// body, which body is it?
174+ #[ serde( default ) ]
175+ pub created_from : Option < ColliderId > ,
103176}
104177
105178impl Collider {
@@ -114,6 +187,7 @@ impl Collider {
114187 layer_filter : 1 ,
115188 override_layers : false ,
116189 label : "New collider" . into ( ) ,
190+ created_from : None ,
117191 }
118192 }
119193}
0 commit comments