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