veloren_voxygen_anim/dragon/
mod.rs

1pub mod fly;
2pub mod idle;
3pub mod run;
4
5// Reexports
6pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation};
7
8use super::{FigureBoneData, Skeleton, vek::*};
9use common::comp;
10use core::convert::TryFrom;
11
12pub type Body = comp::dragon::Body;
13
14skeleton_impls!(struct DragonSkeleton ComputedDragonSkeleton {
15    + head_upper
16    + head_lower
17    + jaw
18    + chest_front
19    + chest_rear
20    + tail_front
21    + tail_rear
22    + wing_in_l
23    + wing_in_r
24    + wing_out_l
25    + wing_out_r
26    + foot_fl
27    + foot_fr
28    + foot_bl
29    + foot_br
30});
31
32impl Skeleton for DragonSkeleton {
33    type Attr = SkeletonAttr;
34    type Body = Body;
35    type ComputedSkeleton = ComputedDragonSkeleton;
36
37    const BONE_COUNT: usize = ComputedDragonSkeleton::BONE_COUNT;
38    #[cfg(feature = "use-dyn-lib")]
39    const COMPUTE_FN: &'static [u8] = b"dragon_compute_mats\0";
40
41    #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "dragon_compute_mats"))]
42
43    fn compute_matrices_inner(
44        &self,
45        base_mat: Mat4<f32>,
46        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
47        _body: Self::Body,
48    ) -> Self::ComputedSkeleton {
49        let base_mat = base_mat * Mat4::scaling_3d(1.0);
50        let chest_front_mat = base_mat * Mat4::<f32>::from(self.chest_front);
51        let chest_rear_mat = chest_front_mat * Mat4::<f32>::from(self.chest_rear);
52        let head_lower_mat = chest_front_mat * Mat4::<f32>::from(self.head_lower);
53        let wing_in_l_mat = chest_front_mat * Mat4::<f32>::from(self.wing_in_l);
54        let wing_in_r_mat = chest_front_mat * Mat4::<f32>::from(self.wing_in_r);
55        let tail_front_mat = chest_rear_mat * Mat4::<f32>::from(self.tail_front);
56        let head_upper_mat = head_lower_mat * Mat4::<f32>::from(self.head_upper);
57
58        let computed_skeleton = ComputedDragonSkeleton {
59            head_upper: head_upper_mat,
60            head_lower: head_lower_mat,
61            jaw: head_upper_mat * Mat4::<f32>::from(self.jaw),
62            chest_front: chest_front_mat,
63            chest_rear: chest_rear_mat,
64            tail_front: tail_front_mat,
65            tail_rear: tail_front_mat * Mat4::<f32>::from(self.tail_rear),
66            wing_in_l: wing_in_l_mat,
67            wing_in_r: wing_in_r_mat,
68            wing_out_l: wing_in_l_mat * Mat4::<f32>::from(self.wing_out_l),
69            wing_out_r: wing_in_r_mat * Mat4::<f32>::from(self.wing_out_r),
70            foot_fl: chest_front_mat * Mat4::<f32>::from(self.foot_fl),
71            foot_fr: chest_front_mat * Mat4::<f32>::from(self.foot_fr),
72            foot_bl: chest_rear_mat * Mat4::<f32>::from(self.foot_bl),
73            foot_br: chest_rear_mat * Mat4::<f32>::from(self.foot_br),
74        };
75
76        computed_skeleton.set_figure_bone_data(buf);
77        computed_skeleton
78    }
79}
80
81pub fn mount_mat(
82    computed_skeleton: &ComputedDragonSkeleton,
83    skeleton: &DragonSkeleton,
84) -> (Mat4<f32>, Quaternion<f32>) {
85    (
86        computed_skeleton.chest_front,
87        skeleton.chest_front.orientation,
88    )
89}
90
91pub fn mount_transform(
92    body: &Body,
93    computed_skeleton: &ComputedDragonSkeleton,
94    skeleton: &DragonSkeleton,
95) -> Transform<f32, f32, f32> {
96    use comp::dragon::Species::*;
97
98    let mount_point = match (body.species, body.body_type) {
99        (Reddragon, _) => (0.0, 0.5, 5.5),
100    }
101    .into();
102
103    let (mount_mat, orientation) = mount_mat(computed_skeleton, skeleton);
104    Transform {
105        position: mount_mat.mul_point(mount_point),
106        orientation,
107        scale: Vec3::one(),
108    }
109}
110
111pub struct SkeletonAttr {
112    head_upper: (f32, f32),
113    head_lower: (f32, f32),
114    jaw: (f32, f32),
115    chest_front: (f32, f32),
116    chest_rear: (f32, f32),
117    tail_front: (f32, f32),
118    tail_rear: (f32, f32),
119    wing_in: (f32, f32, f32),
120    wing_out: (f32, f32, f32),
121    feet_f: (f32, f32, f32),
122    feet_b: (f32, f32, f32),
123    height: f32,
124}
125
126impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
127    type Error = ();
128
129    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
130        match body {
131            comp::Body::Dragon(body) => Ok(SkeletonAttr::from(body)),
132            _ => Err(()),
133        }
134    }
135}
136
137impl Default for SkeletonAttr {
138    fn default() -> Self {
139        Self {
140            head_upper: (0.0, 0.0),
141            head_lower: (0.0, 0.0),
142            jaw: (0.0, 0.0),
143            chest_front: (0.0, 0.0),
144            chest_rear: (0.0, 0.0),
145            tail_front: (0.0, 0.0),
146            tail_rear: (0.0, 0.0),
147            wing_in: (0.0, 0.0, 0.0),
148            wing_out: (0.0, 0.0, 0.0),
149            feet_f: (0.0, 0.0, 0.0),
150            feet_b: (0.0, 0.0, 0.0),
151            height: (0.0),
152        }
153    }
154}
155
156impl<'a> From<&'a Body> for SkeletonAttr {
157    fn from(body: &'a Body) -> Self {
158        use comp::dragon::Species::*;
159        Self {
160            head_upper: match (body.species, body.body_type) {
161                (Reddragon, _) => (2.5, 4.5),
162            },
163            head_lower: match (body.species, body.body_type) {
164                (Reddragon, _) => (7.5, 3.5),
165            },
166            jaw: match (body.species, body.body_type) {
167                (Reddragon, _) => (6.5, -5.0),
168            },
169            chest_front: match (body.species, body.body_type) {
170                (Reddragon, _) => (0.0, 15.0),
171            },
172            chest_rear: match (body.species, body.body_type) {
173                (Reddragon, _) => (-6.5, 0.0),
174            },
175            tail_front: match (body.species, body.body_type) {
176                (Reddragon, _) => (-6.5, 1.5),
177            },
178            tail_rear: match (body.species, body.body_type) {
179                (Reddragon, _) => (-11.5, -1.0),
180            },
181            wing_in: match (body.species, body.body_type) {
182                (Reddragon, _) => (2.5, -16.5, 0.0),
183            },
184            wing_out: match (body.species, body.body_type) {
185                (Reddragon, _) => (23.0, 0.5, 4.0),
186            },
187            feet_f: match (body.species, body.body_type) {
188                (Reddragon, _) => (6.0, 1.0, -13.0),
189            },
190            feet_b: match (body.species, body.body_type) {
191                (Reddragon, _) => (6.0, -2.0, -10.5),
192            },
193            height: match (body.species, body.body_type) {
194                (Reddragon, _) => 1.0,
195            },
196        }
197    }
198}