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