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, Offsets, Skeleton, make_bone, vek::*};
14use common::comp::{self};
15use core::convert::TryFrom;
16
17pub type Body = comp::theropod::Body;
18
19skeleton_impls!(struct TheropodSkeleton {
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
39    const BONE_COUNT: usize = 13;
40    #[cfg(feature = "use-dyn-lib")]
41    const COMPUTE_FN: &'static [u8] = b"theropod_compute_mats\0";
42
43    #[cfg_attr(feature = "be-dyn-lib", export_name = "theropod_compute_mats")]
44
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    ) -> Offsets {
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        *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
62            make_bone(head_mat),
63            make_bone(head_mat * Mat4::<f32>::from(self.jaw)),
64            make_bone(neck_mat),
65            make_bone(chest_front_mat),
66            make_bone(chest_back_mat),
67            make_bone(tail_front_mat),
68            make_bone(tail_front_mat * Mat4::<f32>::from(self.tail_back)),
69            make_bone(chest_front_mat * Mat4::<f32>::from(self.hand_l)),
70            make_bone(chest_front_mat * Mat4::<f32>::from(self.hand_r)),
71            make_bone(leg_l_mat),
72            make_bone(leg_r_mat),
73            make_bone(leg_l_mat * Mat4::<f32>::from(self.foot_l)),
74            make_bone(leg_r_mat * Mat4::<f32>::from(self.foot_r)),
75        ];
76
77        let (mount_mat, mount_orientation) = match (body.species, body.body_type) {
78            (comp::body::theropod::Species::Archaeos, _) => (neck_mat, self.neck.orientation),
79            (comp::body::theropod::Species::Odonto, _) => (head_mat, self.head.orientation),
80            (comp::body::theropod::Species::Yale | comp::body::theropod::Species::Dodarock, _) => {
81                (chest_back_mat, self.chest_back.orientation)
82            },
83            _ => (chest_front_mat, self.chest_front.orientation),
84        };
85
86        let mount_position = mount_mat.mul_point(mount_point(&body));
87
88        Offsets {
89            viewpoint: Some((head_mat * Vec4::new(0.0, 2.0, 0.0, 1.0)).xyz()),
90            // TODO: see quadruped_medium for how to animate this
91            mount_bone: Transform {
92                position: mount_position,
93                orientation: mount_orientation,
94                ..Default::default()
95            },
96            ..Default::default()
97        }
98    }
99}
100
101pub struct SkeletonAttr {
102    head: (f32, f32),
103    neck: (f32, f32),
104    jaw: (f32, f32),
105    chest_front: (f32, f32),
106    chest_back: (f32, f32),
107    tail_front: (f32, f32),
108    tail_back: (f32, f32),
109    hand: (f32, f32, f32),
110    leg: (f32, f32, f32),
111    foot: (f32, f32, f32),
112    scaler: f32,
113    steady_wings: bool,
114}
115
116impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
117    type Error = ();
118
119    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
120        match body {
121            comp::Body::Theropod(body) => Ok(SkeletonAttr::from(body)),
122            _ => Err(()),
123        }
124    }
125}
126
127impl Default for SkeletonAttr {
128    fn default() -> Self {
129        Self {
130            head: (0.0, 0.0),
131            neck: (0.0, 0.0),
132            jaw: (0.0, 0.0),
133            chest_front: (0.0, 0.0),
134            chest_back: (0.0, 0.0),
135            tail_front: (0.0, 0.0),
136            tail_back: (0.0, 0.0),
137            hand: (0.0, 0.0, 0.0),
138            leg: (0.0, 0.0, 0.0),
139            foot: (0.0, 0.0, 0.0),
140            scaler: 0.0,
141            steady_wings: false,
142        }
143    }
144}
145
146impl<'a> From<&'a Body> for SkeletonAttr {
147    fn from(body: &'a Body) -> Self {
148        use comp::theropod::Species::*;
149        Self {
150            head: match (body.species, body.body_type) {
151                (Archaeos, _) => (8.0, 4.0),
152                (Odonto, _) => (2.0, 2.0),
153                (Sandraptor, _) => (8.0, 5.0),
154                (Snowraptor, _) => (8.0, 5.0),
155                (Woodraptor, _) => (8.0, 5.0),
156                (Sunlizard, _) => (6.5, 3.5),
157                (Yale, _) => (7.0, 14.0),
158                (Dodarock, _) => (2.0, 1.5),
159                (Ntouka, _) => (2.0, 2.5),
160                (Axebeak, _) => (11.5, 8.5),
161            },
162            jaw: match (body.species, body.body_type) {
163                (Archaeos, _) => (1.0, -7.0),
164                (Odonto, _) => (2.0, -7.0),
165                (Sandraptor, _) => (0.0, -4.0),
166                (Snowraptor, _) => (0.0, -4.0),
167                (Woodraptor, _) => (0.0, -4.0),
168                (Sunlizard, _) => (2.0, -2.5),
169                (Yale, _) => (2.0, -9.5),
170                (Dodarock, _) => (0.0, -5.0),
171                (Ntouka, _) => (0.0, -4.0),
172                (Axebeak, _) => (2.5, -4.0),
173            },
174            neck: match (body.species, body.body_type) {
175                (Archaeos, _) => (4.5, -2.0),
176                (Odonto, _) => (4.0, 0.0),
177                (Sandraptor, _) => (4.0, 2.5),
178                (Snowraptor, _) => (4.0, 2.5),
179                (Woodraptor, _) => (4.0, 2.5),
180                (Sunlizard, _) => (2.5, 1.5),
181                (Yale, _) => (2.0, 4.0),
182                (Dodarock, _) => (5.0, -1.0),
183                (Ntouka, _) => (4.0, 0.0),
184                (Axebeak, _) => (-5.5, 0.0),
185            },
186            chest_front: match (body.species, body.body_type) {
187                (Archaeos, _) => (0.0, 20.0),
188                (Odonto, _) => (0.0, 13.0),
189                (Sandraptor, _) => (0.0, 15.5),
190                (Snowraptor, _) => (0.0, 15.5),
191                (Woodraptor, _) => (0.0, 15.5),
192                (Sunlizard, _) => (0.0, 14.0),
193                (Yale, _) => (0.0, 19.5),
194                (Dodarock, _) => (0.0, 12.0),
195                (Ntouka, _) => (0.0, 13.0),
196                (Axebeak, _) => (0.0, 12.0),
197            },
198            chest_back: match (body.species, body.body_type) {
199                (Archaeos, _) => (-5.5, -1.0),
200                (Odonto, _) => (-5.0, 2.0),
201                (Sandraptor, _) => (-3.0, 0.5),
202                (Snowraptor, _) => (-3.0, 0.5),
203                (Woodraptor, _) => (-3.0, 0.5),
204                (Sunlizard, _) => (-2.0, 0.0),
205                (Yale, _) => (-3.0, -1.0),
206                (Dodarock, _) => (-4.5, -2.0),
207                (Ntouka, _) => (-4.5, 1.0),
208                (Axebeak, _) => (-5.0, 0.0),
209            },
210            tail_front: match (body.species, body.body_type) {
211                (Archaeos, _) => (-9.0, -1.5),
212                (Odonto, _) => (-7.0, -1.0),
213                (Sandraptor, _) => (-9.5, -1.0),
214                (Snowraptor, _) => (-9.5, -1.0),
215                (Woodraptor, _) => (-9.5, -1.0),
216                (Sunlizard, _) => (-8.5, -2.0),
217                (Yale, _) => (-9.5, -4.0),
218                (Dodarock, _) => (-4.5, -4.5),
219                (Ntouka, _) => (-9.5, -3.5),
220                (Axebeak, _) => (-5.5, 4.5),
221            },
222            tail_back: match (body.species, body.body_type) {
223                (Archaeos, _) => (-8.0, -0.5),
224                (Odonto, _) => (-8.0, 0.5),
225                (Sandraptor, _) => (-10.5, 0.5),
226                (Snowraptor, _) => (-10.5, 1.0),
227                (Woodraptor, _) => (-10.5, 0.5),
228                (Sunlizard, _) => (-10.0, -0.5),
229                (Yale, _) => (-5.0, -2.5),
230                (Dodarock, _) => (-8.5, -2.0),
231                (Ntouka, _) => (-9.5, -2.0),
232                (Axebeak, _) => (-10.0, 3.0),
233            },
234            hand: match (body.species, body.body_type) {
235                (Archaeos, _) => (3.0, 0.0, -4.0),
236                (Odonto, _) => (3.5, 3.0, -4.0),
237                (Sandraptor, _) => (2.5, 3.0, 1.0),
238                (Snowraptor, _) => (2.5, 3.0, 1.0),
239                (Woodraptor, _) => (2.5, 3.0, 1.0),
240                (Sunlizard, _) => (2.5, 1.5, -0.5),
241                (Yale, _) => (3.0, 2.0, -0.5),
242                (Dodarock, _) => (3.5, 3.0, -5.0),
243                (Ntouka, _) => (3.5, 3.0, -4.0),
244                (Axebeak, _) => (1.5, -10.5, 9.5),
245            },
246            leg: match (body.species, body.body_type) {
247                (Archaeos, _) => (2.5, -3.0, -4.0),
248                (Odonto, _) => (3.5, -2.5, -4.0),
249                (Sandraptor, _) => (1.5, -2.5, -3.0),
250                (Snowraptor, _) => (1.5, -2.5, -3.0),
251                (Woodraptor, _) => (1.5, -2.5, -3.0),
252                (Sunlizard, _) => (2.5, -2.5, -3.0),
253                (Yale, _) => (3.0, -3.5, -4.0),
254                (Dodarock, _) => (3.5, 1.5, -4.0),
255                (Ntouka, _) => (4.5, -5.5, -4.0),
256                (Axebeak, _) => (2.5, -0.5, 0.0),
257            },
258            foot: match (body.species, body.body_type) {
259                (Archaeos, _) => (3.0, -0.5, -7.0),
260                (Odonto, _) => (4.0, -6.5, -3.0),
261                (Sandraptor, _) => (2.0, 0.0, -3.0),
262                (Snowraptor, _) => (2.0, 0.0, -3.0),
263                (Woodraptor, _) => (2.0, 0.0, -3.0),
264                (Sunlizard, _) => (1.0, -0.5, -2.5),
265                (Yale, _) => (1.5, 1.0, -3.5),
266                (Dodarock, _) => (1.5, -1.0, -3.5),
267                (Ntouka, _) => (1.5, -1.0, -2.5),
268                (Axebeak, _) => (2.5, 2.5, -7.0),
269            },
270            scaler: match (body.species, body.body_type) {
271                (Archaeos, _) => 2.93,
272                (Odonto, _) => 2.93,
273                (Sandraptor, _) => 0.88,
274                (Snowraptor, _) => 0.85,
275                (Woodraptor, _) => 0.9,
276                (Sunlizard, _) => 1.1,
277                (Yale, _) => 1.26,
278                (Dodarock, _) => 1.1,
279                (Ntouka, _) => 2.93,
280                (Axebeak, _) => 1.1,
281            },
282            steady_wings: matches!((body.species, body.body_type), (Axebeak, _)),
283        }
284    }
285}
286
287fn mount_point(body: &Body) -> Vec3<f32> {
288    use comp::theropod::Species::*;
289    match (body.species, body.body_type) {
290        (Archaeos, _) => (0.0, 2.5, 6.0),
291        (Odonto, _) => (0.0, 10.0, 2.0),
292        (Sandraptor, _) => (0.0, -2.0, 5.0),
293        (Snowraptor, _) => (0.0, -2.0, 5.0),
294        (Woodraptor, _) => (0.0, -2.0, 5.0),
295        (Sunlizard, _) => (0.0, -2.0, 3.5),
296        (Yale, _) => (0.0, -2.5, 5.5),
297        (Ntouka, _) => (0.0, -4.0, 7.5),
298        (Dodarock, _) => (0.0, 3.5, 5.0),
299        (Axebeak, _) => (0.0, -3.5, 6.5),
300    }
301    .into()
302}