diff --git a/common/src/comp/body/theropod.rs b/common/src/comp/body/theropod.rs new file mode 100644 index 0000000000..cee07dd02d --- /dev/null +++ b/common/src/comp/body/theropod.rs @@ -0,0 +1,73 @@ +use rand::{seq::SliceRandom, thread_rng}; +use serde::{Deserialize, Serialize}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct Body { + pub species: Species, + pub body_type: BodyType, +} + +impl Body { + pub fn random() -> Self { + let mut rng = thread_rng(); + let species = *(&ALL_SPECIES).choose(&mut rng).unwrap(); + Self::random_with(&mut rng, &species) + } + + #[inline] + pub fn random_with(rng: &mut impl rand::Rng, &species: &Species) -> Self { + let body_type = *(&ALL_BODY_TYPES).choose(rng).unwrap(); + Self { species, body_type } + } +} + +impl From for super::Body { + fn from(body: Body) -> Self { super::Body::Critter(body) } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[repr(u32)] +pub enum Species { + Archaeos = 0, + Odontotyrannos = 1, + +} + +/// Data representing per-species generic data. +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AllSpecies { + pub archaeos: SpeciesMeta, + pub odontotyrannos: SpeciesMeta, +} + +impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies { + type Output = SpeciesMeta; + + #[inline] + fn index(&self, &index: &'a Species) -> &Self::Output { + match index { + Species::Archaeos => &self.archaeos, + Species::Odontotyrannos => &self.odontotyrannos, + } + } +} + +pub const ALL_SPECIES: [Species; 2] = [ + Species::Archaeos, + Species::Odontotyrannos, +]; + +impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies { + type IntoIter = std::iter::Copied>; + type Item = Species; + + fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[repr(u32)] +pub enum BodyType { + Female = 0, + Male = 1, +} +pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male]; diff --git a/voxygen/src/anim/Cargo.toml b/voxygen/src/anim/Cargo.toml index 75bb0ecbe3..10869c6cc3 100644 --- a/voxygen/src/anim/Cargo.toml +++ b/voxygen/src/anim/Cargo.toml @@ -8,7 +8,7 @@ version = "0.7.0" name = "voxygen_anim" # Uncomment to use animation hot reloading # Note: this breaks `cargo test` -# crate-type = ["lib", "cdylib"] +crate-type = ["lib", "cdylib"] [features] be-dyn-lib = [] diff --git a/voxygen/src/anim/src/character/alpha.rs b/voxygen/src/anim/src/character/alpha.rs index 697c369581..cf04b1309f 100644 --- a/voxygen/src/anim/src/character/alpha.rs +++ b/voxygen/src/anim/src/character/alpha.rs @@ -48,14 +48,14 @@ impl Animation for AlphaAnimation { / (0.4 + 4.6 * ((anim_time as f32 * lab as f32 * 18.0).sin()).powf(2.0 as f32))) .sqrt()) * ((anim_time as f32 * lab as f32 * 18.0).sin()); + let axe = (((1.0) + / (0.05 + 0.95 * ((anim_time as f32 * lab as f32 * 8.0).sin()).powf(2.0 as f32))) + .sqrt()) + * ((anim_time as f32 * lab as f32 * 8.0).sin()); let slower = (((1.0) / (0.0001 + 0.999 * ((anim_time as f32 * lab as f32 * 4.0).sin()).powf(2.0 as f32))) .sqrt()) * ((anim_time as f32 * lab as f32 * 4.0).sin()); - let slowax = (((5.0) - / (0.1 + 4.9 * ((anim_time as f32 * lab as f32 * 4.0 + 1.9).cos()).powf(2.0 as f32))) - .sqrt()) - * ((anim_time as f32 * lab as f32 * 4.0 + 1.9).cos()); match active_tool_kind { //TODO: Inventory @@ -216,51 +216,45 @@ impl Animation for AlphaAnimation { next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler; }, Some(ToolKind::Axe(_)) => { - next.head.position = Vec3::new( - 0.0 + slowax * 2.0, - 0.0 + skeleton_attr.head.0 + slowax * -2.0, - skeleton_attr.head.1, - ); - next.head.orientation = Quaternion::rotation_z(slowax * 0.25) - * Quaternion::rotation_x(0.0 + slowax * 0.2) - * Quaternion::rotation_y(slowax * 0.2); + next.head.position = + Vec3::new(0.0, 0.0 + skeleton_attr.head.0, skeleton_attr.head.1); + next.head.orientation = Quaternion::rotation_z(0.1 + axe * 0.2) + * Quaternion::rotation_x(0.0) + * Quaternion::rotation_y(0.2); next.head.scale = Vec3::one() * skeleton_attr.head_scale; next.chest.position = Vec3::new(0.0, 0.0, 7.0); - next.chest.orientation = Quaternion::rotation_z(slowax * 0.2) - * Quaternion::rotation_x(0.0 + slowax * 0.2) - * Quaternion::rotation_y(slowax * 0.2); + next.chest.orientation = Quaternion::rotation_z(0.2 + axe * 0.2); next.chest.scale = Vec3::one(); next.belt.position = Vec3::new(0.0, 0.0, -2.0); - next.belt.orientation = next.chest.orientation * -0.2; + next.belt.orientation = Quaternion::rotation_z(0.2 + axe * -0.1); next.shorts.position = Vec3::new(0.0, 0.0, -5.0); - next.shorts.orientation = next.chest.orientation * -0.15; + next.shorts.orientation = Quaternion::rotation_z(0.2 + axe * -0.2); - next.l_hand.position = Vec3::new(-4.0, 3.0, 2.0); - next.l_hand.orientation = Quaternion::rotation_x(-0.3) - * Quaternion::rotation_z(3.14 - 0.3) - * Quaternion::rotation_y(-0.8); + next.l_hand.position = Vec3::new(-0.5, 0.0, 4.0); + next.l_hand.orientation = Quaternion::rotation_x(PI / 2.0) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_y(0.0); next.l_hand.scale = Vec3::one() * 1.08; - next.r_hand.position = Vec3::new(-2.5, 9.0, 0.0); - next.r_hand.orientation = Quaternion::rotation_x(-0.3) - * Quaternion::rotation_z(3.14 - 0.3) - * Quaternion::rotation_y(-0.8); + next.r_hand.position = Vec3::new(0.5, 0.0, -2.5); + next.r_hand.orientation = Quaternion::rotation_x(PI / 2.0) + * Quaternion::rotation_z(0.0) + * Quaternion::rotation_y(0.0); next.r_hand.scale = Vec3::one() * 1.06; - next.main.position = Vec3::new(-6.0, 10.0, -5.0); - next.main.orientation = Quaternion::rotation_x(1.27) - * Quaternion::rotation_y(-0.3) - * Quaternion::rotation_z(-0.8); + next.main.position = Vec3::new(-0.0, -2.0, -1.0); + next.main.orientation = Quaternion::rotation_x(0.0) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); - next.lantern.orientation = Quaternion::rotation_x(slowax * -0.7 + 0.4) - * Quaternion::rotation_y(slowax * 0.4); + next.control.position = Vec3::new(2.0 + axe * -7.0, 11.0, 3.0); + next.control.orientation = Quaternion::rotation_x(1.6) + * Quaternion::rotation_y(-2.0 + axe * 0.5) + * Quaternion::rotation_z(PI * 0.4); + next.lantern.orientation = + Quaternion::rotation_x(0.4) * Quaternion::rotation_y(0.0); - next.control.position = Vec3::new(0.0, 0.0 + slowax * 8.2, 6.0); - next.control.orientation = Quaternion::rotation_x(0.8) - * Quaternion::rotation_y(-0.3) - * Quaternion::rotation_z(-0.7 + slowax * -1.9); - next.control.scale = Vec3::one(); next.torso.position = Vec3::new(0.0, 0.0, 0.1) * skeleton_attr.scaler; next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0) diff --git a/voxygen/src/anim/src/golem/alpha.rs b/voxygen/src/anim/src/golem/alpha.rs new file mode 100644 index 0000000000..d4bfbde173 --- /dev/null +++ b/voxygen/src/anim/src/golem/alpha.rs @@ -0,0 +1,132 @@ +use super::{ + super::{vek::*, Animation}, + GolemSkeleton, SkeletonAttr, +}; +use std::f32::consts::PI; + +pub struct AlphaAnimation; + +impl Animation for AlphaAnimation { + type Dependency = (f32, f64); + type Skeleton = GolemSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"golem_alpha\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "golem_alpha")] + + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (_velocity, _global_time): Self::Dependency, + anim_time: f64, + _rate: &mut f32, + skeleton_attr: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let lab = 1.0; + + let slower = (((1.0) + / (0.05 + + 0.95 + * ((anim_time as f32 * lab as f32 * 8.0 - 0.5 * PI).sin()).powf(2.0 as f32))) + .sqrt()) + * ((anim_time as f32 * lab as f32 * 8.0 - 0.5 * PI).sin()) + + 1.0; + let twist = (anim_time as f32 * lab as f32 * 4.0).sin() + 0.5; + + let slowersmooth = (anim_time as f32 * lab as f32 * 8.0).sin(); + next.head.position = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1) * 1.02; + next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.2); + next.head.scale = Vec3::one() * 1.02; + + next.upper_torso.position = Vec3::new( + 0.0, + skeleton_attr.upper_torso.0, + skeleton_attr.upper_torso.1, + ) / 8.0; + next.upper_torso.orientation = + Quaternion::rotation_z(twist * 1.5) * Quaternion::rotation_x(0.0); + next.upper_torso.scale = Vec3::one() / 8.0; + + next.lower_torso.position = Vec3::new( + 0.0, + skeleton_attr.lower_torso.0, + skeleton_attr.lower_torso.1, + ); + next.lower_torso.orientation = + Quaternion::rotation_z(twist * -1.5) * Quaternion::rotation_x(0.0); + next.lower_torso.scale = Vec3::one(); + + next.shoulder_l.position = Vec3::new( + -skeleton_attr.shoulder.0, + skeleton_attr.shoulder.1, + skeleton_attr.shoulder.2, + ); + next.shoulder_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.shoulder_l.scale = Vec3::one(); + + next.shoulder_r.position = Vec3::new( + skeleton_attr.shoulder.0, + skeleton_attr.shoulder.1, + skeleton_attr.shoulder.2, + ); + next.shoulder_r.orientation = + Quaternion::rotation_z(0.0) * Quaternion::rotation_x(slower * 0.9); + next.shoulder_r.scale = Vec3::one(); + + next.hand_l.position = Vec3::new( + -skeleton_attr.hand.0, + skeleton_attr.hand.1, + skeleton_attr.hand.2, + ); + next.hand_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.hand_l.scale = Vec3::one() * 1.02; + + next.hand_r.position = Vec3::new( + skeleton_attr.hand.0, + skeleton_attr.hand.1, + skeleton_attr.hand.2, + ); + next.hand_r.orientation = + Quaternion::rotation_z(0.0) * Quaternion::rotation_x(slower * 1.5); + next.hand_r.scale = Vec3::one() * 1.02; + /* + next.leg_l.position = Vec3::new( + -skeleton_attr.leg.0, + skeleton_attr.leg.1, + skeleton_attr.leg.2, + ) * 1.02; + next.leg_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.leg_l.scale = Vec3::one() * 1.02; + + next.leg_r.position = Vec3::new( + skeleton_attr.leg.0, + skeleton_attr.leg.1, + skeleton_attr.leg.2, + ) * 1.02; + next.leg_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.leg_r.scale = Vec3::one() * 1.02; + + next.foot_l.position = Vec3::new( + -skeleton_attr.foot.0, + skeleton_attr.foot.1, + skeleton_attr.foot.2, + ); + next.foot_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.foot_l.scale = Vec3::one(); + + next.foot_r.position = Vec3::new( + skeleton_attr.foot.0, + skeleton_attr.foot.1, + skeleton_attr.foot.2, + ); + next.foot_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.foot_r.scale = Vec3::one(); + */ + next.torso.position = Vec3::new(0.0, 0.0, 0.0); + next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.torso.scale = Vec3::one(); + next + } +} diff --git a/voxygen/src/anim/src/golem/idle.rs b/voxygen/src/anim/src/golem/idle.rs index da453d4629..c6c2d485b5 100644 --- a/voxygen/src/anim/src/golem/idle.rs +++ b/voxygen/src/anim/src/golem/idle.rs @@ -25,7 +25,7 @@ impl Animation for IdleAnimation { let mut next = (*skeleton).clone(); let lab = 1.0; - let torso = (anim_time as f32 * lab as f32 + 1.5 * PI).sin(); + let breathe = (anim_time as f32 * lab as f32 + 1.5 * PI).sin(); let look = Vec2::new( ((global_time + anim_time) as f32 / 8.0) @@ -43,7 +43,7 @@ impl Animation for IdleAnimation { next.head.position = Vec3::new( 0.0, skeleton_attr.head.0, - skeleton_attr.head.1 + torso * 0.2, + skeleton_attr.head.1 + breathe * 0.2, ) * 1.02; next.head.orientation = Quaternion::rotation_z(look.x * 0.6) * Quaternion::rotation_x(look.y * 0.6); @@ -52,17 +52,25 @@ impl Animation for IdleAnimation { next.upper_torso.position = Vec3::new( 0.0, skeleton_attr.upper_torso.0, - skeleton_attr.upper_torso.1 + torso * 0.5, + skeleton_attr.upper_torso.1 + breathe * 0.5, ) / 8.0; next.upper_torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); next.upper_torso.scale = Vec3::one() / 8.0; + next.lower_torso.position = Vec3::new( + 0.0, + skeleton_attr.lower_torso.0, + skeleton_attr.lower_torso.1 + breathe * -0.2, + ); + next.lower_torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.lower_torso.scale = Vec3::one(); + next.shoulder_l.position = Vec3::new( -skeleton_attr.shoulder.0, skeleton_attr.shoulder.1, skeleton_attr.shoulder.2, ); - next.shoulder_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.shoulder_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.2); next.shoulder_l.scale = Vec3::one(); next.shoulder_r.position = Vec3::new( @@ -70,29 +78,29 @@ impl Animation for IdleAnimation { skeleton_attr.shoulder.1, skeleton_attr.shoulder.2, ); - next.shoulder_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.shoulder_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.2); next.shoulder_r.scale = Vec3::one(); next.hand_l.position = Vec3::new( -skeleton_attr.hand.0, skeleton_attr.hand.1, - skeleton_attr.hand.2 + torso * 0.6, + skeleton_attr.hand.2 + breathe * 0.6, ); - next.hand_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.hand_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.2); next.hand_l.scale = Vec3::one() * 1.02; next.hand_r.position = Vec3::new( skeleton_attr.hand.0, skeleton_attr.hand.1, - skeleton_attr.hand.2 + torso * 0.6, + skeleton_attr.hand.2 + breathe * 0.6, ); - next.hand_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.2); next.hand_r.scale = Vec3::one() * 1.02; next.leg_l.position = Vec3::new( -skeleton_attr.leg.0, skeleton_attr.leg.1, - skeleton_attr.leg.2, + skeleton_attr.leg.2 + breathe * -0.2, ) * 1.02; next.leg_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); next.leg_l.scale = Vec3::one() * 1.02; @@ -100,7 +108,7 @@ impl Animation for IdleAnimation { next.leg_r.position = Vec3::new( skeleton_attr.leg.0, skeleton_attr.leg.1, - skeleton_attr.leg.2, + skeleton_attr.leg.2 + breathe * -0.2, ) * 1.02; next.leg_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); next.leg_r.scale = Vec3::one() * 1.02; @@ -108,18 +116,18 @@ impl Animation for IdleAnimation { next.foot_l.position = Vec3::new( -skeleton_attr.foot.0, skeleton_attr.foot.1, - skeleton_attr.foot.2, - ) / 8.0; + skeleton_attr.foot.2 + breathe * -0.2, + ); next.foot_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); - next.foot_l.scale = Vec3::one() / 8.0; + next.foot_l.scale = Vec3::one(); next.foot_r.position = Vec3::new( skeleton_attr.foot.0, skeleton_attr.foot.1, - skeleton_attr.foot.2, - ) / 8.0; + skeleton_attr.foot.2 + breathe * -0.2, + ); next.foot_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); - next.foot_r.scale = Vec3::one() / 8.0; + next.foot_r.scale = Vec3::one(); next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); diff --git a/voxygen/src/anim/src/golem/mod.rs b/voxygen/src/anim/src/golem/mod.rs index 8a39b74dec..5d5079f721 100644 --- a/voxygen/src/anim/src/golem/mod.rs +++ b/voxygen/src/anim/src/golem/mod.rs @@ -1,9 +1,12 @@ +pub mod alpha; pub mod idle; pub mod jump; pub mod run; // Reexports -pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation}; +pub use self::{ + alpha::AlphaAnimation, idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation, +}; use super::{make_bone, vek::*, FigureBoneData, Skeleton}; use common::comp::{self}; @@ -14,6 +17,7 @@ pub type Body = comp::golem::Body; skeleton_impls!(struct GolemSkeleton { + head, + upper_torso, + + lower_torso, + shoulder_l, + shoulder_r, + hand_l, @@ -29,7 +33,7 @@ impl Skeleton for GolemSkeleton { type Attr = SkeletonAttr; type Body = Body; - const BONE_COUNT: usize = 10; + const BONE_COUNT: usize = 11; #[cfg(feature = "use-dyn-lib")] const COMPUTE_FN: &'static [u8] = b"golem_compute_mats\0"; @@ -40,21 +44,25 @@ impl Skeleton for GolemSkeleton { buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], ) -> Vec3 { let torso_mat = base_mat * Mat4::::from(self.torso); - let foot_l_mat = base_mat * Mat4::::from(self.foot_l); - let foot_r_mat = base_mat * Mat4::::from(self.foot_r); let upper_torso_mat = torso_mat * Mat4::::from(self.upper_torso); + let lower_torso_mat = upper_torso_mat * Mat4::::from(self.lower_torso); + let leg_l_mat = lower_torso_mat * Mat4::::from(self.leg_l); + let leg_r_mat = lower_torso_mat * Mat4::::from(self.leg_r); + let shoulder_l_mat = upper_torso_mat * Mat4::::from(self.shoulder_l); + let shoulder_r_mat = upper_torso_mat * Mat4::::from(self.shoulder_r); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ make_bone(upper_torso_mat * Mat4::::from(self.head)), make_bone(upper_torso_mat), + make_bone(lower_torso_mat), make_bone(upper_torso_mat * Mat4::::from(self.shoulder_l)), make_bone(upper_torso_mat * Mat4::::from(self.shoulder_r)), - make_bone(upper_torso_mat * Mat4::::from(self.hand_l)), - make_bone(upper_torso_mat * Mat4::::from(self.hand_r)), - make_bone(foot_l_mat * Mat4::::from(self.leg_l)), - make_bone(foot_r_mat * Mat4::::from(self.leg_r)), - make_bone(foot_l_mat), - make_bone(foot_r_mat), + make_bone(shoulder_l_mat * Mat4::::from(self.hand_l)), + make_bone(shoulder_r_mat * Mat4::::from(self.hand_r)), + make_bone(leg_l_mat), + make_bone(leg_r_mat), + make_bone(leg_l_mat * Mat4::::from(self.foot_l)), + make_bone(leg_r_mat * Mat4::::from(self.foot_r)), ]; Vec3::default() } @@ -63,6 +71,7 @@ impl Skeleton for GolemSkeleton { pub struct SkeletonAttr { head: (f32, f32), upper_torso: (f32, f32), + lower_torso: (f32, f32), shoulder: (f32, f32, f32), hand: (f32, f32, f32), leg: (f32, f32, f32), @@ -85,6 +94,7 @@ impl Default for SkeletonAttr { Self { head: (0.0, 0.0), upper_torso: (0.0, 0.0), + lower_torso: (0.0, 0.0), shoulder: (0.0, 0.0, 0.0), hand: (0.0, 0.0, 0.0), leg: (0.0, 0.0, 0.0), @@ -98,22 +108,25 @@ impl<'a> From<&'a Body> for SkeletonAttr { use comp::golem::Species::*; Self { head: match (body.species, body.body_type) { - (StoneGolem, _) => (0.0, 16.0), + (StoneGolem, _) => (0.0, 2.0), }, upper_torso: match (body.species, body.body_type) { - (StoneGolem, _) => (0.0, 33.0), + (StoneGolem, _) => (0.0, 34.5), + }, + lower_torso: match (body.species, body.body_type) { + (StoneGolem, _) => (0.0, -10.5), }, shoulder: match (body.species, body.body_type) { - (StoneGolem, _) => (8.0, -0.5, 7.5), + (StoneGolem, _) => (8.0, -1.5, 4.0), }, hand: match (body.species, body.body_type) { - (StoneGolem, _) => (9.5, -1.0, 4.5), + (StoneGolem, _) => (12.5, -1.0, -7.0), }, leg: match (body.species, body.body_type) { - (StoneGolem, _) => (-1.0, 0.0, 9.0), + (StoneGolem, _) => (4.0, 0.0, -3.5), }, foot: match (body.species, body.body_type) { - (StoneGolem, _) => (4.0, 0.5, 11.0), + (StoneGolem, _) => (3.5, 0.5, -9.5), }, } } diff --git a/voxygen/src/anim/src/golem/run.rs b/voxygen/src/anim/src/golem/run.rs index 63761bb1a2..c1226293ed 100644 --- a/voxygen/src/anim/src/golem/run.rs +++ b/voxygen/src/anim/src/golem/run.rs @@ -24,46 +24,68 @@ impl Animation for RunAnimation { ) -> Self::Skeleton { let mut next = (*skeleton).clone(); - let lab = 10.0; - - let belt = (anim_time as f32 * lab as f32 + 1.5 * PI).sin(); - - let foothoril = (anim_time as f32 * lab as f32 + PI * 1.4).sin(); - let foothorir = (anim_time as f32 * lab as f32 + PI * 0.4).sin(); - - let footvertl = (anim_time as f32 * lab as f32).sin().max(0.1); - let footvertr = (anim_time as f32 * lab as f32 + PI).sin().max(0.1); + let lab = 0.45; //.65 + let foothoril = (((1.0) + / (0.4 + + (0.6) + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 1.4).sin()).powf(2.0 as f32))) + .sqrt()) + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 1.4).sin()); + let foothorir = (((1.0) + / (0.4 + + (0.6) + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 0.4).sin()).powf(2.0 as f32))) + .sqrt()) + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 0.4).sin()); + let footvertl = (anim_time as f32 * 16.0 * lab as f32).sin(); + let footvertr = (anim_time as f32 * 16.0 * lab as f32 + PI).sin(); let footrotl = (((5.0) - / (1.0 + (4.0) * ((anim_time as f32 * lab as f32 + PI * 1.4).sin()).powf(2.0 as f32))) + / (2.5 + + (2.5) + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 1.4).sin()).powf(2.0 as f32))) .sqrt()) - * ((anim_time as f32 * lab as f32 + PI * 1.4).sin()); + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 1.4).sin()); let footrotr = (((5.0) - / (1.0 + (4.0) * ((anim_time as f32 * lab as f32 + PI * 0.4).sin()).powf(2.0 as f32))) + / (1.0 + + (4.0) + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 0.4).sin()).powf(2.0 as f32))) .sqrt()) - * ((anim_time as f32 * lab as f32 + PI * 0.4).sin()); + * ((anim_time as f32 * 16.0 * lab as f32 + PI * 0.4).sin()); + + let short = (anim_time as f32 * lab as f32 * 16.0).sin(); + let shortalt = (anim_time as f32 * lab as f32 * 16.0 + PI / 2.0).sin(); next.head.position = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1) * 1.02; - next.head.orientation = Quaternion::rotation_z(belt * -0.3) * Quaternion::rotation_x(0.3); + next.head.orientation = Quaternion::rotation_z(short * -0.3) * Quaternion::rotation_x(-0.2); next.head.scale = Vec3::one() * 1.02; next.upper_torso.position = Vec3::new( 0.0, skeleton_attr.upper_torso.0, - skeleton_attr.upper_torso.1 + belt * 1.0, + skeleton_attr.upper_torso.1 + short * 1.0, ) / 8.0; next.upper_torso.orientation = - Quaternion::rotation_z(belt * 0.40) * Quaternion::rotation_x(0.0); + Quaternion::rotation_z(short * 0.40) * Quaternion::rotation_x(0.0); next.upper_torso.scale = Vec3::one() / 8.0; + next.lower_torso.position = Vec3::new( + 0.0, + skeleton_attr.lower_torso.0, + skeleton_attr.lower_torso.1, + ); + next.lower_torso.orientation = Quaternion::rotation_z(shortalt * 0.60); + next.lower_torso.scale = Vec3::one(); + next.shoulder_l.position = Vec3::new( -skeleton_attr.shoulder.0, skeleton_attr.shoulder.1, skeleton_attr.shoulder.2, ); - next.shoulder_l.orientation = - Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotl * -0.15); + next.shoulder_l.orientation = Quaternion::rotation_z(footrotl * 0.5) + * Quaternion::rotation_y(0.15) + * Quaternion::rotation_x(footrotl * -0.95); next.shoulder_l.scale = Vec3::one(); next.shoulder_r.position = Vec3::new( @@ -71,8 +93,9 @@ impl Animation for RunAnimation { skeleton_attr.shoulder.1, skeleton_attr.shoulder.2, ); - next.shoulder_r.orientation = - Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotr * -0.15); + next.shoulder_r.orientation = Quaternion::rotation_z(footrotr * -0.5) + * Quaternion::rotation_y(-0.15) + * Quaternion::rotation_x(footrotr * -0.95); next.shoulder_r.scale = Vec3::one(); next.hand_l.position = Vec3::new( @@ -80,8 +103,9 @@ impl Animation for RunAnimation { skeleton_attr.hand.1, skeleton_attr.hand.2, ); - next.hand_l.orientation = - Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + footrotl * -0.8); + next.hand_l.orientation = Quaternion::rotation_x(0.5 + footrotl * -1.1) + * Quaternion::rotation_y(0.5) + * Quaternion::rotation_z(-0.35 + footrotl * -1.0); next.hand_l.scale = Vec3::one() * 1.02; next.hand_r.position = Vec3::new( @@ -89,8 +113,9 @@ impl Animation for RunAnimation { skeleton_attr.hand.1, skeleton_attr.hand.2, ); - next.hand_r.orientation = - Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + footrotr * -0.8); + next.hand_r.orientation = Quaternion::rotation_x(0.5 + footrotr * -1.1) + * Quaternion::rotation_y(-0.5) + * Quaternion::rotation_z(0.35 + footrotr * 1.0); next.hand_r.scale = Vec3::one() * 1.02; next.leg_l.position = Vec3::new( @@ -98,7 +123,9 @@ impl Animation for RunAnimation { skeleton_attr.leg.1, skeleton_attr.leg.2, ) * 1.02; - next.leg_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.leg_l.orientation = Quaternion::rotation_x(footrotl * 1.5) + * Quaternion::rotation_y(-0.3) + * Quaternion::rotation_z(footrotl * -0.5); next.leg_l.scale = Vec3::one() * 1.02; next.leg_r.position = Vec3::new( @@ -107,27 +134,29 @@ impl Animation for RunAnimation { skeleton_attr.leg.2, ) * 1.02; - next.leg_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0); + next.leg_r.orientation = Quaternion::rotation_x(footrotr * 1.5) + * Quaternion::rotation_y(0.3) + * Quaternion::rotation_z(footrotr * 0.5); next.leg_r.scale = Vec3::one() * 1.02; next.foot_l.position = Vec3::new( -skeleton_attr.foot.0, - skeleton_attr.foot.1 + foothoril * 8.0 + 3.0, - skeleton_attr.foot.2 + footvertl * 4.0, - ) / 8.0; - next.foot_l.orientation = Quaternion::rotation_x(footrotl * 0.7); - next.foot_l.scale = Vec3::one() / 8.0 * 0.98; + skeleton_attr.foot.1 + foothoril * 13.0, + skeleton_attr.foot.2 - 3.0 + (footvertl * 15.0).max(-2.0), + ); + next.foot_l.orientation = Quaternion::rotation_x(footrotl * 1.8); + next.foot_l.scale = Vec3::one() * 0.98; next.foot_r.position = Vec3::new( skeleton_attr.foot.0, - skeleton_attr.foot.1 + foothorir * 8.0 + 3.0, - skeleton_attr.foot.2 + footvertr * 4.0, - ) / 8.0; + skeleton_attr.foot.1 + foothorir * 13.0, + skeleton_attr.foot.2 - 3.0 + (footvertr * 15.0).max(-2.0), + ); next.foot_r.orientation = - Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotr * 0.7); - next.foot_r.scale = Vec3::one() / 8.0 * 0.98; + Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotr * 1.8); + next.foot_r.scale = Vec3::one() * 0.98; - next.torso.position = Vec3::new(0.0, 0.0, belt * 0.15); + next.torso.position = Vec3::new(0.0, 0.0, short * 0.15); next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.2); next.torso.scale = Vec3::one(); next diff --git a/voxygen/src/scene/figure/cache.rs b/voxygen/src/scene/figure/cache.rs index 421b3259eb..60d723a4d5 100644 --- a/voxygen/src/scene/figure/cache.rs +++ b/voxygen/src/scene/figure/cache.rs @@ -254,7 +254,6 @@ where manifest_indicator, } } - /// NOTE: Intended for render time (useful with systems like wgpu that /// expect data used by the rendering pipelines to be stable throughout /// the render pass). @@ -284,12 +283,6 @@ where }), }; - if let Some(((FigureModelEntryFuture::Done(model), _), _)) = self.models.get(&key) { - Some(model) - } else { - None - } - } pub fn get_or_create_model<'c>( &'c mut self, diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index 1c73ddb797..4fb0025440 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -2777,6 +2777,7 @@ struct GolemCenterSpec(HashMap<(GSpecies, GBodyType), SidedGCenterVoxSpec>); struct SidedGCenterVoxSpec { head: GolemCenterSubSpec, torso_upper: GolemCenterSubSpec, + torso_lower: GolemCenterSubSpec, } #[derive(Deserialize)] struct GolemCenterSubSpec { @@ -2894,6 +2895,27 @@ impl GolemCenterSpec { (center, Vec3::from(spec.torso_upper.offset)) } + + pub fn mesh_torso_lower( + &self, + species: GSpecies, + body_type: GBodyType, + generate_mesh: impl FnOnce(Segment, Vec3) -> BoneMeshes, + ) -> BoneMeshes { + let spec = match self.0.get(&(species, body_type)) { + Some(spec) => spec, + None => { + error!( + "No torso lower specification exists for the combination of {:?} and {:?}", + species, body_type + ); + return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh); + }, + }; + let center = graceful_load_segment(&spec.torso_lower.center.0); + + generate_mesh(center, Vec3::from(spec.torso_lower.offset)) + } } impl GolemLateralSpec { fn mesh_shoulder_l(&self, species: GSpecies, body_type: GBodyType) -> BoneMeshes { diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index e02d6df6a0..b7d4dd9c10 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -2053,7 +2053,6 @@ impl FigureMgr { skeleton_attr, ), - // TODO! _ => anim::golem::IdleAnimation::update_skeleton( &GolemSkeleton::default(), time, @@ -2062,8 +2061,21 @@ impl FigureMgr { skeleton_attr, ), }; + let target_bones = match &character { + CharacterState::BasicMelee(_) => { + anim::golem::AlphaAnimation::update_skeleton( + &target_base, + (vel.0.magnitude(), time), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, + // TODO! + _ => target_base, + }; - state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_base, dt); + state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt); state.update( renderer, pos.0,