1pub mod alpha;
2pub mod beam;
3pub mod combomelee;
4pub mod idle;
5pub mod run;
6pub mod shockwave;
7pub mod shoot;
8
9pub use self::{
11 alpha::AlphaAnimation, beam::BeamAnimation, combomelee::ComboAnimation, idle::IdleAnimation,
12 run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
13};
14
15use super::{FigureBoneData, Offsets, Skeleton, make_bone, vek::*};
16use common::comp::{self};
17use core::convert::TryFrom;
18
19pub type Body = comp::golem::Body;
20
21skeleton_impls!(struct GolemSkeleton {
22 + head,
23 + jaw,
24 + upper_torso,
25 + lower_torso,
26 + shoulder_l,
27 + shoulder_r,
28 + hand_l,
29 + hand_r,
30 + leg_l,
31 + leg_r,
32 + foot_l,
33 + foot_r,
34 torso,
35});
36
37impl Skeleton for GolemSkeleton {
38 type Attr = SkeletonAttr;
39 type Body = Body;
40
41 const BONE_COUNT: usize = 12;
42 #[cfg(feature = "use-dyn-lib")]
43 const COMPUTE_FN: &'static [u8] = b"golem_compute_mats\0";
44
45 #[cfg_attr(feature = "be-dyn-lib", export_name = "golem_compute_mats")]
46 fn compute_matrices_inner(
47 &self,
48 base_mat: Mat4<f32>,
49 buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
50 body: Self::Body,
51 ) -> Offsets {
52 let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 8.0);
53
54 let torso_mat = base_mat * Mat4::<f32>::from(self.torso);
55 let upper_torso_mat = torso_mat * Mat4::<f32>::from(self.upper_torso);
56 let lower_torso_mat = upper_torso_mat * Mat4::<f32>::from(self.lower_torso);
57 let leg_l_mat = lower_torso_mat * Mat4::<f32>::from(self.leg_l);
58 let leg_r_mat = lower_torso_mat * Mat4::<f32>::from(self.leg_r);
59 let shoulder_l_mat = upper_torso_mat * Mat4::<f32>::from(self.shoulder_l);
60 let shoulder_r_mat = upper_torso_mat * Mat4::<f32>::from(self.shoulder_r);
61 let head_mat = upper_torso_mat * Mat4::<f32>::from(self.head);
62
63 *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
64 make_bone(head_mat),
65 make_bone(upper_torso_mat * Mat4::<f32>::from(self.head) * Mat4::<f32>::from(self.jaw)),
66 make_bone(upper_torso_mat),
67 make_bone(lower_torso_mat),
68 make_bone(upper_torso_mat * Mat4::<f32>::from(self.shoulder_l)),
69 make_bone(upper_torso_mat * Mat4::<f32>::from(self.shoulder_r)),
70 make_bone(shoulder_l_mat * Mat4::<f32>::from(self.hand_l)),
71 make_bone(shoulder_r_mat * Mat4::<f32>::from(self.hand_r)),
72 make_bone(leg_l_mat),
73 make_bone(leg_r_mat),
74 make_bone(leg_l_mat * Mat4::<f32>::from(self.foot_l)),
75 make_bone(leg_r_mat * Mat4::<f32>::from(self.foot_r)),
76 ];
77
78 let (mount_mat, mount_orientation) = (
79 head_mat,
80 self.torso.orientation * self.upper_torso.orientation * self.head.orientation,
81 );
82 let mount_position = mount_mat.mul_point(mount_point(&body));
83
84 Offsets {
85 viewpoint: Some((head_mat * Vec4::new(0.0, 0.0, 5.0, 1.0)).xyz()),
86 mount_bone: Transform {
88 position: mount_position,
89 orientation: mount_orientation,
90 scale: Vec3::one(),
91 },
92 ..Default::default()
93 }
94 }
95}
96
97pub struct SkeletonAttr {
98 head: (f32, f32),
99 jaw: (f32, f32),
100 upper_torso: (f32, f32),
101 lower_torso: (f32, f32),
102 shoulder: (f32, f32, f32),
103 hand: (f32, f32, f32),
104 leg: (f32, f32, f32),
105 foot: (f32, f32, f32),
106 scaler: f32,
107 tempo: f32,
108}
109
110impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
111 type Error = ();
112
113 fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
114 match body {
115 comp::Body::Golem(body) => Ok(SkeletonAttr::from(body)),
116 _ => Err(()),
117 }
118 }
119}
120
121impl Default for SkeletonAttr {
122 fn default() -> Self {
123 Self {
124 head: (0.0, 0.0),
125 jaw: (0.0, 0.0),
126 upper_torso: (0.0, 0.0),
127 lower_torso: (0.0, 0.0),
128 shoulder: (0.0, 0.0, 0.0),
129 hand: (0.0, 0.0, 0.0),
130 leg: (0.0, 0.0, 0.0),
131 foot: (0.0, 0.0, 0.0),
132 scaler: 0.0,
133 tempo: 0.0,
134 }
135 }
136}
137
138impl<'a> From<&'a Body> for SkeletonAttr {
139 fn from(body: &'a Body) -> Self {
140 use comp::golem::Species::*;
141 Self {
142 head: match (body.species, body.body_type) {
143 (StoneGolem, _) => (0.0, 2.0),
144 (Treant, _) => (18.0, -8.0),
145 (ClayGolem, _) => (0.0, 7.0),
146 (WoodGolem, _) => (3.0, 6.0),
147 (CoralGolem, _) => (-1.0, 3.0),
148 (Gravewarden, _) => (-2.0, 7.0),
149 (AncientEffigy, _) => (-2.0, 8.0),
150 (Mogwai, _) => (-8.0, 2.0),
151 (IronGolem, _) => (0.0, 3.0),
152 },
153 jaw: match (body.species, body.body_type) {
154 (StoneGolem, _) => (0.0, 0.0),
155 (Treant, _) => (-6.5, -1.0),
156 (ClayGolem, _) => (0.0, 0.0),
157 (WoodGolem, _) => (0.0, 0.0),
158 (CoralGolem, _) => (0.0, 0.0),
159 (Gravewarden, _) => (0.0, 0.0),
160 (AncientEffigy, _) => (0.0, 0.0),
161 (Mogwai, _) => (-6.0, -5.0),
162 (IronGolem, _) => (0.0, 0.0),
163 },
164 upper_torso: match (body.species, body.body_type) {
165 (StoneGolem, _) => (0.0, 34.5),
166 (Treant, _) => (0.0, 28.5),
167 (ClayGolem, _) => (0.0, 23.0),
168 (WoodGolem, _) => (0.0, 24.5),
169 (CoralGolem, _) => (0.0, 25.0),
170 (Gravewarden, _) => (0.0, 26.5),
171 (AncientEffigy, _) => (0.0, 18.0),
172 (Mogwai, _) => (0.0, 18.0),
173 (IronGolem, _) => (0.0, 34.5),
174 },
175 lower_torso: match (body.species, body.body_type) {
176 (StoneGolem, _) => (0.0, -10.5),
177 (Treant, _) => (0.0, -10.5),
178 (ClayGolem, _) => (0.0, -7.5),
179 (WoodGolem, _) => (0.0, -4.5),
180 (CoralGolem, _) => (0.0, -11.5),
181 (Gravewarden, _) => (0.0, -4.5),
182 (AncientEffigy, _) => (0.0, -4.5),
183 (Mogwai, _) => (0.0, -4.5),
184 (IronGolem, _) => (0.0, -10.5),
185 },
186 shoulder: match (body.species, body.body_type) {
187 (StoneGolem, _) => (8.0, -1.5, 4.0),
188 (Treant, _) => (8.0, 4.5, -3.0),
189 (ClayGolem, _) => (8.0, -1.0, -1.0),
190 (WoodGolem, _) => (6.0, 2.0, 1.0),
191 (CoralGolem, _) => (11.0, 1.0, 0.0),
192 (Gravewarden, _) => (8.0, 2.0, 3.0),
193 (AncientEffigy, _) => (8.0, 2.0, 3.0),
194 (Mogwai, _) => (8.0, 2.0, 3.0),
195 (IronGolem, _) => (8.0, -1.5, 0.0),
196 },
197 hand: match (body.species, body.body_type) {
198 (StoneGolem, _) => (12.5, -1.0, -7.0),
199 (Treant, _) => (8.5, -1.0, -7.0),
200 (ClayGolem, _) => (6.5, 0.0, -2.0),
201 (WoodGolem, _) => (5.5, -1.0, -6.0),
202 (CoralGolem, _) => (2.5, -1.5, -5.0),
203 (Gravewarden, _) => (8.5, -1.0, -7.0),
204 (AncientEffigy, _) => (8.5, -1.0, -7.0),
205 (Mogwai, _) => (8.5, -1.0, -7.0),
206 (IronGolem, _) => (12.5, -1.0, -7.0),
207 },
208 leg: match (body.species, body.body_type) {
209 (StoneGolem, _) => (4.0, 0.0, -3.5),
210 (Treant, _) => (2.0, 9.5, -1.0),
211 (ClayGolem, _) => (1.0, 0.0, -3.0),
212 (WoodGolem, _) => (2.0, 0.5, -6.0),
213 (CoralGolem, _) => (2.5, 0.5, -3.0),
214 (Gravewarden, _) => (1.0, 0.5, -6.0),
215 (AncientEffigy, _) => (1.0, 0.5, -6.0),
216 (Mogwai, _) => (1.0, 0.5, -6.0),
217 (IronGolem, _) => (1.5, 1.5, -3.5),
218 },
219 foot: match (body.species, body.body_type) {
220 (StoneGolem, _) => (3.5, 0.5, -9.5),
221 (Treant, _) => (3.5, -5.0, -8.5),
222 (ClayGolem, _) => (3.5, 0.0, -5.5),
223 (WoodGolem, _) => (2.5, 1.0, -5.5),
224 (CoralGolem, _) => (2.5, 1.0, -1.5),
225 (Gravewarden, _) => (3.5, -1.0, -8.5),
226 (AncientEffigy, _) => (3.5, -1.0, -8.5),
227 (Mogwai, _) => (3.5, -1.0, -8.5),
228 (IronGolem, _) => (3.5, 0.5, -9.5),
229 },
230 scaler: match (body.species, body.body_type) {
231 (StoneGolem, _) => 1.5,
232 (Treant, _) => 1.5,
233 (ClayGolem, _) => 1.5,
234 (WoodGolem, _) => 1.5,
235 (CoralGolem, _) => 1.0,
236 (Gravewarden, _) => 1.5,
237 (AncientEffigy, _) => 1.0,
238 (Mogwai, _) => 1.0,
239 (IronGolem, _) => 1.5,
240 },
241 tempo: match (body.species, body.body_type) {
242 (StoneGolem, _) => 1.0,
243 (Treant, _) => 1.0,
244 (ClayGolem, _) => 1.0,
245 (WoodGolem, _) => 1.0,
246 (CoralGolem, _) => 1.0,
247 (Gravewarden, _) => 1.0,
248 (AncientEffigy, _) => 1.0,
249 (Mogwai, _) => 1.0,
250 (IronGolem, _) => 1.0,
251 },
252 }
253 }
254}
255
256fn mount_point(body: &Body) -> Vec3<f32> {
257 use comp::golem::Species::*;
258 match (body.species, body.body_type) {
259 (StoneGolem, _) => (0.0, 0.5, 10.0),
260 (Treant, _) => (0.0, 0.0, 14.0),
261 (ClayGolem, _) => (0.0, 0.0, 12.0),
262 (WoodGolem, _) => (0.0, 0.0, 8.0),
263 (CoralGolem, _) => (0.0, 0.0, 5.0),
264 (Gravewarden, _) => (0.0, -0.5, 7.0),
265 (AncientEffigy, _) => (0.0, -0.5, 4.0),
266 (Mogwai, _) => (0.0, 11.0, 10.5),
267 (IronGolem, _) => (0.0, 0.0, 17.0),
268 }
269 .into()
270}