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", unsafe(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.yeti.frostbreath") => {
290                    next.second.scale = Vec3::one() * 0.0;
291
292                    next.head.orientation =
293                        Quaternion::rotation_x(move1 * 0.5 + move2 * -0.5 + move2shake * -0.02);
294                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
295                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.5 + move2shake * -0.1);
296                    next.control_l.position = Vec3::new(-0.5, 4.0, 1.0);
297                    next.control_r.position = Vec3::new(-0.5, 4.0, 1.0);
298                    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
299                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0);
300
301                    next.weapon_l.position = Vec3::new(-12.0, -1.0, -15.0);
302                    next.weapon_r.position = Vec3::new(12.0, -1.0, -15.0);
303
304                    next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1);
305                    next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1);
306
307                    next.arm_control_r.orientation =
308                        Quaternion::rotation_x(move1 * 1.1 + move2 * -1.6)
309                            * Quaternion::rotation_y(move1 * 1.4 + move2 * -1.8);
310
311                    next.shoulder_l.orientation =
312                        Quaternion::rotation_x(move1 * 1.4 + move2 * -1.8);
313
314                    next.shoulder_r.orientation =
315                        Quaternion::rotation_x(move1 * 1.4 + move2 * -1.8);
316
317                    next.upper_torso.position = Vec3::new(
318                        0.0,
319                        s_a.upper_torso.0,
320                        s_a.upper_torso.1 + move1 * -1.9 + move2 * 1.2,
321                    );
322                    next.upper_torso.orientation =
323                        Quaternion::rotation_x(move1 * 0.8 + move2 * -1.1 + move2shake * -0.02);
324                    next.lower_torso.position =
325                        Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
326                    next.lower_torso.orientation =
327                        Quaternion::rotation_x(move1 * -0.8 + move2 * 1.1 + move2shake * 0.02);
328                },
329                Some("common.abilities.custom.harvester.firebreath") => {
330                    next.head.orientation =
331                        Quaternion::rotation_x(move1 * 0.5 + move2 * -0.4 + move2shake * -0.02);
332
333                    next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
334                    next.jaw.orientation = Quaternion::rotation_x(move2 * -0.5 + move2shake * -0.1);
335
336                    next.upper_torso.position = Vec3::new(
337                        0.0,
338                        s_a.upper_torso.0 + move1 * -3.0 + move2 * 3.0,
339                        s_a.upper_torso.1 + move1 * -0.4,
340                    );
341                    next.upper_torso.orientation =
342                        Quaternion::rotation_x(move1 * 0.8 + move2 * -1.1 + move2shake * -0.02);
343                    next.lower_torso.position =
344                        Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
345                    next.lower_torso.orientation =
346                        Quaternion::rotation_x(move1 * -0.8 + move2 * 1.1 + move2shake * 0.02);
347
348                    next.control_l.position = Vec3::new(1.0, 2.0, 8.0);
349                    next.control_r.position = Vec3::new(1.0, 1.0, -2.0);
350
351                    next.control.position =
352                        Vec3::new(-6.0, 0.0 + s_a.grip.0 / 1.0, -s_a.grip.0 / 0.8);
353
354                    next.control_l.orientation =
355                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_z(PI);
356                    next.control_r.orientation =
357                        Quaternion::rotation_x(PI / 2.0 + 0.2) * Quaternion::rotation_y(-1.0);
358
359                    next.control.orientation =
360                        Quaternion::rotation_x(-1.4) * Quaternion::rotation_y(-2.8);
361
362                    next.weapon_l.position = Vec3::new(move1 * 8.0, move1 * 1.0, move1 * 6.0);
363                    next.weapon_l.orientation =
364                        Quaternion::rotation_x(move1 * 0.5) * Quaternion::rotation_y(move1 * -0.8);
365
366                    next.shoulder_l.position = Vec3::new(
367                        -s_a.shoulder.0,
368                        s_a.shoulder.1,
369                        s_a.shoulder.2 - foothorir * 1.0,
370                    );
371                    next.shoulder_l.orientation = Quaternion::rotation_y(-0.4 + move1 * 0.8)
372                        * Quaternion::rotation_x(-0.4 + move1 * -0.2);
373                    next.shoulder_r.orientation = Quaternion::rotation_y(0.4 + move1 * -0.8)
374                        * Quaternion::rotation_x(0.4 + move1 * -0.8);
375
376                    next.hand_r.position = Vec3::new(
377                        -s_a.grip.1 + move1 * -5.0,
378                        0.0 + move1 * 6.0,
379                        s_a.grip.0 + move1 * 13.0,
380                    );
381                    next.hand_r.orientation = Quaternion::rotation_x(move1 * -3.0)
382                        * Quaternion::rotation_y(move1 * 1.5)
383                        * Quaternion::rotation_z(move1 * -1.5);
384                },
385                _ => {},
386            },
387            Some(ToolKind::Spear) => match ability_id {
388                Some("common.abilities.custom.tidalwarrior.bubbles") => {
389                    next.upper_torso.orientation = Quaternion::rotation_x(-0.1);
390                    next.jaw.orientation = Quaternion::rotation_x(move1 * -0.6);
391                    next.control_l.position = Vec3::new(-1.0, 4.0, 8.0);
392                    next.control_r.position = Vec3::new(17.0, 7.0, 2.0);
393
394                    next.control.position =
395                        Vec3::new(-3.0, 3.0 + s_a.grip.0 / 1.2, -11.0 + -s_a.grip.0 / 2.0);
396
397                    next.control_l.orientation =
398                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.9);
399                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.5)
400                        * Quaternion::rotation_y(0.2)
401                        * Quaternion::rotation_z(0.0);
402
403                    next.control.orientation =
404                        Quaternion::rotation_x(-0.2) * Quaternion::rotation_y(-0.3);
405                },
406                _ => {
407                    next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
408                    next.control_r.position =
409                        Vec3::new(1.0 + move1 * 5.0, 2.0 + move1 * 1.0, 2.0 + move1 * 14.0);
410
411                    next.control.position = Vec3::new(
412                        -3.0 + move1 * -5.0,
413                        3.0 + s_a.grip.0 / 1.2 + move1 * 3.0 + move2shake * 1.0,
414                        -11.0 + -s_a.grip.0 / 2.0 + move1 * -2.0,
415                    );
416                    next.head.orientation =
417                        Quaternion::rotation_x(move1 * -0.2) * Quaternion::rotation_y(move1 * 0.2);
418                    next.jaw.orientation = Quaternion::rotation_x(0.0);
419
420                    next.control_l.orientation =
421                        Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_y(-0.5);
422                    next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.4)
423                        * Quaternion::rotation_y(0.5)
424                        * Quaternion::rotation_z(move1 * 1.2 + move2shake * 0.5);
425
426                    next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * -0.1)
427                        * Quaternion::rotation_y(-0.1 + move1 * 0.6);
428                    next.shoulder_l.position = Vec3::new(
429                        -s_a.shoulder.0,
430                        s_a.shoulder.1,
431                        s_a.shoulder.2 - foothorir * 1.0,
432                    );
433                    next.shoulder_l.orientation = Quaternion::rotation_x(
434                        move1 * 0.2 + 0.3 + 0.8 * speednorm + (footrotr * -0.2),
435                    );
436                    next.shoulder_r.position = Vec3::new(
437                        s_a.shoulder.0,
438                        s_a.shoulder.1,
439                        s_a.shoulder.2 - foothoril * 1.0,
440                    );
441                    next.shoulder_r.orientation = Quaternion::rotation_x(
442                        move1 * 0.2 + 0.3 + 0.6 * speednorm + (footrotl * -0.2),
443                    );
444                },
445            },
446            _ => {},
447        }
448
449        next
450    }
451}