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    fn compute_matrices_inner(
43        &self,
44        base_mat: Mat4<f32>,
45        buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
46        _body: Self::Body,
47    ) -> Self::ComputedSkeleton {
48        let base_mat = base_mat * Mat4::scaling_3d(1.0);
49        let chest_front_mat = base_mat * Mat4::<f32>::from(self.chest_front);
50        let chest_rear_mat = chest_front_mat * Mat4::<f32>::from(self.chest_rear);
51        let head_lower_mat = chest_front_mat * Mat4::<f32>::from(self.head_lower);
52        let wing_in_l_mat = chest_front_mat * Mat4::<f32>::from(self.wing_in_l);
53        let wing_in_r_mat = chest_front_mat * Mat4::<f32>::from(self.wing_in_r);
54        let tail_front_mat = chest_rear_mat * Mat4::<f32>::from(self.tail_front);
55        let head_upper_mat = head_lower_mat * Mat4::<f32>::from(self.head_upper);
56
57        let computed_skeleton = ComputedDragonSkeleton {
58            head_upper: head_upper_mat,
59            head_lower: head_lower_mat,
60            jaw: head_upper_mat * Mat4::<f32>::from(self.jaw),
61            chest_front: chest_front_mat,
62            chest_rear: chest_rear_mat,
63            tail_front: tail_front_mat,
64            tail_rear: tail_front_mat * Mat4::<f32>::from(self.tail_rear),
65            wing_in_l: wing_in_l_mat,
66            wing_in_r: wing_in_r_mat,
67            wing_out_l: wing_in_l_mat * Mat4::<f32>::from(self.wing_out_l),
68            wing_out_r: wing_in_r_mat * Mat4::<f32>::from(self.wing_out_r),
69            foot_fl: chest_front_mat * Mat4::<f32>::from(self.foot_fl),
70            foot_fr: chest_front_mat * Mat4::<f32>::from(self.foot_fr),
71            foot_bl: chest_rear_mat * Mat4::<f32>::from(self.foot_bl),
72            foot_br: chest_rear_mat * Mat4::<f32>::from(self.foot_br),
73        };
74
75        computed_skeleton.set_figure_bone_data(buf);
76        computed_skeleton
77    }
78}
79
80pub fn mount_mat(
81    computed_skeleton: &ComputedDragonSkeleton,
82    skeleton: &DragonSkeleton,
83) -> (Mat4<f32>, Quaternion<f32>) {
84    (
85        computed_skeleton.chest_front,
86        skeleton.chest_front.orientation,
87    )
88}
89
90pub fn mount_transform(
91    body: &Body,
92    computed_skeleton: &ComputedDragonSkeleton,
93    skeleton: &DragonSkeleton,
94) -> Transform<f32, f32, f32> {
95    use comp::dragon::Species::*;
96
97    let mount_point = match (body.species, body.body_type) {
98        (Reddragon, _) => (0.0, 0.5, 5.5),
99    }
100    .into();
101
102    let (mount_mat, orientation) = mount_mat(computed_skeleton, skeleton);
103    Transform {
104        position: mount_mat.mul_point(mount_point),
105        orientation,
106        scale: Vec3::one(),
107    }
108}
109
110pub struct SkeletonAttr {
111    head_upper: (f32, f32),
112    head_lower: (f32, f32),
113    jaw: (f32, f32),
114    chest_front: (f32, f32),
115    chest_rear: (f32, f32),
116    tail_front: (f32, f32),
117    tail_rear: (f32, f32),
118    wing_in: (f32, f32, f32),
119    wing_out: (f32, f32, f32),
120    feet_f: (f32, f32, f32),
121    feet_b: (f32, f32, f32),
122    height: f32,
123}
124
125impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
126    type Error = ();
127
128    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
129        match body {
130            comp::Body::Dragon(body) => Ok(SkeletonAttr::from(body)),
131            _ => Err(()),
132        }
133    }
134}
135
136impl Default for SkeletonAttr {
137    fn default() -> Self {
138        Self {
139            head_upper: (0.0, 0.0),
140            head_lower: (0.0, 0.0),
141            jaw: (0.0, 0.0),
142            chest_front: (0.0, 0.0),
143            chest_rear: (0.0, 0.0),
144            tail_front: (0.0, 0.0),
145            tail_rear: (0.0, 0.0),
146            wing_in: (0.0, 0.0, 0.0),
147            wing_out: (0.0, 0.0, 0.0),
148            feet_f: (0.0, 0.0, 0.0),
149            feet_b: (0.0, 0.0, 0.0),
150            height: (0.0),
151        }
152    }
153}
154
155impl<'a> From<&'a Body> for SkeletonAttr {
156    fn from(body: &'a Body) -> Self {
157        use comp::dragon::Species::*;
158        Self {
159            head_upper: match (body.species, body.body_type) {
160                (Reddragon, _) => (2.5, 4.5),
161            },
162            head_lower: match (body.species, body.body_type) {
163                (Reddragon, _) => (7.5, 3.5),
164            },
165            jaw: match (body.species, body.body_type) {
166                (Reddragon, _) => (6.5, -5.0),
167            },
168            chest_front: match (body.species, body.body_type) {
169                (Reddragon, _) => (0.0, 15.0),
170            },
171            chest_rear: match (body.species, body.body_type) {
172                (Reddragon, _) => (-6.5, 0.0),
173            },
174            tail_front: match (body.species, body.body_type) {
175                (Reddragon, _) => (-6.5, 1.5),
176            },
177            tail_rear: match (body.species, body.body_type) {
178                (Reddragon, _) => (-11.5, -1.0),
179            },
180            wing_in: match (body.species, body.body_type) {
181                (Reddragon, _) => (2.5, -16.5, 0.0),
182            },
183            wing_out: match (body.species, body.body_type) {
184                (Reddragon, _) => (23.0, 0.5, 4.0),
185            },
186            feet_f: match (body.species, body.body_type) {
187                (Reddragon, _) => (6.0, 1.0, -13.0),
188            },
189            feet_b: match (body.species, body.body_type) {
190                (Reddragon, _) => (6.0, -2.0, -10.5),
191            },
192            height: match (body.species, body.body_type) {
193                (Reddragon, _) => 1.0,
194            },
195        }
196    }
197}