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, Skeleton, vek::*};
8use common::comp::{self};
9use core::convert::TryFrom;
10
11pub type Body = comp::fish_small::Body;
12
13skeleton_impls!(struct FishSmallSkeleton ComputedFishSmallSkeleton {
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    type ComputedSkeleton = ComputedFishSmallSkeleton;
24
25    const BONE_COUNT: usize = ComputedFishSmallSkeleton::BONE_COUNT;
26    #[cfg(feature = "use-dyn-lib")]
27    const COMPUTE_FN: &'static [u8] = b"fish_small_compute_mats\0";
28
29    #[cfg_attr(
30        feature = "be-dyn-lib",
31        unsafe(export_name = "fish_small_compute_mats")
32    )]
33    fn compute_matrices_inner(
34        &self,
35        base_mat: Mat4<f32>,
36        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
37        _body: Self::Body,
38    ) -> Self::ComputedSkeleton {
39        let base_mat = base_mat * Mat4::scaling_3d(1.0 / 13.0);
40        let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
41
42        let computed_skeleton = ComputedFishSmallSkeleton {
43            chest: chest_mat,
44            tail: chest_mat * Mat4::<f32>::from(self.tail),
45            fin_l: chest_mat * Mat4::<f32>::from(self.fin_l),
46            fin_r: chest_mat * Mat4::<f32>::from(self.fin_r),
47        };
48
49        computed_skeleton.set_figure_bone_data(buf);
50        computed_skeleton
51    }
52}
53
54pub struct SkeletonAttr {
55    chest: (f32, f32),
56    tail: (f32, f32),
57    fin: (f32, f32, f32),
58    tempo: f32,
59    amplitude: f32,
60}
61
62impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
63    type Error = ();
64
65    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
66        match body {
67            comp::Body::FishSmall(body) => Ok(SkeletonAttr::from(body)),
68            _ => Err(()),
69        }
70    }
71}
72
73impl Default for SkeletonAttr {
74    fn default() -> Self {
75        Self {
76            chest: (0.0, 0.0),
77            tail: (0.0, 0.0),
78            fin: (0.0, 0.0, 0.0),
79            tempo: 0.0,
80            amplitude: 0.0,
81        }
82    }
83}
84
85impl<'a> From<&'a Body> for SkeletonAttr {
86    fn from(body: &'a Body) -> Self {
87        use comp::fish_small::Species::*;
88        Self {
89            chest: match (body.species, body.body_type) {
90                (Clownfish, _) => (0.0, 5.0),
91                (Piranha, _) => (0.0, 5.0),
92            },
93            tail: match (body.species, body.body_type) {
94                (Clownfish, _) => (-7.5, -0.5),
95                (Piranha, _) => (-5.5, -0.5),
96            },
97            fin: match (body.species, body.body_type) {
98                (Clownfish, _) => (2.0, 0.5, 1.0),
99                (Piranha, _) => (2.0, 0.5, -0.5),
100            },
101            tempo: match (body.species, body.body_type) {
102                (Clownfish, _) => 5.0,
103                (Piranha, _) => 5.0,
104            },
105            amplitude: match (body.species, body.body_type) {
106                (Clownfish, _) => 4.0,
107                (Piranha, _) => 4.0,
108            },
109        }
110    }
111}
112
113pub fn mount_mat(
114    computed_skeleton: &ComputedFishSmallSkeleton,
115    skeleton: &FishSmallSkeleton,
116) -> (Mat4<f32>, Quaternion<f32>) {
117    (computed_skeleton.chest, skeleton.chest.orientation)
118}
119
120pub fn mount_transform(
121    body: &Body,
122    computed_skeleton: &ComputedFishSmallSkeleton,
123    skeleton: &FishSmallSkeleton,
124) -> Transform<f32, f32, f32> {
125    use comp::fish_small::Species::*;
126
127    let mount_point = match (body.species, body.body_type) {
128        (Clownfish, _) => (0.0, 0.5, 3.0),
129        (Piranha, _) => (0.0, -1.0, 4.5),
130    }
131    .into();
132
133    let (mount_mat, orientation) = mount_mat(computed_skeleton, skeleton);
134    Transform {
135        position: mount_mat.mul_point(mount_point),
136        orientation,
137        scale: Vec3::one(),
138    }
139}