veloren_voxygen_anim/fish_small/
mod.rs

1pub mod idle;
2pub mod swim;
3
4// Reexports
5pub use self::{idle::IdleAnimation, swim::SwimAnimation};
6
7use super::{FigureBoneData, Offsets, Skeleton, make_bone, vek::*};
8use common::comp::{self};
9use core::convert::TryFrom;
10
11pub type Body = comp::fish_small::Body;
12
13skeleton_impls!(struct FishSmallSkeleton {
14    + chest,
15    + tail,
16    + fin_l,
17    + fin_r,
18});
19
20impl Skeleton for FishSmallSkeleton {
21    type Attr = SkeletonAttr;
22    type Body = Body;
23
24    const BONE_COUNT: usize = 4;
25    #[cfg(feature = "use-dyn-lib")]
26    const COMPUTE_FN: &'static [u8] = b"fish_small_compute_mats\0";
27
28    #[cfg_attr(feature = "be-dyn-lib", export_name = "fish_small_compute_mats")]
29    fn compute_matrices_inner(
30        &self,
31        base_mat: Mat4<f32>,
32        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
33        body: Self::Body,
34    ) -> Offsets {
35        let base_mat = base_mat * Mat4::scaling_3d(1.0 / 13.0);
36        let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
37
38        *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
39            make_bone(chest_mat),
40            make_bone(chest_mat * Mat4::<f32>::from(self.tail)),
41            make_bone(chest_mat * Mat4::<f32>::from(self.fin_l)),
42            make_bone(chest_mat * Mat4::<f32>::from(self.fin_r)),
43        ];
44
45        let (mount_bone_mat, mount_bone_ori) = (chest_mat, self.chest.orientation);
46        let mount_position = mount_bone_mat.mul_point(mount_point(&body));
47        let mount_orientation = mount_bone_ori;
48
49        Offsets {
50            viewpoint: Some((chest_mat * Vec4::new(0.0, 3.0, 0.0, 1.0)).xyz()),
51            // TODO: see quadruped_medium for how to animate this
52            mount_bone: Transform {
53                position: mount_position,
54                orientation: mount_orientation,
55                scale: Vec3::one(),
56            },
57            ..Default::default()
58        }
59    }
60}
61
62pub struct SkeletonAttr {
63    chest: (f32, f32),
64    tail: (f32, f32),
65    fin: (f32, f32, f32),
66    tempo: f32,
67    amplitude: f32,
68}
69
70impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
71    type Error = ();
72
73    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
74        match body {
75            comp::Body::FishSmall(body) => Ok(SkeletonAttr::from(body)),
76            _ => Err(()),
77        }
78    }
79}
80
81impl Default for SkeletonAttr {
82    fn default() -> Self {
83        Self {
84            chest: (0.0, 0.0),
85            tail: (0.0, 0.0),
86            fin: (0.0, 0.0, 0.0),
87            tempo: 0.0,
88            amplitude: 0.0,
89        }
90    }
91}
92
93impl<'a> From<&'a Body> for SkeletonAttr {
94    fn from(body: &'a Body) -> Self {
95        use comp::fish_small::Species::*;
96        Self {
97            chest: match (body.species, body.body_type) {
98                (Clownfish, _) => (0.0, 5.0),
99                (Piranha, _) => (0.0, 5.0),
100            },
101            tail: match (body.species, body.body_type) {
102                (Clownfish, _) => (-7.5, -0.5),
103                (Piranha, _) => (-5.5, -0.5),
104            },
105            fin: match (body.species, body.body_type) {
106                (Clownfish, _) => (2.0, 0.5, 1.0),
107                (Piranha, _) => (2.0, 0.5, -0.5),
108            },
109            tempo: match (body.species, body.body_type) {
110                (Clownfish, _) => 5.0,
111                (Piranha, _) => 5.0,
112            },
113            amplitude: match (body.species, body.body_type) {
114                (Clownfish, _) => 4.0,
115                (Piranha, _) => 4.0,
116            },
117        }
118    }
119}
120
121fn mount_point(body: &Body) -> Vec3<f32> {
122    use comp::fish_small::Species::*;
123    match (body.species, body.body_type) {
124        (Clownfish, _) => (0.0, 0.5, 3.0),
125        (Piranha, _) => (0.0, -1.0, 4.5),
126    }
127    .into()
128}