veloren_voxygen_anim/fish_small/
mod.rs1pub mod idle;
2pub mod swim;
3
4pub 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(
29 feature = "be-dyn-lib",
30 unsafe(export_name = "fish_small_compute_mats")
31 )]
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 / 13.0);
39 let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
40
41 *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
42 make_bone(chest_mat),
43 make_bone(chest_mat * Mat4::<f32>::from(self.tail)),
44 make_bone(chest_mat * Mat4::<f32>::from(self.fin_l)),
45 make_bone(chest_mat * Mat4::<f32>::from(self.fin_r)),
46 ];
47
48 let (mount_bone_mat, mount_bone_ori) = (chest_mat, self.chest.orientation);
49 let mount_position = mount_bone_mat.mul_point(mount_point(&body));
50 let mount_orientation = mount_bone_ori;
51
52 Offsets {
53 viewpoint: Some((chest_mat * Vec4::new(0.0, 3.0, 0.0, 1.0)).xyz()),
54 mount_bone: Transform {
56 position: mount_position,
57 orientation: mount_orientation,
58 scale: Vec3::one(),
59 },
60 ..Default::default()
61 }
62 }
63}
64
65pub struct SkeletonAttr {
66 chest: (f32, f32),
67 tail: (f32, f32),
68 fin: (f32, f32, f32),
69 tempo: f32,
70 amplitude: f32,
71}
72
73impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
74 type Error = ();
75
76 fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
77 match body {
78 comp::Body::FishSmall(body) => Ok(SkeletonAttr::from(body)),
79 _ => Err(()),
80 }
81 }
82}
83
84impl Default for SkeletonAttr {
85 fn default() -> Self {
86 Self {
87 chest: (0.0, 0.0),
88 tail: (0.0, 0.0),
89 fin: (0.0, 0.0, 0.0),
90 tempo: 0.0,
91 amplitude: 0.0,
92 }
93 }
94}
95
96impl<'a> From<&'a Body> for SkeletonAttr {
97 fn from(body: &'a Body) -> Self {
98 use comp::fish_small::Species::*;
99 Self {
100 chest: match (body.species, body.body_type) {
101 (Clownfish, _) => (0.0, 5.0),
102 (Piranha, _) => (0.0, 5.0),
103 },
104 tail: match (body.species, body.body_type) {
105 (Clownfish, _) => (-7.5, -0.5),
106 (Piranha, _) => (-5.5, -0.5),
107 },
108 fin: match (body.species, body.body_type) {
109 (Clownfish, _) => (2.0, 0.5, 1.0),
110 (Piranha, _) => (2.0, 0.5, -0.5),
111 },
112 tempo: match (body.species, body.body_type) {
113 (Clownfish, _) => 5.0,
114 (Piranha, _) => 5.0,
115 },
116 amplitude: match (body.species, body.body_type) {
117 (Clownfish, _) => 4.0,
118 (Piranha, _) => 4.0,
119 },
120 }
121 }
122}
123
124fn mount_point(body: &Body) -> Vec3<f32> {
125 use comp::fish_small::Species::*;
126 match (body.species, body.body_type) {
127 (Clownfish, _) => (0.0, 0.5, 3.0),
128 (Piranha, _) => (0.0, -1.0, 4.5),
129 }
130 .into()
131}