1pub mod fly;
2pub mod idle;
3pub mod run;
4
5pub 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 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}