1pub mod basic;
2pub mod boost;
3pub mod climb;
4pub mod collect;
5pub mod consume;
6pub mod crawl;
7pub mod dance;
8pub mod equip;
9pub mod glidewield;
10pub mod gliding;
11pub mod idle;
12pub mod jump;
13pub mod mount;
14pub mod multi;
15pub mod music;
16pub mod pet;
17pub mod roll;
18pub mod run;
19pub mod sit;
20pub mod sleep;
21pub mod sneak;
22pub mod sneakequip;
23pub mod sneakwield;
24pub mod staggered;
25pub mod stand;
26pub mod steer;
27pub mod stunned;
28pub mod swim;
29pub mod swimwield;
30pub mod talk;
31pub mod throw;
32pub mod wallrun;
33pub mod wield;
34
35pub use self::{
37 basic::{BasicAction, BasicActionDependency},
38 boost::BoostAnimation,
39 climb::ClimbAnimation,
40 collect::CollectAnimation,
41 consume::ConsumeAnimation,
42 crawl::CrawlAnimation,
43 dance::DanceAnimation,
44 equip::EquipAnimation,
45 glidewield::GlideWieldAnimation,
46 gliding::GlidingAnimation,
47 idle::IdleAnimation,
48 jump::JumpAnimation,
49 mount::MountAnimation,
50 multi::{MultiAction, MultiActionDependency},
51 music::MusicAnimation,
52 pet::PetAnimation,
53 roll::RollAnimation,
54 run::RunAnimation,
55 sit::SitAnimation,
56 sleep::SleepAnimation,
57 sneak::SneakAnimation,
58 sneakequip::SneakEquipAnimation,
59 sneakwield::SneakWieldAnimation,
60 staggered::StaggeredAnimation,
61 stand::StandAnimation,
62 steer::SteerAnimation,
63 stunned::StunnedAnimation,
64 swim::SwimAnimation,
65 swimwield::SwimWieldAnimation,
66 talk::TalkAnimation,
67 throw::ThrowAnimation,
68 wallrun::WallrunAnimation,
69 wield::WieldAnimation,
70};
71use super::{FigureBoneData, Skeleton, vek::*};
72use common::comp::{
73 self,
74 tool::{Hands, ToolKind},
75};
76use core::{convert::TryFrom, f32::consts::PI};
77
78pub type Body = comp::humanoid::Body;
79
80skeleton_impls!(struct CharacterSkeleton ComputedCharacterSkeleton {
81 + head
82 + chest
83 + belt
84 + back
85 + shorts
86 + hand_l
87 + hand_r
88 + foot_l
89 + foot_r
90 + shoulder_l
91 + shoulder_r
92 + glider
93 + main
94 + second
95 + lantern
96 + hold
97 torso
98 control
99 control_l
100 control_r
101 :: holding_lantern: bool,
103 back_carry_offset: f32,
105 main_weapon_trail: bool,
106 off_weapon_trail: bool,
107 glider_trails: bool,
109 squash: f32,
110});
111
112impl CharacterSkeleton {
113 pub fn new(holding_lantern: bool, back_carry_offset: f32, squash: f32) -> Self {
114 Self {
115 holding_lantern,
116 back_carry_offset,
117 squash,
118 ..Self::default()
119 }
120 }
121}
122
123impl Skeleton for CharacterSkeleton {
124 type Attr = SkeletonAttr;
125 type Body = Body;
126 type ComputedSkeleton = ComputedCharacterSkeleton;
127
128 const BONE_COUNT: usize = ComputedCharacterSkeleton::BONE_COUNT;
129 #[cfg(feature = "use-dyn-lib")]
130 const COMPUTE_FN: &'static [u8] = b"character_compute_mats\0";
131
132 #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "character_compute_mats"))]
133 fn compute_matrices_inner(
134 &self,
135 base_mat: Mat4<f32>,
136 buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
137 body: Self::Body,
138 ) -> Self::ComputedSkeleton {
139 let height_scale = body.height_scale();
140
141 let base_mat =
145 base_mat * Mat4::scaling_3d(Body::BASE_HEIGHT * body.scaler() * (1.0 / 25.0));
146
147 let transform_chest = |tr: Transform<f32, f32, f32>| Transform {
148 position: tr.position * Vec3::new(1.0, 1.0, self.squash * height_scale.powi(2))
149 + Vec3::new(0.0, (self.squash - 1.0).min(0.0) * 8.0, 0.0),
150 orientation: tr.orientation
151 * Quaternion::rotation_x((self.squash - 1.0).min(0.0) * 2.0),
152 scale: tr.scale * Lerp::lerp(1.0, height_scale, 0.25),
153 };
154 let transform_limb = |tr: Transform<f32, f32, f32>| Transform {
155 position: tr.position * Vec3::new(1.0, 1.0, self.squash)
156 + Vec3::new(0.0, (1.0 - self.squash).max(0.0) * 5.0, 0.0),
157 orientation: tr.orientation
158 * Quaternion::rotation_x((1.0 - self.squash).max(0.0) * 2.0),
159 ..tr
160 };
161 let transform_other = |stretch: f32, tr: Transform<f32, f32, f32>| Transform {
162 position: tr.position * Vec3::new(1.0, 1.0, height_scale.max(0.0).powf(stretch * 2.0)),
163 scale: tr.scale * Vec3::new(1.0, 1.0, height_scale.max(1.0).powf(stretch * 2.0)),
164 ..tr
165 };
166
167 let torso_mat = base_mat * Mat4::<f32>::from(self.torso);
168 let chest_mat = torso_mat * Mat4::<f32>::from(transform_chest(self.chest));
169 let head_mat = chest_mat * Mat4::<f32>::from(transform_limb(self.head));
170 let shorts_mat = chest_mat * Mat4::<f32>::from(transform_other(0.6, self.shorts));
171 let control_mat = chest_mat * Mat4::<f32>::from(self.control);
172 let control_l_mat = control_mat * Mat4::<f32>::from(self.control_l);
173 let control_r_mat = control_mat * Mat4::<f32>::from(self.control_r);
174 let hand_r_mat = control_r_mat * Mat4::<f32>::from(transform_limb(self.hand_r));
175
176 let hand_l_mat = Mat4::<f32>::from(transform_limb(self.hand_l));
177 let lantern_mat = if self.holding_lantern {
178 hand_r_mat
179 } else {
180 shorts_mat
181 } * Mat4::<f32>::from(self.lantern);
182 let main_mat = control_l_mat * Mat4::<f32>::from(self.main);
183 let second_mat = control_r_mat * Mat4::<f32>::from(self.second);
184 let glider_mat = chest_mat * Mat4::<f32>::from(self.glider);
185
186 let computed_skeleton = ComputedCharacterSkeleton {
187 head: head_mat,
188 chest: chest_mat,
189 belt: chest_mat * Mat4::<f32>::from(transform_other(1.1, self.belt)),
190 back: chest_mat * Mat4::<f32>::from(self.back),
191 shorts: shorts_mat,
192 hand_l: control_l_mat * hand_l_mat,
193 hand_r: hand_r_mat,
194 foot_l: torso_mat * Mat4::<f32>::from(self.foot_l),
195 foot_r: torso_mat * Mat4::<f32>::from(self.foot_r),
196 shoulder_l: chest_mat * Mat4::<f32>::from(self.shoulder_l),
197 shoulder_r: chest_mat * Mat4::<f32>::from(self.shoulder_r),
198 glider: glider_mat,
199 main: main_mat,
200 second: second_mat,
201 lantern: lantern_mat,
202 hold: control_mat * hand_l_mat * Mat4::<f32>::from(self.hold),
204 };
205
206 computed_skeleton.set_figure_bone_data(buf);
207 computed_skeleton
208 }
209}
210
211pub struct SkeletonAttr {
212 scaler: f32,
213 head_scale: f32,
214 head: (f32, f32),
215 chest: (f32, f32),
216 belt: (f32, f32),
217 back: (f32, f32),
218 shorts: (f32, f32),
219 hand: (f32, f32, f32),
220 foot: (f32, f32, f32),
221 shoulder: (f32, f32, f32),
222 lantern: (f32, f32, f32),
223 shl: (f32, f32, f32, f32, f32, f32),
224 shr: (f32, f32, f32, f32, f32, f32),
225 sc: (f32, f32, f32, f32, f32, f32),
226 hhl: (f32, f32, f32, f32, f32, f32),
227 hhr: (f32, f32, f32, f32, f32, f32),
228 hc: (f32, f32, f32, f32, f32, f32),
229 sthl: (f32, f32, f32, f32, f32, f32),
230 sthr: (f32, f32, f32, f32, f32, f32),
231 stc: (f32, f32, f32, f32, f32, f32),
232 ahl: (f32, f32, f32, f32, f32, f32),
233 ahr: (f32, f32, f32, f32, f32, f32),
234 ac: (f32, f32, f32, f32, f32, f32),
235 bhl: (f32, f32, f32, f32, f32, f32),
236 bhr: (f32, f32, f32, f32, f32, f32),
237 bc: (f32, f32, f32, f32, f32, f32),
238}
239
240impl Default for SkeletonAttr {
241 fn default() -> Self {
242 Self {
243 scaler: 0.0,
244 head_scale: 0.0,
245 head: (0.0, 0.0),
246 chest: (0.0, 0.0),
247 belt: (0.0, 0.0),
248 back: (0.0, 0.0),
249 shorts: (0.0, 0.0),
250 hand: (0.0, 0.0, 0.0),
251 foot: (0.0, 0.0, 0.0),
252 shoulder: (0.0, 0.0, 0.0),
253 lantern: (0.0, 0.0, 0.0),
254 shl: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
255 shr: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
256 sc: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
257 hhl: (0.0, 0.0, 10.0, 0.0, 0.0, 0.0),
258 hhr: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
259 hc: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
260 sthl: (0.0, 0.0, 10.0, 0.0, 0.0, 0.0),
261 sthr: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
262 stc: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
263 ahl: (0.0, 0.0, 10.0, 0.0, 0.0, 0.0),
264 ahr: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
265 ac: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
266 bhl: (0.0, 0.0, 10.0, 0.0, 0.0, 0.0),
267 bhr: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
268 bc: (0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
269 }
270 }
271}
272
273impl<'a> TryFrom<&'a comp::Body> for SkeletonAttr {
274 type Error = ();
275
276 fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
277 match body {
278 comp::Body::Humanoid(body) => Ok(SkeletonAttr::from(body)),
279 _ => Err(()),
280 }
281 }
282}
283
284impl<'a> From<&'a Body> for SkeletonAttr {
285 fn from(body: &'a Body) -> Self {
286 use comp::humanoid::{BodyType::*, Species::*};
287 Self {
288 scaler: body.scaler(),
289 head_scale: match (body.species, body.body_type) {
290 (Orc, Male) => 0.9,
291 (Orc, Female) => 0.9,
292 (Human, Male) => 0.9,
293 (Human, Female) => 0.9,
294 (Elf, Male) => 0.9,
295 (Elf, Female) => 0.9,
296 (Dwarf, Male) => 1.0,
297 (Dwarf, Female) => 1.0,
298 (Draugr, Male) => 0.9,
299 (Draugr, Female) => 0.9,
300 (Danari, Male) => 1.15,
301 (Danari, Female) => 1.15,
302 },
303 head: match (body.species, body.body_type) {
304 (Orc, Male) => (-2.0, 9.0),
305 (Orc, Female) => (-2.0, 9.5),
306 (Human, Male) => (-2.3, 9.5),
307 (Human, Female) => (-2.0, 9.5),
308 (Elf, Male) => (-2.5, 9.5),
309 (Elf, Female) => (-1.0, 9.5),
310 (Dwarf, Male) => (-2.0, 10.0),
311 (Dwarf, Female) => (-2.0, 9.5),
312 (Draugr, Male) => (-1.5, 8.5),
313 (Draugr, Female) => (-1.5, 9.5),
314 (Danari, Male) => (-1.5, 7.0),
315 (Danari, Female) => (-1.5, 7.0),
316 },
317 chest: (0.0, 8.0),
318 belt: (0.0, -2.0),
319 back: (-3.1, 7.25),
320 shorts: (0.0, -5.0),
321 hand: (7.0, -0.25, 0.5),
322 foot: (3.4, 0.5, 2.0),
323 shoulder: (5.0, 0.0, 5.0),
324 lantern: (5.0, 2.5, 5.5),
325 shl: (-0.75, -1.0, 0.5, 1.47, -0.2, 0.0),
326 shr: (0.75, -1.5, -2.5, 1.47, 0.3, 0.0),
327 sc: (-6.0, 6.0, 0.0, -0.5, 0.0, 0.0),
328 hhl: (0.1, 0.0, 11.0, 4.71, 0.0, PI),
329 hhr: (0.0, 0.0, 0.0, 4.71, 0.0, PI),
330 hc: (6.0, 7.0, 1.0, -0.3, -PI / 2.0, 3.64),
331 sthl: (0.0, 0.0, 6.0, 1.97, 0.0, 0.0),
332 sthr: (0.0, 0.0, 0.0, 1.27, 0.2, 0.0),
333 stc: (-5.0, 7.0, -2.0, -0.3, 0.15, 0.0),
334 ahl: (-0.5, -1.5, 5.25, 1.5, PI, 0.0),
335 ahr: (0.0, -2.0, 1.0, 1.5, 0.0, PI),
336 ac: (-8.5, 2.0, 0.5, 4.25, PI, 0.2),
337 bhl: (0.0, -4.0, 1.0, PI / 2.0, 0.0, 0.0),
338 bhr: (1.0, 2.0, -2.0, PI / 2.0, 0.0, 0.0),
339 bc: (-5.0, 9.0, 1.0, 0.0, 1.2, -0.6),
340 }
341 }
342}
343
344pub fn mount_mat(
345 computed_skeleton: &ComputedCharacterSkeleton,
346 skeleton: &CharacterSkeleton,
347) -> (Mat4<f32>, Quaternion<f32>) {
348 (
349 computed_skeleton.chest,
350 skeleton.torso.orientation * skeleton.chest.orientation * Quaternion::rotation_y(0.4),
351 )
352}
353
354pub fn mount_transform(
355 computed_skeleton: &ComputedCharacterSkeleton,
356 skeleton: &CharacterSkeleton,
357) -> Transform<f32, f32, f32> {
358 let (mount_mat, orientation) = mount_mat(computed_skeleton, skeleton);
359 Transform {
360 position: mount_mat.mul_point(Vec3::new(5.5, 0.0, 6.5)),
361 orientation,
362 scale: Vec3::one(),
363 }
364}
365
366impl CharacterSkeleton {
367 pub fn do_tools_on_back(
370 &mut self,
371 hands: (Option<Hands>, Option<Hands>),
372 active_tool_kind: Option<ToolKind>,
373 second_tool_kind: Option<ToolKind>,
374 ) {
375 match (hands, active_tool_kind, second_tool_kind) {
376 ((Some(Hands::Two), _), tool, _) | ((None, Some(Hands::Two)), _, tool) => match tool {
377 Some(ToolKind::Bow) => {
378 self.main.position = Vec3::new(0.0, -5.0 - self.back_carry_offset, 6.0);
379 self.main.orientation =
380 Quaternion::rotation_y(2.5) * Quaternion::rotation_z(PI / 2.0);
381 },
382 Some(ToolKind::Staff) | Some(ToolKind::Sceptre) => {
383 self.main.position = Vec3::new(2.0, -5.0 - self.back_carry_offset, -1.0);
384 self.main.orientation =
385 Quaternion::rotation_y(-0.5) * Quaternion::rotation_z(PI / 2.0);
386 },
387 Some(ToolKind::Shield) => {
388 self.main.position = Vec3::new(-2.0, -3.0 - self.back_carry_offset, 1.0);
389 self.main.orientation =
390 Quaternion::rotation_y(-0.75) * Quaternion::rotation_z(PI / 2.0);
391 },
392 _ => {
393 self.main.position = Vec3::new(-7.0, -5.0 - self.back_carry_offset, 15.0);
394 self.main.orientation =
395 Quaternion::rotation_y(2.5) * Quaternion::rotation_z(PI / 2.0);
396 },
397 },
398 ((_, _), _, _) => {},
399 }
400
401 match hands {
402 (Some(Hands::One), _) => match active_tool_kind {
403 Some(ToolKind::Dagger) => {
404 self.main.position = Vec3::new(5.0, 1.0 - self.back_carry_offset, 2.0);
405 self.main.orientation =
406 Quaternion::rotation_x(-1.35 * PI) * Quaternion::rotation_z(2.0 * PI);
407 },
408 Some(ToolKind::Axe) | Some(ToolKind::Hammer) | Some(ToolKind::Sword) => {
409 self.main.position = Vec3::new(-4.0, -4.5 - self.back_carry_offset, 10.0);
410 self.main.orientation =
411 Quaternion::rotation_y(2.5) * Quaternion::rotation_z(PI / 2.0);
412 },
413 Some(ToolKind::Shield) => {
414 self.main.position = Vec3::new(-2.0, -4.0 - self.back_carry_offset, 3.0);
415 self.main.orientation =
416 Quaternion::rotation_y(0.25 * PI) * Quaternion::rotation_z(-1.5 * PI);
417 },
418 Some(ToolKind::Throwable) => {
419 self.main.position = Vec3::new(-6.0, 0.0, -4.0);
420 self.main.scale = Vec3::zero();
421 },
422 _ => {},
423 },
424 (_, _) => {},
425 }
426 match hands {
427 (None | Some(Hands::One), Some(Hands::One)) => match second_tool_kind {
428 Some(ToolKind::Dagger) => {
429 self.second.position = Vec3::new(-5.0, 1.0 - self.back_carry_offset, 2.0);
430 self.second.orientation =
431 Quaternion::rotation_x(-1.35 * PI) * Quaternion::rotation_z(-2.0 * PI);
432 },
433 Some(ToolKind::Axe) | Some(ToolKind::Hammer) | Some(ToolKind::Sword) => {
434 self.second.position = Vec3::new(4.0, -5.0 - self.back_carry_offset, 10.0);
435 self.second.orientation =
436 Quaternion::rotation_y(-2.5) * Quaternion::rotation_z(-PI / 2.0);
437 },
438 Some(ToolKind::Shield) => {
439 self.second.position = Vec3::new(1.5, -4.0 - self.back_carry_offset, 3.0);
440 self.second.orientation =
441 Quaternion::rotation_y(-0.25 * PI) * Quaternion::rotation_z(1.5 * PI);
442 },
443 Some(ToolKind::Throwable) => {
444 self.second.position = Vec3::new(6.0, 0.0, -4.0);
445 self.second.scale = Vec3::zero();
446 },
447 _ => {},
448 },
449 (_, _) => {},
450 }
451 }
452
453 pub fn do_hold_lantern(
456 &mut self,
457 s_a: &SkeletonAttr,
458 anim_time: f32,
459 acc_vel: f32,
460 speednorm: f32,
461 impact: f32,
462 tilt: f32,
463 last_ori: Option<Vec3<f32>>,
464 look_dir: Option<Vec3<f32>>,
465 ) {
466 let align_with_cam = look_dir
467 .zip(last_ori)
468 .map_or(0.0, |(l, o)| (l.xy().dot(o.xy()) * 0.5 + 0.5).max(0.0));
469
470 let lab = 2.0 / s_a.scaler;
471
472 let shorte = ((1.0 / (0.8 + 0.2 * ((acc_vel * lab * 1.6).sin()).powi(2))).sqrt())
473 * ((acc_vel * lab * 1.6).sin());
474
475 self.lantern.scale = Vec3::one() * 0.65;
476
477 if self.holding_lantern {
478 let pitch =
479 look_dir.unwrap_or_default().z.clamp(-1.0, 1.0) * (align_with_cam * 5.0).min(1.0);
480 let yaw = look_dir.zip(last_ori).map_or(0.0, |(l, o)| {
481 l.xy().angle_between(o.xy()).min(1.0)
482 * l.xy().determine_side(Vec2::zero(), o.xy()).signum()
483 }) * (align_with_cam * 15.0).min(1.0);
484
485 let fast = (anim_time * 8.0).sin();
486 let fast2 = (anim_time * 6.0 + 8.0).sin();
487 let breathe = anim_time.sin();
488
489 self.hand_r.position = Vec3::new(
490 s_a.hand.0 + 0.5 - yaw * 3.0,
491 s_a.hand.1 + 3.0 - impact * 0.2 + yaw * 3.5 - breathe * 1.0,
492 s_a.hand.2 + 12.0 + impact * -0.1 + pitch * 1.5 + breathe * 0.5,
493 );
494 self.hand_r.orientation = Quaternion::rotation_z(yaw * 1.0)
495 * Quaternion::rotation_x(2.25 + pitch + breathe * 0.3)
496 * Quaternion::rotation_z(0.9);
497
498 self.control_r.position = Vec3::zero();
499 self.control_r.orientation = Quaternion::rotation_x(0.0)
500 * Quaternion::rotation_y(0.0)
501 * Quaternion::rotation_z(0.0);
502
503 self.shoulder_r.position.z += 3.0;
504 self.shoulder_r.orientation = Quaternion::rotation_z(yaw.min(0.0) * 1.0)
505 * Quaternion::rotation_x(2.25 + breathe * 0.1);
506
507 self.head.position.x += yaw;
508 self.head.position.y -= pitch.min(0.0) * 1.5 - yaw.abs();
509 self.head.orientation = self.head.orientation
510 * Quaternion::rotation_z(yaw)
511 * Quaternion::rotation_x(pitch * 0.6);
512
513 self.chest.orientation = self.chest.orientation * Quaternion::rotation_x(pitch * 0.3);
514
515 self.lantern.position = Vec3::new(-0.5, -0.5, -2.5);
516 self.lantern.orientation = self.hand_r.orientation.inverse()
517 * self.chest.orientation.inverse()
518 * Quaternion::rotation_x(
519 (fast + 0.5) * 0.1 * speednorm
520 + (tilt.abs() * 2.0).min(PI * 0.5) * (0.25 + speednorm)
521 + pitch
522 + breathe * 0.05,
523 )
524 * Quaternion::rotation_y(tilt * 1.0 * fast + tilt * 1.0 + fast2 * speednorm * 0.25)
525 * Quaternion::rotation_z(yaw)
526 * Quaternion::slerp(Default::default(), self.chest.orientation, 0.3);
527 } else {
528 self.lantern.position = Vec3::new(s_a.lantern.0, s_a.lantern.1, s_a.lantern.2);
529 self.lantern.orientation =
530 Quaternion::slerp(
531 Default::default(),
532 self.chest.orientation.inverse() * self.shorts.orientation.inverse(),
533 0.75,
534 ) * Quaternion::rotation_x(shorte * 0.0 * speednorm.powi(2) + 0.25)
535 * Quaternion::rotation_y(shorte * 0.2 * speednorm.powi(2) - 0.3);
536 }
537 }
538}
539
540pub fn hammer_start(next: &mut CharacterSkeleton, s_a: &SkeletonAttr) {
541 next.main.position = Vec3::new(0.0, 0.0, 0.0);
542 next.main.orientation = Quaternion::rotation_z(0.0);
543 next.hand_l.position = Vec3::new(s_a.hhl.0, s_a.hhl.1 + 3.0, s_a.hhl.2 - 1.0);
544 next.hand_l.orientation = Quaternion::rotation_x(s_a.hhl.3)
545 * Quaternion::rotation_y(s_a.hhl.4)
546 * Quaternion::rotation_z(s_a.hhl.5);
547 next.hand_r.position = Vec3::new(s_a.hhr.0, s_a.hhr.1 + 3.0, s_a.hhr.2 + 1.0);
548 next.hand_r.orientation = Quaternion::rotation_x(s_a.hhr.3)
549 * Quaternion::rotation_y(s_a.hhr.4)
550 * Quaternion::rotation_z(s_a.hhr.5);
551
552 next.control.position = Vec3::new(s_a.hc.0 - 1.0, s_a.hc.1, s_a.hc.2 - 3.0);
553 next.control.orientation = Quaternion::rotation_x(s_a.hc.3)
554 * Quaternion::rotation_y(s_a.hc.4)
555 * Quaternion::rotation_z(s_a.hc.5);
556}
557
558pub fn bow_start(next: &mut CharacterSkeleton, s_a: &SkeletonAttr) {
559 next.main.position = Vec3::new(0.0, 0.0, 0.0);
560 next.main.orientation = Quaternion::rotation_x(0.0);
561 next.hand_l.position = Vec3::new(s_a.bhl.0 - 1.0, s_a.bhl.1, s_a.bhl.2);
562 next.hand_l.orientation = Quaternion::rotation_x(s_a.bhl.3);
563 next.hand_r.position = Vec3::new(s_a.bhr.0, s_a.bhr.1, s_a.bhr.2);
564 next.hand_r.orientation = Quaternion::rotation_x(s_a.bhr.3);
565
566 next.hold.orientation = Quaternion::rotation_x(-PI / 2.0);
567 next.hold.scale = Vec3::one();
568
569 next.control.position = Vec3::new(s_a.bc.0, s_a.bc.1, s_a.bc.2);
570 next.control.orientation = Quaternion::rotation_y(s_a.bc.4) * Quaternion::rotation_z(s_a.bc.5);
571
572 next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
573}
574
575pub fn bow_draw(next: &mut CharacterSkeleton, move1: f32, look_dir_z: f32) {
576 next.control.position += Vec3::new(
577 7.0 + look_dir_z.abs() * -4.0,
578 2.0 + look_dir_z.abs() * -5.0,
579 8.0 + look_dir_z * 15.0,
580 ) * move1;
581 next.control.orientation.rotate_y(move1 * -1.25);
582 next.control
583 .orientation
584 .rotate_z((-0.2 + look_dir_z.abs() * 0.8) * move1);
585 next.control.orientation.rotate_x(look_dir_z * 1.6 * move1);
586
587 next.head.orientation = Quaternion::rotation_x(look_dir_z * 0.7 * move1);
588 next.chest.orientation = Quaternion::rotation_z(0.8 * move1);
589}
590
591pub fn twist_back(next: &mut CharacterSkeleton, move1: f32, c: f32, h: f32, b: f32, s: f32) {
592 next.chest.orientation.rotate_z(move1 * c);
593 next.head.orientation.rotate_z(move1 * -h);
594 next.belt.orientation.rotate_z(move1 * -b);
595 next.shorts.orientation.rotate_z(move1 * -s);
596}
597
598pub fn twist_forward(next: &mut CharacterSkeleton, move2: f32, c: f32, h: f32, b: f32, s: f32) {
599 next.chest.orientation.rotate_z(move2 * -c);
600 next.head.orientation.rotate_z(move2 * h);
601 next.belt.orientation.rotate_z(move2 * b);
602 next.shorts.orientation.rotate_z(move2 * s);
603}
604
605pub fn dual_wield_start(next: &mut CharacterSkeleton) {
606 next.main.position = Vec3::new(0.0, 0.0, 0.0);
607 next.main.orientation = Quaternion::rotation_z(0.0);
608 next.second.position = Vec3::new(0.0, 0.0, 0.0);
609 next.second.orientation = Quaternion::rotation_z(0.0);
610
611 next.control_l.position =
612 next.hand_l.position * Vec3::new(0.5, 0.5, 0.3) + Vec3::new(-4.0, 0.0, 0.0);
613 next.control_l.orientation = Quaternion::lerp(
614 next.hand_l.orientation,
615 Quaternion::rotation_x(PI * -0.5),
616 0.65,
617 );
618 next.hand_l.position = Vec3::new(0.0, -2.0, 0.0);
619 next.hand_l.orientation = Quaternion::rotation_x(PI * 0.5);
620
621 next.control_r.position =
622 next.hand_r.position * Vec3::new(0.5, 0.5, 0.3) + Vec3::new(4.0, 0.0, 0.0);
623 next.control_r.orientation = Quaternion::lerp(
624 next.hand_r.orientation,
625 Quaternion::rotation_x(PI * -0.5),
626 0.65,
627 );
628 next.hand_r.position = Vec3::new(0.0, -2.0, 0.0);
629 next.hand_r.orientation = Quaternion::rotation_x(PI * 0.5);
630}