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