veloren_voxygen_anim/theropod/
mod.rs

1pub mod combomelee;
2pub mod dash;
3pub mod idle;
4pub mod jump;
5pub mod run;
6
7// Reexports
8pub use self::{
9    combomelee::ComboAnimation, dash::DashAnimation, idle::IdleAnimation, jump::JumpAnimation,
10    run::RunAnimation,
11};
12
13use super::{FigureBoneData, Skeleton, vek::*};
14use common::comp::{self};
15use core::convert::TryFrom;
16
17pub type Body = comp::theropod::Body;
18
19skeleton_impls!(struct TheropodSkeleton ComputedTheropodSkeleton {
20    + head
21    + jaw
22    + neck
23    + chest_front
24    + chest_back
25    + tail_front
26    + tail_back
27    + hand_l
28    + hand_r
29    + leg_l
30    + leg_r
31    + foot_l
32    + foot_r
33});
34
35impl Skeleton for TheropodSkeleton {
36    type Attr = SkeletonAttr;
37    type Body = Body;
38    type ComputedSkeleton = ComputedTheropodSkeleton;
39
40    const BONE_COUNT: usize = ComputedTheropodSkeleton::BONE_COUNT;
41    #[cfg(feature = "use-dyn-lib")]
42    const COMPUTE_FN: &'static [u8] = b"theropod_compute_mats\0";
43
44    #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "theropod_compute_mats"))]
45
46    fn compute_matrices_inner(
47        &self,
48        base_mat: Mat4<f32>,
49        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
50        body: Self::Body,
51    ) -> Self::ComputedSkeleton {
52        let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0);
53
54        let chest_front_mat = base_mat * Mat4::<f32>::from(self.chest_front);
55        let neck_mat = chest_front_mat * Mat4::<f32>::from(self.neck);
56        let head_mat = neck_mat * Mat4::<f32>::from(self.head);
57        let chest_back_mat = chest_front_mat * Mat4::<f32>::from(self.chest_back);
58        let tail_front_mat = chest_back_mat * Mat4::<f32>::from(self.tail_front);
59        let leg_l_mat = chest_back_mat * Mat4::<f32>::from(self.leg_l);
60        let leg_r_mat = chest_back_mat * Mat4::<f32>::from(self.leg_r);
61
62        let computed_skeleton = ComputedTheropodSkeleton {
63            head: head_mat,
64            jaw: head_mat * Mat4::<f32>::from(self.jaw),
65            neck: neck_mat,
66            chest_front: chest_front_mat,
67            chest_back: chest_back_mat,
68            tail_front: tail_front_mat,
69            tail_back: tail_front_mat * Mat4::<f32>::from(self.tail_back),
70            hand_l: chest_front_mat * Mat4::<f32>::from(self.hand_l),
71            hand_r: chest_front_mat * Mat4::<f32>::from(self.hand_r),
72            leg_l: leg_l_mat,
73            leg_r: leg_r_mat,
74            foot_l: leg_l_mat * Mat4::<f32>::from(self.foot_l),
75            foot_r: leg_r_mat * Mat4::<f32>::from(self.foot_r),
76        };
77
78        computed_skeleton.set_figure_bone_data(buf);
79        computed_skeleton
80    }
81}
82
83pub struct SkeletonAttr {
84    head: (f32, f32),
85    neck: (f32, f32),
86    jaw: (f32, f32),
87    chest_front: (f32, f32),
88    chest_back: (f32, f32),
89    tail_front: (f32, f32),
90    tail_back: (f32, f32),
91    hand: (f32, f32, f32),
92    leg: (f32, f32, f32),
93    foot: (f32, f32, f32),
94    scaler: f32,
95    steady_wings: bool,
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::Theropod(body) => Ok(SkeletonAttr::from(body)),
104            _ => Err(()),
105        }
106    }
107}
108
109impl Default for SkeletonAttr {
110    fn default() -> Self {
111        Self {
112            head: (0.0, 0.0),
113            neck: (0.0, 0.0),
114            jaw: (0.0, 0.0),
115            chest_front: (0.0, 0.0),
116            chest_back: (0.0, 0.0),
117            tail_front: (0.0, 0.0),
118            tail_back: (0.0, 0.0),
119            hand: (0.0, 0.0, 0.0),
120            leg: (0.0, 0.0, 0.0),
121            foot: (0.0, 0.0, 0.0),
122            scaler: 0.0,
123            steady_wings: false,
124        }
125    }
126}
127
128impl<'a> From<&'a Body> for SkeletonAttr {
129    fn from(body: &'a Body) -> Self {
130        use comp::theropod::Species::*;
131        Self {
132            head: match (body.species, body.body_type) {
133                (Archaeos, _) => (8.0, 4.0),
134                (Odonto, _) => (2.0, 2.0),
135                (Sandraptor, _) => (8.0, 5.0),
136                (Snowraptor, _) => (8.0, 5.0),
137                (Woodraptor, _) => (8.0, 5.0),
138                (Sunlizard, _) => (6.5, 3.5),
139                (Yale, _) => (7.0, 14.0),
140                (Dodarock, _) => (2.0, 1.5),
141                (Ntouka, _) => (2.0, 2.5),
142                (Axebeak, _) => (11.5, 8.5),
143            },
144            jaw: match (body.species, body.body_type) {
145                (Archaeos, _) => (1.0, -7.0),
146                (Odonto, _) => (2.0, -7.0),
147                (Sandraptor, _) => (0.0, -4.0),
148                (Snowraptor, _) => (0.0, -4.0),
149                (Woodraptor, _) => (0.0, -4.0),
150                (Sunlizard, _) => (2.0, -2.5),
151                (Yale, _) => (2.0, -9.5),
152                (Dodarock, _) => (0.0, -5.0),
153                (Ntouka, _) => (0.0, -4.0),
154                (Axebeak, _) => (2.5, -4.0),
155            },
156            neck: match (body.species, body.body_type) {
157                (Archaeos, _) => (4.5, -2.0),
158                (Odonto, _) => (4.0, 0.0),
159                (Sandraptor, _) => (4.0, 2.5),
160                (Snowraptor, _) => (4.0, 2.5),
161                (Woodraptor, _) => (4.0, 2.5),
162                (Sunlizard, _) => (2.5, 1.5),
163                (Yale, _) => (2.0, 4.0),
164                (Dodarock, _) => (5.0, -1.0),
165                (Ntouka, _) => (4.0, 0.0),
166                (Axebeak, _) => (-5.5, 0.0),
167            },
168            chest_front: match (body.species, body.body_type) {
169                (Archaeos, _) => (0.0, 20.0),
170                (Odonto, _) => (0.0, 13.0),
171                (Sandraptor, _) => (0.0, 15.5),
172                (Snowraptor, _) => (0.0, 15.5),
173                (Woodraptor, _) => (0.0, 15.5),
174                (Sunlizard, _) => (0.0, 14.0),
175                (Yale, _) => (0.0, 19.5),
176                (Dodarock, _) => (0.0, 12.0),
177                (Ntouka, _) => (0.0, 13.0),
178                (Axebeak, _) => (0.0, 12.0),
179            },
180            chest_back: match (body.species, body.body_type) {
181                (Archaeos, _) => (-5.5, -1.0),
182                (Odonto, _) => (-5.0, 2.0),
183                (Sandraptor, _) => (-3.0, 0.5),
184                (Snowraptor, _) => (-3.0, 0.5),
185                (Woodraptor, _) => (-3.0, 0.5),
186                (Sunlizard, _) => (-2.0, 0.0),
187                (Yale, _) => (-3.0, -1.0),
188                (Dodarock, _) => (-4.5, -2.0),
189                (Ntouka, _) => (-4.5, 1.0),
190                (Axebeak, _) => (-5.0, 0.0),
191            },
192            tail_front: match (body.species, body.body_type) {
193                (Archaeos, _) => (-9.0, -1.5),
194                (Odonto, _) => (-7.0, -1.0),
195                (Sandraptor, _) => (-9.5, -1.0),
196                (Snowraptor, _) => (-9.5, -1.0),
197                (Woodraptor, _) => (-9.5, -1.0),
198                (Sunlizard, _) => (-8.5, -2.0),
199                (Yale, _) => (-9.5, -4.0),
200                (Dodarock, _) => (-4.5, -4.5),
201                (Ntouka, _) => (-9.5, -3.5),
202                (Axebeak, _) => (-5.5, 4.5),
203            },
204            tail_back: match (body.species, body.body_type) {
205                (Archaeos, _) => (-8.0, -0.5),
206                (Odonto, _) => (-8.0, 0.5),
207                (Sandraptor, _) => (-10.5, 0.5),
208                (Snowraptor, _) => (-10.5, 1.0),
209                (Woodraptor, _) => (-10.5, 0.5),
210                (Sunlizard, _) => (-10.0, -0.5),
211                (Yale, _) => (-5.0, -2.5),
212                (Dodarock, _) => (-8.5, -2.0),
213                (Ntouka, _) => (-9.5, -2.0),
214                (Axebeak, _) => (-10.0, 3.0),
215            },
216            hand: match (body.species, body.body_type) {
217                (Archaeos, _) => (3.0, 0.0, -4.0),
218                (Odonto, _) => (3.5, 3.0, -4.0),
219                (Sandraptor, _) => (2.5, 3.0, 1.0),
220                (Snowraptor, _) => (2.5, 3.0, 1.0),
221                (Woodraptor, _) => (2.5, 3.0, 1.0),
222                (Sunlizard, _) => (2.5, 1.5, -0.5),
223                (Yale, _) => (3.0, 2.0, -0.5),
224                (Dodarock, _) => (3.5, 3.0, -5.0),
225                (Ntouka, _) => (3.5, 3.0, -4.0),
226                (Axebeak, _) => (1.5, -10.5, 9.5),
227            },
228            leg: match (body.species, body.body_type) {
229                (Archaeos, _) => (2.5, -3.0, -4.0),
230                (Odonto, _) => (3.5, -2.5, -4.0),
231                (Sandraptor, _) => (1.5, -2.5, -3.0),
232                (Snowraptor, _) => (1.5, -2.5, -3.0),
233                (Woodraptor, _) => (1.5, -2.5, -3.0),
234                (Sunlizard, _) => (2.5, -2.5, -3.0),
235                (Yale, _) => (3.0, -3.5, -4.0),
236                (Dodarock, _) => (3.5, 1.5, -4.0),
237                (Ntouka, _) => (4.5, -5.5, -4.0),
238                (Axebeak, _) => (2.5, -0.5, 0.0),
239            },
240            foot: match (body.species, body.body_type) {
241                (Archaeos, _) => (3.0, -0.5, -7.0),
242                (Odonto, _) => (4.0, -6.5, -3.0),
243                (Sandraptor, _) => (2.0, 0.0, -3.0),
244                (Snowraptor, _) => (2.0, 0.0, -3.0),
245                (Woodraptor, _) => (2.0, 0.0, -3.0),
246                (Sunlizard, _) => (1.0, -0.5, -2.5),
247                (Yale, _) => (1.5, 1.0, -3.5),
248                (Dodarock, _) => (1.5, -1.0, -3.5),
249                (Ntouka, _) => (1.5, -1.0, -2.5),
250                (Axebeak, _) => (2.5, 2.5, -7.0),
251            },
252            scaler: match (body.species, body.body_type) {
253                (Archaeos, _) => 2.93,
254                (Odonto, _) => 2.93,
255                (Sandraptor, _) => 0.88,
256                (Snowraptor, _) => 0.85,
257                (Woodraptor, _) => 0.9,
258                (Sunlizard, _) => 1.1,
259                (Yale, _) => 1.26,
260                (Dodarock, _) => 1.1,
261                (Ntouka, _) => 2.93,
262                (Axebeak, _) => 1.1,
263            },
264            steady_wings: matches!((body.species, body.body_type), (Axebeak, _)),
265        }
266    }
267}
268
269pub fn mount_mat(
270    body: &Body,
271    computed_skeleton: &ComputedTheropodSkeleton,
272    skeleton: &TheropodSkeleton,
273) -> (Mat4<f32>, Quaternion<f32>) {
274    use comp::theropod::Species::*;
275
276    match (body.species, body.body_type) {
277        (Archaeos, _) => (computed_skeleton.neck, skeleton.neck.orientation),
278        (Odonto, _) => (computed_skeleton.head, skeleton.head.orientation),
279        (Yale | Dodarock, _) => (
280            computed_skeleton.chest_back,
281            skeleton.chest_back.orientation,
282        ),
283        _ => (
284            computed_skeleton.chest_front,
285            skeleton.chest_front.orientation,
286        ),
287    }
288}
289
290pub fn mount_transform(
291    body: &Body,
292    computed_skeleton: &ComputedTheropodSkeleton,
293    skeleton: &TheropodSkeleton,
294) -> Transform<f32, f32, f32> {
295    use comp::theropod::Species::*;
296
297    let mount_point = match (body.species, body.body_type) {
298        (Archaeos, _) => (0.0, 2.5, 6.0),
299        (Odonto, _) => (0.0, 10.0, 2.0),
300        (Sandraptor, _) => (0.0, -2.0, 5.0),
301        (Snowraptor, _) => (0.0, -2.0, 5.0),
302        (Woodraptor, _) => (0.0, -2.0, 5.0),
303        (Sunlizard, _) => (0.0, -2.0, 3.5),
304        (Yale, _) => (0.0, -2.5, 5.5),
305        (Ntouka, _) => (0.0, -4.0, 7.5),
306        (Dodarock, _) => (0.0, 3.5, 5.0),
307        (Axebeak, _) => (0.0, -3.5, 6.5),
308    }
309    .into();
310
311    let (mount_mat, orientation) = mount_mat(body, computed_skeleton, skeleton);
312    Transform {
313        position: mount_mat.mul_point(mount_point),
314        orientation,
315        scale: Vec3::one(),
316    }
317}