veloren_voxygen_anim/biped_large/
summon.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 SummonAnimation;
12
13impl Animation for SummonAnimation {
14    type Dependency<'a> = (
15        Option<ToolKind>,
16        (Option<ToolKind>, Option<&'a AbilitySpec>),
17        Vec3<f32>,
18        f32,
19        Option<StageSection>,
20        f32,
21        Option<&'a str>,
22    );
23    type Skeleton = BipedLargeSkeleton;
24
25    #[cfg(feature = "use-dyn-lib")]
26    const UPDATE_FN: &'static [u8] = b"biped_large_summon\0";
27
28    #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_summon")]
29    fn update_skeleton_inner(
30        skeleton: &Self::Skeleton,
31        (
32            active_tool_kind,
33            _second_tool_kind,
34            velocity,
35            _global_time,
36            stage_section,
37            acc_vel,
38            ability_id,
39        ): Self::Dependency<'_>,
40        anim_time: f32,
41        rate: &mut f32,
42        s_a: &SkeletonAttr,
43    ) -> Self::Skeleton {
44        *rate = 1.0;
45        let mut next = (*skeleton).clone();
46
47        let speed = Vec2::<f32>::from(velocity).magnitude();
48
49        let lab: f32 = 0.65 * s_a.tempo;
50        let speednorm = (speed / 12.0).powf(0.4);
51        let foothoril = (acc_vel * lab + PI * 1.45).sin() * speednorm;
52        let foothorir = (acc_vel * lab + PI * (0.45)).sin() * speednorm;
53        let footrotl = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 1.4).sin()).powi(2))).sqrt())
54            * ((acc_vel * lab + PI * 1.4).sin());
55
56        let footrotr = ((1.0 / (0.5 + (0.5) * ((acc_vel * lab + PI * 0.4).sin()).powi(2))).sqrt())
57            * ((acc_vel * lab + PI * 0.4).sin());
58
59        let (move1base, move2base, move3) = match stage_section {
60            Some(StageSection::Buildup) => ((anim_time.powf(0.5)), 0.0, 0.0),
61            Some(StageSection::Action) => (1.0, (anim_time.powi(2)), 0.0),
62            Some(StageSection::Recover) => (1.0, 1.0, anim_time),
63            _ => (0.0, 0.0, 0.0),
64        };
65        let pullback = 1.0 - move3;
66        let move1 = move1base * pullback;
67        let move2 = move2base * pullback;
68
69        next.torso.orientation = Quaternion::rotation_z(0.0);
70
71        next.main.position = Vec3::new(0.0, 0.0, 0.0);
72        next.main.orientation = Quaternion::rotation_x(0.0);
73
74        next.hand_l.position = Vec3::new(s_a.grip.1, 0.0, s_a.grip.0);
75        next.hand_r.position = Vec3::new(-s_a.grip.1, 0.0, s_a.grip.0);
76
77        next.hand_l.orientation = Quaternion::rotation_x(0.0);
78        next.hand_r.orientation = Quaternion::rotation_x(0.0);
79
80        #[expect(clippy::single_match)]
81        match active_tool_kind {
82            Some(ToolKind::Staff) => {
83                next.shoulder_l.position = Vec3::new(
84                    -s_a.shoulder.0,
85                    s_a.shoulder.1,
86                    s_a.shoulder.2 - foothorir * 1.0,
87                );
88                next.shoulder_l.orientation = Quaternion::rotation_x(
89                    move1 * 0.8 + 0.6 * speednorm + (footrotr * -0.2) * speednorm,
90                );
91
92                next.shoulder_r.position = Vec3::new(
93                    s_a.shoulder.0,
94                    s_a.shoulder.1,
95                    s_a.shoulder.2 - foothoril * 1.0,
96                );
97                next.shoulder_r.orientation = Quaternion::rotation_x(
98                    move1 * 0.8 + 0.6 * speednorm + (footrotl * -0.2) * speednorm,
99                );
100                next.head.orientation = Quaternion::rotation_x(0.0);
101                next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
102                next.control_r.position = Vec3::new(
103                    1.0 + move1 * 3.0 + move2 * 20.0,
104                    2.0 + move1 * -5.0 + move2 * 5.0,
105                    2.0 + move1 * 15.0 + move2 * 0.0,
106                );
107
108                next.control.position = Vec3::new(
109                    -3.0 + move2 * 9.0,
110                    3.0 + s_a.grip.0 / 1.2 + move1 * 15.0 + move2 * 2.0,
111                    -11.0 + -s_a.grip.0 / 2.0 + move1 * 15.0 + move2 * -12.0,
112                );
113
114                next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 - move1 * 0.2)
115                    * Quaternion::rotation_y(-0.5 + move2 * -0.4)
116                    * Quaternion::rotation_z(move1 * 0.0);
117                next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.2)
118                    * Quaternion::rotation_y(0.5 + move1 * 0.5 + move2 * 0.0)
119                    * Quaternion::rotation_z(move1 * 0.5 + move2 * 0.8);
120
121                next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * 1.0)
122                    * Quaternion::rotation_y(-0.1 + move2 * -0.8);
123            },
124            Some(ToolKind::Sceptre) => {
125                next.shoulder_l.position = Vec3::new(
126                    -s_a.shoulder.0,
127                    s_a.shoulder.1,
128                    s_a.shoulder.2 - foothorir * 1.0,
129                );
130                next.shoulder_l.orientation = Quaternion::rotation_x(
131                    move1 * 0.8 + 0.6 * speednorm + (footrotr * -0.2) * speednorm,
132                );
133
134                next.shoulder_r.position = Vec3::new(
135                    s_a.shoulder.0,
136                    s_a.shoulder.1,
137                    s_a.shoulder.2 - foothoril * 1.0,
138                );
139                next.shoulder_r.orientation = Quaternion::rotation_x(
140                    move1 * 0.8 + 0.6 * speednorm + (footrotl * -0.2) * speednorm,
141                );
142                next.head.orientation = Quaternion::rotation_x(0.0);
143                next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
144                next.control_r.position = Vec3::new(
145                    1.0 + move1 * 3.0 + move2 * 20.0,
146                    2.0 + move1 * -5.0 + move2 * 5.0,
147                    2.0 + move1 * 15.0 + move2 * 0.0,
148                );
149
150                next.control.position = Vec3::new(
151                    -3.0 + move2 * 9.0,
152                    3.0 + s_a.grip.0 / 1.2 + move1 * 8.0 + move2 * 2.0,
153                    -11.0 + -s_a.grip.0 / 2.0 + move1 * 8.0 + move2 * -12.0,
154                );
155
156                next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 - move1 * 0.2)
157                    * Quaternion::rotation_y(-0.5 + move2 * -0.4)
158                    * Quaternion::rotation_z(move1 * 0.0);
159                next.control_r.orientation = Quaternion::rotation_x(PI / 2.5 + move1 * 0.2)
160                    * Quaternion::rotation_y(0.5 + move1 * 0.5 + move2 * 0.0)
161                    * Quaternion::rotation_z(move1 * 0.5 + move2 * 0.8);
162
163                next.control.orientation = Quaternion::rotation_x(-0.2 + move1 * 1.0)
164                    * Quaternion::rotation_y(-0.1 + move2 * -0.8);
165            },
166            Some(ToolKind::Natural) => match ability_id {
167                Some("common.abilities.custom.tidalwarrior.totem") => {
168                    let (move1base, move2base, move3) = match stage_section {
169                        Some(StageSection::Buildup) => ((anim_time.powi(2)), 0.0, 0.0),
170                        Some(StageSection::Action) => (1.0, (anim_time * 30.0).sin(), 0.0),
171                        Some(StageSection::Recover) => (1.0, 1.0, anim_time),
172                        _ => (0.0, 0.0, 0.0),
173                    };
174                    let pullback = 1.0 - move3;
175                    let move1 = move1base * pullback;
176                    let move2 = move2base * pullback;
177                    next.torso.position = Vec3::new(0.0, 0.0 + move1 * 4.7, move1 * -18.8);
178                    next.upper_torso.position =
179                        Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1);
180
181                    next.lower_torso.position =
182                        Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1);
183
184                    next.head.position =
185                        Vec3::new(0.0, s_a.head.0 + move1 * -8.0, s_a.head.1 + move1 * 6.0);
186                    next.shoulder_l.orientation = Quaternion::rotation_x(move1 * 2.5)
187                        * Quaternion::rotation_y(move1 * 0.4 + move2 * 0.05);
188                    next.shoulder_r.orientation = Quaternion::rotation_x(move1 * 2.5)
189                        * Quaternion::rotation_y(move1 * -0.4 + move2 * -0.05);
190                    next.head.orientation =
191                        Quaternion::rotation_x(move1 * 1.4) * Quaternion::rotation_y(move2 * 0.02);
192                    next.upper_torso.orientation = Quaternion::rotation_x(move1 * -1.5)
193                        * Quaternion::rotation_y(move2 * -0.02);
194                    next.lower_torso.orientation =
195                        Quaternion::rotation_x(move1 * 0.2) * Quaternion::rotation_y(move2 * 0.02);
196                    next.hand_l.position = Vec3::new(
197                        -14.0 + move1 * -5.0,
198                        2.0 + move1 * -2.0,
199                        -4.0 + move1 * 12.0,
200                    );
201                    next.hand_r.position =
202                        Vec3::new(14.0 + move1 * 5.0, 2.0 + move1 * -2.0, -4.0 + move1 * 12.0);
203
204                    next.hand_l.orientation = Quaternion::rotation_x(PI / 3.0 + move1 * 1.5)
205                        * Quaternion::rotation_y(-move1 * 0.7 + move2 * 0.2)
206                        * Quaternion::rotation_z(-0.35);
207                    next.hand_r.orientation = Quaternion::rotation_x(PI / 3.0 + move1 * 1.5)
208                        * Quaternion::rotation_y(move1 * 0.7 + move2 * 0.2)
209                        * Quaternion::rotation_z(0.35);
210                    next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2);
211                    next.leg_l.orientation =
212                        Quaternion::rotation_z(0.0) * Quaternion::rotation_x(move1 * -0.8);
213
214                    next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2);
215                    next.foot_l.position =
216                        Vec3::new(-s_a.foot.0, s_a.foot.1 + move1 * -3.0, s_a.foot.2);
217                    next.foot_r.position =
218                        Vec3::new(s_a.foot.0, s_a.foot.1 + move1 * -3.0, s_a.foot.2);
219                    next.leg_r.orientation =
220                        Quaternion::rotation_z(0.0) * Quaternion::rotation_x(move1 * -0.8);
221                    next.foot_l.orientation =
222                        Quaternion::rotation_z(0.0) * Quaternion::rotation_x(move1 * 0.8);
223                    next.foot_r.orientation =
224                        Quaternion::rotation_z(0.0) * Quaternion::rotation_x(move1 * 0.8);
225                },
226                _ => {},
227            },
228            Some(ToolKind::Axe) => match ability_id {
229                Some("common.abilities.custom.gigas_frost.frost_summons") => {
230                    next.shoulder_l.position = Vec3::new(
231                        -s_a.shoulder.0,
232                        s_a.shoulder.1,
233                        s_a.shoulder.2 - foothorir * 1.0,
234                    );
235                    next.shoulder_l.orientation =
236                        Quaternion::rotation_x(move1 * 2.7 + 0.1 * speednorm)
237                            * Quaternion::rotation_y(move1 * 0.7 + 0.1 * speednorm);
238                    next.head.orientation = Quaternion::rotation_x(0.0);
239                    next.hand_l.position = Vec3::new(
240                        -14.0 + move1 * -5.0,
241                        2.0 + move1 * -2.0,
242                        -2.0 + move1 * 6.0 + move2 * 4.0,
243                    );
244                    next.hand_r.position = Vec3::new(14.0, 2.0, -4.0);
245                    next.hand_l.orientation = Quaternion::rotation_x(PI / 3.0 + move1 * 2.2)
246                        * Quaternion::rotation_y(move1 * 0.1)
247                        * Quaternion::rotation_z(-0.35);
248                    next.hand_r.orientation =
249                        Quaternion::rotation_x(PI / 3.0) * Quaternion::rotation_z(0.35);
250                    next.main.position = Vec3::new(14.0, 2.0, -4.0);
251                    next.main.orientation =
252                        Quaternion::rotation_x(PI / 3.0) * Quaternion::rotation_z(0.35);
253                },
254                _ => {},
255            },
256            Some(ToolKind::Hammer) => match ability_id {
257                Some("common.abilities.custom.dwarves.forgemaster.summon_iron_dwarf") => {
258                    next.main.position = Vec3::new(-10.0, -8.0, 12.0);
259                    next.main.orientation =
260                        Quaternion::rotation_y(2.5) * Quaternion::rotation_z(PI / 2.0);
261                    next.hand_l.position = Vec3::new(
262                        -s_a.hand.0 - 3.0 * move1,
263                        s_a.hand.1 + 4.0,
264                        s_a.hand.2 + 6.0 * move1,
265                    );
266                    next.hand_r.position = Vec3::new(
267                        s_a.hand.0 + 3.0 * move1,
268                        s_a.hand.1 + 4.0,
269                        s_a.hand.2 + 6.0 * move1,
270                    );
271                    next.shoulder_l.orientation =
272                        Quaternion::rotation_x(move1 * 1.4) * Quaternion::rotation_y(move1 * 0.5);
273                    next.shoulder_r.orientation =
274                        Quaternion::rotation_x(move1 * 1.4) * Quaternion::rotation_y(move1 * -0.5);
275                    next.head.orientation = Quaternion::rotation_x(move1 * 0.25 + move2 * -0.25)
276                        * Quaternion::rotation_z(move1 * 0.25);
277                    next.hand_l.orientation =
278                        Quaternion::rotation_x(move1 * 1.0) * Quaternion::rotation_y(move1 * 1.4);
279                    next.hand_r.orientation =
280                        Quaternion::rotation_x(move1 * 1.0) * Quaternion::rotation_y(move1 * -1.4);
281                    next.foot_l.orientation = Quaternion::rotation_x(move1 * 0.3 + move2 * -0.3);
282                    next.foot_r.orientation = Quaternion::rotation_x(move1 * 0.3 + move2 * -0.3);
283                },
284                _ => {},
285            },
286            _ => {},
287        }
288
289        next
290    }
291}