1
+ use std:: cmp:: Ordering ;
1
2
use std:: time:: { Duration , Instant } ;
2
3
3
4
use bevy:: prelude:: * ;
@@ -20,7 +21,7 @@ pub(crate) struct RotationData {
20
21
pub ( crate ) struct RotationState {
21
22
#[ derivative( Default ( value = "CartesianDirection::Y" ) ) ]
22
23
top : CartesianDirection ,
23
- #[ derivative( Default ( value = "CartesianDirection::X " ) ) ]
24
+ #[ derivative( Default ( value = "CartesianDirection::Z " ) ) ]
24
25
side : CartesianDirection ,
25
26
}
26
27
@@ -73,9 +74,8 @@ impl RotationAnimationData {
73
74
let animation_progress =
74
75
( Instant :: now ( ) - self . animation_started ) . as_secs_f64 ( ) / rotation_time. as_secs_f64 ( ) ;
75
76
let rotation_amount = rotation_curve ( animation_progress as f32 ) ;
76
- self . from . as_vec3 ( ) * ( 1. - rotation_amount) + self . target . as_vec3 ( ) * ( rotation_amount)
77
+ self . from . as_vec3 ( ) * ( 1. - rotation_amount) + self . target . as_vec3 ( ) * ( rotation_amount)
77
78
}
78
-
79
79
}
80
80
81
81
pub ( crate ) fn iterate (
@@ -96,22 +96,32 @@ pub(crate) fn iterate(
96
96
for mut camera in & mut query {
97
97
let mut transform = camera. 0 ;
98
98
transform. translation = rotation_data. rotation_state . camera_location ( ) * 2. ;
99
- // The camera rotates in the opposite direction from how the cube would have rotated to get
100
- // to the same place
99
+
100
+ // Needed to prevent dropping this value
101
+ let animations = [
102
+ rotation_data. top_rotation_animation ,
103
+ rotation_data. side_rotation_animation ,
104
+ ] ;
105
+ let mut animations = animations
106
+ . iter ( )
107
+ . flatten ( )
108
+ . collect :: < Vec < & RotationAnimationData > > ( ) ;
109
+ // Sort by when the animation started. If this is not done, the animations may be added in the wrong order resulting in wrong rotation
110
+ animations. sort_by ( |c1, c2| {
111
+ if c1. animation_started < c2. animation_started {
112
+ Ordering :: Greater
113
+ } else {
114
+ Ordering :: Less
115
+ }
116
+ } ) ;
101
117
transform. translate_around (
102
118
Vec3 :: ZERO ,
103
- total_animation_rotation (
104
- & [
105
- rotation_data. top_rotation_animation ,
106
- rotation_data. side_rotation_animation ,
107
- ] ,
108
- rotation_duration,
109
- ) ,
119
+ total_animation_rotation ( & animations, rotation_duration) ,
110
120
) ;
111
121
112
122
transform. look_at (
113
123
Vec3 :: new ( 0. , 0. , 0. ) ,
114
- camera_up_vector ( rotation_data, rotation_duration)
124
+ camera_up_vector ( rotation_data, rotation_duration) ,
115
125
) ;
116
126
117
127
camera. 0 = transform;
@@ -192,12 +202,13 @@ fn start_rotation(rotation_data: &mut RotationData, rotation: CartesianDirection
192
202
}
193
203
194
204
fn total_animation_rotation (
195
- animations : & [ Option < RotationAnimationData > ] ,
205
+ animations : & [ & RotationAnimationData ] ,
196
206
rotation_time : Duration ,
197
207
) -> Quat {
198
208
let mut output = Quat :: IDENTITY ;
209
+ // let mut output = animations.iter().flatten().last().map_or(Quat::IDENTITY, |p|p.partial_camera_translation(rotation_time));
199
210
// Iterate without Nones
200
- for animation in animations. iter ( ) . flatten ( ) {
211
+ for animation in animations {
201
212
output *= animation. partial_camera_translation ( rotation_time) ;
202
213
}
203
214
output
@@ -209,8 +220,8 @@ fn camera_up_vector(rotation_data: &RotationData, rotation_time: Duration) -> Ve
209
220
rotation_data. top_rotation_animation ,
210
221
rotation_data. side_rotation_animation ,
211
222
]
212
- . iter ( )
213
- . flatten ( )
223
+ . iter ( )
224
+ . flatten ( )
214
225
{
215
226
let top = rotation_data. rotation_state . top ;
216
227
if ( animation. target . is_parallel_to ( top) || animation. from . is_parallel_to ( top) )
@@ -230,10 +241,10 @@ fn rotation_curve(time: f32) -> f32 {
230
241
// return 0.;
231
242
// }
232
243
// time
233
- //
244
+
234
245
let c1 = 1.70158 ;
235
246
let c3 = c1 + 1. ;
236
-
247
+
237
248
1. + c3 * ( time - 1. ) . powi ( 3 ) + c1 * ( time - 1. ) . powi ( 2 )
238
249
}
239
250
0 commit comments