veloren_voxygen_anim/arthropod/
mod.rs

1pub mod basic;
2pub mod idle;
3pub mod jump;
4pub mod multi;
5pub mod run;
6pub mod stunned;
7
8// Reexports
9pub use self::{
10    basic::{BasicAction, BasicActionDependency},
11    idle::IdleAnimation,
12    jump::JumpAnimation,
13    multi::{MultiAction, MultiActionDependency},
14    run::RunAnimation,
15    stunned::StunnedAnimation,
16};
17
18use super::{FigureBoneData, Offsets, Skeleton, make_bone, vek::*};
19use common::comp::{self};
20use core::convert::TryFrom;
21
22pub type Body = comp::arthropod::Body;
23
24skeleton_impls!(struct ArthropodSkeleton {
25    + head,
26    + chest,
27    + mandible_l,
28    + mandible_r,
29    + wing_fl,
30    + wing_fr,
31    + wing_bl,
32    + wing_br,
33    + leg_fl,
34    + leg_fr,
35    + leg_fcl,
36    + leg_fcr,
37    + leg_bcl,
38    + leg_bcr,
39    + leg_bl,
40    + leg_br,
41});
42
43impl Skeleton for ArthropodSkeleton {
44    type Attr = SkeletonAttr;
45    type Body = Body;
46
47    const BONE_COUNT: usize = 16;
48    #[cfg(feature = "use-dyn-lib")]
49    const COMPUTE_FN: &'static [u8] = b"arthropod_compute_s\0";
50
51    #[cfg_attr(feature = "be-dyn-lib", export_name = "arthropod_compute_s")]
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    ) -> Offsets {
59        let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 6.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 mandible_l_mat = head_mat * Mat4::<f32>::from(self.mandible_l);
64        let mandible_r_mat = head_mat * Mat4::<f32>::from(self.mandible_r);
65        let wing_fl_mat = chest_mat * Mat4::<f32>::from(self.wing_fl);
66        let wing_fr_mat = chest_mat * Mat4::<f32>::from(self.wing_fr);
67        let wing_bl_mat = chest_mat * Mat4::<f32>::from(self.wing_bl);
68        let wing_br_mat = chest_mat * Mat4::<f32>::from(self.wing_br);
69        let leg_fl_mat = chest_mat * Mat4::<f32>::from(self.leg_fl);
70        let leg_fr_mat = chest_mat * Mat4::<f32>::from(self.leg_fr);
71        let leg_fcl_mat = chest_mat * Mat4::<f32>::from(self.leg_fcl);
72        let leg_fcr_mat = chest_mat * Mat4::<f32>::from(self.leg_fcr);
73        let leg_bcl_mat = chest_mat * Mat4::<f32>::from(self.leg_bcl);
74        let leg_bcr_mat = chest_mat * Mat4::<f32>::from(self.leg_bcr);
75        let leg_bl_mat = chest_mat * Mat4::<f32>::from(self.leg_bl);
76        let leg_br_mat = chest_mat * Mat4::<f32>::from(self.leg_br);
77
78        *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
79            make_bone(head_mat),
80            make_bone(chest_mat),
81            make_bone(mandible_l_mat),
82            make_bone(mandible_r_mat),
83            make_bone(wing_fl_mat),
84            make_bone(wing_fr_mat),
85            make_bone(wing_bl_mat),
86            make_bone(wing_br_mat),
87            make_bone(leg_fl_mat),
88            make_bone(leg_fr_mat),
89            make_bone(leg_fcl_mat),
90            make_bone(leg_fcr_mat),
91            make_bone(leg_bcl_mat),
92            make_bone(leg_bcr_mat),
93            make_bone(leg_bl_mat),
94            make_bone(leg_br_mat),
95        ];
96
97        use comp::arthropod::Species::*;
98        let (mount_bone_mat, mount_bone_ori) = match (body.species, body.body_type) {
99            (
100                Hornbeetle | Leafbeetle | Stagbeetle | Weevil | Moltencrawler | Mosscrawler
101                | Sandcrawler | Dagonite,
102                _,
103            ) => (head_mat, self.head.orientation),
104            _ => (chest_mat, self.chest.orientation),
105        };
106        // Offset from the mounted bone's origin.
107        // Note: This could be its own bone if we need to animate it independently.
108        let mount_position = (mount_bone_mat * Vec4::from_point(mount_point(&body)))
109            .homogenized()
110            .xyz();
111        // NOTE: We apply the ori from base_mat externally so we don't need to worry
112        // about it here for now.
113        let mount_orientation = mount_bone_ori;
114
115        Offsets {
116            viewpoint: Some((head_mat * Vec4::new(0.0, 7.0, 0.0, 1.0)).xyz()),
117            mount_bone: Transform {
118                position: mount_position,
119                orientation: mount_orientation,
120                scale: Vec3::one(),
121            },
122            ..Default::default()
123        }
124    }
125}
126
127pub struct SkeletonAttr {
128    head: (f32, f32),
129    chest: (f32, f32),
130    mandible: (f32, f32, f32),
131    wing_f: (f32, f32, f32),
132    wing_b: (f32, f32, f32),
133    leg_f: (f32, f32, f32),
134    leg_fc: (f32, f32, f32),
135    leg_bc: (f32, f32, f32),
136    leg_b: (f32, f32, f32),
137    scaler: f32,
138    leg_ori: (f32, f32, f32, f32),
139    snapper: bool,
140}
141
142impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
143    type Error = ();
144
145    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
146        match body {
147            comp::Body::Arthropod(body) => Ok(SkeletonAttr::from(body)),
148            _ => Err(()),
149        }
150    }
151}
152
153impl Default for SkeletonAttr {
154    fn default() -> Self {
155        Self {
156            head: (0.0, 0.0),
157            chest: (0.0, 0.0),
158            mandible: (0.0, 0.0, 0.0),
159            wing_f: (0.0, 0.0, 0.0),
160            wing_b: (0.0, 0.0, 0.0),
161            leg_f: (0.0, 0.0, 0.0),
162            leg_fc: (0.0, 0.0, 0.0),
163            leg_bc: (0.0, 0.0, 0.0),
164            leg_b: (0.0, 0.0, 0.0),
165            scaler: 0.0,
166            leg_ori: (0.0, 0.0, 0.0, 0.0),
167            snapper: false,
168        }
169    }
170}
171
172impl<'a> From<&'a Body> for SkeletonAttr {
173    fn from(body: &'a Body) -> Self {
174        use comp::arthropod::Species::*;
175        Self {
176            head: match (body.species, body.body_type) {
177                (Tarantula, _) => (6.0, 0.5),
178                (Blackwidow, _) => (5.5, -3.0),
179                (Antlion, _) => (4.5, 0.0),
180                (Hornbeetle, _) => (5.0, 3.0),
181                (Leafbeetle, _) => (4.0, 0.0),
182                (Stagbeetle, _) => (5.0, -1.0),
183                (Weevil, _) => (4.0, 0.0),
184                (Cavespider, _) => (6.0, 0.5),
185                (Moltencrawler, _) => (4.0, -1.0),
186                (Mosscrawler, _) => (4.0, -1.5),
187                (Sandcrawler, _) => (4.0, -1.0),
188                (Dagonite, _) => (4.0, -1.0),
189                (Emberfly, _) => (-1.5, 0.5),
190            },
191            chest: match (body.species, body.body_type) {
192                (Tarantula, _) => (-5.0, 6.0),
193                (Blackwidow, _) => (-5.0, 10.0),
194                (Antlion, _) => (-5.0, 8.5),
195                (Hornbeetle, _) => (-5.0, 7.5),
196                (Leafbeetle, _) => (-5.0, 6.0),
197                (Stagbeetle, _) => (-5.0, 6.5),
198                (Weevil, _) => (-5.0, 6.0),
199                (Cavespider, _) => (-5.0, 7.0),
200                (Moltencrawler, _) => (-7.0, 6.0),
201                (Mosscrawler, _) => (-7.0, 6.5),
202                (Sandcrawler, _) => (-7.0, 6.0),
203                (Dagonite, _) => (-6.0, 8.0),
204                (Emberfly, _) => (-5.0, 2.5),
205            },
206            mandible: match (body.species, body.body_type) {
207                (Tarantula, _) => (1.5, 7.0, -0.5),
208                (Blackwidow, _) => (2.5, 8.0, 0.0),
209                (Antlion, _) => (8.5, 9.0, -3.5),
210                (Hornbeetle, _) => (1.5, 7.0, -0.5),
211                (Leafbeetle, _) => (1.5, 7.0, -0.5),
212                (Stagbeetle, _) => (1.5, 10.0, 1.0),
213                (Weevil, _) => (1.5, 7.0, -0.5),
214                (Cavespider, _) => (2.5, 8.0, -0.5),
215                (Moltencrawler, _) => (2.5, 8.0, 0.0),
216                (Mosscrawler, _) => (2.5, 8.0, 0.0),
217                (Sandcrawler, _) => (2.5, 8.0, 0.0),
218                (Dagonite, _) => (2.5, 8.0, 0.0),
219                (Emberfly, _) => (1.5, 7.0, -0.5),
220            },
221            wing_f: match (body.species, body.body_type) {
222                (Tarantula, _) => (3.0, 0.0, -4.0),
223                (Blackwidow, _) => (3.0, 0.0, -4.0),
224                (Antlion, _) => (3.0, 0.0, -4.0),
225                (Hornbeetle, _) => (5.5, 5.0, 3.0),
226                (Leafbeetle, _) => (0.5, 5.0, 3.0),
227                (Stagbeetle, _) => (0.5, 6.0, 4.5),
228                (Weevil, _) => (0.5, 5.0, 3.0),
229                (Cavespider, _) => (3.0, 0.0, -4.0),
230                (Moltencrawler, _) => (3.0, 0.0, -4.0),
231                (Mosscrawler, _) => (3.0, 0.0, -4.0),
232                (Sandcrawler, _) => (3.0, 0.0, -4.0),
233                (Dagonite, _) => (3.0, 0.0, -4.0),
234                (Emberfly, _) => (5.5, 6.0, 3.0),
235            },
236            wing_b: match (body.species, body.body_type) {
237                (Tarantula, _) => (3.0, 0.0, -4.0),
238                (Blackwidow, _) => (3.0, 0.0, -4.0),
239                (Antlion, _) => (3.0, 0.0, -4.0),
240                (Hornbeetle, _) => (4.0, 6.0, 2.0),
241                (Leafbeetle, _) => (0.5, 4.0, 2.0),
242                (Stagbeetle, _) => (0.5, 6.0, 3.0),
243                (Weevil, _) => (0.5, 4.0, 1.5),
244                (Cavespider, _) => (3.0, 0.0, -4.0),
245                (Moltencrawler, _) => (3.0, 0.0, -4.0),
246                (Mosscrawler, _) => (3.0, 0.0, -4.0),
247                (Sandcrawler, _) => (3.0, 0.0, -4.0),
248                (Dagonite, _) => (3.0, 0.0, -4.0),
249                (Emberfly, _) => (4.0, 6.0, 2.0),
250            },
251            leg_f: match (body.species, body.body_type) {
252                (Tarantula, _) => (4.0, 11.0, -1.5),
253                (Blackwidow, _) => (4.0, 13.5, -6.0),
254                (Antlion, _) => (4.0, 11.5, -4.0),
255                (Hornbeetle, _) => (5.0, 6.0, -3.0),
256                (Leafbeetle, _) => (5.0, 6.0, -1.0),
257                (Stagbeetle, _) => (4.5, 6.0, -2.0),
258                (Weevil, _) => (5.0, 9.0, -2.0),
259                (Cavespider, _) => (4.0, 13.0, -3.0),
260                (Moltencrawler, _) => (2.5, 14.0, -3.0),
261                (Mosscrawler, _) => (1.5, 14.0, -3.5),
262                (Sandcrawler, _) => (1.5, 14.0, -3.0),
263                (Dagonite, _) => (1.5, 14.0, -3.0),
264                (Emberfly, _) => (2.5, 6.0, -2.5),
265            },
266            leg_fc: match (body.species, body.body_type) {
267                (Tarantula, _) => (1.5, 13.5, -1.5),
268                (Blackwidow, _) => (2.5, 13.0, -5.5),
269                (Antlion, _) => (1.5, 6.0, -4.0),
270                (Hornbeetle, _) => (1.5, 7.5, -3.0),
271                (Leafbeetle, _) => (1.5, 6.5, -1.5),
272                (Stagbeetle, _) => (1.5, 7.5, -2.0),
273                (Weevil, _) => (1.5, 8.5, -2.0),
274                (Cavespider, _) => (2.5, 12.5, -2.5),
275                (Moltencrawler, _) => (3.5, 11.0, -3.0),
276                (Mosscrawler, _) => (2.5, 11.0, -3.5),
277                (Sandcrawler, _) => (2.5, 11.0, -3.0),
278                (Dagonite, _) => (2.5, 11.0, -3.0),
279                (Emberfly, _) => (1.5, 7.5, -2.5),
280            },
281            leg_bc: match (body.species, body.body_type) {
282                (Tarantula, _) => (1.5, 10.5, -1.5),
283                (Blackwidow, _) => (2.5, 10.0, -5.5),
284                (Antlion, _) => (6.0, 7.5, -4.0),
285                (Hornbeetle, _) => (5.0, 6.0, -3.0),
286                (Leafbeetle, _) => (4.5, 5.0, -2.5),
287                (Stagbeetle, _) => (5.0, 6.0, -2.0),
288                (Weevil, _) => (6.0, 5.0, -2.5),
289                (Cavespider, _) => (2.5, 9.5, -2.5),
290                (Moltencrawler, _) => (2.5, 8.0, -3.0),
291                (Mosscrawler, _) => (1.5, 8.0, -3.5),
292                (Sandcrawler, _) => (1.5, 8.0, -3.0),
293                (Dagonite, _) => (1.5, 8.0, -3.0),
294                (Emberfly, _) => (2.5, 3.5, -2.5),
295            },
296            leg_b: match (body.species, body.body_type) {
297                (Tarantula, _) => (1.5, 7.5, -1.5),
298                (Blackwidow, _) => (2.5, 7.0, -5.5),
299                (Antlion, _) => (1.5, 7.5, -1.5),
300                (Hornbeetle, _) => (1.5, 7.5, -1.5),
301                (Leafbeetle, _) => (1.5, 7.5, -1.5),
302                (Stagbeetle, _) => (1.5, 7.5, -1.5),
303                (Weevil, _) => (1.5, 7.5, -1.5),
304                (Cavespider, _) => (2.5, 6.5, -2.5),
305                (Moltencrawler, _) => (2.5, 7.0, -5.5),
306                (Mosscrawler, _) => (2.5, 7.0, -5.5),
307                (Sandcrawler, _) => (2.5, 7.0, -5.5),
308                (Dagonite, _) => (2.5, 7.0, -5.5),
309                (Emberfly, _) => (1.5, 7.5, -1.0),
310            },
311            scaler: match (body.species, body.body_type) {
312                (Tarantula, _) => 1.0,
313                (Blackwidow, _) => 1.0,
314                (Antlion, _) => 1.0,
315                (Hornbeetle, _) => 1.0,
316                (Leafbeetle, _) => 0.8,
317                (Stagbeetle, _) => 1.0,
318                (Weevil, _) => 0.75,
319                (Cavespider, _) => 1.0,
320                (Moltencrawler, _) => 1.0,
321                (Mosscrawler, _) => 1.0,
322                (Sandcrawler, _) => 1.0,
323                (Dagonite, _) => 1.0,
324                (Emberfly, _) => 0.5,
325            },
326            // Z ori (front, front center, back center, center)
327            leg_ori: match (body.species, body.body_type) {
328                (Antlion, _) => (0.7, -0.3, -0.4, 0.4),
329                (_, _) => (0.1, -0.3, 0.0, 0.4),
330            },
331            // Whether or not it used its mandibles for attacks
332            snapper: match (body.species, body.body_type) {
333                (Stagbeetle, _) => true,
334                (Antlion, _) => true,
335                (_, _) => false,
336            },
337        }
338    }
339}
340
341fn mount_point(body: &Body) -> Vec3<f32> {
342    use comp::arthropod::Species::*;
343    match (body.species, body.body_type) {
344        (Tarantula, _) => (0.0, 1.0, 4.0),
345        (Blackwidow, _) => (0.0, 0.0, 5.0),
346        (Antlion, _) => (0.0, 2.0, 3.5),
347        (Hornbeetle, _) => (0.0, 1.5, 1.5),
348        (Leafbeetle, _) => (0.0, 1.5, 3.0),
349        (Stagbeetle, _) => (0.0, 3.5, 3.5),
350        (Weevil, _) => (0.0, 1.5, 3.0),
351        (Cavespider, _) => (0.0, 1.0, 4.0),
352        (Moltencrawler, _) => (0.0, 5.5, 6.0),
353        (Mosscrawler, _) => (0.0, 6.5, 6.0),
354        (Sandcrawler, _) => (0.0, 6.5, 6.0),
355        (Dagonite, _) => (0.0, 8.5, 6.0),
356        (Emberfly, _) => (0.0, 3.0, 4.0),
357    }
358    .into()
359}