1pub mod basic;
2pub mod idle;
3pub mod jump;
4pub mod multi;
5pub mod run;
6pub mod stunned;
7
8pub 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 let mount_position = (mount_bone_mat * Vec4::from_point(mount_point(&body)))
109 .homogenized()
110 .xyz();
111 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 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 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}