1pub mod combomelee;
2pub mod dash;
3pub mod idle;
4pub mod jump;
5pub mod run;
6
7pub 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 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}