veloren_voxygen_anim/biped_large/
beam.rs

1use super::{
2    super::{Animation, vek::*},
3    BipedLargeSkeleton, SkeletonAttr,
4};
5use common::{
6    comp::item::{AbilitySpec, ToolKind},
7    states::utils::StageSection,
8};
9use core::f32::consts::PI;
10
11pub struct BeamAnimation;
12
13impl Animation for BeamAnimation {
14    type Dependency<'a> = (
15        Option<ToolKind>,
16        (Option<ToolKind>, Option<&'a AbilitySpec>),
17        f32,
18        Vec3<f32>,
19        Option<StageSection>,
20        f32,
21        f32,
22        Option<&'a str>,
23    );
24    type Skeleton = BipedLargeSkeleton;
25
26    #[cfg(feature = "use-dyn-lib")]
27    const UPDATE_FN: &'static [u8] = b"biped_large_beam\0";
28
29    #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_beam")]
30    fn update_skeleton_inner(
31        skeleton: &Self::Skeleton,
32        (
33            active_tool_kind,
34            _second_tool_kind,
35            global_time,
36            velocity,
37            stage_section,
38            acc_vel,
39            timer,
40            ability_id,
41        ): Self::Dependency<'_>,
42        anim_time: f32,
43        rate: &mut f32,
44        s_a: &SkeletonAttr,
45    ) -> Self::Skeleton {
46        *rate = 1.0;
47        let mut next = (*skeleton).clone();
48
49        let speed = Vec2::<f32>::from(velocity).magnitude();
50
51        let lab: f32 = 0.65 * s_a.tempo;
52        let speednorm = (speed / 12.0).powf(0.4);
53        let foothoril = (acc_vel * lab + PI * 1.45).sin() * speednorm;
54        let foothorir = (acc_vel * lab + PI * (0.45)).sin() * speednorm;
55        let footrotl = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 1.4).sin()).powi(2))).sqrt())
56            * ((acc_vel * lab + PI * 1.4).sin())
57            * speednorm;
58
59        let footrotr = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 0.4).sin()).powi(2))).sqrt())
60            * ((acc_vel * lab + PI * 0.4).sin())
61            * speednorm;
62        let subtract = global_time - timer;
63        let check = subtract - subtract.trunc();
64        let mirror = (check - 0.5).signum();
65        next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
66        next.jaw.orientation = Quaternion::rotation_x(0.0);
67
68        next.main.position = Vec3::new(0.0, 0.0, 0.0);
69        next.main.orientation = Quaternion::rotation_x(0.0);
70
71        next.hand_l.position = Vec3::new(s_a.grip.1, 0.0, s_a.grip.0);
72        next.hand_r.position = Vec3::new(-s_a.grip.1, 0.0, s_a.grip.0);
73
74        next.hand_l.orientation = Quaternion::rotation_x(0.0);
75        next.hand_r.orientation = Quaternion::rotation_x(0.0);
76        let (move1base, move2shake, move2base, move3) = match stage_section {
77            Some(StageSection::Buildup) => ((anim_time.powf(0.25)).min(1.0), 0.0, 0.0, 0.0),
78            Some(StageSection::Action) => (
79                1.0,
80                (anim_time * 15.0 + PI).sin(),
81                (anim_time.powf(0.1)).min(1.0),
82                0.0,
83            ),
84            Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time),
85            _ => (0.0, 0.0, 0.0, 0.0),
86        };
87        let pullback = 1.0 - move3;
88        let move1 = move1base * pullback;
89        let move2 = move2base * pullback;
90        match active_tool_kind {
91            Some(ToolKind::Staff) => {
92                next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
93                next.control_r.position =
94                    Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
95
96                next.control.position = Vec3::new(
97                    -3.0 + move1 * -5.0,
98                    3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
99                    -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
100                );
101                next.head.orientation =
102                    Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
103                next.jaw.orientation = Quaternion::rotation_x(0.0);
104
105                next.control_l.orientation =
106                    Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
107                next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
108                    * Quaternion::rotation_y(0.5)
109                    * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
110
111                next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
112                    * Quaternion::rotation_y(-0.1 + move1 * 0.6);
113                next.shoulder_l.position = Vec3::new(
114                    -s_a.shoulder.0,
115                    s_a.shoulder.1,
116                    s_a.shoulder.2 - foothorir * 1.0,
117                );
118                next.shoulder_l.orientation =
119                    Quaternion::rotation_x(move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2));
120                next.shoulder_r.position = Vec3::new(
121                    s_a.shoulder.0,
122                    s_a.shoulder.1,
123                    s_a.shoulder.2 - foothoril * 1.0,
124                );
125                next.shoulder_r.orientation =
126                    Quaternion::rotation_x(move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2));
127            },
128            Some(ToolKind::Sceptre) => match ability_id {
129                Some("common.abilities.custom.sea_bishop.longbeam") => {
130                    next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
131                    next.control_r.position =
132                        Vec3::new(-1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
133
134                    next.control.position = Vec3::new(
135                        -3.0 + move1 * -5.0,
136                        -2.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
137                        -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
138                    );
139                    next.head.orientation =
140                        Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
141                    next.jaw.orientation = Quaternion::rotation_x(0.0);
142
143                    next.control_l.orientation =
144                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
145                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
146                        * Quaternion::rotation_y(0.5)
147                        * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
148
149                    next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
150                        * Quaternion::rotation_y(-0.1 + move1 * 0.6);
151                    next.shoulder_l.position = Vec3::new(
152                        -s_a.shoulder.0,
153                        s_a.shoulder.1,
154                        s_a.shoulder.2 - foothorir * 1.0,
155                    );
156                    next.shoulder_l.orientation = Quaternion::rotation_x(
157                        move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
158                    );
159                    next.shoulder_r.position = Vec3::new(
160                        s_a.shoulder.0,
161                        s_a.shoulder.1,
162                        s_a.shoulder.2 - foothoril * 1.0,
163                    );
164                    next.shoulder_r.orientation = Quaternion::rotation_x(
165                        move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
166                    );
167                },
168                _ => {
169                    next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
170                    next.control_r.position =
171                        Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
172
173                    next.control.position = Vec3::new(
174                        -3.0 + move1 * -5.0,
175                        3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
176                        -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
177                    );
178                    next.head.orientation =
179                        Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
180                    next.jaw.orientation = Quaternion::rotation_x(0.0);
181
182                    next.control_l.orientation =
183                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
184                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
185                        * Quaternion::rotation_y(0.5)
186                        * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
187
188                    next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
189                        * Quaternion::rotation_y(-0.1 + move1 * 0.6);
190                    next.shoulder_l.position = Vec3::new(
191                        -s_a.shoulder.0,
192                        s_a.shoulder.1,
193                        s_a.shoulder.2 - foothorir * 1.0,
194                    );
195                    next.shoulder_l.orientation = Quaternion::rotation_x(
196                        move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
197                    );
198                    next.shoulder_r.position = Vec3::new(
199                        s_a.shoulder.0,
200                        s_a.shoulder.1,
201                        s_a.shoulder.2 - foothoril * 1.0,
202                    );
203                    next.shoulder_r.orientation = Quaternion::rotation_x(
204                        move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
205                    );
206                },
207            },
208            Some(ToolKind::Hammer) => match ability_id {
209                Some("common.abilities.custom.dwarves.forgemaster.flamethrower") => {
210                    next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
211                    next.control_r.position =
212                        Vec3::new(-1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
213
214                    next.control.position = Vec3::new(
215                        -3.0 + move1 * -5.0,
216                        -2.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
217                        -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
218                    );
219                    next.head.orientation =
220                        Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
221                    next.jaw.orientation = Quaternion::rotation_x(0.0);
222
223                    next.control_l.orientation =
224                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
225                    next.control_r.orientation = Quaternion::rotation_x(move1 * 0.4)
226                        * Quaternion::rotation_y(0.8)
227                        * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
228
229                    next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
230                        * Quaternion::rotation_y(-0.1 + move1 * 0.3);
231                    next.shoulder_l.position = Vec3::new(
232                        -s_a.shoulder.0,
233                        s_a.shoulder.1,
234                        s_a.shoulder.2 - foothorir * 1.0,
235                    );
236                    next.shoulder_l.orientation = Quaternion::rotation_x(
237                        move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
238                    );
239                    next.shoulder_r.position = Vec3::new(
240                        s_a.shoulder.0,
241                        s_a.shoulder.1,
242                        s_a.shoulder.2 - foothoril * 1.0,
243                    );
244                    next.shoulder_r.orientation = Quaternion::rotation_x(
245                        move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
246                    );
247                },
248                _ => {
249                    next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
250                    next.control_r.position =
251                        Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
252
253                    next.control.position = Vec3::new(
254                        -3.0 + move1 * -5.0,
255                        3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
256                        -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
257                    );
258                    next.head.orientation =
259                        Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
260                    next.jaw.orientation = Quaternion::rotation_x(0.0);
261
262                    next.control_l.orientation =
263                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
264                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
265                        * Quaternion::rotation_y(0.5)
266                        * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
267
268                    next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
269                        * Quaternion::rotation_y(-0.1 + move1 * 0.6);
270                    next.shoulder_l.position = Vec3::new(
271                        -s_a.shoulder.0,
272                        s_a.shoulder.1,
273                        s_a.shoulder.2 - foothorir * 1.0,
274                    );
275                    next.shoulder_l.orientation = Quaternion::rotation_x(
276                        move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
277                    );
278                    next.shoulder_r.position = Vec3::new(
279                        s_a.shoulder.0,
280                        s_a.shoulder.1,
281                        s_a.shoulder.2 - foothoril * 1.0,
282                    );
283                    next.shoulder_r.orientation = Quaternion::rotation_x(
284                        move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
285                    );
286                },
287            },
288            Some(ToolKind::Natural) => match ability_id {
289                Some("common.abilities.custom.tidalwarrior.bubbles") => {
290                    if mirror > 0.0 {
291                        next.head.orientation = Quaternion::rotation_z(move1 * -0.6);
292                        next.upper_torso.orientation = Quaternion::rotation_z(move1 * 0.6);
293                        next.lower_torso.orientation = Quaternion::rotation_z(move1 * -0.6);
294
295                        next.shoulder_l.orientation = Quaternion::rotation_z(move1 * 0.3);
296                        next.hand_l.position = Vec3::new(-14.0 + move1 * 3.0, 2.0, -4.0);
297
298                        next.hand_l.orientation =
299                            Quaternion::rotation_x(PI / 3.0 + move2shake * -0.07)
300                                * Quaternion::rotation_y(move1 * -0.5)
301                                * Quaternion::rotation_z(-0.35 + move2shake * 0.07);
302                        next.hand_r.position = Vec3::new(14.0 + move1 - 3.0, 2.0, -4.0);
303
304                        next.hand_r.orientation =
305                            Quaternion::rotation_x(PI / 3.0 + move2shake * 0.07)
306                                * Quaternion::rotation_y(move1 * -0.5)
307                                * Quaternion::rotation_z(0.35 - move2shake * 0.07);
308
309                        next.shoulder_r.orientation = Quaternion::rotation_z(move1 * -0.3);
310                    } else {
311                        next.head.orientation = Quaternion::rotation_z(move1 * 0.6);
312                        next.upper_torso.orientation = Quaternion::rotation_z(move1 * -0.6);
313                        next.lower_torso.orientation = Quaternion::rotation_z(move1 * 0.6);
314
315                        next.shoulder_l.orientation = Quaternion::rotation_z(move1 * -0.3);
316                        next.hand_l.position = Vec3::new(-14.0 + move1 * 3.0, 2.0, -4.0);
317
318                        next.hand_l.orientation =
319                            Quaternion::rotation_x(PI / 3.0 + move2shake * 0.07)
320                                * Quaternion::rotation_y(move1 * 0.5)
321                                * Quaternion::rotation_z(-0.35 + move2shake * 0.07);
322                        next.hand_r.position = Vec3::new(14.0 + move1 - 3.0, 2.0, -4.0);
323
324                        next.hand_r.orientation =
325                            Quaternion::rotation_x(PI / 3.0 + move2shake * -0.07)
326                                * Quaternion::rotation_y(move1 * 0.5)
327                                * Quaternion::rotation_z(0.35 - move2shake * -0.07);
328
329                        next.shoulder_r.orientation = Quaternion::rotation_z(move1 * 0.3);
330                    };
331                },
332                Some("common.abilities.custom.yeti.frostbreath") => {
333                    next.second.scale = Vec3::one() * 0.0;
334
335                    next.head.orientation =
336                        Quaternion::rotation_x(move1 * 0.5 + move2 * -0.5 + move2shake * -0.02);
337                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
338                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.5 + move2shake * -0.1);
339                    next.control_l.position = Vec3::new(-0.5, 4.0, 1.0);
340                    next.control_r.position = Vec3::new(-0.5, 4.0, 1.0);
341                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
342                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
343
344                    next.weapon_l.position = Vec3::new(-12.0, -1.0, -15.0);
345                    next.weapon_r.position = Vec3::new(12.0, -1.0, -15.0);
346
347                    next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1);
348                    next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1);
349
350                    next.arm_control_r.orientation =
351                        Quaternion::rotation_x(move1 * 1.1 + move2 * -1.6)
352                            * Quaternion::rotation_y(move1 * 1.4 + move2 * -1.8);
353
354                    next.shoulder_l.orientation =
355                        Quaternion::rotation_x(move1 * 1.4 + move2 * -1.8);
356
357                    next.shoulder_r.orientation =
358                        Quaternion::rotation_x(move1 * 1.4 + move2 * -1.8);
359
360                    next.upper_torso.position = Vec3::new(
361                        0.0,
362                        s_a.upper_torso.0,
363                        s_a.upper_torso.1 + move1 * -1.9 + move2 * 1.2,
364                    );
365                    next.upper_torso.orientation =
366                        Quaternion::rotation_x(move1 * 0.8 + move2 * -1.1 + move2shake * -0.02);
367                    next.lower_torso.position =
368                        Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
369                    next.lower_torso.orientation =
370                        Quaternion::rotation_x(move1 * -0.8 + move2 * 1.1 + move2shake * 0.02);
371                },
372                Some("common.abilities.custom.harvester.firebreath") => {
373                    next.head.orientation =
374                        Quaternion::rotation_x(move1 * 0.5 + move2 * -0.4 + move2shake * -0.02);
375
376                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
377                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.5 + move2shake * -0.1);
378
379                    next.upper_torso.position = Vec3::new(
380                        0.0,
381                        s_a.upper_torso.0 + move1 * -3.0 + move2 * 3.0,
382                        s_a.upper_torso.1 + move1 * -0.4,
383                    );
384                    next.upper_torso.orientation =
385                        Quaternion::rotation_x(move1 * 0.8 + move2 * -1.1 + move2shake * -0.02);
386                    next.lower_torso.position =
387                        Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
388                    next.lower_torso.orientation =
389                        Quaternion::rotation_x(move1 * -0.8 + move2 * 1.1 + move2shake * 0.02);
390
391                    next.control_l.position = Vec3::new(1.0, 2.0, 8.0);
392                    next.control_r.position = Vec3::new(1.0, 1.0, -2.0);
393
394                    next.control.position =
395                        Vec3::new(-6.0, 0.0 + s_a.grip.0 / 1.0, -s_a.grip.0 / 0.8);
396
397                    next.control_l.orientation =
398                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_z(PI);
399                    next.control_r.orientation =
400                        Quaternion::rotation_x(PI / 2.0 + 0.2) * Quaternion::rotation_y(-1.0);
401
402                    next.control.orientation =
403                        Quaternion::rotation_x(-1.4) * Quaternion::rotation_y(-2.8);
404
405                    next.weapon_l.position = Vec3::new(move1 * 8.0, move1 * 1.0, move1 * 6.0);
406                    next.weapon_l.orientation =
407                        Quaternion::rotation_x(move1 * 0.5) * Quaternion::rotation_y(move1 * -0.8);
408
409                    next.shoulder_l.position = Vec3::new(
410                        -s_a.shoulder.0,
411                        s_a.shoulder.1,
412                        s_a.shoulder.2 - foothorir * 1.0,
413                    );
414                    next.shoulder_l.orientation = Quaternion::rotation_y(-0.4 + move1 * 0.8)
415                        * Quaternion::rotation_x(-0.4 + move1 * -0.2);
416                    next.shoulder_r.orientation = Quaternion::rotation_y(0.4 + move1 * -0.8)
417                        * Quaternion::rotation_x(0.4 + move1 * -0.8);
418
419                    next.hand_r.position = Vec3::new(
420                        -s_a.grip.1 + move1 * -5.0,
421                        0.0 + move1 * 6.0,
422                        s_a.grip.0 + move1 * 13.0,
423                    );
424                    next.hand_r.orientation = Quaternion::rotation_x(move1 * -3.0)
425                        * Quaternion::rotation_y(move1 * 1.5)
426                        * Quaternion::rotation_z(move1 * -1.5);
427                },
428                _ => {},
429            },
430            _ => {},
431        }
432
433        next
434    }
435}