veloren_voxygen_anim/character/
throw.rs

1use std::f32::consts::PI;
2
3use common::{
4    comp::tool::ToolKind,
5    states::utils::{HandInfo, StageSection},
6};
7
8use crate::{
9    Animation,
10    character::{CharacterSkeleton, SkeletonAttr, twist_back, twist_forward},
11    vek::*,
12};
13
14pub struct ThrowAnimation;
15
16type ThrowDependency = (Option<StageSection>, ToolKind, HandInfo);
17
18impl Animation for ThrowAnimation {
19    type Dependency<'a> = ThrowDependency;
20    type Skeleton = CharacterSkeleton;
21
22    #[cfg(feature = "use-dyn-lib")]
23    const UPDATE_FN: &'static [u8] = b"character_throw";
24
25    #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "character_throw"))]
26    fn update_skeleton_inner(
27        skeleton: &Self::Skeleton,
28        (stage_section, tool_kind, hand_info): Self::Dependency<'_>,
29        anim_time: f32,
30        rate: &mut f32,
31        _s_a: &SkeletonAttr,
32    ) -> Self::Skeleton {
33        *rate = 1.0;
34        let mut next = (*skeleton).clone();
35
36        let (move1base, chargebase, move2base, move3base) = match stage_section {
37            Some(StageSection::Buildup) => (anim_time, 0.0, 0.0, 0.0),
38            Some(StageSection::Charge) => (1.0, anim_time, 0.0, 0.0),
39            Some(StageSection::Action) => (1.0, 1.0, anim_time, 0.0),
40            Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time),
41            _ => (0.0, 0.0, 0.0, 0.0),
42        };
43        let pullback = 1.0 - move3base;
44        let move1 = move1base * pullback;
45        let charge = chargebase.min(1.0);
46        let tension = 0.5 * (chargebase * 16.0).sin();
47        let move2 = move2base * pullback;
48
49        match tool_kind {
50            ToolKind::Throwable => {
51                next.main.position += Vec3::new(0.0, 0.0, 4.0);
52                next.main.orientation.rotate_x(-PI / 2.0);
53                next.main.scale = Vec3::one();
54                next.second.position += Vec3::new(0.0, 0.0, 4.0);
55                next.second.orientation.rotate_x(-PI / 2.0);
56                next.second.scale = Vec3::one();
57
58                match hand_info {
59                    HandInfo::MainHand => {
60                        twist_back(&mut next, move1, 0.5, 0.5, 0.2, 0.4);
61                        next.control_l.position += Vec3::new(-6.0, 0.0, 0.0) * move1;
62                        next.control_l.orientation.rotate_x(PI / 2.0 * move1);
63                        next.control_r.position += Vec3::new(6.0, 0.0, 0.0) * move1;
64                        next.foot_l.position += Vec3::new(0.0, -2.0, 0.0) * move1;
65                        next.foot_l.orientation.rotate_z(PI / 4.0 * move1);
66                        next.foot_r.position += Vec3::new(0.0, 2.0, 0.0) * move1;
67                        next.foot_r.orientation.rotate_z(PI / 8.0 * move1);
68
69                        twist_back(&mut next, charge, 1.0, 1.0, 0.2, 0.4);
70                        next.control_l.position += Vec3::new(tension, 6.0, 4.0) * charge;
71                        next.control_l.orientation.rotate_y(PI / 4.0 * charge);
72                        next.control_r.position += Vec3::new(6.0, 0.0, -2.0) * charge;
73                        next.control_r.orientation.rotate_y(-PI / 2.0 * charge);
74
75                        twist_forward(&mut next, move2, 3.0, 2.8, 0.2, 0.4);
76                        next.control_l.position += Vec3::new(6.0, 14.0, -4.0) * move2;
77                        next.foot_l.position += Vec3::new(0.0, 4.0, 0.0) * move2;
78                        next.foot_l.orientation.rotate_z(-PI / 2.0 * move2);
79                        next.foot_r.position += Vec3::new(0.0, -4.0, 0.0) * move2;
80                        next.foot_r.orientation.rotate_z(-PI / 4.0 * move2);
81                    },
82                    HandInfo::OffHand => {
83                        twist_forward(&mut next, move1, 0.5, 0.5, 0.2, 0.4);
84                        next.control_l.position += Vec3::new(-6.0, 0.0, 0.0) * move1;
85                        next.control_r.position += Vec3::new(6.0, 0.0, 0.0) * move1;
86                        next.control_r.orientation.rotate_x(PI / 2.0 * move1);
87                        next.foot_l.position += Vec3::new(0.0, 2.0, 0.0) * move1;
88                        next.foot_l.orientation.rotate_z(-PI / 8.0 * move1);
89                        next.foot_r.position += Vec3::new(0.0, -2.0, 0.0) * move1;
90                        next.foot_r.orientation.rotate_z(-PI / 4.0 * move1);
91
92                        twist_forward(&mut next, charge, 1.0, 1.0, 0.2, 0.4);
93                        next.control_l.position += Vec3::new(-6.0, 0.0, -2.0) * charge;
94                        next.control_l.orientation.rotate_y(PI / 2.0 * charge);
95                        next.control_r.position += Vec3::new(tension, 6.0, 4.0) * charge;
96                        next.control_r.orientation.rotate_y(-PI / 4.0 * charge);
97
98                        twist_back(&mut next, move2, 3.0, 2.8, 0.2, 0.4);
99                        next.control_r.position += Vec3::new(6.0, 14.0, -4.0) * move2;
100                        next.foot_l.position += Vec3::new(0.0, -4.0, 0.0) * move2;
101                        next.foot_l.orientation.rotate_z(PI / 4.0 * move2);
102                        next.foot_r.position += Vec3::new(0.0, 4.0, 0.0) * move2;
103                        next.foot_r.orientation.rotate_z(PI / 2.0 * move2);
104                    },
105                    HandInfo::TwoHanded => {},
106                }
107            },
108            _ => {},
109        }
110
111        next
112    }
113}