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, Skeleton, vek::*};
8use common::comp::{self};
9use core::convert::TryFrom;
10
11pub type Body = comp::fish_medium::Body;
12
13skeleton_impls!(struct FishMediumSkeleton ComputedFishMediumSkeleton {
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    type ComputedSkeleton = ComputedFishMediumSkeleton;
27
28    const BONE_COUNT: usize = ComputedFishMediumSkeleton::BONE_COUNT;
29    #[cfg(feature = "use-dyn-lib")]
30    const COMPUTE_FN: &'static [u8] = b"fish_medium_compute_mats\0";
31
32    #[cfg_attr(
33        feature = "be-dyn-lib",
34        unsafe(export_name = "fish_medium_compute_mats")
35    )]
36    fn compute_matrices_inner(
37        &self,
38        base_mat: Mat4<f32>,
39        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
40        _body: Self::Body,
41    ) -> Self::ComputedSkeleton {
42        let base_mat = base_mat * Mat4::scaling_3d(1.0 / 11.0);
43
44        let chest_front_mat = base_mat * Mat4::<f32>::from(self.chest_front);
45        let chest_back_mat = Mat4::<f32>::from(self.chest_back);
46        let head_mat = chest_front_mat * Mat4::<f32>::from(self.head);
47
48        let computed_skeleton = ComputedFishMediumSkeleton {
49            head: head_mat,
50            jaw: head_mat * Mat4::<f32>::from(self.jaw),
51            chest_front: chest_front_mat,
52            chest_back: chest_front_mat * chest_back_mat,
53            tail: chest_front_mat * chest_back_mat * Mat4::<f32>::from(self.tail),
54            fin_l: chest_front_mat * Mat4::<f32>::from(self.fin_l),
55            fin_r: chest_front_mat * Mat4::<f32>::from(self.fin_r),
56        };
57
58        computed_skeleton.set_figure_bone_data(buf);
59        computed_skeleton
60    }
61}
62
63pub struct SkeletonAttr {
64    head: (f32, f32),
65    jaw: (f32, f32),
66    chest_front: (f32, f32),
67    chest_back: (f32, f32),
68    tail: (f32, f32),
69    fin: (f32, f32, f32),
70    tempo: f32,
71    amplitude: f32,
72}
73
74impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
75    type Error = ();
76
77    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
78        match body {
79            comp::Body::FishMedium(body) => Ok(SkeletonAttr::from(body)),
80            _ => Err(()),
81        }
82    }
83}
84
85impl Default for SkeletonAttr {
86    fn default() -> Self {
87        Self {
88            head: (0.0, 0.0),
89            jaw: (0.0, 0.0),
90            chest_front: (0.0, 0.0),
91            chest_back: (0.0, 0.0),
92            tail: (0.0, 0.0),
93            fin: (0.0, 0.0, 0.0),
94            tempo: 0.0,
95            amplitude: 0.0,
96        }
97    }
98}
99
100impl<'a> From<&'a Body> for SkeletonAttr {
101    fn from(body: &'a Body) -> Self {
102        use comp::fish_medium::Species::*;
103        Self {
104            head: match (body.species, body.body_type) {
105                (Marlin, _) => (2.0, 1.5),
106                (Icepike, _) => (3.0, 1.0),
107            },
108            jaw: match (body.species, body.body_type) {
109                (Marlin, _) => (2.5, -3.0),
110                (Icepike, _) => (0.0, 0.0),
111            },
112            chest_front: match (body.species, body.body_type) {
113                (Marlin, _) => (0.0, 2.5),
114                (Icepike, _) => (0.0, 2.5),
115            },
116            chest_back: match (body.species, body.body_type) {
117                (Marlin, _) => (-1.0, 1.0),
118                (Icepike, _) => (-4.5, 0.0),
119            },
120            tail: match (body.species, body.body_type) {
121                (Marlin, _) => (-7.0, 0.0),
122                (Icepike, _) => (-0.5, 1.5),
123            },
124            fin: match (body.species, body.body_type) {
125                (Marlin, _) => (2.5, 1.0, 3.5),
126                (Icepike, _) => (3.5, 3.0, 0.0),
127            },
128            tempo: match (body.species, body.body_type) {
129                (Marlin, _) => 4.0,
130                (Icepike, _) => 4.0,
131            },
132            amplitude: match (body.species, body.body_type) {
133                (Marlin, _) => 4.0,
134                (Icepike, _) => 4.0,
135            },
136        }
137    }
138}
139
140pub fn mount_mat(
141    computed_skeleton: &ComputedFishMediumSkeleton,
142    skeleton: &FishMediumSkeleton,
143) -> (Mat4<f32>, Quaternion<f32>) {
144    (computed_skeleton.head, skeleton.head.orientation)
145}
146
147pub fn mount_transform(
148    body: &Body,
149    computed_skeleton: &ComputedFishMediumSkeleton,
150    skeleton: &FishMediumSkeleton,
151) -> Transform<f32, f32, f32> {
152    use comp::fish_medium::Species::*;
153
154    let mount_point = match (body.species, body.body_type) {
155        (Marlin, _) => (0.0, 0.5, 3.0),
156        (Icepike, _) => (0.0, 0.5, 4.0),
157    }
158    .into();
159
160    let (mount_mat, orientation) = mount_mat(computed_skeleton, skeleton);
161    Transform {
162        position: mount_mat.mul_point(mount_point),
163        orientation,
164        scale: Vec3::one(),
165    }
166}