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 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}