diff --git a/common/src/comp/animation.rs b/common/src/comp/animation.rs index ee4fc69da4..001d292059 100644 --- a/common/src/comp/animation.rs +++ b/common/src/comp/animation.rs @@ -4,7 +4,9 @@ use specs_idvs::IDVStorage; #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum Animation { Idle, + Stand, Run, + Lean, Jump, Gliding, Attack, diff --git a/common/src/sys/animation.rs b/common/src/sys/animation.rs index fde92932c3..3bc916fc5c 100644 --- a/common/src/sys/animation.rs +++ b/common/src/sys/animation.rs @@ -33,8 +33,10 @@ impl<'a> System<'a> for Sys { let animation = match (physics.on_ground, &character.movement, &character.action) { (_, Roll { .. }, Idle) => Animation::Roll, - (true, Stand, Idle) => Animation::Idle, - (true, Run, Idle) => Animation::Run, + (true, Stand, _) => Animation::Stand, //if standing still, legs still + (true, Stand, Idle) => Animation::Idle, //if standing still and not acting, idle the body + (true, Run, _) => Animation::Run, //if running, legs run + (true, Run, Idle) => Animation::Lean, //if running and not acting, lean the body (false, Jump, Idle) => Animation::Jump, (true, Stand, Wield { .. }) => Animation::Cidle, (true, Run, Wield { .. }) => Animation::Crun, diff --git a/voxygen/src/anim/character/idle.rs b/voxygen/src/anim/character/idle.rs index f5ab828a78..dae68319fb 100644 --- a/voxygen/src/anim/character/idle.rs +++ b/voxygen/src/anim/character/idle.rs @@ -75,14 +75,6 @@ impl Animation for IdleAnimation { next.r_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * -0.06); next.r_hand.scale = Vec3::one(); - next.l_foot.offset = Vec3::new(-3.4, -0.1, 8.0); - next.l_foot.ori = Quaternion::identity(); - next.l_foot.scale = Vec3::one(); - - next.r_foot.offset = Vec3::new(3.4, -0.1, 8.0); - next.r_foot.ori = Quaternion::identity(); - next.r_foot.scale = Vec3::one(); - next.weapon.offset = Vec3::new( -7.0 + skeleton_attr.weapon_x, -5.0 + skeleton_attr.weapon_y, diff --git a/voxygen/src/anim/character/lean.rs b/voxygen/src/anim/character/lean.rs new file mode 100644 index 0000000000..1d60609225 --- /dev/null +++ b/voxygen/src/anim/character/lean.rs @@ -0,0 +1,107 @@ +use super::{ + super::{Animation, SkeletonAttr}, + CharacterSkeleton, +}; +use std::f32::consts::PI; +use std::ops::Mul; +use vek::*; + +pub struct LeanAnimation; + +impl Animation for LeanAnimation { + type Skeleton = CharacterSkeleton; + type Dependency = (f32, f64); + + fn update_skeleton( + skeleton: &Self::Skeleton, + (velocity, global_time): Self::Dependency, + anim_time: f64, + skeleton_attr: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave = (anim_time as f32 * 12.0).sin(); + let wave_cos = (anim_time as f32 * 12.0).cos(); + let wave_diff = (anim_time as f32 * 12.0 + PI / 2.0).sin(); + let wave_cos_dub = (anim_time as f32 * 24.0).cos(); + let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin(); + + let head_look = Vec2::new( + ((global_time + anim_time) as f32 / 2.0) + .floor() + .mul(7331.0) + .sin() + * 0.2, + ((global_time + anim_time) as f32 / 2.0) + .floor() + .mul(1337.0) + .sin() + * 0.1, + ); + + next.head.offset = Vec3::new( + 0.0, + -1.0 + skeleton_attr.neck_forward, + skeleton_attr.neck_height + 15.0 + wave_cos * 1.3, + ); + next.head.ori = Quaternion::rotation_z(head_look.x + wave * 0.1) + * Quaternion::rotation_x(head_look.y + 0.35); + next.head.scale = Vec3::one() * skeleton_attr.head_scale; + + next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 1.1); + next.chest.ori = Quaternion::rotation_z(wave * 0.2); + next.chest.scale = Vec3::one(); + + next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_cos * 1.1); + next.belt.ori = Quaternion::rotation_z(wave * 0.35); + next.belt.scale = Vec3::one(); + + next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_cos * 1.1); + next.shorts.ori = Quaternion::rotation_z(wave * 0.6); + next.shorts.scale = Vec3::one(); + + next.l_hand.offset = Vec3::new( + -7.5 + wave_cos_dub * 1.0, + 2.0 + wave_cos * 5.0, + 0.0 - wave * 1.5, + ); + next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8); + next.l_hand.scale = Vec3::one(); + + next.r_hand.offset = Vec3::new( + 7.5 - wave_cos_dub * 1.0, + 2.0 - wave_cos * 5.0, + 0.0 + wave * 1.5, + ); + next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8); + next.r_hand.scale = Vec3::one(); + + next.weapon.offset = Vec3::new( + -7.0 + skeleton_attr.weapon_x, + -5.0 + skeleton_attr.weapon_y, + 15.0, + ); + next.weapon.ori = + Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25); + next.weapon.scale = Vec3::one(); + + next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7); + next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15); + next.l_shoulder.scale = Vec3::one() * 1.1; + + next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7); + next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15); + next.r_shoulder.scale = Vec3::one() * 1.1; + + next.draw.offset = Vec3::new(0.0, 5.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; + + next.torso.offset = Vec3::new(0.0, -0.2 + wave * -0.08, 0.4) * skeleton_attr.scaler; + next.torso.ori = + Quaternion::rotation_x(wave_stop * velocity * -0.06 + wave_diff * velocity * -0.005); + next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler; + + next + } +} diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index 138ca93a2b..0837dcb881 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -5,9 +5,11 @@ pub mod cjump; pub mod crun; pub mod gliding; pub mod idle; +pub mod stand; pub mod jump; pub mod roll; pub mod run; +pub mod lean; // Reexports pub use self::attack::AttackAnimation; @@ -17,9 +19,11 @@ pub use self::cjump::CjumpAnimation; pub use self::crun::CrunAnimation; pub use self::gliding::GlidingAnimation; pub use self::idle::IdleAnimation; +pub use self::stand::StandAnimation; pub use self::jump::JumpAnimation; pub use self::roll::RollAnimation; pub use self::run::RunAnimation; +pub use self::lean::LeanAnimation; use super::{Bone, Skeleton}; use crate::render::FigureBoneData; diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index be4d9c802a..2a646a8c98 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -26,56 +26,6 @@ impl Animation for RunAnimation { let wave_cos_dub = (anim_time as f32 * 24.0).cos(); let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin(); - let head_look = Vec2::new( - ((global_time + anim_time) as f32 / 2.0) - .floor() - .mul(7331.0) - .sin() - * 0.2, - ((global_time + anim_time) as f32 / 2.0) - .floor() - .mul(1337.0) - .sin() - * 0.1, - ); - - next.head.offset = Vec3::new( - 0.0, - -1.0 + skeleton_attr.neck_forward, - skeleton_attr.neck_height + 15.0 + wave_cos * 1.3, - ); - next.head.ori = Quaternion::rotation_z(head_look.x + wave * 0.1) - * Quaternion::rotation_x(head_look.y + 0.35); - next.head.scale = Vec3::one() * skeleton_attr.head_scale; - - next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 1.1); - next.chest.ori = Quaternion::rotation_z(wave * 0.2); - next.chest.scale = Vec3::one(); - - next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_cos * 1.1); - next.belt.ori = Quaternion::rotation_z(wave * 0.35); - next.belt.scale = Vec3::one(); - - next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_cos * 1.1); - next.shorts.ori = Quaternion::rotation_z(wave * 0.6); - next.shorts.scale = Vec3::one(); - - next.l_hand.offset = Vec3::new( - -7.5 + wave_cos_dub * 1.0, - 2.0 + wave_cos * 5.0, - 0.0 - wave * 1.5, - ); - next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8); - next.l_hand.scale = Vec3::one(); - - next.r_hand.offset = Vec3::new( - 7.5 - wave_cos_dub * 1.0, - 2.0 - wave_cos * 5.0, - 0.0 + wave * 1.5, - ); - next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8); - next.r_hand.scale = Vec3::one(); - next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7); next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.5); next.l_foot.scale = Vec3::one(); @@ -83,33 +33,7 @@ impl Animation for RunAnimation { next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7); next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.5); next.r_foot.scale = Vec3::one(); - - next.weapon.offset = Vec3::new( - -7.0 + skeleton_attr.weapon_x, - -5.0 + skeleton_attr.weapon_y, - 15.0, - ); - next.weapon.ori = - Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25); - next.weapon.scale = Vec3::one(); - - next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7); - next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15); - next.l_shoulder.scale = Vec3::one() * 1.1; - - next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7); - next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15); - next.r_shoulder.scale = Vec3::one() * 1.1; - - next.draw.offset = Vec3::new(0.0, 5.0, 0.0); - next.draw.ori = Quaternion::rotation_y(0.0); - next.draw.scale = Vec3::one() * 0.0; - - next.torso.offset = Vec3::new(0.0, -0.2 + wave * -0.08, 0.4) * skeleton_attr.scaler; - next.torso.ori = - Quaternion::rotation_x(wave_stop * velocity * -0.06 + wave_diff * velocity * -0.005); - next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler; - + next } } diff --git a/voxygen/src/anim/character/stand.rs b/voxygen/src/anim/character/stand.rs new file mode 100644 index 0000000000..a542690c0f --- /dev/null +++ b/voxygen/src/anim/character/stand.rs @@ -0,0 +1,36 @@ +use super::{ + super::{Animation, SkeletonAttr}, + CharacterSkeleton, +}; +use std::{f32::consts::PI, ops::Mul}; +use vek::*; + +pub struct Input { + pub attack: bool, +} +pub struct StandAnimation; + +impl Animation for StandAnimation { + type Skeleton = CharacterSkeleton; + type Dependency = f64; + + fn update_skeleton( + skeleton: &Self::Skeleton, + global_time: f64, + anim_time: f64, + skeleton_attr: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + + next.l_foot.offset = Vec3::new(-3.4, -0.1, 8.0); + next.l_foot.ori = Quaternion::identity(); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(3.4, -0.1, 8.0); + next.r_foot.ori = Quaternion::identity(); + next.r_foot.scale = Vec3::one(); + + next + } +} diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index f6551a04df..87e97a8c23 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -703,7 +703,7 @@ impl FigureMgr { let time_since_action_change = state.last_action_change.elapsed().as_secs_f64(); let target_movement = match &character.movement { - Stand => anim::character::IdleAnimation::update_skeleton( + Stand => anim::character::StandAnimation::update_skeleton( state.skeleton_mut(), time, time_since_movement_change, @@ -739,10 +739,11 @@ impl FigureMgr { let target_action = match &character.action { Idle => anim::character::IdleAnimation::update_skeleton( state.skeleton_mut(), - time, - time_since_action_change, + (vel.0.magnitude(), time), + time_since_movement_change, skeleton_attr, ), + Wield { .. } => anim::character::CidleAnimation::update_skeleton( state.skeleton_mut(), time,