veloren_voxygen_anim/character/
climb.rs1use super::{
2 super::{Animation, vek::*},
3 CharacterSkeleton, SkeletonAttr,
4};
5use common::comp::item::ToolKind;
6use std::{f32::consts::PI, ops::Mul};
7
8pub struct ClimbAnimation;
9
10impl Animation for ClimbAnimation {
11 type Dependency<'a> = (
12 Option<ToolKind>,
13 Option<ToolKind>,
14 Vec3<f32>,
15 Vec3<f32>,
16 f32,
17 );
18 type Skeleton = CharacterSkeleton;
19
20 #[cfg(feature = "use-dyn-lib")]
21 const UPDATE_FN: &'static [u8] = b"character_climb\0";
22
23 #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "character_climb"))]
24 fn update_skeleton_inner(
25 skeleton: &Self::Skeleton,
26 (_active_tool_kind, _second_tool_kind, velocity, _orientation, global_time): Self::Dependency<'_>,
27 anim_time: f32,
28 rate: &mut f32,
29 s_a: &SkeletonAttr,
30 ) -> Self::Skeleton {
31 let mut next = (*skeleton).clone();
32 let lateral = Vec2::<f32>::from(velocity).magnitude();
33 let speed = velocity.z;
34 *rate = speed;
35 let constant: f32 = 1.0;
36 let smooth = (anim_time * constant * 1.5).sin();
37 let smootha = (anim_time * constant * 1.5 + PI / 2.0).sin();
38 let drop = (anim_time * constant * 4.0 + PI / 2.0).sin();
39 let dropa = (anim_time * constant * 4.0).sin();
40
41 let quick = ((5.0 / (0.6 + 4.0 * ((anim_time * constant * 1.5).sin()).powi(2))).sqrt())
42 * ((anim_time * constant * 1.5).sin());
43 let quicka =
44 ((5.0 / (0.6 + 4.0 * ((anim_time * constant * 1.5 + PI / 2.0).sin()).powi(2))).sqrt())
45 * ((anim_time * constant * 1.5 + PI / 2.0).sin());
46 let head_look = Vec2::new(
47 (global_time / 2.0 + anim_time / 2.0)
48 .floor()
49 .mul(7331.0)
50 .sin()
51 * 0.3,
52 (global_time / 2.0 + anim_time / 2.0)
53 .floor()
54 .mul(1337.0)
55 .sin()
56 * 0.15,
57 );
58 let stagnant = if speed > -0.7 { 1.0 } else { 0.0 }; next.hold.scale = Vec3::one() * 0.0;
61
62 if speed > 0.7 || lateral > 0.1 {
63 next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + smootha * 0.2);
64 next.head.orientation = Quaternion::rotation_z(smooth * 0.1)
65 * Quaternion::rotation_x(0.6)
66 * Quaternion::rotation_y(quick * 0.1);
67
68 next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + smootha * 1.1);
69 next.chest.orientation = Quaternion::rotation_z(quick * 0.25)
70 * Quaternion::rotation_x(-0.15)
71 * Quaternion::rotation_y(quick * -0.12);
72
73 next.belt.position = Vec3::new(0.0, s_a.belt.0 + 1.0, s_a.belt.1);
74
75 next.back.orientation = Quaternion::rotation_x(-0.2);
76
77 next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + 1.0, s_a.shorts.1);
78 next.shorts.orientation = Quaternion::rotation_z(quick * 0.0)
79 * Quaternion::rotation_x(0.1)
80 * Quaternion::rotation_y(quick * 0.10);
81
82 next.hand_l.position = Vec3::new(
83 -s_a.hand.0,
84 4.0 + s_a.hand.1 + quicka * 1.5,
85 5.0 + s_a.hand.2 - quick * 4.0,
86 );
87 next.hand_l.orientation = Quaternion::rotation_x(2.2 + quicka * 0.5);
88
89 next.hand_r.position = Vec3::new(
90 s_a.hand.0,
91 5.0 + s_a.hand.1 - quicka * 1.5,
92 5.0 + s_a.hand.2 + quick * 4.0,
93 );
94 next.hand_r.orientation = Quaternion::rotation_x(2.2 - quicka * 0.5);
95
96 next.foot_l.position =
97 Vec3::new(-s_a.foot.0, 5.0 + s_a.foot.1, s_a.foot.2 + quick * 2.5);
98 next.foot_l.orientation = Quaternion::rotation_x(0.2 - quicka * 0.5);
99
100 next.foot_r.position =
101 Vec3::new(s_a.foot.0, 4.0 + s_a.foot.1, s_a.foot.2 - quick * 2.5);
102 next.foot_r.orientation = Quaternion::rotation_x(0.2 + quicka * 0.5);
103
104 next.shoulder_l.orientation = Quaternion::rotation_x(smootha * 0.15);
105
106 next.shoulder_r.orientation = Quaternion::rotation_x(smooth * 0.15);
107
108 next.lantern.orientation =
109 Quaternion::rotation_x(smooth * -0.3) * Quaternion::rotation_y(smooth * -0.3);
110
111 next.torso.position = Vec3::new(0.0, -2.2 + smooth * -0.88, 4.4);
112 } else {
113 next.head.position = Vec3::new(0.0, -1.0 - stagnant + s_a.head.0, s_a.head.1);
114 next.head.orientation = Quaternion::rotation_x(
115 -0.25 * (1.0 - stagnant) + stagnant * 2.0 * head_look.x.abs(),
116 ) * Quaternion::rotation_z(stagnant * 3.5 * head_look.x.abs());
117
118 next.chest.position = Vec3::new(0.0, 1.0 + s_a.chest.0, s_a.chest.1);
119 next.chest.orientation = Quaternion::rotation_z(0.6 * stagnant)
120 * Quaternion::rotation_x((0.2 + drop * 0.05) * (1.0 - stagnant));
121
122 next.belt.position = Vec3::new(0.0, s_a.belt.0 + 0.5, s_a.belt.1);
123 next.belt.orientation = Quaternion::rotation_x(0.1 + dropa * 0.1);
124
125 next.back.orientation = Quaternion::rotation_x(
126 -0.2 + dropa * 0.1 - 0.15 * (1.0 - stagnant) + stagnant * 0.1,
127 );
128
129 next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + 1.0, s_a.shorts.1);
130 next.shorts.orientation = Quaternion::rotation_x(0.1 + dropa * 0.12 * (1.0 - stagnant));
131
132 next.hand_l.position = Vec3::new(
133 -s_a.hand.0,
134 7.5 + stagnant * -5.0 + s_a.hand.1,
135 7.0 + stagnant * -7.0 + s_a.hand.2 + dropa * -1.0 * (1.0 - stagnant),
136 );
137 next.hand_l.orientation = Quaternion::rotation_x(2.2 + stagnant * -1.4)
138 * Quaternion::rotation_y((0.3 + dropa * 0.1) * (1.0 - stagnant));
139
140 next.hand_r.position = Vec3::new(
141 s_a.hand.0,
142 7.5 + stagnant * -2.5 + s_a.hand.1,
143 5.0 + s_a.hand.2 + drop * -1.0 * (1.0 - stagnant),
144 );
145 next.hand_r.orientation = Quaternion::rotation_x(2.2)
146 * Quaternion::rotation_y(-0.3 + drop * 0.1 * (1.0 - stagnant));
147
148 next.foot_l.position = Vec3::new(
149 -s_a.foot.0,
150 4.0 + stagnant * 3.0 + s_a.foot.1,
151 1.0 + s_a.foot.2 + drop * -2.0 * (1.0 - stagnant),
152 );
153 next.foot_l.orientation = Quaternion::rotation_x(0.55 + drop * 0.1 * (1.0 - stagnant));
154
155 next.foot_r.position = Vec3::new(
156 s_a.foot.0,
157 2.0 + stagnant * 4.0 + s_a.foot.1,
158 -2.0 + s_a.foot.2 + smooth * 1.0 * (1.0 - stagnant),
159 );
160 next.foot_r.orientation =
161 Quaternion::rotation_x(0.2 + smooth * 0.15 * (1.0 - stagnant));
162
163 next.torso.position = Vec3::new(0.0, -2.2, 4.4);
164 };
165
166 next
167 }
168}