veloren_voxygen_anim/biped_small/
mod.rs

1pub mod alpha;
2pub mod beam;
3pub mod block;
4pub mod combomelee;
5pub mod dash;
6pub mod idle;
7pub mod leapmelee;
8pub mod rapidmelee;
9pub mod ripostemelee;
10pub mod run;
11pub mod shockwave;
12pub mod shoot;
13pub mod spritesummon;
14pub mod stunned;
15pub mod summon;
16pub mod wield;
17
18// Reexports
19pub use self::{
20    alpha::AlphaAnimation, beam::BeamAnimation, block::BlockAnimation, combomelee::ComboAnimation,
21    dash::DashAnimation, idle::IdleAnimation, leapmelee::LeapAnimation,
22    rapidmelee::RapidMeleeAnimation, ripostemelee::RiposteMeleeAnimation, run::RunAnimation,
23    shockwave::ShockwaveAnimation, shoot::ShootAnimation, spritesummon::SpriteSummonAnimation,
24    stunned::StunnedAnimation, summon::SummonAnimation, wield::WieldAnimation,
25};
26
27use super::{FigureBoneData, Offsets, Skeleton, make_bone, vek::*};
28use common::comp::{self};
29use core::convert::TryFrom;
30use std::f32::consts::PI;
31
32pub type Body = comp::biped_small::Body;
33
34skeleton_impls!(struct BipedSmallSkeleton {
35    + head,
36    + chest,
37    + pants,
38    + tail,
39    + main,
40    + hand_l,
41    + hand_r,
42    + foot_l,
43    + foot_r,
44    control,
45    control_l,
46    control_r,
47    :: // Begin non-bone fields
48    // Allows right hand to not be moved by control bone
49    detach_right: bool,
50});
51
52impl Skeleton for BipedSmallSkeleton {
53    type Attr = SkeletonAttr;
54    type Body = Body;
55
56    const BONE_COUNT: usize = 9;
57    #[cfg(feature = "use-dyn-lib")]
58    const COMPUTE_FN: &'static [u8] = b"biped_small_compute_mats\0";
59
60    #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_small_compute_mats")]
61    fn compute_matrices_inner(
62        &self,
63        base_mat: Mat4<f32>,
64        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
65        body: Self::Body,
66    ) -> Offsets {
67        let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0);
68
69        let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
70        let pants_mat = chest_mat * Mat4::<f32>::from(self.pants);
71        let control_mat = chest_mat * Mat4::<f32>::from(self.control);
72        let control_l_mat = Mat4::<f32>::from(self.control_l);
73        let control_r_mat = Mat4::<f32>::from(self.control_r);
74        let head_mat = chest_mat * Mat4::<f32>::from(self.head);
75        let tail_mat = pants_mat * Mat4::<f32>::from(self.tail);
76        *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
77            make_bone(head_mat),
78            make_bone(chest_mat),
79            make_bone(pants_mat),
80            make_bone(tail_mat),
81            make_bone(control_mat * Mat4::<f32>::from(self.main)),
82            make_bone(control_mat * control_l_mat * Mat4::<f32>::from(self.hand_l)),
83            make_bone(
84                if self.detach_right {
85                    chest_mat
86                } else {
87                    control_mat
88                } * control_r_mat
89                    * Mat4::<f32>::from(self.hand_r),
90            ),
91            make_bone(base_mat * Mat4::<f32>::from(self.foot_l)),
92            make_bone(base_mat * Mat4::<f32>::from(self.foot_r)),
93        ];
94
95        use comp::biped_small::Species::*;
96        let (mount_mat, mount_orientation) = match (body.species, body.body_type) {
97            (Sahagin | Mandragora | Kappa | Gnoll | Bushly | Irrwurz | TreasureEgg, _) => {
98                (chest_mat, self.chest.orientation)
99            },
100            (GoblinThug | GoblinChucker | GoblinRuffian, _) => (
101                chest_mat,
102                self.chest.orientation * Quaternion::rotation_x(0.7),
103            ),
104            (Myrmidon, _) => (
105                tail_mat,
106                self.chest.orientation * self.pants.orientation * self.tail.orientation,
107            ),
108            _ => (head_mat, self.chest.orientation * self.head.orientation),
109        };
110        let mount_position = mount_mat.mul_point(mount_point(&body));
111
112        Offsets {
113            viewpoint: Some((head_mat * Vec4::new(0.0, 0.0, 0.0, 1.0)).xyz()),
114            // TODO: see quadruped_medium for how to animate this
115            mount_bone: Transform {
116                position: mount_position,
117                orientation: mount_orientation,
118                scale: Vec3::one(),
119            },
120            ..Default::default()
121        }
122    }
123}
124
125pub struct SkeletonAttr {
126    head: (f32, f32),
127    chest: (f32, f32),
128    pants: (f32, f32),
129    tail: (f32, f32),
130    hand: (f32, f32, f32),
131    foot: (f32, f32, f32),
132    grip: (f32, f32, f32),
133    scaler: f32,
134    wing_for_foot: bool,
135}
136
137impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
138    type Error = ();
139
140    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
141        match body {
142            comp::Body::BipedSmall(body) => Ok(SkeletonAttr::from(body)),
143            _ => Err(()),
144        }
145    }
146}
147
148impl Default for SkeletonAttr {
149    fn default() -> Self {
150        Self {
151            head: (0.0, 0.0),
152            chest: (0.0, 0.0),
153            pants: (0.0, 0.0),
154            tail: (0.0, 0.0),
155            hand: (0.0, 0.0, 0.0),
156            foot: (0.0, 0.0, 0.0),
157            grip: (0.0, 0.0, 0.0),
158            scaler: 0.0,
159            wing_for_foot: false,
160        }
161    }
162}
163
164impl<'a> From<&'a Body> for SkeletonAttr {
165    fn from(body: &'a Body) -> Self {
166        use comp::biped_small::Species::*;
167        Self {
168            head: match (body.species, body.body_type) {
169                (Gnome, _) => (-1.0, 9.0),
170                (Sahagin, _) => (7.0, -3.5),
171                (Adlet, _) => (0.0, 7.0),
172                (Gnarling, _) => (0.0, 6.0),
173                (Mandragora, _) => (-1.0, 9.0),
174                (Kappa, _) => (8.0, 3.5),
175                (Cactid, _) => (-1.0, 9.0),
176                (Gnoll, _) => (5.5, -1.0),
177                (Haniwa, _) => (0.0, 7.0),
178                (Myrmidon, _) => (0.0, 8.0),
179                (Husk, _) => (0.5, 8.5),
180                (Boreal, _) => (-0.5, 13.0),
181                (Bushly, _) => (-1.0, 9.0),
182                (Irrwurz, _) => (-1.0, 9.0),
183                (IronDwarf, _) => (3.0, 3.5),
184                (Flamekeeper, _) => (3.0, 3.5),
185                (ShamanicSpirit, _) => (-0.5, 4.5),
186                (Jiangshi, _) => (-1.0, 6.5),
187                (TreasureEgg, _) => (-1.0, 9.0),
188                (GnarlingChieftain, _) => (0.0, 6.0),
189                (BloodmoonHeiress, _) => (0.0, 3.5),
190                (Bloodservant, _) => (-1.0, 6.5),
191                (Harlequin, _) => (0.0, 8.0),
192                (GoblinThug, _) => (-0.5, 3.5),
193                (GoblinChucker, _) => (-0.5, 3.5),
194                (GoblinRuffian, _) => (-0.5, 3.5),
195                (GreenLegoom, _) => (0.0, 3.5),
196                (OchreLegoom, _) => (0.0, 3.5),
197                (PurpleLegoom, _) => (-0.5, 3.5),
198                (RedLegoom, _) => (0.0, 3.5),
199            },
200            chest: match (body.species, body.body_type) {
201                (Gnome, _) => (0.0, 9.0),
202                (Sahagin, _) => (0.0, 15.0),
203                (Adlet, _) => (0.0, 11.0),
204                (Gnarling, _) => (0.0, 7.5),
205                (Mandragora, _) => (0.0, 4.0),
206                (Kappa, _) => (0.0, 14.5),
207                (Cactid, _) => (0.0, 7.0),
208                (Gnoll, _) => (0.0, 15.5),
209                (Haniwa, _) => (0.0, 11.0),
210                (Myrmidon, _) => (0.0, 11.0),
211                (Husk, _) => (0.0, 13.0),
212                (Boreal, _) => (0.0, 12.0),
213                (Bushly, _) => (0.0, 4.0),
214                (Irrwurz, _) => (0.0, 6.0),
215                (IronDwarf, _) => (0.0, 14.0),
216                (Flamekeeper, _) => (0.0, 14.0),
217                (ShamanicSpirit, _) => (0.0, 14.5),
218                (Jiangshi, _) => (0.0, 14.0),
219                (TreasureEgg, _) => (0.0, 3.0),
220                (GnarlingChieftain, _) => (0.0, 7.5),
221                (BloodmoonHeiress, _) => (0.0, 21.0),
222                (Bloodservant, _) => (0.0, 14.0),
223                (Harlequin, _) => (0.0, 13.5),
224                (GoblinThug, _) => (0.0, 8.5),
225                (GoblinChucker, _) => (0.0, 8.5),
226                (GoblinRuffian, _) => (0.0, 8.5),
227                (GreenLegoom, _) => (0.0, 7.0),
228                (OchreLegoom, _) => (0.0, 7.0),
229                (PurpleLegoom, _) => (0.0, 7.5),
230                (RedLegoom, _) => (0.0, 7.0),
231            },
232            pants: match (body.species, body.body_type) {
233                (Gnome, _) => (0.0, -3.0),
234                (Sahagin, _) => (0.5, -7.0),
235                (Adlet, _) => (0.0, -3.0),
236                (Gnarling, _) => (0.0, -3.0),
237                (Mandragora, _) => (0.0, 0.0),
238                (Kappa, _) => (0.0, -3.0),
239                (Cactid, _) => (0.0, -2.0),
240                (Gnoll, _) => (0.5, -7.5),
241                (Haniwa, _) => (0.0, -3.5),
242                (Myrmidon, _) => (0.0, -3.0),
243                (Husk, _) => (-1.0, -3.0),
244                (Boreal, _) => (1.5, -5.0),
245                (Bushly, _) => (0.0, 1.0),
246                (Irrwurz, _) => (-5.5, -0.5),
247                (IronDwarf, _) => (-1.0, -8.0),
248                (Flamekeeper, _) => (-1.0, -8.0),
249                (ShamanicSpirit, _) => (0.0, -8.0),
250                (Jiangshi, _) => (0.5, -6.0),
251                (TreasureEgg, _) => (0.0, 1.0),
252                (GnarlingChieftain, _) => (0.0, -3.0),
253                (BloodmoonHeiress, _) => (0.0, -8.0),
254                (Bloodservant, _) => (0.0, -6.0),
255                (Harlequin, _) => (0.0, -5.5),
256                (GoblinThug, _) => (0.0, -4.5),
257                (GoblinChucker, _) => (0.0, -4.5),
258                (GoblinRuffian, _) => (0.0, -4.5),
259                (GreenLegoom, _) => (0.0, -3.5),
260                (OchreLegoom, _) => (0.0, -3.5),
261                (PurpleLegoom, _) => (0.0, -4.0),
262                (RedLegoom, _) => (0.0, -3.5),
263            },
264            tail: match (body.species, body.body_type) {
265                (Gnome, _) => (0.0, 0.0),
266                (Sahagin, _) => (-2.5, -2.0),
267                (Adlet, _) => (-4.5, -2.0),
268                (Gnarling, _) => (-2.0, 1.5),
269                (Mandragora, _) => (0.0, -1.0),
270                (Kappa, _) => (0.0, -4.0),
271                (Cactid, _) => (0.0, 0.0),
272                (Gnoll, _) => (-2.5, -2.0),
273                (Haniwa, _) => (-4.5, -2.0),
274                (Myrmidon, _) => (-2.5, -1.0),
275                (Husk, _) => (0.0, 0.0),
276                (Boreal, _) => (0.0, 0.0),
277                (Bushly, _) => (0.0, -1.0),
278                (Irrwurz, _) => (0.0, -1.0),
279                (IronDwarf, _) => (0.0, 0.0),
280                (Flamekeeper, _) => (0.0, 0.0),
281                (ShamanicSpirit, _) => (0.0, 0.0),
282                (Jiangshi, _) => (0.0, 0.0),
283                (TreasureEgg, _) => (0.0, 0.0),
284                (GnarlingChieftain, _) => (-2.0, 1.5),
285                (BloodmoonHeiress, _) => (0.0, 0.0),
286                (Bloodservant, _) => (0.0, 0.0),
287                (Harlequin, _) => (0.0, 0.0),
288                (GoblinThug, _) => (0.0, 0.0),
289                (GoblinChucker, _) => (0.0, 0.0),
290                (GoblinRuffian, _) => (0.0, 0.0),
291                (GreenLegoom, _) => (0.0, 0.0),
292                (OchreLegoom, _) => (0.0, 0.0),
293                (PurpleLegoom, _) => (0.0, 0.0),
294                (RedLegoom, _) => (0.0, 0.0),
295            },
296            hand: match (body.species, body.body_type) {
297                (Gnome, _) => (4.0, 0.5, -1.0),
298                (Sahagin, _) => (3.5, 3.5, -2.0),
299                (Adlet, _) => (4.5, -0.5, 2.0),
300                (Gnarling, _) => (4.0, 0.0, 1.5),
301                (Mandragora, _) => (4.0, -0.5, 4.0),
302                (Kappa, _) => (4.0, 3.5, -0.5),
303                (Cactid, _) => (3.0, -0.5, 1.5),
304                (Gnoll, _) => (3.5, 0.5, -1.0),
305                (Haniwa, _) => (4.25, -1.0, 1.5),
306                (Myrmidon, _) => (3.5, 1.5, 2.0),
307                (Husk, _) => (4.0, 0.0, 1.0),
308                (Boreal, _) => (5.0, 0.5, 5.0),
309                (Bushly, _) => (5.0, 2.0, 8.0),
310                (Irrwurz, _) => (3.5, 2.0, 3.0),
311                (IronDwarf, _) => (4.0, 1.5, -3.5),
312                (Flamekeeper, _) => (4.0, 1.5, -3.5),
313                (ShamanicSpirit, _) => (5.0, 0.0, 1.0),
314                (Jiangshi, _) => (5.0, -1.0, 3.0),
315                (TreasureEgg, _) => (5.0, 2.0, 5.0),
316                (GnarlingChieftain, _) => (4.0, 0.0, 1.5),
317                (BloodmoonHeiress, _) => (2.5, 2.5, 7.0),
318                (Bloodservant, _) => (5.0, -1.0, 2.0),
319                (Harlequin, _) => (5.0, 0.0, 2.5),
320                (GoblinThug, _) => (4.5, 0.0, 2.0),
321                (GoblinChucker, _) => (4.5, 0.0, 2.0),
322                (GoblinRuffian, _) => (4.5, 0.0, 2.0),
323                (GreenLegoom, _) => (3.0, 0.0, 1.5),
324                (OchreLegoom, _) => (3.0, 0.0, 1.5),
325                (PurpleLegoom, _) => (3.0, 0.0, 1.5),
326                (RedLegoom, _) => (3.0, 0.0, 1.5),
327            },
328            foot: match (body.species, body.body_type) {
329                (Gnome, _) => (3.0, 0.0, 4.0),
330                (Sahagin, _) => (3.0, 1.0, 8.0),
331                (Adlet, _) => (3.0, 0.5, 7.0),
332                (Gnarling, _) => (2.5, 1.0, 5.0),
333                (Mandragora, _) => (3.0, 0.0, 4.0),
334                (Kappa, _) => (3.0, 3.0, 9.0),
335                (Cactid, _) => (2.5, 0.0, 5.0),
336                (Gnoll, _) => (3.0, 1.0, 7.0),
337                (Haniwa, _) => (3.0, 0.5, 8.0),
338                (Myrmidon, _) => (3.0, 0.5, 7.0),
339                (Husk, _) => (4.0, 0.5, 7.0),
340                (Boreal, _) => (3.0, 0.0, 9.0),
341                (Bushly, _) => (2.5, 0.0, 7.0),
342                (Irrwurz, _) => (4.0, 0.0, 6.0),
343                (IronDwarf, _) => (3.5, 3.0, 7.0),
344                (Flamekeeper, _) => (3.5, 3.0, 7.0),
345                (ShamanicSpirit, _) => (3.5, 3.0, 7.0),
346                (Jiangshi, _) => (3.0, 0.0, 8.0),
347                (TreasureEgg, _) => (2.0, 0.5, 4.0),
348                (GnarlingChieftain, _) => (2.5, 1.0, 5.0),
349                (BloodmoonHeiress, _) => (8.0, 0.5, 32.5),
350                (Bloodservant, _) => (2.5, 1.0, 7.0),
351                (Harlequin, _) => (2.5, 2.0, 10.0),
352                (GoblinThug, _) => (3.0, 0.5, 5.0),
353                (GoblinChucker, _) => (3.0, 0.5, 5.0),
354                (GoblinRuffian, _) => (3.0, 0.5, 5.0),
355                (GreenLegoom, _) => (2.0, -0.5, 4.0),
356                (OchreLegoom, _) => (2.0, -0.5, 4.0),
357                (PurpleLegoom, _) => (2.0, -0.5, 4.0),
358                (RedLegoom, _) => (2.0, -0.5, 4.0),
359            },
360            grip: match (body.species, body.body_type) {
361                (Gnome, _) => (0.0, 0.0, 5.0),
362                (Sahagin, _) => (1.0, 0.0, 13.0),
363                (Adlet, _) => (0.0, 0.0, 7.0),
364                (Gnarling, _) => (0.0, 0.0, 7.0),
365                (Mandragora, _) => (0.0, 0.0, 7.0),
366                (Kappa, _) => (0.75, 1.0, 12.0),
367                (Cactid, _) => (0.0, 0.0, 8.0),
368                (Gnoll, _) => (1.0, 0.0, 9.0),
369                (Haniwa, _) => (0.0, 0.5, 8.0),
370                (Myrmidon, _) => (0.0, 0.0, 8.0),
371                (Husk, _) => (0.0, 0.0, 8.0),
372                (Boreal, _) => (1.0, 0.0, 5.0),
373                (Bushly, _) => (0.0, 0.0, 7.0),
374                (Irrwurz, _) => (0.0, 0.0, 7.0),
375                (IronDwarf, _) => (0.0, 0.0, 8.0),
376                (Flamekeeper, _) => (0.0, 0.0, 8.0),
377                (ShamanicSpirit, _) => (0.0, 0.0, 8.0),
378                (Jiangshi, _) => (0.0, 0.0, 8.0),
379                (TreasureEgg, _) => (0.0, 0.0, 7.0),
380                (GnarlingChieftain, _) => (0.0, 0.0, 7.0),
381                (BloodmoonHeiress, _) => (0.0, 0.0, 8.0),
382                (Bloodservant, _) => (0.0, 0.0, 8.0),
383                (Harlequin, _) => (0.0, 0.0, 8.0),
384                (GoblinThug, _) => (0.0, 0.0, 8.0),
385                (GoblinChucker, _) => (0.0, 0.0, 8.0),
386                (GoblinRuffian, _) => (0.0, 0.0, 8.0),
387                (GreenLegoom, _) => (0.0, 0.0, 8.0),
388                (OchreLegoom, _) => (0.0, 0.0, 8.0),
389                (PurpleLegoom, _) => (0.0, 0.0, 8.0),
390                (RedLegoom, _) => (0.0, 0.0, 8.0),
391            },
392            scaler: match (body.species, body.body_type) {
393                (Gnome, _) => 0.8,
394                (Sahagin, _) => 1.05,
395                (Adlet, _) => 1.0,
396                (Gnarling, _) => 0.8,
397                (Mandragora, _) => 0.8,
398                (Kappa, _) => 0.8,
399                (Cactid, _) => 0.8,
400                (Gnoll, _) => 0.8,
401                (Haniwa, _) => 1.12,
402                (Myrmidon, _) => 1.24,
403                (Husk, _) => 1.12,
404                (Boreal, _) => 1.8,
405                (Bushly, _) => 1.0,
406                (Irrwurz, _) => 1.0,
407                (IronDwarf, _) => 1.5,
408                (Flamekeeper, _) => 1.0,
409                (ShamanicSpirit, _) => 1.0,
410                (Jiangshi, _) => 1.0,
411                (TreasureEgg, _) => 1.0,
412                (GnarlingChieftain, _) => 0.8,
413                (BloodmoonHeiress, _) => 1.5,
414                (Bloodservant, _) => 1.0,
415                (Harlequin, _) => 1.0,
416                (GoblinThug, _) => 1.0,
417                (GoblinChucker, _) => 1.0,
418                (GoblinRuffian, _) => 1.0,
419                (GreenLegoom, _) => 1.0,
420                (OchreLegoom, _) => 1.0,
421                (PurpleLegoom, _) => 1.0,
422                (RedLegoom, _) => 1.0,
423            },
424            wing_for_foot: matches!((body.species, body.body_type), (BloodmoonHeiress, _)),
425        }
426    }
427}
428
429pub fn init_biped_small_alpha(next: &mut BipedSmallSkeleton, s_a: &SkeletonAttr) {
430    next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
431    next.hand_r.position = Vec3::new(-s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
432    next.main.position = Vec3::new(0.0, 0.0, 0.0);
433    next.main.orientation = Quaternion::rotation_x(0.0);
434    next.hand_l.orientation = Quaternion::rotation_x(0.0);
435    next.hand_r.orientation = Quaternion::rotation_x(0.0);
436}
437
438pub fn biped_small_alpha_spear(
439    next: &mut BipedSmallSkeleton,
440    s_a: &SkeletonAttr,
441    move1abs: f32,
442    move2abs: f32,
443    anim_time: f32,
444    speednormcancel: f32,
445) {
446    let fast = (anim_time * 10.0).sin();
447    let fastalt = (anim_time * 10.0 + PI / 2.0).sin();
448
449    next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
450    next.head.orientation = Quaternion::rotation_x(move1abs * 0.2 + move2abs * 0.3)
451        * Quaternion::rotation_z(move1abs * -0.2 + move2abs * 0.6)
452        * Quaternion::rotation_y(move1abs * 0.3 + move2abs * -0.5);
453    next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1);
454    next.chest.orientation = Quaternion::rotation_x(move1abs * -0.2 + move2abs * 0.3)
455        * Quaternion::rotation_z(move1abs * 0.5 + move2abs * -0.6);
456
457    next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1);
458    next.pants.orientation = Quaternion::rotation_x(move1abs * 0.2 + move2abs * -0.3)
459        * Quaternion::rotation_z(move1abs * -0.2 + move2abs * 0.2);
460
461    next.control_l.position = Vec3::new(1.0 - s_a.grip.0 * 2.0, 2.0, -2.0);
462    next.control_r.position = Vec3::new(-1.0 + s_a.grip.0 * 2.0, 2.0, 2.0);
463
464    next.control.position = Vec3::new(
465        -3.0 + move1abs * -3.0 + move2abs * 5.0,
466        s_a.grip.2 + move1abs * -12.0 + move2abs * 17.0,
467        -s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0 + move2abs * 5.0,
468    );
469
470    next.control_l.orientation =
471        Quaternion::rotation_x(PI / 1.5 + move1abs * -1.5 + move2abs * 2.5)
472            * Quaternion::rotation_y(-0.3);
473    next.control_r.orientation =
474        Quaternion::rotation_x(PI / 1.5 + s_a.grip.0 * 0.2 + move1abs * -1.5 + move2abs * 2.5)
475            * Quaternion::rotation_y(0.5 + s_a.grip.0 * 0.2);
476
477    next.control.orientation = Quaternion::rotation_x(-1.35 + move1abs * -0.3 + move2abs * 0.5)
478        * Quaternion::rotation_z(move1abs * 1.0 + move2abs * -1.0)
479        * Quaternion::rotation_y(move2abs * 0.0);
480
481    next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
482    next.tail.orientation = Quaternion::rotation_x(0.05 * fastalt * speednormcancel)
483        * Quaternion::rotation_z(fast * 0.15 * speednormcancel);
484}
485
486pub fn biped_small_alpha_axe(
487    next: &mut BipedSmallSkeleton,
488    s_a: &SkeletonAttr,
489    move1abs: f32,
490    move2abs: f32,
491) {
492    next.main.position = Vec3::new(2.0, 2.0, 0.0);
493    next.control_l.position = Vec3::new(2.0 - 2.0 * s_a.grip.0, 1.0, 3.0);
494    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0);
495
496    next.head.orientation = Quaternion::rotation_z(0.3 * move1abs - 0.6 * move2abs);
497    next.chest.orientation = Quaternion::rotation_z(0.5 * move1abs - 1.2 * move2abs);
498    next.foot_l.orientation = Quaternion::rotation_z(0.5 * move1abs - 0.8 * move2abs);
499    next.foot_r.orientation = Quaternion::rotation_z(0.3 * move1abs - 0.6 * move2abs);
500
501    next.control.position = Vec3::new(
502        -5.0 + 5.0 * move1abs,
503        -1.0 + s_a.grip.2,
504        -1.0 + 3.0 * move1abs + -s_a.grip.2 / 2.5 - 2.0 * s_a.grip.0,
505    );
506    next.control.orientation = Quaternion::rotation_x(-0.3 - move2abs)
507        * Quaternion::rotation_y(-0.9 * move1abs + 1.0 * move2abs)
508        * Quaternion::rotation_z(-0.3);
509    next.control_r.position = Vec3::new(
510        9.0 - 5.0 * move1abs + 2.0 * s_a.grip.0,
511        -1.0 + 2.0 * move1abs,
512        3.0 * move1abs - 2.0,
513    );
514    next.control_r.orientation = Quaternion::rotation_x(0.5 + 1.5 * move1abs + 0.2 * s_a.grip.0)
515        * Quaternion::rotation_y(0.2 + 0.2 * s_a.grip.0);
516}
517
518pub fn biped_small_alpha_dagger(
519    next: &mut BipedSmallSkeleton,
520    s_a: &SkeletonAttr,
521    move1abs: f32,
522    move2abs: f32,
523) {
524    next.head.orientation = Quaternion::rotation_x(move1abs * 0.15 + move2abs * -0.15)
525        * Quaternion::rotation_z(move1abs * 0.15 + move2abs * -0.3);
526    next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
527    next.control_r.position = Vec3::new(
528        9.0 + move1abs * -7.0 + s_a.grip.0 * 2.0,
529        -1.0 + move1abs * 6.0,
530        -2.0,
531    );
532    let z_offset = if s_a.wing_for_foot {
533        s_a.grip.2 / 3.0
534    } else {
535        -s_a.grip.2 / 2.5
536    };
537    next.control.position = Vec3::new(
538        -5.0 + move1abs * 5.0 + move2abs * 9.0,
539        -1.0 + move2abs * -3.0 + s_a.grip.2,
540        -1.0 + move1abs * 3.0 + z_offset + s_a.grip.0 * -2.0,
541    );
542
543    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0)
544        * Quaternion::rotation_y(-0.0)
545        * Quaternion::rotation_z(-0.0);
546    next.control_r.orientation = Quaternion::rotation_x(0.5 + move1abs * 1.5 + s_a.grip.0 * 0.2)
547        * Quaternion::rotation_y(0.2 + s_a.grip.0 * 0.2)
548        * Quaternion::rotation_z(-0.0);
549
550    next.control.orientation = Quaternion::rotation_x(-0.3 + move2abs * -1.0)
551        * Quaternion::rotation_y(move1abs * -0.4 + move2abs * 1.0)
552        * Quaternion::rotation_z(-0.3 + move2abs * -2.2);
553}
554
555pub fn biped_small_wield_sword(
556    next: &mut BipedSmallSkeleton,
557    s_a: &SkeletonAttr,
558    speednorm: f32,
559    slow: f32,
560) {
561    next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
562    next.control_r.position = Vec3::new(9.0 + s_a.grip.0 * 2.0, -1.0, -2.0 + speednorm * -3.0);
563    let z_offset = if s_a.wing_for_foot {
564        s_a.grip.2 / 3.0
565    } else {
566        -s_a.grip.2 / 2.5
567    };
568    next.control.position = Vec3::new(
569        -5.0,
570        -1.0 + s_a.grip.2,
571        -1.0 + z_offset + s_a.grip.0 * -2.0 + speednorm * 2.0,
572    );
573
574    next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + slow * 0.1)
575        * Quaternion::rotation_y(-0.0)
576        * Quaternion::rotation_z(-0.0);
577    next.control_r.orientation = Quaternion::rotation_x(0.5 + slow * 0.1 + s_a.grip.0 * 0.2)
578        * Quaternion::rotation_y(0.2 + slow * 0.0 + s_a.grip.0 * 0.2)
579        * Quaternion::rotation_z(-0.0);
580
581    next.control.orientation = Quaternion::rotation_x(-0.3 + 0.2 * speednorm)
582        * Quaternion::rotation_y(-0.2 * speednorm)
583        * Quaternion::rotation_z(-0.3);
584}
585
586pub fn biped_small_wield_spear(
587    next: &mut BipedSmallSkeleton,
588    s_a: &SkeletonAttr,
589    anim_time: f32,
590    speed: f32,
591    fastacc: f32,
592) {
593    let speednorm = speed / 9.4;
594    let speednormcancel = 1.0 - speednorm;
595    let fastalt = (anim_time * 10.0 + PI / 2.0).sin();
596    let slow = (anim_time * 2.0).sin();
597
598    next.control_l.position = Vec3::new(1.0 - s_a.grip.0 * 2.0, 2.0, -2.0);
599    next.control_r.position = Vec3::new(-1.0 + s_a.grip.0 * 2.0, 2.0, 2.0);
600
601    next.control.position = Vec3::new(
602        -3.0,
603        s_a.grip.2,
604        -s_a.grip.2 / 2.5
605            + s_a.grip.0 * -2.0
606            + fastacc * 1.5
607            + fastalt * 0.5 * speednormcancel
608            + speednorm * 2.0,
609    );
610
611    next.control_l.orientation =
612        Quaternion::rotation_x(PI / 1.5 + slow * 0.1) * Quaternion::rotation_y(-0.3);
613    next.control_r.orientation = Quaternion::rotation_x(PI / 1.5 + slow * 0.1 + s_a.grip.0 * 0.2)
614        * Quaternion::rotation_y(0.5 + slow * 0.0 + s_a.grip.0 * 0.2);
615
616    next.control.orientation = Quaternion::rotation_x(-1.35 + 0.5 * speednorm);
617}
618
619pub fn biped_small_wield_bow(
620    next: &mut BipedSmallSkeleton,
621    s_a: &SkeletonAttr,
622    anim_time: f32,
623    speed: f32,
624    fastacc: f32,
625) {
626    let speednorm = speed / 9.4;
627    let speednormcancel = 1.0 - speednorm;
628    let fastalt = (anim_time * 10.0 + PI / 2.0).sin();
629    let slow = (anim_time * 2.0).sin();
630
631    next.control_l.position = Vec3::new(-1.0 - s_a.grip.0 * 2.0, 0.0, 0.0);
632    next.control_r.position = Vec3::new(1.0 + s_a.grip.0 * 2.0, 3.0, -2.0);
633
634    next.control.position = Vec3::new(
635        -1.0,
636        2.0 + s_a.grip.2,
637        3.0 + -s_a.grip.2 / 2.5
638            + s_a.grip.0 * -2.0
639            + fastacc * 1.5
640            + fastalt * 0.5 * speednormcancel
641            + speednorm * 2.0,
642    );
643
644    next.control_l.orientation =
645        Quaternion::rotation_x(PI / 2.0 + slow * 0.1) * Quaternion::rotation_y(-0.3);
646    next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + slow * 0.1 + s_a.grip.0 * 0.2)
647        * Quaternion::rotation_y(0.5 + slow * 0.0 + s_a.grip.0 * 0.2);
648
649    next.control.orientation =
650        Quaternion::rotation_x(-0.3 + 0.5 * speednorm) * Quaternion::rotation_y(0.5 * speednorm);
651}
652
653fn mount_point(body: &Body) -> Vec3<f32> {
654    use comp::biped_small::Species::*;
655    // TODO: Come up with a way to position rider
656    match (body.species, body.body_type) {
657        (Gnome, _) => (0.0, -4.0, -1.0),
658        (Sahagin, _) => (0.0, 0.0, 5.0),
659        (Adlet, _) => (0.0, -4.0, 1.0),
660        (Gnarling, _) => (0.0, -4.0, 1.5),
661        (Mandragora, _) => (0.0, -3.5, 6.0),
662        (Kappa, _) => (0.0, -5.0, 1.0),
663        (Cactid, _) => (0.0, -2.5, -0.5),
664        (Gnoll, _) => (0.0, -4.0, 2.0),
665        (Haniwa, _) => (0.0, -6.0, 1.0),
666        (Myrmidon, _) => (0.0, -5.5, 1.5),
667        (Husk, _) => (0.0, -5.5, 1.5),
668        (Boreal, _) => (0.0, -4.5, 2.0),
669        (Bushly, _) => (0.0, -3.0, 16.0),
670        (Irrwurz, _) => (0.0, -4.0, 10.0),
671        (IronDwarf, _) => (0.0, -4.0, 4.5),
672        (Flamekeeper, _) => (0.0, -6.5, 7.0),
673        (ShamanicSpirit, _) => (0.0, 0.0, 6.5),
674        (Jiangshi, _) => (0.0, -1.5, 7.5),
675        (TreasureEgg, _) => (0.0, -3.5, 8.0),
676        (GnarlingChieftain, _) => (0.0, -4.0, 4.5),
677        (BloodmoonHeiress, _) => (0.0, -1.0, 14.0),
678        (Bloodservant, _) => (0.0, -1.5, 4.5),
679        (Harlequin, _) => (0.0, -3.0, 2.5),
680        (GoblinThug, _) => (0.0, -4.0, -3.0),
681        (GoblinChucker, _) => (0.0, -9.0, -3.0),
682        (GoblinRuffian, _) => (0.0, -4.0, -3.0),
683        (GreenLegoom, _) => (0.0, -4.5, 6.0),
684        (OchreLegoom, _) => (0.0, -4.5, 3.0),
685        (PurpleLegoom, _) => (0.0, -3.5, 7.5),
686        (RedLegoom, _) => (0.0, -3.5, 5.0),
687    }
688    .into()
689}