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, Skeleton, vek::*};
19use common::comp::{self};
20use core::convert::TryFrom;
21
22pub type Body = comp::arthropod::Body;
23
24skeleton_impls!(struct ArthropodSkeleton ComputedArthropodSkeleton {
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 type ComputedSkeleton = ComputedArthropodSkeleton;
47
48 const BONE_COUNT: usize = ComputedArthropodSkeleton::BONE_COUNT;
49 #[cfg(feature = "use-dyn-lib")]
50 const COMPUTE_FN: &'static [u8] = b"arthropod_compute_s\0";
51
52 #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "arthropod_compute_s"))]
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 ) -> Self::ComputedSkeleton {
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 let computed_skeleton = ComputedArthropodSkeleton {
79 head: head_mat,
80 chest: chest_mat,
81 mandible_l: mandible_l_mat,
82 mandible_r: mandible_r_mat,
83 wing_fl: wing_fl_mat,
84 wing_fr: wing_fr_mat,
85 wing_bl: wing_bl_mat,
86 wing_br: wing_br_mat,
87 leg_fl: leg_fl_mat,
88 leg_fr: leg_fr_mat,
89 leg_fcl: leg_fcl_mat,
90 leg_fcr: leg_fcr_mat,
91 leg_bcl: leg_bcl_mat,
92 leg_bcr: leg_bcr_mat,
93 leg_bl: leg_bl_mat,
94 leg_br: leg_br_mat,
95 };
96
97 computed_skeleton.set_figure_bone_data(buf);
98 computed_skeleton
99 }
100}
101
102pub struct SkeletonAttr {
103 head: (f32, f32),
104 chest: (f32, f32),
105 mandible: (f32, f32, f32),
106 wing_f: (f32, f32, f32),
107 wing_b: (f32, f32, f32),
108 leg_f: (f32, f32, f32),
109 leg_fc: (f32, f32, f32),
110 leg_bc: (f32, f32, f32),
111 leg_b: (f32, f32, f32),
112 scaler: f32,
113 leg_ori: (f32, f32, f32, f32),
114 snapper: bool,
115}
116
117impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
118 type Error = ();
119
120 fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
121 match body {
122 comp::Body::Arthropod(body) => Ok(SkeletonAttr::from(body)),
123 _ => Err(()),
124 }
125 }
126}
127
128impl Default for SkeletonAttr {
129 fn default() -> Self {
130 Self {
131 head: (0.0, 0.0),
132 chest: (0.0, 0.0),
133 mandible: (0.0, 0.0, 0.0),
134 wing_f: (0.0, 0.0, 0.0),
135 wing_b: (0.0, 0.0, 0.0),
136 leg_f: (0.0, 0.0, 0.0),
137 leg_fc: (0.0, 0.0, 0.0),
138 leg_bc: (0.0, 0.0, 0.0),
139 leg_b: (0.0, 0.0, 0.0),
140 scaler: 0.0,
141 leg_ori: (0.0, 0.0, 0.0, 0.0),
142 snapper: false,
143 }
144 }
145}
146
147impl<'a> From<&'a Body> for SkeletonAttr {
148 fn from(body: &'a Body) -> Self {
149 use comp::arthropod::Species::*;
150 Self {
151 head: match (body.species, body.body_type) {
152 (Tarantula, _) => (6.0, 0.5),
153 (Blackwidow, _) => (5.5, -3.0),
154 (Antlion, _) => (4.5, 0.0),
155 (Hornbeetle, _) => (5.0, 3.0),
156 (Leafbeetle, _) => (4.0, 0.0),
157 (Stagbeetle, _) => (5.0, -1.0),
158 (Weevil, _) => (4.0, 0.0),
159 (Cavespider, _) => (6.0, 0.5),
160 (Moltencrawler, _) => (4.0, -1.0),
161 (Mosscrawler, _) => (4.0, -1.5),
162 (Sandcrawler, _) => (4.0, -1.0),
163 (Dagonite, _) => (4.0, -1.0),
164 (Emberfly, _) => (-1.5, 0.5),
165 },
166 chest: match (body.species, body.body_type) {
167 (Tarantula, _) => (-5.0, 6.0),
168 (Blackwidow, _) => (-5.0, 10.0),
169 (Antlion, _) => (-5.0, 8.5),
170 (Hornbeetle, _) => (-5.0, 7.5),
171 (Leafbeetle, _) => (-5.0, 6.0),
172 (Stagbeetle, _) => (-5.0, 6.5),
173 (Weevil, _) => (-5.0, 6.0),
174 (Cavespider, _) => (-5.0, 7.0),
175 (Moltencrawler, _) => (-7.0, 6.0),
176 (Mosscrawler, _) => (-7.0, 6.5),
177 (Sandcrawler, _) => (-7.0, 6.0),
178 (Dagonite, _) => (-6.0, 8.0),
179 (Emberfly, _) => (-5.0, 2.5),
180 },
181 mandible: match (body.species, body.body_type) {
182 (Tarantula, _) => (1.5, 7.0, -0.5),
183 (Blackwidow, _) => (2.5, 8.0, 0.0),
184 (Antlion, _) => (8.5, 9.0, -3.5),
185 (Hornbeetle, _) => (1.5, 7.0, -0.5),
186 (Leafbeetle, _) => (1.5, 7.0, -0.5),
187 (Stagbeetle, _) => (1.5, 10.0, 1.0),
188 (Weevil, _) => (1.5, 7.0, -0.5),
189 (Cavespider, _) => (2.5, 8.0, -0.5),
190 (Moltencrawler, _) => (2.5, 8.0, 0.0),
191 (Mosscrawler, _) => (2.5, 8.0, 0.0),
192 (Sandcrawler, _) => (2.5, 8.0, 0.0),
193 (Dagonite, _) => (2.5, 8.0, 0.0),
194 (Emberfly, _) => (1.5, 7.0, -0.5),
195 },
196 wing_f: match (body.species, body.body_type) {
197 (Tarantula, _) => (3.0, 0.0, -4.0),
198 (Blackwidow, _) => (3.0, 0.0, -4.0),
199 (Antlion, _) => (3.0, 0.0, -4.0),
200 (Hornbeetle, _) => (5.5, 5.0, 3.0),
201 (Leafbeetle, _) => (0.5, 5.0, 3.0),
202 (Stagbeetle, _) => (0.5, 6.0, 4.5),
203 (Weevil, _) => (0.5, 5.0, 3.0),
204 (Cavespider, _) => (3.0, 0.0, -4.0),
205 (Moltencrawler, _) => (3.0, 0.0, -4.0),
206 (Mosscrawler, _) => (3.0, 0.0, -4.0),
207 (Sandcrawler, _) => (3.0, 0.0, -4.0),
208 (Dagonite, _) => (3.0, 0.0, -4.0),
209 (Emberfly, _) => (5.5, 6.0, 3.0),
210 },
211 wing_b: match (body.species, body.body_type) {
212 (Tarantula, _) => (3.0, 0.0, -4.0),
213 (Blackwidow, _) => (3.0, 0.0, -4.0),
214 (Antlion, _) => (3.0, 0.0, -4.0),
215 (Hornbeetle, _) => (4.0, 6.0, 2.0),
216 (Leafbeetle, _) => (0.5, 4.0, 2.0),
217 (Stagbeetle, _) => (0.5, 6.0, 3.0),
218 (Weevil, _) => (0.5, 4.0, 1.5),
219 (Cavespider, _) => (3.0, 0.0, -4.0),
220 (Moltencrawler, _) => (3.0, 0.0, -4.0),
221 (Mosscrawler, _) => (3.0, 0.0, -4.0),
222 (Sandcrawler, _) => (3.0, 0.0, -4.0),
223 (Dagonite, _) => (3.0, 0.0, -4.0),
224 (Emberfly, _) => (4.0, 6.0, 2.0),
225 },
226 leg_f: match (body.species, body.body_type) {
227 (Tarantula, _) => (4.0, 11.0, -1.5),
228 (Blackwidow, _) => (4.0, 13.5, -6.0),
229 (Antlion, _) => (4.0, 11.5, -4.0),
230 (Hornbeetle, _) => (5.0, 6.0, -3.0),
231 (Leafbeetle, _) => (5.0, 6.0, -1.0),
232 (Stagbeetle, _) => (4.5, 6.0, -2.0),
233 (Weevil, _) => (5.0, 9.0, -2.0),
234 (Cavespider, _) => (4.0, 13.0, -3.0),
235 (Moltencrawler, _) => (2.5, 14.0, -3.0),
236 (Mosscrawler, _) => (1.5, 14.0, -3.5),
237 (Sandcrawler, _) => (1.5, 14.0, -3.0),
238 (Dagonite, _) => (1.5, 14.0, -3.0),
239 (Emberfly, _) => (2.5, 6.0, -2.5),
240 },
241 leg_fc: match (body.species, body.body_type) {
242 (Tarantula, _) => (1.5, 13.5, -1.5),
243 (Blackwidow, _) => (2.5, 13.0, -5.5),
244 (Antlion, _) => (1.5, 6.0, -4.0),
245 (Hornbeetle, _) => (1.5, 7.5, -3.0),
246 (Leafbeetle, _) => (1.5, 6.5, -1.5),
247 (Stagbeetle, _) => (1.5, 7.5, -2.0),
248 (Weevil, _) => (1.5, 8.5, -2.0),
249 (Cavespider, _) => (2.5, 12.5, -2.5),
250 (Moltencrawler, _) => (3.5, 11.0, -3.0),
251 (Mosscrawler, _) => (2.5, 11.0, -3.5),
252 (Sandcrawler, _) => (2.5, 11.0, -3.0),
253 (Dagonite, _) => (2.5, 11.0, -3.0),
254 (Emberfly, _) => (1.5, 7.5, -2.5),
255 },
256 leg_bc: match (body.species, body.body_type) {
257 (Tarantula, _) => (1.5, 10.5, -1.5),
258 (Blackwidow, _) => (2.5, 10.0, -5.5),
259 (Antlion, _) => (6.0, 7.5, -4.0),
260 (Hornbeetle, _) => (5.0, 6.0, -3.0),
261 (Leafbeetle, _) => (4.5, 5.0, -2.5),
262 (Stagbeetle, _) => (5.0, 6.0, -2.0),
263 (Weevil, _) => (6.0, 5.0, -2.5),
264 (Cavespider, _) => (2.5, 9.5, -2.5),
265 (Moltencrawler, _) => (2.5, 8.0, -3.0),
266 (Mosscrawler, _) => (1.5, 8.0, -3.5),
267 (Sandcrawler, _) => (1.5, 8.0, -3.0),
268 (Dagonite, _) => (1.5, 8.0, -3.0),
269 (Emberfly, _) => (2.5, 3.5, -2.5),
270 },
271 leg_b: match (body.species, body.body_type) {
272 (Tarantula, _) => (1.5, 7.5, -1.5),
273 (Blackwidow, _) => (2.5, 7.0, -5.5),
274 (Antlion, _) => (1.5, 7.5, -1.5),
275 (Hornbeetle, _) => (1.5, 7.5, -1.5),
276 (Leafbeetle, _) => (1.5, 7.5, -1.5),
277 (Stagbeetle, _) => (1.5, 7.5, -1.5),
278 (Weevil, _) => (1.5, 7.5, -1.5),
279 (Cavespider, _) => (2.5, 6.5, -2.5),
280 (Moltencrawler, _) => (2.5, 7.0, -5.5),
281 (Mosscrawler, _) => (2.5, 7.0, -5.5),
282 (Sandcrawler, _) => (2.5, 7.0, -5.5),
283 (Dagonite, _) => (2.5, 7.0, -5.5),
284 (Emberfly, _) => (1.5, 7.5, -1.0),
285 },
286 scaler: match (body.species, body.body_type) {
287 (Tarantula, _) => 1.0,
288 (Blackwidow, _) => 1.0,
289 (Antlion, _) => 1.0,
290 (Hornbeetle, _) => 1.0,
291 (Leafbeetle, _) => 0.8,
292 (Stagbeetle, _) => 1.0,
293 (Weevil, _) => 0.75,
294 (Cavespider, _) => 1.0,
295 (Moltencrawler, _) => 1.0,
296 (Mosscrawler, _) => 1.0,
297 (Sandcrawler, _) => 1.0,
298 (Dagonite, _) => 1.0,
299 (Emberfly, _) => 0.5,
300 },
301 leg_ori: match (body.species, body.body_type) {
303 (Antlion, _) => (0.7, -0.3, -0.4, 0.4),
304 (_, _) => (0.1, -0.3, 0.0, 0.4),
305 },
306 snapper: match (body.species, body.body_type) {
308 (Stagbeetle, _) => true,
309 (Antlion, _) => true,
310 (_, _) => false,
311 },
312 }
313 }
314}
315
316pub fn mount_mat(
317 body: &Body,
318 computed_skeleton: &ComputedArthropodSkeleton,
319 skeleton: &ArthropodSkeleton,
320) -> (Mat4<f32>, Quaternion<f32>) {
321 use comp::arthropod::Species::*;
322
323 match (body.species, body.body_type) {
324 (
325 Hornbeetle | Leafbeetle | Stagbeetle | Weevil | Moltencrawler | Mosscrawler
326 | Sandcrawler | Dagonite,
327 _,
328 ) => (computed_skeleton.head, skeleton.head.orientation),
329 _ => (computed_skeleton.chest, skeleton.chest.orientation),
330 }
331}
332
333pub fn mount_transform(
334 body: &Body,
335 computed_skeleton: &ComputedArthropodSkeleton,
336 skeleton: &ArthropodSkeleton,
337) -> Transform<f32, f32, f32> {
338 use comp::arthropod::Species::*;
339
340 let mount_point = match (body.species, body.body_type) {
341 (Tarantula, _) => (0.0, 1.0, 4.0),
342 (Blackwidow, _) => (0.0, 0.0, 5.0),
343 (Antlion, _) => (0.0, 2.0, 3.5),
344 (Hornbeetle, _) => (0.0, 1.5, 1.5),
345 (Leafbeetle, _) => (0.0, 1.5, 3.0),
346 (Stagbeetle, _) => (0.0, 3.5, 3.5),
347 (Weevil, _) => (0.0, 1.5, 3.0),
348 (Cavespider, _) => (0.0, 1.0, 4.0),
349 (Moltencrawler, _) => (0.0, 5.5, 6.0),
350 (Mosscrawler, _) => (0.0, 6.5, 6.0),
351 (Sandcrawler, _) => (0.0, 6.5, 6.0),
352 (Dagonite, _) => (0.0, 8.5, 6.0),
353 (Emberfly, _) => (0.0, 3.0, 4.0),
354 }
355 .into();
356
357 let (mount_mat, orientation) = mount_mat(body, computed_skeleton, skeleton);
358 Transform {
359 position: mount_mat.mul_point(mount_point),
360 orientation,
361 scale: Vec3::one(),
362 }
363}