1pub mod alpha;
2pub mod breathe;
3pub mod dash;
4pub mod feed;
5pub mod fly;
6pub mod idle;
7pub mod run;
8pub mod shockwave;
9pub mod shoot;
10pub mod stunned;
11pub mod summon;
12pub mod swim;
13
14pub use self::{
16 alpha::AlphaAnimation, breathe::BreatheAnimation, dash::DashAnimation, feed::FeedAnimation,
17 fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation,
18 shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation,
19};
20
21use super::{FigureBoneData, Skeleton, vek::*};
22use common::comp::{self};
23use core::convert::TryFrom;
24
25pub type Body = comp::bird_medium::Body;
26
27skeleton_impls!(struct BirdMediumSkeleton ComputedBirdMediumSkeleton {
28 + head
29 + chest
30 + tail
31 + wing_in_l
32 + wing_in_r
33 + wing_out_l
34 + wing_out_r
35 + leg_l
36 + leg_r
37});
38
39impl Skeleton for BirdMediumSkeleton {
40 type Attr = SkeletonAttr;
41 type Body = Body;
42 type ComputedSkeleton = ComputedBirdMediumSkeleton;
43
44 const BONE_COUNT: usize = ComputedBirdMediumSkeleton::BONE_COUNT;
45 #[cfg(feature = "use-dyn-lib")]
46 const COMPUTE_FN: &'static [u8] = b"bird_medium_compute_mats\0";
47
48 #[cfg_attr(
49 feature = "be-dyn-lib",
50 unsafe(export_name = "bird_medium_compute_mats")
51 )]
52
53 fn compute_matrices_inner(
54 &self,
55 base_mat: Mat4<f32>,
56 buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
57 body: Self::Body,
58 ) -> Self::ComputedSkeleton {
59 let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 8.0);
60
61 let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
62 let head_mat = chest_mat * Mat4::<f32>::from(self.head);
63 let tail_mat = chest_mat * Mat4::<f32>::from(self.tail);
64 let wing_in_l_mat = chest_mat * Mat4::<f32>::from(self.wing_in_l);
65 let wing_in_r_mat = chest_mat * Mat4::<f32>::from(self.wing_in_r);
66 let wing_out_l_mat = wing_in_l_mat * Mat4::<f32>::from(self.wing_out_l);
67 let wing_out_r_mat = wing_in_r_mat * Mat4::<f32>::from(self.wing_out_r);
68 let leg_l_mat = base_mat * Mat4::<f32>::from(self.leg_l);
69 let leg_r_mat = base_mat * Mat4::<f32>::from(self.leg_r);
70
71 let computed_skeleton = ComputedBirdMediumSkeleton {
72 head: head_mat,
73 chest: chest_mat,
74 tail: tail_mat,
75 wing_in_l: wing_in_l_mat,
76 wing_in_r: wing_in_r_mat,
77 wing_out_l: wing_out_l_mat,
78 wing_out_r: wing_out_r_mat,
79 leg_l: leg_l_mat,
80 leg_r: leg_r_mat,
81 };
82
83 computed_skeleton.set_figure_bone_data(buf);
84 computed_skeleton
85 }
86}
87
88pub struct SkeletonAttr {
89 head: (f32, f32),
90 chest: (f32, f32),
91 tail: (f32, f32),
92 wing_in: (f32, f32, f32),
93 wing_out: (f32, f32, f32),
94 leg: (f32, f32, f32),
95 scaler: f32,
96 feed: f32,
97}
98
99impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
100 type Error = ();
101
102 fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
103 match body {
104 comp::Body::BirdMedium(body) => Ok(SkeletonAttr::from(body)),
105 _ => Err(()),
106 }
107 }
108}
109
110impl Default for SkeletonAttr {
111 fn default() -> Self {
112 Self {
113 chest: (0.0, 0.0),
114 head: (0.0, 0.0),
115 tail: (0.0, 0.0),
116 wing_in: (0.0, 0.0, 0.0),
117 wing_out: (0.0, 0.0, 0.0),
118 leg: (0.0, 0.0, 0.0),
119 scaler: 0.0,
120 feed: 0.0,
121 }
122 }
123}
124
125impl<'a> From<&'a Body> for SkeletonAttr {
126 fn from(body: &'a Body) -> Self {
127 use comp::bird_medium::{BodyType::*, Species::*};
128 Self {
129 chest: match (body.species, body.body_type) {
130 (SnowyOwl, _) => (0.0, 4.5),
131 (HornedOwl, _) => (0.0, 4.5),
132 (Duck, _) => (0.0, 4.0),
133 (Cockatiel, _) => (0.0, 4.0),
134 (Chicken, Male) => (0.0, 5.5),
135 (Chicken, Female) => (0.0, 5.5),
136 (Bat, _) => (0.0, 7.0),
137 (Penguin, _) => (0.0, 7.0),
138 (Goose, _) => (0.0, 6.5),
139 (Peacock, _) => (0.0, 7.5),
140 (Eagle, _) => (0.0, 6.0),
141 (Parrot, _) => (0.0, 5.0),
142 (Crow, _) => (0.0, 4.0),
143 (Dodo, _) => (0.0, 6.0),
144 (Parakeet, _) => (0.0, 3.5),
145 (Puffin, _) => (0.0, 6.0),
146 (Toucan, _) => (0.0, 5.0),
147 (BloodmoonBat, _) => (0.0, 7.0),
148 (VampireBat, _) => (0.0, 7.5),
149 },
150 head: match (body.species, body.body_type) {
151 (SnowyOwl, _) => (3.5, 5.0),
152 (HornedOwl, _) => (3.5, 5.0),
153 (Duck, _) => (2.0, 5.5),
154 (Cockatiel, _) => (3.0, 5.5),
155 (Chicken, Male) => (3.0, 4.5),
156 (Chicken, Female) => (3.0, 6.0),
157 (Bat, _) => (2.5, 5.0),
158 (Penguin, _) => (1.5, 6.0),
159 (Goose, _) => (5.0, 4.0),
160 (Peacock, _) => (3.0, 5.0),
161 (Eagle, _) => (4.5, 5.0),
162 (Parrot, _) => (1.5, 4.5),
163 (Crow, _) => (4.5, 4.0),
164 (Dodo, _) => (3.5, 4.5),
165 (Parakeet, _) => (2.0, 4.0),
166 (Puffin, _) => (3.5, 5.5),
167 (Toucan, _) => (2.5, 4.5),
168 (BloodmoonBat, _) => (4.0, 5.0),
169 (VampireBat, _) => (2.5, 5.0),
170 },
171 tail: match (body.species, body.body_type) {
172 (SnowyOwl, _) => (-6.0, -2.0),
173 (HornedOwl, _) => (-6.0, -2.0),
174 (Duck, _) => (-5.0, 1.0),
175 (Cockatiel, _) => (-3.0, -0.5),
176 (Chicken, Male) => (-7.5, 3.5),
177 (Chicken, Female) => (-4.5, 3.0),
178 (Bat, _) => (-8.0, -4.0),
179 (Penguin, _) => (-3.0, -4.0),
180 (Goose, _) => (-4.0, 3.0),
181 (Peacock, _) => (-5.5, 1.0),
182 (Eagle, _) => (-6.0, -2.0),
183 (Parrot, _) => (-6.0, 0.0),
184 (Crow, _) => (-5.0, -1.5),
185 (Dodo, _) => (-7.5, -0.5),
186 (Parakeet, _) => (-5.0, -1.0),
187 (Puffin, _) => (-7.0, -2.0),
188 (Toucan, _) => (-6.0, 0.0),
189 (BloodmoonBat, _) => (-6.0, 1.0),
190 (VampireBat, _) => (-5.0, -4.0),
191 },
192 wing_in: match (body.species, body.body_type) {
193 (SnowyOwl, _) => (2.5, 1.0, 1.5),
194 (HornedOwl, _) => (2.5, 1.0, 1.5),
195 (Duck, _) => (2.5, 0.5, 1.0),
196 (Cockatiel, _) => (1.5, 0.5, 1.0),
197 (Chicken, Male) => (2.0, 1.0, 1.0),
198 (Chicken, Female) => (2.0, 1.5, 1.0),
199 (Bat, _) => (2.0, 2.0, -2.0),
200 (Penguin, _) => (3.0, 0.5, 1.0),
201 (Goose, _) => (2.5, 1.0, 2.0),
202 (Peacock, _) => (2.0, 1.0, 1.0),
203 (Eagle, _) => (3.0, 1.5, 1.0),
204 (Parrot, _) => (2.0, 0.5, 0.0),
205 (Crow, _) => (2.0, 0.5, 1.0),
206 (Dodo, _) => (3.0, -1.0, 1.0),
207 (Parakeet, _) => (1.0, 0.5, 0.0),
208 (Puffin, _) => (2.0, 0.0, 1.0),
209 (Toucan, _) => (2.0, 0.5, 0.0),
210 (BloodmoonBat, _) => (4.0, 3.0, 1.5),
211 (VampireBat, _) => (2.0, 2.0, -2.0),
212 },
213 wing_out: match (body.species, body.body_type) {
214 (SnowyOwl, _) => (4.5, 3.5, 1.0),
215 (HornedOwl, _) => (4.5, 3.5, 1.0),
216 (Duck, _) => (3.0, 2.0, 0.5),
217 (Cockatiel, _) => (3.0, 2.0, 0.5),
218 (Chicken, Male) => (3.0, 2.0, 0.5),
219 (Chicken, Female) => (3.0, 2.0, 0.5),
220 (Bat, _) => (5.0, 3.0, 0.0),
221 (Penguin, _) => (3.0, 2.5, 0.5),
222 (Goose, _) => (4.0, 3.0, 0.5),
223 (Peacock, _) => (5.0, 3.0, 0.5),
224 (Eagle, _) => (8.0, 4.5, 0.5),
225 (Parrot, _) => (5.0, 3.0, 0.5),
226 (Crow, _) => (5.0, 3.0, 0.5),
227 (Dodo, _) => (3.0, 3.0, 0.5),
228 (Parakeet, _) => (3.0, 0.0, 0.5),
229 (Puffin, _) => (5.0, 3.0, 0.5),
230 (Toucan, _) => (5.0, 3.0, 0.5),
231 (BloodmoonBat, _) => (11.0, 6.0, 0.0),
232 (VampireBat, _) => (5.0, 5.0, 0.0),
233 },
234 leg: match (body.species, body.body_type) {
235 (SnowyOwl, _) => (1.5, -2.5, 4.8),
236 (HornedOwl, _) => (1.5, -2.5, 4.8),
237 (Duck, _) => (1.5, 0.0, 3.0),
238 (Cockatiel, _) => (1.0, -1.0, 3.0),
239 (Chicken, Male) => (1.0, 0.0, 4.4),
240 (Chicken, Female) => (1.0, 0.0, 4.4),
241 (Bat, _) => (2.5, -1.0, 6.0),
242 (Penguin, _) => (1.5, -1.5, 4.5),
243 (Goose, _) => (2.0, -2.5, 4.4),
244 (Peacock, _) => (2.0, -2.0, 7.0),
245 (Eagle, _) => (1.5, -4.0, 4.4),
246 (Parrot, _) => (1.5, -1.0, 2.2),
247 (Crow, _) => (1.5, -2.5, 2.1),
248 (Dodo, _) => (1.5, -3.0, 3.0),
249 (Parakeet, _) => (1.0, -2.0, 1.3),
250 (Puffin, _) => (1.5, -2.2, 2.5),
251 (Toucan, _) => (1.5, -3.0, 2.3),
252 (BloodmoonBat, _) => (1.5, -3.5, 6.0),
253 (VampireBat, _) => (2.5, -1.0, 6.0),
254 },
255 scaler: match (body.species, body.body_type) {
256 (SnowyOwl, _) => 0.75,
257 (HornedOwl, _) => 0.75,
258 (Duck, _) => 0.75,
259 (Cockatiel, _) => 0.75,
260 (Chicken, _) => 0.75,
261 (Bat, _) => 0.75,
262 (Penguin, _) => 0.75,
263 (Goose, _) => 0.75,
264 (Peacock, _) => 0.75,
265 (Eagle, _) => 0.75,
266 (Parrot, _) => 0.75,
267 (Crow, _) => 0.75,
268 (Dodo, _) => 0.75,
269 (Parakeet, _) => 0.75,
270 (Puffin, _) => 0.75,
271 (Toucan, _) => 0.75,
272 (BloodmoonBat, _) => 1.05,
273 (VampireBat, _) => 0.75,
274 },
275 feed: match (body.species, body.body_type) {
276 (SnowyOwl, _) => -0.65,
277 (HornedOwl, _) => -0.65,
278 (Duck, _) => -0.55,
279 (Cockatiel, _) => -0.60,
280 (Chicken, _) => -0.65,
281 (Bat, _) => -0.55,
282 (Penguin, _) => -0.75,
283 (Goose, _) => -0.65,
284 (Peacock, _) => -1.2,
285 (Eagle, _) => -0.75,
286 (Parrot, _) => -0.60,
287 (Crow, _) => -0.65,
288 (Dodo, _) => -0.65,
289 (Parakeet, _) => -0.60,
290 (Puffin, _) => -0.75,
291 (Toucan, _) => -0.50,
292 (BloodmoonBat, _) => -0.55,
293 (VampireBat, _) => -0.55,
294 },
295 }
296 }
297}
298
299pub fn viewpoint(body: &Body) -> Vec4<f32> {
300 use comp::bird_medium::Species::*;
301 match body.species {
302 Bat | BloodmoonBat | VampireBat => Vec4::new(0.0, 5.0, -4.0, 1.0),
303 _ => Vec4::new(0.0, 3.0, 2.0, 1.0),
304 }
305}
306
307pub fn mount_mat(
308 computed_skeleton: &ComputedBirdMediumSkeleton,
309 skeleton: &BirdMediumSkeleton,
310) -> (Mat4<f32>, Quaternion<f32>) {
311 (computed_skeleton.chest, skeleton.chest.orientation)
312}
313
314pub fn mount_transform(
315 body: &Body,
316 computed_skeleton: &ComputedBirdMediumSkeleton,
317 skeleton: &BirdMediumSkeleton,
318) -> Transform<f32, f32, f32> {
319 use comp::bird_medium::{BodyType::*, Species::*};
320
321 let mount_point = match (body.species, body.body_type) {
322 (SnowyOwl, _) => (0.0, -4.0, 2.0),
323 (HornedOwl, _) => (0.0, -4.0, 1.0),
324 (Duck, _) => (0.0, -3.0, 2.0),
325 (Cockatiel, _) => (0.0, -1.5, 1.5),
326 (Chicken, Female) => (0.0, -2.5, 2.5),
327 (Chicken, Male) => (0.0, -2.0, 2.5),
328 (Bat, _) => (0.0, 0.0, -1.5),
329 (Penguin, _) => (0.0, -2.5, 4.5),
330 (Goose, _) => (0.0, -1.0, 3.0),
331 (Peacock, _) => (0.0, -3.0, 2.5),
332 (Eagle, _) => (0.0, -4.0, 2.0),
333 (Parrot, _) => (0.0, -3.0, 1.5),
334 (Crow, _) => (0.0, -1.5, 2.0),
335 (Dodo, _) => (0.0, -4.0, 3.0),
336 (Parakeet, _) => (0.0, -1.5, 1.5),
337 (Puffin, _) => (0.0, -3.5, 1.0),
338 (Toucan, _) => (0.0, -2.0, 1.5),
339 (BloodmoonBat, _) => (0.0, 0.5, 3.5),
340 (VampireBat, _) => (0.0, 0.0, -1.5),
341 }
342 .into();
343
344 let (mount_mat, orientation) = mount_mat(computed_skeleton, skeleton);
345 Transform {
346 position: mount_mat.mul_point(mount_point),
347 orientation,
348 scale: Vec3::one(),
349 }
350}