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, Offsets, Skeleton, make_bone, vek::*};
9use common::comp;
10use core::convert::TryFrom;
11
12pub type Body = comp::dragon::Body;
13
14skeleton_impls!(struct DragonSkeleton {
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
36    const BONE_COUNT: usize = 15;
37    #[cfg(feature = "use-dyn-lib")]
38    const COMPUTE_FN: &'static [u8] = b"dragon_compute_mats\0";
39
40    #[cfg_attr(feature = "be-dyn-lib", export_name = "dragon_compute_mats")]
41
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    ) -> Offsets {
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        *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
58            make_bone(head_upper_mat),
59            make_bone(head_lower_mat),
60            make_bone(head_upper_mat * Mat4::<f32>::from(self.jaw)),
61            make_bone(chest_front_mat),
62            make_bone(chest_rear_mat),
63            make_bone(tail_front_mat),
64            make_bone(tail_front_mat * Mat4::<f32>::from(self.tail_rear)),
65            make_bone(wing_in_l_mat),
66            make_bone(wing_in_r_mat),
67            make_bone(wing_in_l_mat * Mat4::<f32>::from(self.wing_out_l)),
68            make_bone(wing_in_r_mat * Mat4::<f32>::from(self.wing_out_r)),
69            make_bone(chest_front_mat * Mat4::<f32>::from(self.foot_fl)),
70            make_bone(chest_front_mat * Mat4::<f32>::from(self.foot_fr)),
71            make_bone(chest_rear_mat * Mat4::<f32>::from(self.foot_bl)),
72            make_bone(chest_rear_mat * Mat4::<f32>::from(self.foot_br)),
73        ];
74
75        let mount_position = chest_front_mat.mul_point(mount_point(&body));
76        let mount_orientation = self.chest_front.orientation;
77
78        Offsets {
79            viewpoint: Some((head_upper_mat * Vec4::new(0.0, 8.0, 0.0, 1.0)).xyz()),
80            // TODO: see quadruped_medium for how to animate this
81            mount_bone: Transform {
82                position: mount_position,
83                orientation: mount_orientation,
84                ..Default::default()
85            },
86            ..Default::default()
87        }
88    }
89}
90
91fn mount_point(body: &Body) -> Vec3<f32> {
92    use comp::dragon::Species::*;
93    match (body.species, body.body_type) {
94        (Reddragon, _) => (0.0, 0.5, 5.5),
95    }
96    .into()
97}
98
99pub struct SkeletonAttr {
100    head_upper: (f32, f32),
101    head_lower: (f32, f32),
102    jaw: (f32, f32),
103    chest_front: (f32, f32),
104    chest_rear: (f32, f32),
105    tail_front: (f32, f32),
106    tail_rear: (f32, f32),
107    wing_in: (f32, f32, f32),
108    wing_out: (f32, f32, f32),
109    feet_f: (f32, f32, f32),
110    feet_b: (f32, f32, f32),
111    height: f32,
112}
113
114impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
115    type Error = ();
116
117    fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
118        match body {
119            comp::Body::Dragon(body) => Ok(SkeletonAttr::from(body)),
120            _ => Err(()),
121        }
122    }
123}
124
125impl Default for SkeletonAttr {
126    fn default() -> Self {
127        Self {
128            head_upper: (0.0, 0.0),
129            head_lower: (0.0, 0.0),
130            jaw: (0.0, 0.0),
131            chest_front: (0.0, 0.0),
132            chest_rear: (0.0, 0.0),
133            tail_front: (0.0, 0.0),
134            tail_rear: (0.0, 0.0),
135            wing_in: (0.0, 0.0, 0.0),
136            wing_out: (0.0, 0.0, 0.0),
137            feet_f: (0.0, 0.0, 0.0),
138            feet_b: (0.0, 0.0, 0.0),
139            height: (0.0),
140        }
141    }
142}
143
144impl<'a> From<&'a Body> for SkeletonAttr {
145    fn from(body: &'a Body) -> Self {
146        use comp::dragon::Species::*;
147        Self {
148            head_upper: match (body.species, body.body_type) {
149                (Reddragon, _) => (2.5, 4.5),
150            },
151            head_lower: match (body.species, body.body_type) {
152                (Reddragon, _) => (7.5, 3.5),
153            },
154            jaw: match (body.species, body.body_type) {
155                (Reddragon, _) => (6.5, -5.0),
156            },
157            chest_front: match (body.species, body.body_type) {
158                (Reddragon, _) => (0.0, 15.0),
159            },
160            chest_rear: match (body.species, body.body_type) {
161                (Reddragon, _) => (-6.5, 0.0),
162            },
163            tail_front: match (body.species, body.body_type) {
164                (Reddragon, _) => (-6.5, 1.5),
165            },
166            tail_rear: match (body.species, body.body_type) {
167                (Reddragon, _) => (-11.5, -1.0),
168            },
169            wing_in: match (body.species, body.body_type) {
170                (Reddragon, _) => (2.5, -16.5, 0.0),
171            },
172            wing_out: match (body.species, body.body_type) {
173                (Reddragon, _) => (23.0, 0.5, 4.0),
174            },
175            feet_f: match (body.species, body.body_type) {
176                (Reddragon, _) => (6.0, 1.0, -13.0),
177            },
178            feet_b: match (body.species, body.body_type) {
179                (Reddragon, _) => (6.0, -2.0, -10.5),
180            },
181            height: match (body.species, body.body_type) {
182                (Reddragon, _) => 1.0,
183            },
184        }
185    }
186}