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