veloren_voxygen_anim/fish_medium/
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_medium::Body;
12
13skeleton_impls!(struct FishMediumSkeleton {
14    + head,
15    + jaw,
16    + chest_front,
17    + chest_back,
18    + tail,
19    + fin_l,
20    + fin_r,
21});
22
23impl Skeleton for FishMediumSkeleton {
24    type Attr = SkeletonAttr;
25    type Body = Body;
26
27    const BONE_COUNT: usize = 7;
28    #[cfg(feature = "use-dyn-lib")]
29    const COMPUTE_FN: &'static [u8] = b"fish_medium_compute_mats\0";
30
31    #[cfg_attr(feature = "be-dyn-lib", export_name = "fish_medium_compute_mats")]
32    fn compute_matrices_inner(
33        &self,
34        base_mat: Mat4<f32>,
35        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
36        body: Self::Body,
37    ) -> Offsets {
38        let base_mat = base_mat * Mat4::scaling_3d(1.0 / 11.0);
39
40        let chest_front_mat = base_mat * Mat4::<f32>::from(self.chest_front);
41        let chest_back_mat = Mat4::<f32>::from(self.chest_back);
42        let head_mat = chest_front_mat * Mat4::<f32>::from(self.head);
43
44        *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
45            make_bone(head_mat),
46            make_bone(head_mat * Mat4::<f32>::from(self.jaw)),
47            make_bone(chest_front_mat),
48            make_bone(chest_front_mat * chest_back_mat),
49            make_bone(chest_front_mat * chest_back_mat * Mat4::<f32>::from(self.tail)),
50            make_bone(chest_front_mat * Mat4::<f32>::from(self.fin_l)),
51            make_bone(chest_front_mat * Mat4::<f32>::from(self.fin_r)),
52        ];
53
54        let (mount_bone_mat, mount_bone_ori) = (head_mat, self.head.orientation);
55        let mount_position = mount_bone_mat.mul_point(mount_point(&body));
56        let mount_orientation = mount_bone_ori;
57
58        Offsets {
59            viewpoint: Some((head_mat * Vec4::new(0.0, 5.0, 0.0, 1.0)).xyz()),
60            // TODO: see quadruped_medium for how to animate this
61            mount_bone: Transform {
62                position: mount_position,
63                orientation: mount_orientation,
64                scale: Vec3::one(),
65            },
66            ..Default::default()
67        }
68    }
69}
70
71pub struct SkeletonAttr {
72    head: (f32, f32),
73    jaw: (f32, f32),
74    chest_front: (f32, f32),
75    chest_back: (f32, f32),
76    tail: (f32, f32),
77    fin: (f32, f32, f32),
78    tempo: f32,
79    amplitude: f32,
80}
81
82impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
83    type Error = ();
84
85    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
86        match body {
87            comp::Body::FishMedium(body) => Ok(SkeletonAttr::from(body)),
88            _ => Err(()),
89        }
90    }
91}
92
93impl Default for SkeletonAttr {
94    fn default() -> Self {
95        Self {
96            head: (0.0, 0.0),
97            jaw: (0.0, 0.0),
98            chest_front: (0.0, 0.0),
99            chest_back: (0.0, 0.0),
100            tail: (0.0, 0.0),
101            fin: (0.0, 0.0, 0.0),
102            tempo: 0.0,
103            amplitude: 0.0,
104        }
105    }
106}
107
108impl<'a> From<&'a Body> for SkeletonAttr {
109    fn from(body: &'a Body) -> Self {
110        use comp::fish_medium::Species::*;
111        Self {
112            head: match (body.species, body.body_type) {
113                (Marlin, _) => (2.0, 1.5),
114                (Icepike, _) => (3.0, 1.0),
115            },
116            jaw: match (body.species, body.body_type) {
117                (Marlin, _) => (2.5, -3.0),
118                (Icepike, _) => (0.0, 0.0),
119            },
120            chest_front: match (body.species, body.body_type) {
121                (Marlin, _) => (0.0, 2.5),
122                (Icepike, _) => (0.0, 2.5),
123            },
124            chest_back: match (body.species, body.body_type) {
125                (Marlin, _) => (-1.0, 1.0),
126                (Icepike, _) => (-4.5, 0.0),
127            },
128            tail: match (body.species, body.body_type) {
129                (Marlin, _) => (-7.0, 0.0),
130                (Icepike, _) => (-0.5, 1.5),
131            },
132            fin: match (body.species, body.body_type) {
133                (Marlin, _) => (2.5, 1.0, 3.5),
134                (Icepike, _) => (3.5, 3.0, 0.0),
135            },
136            tempo: match (body.species, body.body_type) {
137                (Marlin, _) => 4.0,
138                (Icepike, _) => 4.0,
139            },
140            amplitude: match (body.species, body.body_type) {
141                (Marlin, _) => 4.0,
142                (Icepike, _) => 4.0,
143            },
144        }
145    }
146}
147
148fn mount_point(body: &Body) -> Vec3<f32> {
149    use comp::fish_medium::Species::*;
150    match (body.species, body.body_type) {
151        (Marlin, _) => (0.0, 0.5, 3.0),
152        (Icepike, _) => (0.0, 0.5, 4.0),
153    }
154    .into()
155}