veloren_voxygen_anim/golem/
mod.rs

1pub mod alpha;
2pub mod beam;
3pub mod combomelee;
4pub mod idle;
5pub mod run;
6pub mod shockwave;
7pub mod shoot;
8
9// Reexports
10pub 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}