diff --git a/assets/voxygen/voxel/quadruped_medium_central_manifest.ron b/assets/voxygen/voxel/quadruped_medium_central_manifest.ron index ad5263a0f1..3c50063065 100644 --- a/assets/voxygen/voxel/quadruped_medium_central_manifest.ron +++ b/assets/voxygen/voxel/quadruped_medium_central_manifest.ron @@ -481,7 +481,7 @@ ), (Mouflon, Male): ( head: ( - offset: (-7.0, 0.0, -4.5), + offset: (-7.0, -5.0, 0.0), central: ("npc.mouflon.male.head"), ), neck: ( @@ -511,7 +511,7 @@ ), (Mouflon, Female): ( head: ( - offset: (-7.0, 0.0, -4.5), + offset: (-7.0, -5.0, 0.0), central: ("npc.mouflon.male.head"), ), neck: ( diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index dfbd747cce..1b50424c2e 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -32,7 +32,7 @@ impl Body { match self { Body::Humanoid(_) => 100.0, Body::QuadrupedSmall(_) => 125.0, - Body::QuadrupedMedium(_) => 30.0, + Body::QuadrupedMedium(_) => 180.0, Body::BirdMedium(_) => 80.0, Body::FishMedium(_) => 50.0, Body::Dragon(_) => 250.0, diff --git a/voxygen/src/anim/src/quadruped_medium/feed.rs b/voxygen/src/anim/src/quadruped_medium/feed.rs new file mode 100644 index 0000000000..bef398b5fa --- /dev/null +++ b/voxygen/src/anim/src/quadruped_medium/feed.rs @@ -0,0 +1,205 @@ +use super::{ + super::{vek::*, Animation}, + QuadrupedMediumSkeleton, SkeletonAttr, +}; +use std::{f32::consts::PI, ops::Mul}; + +pub struct FeedAnimation; + +impl Animation for FeedAnimation { + type Dependency = f64; + type Skeleton = QuadrupedMediumSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"quadruped_medium_feed\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "quadruped_medium_feed")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + global_time: Self::Dependency, + anim_time: f64, + _rate: &mut f32, + skeleton_attr: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let slower = (anim_time as f32 * 1.0 + PI).sin(); + let slow = (anim_time as f32 * 3.5 + PI).sin(); + let fast = (anim_time as f32 * 5.0).sin(); + let faster = (anim_time as f32 * 14.0).sin(); + + let transition = (anim_time as f32).min(0.4) / 0.4; + + let look = Vec2::new( + ((global_time + anim_time) as f32 / 8.0) + .floor() + .mul(7331.0) + .sin() + * 0.5, + ((global_time + anim_time) as f32 / 8.0) + .floor() + .mul(1337.0) + .sin() + * 0.25, + ); + let tailmove = Vec2::new( + ((global_time + anim_time) as f32 / 2.0) + .floor() + .mul(7331.0) + .sin() + * 0.25, + ((global_time + anim_time) as f32 / 2.0) + .floor() + .mul(1337.0) + .sin() + * 0.125, + ); + + if skeleton_attr.feed.0 { + next.head.position = Vec3::new( + 0.0, + skeleton_attr.head.0, + skeleton_attr.head.1 + slower * 0.2, + ); + next.head.orientation = + Quaternion::rotation_z(0.3 * look.x) + * Quaternion::rotation_x(fast * 0.05 + faster * 0.08 + 0.8 * skeleton_attr.feed.1 * transition); + next.head.scale = Vec3::one(); + + next.neck.position = Vec3::new( + 0.0, + skeleton_attr.neck.0, + skeleton_attr.neck.1 + slower * 0.1 - 4.0 * transition, + ); + next.neck.orientation =Quaternion::rotation_x(-2.5 * skeleton_attr.feed.1 * transition); + next.neck.scale = Vec3::one() * 1.02; + + next.jaw.position = Vec3::new( + 0.0, + skeleton_attr.jaw.0 - slower * 0.12, + skeleton_attr.jaw.1 + slow * 0.2 + 0.5, + ); + next.jaw.orientation = Quaternion::rotation_x((fast * 0.18 + faster * 0.26).min(0.0)); + next.jaw.scale = Vec3::one() * 1.02; + } else { + next.head.position = Vec3::new( + 0.0, + skeleton_attr.head.0, + skeleton_attr.head.1 + slower * 0.2, + ); + next.head.orientation = + Quaternion::rotation_z(0.3 * look.x) * Quaternion::rotation_x(0.3 * look.y); + next.head.scale = Vec3::one(); + + next.neck.position = Vec3::new( + 0.0, + skeleton_attr.neck.0, + skeleton_attr.neck.1 + slower * 0.1, + ); + next.neck.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.neck.scale = Vec3::one() * 1.02; + + next.jaw.position = Vec3::new( + 0.0, + skeleton_attr.jaw.0 - slower * 0.12, + skeleton_attr.jaw.1 + slow * 0.2 + 0.5, + ); + next.jaw.orientation = Quaternion::rotation_x(slow * 0.05 - 0.08); + next.jaw.scale = Vec3::one() * 1.02; + } + + next.tail.position = Vec3::new(0.0, skeleton_attr.tail.0, skeleton_attr.tail.1); + next.tail.orientation = + Quaternion::rotation_z(0.0 + slow * 0.2 + tailmove.x) * Quaternion::rotation_x(0.0); + next.tail.scale = Vec3::one(); + + next.torso_front.position = Vec3::new( + 0.0, + skeleton_attr.torso_front.0, + skeleton_attr.torso_front.1 + slower * 0.3, + ) * skeleton_attr.scaler + / 11.0; + next.torso_front.orientation = Quaternion::rotation_y(slow * 0.02); + next.torso_front.scale = Vec3::one() * skeleton_attr.scaler / 11.0; + + next.torso_back.position = Vec3::new( + 0.0, + skeleton_attr.torso_back.0, + skeleton_attr.torso_back.1 + slower * 0.2, + ); + next.torso_back.orientation = Quaternion::rotation_y(-slow * 0.005) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_x(0.0); + next.torso_back.scale = Vec3::one() * 0.99; + + next.ears.position = Vec3::new(0.0, skeleton_attr.ears.0, skeleton_attr.ears.1); + next.ears.orientation = Quaternion::rotation_x(0.0 + slower * 0.03); + next.ears.scale = Vec3::one() * 1.02; + + next.leg_fl.position = Vec3::new( + -skeleton_attr.leg_f.0, + skeleton_attr.leg_f.1, + skeleton_attr.leg_f.2 + slow * -0.15 + slower * -0.15, + ); + next.leg_fl.orientation = Quaternion::rotation_y(slow * -0.02); + next.leg_fl.scale = Vec3::one() * 1.02; + + next.leg_fr.position = Vec3::new( + skeleton_attr.leg_f.0, + skeleton_attr.leg_f.1, + skeleton_attr.leg_f.2 + slow * 0.15 + slower * -0.15, + ); + next.leg_fr.orientation = Quaternion::rotation_y(slow * -0.02); + next.leg_fr.scale = Vec3::one() * 1.02; + + next.leg_bl.position = Vec3::new( + -skeleton_attr.leg_b.0, + skeleton_attr.leg_b.1, + skeleton_attr.leg_b.2 + slower * -0.3, + ); + next.leg_bl.orientation = Quaternion::rotation_y(slow * -0.02); + next.leg_bl.scale = Vec3::one() * 1.02; + + next.leg_br.position = Vec3::new( + skeleton_attr.leg_b.0, + skeleton_attr.leg_b.1, + skeleton_attr.leg_b.2 + slower * -0.3, + ); + next.leg_br.orientation = Quaternion::rotation_y(slow * -0.02); + next.leg_br.scale = Vec3::one() * 1.02; + + next.foot_fl.position = Vec3::new( + -skeleton_attr.feet_f.0, + skeleton_attr.feet_f.1, + skeleton_attr.feet_f.2 + slower * -0.2, + ); + next.foot_fl.orientation = Quaternion::rotation_x(0.0); + next.foot_fl.scale = Vec3::one() * 0.94; + + next.foot_fr.position = Vec3::new( + skeleton_attr.feet_f.0, + skeleton_attr.feet_f.1, + skeleton_attr.feet_f.2 + slower * -0.2, + ); + next.foot_fr.orientation = Quaternion::rotation_x(0.0); + next.foot_fr.scale = Vec3::one() * 0.94; + + next.foot_bl.position = Vec3::new( + -skeleton_attr.feet_b.0, + skeleton_attr.feet_b.1, + skeleton_attr.feet_b.2 + slower * -0.2, + ); + next.foot_bl.orientation = Quaternion::rotation_x(0.0); + next.foot_bl.scale = Vec3::one() * 0.94; + + next.foot_br.position = Vec3::new( + skeleton_attr.feet_b.0, + skeleton_attr.feet_b.1, + skeleton_attr.feet_b.2 + slower * -0.2, + ); + next.foot_br.orientation = Quaternion::rotation_x(0.0); + next.foot_br.scale = Vec3::one() * 0.94; + + next + } +} \ No newline at end of file diff --git a/voxygen/src/anim/src/quadruped_medium/idle.rs b/voxygen/src/anim/src/quadruped_medium/idle.rs index 3285ba2bcb..5da26b09e6 100644 --- a/voxygen/src/anim/src/quadruped_medium/idle.rs +++ b/voxygen/src/anim/src/quadruped_medium/idle.rs @@ -170,4 +170,4 @@ impl Animation for IdleAnimation { next } -} +} \ No newline at end of file diff --git a/voxygen/src/anim/src/quadruped_medium/mod.rs b/voxygen/src/anim/src/quadruped_medium/mod.rs index 1c843add78..0ed951dca2 100644 --- a/voxygen/src/anim/src/quadruped_medium/mod.rs +++ b/voxygen/src/anim/src/quadruped_medium/mod.rs @@ -1,11 +1,12 @@ pub mod alpha; +pub mod feed; pub mod idle; pub mod jump; pub mod run; // Reexports pub use self::{ - alpha::AlphaAnimation, idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation, + alpha::AlphaAnimation, feed::FeedAnimation, idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Skeleton}; @@ -92,6 +93,7 @@ pub struct SkeletonAttr { startangle: f32, tempo: f32, spring: f32, + feed: (bool, f32), } impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr { @@ -123,6 +125,7 @@ impl Default for SkeletonAttr { startangle: 0.0, tempo: 0.0, spring: 0.0, + feed: (false, 0.0), } } } @@ -140,7 +143,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Tiger, _) => (2.0, 1.0), (Wolf, _) => (-0.5, 3.0), (Frostfang, _) => (1.0, -2.0), - (Mouflon, _) => (-2.5, 6.0), + (Mouflon, _) => (0.5, 1.5), (Catoblepas, _) => (-1.0, -6.5), (Bonerattler, _) => (-1.0, 2.5), (Deer, Male) => (0.5, 3.5), @@ -156,7 +159,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Tiger, _) => (0.0, 0.0), (Wolf, _) => (-4.5, 2.0), (Frostfang, _) => (2.0, 1.5), - (Mouflon, _) => (-1.0, 0.5), + (Mouflon, _) => (-1.0, 1.0), (Catoblepas, _) => (19.5, -2.0), (Bonerattler, _) => (7.0, -1.5), (Deer, _) => (-0.5, 1.0), @@ -171,7 +174,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Tiger, _) => (3.5, -4.0), (Wolf, _) => (5.0, -3.0), (Frostfang, _) => (4.0, -3.0), - (Mouflon, _) => (10.5, -4.0), + (Mouflon, _) => (6.0, 0.5), (Catoblepas, _) => (1.0, -4.0), (Bonerattler, _) => (3.0, -3.0), (Deer, _) => (3.5, 2.0), @@ -358,6 +361,13 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Deer, _) => (0.9), (Hirdrassil, _) => (1.1), }, + feed: match (body.species, body.body_type) { + (Tuskram, _) => (true, 0.5), + (Mouflon, _) => (true, 1.0), + (Deer, _) => (true, 1.0), + (Hirdrassil, _) => (true, 0.9), + (_, _) => (false, 0.0), + }, } } -} +} \ No newline at end of file diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 5d95d14b07..7a6c93c8be 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -1268,6 +1268,15 @@ impl FigureMgr { skeleton_attr, ) }, + CharacterState::Sit { .. } => { + anim::quadruped_medium::FeedAnimation::update_skeleton( + &target_base, + time, + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, // TODO! _ => target_base, };