veloren_voxygen_anim/character/
music.rs

1use super::{
2    super::{Animation, vek::*},
3    CharacterSkeleton, SkeletonAttr,
4};
5use common::{
6    comp::item::{Hands, ToolKind},
7    states::utils::AbilityInfo,
8};
9use std::{f32::consts::PI, ops::Mul};
10
11pub struct MusicAnimation;
12
13type MusicAnimationDependency<'a> = (
14    (Option<Hands>, Option<Hands>),
15    (Option<AbilityInfo>, f32),
16    Vec3<f32>,
17    Option<&'a str>,
18);
19impl Animation for MusicAnimation {
20    type Dependency<'a> = MusicAnimationDependency<'a>;
21    type Skeleton = CharacterSkeleton;
22
23    #[cfg(feature = "use-dyn-lib")]
24    const UPDATE_FN: &'static [u8] = b"character_music\0";
25
26    #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "character_music"))]
27    fn update_skeleton_inner(
28        skeleton: &Self::Skeleton,
29        (_hands, (ability_info, global_time), rel_vel, ability_id): Self::Dependency<'_>,
30        anim_time: f32,
31        rate: &mut f32,
32        s_a: &SkeletonAttr,
33    ) -> Self::Skeleton {
34        let mut next = (*skeleton).clone();
35
36        *rate = 2.0;
37
38        let lab: f32 = 1.0;
39        let short = ((5.0 / (3.0 + 2.0 * ((anim_time * lab * 6.0).sin()).powi(2))).sqrt())
40            * ((anim_time * lab * 6.0).sin());
41        let noisea = (anim_time * 11.0 + PI / 6.0).sin();
42        let noiseb = (anim_time * 19.0 + PI / 4.0).sin();
43
44        let shorte = (anim_time * lab * 6.0).sin();
45        let shorter = (anim_time * lab * 6.0 + PI * 2.0).sin();
46        let shortealt_raw = (anim_time * lab * 6.0 + PI / 2.0).sin();
47
48        let shortealt_slow = (anim_time * lab * 3.0 + PI / 2.0).sin();
49        let shortealt = match ability_id {
50            Some("common.abilities.music.viola_pizzicato") => shortealt_slow,
51            _ => shortealt_raw,
52        };
53        let foot = ((0.1 / (1.0 + (4.0) * ((anim_time * lab * 8.0).sin()).powi(2))).sqrt())
54            * ((anim_time * lab * 8.0).sin());
55
56        // common animations
57        next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + shortealt * 1.5);
58        next.chest.orientation = Quaternion::rotation_z(short * 0.35)
59            * Quaternion::rotation_y(shorte * 0.08)
60            * Quaternion::rotation_x(foot * 0.07);
61
62        next.belt.position = Vec3::new(0.0, s_a.belt.0, s_a.belt.1);
63        next.belt.orientation = Quaternion::rotation_z(shorte * 0.25);
64
65        next.back.position = Vec3::new(0.0, s_a.back.0, s_a.back.1);
66        next.back.orientation =
67            Quaternion::rotation_x(-0.25 + shorte * 0.1 + noisea * 0.1 + noiseb * 0.1);
68
69        next.shorts.position = Vec3::new(0.0, s_a.shorts.0, s_a.shorts.1);
70        next.shorts.orientation = Quaternion::rotation_z(foot * 0.35);
71
72        // don't override run animation when instruments are played moving
73        if rel_vel.magnitude() < 0.1
74            && !matches!(ability_id, Some("common.abilities.music.viola_pizzicato",))
75        {
76            next.foot_l.position = Vec3::new(
77                -s_a.foot.0 + foot * 0.8,
78                1.5 + -s_a.foot.1 + foot * -4.0,
79                s_a.foot.2,
80            );
81            next.foot_l.orientation =
82                Quaternion::rotation_x(foot * -0.3) * Quaternion::rotation_z(short * -0.15);
83
84            next.foot_r.position = Vec3::new(
85                s_a.foot.0 + foot * 0.8,
86                1.5 + -s_a.foot.1 + foot * 4.0,
87                s_a.foot.2,
88            );
89            next.foot_r.orientation =
90                Quaternion::rotation_x(foot * 0.3) * Quaternion::rotation_z(short * 0.15);
91        };
92        next.shoulder_l.position = Vec3::new(-s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2);
93        next.shoulder_l.orientation = Quaternion::rotation_x(shorte * 0.15);
94
95        next.shoulder_r.position = Vec3::new(s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2);
96        next.shoulder_r.orientation = Quaternion::rotation_x(shorte * -0.15);
97
98        next.lantern.orientation = match ability_id {
99            Some("common.abilities.music.kora" | "common.abilities.music.banjo") => {
100                Quaternion::rotation_x(shorte * 0.2) * Quaternion::rotation_y(shorte * 0.2)
101            },
102            _ => Quaternion::rotation_x(shorte * 0.7 + 0.4) * Quaternion::rotation_y(shorte * 0.4),
103        };
104
105        next.torso.position = Vec3::new(0.0, -3.3, 0.0);
106        next.torso.orientation = Quaternion::rotation_z(short * -0.2);
107
108        let head_look = Vec2::new(
109            (global_time + anim_time / 6.0).floor().mul(7331.0).sin() * 0.3,
110            (global_time + anim_time / 6.0).floor().mul(1337.0).sin() * 0.15,
111        );
112
113        match ability_info.and_then(|a| a.tool) {
114            Some(ToolKind::Instrument) => {
115                // instrument specific head_bop
116                let head_bop = match ability_id {
117                    Some("common.abilities.music.viola_pizzicato") => 0.1,
118                    Some(
119                        "common.abilities.music.flute"
120                        | "common.abilities.music.glass_flute"
121                        | "common.abilities.music.starlight_conch"
122                        | "common.abilities.music.melodica",
123                    ) => 0.2,
124                    Some(
125                        "common.abilities.music.guitar"
126                        | "common.abilities.music.dark_guitar"
127                        | "common.abilities.music.lute"
128                        | "common.abilities.music.oud"
129                        | "common.abilities.music.kora"
130                        | "common.abilities.music.banjo"
131                        | "common.abilities.music.sitar",
132                    ) => 0.5,
133
134                    Some(
135                        "common.abilities.music.lyre"
136                        | "common.abilities.music.icy_talharpa"
137                        | "common.abilities.music.shamisen"
138                        | "common.abilities.music.kalimba"
139                        | "common.abilities.music.timbrel_of_chaos"
140                        | "common.abilities.music.rhythmo"
141                        | "common.abilities.music.steeltonguedrum",
142                    ) => 0.3,
143                    _ => 1.0,
144                };
145                next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
146                next.head.orientation = Quaternion::rotation_z((short * head_bop) * -0.6)
147                    * Quaternion::rotation_x(
148                        0.2 + head_look.y.max(0.0) + (shorte * head_bop).abs() * -0.2,
149                    );
150                // instrument specific hand and instrument animations
151                match ability_id {
152                    Some("common.abilities.music.double_bass") => {
153                        next.hand_l.position = Vec3::new(
154                            3.5 - s_a.hand.0,
155                            7.0 + s_a.hand.1 + shortealt * -3.0,
156                            8.0 + s_a.hand.2 + shortealt * -0.75,
157                        );
158                        next.hand_l.orientation = Quaternion::rotation_x(2.4 + foot * 0.15)
159                            * Quaternion::rotation_y(-0.5);
160
161                        next.hand_r.position = Vec3::new(
162                            -2.0 + s_a.hand.0,
163                            4.0 + s_a.hand.1 + shortealt * 6.0,
164                            4.0 + s_a.hand.2 + shortealt * 0.75,
165                        );
166                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
167                            * Quaternion::rotation_y(0.4);
168
169                        next.main.position = Vec3::new(-4.0, 6.0, 16.0);
170                        next.main.orientation = Quaternion::rotation_x(0.1)
171                            * Quaternion::rotation_y(3.0)
172                            * Quaternion::rotation_z(PI / -3.0);
173                    },
174                    Some("common.abilities.music.kora") => {
175                        next.hand_l.position = Vec3::new(
176                            5.0 - s_a.hand.0 + shortealt * 1.0,
177                            8.0 + s_a.hand.1 + shortealt * -1.0,
178                            5.0 + s_a.hand.2 + shortealt * -0.5,
179                        );
180                        next.hand_l.orientation = Quaternion::rotation_x(1.2 + foot * 0.15)
181                            * Quaternion::rotation_y(-0.5 - foot * 0.3);
182
183                        next.hand_r.position = Vec3::new(
184                            -4.5 + s_a.hand.0 - shortealt * 1.0,
185                            8.0 + s_a.hand.1 + shortealt * 1.0,
186                            4.0 + s_a.hand.2 + shortealt * 0.5,
187                        );
188                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
189                            * Quaternion::rotation_y(0.4 + foot * 0.3);
190
191                        next.main.position = Vec3::new(0.0, 16.0, 14.0);
192                        next.main.orientation = Quaternion::rotation_x(-0.5)
193                            * Quaternion::rotation_y(3.0)
194                            * Quaternion::rotation_z(1.3);
195                    },
196                    Some("common.abilities.music.flute" | "common.abilities.music.glass_flute") => {
197                        next.hand_l.position = Vec3::new(
198                            4.0 - s_a.hand.0,
199                            6.0 + s_a.hand.1 + shortealt * -0.5,
200                            4.0 + s_a.hand.2 + shortealt * -0.75,
201                        );
202                        next.hand_l.orientation = Quaternion::rotation_x(2.4 + foot * 0.15)
203                            * Quaternion::rotation_y(-0.9);
204
205                        next.hand_r.position = Vec3::new(
206                            -4.5 + s_a.hand.0,
207                            4.0 + s_a.hand.1 + shortealt * 2.0,
208                            2.0 + s_a.hand.2 + shortealt * 0.75,
209                        );
210                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
211                            * Quaternion::rotation_y(0.6);
212
213                        next.main.position = Vec3::new(-2.5, 10.0, -11.0);
214                        next.main.orientation = Quaternion::rotation_x(3.5)
215                            * Quaternion::rotation_y(PI)
216                            * Quaternion::rotation_z(0.05);
217                    },
218                    Some("common.abilities.music.starlight_conch") => {
219                        next.hand_l.position =
220                            Vec3::new(2.0 - s_a.hand.0, 6.0 + s_a.hand.1, 4.0 + s_a.hand.2);
221                        next.hand_l.orientation = Quaternion::rotation_x(2.4 + foot * 0.15)
222                            * Quaternion::rotation_y(-0.9);
223
224                        next.hand_r.position =
225                            Vec3::new(-2.5 + s_a.hand.0, 6.0 + s_a.hand.1, 2.0 + s_a.hand.2);
226                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
227                            * Quaternion::rotation_y(0.6);
228
229                        next.main.position = Vec3::new(-0.5, 18.0, -6.0);
230                        next.main.orientation = Quaternion::rotation_x(4.2)
231                            * Quaternion::rotation_y(PI)
232                            * Quaternion::rotation_z(0.05);
233                    },
234                    Some(
235                        "common.abilities.music.guitar" | "common.abilities.music.dark_guitar",
236                    ) => {
237                        next.hand_l.position = Vec3::new(
238                            1.0 - s_a.hand.0,
239                            6.0 + s_a.hand.1 + shortealt * -1.0,
240                            2.0 + s_a.hand.2 + shortealt * -1.5,
241                        );
242                        next.hand_l.orientation = Quaternion::rotation_x(1.8 + foot * 0.15)
243                            * Quaternion::rotation_y(-0.6)
244                            * Quaternion::rotation_z(0.8);
245
246                        next.hand_r.position = Vec3::new(
247                            -2.0 + s_a.hand.0 - shortealt * 1.25,
248                            6.0 + s_a.hand.1 + shortealt * 2.0,
249                            3.0 + s_a.hand.2 + shortealt * 0.25,
250                        );
251                        next.hand_r.orientation = Quaternion::rotation_x(1.0 + foot * -0.15)
252                            * Quaternion::rotation_y(0.6);
253
254                        next.main.position = Vec3::new(-14.0, 6.0, 5.0);
255                        next.main.orientation = Quaternion::rotation_x(0.1)
256                            * Quaternion::rotation_y(2.0)
257                            * Quaternion::rotation_z(PI / -3.0);
258                    },
259                    Some(
260                        "common.abilities.music.lyre"
261                        | "common.abilities.music.wildskin_drum"
262                        | "common.abilities.music.steeltonguedrum"
263                        | "common.abilities.music.timbrel_of_chaos"
264                        | "common.abilities.music.icy_talharpa",
265                    ) => {
266                        next.hand_l.position = Vec3::new(
267                            3.0 - s_a.hand.0,
268                            4.0 + s_a.hand.1 + shortealt * -0.1,
269                            1.0 + s_a.hand.2 + shortealt * -0.2,
270                        );
271                        next.hand_l.orientation = Quaternion::rotation_x(1.4 + foot * 0.15)
272                            * Quaternion::rotation_y(-0.6);
273
274                        next.hand_r.position = Vec3::new(
275                            -4.0 + s_a.hand.0 + shortealt * 2.0,
276                            5.0 + s_a.hand.1 - shortealt * 3.0,
277                            2.0 + s_a.hand.2 + shortealt * 0.75,
278                        );
279                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
280                            * Quaternion::rotation_y(0.9);
281
282                        next.main.position = Vec3::new(8.0, 14.0, -6.0);
283                        next.main.orientation = Quaternion::rotation_x(0.2)
284                            * Quaternion::rotation_y(-0.75)
285                            * Quaternion::rotation_z(0.20);
286                    },
287                    Some("common.abilities.music.kalimba") => {
288                        next.hand_l.position = Vec3::new(
289                            3.0 - s_a.hand.0,
290                            4.0 + s_a.hand.1 + shortealt * -0.1,
291                            1.0 + s_a.hand.2 + shortealt * -0.2,
292                        );
293                        next.hand_l.orientation = Quaternion::rotation_x(1.4 + foot * 0.15)
294                            * Quaternion::rotation_y(-0.6);
295
296                        next.hand_r.position = Vec3::new(
297                            -2.0 + s_a.hand.0 + shortealt * 2.0,
298                            5.0 + s_a.hand.1 - shortealt * 3.0,
299                            2.0 + s_a.hand.2 + shortealt * 0.75,
300                        );
301                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
302                            * Quaternion::rotation_y(0.9);
303
304                        next.main.position = Vec3::new(8.0, 12.0, -8.0);
305                        next.main.orientation = Quaternion::rotation_x(0.2)
306                            * Quaternion::rotation_y(-0.75)
307                            * Quaternion::rotation_z(PI - 0.2);
308                    },
309                    Some("common.abilities.music.viola_pizzicato") => {
310                        next.hand_l.position = Vec3::new(
311                            -3.0 - s_a.hand.0,
312                            8.0 + s_a.hand.1 + shortealt * 1.5,
313                            2.0 + s_a.hand.2 + shortealt * 0.6,
314                        );
315                        next.hand_l.orientation = Quaternion::rotation_x(1.0 + foot * 0.15)
316                            * Quaternion::rotation_y(-0.6)
317                            * Quaternion::rotation_z(PI / 1.5);
318
319                        next.hand_r.position = Vec3::new(
320                            -6.0 + s_a.hand.0 - shortealt * 3.0,
321                            8.5 + s_a.hand.1 - shortealt * 1.5,
322                            5.0 + s_a.hand.2 + shortealt * 0.75,
323                        );
324                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
325                            * Quaternion::rotation_y(0.9);
326
327                        next.main.position = Vec3::new(-9.0, 13.0, -5.0);
328                        next.main.orientation = Quaternion::rotation_x(PI / 4.0)
329                            * Quaternion::rotation_y(PI / 6.0)
330                            * Quaternion::rotation_z(PI / -1.5);
331                    },
332                    Some("common.abilities.music.rhythmo") => {
333                        next.main.scale = Vec3::one() * (1.0 - shorter / 12.0);
334                        next.hand_l.position =
335                            Vec3::new(3.0 - s_a.hand.0, 4.0 + s_a.hand.1, 1.0 + s_a.hand.2);
336                        next.hand_l.orientation =
337                            Quaternion::rotation_x(1.4 + foot * 0.1) * Quaternion::rotation_y(-0.6);
338
339                        next.hand_r.position =
340                            Vec3::new(-2.0 + s_a.hand.0, 5.0 + s_a.hand.1, 2.0 + s_a.hand.2);
341                        next.hand_r.orientation =
342                            Quaternion::rotation_x(1.4 + foot * -0.1) * Quaternion::rotation_y(0.9);
343
344                        next.main.position = Vec3::new(6.0, 8.0, -6.0);
345                        next.main.orientation = Quaternion::rotation_x(0.2)
346                            * Quaternion::rotation_y(-0.75)
347                            * Quaternion::rotation_z(PI - 0.2);
348                    },
349                    Some(
350                        "common.abilities.music.lute"
351                        | "common.abilities.music.shamisen"
352                        | "common.abilities.music.banjo",
353                    ) => {
354                        next.hand_l.position = Vec3::new(
355                            2.0 - s_a.hand.0,
356                            5.0 + s_a.hand.1 + shortealt * -1.0,
357                            2.0 + s_a.hand.2 + shortealt * -1.5,
358                        );
359                        next.hand_l.orientation = Quaternion::rotation_x(1.8 + foot * 0.15)
360                            * Quaternion::rotation_y(-0.6)
361                            * Quaternion::rotation_z(0.8);
362
363                        next.hand_r.position = Vec3::new(
364                            -1.0 + s_a.hand.0 - shortealt * 1.25,
365                            6.0 + s_a.hand.1 + shortealt * 2.0,
366                            2.0 + s_a.hand.2 + shortealt * 0.25,
367                        );
368                        next.hand_r.orientation = Quaternion::rotation_x(1.0 + foot * -0.15)
369                            * Quaternion::rotation_y(0.6);
370
371                        next.main.position = Vec3::new(-14.0, 6.0, 4.0);
372                        next.main.orientation = Quaternion::rotation_x(0.1)
373                            * Quaternion::rotation_y(2.0)
374                            * Quaternion::rotation_z(PI / -3.0);
375                    },
376                    Some("common.abilities.music.oud") => {
377                        next.hand_l.position = Vec3::new(
378                            2.0 - s_a.hand.0,
379                            5.0 + s_a.hand.1 + shortealt * -1.0,
380                            2.0 + s_a.hand.2 + shortealt * -1.5,
381                        );
382                        next.hand_l.orientation = Quaternion::rotation_x(1.8 + foot * 0.15)
383                            * Quaternion::rotation_y(-0.6)
384                            * Quaternion::rotation_z(0.8);
385
386                        next.hand_r.position = Vec3::new(
387                            -1.0 + s_a.hand.0 - shortealt * 2.25,
388                            6.0 + s_a.hand.1 + shortealt * 2.0,
389                            2.0 + s_a.hand.2 + shortealt * 0.25,
390                        );
391                        next.hand_r.orientation = Quaternion::rotation_x(1.0 + foot * -0.15)
392                            * Quaternion::rotation_y(0.6);
393
394                        next.main.position = Vec3::new(-14.0, 6.0, 4.0);
395                        next.main.orientation = Quaternion::rotation_x(0.1)
396                            * Quaternion::rotation_y(2.0)
397                            * Quaternion::rotation_z(PI / -3.0);
398                    },
399                    Some("common.abilities.music.melodica") => {
400                        next.hand_l.position = Vec3::new(
401                            4.0 - s_a.hand.0,
402                            6.0 + s_a.hand.1 + shortealt * -0.5,
403                            4.0 + s_a.hand.2 + shortealt * -0.75,
404                        );
405                        next.hand_l.orientation = Quaternion::rotation_x(2.4 + foot * 0.15)
406                            * Quaternion::rotation_y(-0.9);
407
408                        next.hand_r.position = Vec3::new(
409                            -3.5 + s_a.hand.0,
410                            4.0 + s_a.hand.1 + shortealt * 2.0,
411                            2.0 + s_a.hand.2 + shortealt * 0.75,
412                        );
413                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
414                            * Quaternion::rotation_y(0.6);
415
416                        next.main.position = Vec3::new(-1.0, 2.0, 16.0);
417                        next.main.orientation = Quaternion::rotation_x(0.3)
418                            * Quaternion::rotation_y(PI)
419                            * Quaternion::rotation_z(PI / -2.0);
420                    },
421                    Some("common.abilities.music.washboard") => {
422                        next.hand_l.position = Vec3::new(
423                            3.0 - s_a.hand.0,
424                            4.0 + s_a.hand.1 + shortealt * -0.1,
425                            1.0 + s_a.hand.2 + shortealt * -0.2,
426                        );
427                        next.hand_l.orientation = Quaternion::rotation_x(1.4 + foot * 0.15)
428                            * Quaternion::rotation_y(-0.6);
429
430                        next.hand_r.position = Vec3::new(
431                            -4.0 + s_a.hand.0 + shortealt * 2.0,
432                            5.0 + s_a.hand.1 - shortealt * 3.0,
433                            2.0 + s_a.hand.2 + shortealt * 0.75,
434                        );
435                        next.hand_r.orientation = Quaternion::rotation_x(1.4 + foot * -0.15)
436                            * Quaternion::rotation_y(0.9);
437
438                        next.main.position = Vec3::new(8.0, 14.0, -6.0);
439                        next.main.orientation = Quaternion::rotation_x(0.2)
440                            * Quaternion::rotation_y(-0.75)
441                            * Quaternion::rotation_z(0.20);
442                    },
443                    Some("common.abilities.music.sitar") => {
444                        next.hand_l.position = Vec3::new(
445                            2.0 - s_a.hand.0,
446                            6.0 + s_a.hand.1 + shortealt * -1.0,
447                            1.0 + s_a.hand.2 + shortealt * -1.5,
448                        );
449                        next.hand_l.orientation = Quaternion::rotation_x(1.8 + foot * 0.15)
450                            * Quaternion::rotation_y(-0.6)
451                            * Quaternion::rotation_z(0.8);
452
453                        next.hand_r.position = Vec3::new(
454                            -2.0 + s_a.hand.0 - shortealt * 1.25,
455                            6.0 + s_a.hand.1 + shortealt * 2.0,
456                            2.0 + s_a.hand.2 + shortealt * 0.25,
457                        );
458                        next.hand_r.orientation = Quaternion::rotation_x(1.0 + foot * -0.15)
459                            * Quaternion::rotation_y(0.6);
460
461                        next.main.position = Vec3::new(-15.0, 6.0, 4.0);
462                        next.main.orientation = Quaternion::rotation_x(0.1)
463                            * Quaternion::rotation_y(2.0)
464                            * Quaternion::rotation_z(PI / -3.0);
465                    },
466                    _ => {},
467                }
468            },
469            _ => {},
470        }
471
472        if skeleton.holding_lantern {
473            next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1 + 5.0, s_a.hand.2 + 12.0);
474            next.hand_r.orientation = Quaternion::rotation_x(2.25) * Quaternion::rotation_z(0.9);
475
476            next.lantern.position = Vec3::new(-0.5, -0.5, 5.5);
477            next.lantern.orientation = next.hand_r.orientation.inverse();
478        }
479
480        next
481    }
482}