veloren_voxygen_anim/fish_medium/
mod.rs1pub mod idle;
2pub mod swim;
3
4pub 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}