diff --git a/assets/voxygen/voxel/quadruped_medium_central_manifest.ron b/assets/voxygen/voxel/quadruped_medium_central_manifest.ron index 69901c6685..8eb2192a7b 100644 --- a/assets/voxygen/voxel/quadruped_medium_central_manifest.ron +++ b/assets/voxygen/voxel/quadruped_medium_central_manifest.ron @@ -159,7 +159,7 @@ central: ("npc.tuskram.male.neck"), ), jaw: ( - offset: (-5.0, 0.0, -1.5), + offset: (-5.0, 0.0, -8.0), central: ("npc.tuskram.male.jaw"), ), torso_front: ( diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index a4609a180b..182bc80e5c 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -764,12 +764,68 @@ impl Body { ) } - pub fn mounting_offset(&self) -> Vec3 { + /// Component of the mounting offset specific to the mountee + pub fn mountee_offset(&self) -> Vec3 { match self { - Body::Ship(ship::Body::DefaultAirship) => Vec3::from([0.0, 0.0, 10.0]), - Body::Ship(ship::Body::AirBalloon) => Vec3::from([0.0, 0.0, 5.0]), - _ => Vec3::unit_z(), + Body::QuadrupedMedium(quadruped_medium) => { + match (quadruped_medium.species, quadruped_medium.body_type) { + (quadruped_medium::Species::Grolgar, _) => [0.5, 0.5, 1.8], + (quadruped_medium::Species::Saber, _) => [0.3, 0.3, 1.3], + (quadruped_medium::Species::Tiger, _) => [0.2, 0.2, 1.4], + (quadruped_medium::Species::Tuskram, _) => [-0.5, -0.5, 1.5], + (quadruped_medium::Species::Lion, _) => [0.3, 0.3, 1.5], + (quadruped_medium::Species::Tarasque, _) => [0.6, 0.6, 2.0], + (quadruped_medium::Species::Wolf, _) => [0.5, 0.5, 1.3], + (quadruped_medium::Species::Frostfang, _) => [0.5, 0.5, 1.2], + (quadruped_medium::Species::Mouflon, _) => [0.3, 0.3, 1.2], + (quadruped_medium::Species::Catoblepas, _) => [0.0, 0.0, 2.0], + (quadruped_medium::Species::Bonerattler, _) => [0.5, 0.5, 1.2], + (quadruped_medium::Species::Deer, _) => [0.2, 0.2, 1.3], + (quadruped_medium::Species::Hirdrasil, _) => [0.0, 0.0, 1.4], + (quadruped_medium::Species::Roshwalr, _) => [0.5, 0.5, 1.8], + (quadruped_medium::Species::Donkey, _) => [0.5, 0.5, 1.5], + (quadruped_medium::Species::Camel, _) => [-0.1, -0.1, 2.8], + (quadruped_medium::Species::Zebra, _) => [0.5, 0.5, 1.8], + (quadruped_medium::Species::Antelope, _) => [0.3, 0.3, 1.4], + (quadruped_medium::Species::Kelpie, _) => [0.5, 0.5, 1.9], + (quadruped_medium::Species::Horse, _) => [0.0, 0.0, 2.0], + (quadruped_medium::Species::Barghest, _) => [0.5, 0.5, 2.2], + (quadruped_medium::Species::Cattle, quadruped_medium::BodyType::Male) => { + [0.5, 0.5, 2.6] + }, + (quadruped_medium::Species::Cattle, quadruped_medium::BodyType::Female) => { + [0.7, 0.7, 2.2] + }, + (quadruped_medium::Species::Darkhound, _) => [0.5, 0.5, 1.4], + (quadruped_medium::Species::Highland, _) => [0.5, 0.5, 2.3], + (quadruped_medium::Species::Yak, _) => [0.0, 0.0, 3.0], + (quadruped_medium::Species::Panda, _) => [-0.2, -0.2, 1.4], + (quadruped_medium::Species::Bear, _) => [-0.4, -0.4, 2.5], + (quadruped_medium::Species::Dreadhorn, _) => [0.2, 0.2, 3.5], + (quadruped_medium::Species::Moose, _) => [-0.6, -0.6, 2.1], + (quadruped_medium::Species::Snowleopard, _) => [-0.5, -0.5, 1.4], + (quadruped_medium::Species::Mammoth, _) => [0.0, 4.9, 7.2], + (quadruped_medium::Species::Ngoubou, _) => [0.0, 0.3, 2.0], + (quadruped_medium::Species::Llama, _) => [0.0, 0.1, 1.5], + (quadruped_medium::Species::Alpaca, _) => [0.0, -0.1, 1.0], + } + }, + Body::Ship(ship) => match ship { + ship::Body::DefaultAirship => [0.0, 0.0, 10.0], + ship::Body::AirBalloon => [0.0, 0.0, 5.0], + }, + _ => [0.0, 0.0, 0.0], } + .into() + } + + /// Component of the mounting offset specific to the mounter + pub fn mounter_offset(&self) -> Vec3 { + match self { + Body::Humanoid(_) => [0.0, 0.0, 0.0], + _ => [0.0, 0.0, 0.0], + } + .into() } } diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index db48764235..e9de5617c3 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -352,11 +352,10 @@ impl<'a> System<'a> for Sys { // Mounted occurs after control actions have been handled // If mounted, character state is controlled by mount - // TODO: Make mounting a state if let Some(Mounting(_)) = read_data.mountings.get(entity) { - let sit_state = CharacterState::Sit {}; - if join_struct.char_state.get_unchecked() != &sit_state { - *join_struct.char_state.get_mut_unchecked() = sit_state; + let idle_state = CharacterState::Idle {}; + if join_struct.char_state.get_unchecked() != &idle_state { + *join_struct.char_state.get_mut_unchecked() = idle_state; } continue; } diff --git a/common/systems/src/mount.rs b/common/systems/src/mount.rs index 016fb9eb60..04139ed167 100644 --- a/common/systems/src/mount.rs +++ b/common/systems/src/mount.rs @@ -66,9 +66,11 @@ impl<'a> System<'a> for Sys { let ori = orientations.get(entity).copied(); let vel = velocities.get(entity).copied(); if let (Some(pos), Some(ori), Some(vel)) = (pos, ori, vel) { - let mounting_offset = - body.map_or(Vec3::unit_z(), Body::mounting_offset); - let _ = positions.insert(mounter, Pos(pos.0 + mounting_offset)); + let mounter_body = bodies.get(mounter); + let mounting_offset = body.map_or(Vec3::unit_z(), Body::mountee_offset) + + mounter_body.map_or(Vec3::zero(), Body::mounter_offset); + let _ = positions + .insert(mounter, Pos(pos.0 + ori.to_quat() * mounting_offset)); let _ = orientations.insert(mounter, ori); let _ = velocities.insert(mounter, vel); } diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs index 88c6dae69b..3ec0cf10a2 100644 --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -109,16 +109,20 @@ pub fn handle_mount(server: &mut Server, mounter: EcsEntity, mountee: EcsEntity) Some(comp::MountState::Unmounted) ); - let within_range = within_mounting_range( - state.ecs().read_storage::().get(mounter), - state.ecs().read_storage::().get(mountee), - ); + let within_range = || { + let positions = state.ecs().read_storage::(); + within_mounting_range(positions.get(mounter), positions.get(mountee)) + }; + let healths = state.ecs().read_storage::(); + let alive = |e| healths.get(e).map_or(true, |h| !h.is_dead); - if not_mounting_yet && within_range { - if let (Some(mounter_uid), Some(mountee_uid)) = ( - state.ecs().uid_from_entity(mounter), - state.ecs().uid_from_entity(mountee), - ) { + if not_mounting_yet && within_range() && alive(mounter) && alive(mountee) { + let uids = state.ecs().read_storage::(); + if let (Some(mounter_uid), Some(mountee_uid)) = + (uids.get(mounter).copied(), uids.get(mountee).copied()) + { + drop(uids); + drop(healths); // We know the entities must exist to be able to look up their UIDs, so these // are guaranteed to work; hence we can ignore possible errors here. state.write_component_ignore_entity_dead( diff --git a/voxygen/anim/src/biped_large/alpha.rs b/voxygen/anim/src/biped_large/alpha.rs index ba870c6b2d..075cd1d758 100644 --- a/voxygen/anim/src/biped_large/alpha.rs +++ b/voxygen/anim/src/biped_large/alpha.rs @@ -173,7 +173,7 @@ impl Animation for AlphaAnimation { if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { match spec.as_str() { "Wendigo Magic" => { - next.torso.position = Vec3::new(0.0, 0.0, move1 * -0.3); + next.torso.position = Vec3::new(0.0, 0.0, move1 * -2.18); next.upper_torso.orientation = Quaternion::rotation_x(move1 * -0.5 + move2 * -0.4); next.lower_torso.orientation = @@ -262,7 +262,7 @@ impl Animation for AlphaAnimation { next.shoulder_l.orientation = Quaternion::rotation_x(0.0); }; - next.torso.position = Vec3::new(0.0, move2 * -2.2, move2 * -1.0); + next.torso.position = Vec3::new(0.0, move2 * -10.35, move2 * -4.7); }, "Minotaur" => { next.control_l.position = Vec3::new(0.0, 4.0, 5.0); diff --git a/voxygen/anim/src/biped_large/beta.rs b/voxygen/anim/src/biped_large/beta.rs index 6af78b06e6..7ed6c398c4 100644 --- a/voxygen/anim/src/biped_large/beta.rs +++ b/voxygen/anim/src/biped_large/beta.rs @@ -170,7 +170,7 @@ impl Animation for BetaAnimation { if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { match spec.as_str() { "Wendigo Magic" => { - next.torso.position = Vec3::new(0.0, 0.0, move1 * -0.3); + next.torso.position = Vec3::new(0.0, 0.0, move1 * -2.18); next.upper_torso.orientation = Quaternion::rotation_x(move1 * -0.5 + move2 * -0.4); next.lower_torso.orientation = @@ -198,7 +198,7 @@ impl Animation for BetaAnimation { next.head.orientation = Quaternion::rotation_x(move1 * 0.3); }, "Tidal Claws" => { - next.torso.position = Vec3::new(0.0, 0.0, move1 * -0.3); + next.torso.position = Vec3::new(0.0, 0.0, move1 * -1.4); next.upper_torso.orientation = Quaternion::rotation_x(move1 * -0.5 + move2 * -0.4); next.lower_torso.orientation = diff --git a/voxygen/anim/src/biped_large/chargemelee.rs b/voxygen/anim/src/biped_large/chargemelee.rs index 92311f793e..df141df553 100644 --- a/voxygen/anim/src/biped_large/chargemelee.rs +++ b/voxygen/anim/src/biped_large/chargemelee.rs @@ -121,7 +121,7 @@ impl Animation for ChargeMeleeAnimation { -6.0 + move1 * 22.0 + move2 * 8.0, -18.0 + move1 * 14.0 + move2 * -19.0, ); - next.torso.position = Vec3::new(0.0, move2 * 1.5, 0.0); + next.torso.position = Vec3::new(0.0, move2 * 7.06, 0.0); next.second.scale = Vec3::one() * 1.0; next.weapon_l.orientation = diff --git a/voxygen/anim/src/biped_large/idle.rs b/voxygen/anim/src/biped_large/idle.rs index 870d25f424..18196eb150 100644 --- a/voxygen/anim/src/biped_large/idle.rs +++ b/voxygen/anim/src/biped_large/idle.rs @@ -62,7 +62,6 @@ impl Animation for IdleAnimation { next.hand_r.scale = Vec3::one() * 1.04; next.lower_torso.scale = Vec3::one() * 1.02; next.hold.scale = Vec3::one() * 0.0; - next.torso.scale = Vec3::one() / 8.0 * s_a.scaler; next.second.scale = Vec3::one() * 0.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + torso * 0.2); @@ -137,7 +136,7 @@ impl Animation for IdleAnimation { next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); - next.torso.position = Vec3::new(0.0, 0.0, 0.0) / 8.0 * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); if s_a.float { next.upper_torso.position = Vec3::new( diff --git a/voxygen/anim/src/biped_large/jump.rs b/voxygen/anim/src/biped_large/jump.rs index b31c4dbdf4..47c6b0788f 100644 --- a/voxygen/anim/src/biped_large/jump.rs +++ b/voxygen/anim/src/biped_large/jump.rs @@ -116,9 +116,8 @@ impl Animation for JumpAnimation { next.foot_r.position = Vec3::new(s_a.foot.0, 5.0 + s_a.foot.1, s_a.foot.2); next.foot_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.4); - next.torso.position = Vec3::new(0.0, 0.0, 0.0) / 8.0 * s_a.scaler; + 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() / 8.0 * s_a.scaler; next } diff --git a/voxygen/anim/src/biped_large/mod.rs b/voxygen/anim/src/biped_large/mod.rs index 9a5ca48719..9ced7b2b1c 100644 --- a/voxygen/anim/src/biped_large/mod.rs +++ b/voxygen/anim/src/biped_large/mod.rs @@ -31,7 +31,7 @@ pub use self::{ wield::WieldAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::{convert::TryFrom, f32::consts::PI}; @@ -79,11 +79,12 @@ impl Skeleton for BipedLargeSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { - let upper_torso = Mat4::::from(self.upper_torso); + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 8.0); let torso_mat = base_mat * Mat4::::from(self.torso); - let upper_torso_mat = torso_mat * upper_torso; + let upper_torso_mat = torso_mat * Mat4::::from(self.upper_torso); let control_mat = Mat4::::from(self.control); let control_l_mat = Mat4::::from(self.control_l); let control_r_mat = Mat4::::from(self.control_r); @@ -126,7 +127,17 @@ impl Skeleton for BipedLargeSkeleton { // FIXME: Should this be control_l_mat? make_bone(upper_torso_mat * control_mat * hand_l_mat * Mat4::::from(self.hold)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::BipedLarge(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/biped_large/run.rs b/voxygen/anim/src/biped_large/run.rs index d88245ae8c..e957775038 100644 --- a/voxygen/anim/src/biped_large/run.rs +++ b/voxygen/anim/src/biped_large/run.rs @@ -138,7 +138,6 @@ impl Animation for RunAnimation { next.hand_l.scale = Vec3::one() * 1.04; next.hand_r.scale = Vec3::one() * 1.04; next.hold.scale = Vec3::one() * 0.0; - next.torso.scale = Vec3::one() / 8.0 * s_a.scaler; next.second.scale = Vec3::one() * 0.0; if s_a.beast { @@ -256,10 +255,9 @@ impl Animation for RunAnimation { next.torso.position = Vec3::new( 0.0, - 0.0 + (short * 0.75).max(-2.0), - speedavg * 0.15 + (short * 0.75).max(-2.0), - ) / 8.0 - * s_a.scaler; + 0.0 + (short * 6.0).max(-16.0), + speedavg * 1.2 + (short * 6.0).max(-16.0), + ); next.torso.orientation = Quaternion::rotation_x(x_tilt + amplitude * short * 0.1 + speedavg * -0.045); } else { @@ -410,7 +408,7 @@ impl Animation for RunAnimation { tilt * 1.0 + side * 0.3 + side * (foothorir * 0.3), ) * Quaternion::rotation_z(side * 0.2); - next.torso.position = Vec3::new(0.0, 0.0, 0.0) / 8.0; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.torso.orientation = Quaternion::rotation_x(-0.25 * speednorm); } diff --git a/voxygen/anim/src/biped_large/spinmelee.rs b/voxygen/anim/src/biped_large/spinmelee.rs index ea284922c8..eee429c8d6 100644 --- a/voxygen/anim/src/biped_large/spinmelee.rs +++ b/voxygen/anim/src/biped_large/spinmelee.rs @@ -113,7 +113,7 @@ impl Animation for SpinMeleeAnimation { next.upper_torso.orientation = Quaternion::rotation_x(move1 * -0.5); next.lower_torso.orientation = Quaternion::rotation_x(move1 * 0.8); - next.torso.position = Vec3::new(0.0, 0.0, move1 * 0.8); + next.torso.position = Vec3::new(0.0, 0.0, move1 * 6.4); }, _ => {}, diff --git a/voxygen/anim/src/biped_large/summon.rs b/voxygen/anim/src/biped_large/summon.rs index 1d128348bf..24960c3ec9 100644 --- a/voxygen/anim/src/biped_large/summon.rs +++ b/voxygen/anim/src/biped_large/summon.rs @@ -133,7 +133,7 @@ impl Animation for SummonAnimation { let pullback = 1.0 - move3; let move1 = move1base * pullback; let move2 = move2base * pullback; - next.torso.position = Vec3::new(0.0, 0.0 + move1 * 1.0, move1 * -4.0); + next.torso.position = Vec3::new(0.0, 0.0 + move1 * 4.7, move1 * -18.8); next.upper_torso.position = Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1); diff --git a/voxygen/anim/src/biped_small/alpha.rs b/voxygen/anim/src/biped_small/alpha.rs index 69dc4b0f10..0a14e920fb 100644 --- a/voxygen/anim/src/biped_small/alpha.rs +++ b/voxygen/anim/src/biped_small/alpha.rs @@ -74,7 +74,7 @@ impl Animation for AlphaAnimation { next.head.orientation = Quaternion::rotation_x(move1abs * 0.2 + move2abs * 0.3) * Quaternion::rotation_z(move1abs * -0.2 + move2abs * 0.6) * Quaternion::rotation_y(move1abs * 0.3 + move2abs * -0.5); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_x(move1abs * -0.2 + move2abs * 0.3) * Quaternion::rotation_z(move1abs * 0.5 + move2abs * -0.6); diff --git a/voxygen/anim/src/biped_small/idle.rs b/voxygen/anim/src/biped_small/idle.rs index 929151f635..7881aed783 100644 --- a/voxygen/anim/src/biped_small/idle.rs +++ b/voxygen/anim/src/biped_small/idle.rs @@ -27,14 +27,9 @@ impl Animation for IdleAnimation { let mut next = (*skeleton).clone(); let slow = (anim_time * 4.0).sin(); - next.foot_l.scale = Vec3::one() * s_a.scaler / 11.0; - next.foot_r.scale = Vec3::one() * s_a.scaler / 11.0; - - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + slow * -0.1); - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + slow * 0.3) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + slow * 0.3); next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1); next.main.position = Vec3::new(2.0, -3.0, -3.0); next.main.orientation = Quaternion::rotation_y(-0.5) * Quaternion::rotation_z(PI / 2.0); @@ -42,8 +37,8 @@ impl Animation for IdleAnimation { next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1); next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2 + slow * -0.1); next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2 + slow * -0.1); - next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2) * s_a.scaler / 11.0; - next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2) * s_a.scaler / 11.0; + next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); + next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); next } diff --git a/voxygen/anim/src/biped_small/mod.rs b/voxygen/anim/src/biped_small/mod.rs index ba89f7c4c4..fa3c6ccedf 100644 --- a/voxygen/anim/src/biped_small/mod.rs +++ b/voxygen/anim/src/biped_small/mod.rs @@ -12,7 +12,7 @@ pub use self::{ shoot::ShootAnimation, stunned::StunnedAnimation, wield::WieldAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -47,7 +47,10 @@ impl Skeleton for BipedSmallSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0); + let chest_mat = base_mat * Mat4::::from(self.chest); let pants_mat = chest_mat * Mat4::::from(self.pants); let control_mat = chest_mat * Mat4::::from(self.control); @@ -64,7 +67,17 @@ impl Skeleton for BipedSmallSkeleton { make_bone(base_mat * Mat4::::from(self.foot_l)), make_bone(base_mat * Mat4::::from(self.foot_r)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::BipedSmall(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/biped_small/run.rs b/voxygen/anim/src/biped_small/run.rs index 9d85372dc7..08db2a3f30 100644 --- a/voxygen/anim/src/biped_small/run.rs +++ b/voxygen/anim/src/biped_small/run.rs @@ -78,9 +78,6 @@ impl Animation for RunAnimation { (global_time + anim_time / 18.0).floor().mul(7331.0).sin() * 0.2, (global_time + anim_time / 18.0).floor().mul(1137.0).sin() * 0.1, ); - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; - next.foot_l.scale = Vec3::one() * s_a.scaler / 11.0; - next.foot_r.scale = Vec3::one() * s_a.scaler / 11.0; next.head.position = Vec3::new(0.0, -1.0 + s_a.head.0, s_a.head.1 + short * 0.1); next.head.orientation = Quaternion::rotation_z(tilt * -2.5 + head_look.x * 0.2 - short * 0.02) @@ -90,8 +87,7 @@ impl Animation for RunAnimation { 0.0, s_a.chest.0, s_a.chest.1 + 1.0 * speednorm + shortalt * -0.8, - ) * s_a.scaler - / 11.0; + ); next.chest.orientation = Quaternion::rotation_z(short * 0.06 + tilt * -0.6) * Quaternion::rotation_y(tilt * 1.6) * Quaternion::rotation_x(shortalter * 0.035 + speednorm * -0.4 + (tilt.abs())); @@ -121,7 +117,6 @@ impl Animation for RunAnimation { Quaternion::rotation_x(0.4 * speednorm + (footrotl * -1.2) * speednorm) * Quaternion::rotation_y(footrotl * -0.4 * speednorm); - // next.foot_l.position = Vec3::new( -s_a.foot.0 + footstrafel * sideabs * 3.0 + tilt * -2.0, s_a.foot.1 @@ -130,8 +125,7 @@ impl Animation for RunAnimation { s_a.foot.2 + (1.0 - sideabs) * (2.0 * speednorm + ((footvertl * -1.1 * speednorm).max(-1.0))) + side * ((footvertsl * 1.5).max(-1.0)), - ) * s_a.scaler - / 11.0; + ); next.foot_l.orientation = Quaternion::rotation_x( (1.0 - sideabs) * (-0.2 * speednorm + foothoril * -0.9 * speednorm) + sideabs * -0.5, ) * Quaternion::rotation_y( @@ -146,8 +140,7 @@ impl Animation for RunAnimation { s_a.foot.2 + (1.0 - sideabs) * (2.0 * speednorm + ((footvertr * -1.1 * speednorm).max(-1.0))) + side * ((footvertsr * -1.5).max(-1.0)), - ) * s_a.scaler - / 11.0; + ); next.foot_r.orientation = Quaternion::rotation_x( (1.0 - sideabs) * (-0.2 * speednorm + foothorir * -0.9 * speednorm) + sideabs * -0.5, ) * Quaternion::rotation_y( diff --git a/voxygen/anim/src/biped_small/shoot.rs b/voxygen/anim/src/biped_small/shoot.rs index 4f5c52a20b..4368f70a78 100644 --- a/voxygen/anim/src/biped_small/shoot.rs +++ b/voxygen/anim/src/biped_small/shoot.rs @@ -61,8 +61,7 @@ impl Animation for ShootAnimation { 0.0, s_a.chest.0, s_a.chest.1 + fastalt * 0.4 * speednormcancel + speednormcancel * -0.5, - ) * s_a.scaler - / 11.0; + ); next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1); diff --git a/voxygen/anim/src/biped_small/stunned.rs b/voxygen/anim/src/biped_small/stunned.rs index 401e63f8d8..82dff4248d 100644 --- a/voxygen/anim/src/biped_small/stunned.rs +++ b/voxygen/anim/src/biped_small/stunned.rs @@ -66,8 +66,7 @@ impl Animation for StunnedAnimation { next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x(movement1 * 0.2) * Quaternion::rotation_z(movement1 * -0.3); - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + movement1abs - 3.0) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + movement1abs - 3.0); next.chest.orientation = Quaternion::rotation_z(movement1 * 1.2); next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1); @@ -162,13 +161,9 @@ impl Animation for StunnedAnimation { _ => {}, } } else { - next.foot_l.scale = Vec3::one() * s_a.scaler / 11.0; - next.foot_r.scale = Vec3::one() * s_a.scaler / 11.0; - - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1); next.main.position = Vec3::new(2.0, -3.0, -3.0); next.main.orientation = Quaternion::rotation_y(-0.5) * Quaternion::rotation_z(PI / 2.0); @@ -176,11 +171,10 @@ impl Animation for StunnedAnimation { next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1); next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2); next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2); - next.foot_l.position = - Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2) * s_a.scaler / 11.0; - next.foot_r.position = - Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2) * s_a.scaler / 11.0; - }; + next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); + next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); + } + next } } diff --git a/voxygen/anim/src/biped_small/wield.rs b/voxygen/anim/src/biped_small/wield.rs index 0b642440fd..8e17934746 100644 --- a/voxygen/anim/src/biped_small/wield.rs +++ b/voxygen/anim/src/biped_small/wield.rs @@ -51,8 +51,7 @@ impl Animation for WieldAnimation { 0.0, s_a.chest.0, s_a.chest.1 + fastalt * 0.4 * speednormcancel + speednormcancel * -0.5, - ) * s_a.scaler - / 11.0; + ); next.pants.position = Vec3::new(0.0, s_a.pants.0, s_a.pants.1); diff --git a/voxygen/anim/src/bird_large/alpha.rs b/voxygen/anim/src/bird_large/alpha.rs index 39f18af013..fef6419431 100644 --- a/voxygen/anim/src/bird_large/alpha.rs +++ b/voxygen/anim/src/bird_large/alpha.rs @@ -53,14 +53,12 @@ impl Animation for AlphaAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06) * s_a.scaler / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06); next.chest.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); diff --git a/voxygen/anim/src/bird_large/breathe.rs b/voxygen/anim/src/bird_large/breathe.rs index 518df0b4af..798ad1cd47 100644 --- a/voxygen/anim/src/bird_large/breathe.rs +++ b/voxygen/anim/src/bird_large/breathe.rs @@ -53,18 +53,16 @@ impl Animation for BreatheAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; next.chest.position = Vec3::new( 0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + twitch2 * 0.1, - ) * s_a.scaler - / 8.0; + ); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); next.neck.orientation = Quaternion::rotation_x(movement1abs * 0.5 - movement2abs * 0.5); diff --git a/voxygen/anim/src/bird_large/dash.rs b/voxygen/anim/src/bird_large/dash.rs index 65717f32fd..c177986d15 100644 --- a/voxygen/anim/src/bird_large/dash.rs +++ b/voxygen/anim/src/bird_large/dash.rs @@ -89,11 +89,10 @@ impl Animation for DashAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x( @@ -114,8 +113,7 @@ impl Animation for DashAnimation { 0.0, s_a.chest.0, s_a.chest.1 + short * 0.5 + 0.5 * speednorm, - ) * s_a.scaler - / 8.0; + ); next.chest.orientation = Quaternion::rotation_x(short * 0.07 + movement1abs * 0.8 + movement2abs * -1.2) * Quaternion::rotation_y(tilt * 0.8) diff --git a/voxygen/anim/src/bird_large/feed.rs b/voxygen/anim/src/bird_large/feed.rs index ccc6078cc5..11b9aec664 100644 --- a/voxygen/anim/src/bird_large/feed.rs +++ b/voxygen/anim/src/bird_large/feed.rs @@ -41,15 +41,12 @@ impl Animation for FeedAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 - 1.8) - * s_a.scaler - / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 - 1.8); next.chest.orientation = Quaternion::rotation_x(s_a.feed); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); @@ -85,9 +82,9 @@ impl Animation for FeedAnimation { next.wing_out_l.orientation = Quaternion::rotation_y(-0.2) * Quaternion::rotation_z(0.2); next.wing_out_r.orientation = Quaternion::rotation_y(0.2) * Quaternion::rotation_z(-0.2); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_l.orientation = Quaternion::rotation_x(0.0); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_r.orientation = Quaternion::rotation_x(0.0); next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); diff --git a/voxygen/anim/src/bird_large/fly.rs b/voxygen/anim/src/bird_large/fly.rs index 9c042b87ae..acb32f23f0 100644 --- a/voxygen/anim/src/bird_large/fly.rs +++ b/voxygen/anim/src/bird_large/fly.rs @@ -60,11 +60,10 @@ impl Animation for FlyAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); next.neck.orientation = @@ -79,8 +78,7 @@ impl Animation for FlyAnimation { next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1); if velocity.z > 2.0 || velocity.xy().magnitude() < 12.0 { - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 - flap4 * 1.5) * s_a.scaler / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 - flap4 * 1.5); next.chest.orientation = Quaternion::rotation_x( (0.8 - 0.8 * velocity.xy().magnitude() / 5.0).max(-0.2) - flap1 * 0.2, ) * Quaternion::rotation_y(tilt * 1.8 + fast * 0.01); @@ -110,11 +108,11 @@ impl Animation for FlyAnimation { next.tail_rear.orientation = Quaternion::rotation_x(-flap3 * 0.3 + 0.15) * Quaternion::rotation_z(-tilt * 0.8); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2 - flap4 * 1.5) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2 - flap4 * 1.5); next.leg_l.orientation = Quaternion::rotation_x( (-1.0 * velocity.xy().magnitude() / 5.0).max(-1.2) + flap1 * -0.1, ) * Quaternion::rotation_y(tilt * 1.6 + fast * 0.01); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2 - flap4 * 1.5) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2 - flap4 * 1.5); next.leg_r.orientation = Quaternion::rotation_x( (-1.0 * velocity.xy().magnitude() / 5.0).max(-1.2) + flap1 * -0.1, ) * Quaternion::rotation_y(tilt * 1.6 + fast * 0.01); @@ -124,8 +122,7 @@ impl Animation for FlyAnimation { next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); next.foot_r.orientation = Quaternion::rotation_x(flap1 * -0.1); } else { - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + slow * 0.05) * s_a.scaler / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + slow * 0.05); next.chest.orientation = Quaternion::rotation_x(-0.2 + slow * 0.05 + (0.8 * velocity.z / 80.0).min(0.8)) * Quaternion::rotation_y(tilt * 1.8 + fast * 0.01); @@ -159,10 +156,10 @@ impl Animation for FlyAnimation { next.tail_rear.orientation = Quaternion::rotation_x(slow * 0.08) * Quaternion::rotation_z(-tilt * 0.8); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2 + slow * 0.05) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2 + slow * 0.05); next.leg_l.orientation = Quaternion::rotation_x(-1.2 + slow * -0.05) * Quaternion::rotation_y(tilt * 1.6 + fast * 0.01); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2 + slow * 0.05) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2 + slow * 0.05); next.leg_r.orientation = Quaternion::rotation_x(-1.2 + slow * -0.05) * Quaternion::rotation_y(tilt * 1.6 + fast * 0.01); diff --git a/voxygen/anim/src/bird_large/idle.rs b/voxygen/anim/src/bird_large/idle.rs index bcedcd54dc..c48f0fcf8f 100644 --- a/voxygen/anim/src/bird_large/idle.rs +++ b/voxygen/anim/src/bird_large/idle.rs @@ -39,15 +39,12 @@ impl Animation for IdleAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + 1.5) - * s_a.scaler - / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + 1.5); next.chest.orientation = Quaternion::rotation_x(0.0); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); @@ -83,9 +80,9 @@ impl Animation for IdleAnimation { next.wing_out_l.orientation = Quaternion::rotation_y(-0.4) * Quaternion::rotation_z(0.2); next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_l.orientation = Quaternion::rotation_x(0.0); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_r.orientation = Quaternion::rotation_x(0.0); next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); diff --git a/voxygen/anim/src/bird_large/mod.rs b/voxygen/anim/src/bird_large/mod.rs index 58a3ae27a1..671908a5f9 100644 --- a/voxygen/anim/src/bird_large/mod.rs +++ b/voxygen/anim/src/bird_large/mod.rs @@ -18,7 +18,7 @@ pub use self::{ shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -57,7 +57,10 @@ impl Skeleton for BirdLargeSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 8.0); + let chest_mat = base_mat * Mat4::::from(self.chest); let neck_mat = chest_mat * Mat4::::from(self.neck); let head_mat = neck_mat * Mat4::::from(self.head); @@ -93,7 +96,17 @@ impl Skeleton for BirdLargeSkeleton { make_bone(foot_l_mat), make_bone(foot_r_mat), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::BirdLarge(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/bird_large/run.rs b/voxygen/anim/src/bird_large/run.rs index b71ea77af3..7ac8b4c905 100644 --- a/voxygen/anim/src/bird_large/run.rs +++ b/voxygen/anim/src/bird_large/run.rs @@ -67,11 +67,10 @@ impl Animation for RunAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x(-0.1 * speednorm + short * -0.05) @@ -90,8 +89,7 @@ impl Animation for RunAnimation { 0.0, s_a.chest.0, s_a.chest.1 + short * 0.5 + 0.5 * speednorm, - ) * s_a.scaler - / 8.0; + ); next.chest.orientation = Quaternion::rotation_x(short * 0.07) * Quaternion::rotation_y(tilt * 0.8) * Quaternion::rotation_z(shortalt * 0.10); @@ -124,7 +122,7 @@ impl Animation for RunAnimation { -s_a.leg.0 + speednorm * 1.5, s_a.leg.1 + foot1b * -2.3, s_a.leg.2, - ) / 8.0; + ); next.leg_l.orientation = Quaternion::rotation_x(-0.2 * speednorm + foot1a * 0.15) * Quaternion::rotation_y(tilt * 0.5); @@ -132,7 +130,7 @@ impl Animation for RunAnimation { s_a.leg.0 + speednorm * -1.5, s_a.leg.1 + foot2b * -2.3, s_a.leg.2, - ) / 8.0; + ); next.leg_r.orientation = Quaternion::rotation_x(-0.2 * speednorm + foot2a * 0.15) * Quaternion::rotation_y(tilt * 0.5); diff --git a/voxygen/anim/src/bird_large/shockwave.rs b/voxygen/anim/src/bird_large/shockwave.rs index 9208c62d42..ea40d09785 100644 --- a/voxygen/anim/src/bird_large/shockwave.rs +++ b/voxygen/anim/src/bird_large/shockwave.rs @@ -40,14 +40,12 @@ impl Animation for ShockwaveAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + movement1abs * 1.5) * s_a.scaler / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + movement1abs * 1.5); next.chest.orientation = Quaternion::rotation_x(movement1abs * 1.0 + movement2abs * -1.0); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); @@ -89,9 +87,9 @@ impl Animation for ShockwaveAnimation { next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_l.orientation = Quaternion::rotation_x(0.0); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_r.orientation = Quaternion::rotation_x(0.0); next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); diff --git a/voxygen/anim/src/bird_large/shoot.rs b/voxygen/anim/src/bird_large/shoot.rs index 673afe07a5..2b346cc762 100644 --- a/voxygen/anim/src/bird_large/shoot.rs +++ b/voxygen/anim/src/bird_large/shoot.rs @@ -45,18 +45,16 @@ impl Animation for ShootAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; next.chest.position = Vec3::new( 0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + twitch2 * 0.1, - ) * s_a.scaler - / 8.0; + ); next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = diff --git a/voxygen/anim/src/bird_large/stunned.rs b/voxygen/anim/src/bird_large/stunned.rs index 68e016e104..680da225ac 100644 --- a/voxygen/anim/src/bird_large/stunned.rs +++ b/voxygen/anim/src/bird_large/stunned.rs @@ -39,14 +39,12 @@ impl Animation for StunnedAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06) * s_a.scaler / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06); next.chest.orientation = Quaternion::rotation_x(movement1base * 0.5); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); @@ -79,9 +77,9 @@ impl Animation for StunnedAnimation { next.wing_out_l.orientation = Quaternion::rotation_y(-0.2) * Quaternion::rotation_z(0.2); next.wing_out_r.orientation = Quaternion::rotation_y(0.2) * Quaternion::rotation_z(-0.2); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_l.orientation = Quaternion::rotation_x(movement1abs * 0.8); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2); next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); diff --git a/voxygen/anim/src/bird_large/summon.rs b/voxygen/anim/src/bird_large/summon.rs index 0853162d59..c650af8fc3 100644 --- a/voxygen/anim/src/bird_large/summon.rs +++ b/voxygen/anim/src/bird_large/summon.rs @@ -46,18 +46,16 @@ impl Animation for SummonAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; next.chest.position = Vec3::new( 0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + twitch2 * 0.1, - ) * s_a.scaler - / 8.0; + ); next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = diff --git a/voxygen/anim/src/bird_large/swim.rs b/voxygen/anim/src/bird_large/swim.rs index f3eb1219cc..8535b06c47 100644 --- a/voxygen/anim/src/bird_large/swim.rs +++ b/voxygen/anim/src/bird_large/swim.rs @@ -43,15 +43,12 @@ impl Animation for SwimAnimation { next.head.scale = Vec3::one() * 0.98; next.neck.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 8.0 * 0.98; - next.leg_r.scale = Vec3::one() / 8.0 * 0.98; + next.leg_l.scale = Vec3::one() * 0.98; + next.leg_r.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 1.02; next.foot_r.scale = Vec3::one() * 1.02; - next.chest.scale = Vec3::one() * s_a.scaler / 8.0; - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + 1.5) - * s_a.scaler - / 8.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06 + 1.5); next.chest.orientation = Quaternion::rotation_x(0.0); next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); @@ -87,9 +84,9 @@ impl Animation for SwimAnimation { next.wing_out_l.orientation = Quaternion::rotation_y(-0.4) * Quaternion::rotation_z(0.2); next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2); - next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_l.orientation = Quaternion::rotation_x(-0.8 + wave_fast * 0.5); - next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0; + next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2); next.leg_r.orientation = Quaternion::rotation_x(-0.8 + wave_fast_cos * 0.5); next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); diff --git a/voxygen/anim/src/bird_medium/feed.rs b/voxygen/anim/src/bird_medium/feed.rs index 1760ac7798..70e1bb43ac 100644 --- a/voxygen/anim/src/bird_medium/feed.rs +++ b/voxygen/anim/src/bird_medium/feed.rs @@ -50,7 +50,7 @@ impl Animation for FeedAnimation { 0.0, s_a.chest.0 + s_a.feed, -1.0 - 5.0 * (s_a.feed - 1.0) + wave_slow * 0.3 + s_a.chest.1, - ) / 11.0; + ); next.torso.orientation = Quaternion::rotation_x(-0.5 * s_a.feed) * Quaternion::rotation_y(wave_slow * 0.03); @@ -63,9 +63,9 @@ impl Animation for FeedAnimation { next.wing_r.position = Vec3::new(s_a.wing.0, s_a.wing.1, s_a.wing.2); next.wing_r.orientation = Quaternion::rotation_y(-0.4 + wave_slow * 0.1); - next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2) / 11.0; + next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); - next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2) / 11.0; + next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); next } } diff --git a/voxygen/anim/src/bird_medium/fly.rs b/voxygen/anim/src/bird_medium/fly.rs index 5fefb3ffae..cd697db87c 100644 --- a/voxygen/anim/src/bird_medium/fly.rs +++ b/voxygen/anim/src/bird_medium/fly.rs @@ -30,11 +30,8 @@ impl Animation for FlyAnimation { let center = (anim_time * lab + PI / 2.0).sin(); let centeroffset = (anim_time * lab + PI * 1.5).sin(); - next.torso.scale = Vec3::one() / 11.0; next.wing_l.scale = Vec3::one() * 1.05; next.wing_r.scale = Vec3::one() * 1.05; - next.leg_l.scale = Vec3::one() / 11.0; - next.leg_r.scale = Vec3::one() / 11.0; next.head.position = Vec3::new(0.0, s_a.head.0 + 0.5, s_a.head.1 + center * 0.5 - 1.0); next.head.orientation = @@ -44,7 +41,7 @@ impl Animation for FlyAnimation { 0.0, s_a.chest.0 + centeroffset * 0.6, center * 0.6 + s_a.chest.1, - ) / 11.0; + ); next.torso.orientation = Quaternion::rotation_y(center * 0.05); next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1 + centeroffset * 0.6); @@ -56,10 +53,10 @@ impl Animation for FlyAnimation { next.wing_r.position = Vec3::new(s_a.wing.0, s_a.wing.1, s_a.wing.2); next.wing_r.orientation = Quaternion::rotation_y((-0.57 + footr * 1.2).min(0.0)); - next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2) / 11.0; + next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); next.leg_l.orientation = Quaternion::rotation_x(-1.3 + footl * 0.06); - next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2) / 11.0; + next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); next.leg_r.orientation = Quaternion::rotation_x(-1.3 + footr * 0.06); next } diff --git a/voxygen/anim/src/bird_medium/idle.rs b/voxygen/anim/src/bird_medium/idle.rs index d11b599c3c..833573f246 100644 --- a/voxygen/anim/src/bird_medium/idle.rs +++ b/voxygen/anim/src/bird_medium/idle.rs @@ -40,17 +40,14 @@ impl Animation for IdleAnimation { * 0.25, ); - next.torso.scale = Vec3::one() / 11.0; next.wing_l.scale = Vec3::one() * 1.02; next.wing_r.scale = Vec3::one() * 1.02; - next.leg_l.scale = Vec3::one() / 11.0; - next.leg_r.scale = Vec3::one() / 11.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_z(duck_head_look.x) * Quaternion::rotation_x(-duck_head_look.y.abs() + wave_slow_cos * 0.03); - next.torso.position = Vec3::new(0.0, s_a.chest.0, wave_slow * 0.3 + s_a.chest.1) / 11.0; + next.torso.position = Vec3::new(0.0, s_a.chest.0, wave_slow * 0.3 + s_a.chest.1); next.torso.orientation = Quaternion::rotation_y(wave_slow * 0.03); next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1); @@ -60,9 +57,9 @@ impl Animation for IdleAnimation { next.wing_r.position = Vec3::new(s_a.wing.0, s_a.wing.1, s_a.wing.2); - next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2) / 11.0; + next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2); - next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2) / 11.0; + next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2); next } } diff --git a/voxygen/anim/src/bird_medium/mod.rs b/voxygen/anim/src/bird_medium/mod.rs index 5caa8f17ae..aa6ceb4929 100644 --- a/voxygen/anim/src/bird_medium/mod.rs +++ b/voxygen/anim/src/bird_medium/mod.rs @@ -6,7 +6,7 @@ pub mod run; // Reexports pub use self::{feed::FeedAnimation, fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation}; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -36,7 +36,9 @@ impl Skeleton for BirdMediumSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(1.0 / 11.0); let torso_mat = base_mat * Mat4::::from(self.torso); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ @@ -48,7 +50,17 @@ impl Skeleton for BirdMediumSkeleton { make_bone(base_mat * Mat4::::from(self.leg_l)), make_bone(base_mat * Mat4::::from(self.leg_r)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::BirdMedium(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/bird_medium/run.rs b/voxygen/anim/src/bird_medium/run.rs index 9f1dd93ac1..84f9d85655 100644 --- a/voxygen/anim/src/bird_medium/run.rs +++ b/voxygen/anim/src/bird_medium/run.rs @@ -30,11 +30,8 @@ impl Animation for RunAnimation { let center = (anim_time * lab + PI / 2.0).sin(); let centeroffset = (anim_time * lab + PI * 1.5).sin(); - next.torso.scale = Vec3::one() / 11.0; next.wing_l.scale = Vec3::one() * 1.05; next.wing_r.scale = Vec3::one() * 1.05; - next.leg_l.scale = Vec3::one() / 11.0; - next.leg_r.scale = Vec3::one() / 11.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + center * 0.5); next.head.orientation = @@ -44,9 +41,8 @@ impl Animation for RunAnimation { 0.0, s_a.chest.0 + centeroffset * 0.6, center * 0.6 + s_a.chest.1, - ) / 11.0; + ); next.torso.orientation = Quaternion::rotation_y(center * 0.05); - next.torso.scale = Vec3::one() / 11.0; next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1 + centeroffset * 0.6); next.tail.orientation = Quaternion::rotation_x(center * 0.03); @@ -57,10 +53,10 @@ impl Animation for RunAnimation { next.wing_r.position = Vec3::new(s_a.wing.0, s_a.wing.1, s_a.wing.2); next.wing_r.orientation = Quaternion::rotation_y((footr * 0.35).min(0.0)); - next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1 + footl * 1.0, s_a.foot.2) / 11.0; + next.leg_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1 + footl * 1.0, s_a.foot.2); next.leg_l.orientation = Quaternion::rotation_x(footl * 0.5); - next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1 + footr * 1.0, s_a.foot.2) / 11.0; + next.leg_r.position = Vec3::new(s_a.foot.0, s_a.foot.1 + footr * 1.0, s_a.foot.2); next.leg_r.orientation = Quaternion::rotation_x(footr * 0.5); next } diff --git a/voxygen/anim/src/character/alpha.rs b/voxygen/anim/src/character/alpha.rs index c09dc33eb0..c7bcfbe010 100644 --- a/voxygen/anim/src/character/alpha.rs +++ b/voxygen/anim/src/character/alpha.rs @@ -44,7 +44,7 @@ impl Animation for AlphaAnimation { next.main.orientation = Quaternion::rotation_x(0.0); next.second.position = Vec3::new(0.0, 0.0, 0.0); next.second.orientation = Quaternion::rotation_z(0.0); - next.torso.position = Vec3::new(0.0, 0.0, 0.1) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 1.1); next.torso.orientation = Quaternion::rotation_z(0.0); match ability_info.and_then(|a| a.tool) { diff --git a/voxygen/anim/src/character/climb.rs b/voxygen/anim/src/character/climb.rs index b920e9c123..039e8ab66c 100644 --- a/voxygen/anim/src/character/climb.rs +++ b/voxygen/anim/src/character/climb.rs @@ -106,7 +106,7 @@ impl Animation for ClimbAnimation { next.lantern.orientation = Quaternion::rotation_x(smooth * -0.3) * Quaternion::rotation_y(smooth * -0.3); - next.torso.position = Vec3::new(0.0, -0.2 + smooth * -0.08, 0.4) * s_a.scaler; + next.torso.position = Vec3::new(0.0, -2.2 + smooth * -0.88, 4.4); } else { next.head.position = Vec3::new(0.0, -1.0 - stagnant + s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x( @@ -158,7 +158,7 @@ impl Animation for ClimbAnimation { next.foot_r.orientation = Quaternion::rotation_x(0.2 + smooth * 0.15 * (1.0 - stagnant)); - next.torso.position = Vec3::new(0.0, -0.2, 0.4) * s_a.scaler; + next.torso.position = Vec3::new(0.0, -2.2, 4.4); }; next diff --git a/voxygen/anim/src/character/dance.rs b/voxygen/anim/src/character/dance.rs index f3239d0f5a..be42143a3f 100644 --- a/voxygen/anim/src/character/dance.rs +++ b/voxygen/anim/src/character/dance.rs @@ -104,7 +104,7 @@ impl Animation for DanceAnimation { next.lantern.orientation = Quaternion::rotation_x(shorte * 0.7 + 0.4) * Quaternion::rotation_y(shorte * 0.4); - next.torso.position = Vec3::new(0.0, -0.3, 0.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, -3.3, 0.0); next.torso.orientation = Quaternion::rotation_z(short * -0.2); next diff --git a/voxygen/anim/src/character/idle.rs b/voxygen/anim/src/character/idle.rs index b8934df70a..81c3145038 100644 --- a/voxygen/anim/src/character/idle.rs +++ b/voxygen/anim/src/character/idle.rs @@ -43,7 +43,6 @@ impl Animation for IdleAnimation { next.back.scale = Vec3::one() * 1.02; next.hold.scale = Vec3::one() * 0.0; next.lantern.scale = Vec3::one() * 0.65; - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; next.shoulder_l.scale = Vec3::one() * 1.1; next.shoulder_r.scale = Vec3::one() * 1.1; @@ -136,7 +135,7 @@ impl Animation for IdleAnimation { next.lantern.position = Vec3::new(s_a.lantern.0, s_a.lantern.1, s_a.lantern.2); next.lantern.orientation = Quaternion::rotation_x(0.1) * Quaternion::rotation_y(0.1); - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.second.scale = match hands { (Some(Hands::One), Some(Hands::One)) => Vec3::one(), diff --git a/voxygen/anim/src/character/jump.rs b/voxygen/anim/src/character/jump.rs index 0458c95ec3..73d6e7e685 100644 --- a/voxygen/anim/src/character/jump.rs +++ b/voxygen/anim/src/character/jump.rs @@ -205,9 +205,8 @@ impl Animation for JumpAnimation { * Quaternion::rotation_y(tilt * 4.0 * slow + tilt * 3.0); } - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.torso.orientation = Quaternion::rotation_x(0.0); - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; match hands { (Some(Hands::One), _) => match active_tool_kind { diff --git a/voxygen/anim/src/character/leapmelee.rs b/voxygen/anim/src/character/leapmelee.rs index 17e65007fc..b9268f368d 100644 --- a/voxygen/anim/src/character/leapmelee.rs +++ b/voxygen/anim/src/character/leapmelee.rs @@ -51,7 +51,7 @@ impl Animation for LeapAnimation { next.second.orientation = Quaternion::rotation_z(0.0); next.main.position = Vec3::new(0.0, 0.0, 0.0); next.main.orientation = Quaternion::rotation_z(0.0); - next.torso.position = Vec3::new(0.0, 0.0, 0.1) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 1.1); next.torso.orientation = Quaternion::rotation_z(0.0); match ability_info.and_then(|a| a.tool) { diff --git a/voxygen/anim/src/character/mod.rs b/voxygen/anim/src/character/mod.rs index 6047f97717..c8e6333b25 100644 --- a/voxygen/anim/src/character/mod.rs +++ b/voxygen/anim/src/character/mod.rs @@ -13,6 +13,7 @@ pub mod gliding; pub mod idle; pub mod jump; pub mod leapmelee; +pub mod mount; pub mod repeater; pub mod roll; pub mod run; @@ -36,13 +37,14 @@ pub use self::{ chargeswing::ChargeswingAnimation, climb::ClimbAnimation, consume::ConsumeAnimation, dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation, glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation, - jump::JumpAnimation, leapmelee::LeapAnimation, repeater::RepeaterAnimation, - roll::RollAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation, - sit::SitAnimation, sneak::SneakAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation, - staggered::StaggeredAnimation, stand::StandAnimation, stunned::StunnedAnimation, - swim::SwimAnimation, swimwield::SwimWieldAnimation, talk::TalkAnimation, wield::WieldAnimation, + jump::JumpAnimation, leapmelee::LeapAnimation, mount::MountAnimation, + repeater::RepeaterAnimation, roll::RollAnimation, run::RunAnimation, + shockwave::ShockwaveAnimation, shoot::ShootAnimation, sit::SitAnimation, sneak::SneakAnimation, + spin::SpinAnimation, spinmelee::SpinMeleeAnimation, staggered::StaggeredAnimation, + stand::StandAnimation, stunned::StunnedAnimation, swim::SwimAnimation, + swimwield::SwimWieldAnimation, talk::TalkAnimation, wield::WieldAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp; use core::{convert::TryFrom, f32::consts::PI}; @@ -96,7 +98,13 @@ impl Skeleton for CharacterSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + // TODO: extract scaler from body to it's own method so we can call that + // directly instead of going through SkeletonAttr? (note todo also + // appiles to other body variant animations) + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0); + let torso_mat = base_mat * Mat4::::from(self.torso); let chest_mat = torso_mat * Mat4::::from(self.chest); let head_mat = chest_mat * Mat4::::from(self.head); @@ -132,7 +140,17 @@ impl Skeleton for CharacterSkeleton { // FIXME: Should this be control_l_mat? make_bone(control_mat * hand_l_mat * Mat4::::from(self.hold)), ]; - (lantern_mat * Vec4::new(0.0, 0.0, -4.0, 1.0)).xyz() + Offsets { + lantern: (lantern_mat * Vec4::new(0.0, 0.0, -4.0, 1.0)).xyz(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::Humanoid(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/character/mount.rs b/voxygen/anim/src/character/mount.rs new file mode 100644 index 0000000000..8d5fc33535 --- /dev/null +++ b/voxygen/anim/src/character/mount.rs @@ -0,0 +1,216 @@ +use super::{ + super::{vek::*, Animation}, + CharacterSkeleton, SkeletonAttr, +}; +use common::comp::item::{Hands, ToolKind}; +use std::{f32::consts::PI, ops::Mul}; + +pub struct MountAnimation; + +impl Animation for MountAnimation { + #[allow(clippy::type_complexity)] + type Dependency<'a> = ( + Option, + Option, + (Option, Option), + f32, + Vec3, + Vec3, + Vec3, + Vec3, + ); + type Skeleton = CharacterSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"character_mount\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "character_mount")] + fn update_skeleton_inner<'a>( + skeleton: &Self::Skeleton, + ( + active_tool_kind, + second_tool_kind, + hands, + global_time, + velocity, + avg_vel, + orientation, + last_ori, + ): Self::Dependency<'a>, + anim_time: f32, + _rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let slow = (anim_time * 1.0).sin(); + let slowa = (anim_time * 1.0 + PI / 2.0).sin(); + let stop = (anim_time * 3.0).min(PI / 2.0).sin(); + + let head_look = Vec2::new( + (global_time * 0.05 + anim_time / 15.0) + .floor() + .mul(7331.0) + .sin() + * 0.25, + (global_time * 0.05 + anim_time / 15.0) + .floor() + .mul(1337.0) + .sin() + * 0.125, + ); + + let ori: Vec2 = Vec2::from(orientation); + let last_ori = Vec2::from(last_ori); + let speed = (Vec2::::from(velocity).magnitude()).min(24.0); + let canceler = (speed / 24.0).powf(0.6); + let _x_tilt = avg_vel.z.atan2(avg_vel.xy().magnitude()) * canceler; + let _tilt = if ::vek::Vec2::new(ori, last_ori) + .map(|o| o.magnitude_squared()) + .map(|m| m > 0.001 && m.is_finite()) + .reduce_and() + && ori.angle_between(last_ori).is_finite() + { + ori.angle_between(last_ori).min(0.2) + * last_ori.determine_side(Vec2::zero(), ori).signum() + } else { + 0.0 + } * 1.3; + + next.head.scale = Vec3::one() * s_a.head_scale; + next.chest.scale = Vec3::one() * 1.01; + next.hand_l.scale = Vec3::one() * 1.04; + next.hand_r.scale = Vec3::one() * 1.04; + next.back.scale = Vec3::one() * 1.02; + next.hold.scale = Vec3::one() * 0.0; + next.lantern.scale = Vec3::one() * 0.65; + next.shoulder_l.scale = Vec3::one() * 1.1; + next.shoulder_r.scale = Vec3::one() * 1.1; + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + slow * 0.1 + stop * -0.8); + next.head.orientation = Quaternion::rotation_z(head_look.x + slow * 0.2 - slow * 0.1) + * Quaternion::rotation_x((0.4 + slowa * -0.1 + slow * 0.1 + head_look.y).abs()); + + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); + next.chest.orientation = Quaternion::rotation_x(-0.6 + stop * 0.15); + + next.belt.position = Vec3::new(0.0, s_a.belt.0 + stop * 1.2, s_a.belt.1); + next.belt.orientation = Quaternion::rotation_x(stop * 0.3); + + next.back.position = Vec3::new(0.0, s_a.back.0, s_a.back.1); + + next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + stop * 2.5, s_a.shorts.1 + stop * 0.6); + next.shorts.orientation = Quaternion::rotation_x(stop * 0.6); + + next.hand_l.position = Vec3::new( + -s_a.hand.0 + 4.0, + s_a.hand.1 + slowa * 0.15 + stop * 8.0, + s_a.hand.2 + slow * 0.7 + stop * 4.0, + ); + next.hand_l.orientation = + Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_z(-PI / 2.0); + + next.hand_r.position = Vec3::new( + s_a.hand.0 - 4.0, + s_a.hand.1 + slowa * 0.15 + stop * 8.0, + s_a.hand.2 + slow * 0.7 + stop * 4.0, + ); + next.hand_r.orientation = + Quaternion::rotation_x(PI / 2.0) * Quaternion::rotation_z(PI / 2.0); + + next.foot_l.position = Vec3::new(-s_a.foot.0 - 2.0, 4.0 + s_a.foot.1, s_a.foot.2); + next.foot_l.orientation = Quaternion::rotation_x(slow * 0.1 + stop * 0.4 + slow * 0.1) + * Quaternion::rotation_y(0.5); + + next.foot_r.position = Vec3::new(s_a.foot.0 + 2.0, 4.0 + s_a.foot.1, s_a.foot.2); + next.foot_r.orientation = Quaternion::rotation_x(slowa * 0.1 + stop * 0.4 + slowa * 0.1) + * Quaternion::rotation_y(-0.5); + + next.shoulder_l.position = Vec3::new(-s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2); + next.shoulder_l.orientation = Quaternion::rotation_x(0.0); + + next.shoulder_r.position = Vec3::new(s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2); + next.shoulder_r.orientation = Quaternion::rotation_x(0.0); + + next.torso.position = Vec3::new(0.0, 0.0, stop * -1.76); + + if skeleton.holding_lantern { + next.hand_r.position = Vec3::new( + s_a.hand.0 + 1.0 - head_look.x * 8.0, + s_a.hand.1 + 5.0 + head_look.x * 6.0, + s_a.hand.2 + 9.0 + head_look.y * 6.0, + ); + next.hand_r.orientation = Quaternion::rotation_x(2.25) + * Quaternion::rotation_z(0.9) + * Quaternion::rotation_y(head_look.x * 3.0) + * Quaternion::rotation_x(head_look.y * 3.0); + + let fast = (anim_time * 5.0).sin(); + let fast2 = (anim_time * 4.5 + 8.0).sin(); + + next.lantern.position = Vec3::new(-0.5, -0.5, -2.5); + next.lantern.orientation = next.hand_r.orientation.inverse() + * Quaternion::rotation_x(fast * 0.1) + * Quaternion::rotation_y(fast2 * 0.1); + } + + next.glider.position = Vec3::new(0.0, 0.0, 10.0); + next.glider.scale = Vec3::one() * 0.0; + next.hold.position = Vec3::new(0.4, -0.3, -5.8); + match hands { + (Some(Hands::Two), _) | (None, Some(Hands::Two)) => match active_tool_kind { + Some(ToolKind::Bow) => { + next.main.position = Vec3::new(0.0, -5.0, 6.0); + next.main.orientation = + Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + }, + Some(ToolKind::Staff) | Some(ToolKind::Sceptre) => { + next.main.position = Vec3::new(2.0, -5.0, -1.0); + next.main.orientation = + Quaternion::rotation_y(-0.5) * Quaternion::rotation_z(1.57); + }, + _ => { + next.main.position = Vec3::new(-7.0, -5.0, 15.0); + next.main.orientation = + Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + }, + }, + (_, _) => {}, + }; + + match hands { + (Some(Hands::One), _) => match active_tool_kind { + Some(ToolKind::Axe) | Some(ToolKind::Hammer) | Some(ToolKind::Sword) => { + next.main.position = Vec3::new(-4.0, -5.0, 10.0); + next.main.orientation = + Quaternion::rotation_y(2.35) * Quaternion::rotation_z(1.57); + }, + + _ => {}, + }, + (_, _) => {}, + }; + match hands { + (None | Some(Hands::One), Some(Hands::One)) => match second_tool_kind { + Some(ToolKind::Axe) | Some(ToolKind::Hammer) | Some(ToolKind::Sword) => { + next.second.position = Vec3::new(4.0, -6.0, 10.0); + next.second.orientation = + Quaternion::rotation_y(-2.5) * Quaternion::rotation_z(-1.57); + }, + _ => {}, + }, + (_, _) => {}, + }; + + next.second.scale = match hands { + (Some(Hands::One), Some(Hands::One)) => Vec3::one(), + (_, _) => Vec3::zero(), + }; + + if let (None, Some(Hands::Two)) = hands { + next.second = next.main; + } + + next + } +} diff --git a/voxygen/anim/src/character/roll.rs b/voxygen/anim/src/character/roll.rs index 7b7d53a3d9..55302c5c06 100644 --- a/voxygen/anim/src/character/roll.rs +++ b/voxygen/anim/src/character/roll.rs @@ -109,7 +109,7 @@ impl Animation for RollAnimation { ); next.foot_r.orientation = Quaternion::rotation_x(0.9 * movement1); - next.torso.position = Vec3::new(0.0, 0.0, 8.0 * movement1) / 11.0 * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 8.0 * movement1); next.torso.orientation = Quaternion::rotation_x(movement1 * -0.4 + movement2 * -2.0 * PI) * Quaternion::rotation_z(tilt * -10.0); diff --git a/voxygen/anim/src/character/run.rs b/voxygen/anim/src/character/run.rs index 354e5af649..9e1dbc966c 100644 --- a/voxygen/anim/src/character/run.rs +++ b/voxygen/anim/src/character/run.rs @@ -275,8 +275,7 @@ impl Animation for RunAnimation { * Quaternion::rotation_y(tilt * 4.0 * fast + tilt * 3.0 + fast2 * speednorm * 0.25); } - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); match hands { (Some(Hands::One), _) => match active_tool_kind { diff --git a/voxygen/anim/src/character/sit.rs b/voxygen/anim/src/character/sit.rs index b620143c9c..d296480b88 100644 --- a/voxygen/anim/src/character/sit.rs +++ b/voxygen/anim/src/character/sit.rs @@ -85,7 +85,7 @@ impl Animation for SitAnimation { next.shoulder_r.position = Vec3::new(s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2); next.shoulder_r.orientation = Quaternion::rotation_x(0.0); - next.torso.position = Vec3::new(0.0, -0.2, stop * -0.16) * s_a.scaler; + next.torso.position = Vec3::new(0.0, -2.2, stop * -1.76); if skeleton.holding_lantern { next.hand_r.position = Vec3::new( diff --git a/voxygen/anim/src/character/spin.rs b/voxygen/anim/src/character/spin.rs index 47bf224d90..a9413004db 100644 --- a/voxygen/anim/src/character/spin.rs +++ b/voxygen/anim/src/character/spin.rs @@ -96,8 +96,9 @@ impl Animation for SpinAnimation { next.torso.position = Vec3::new( 0.0, 0.0, - -1.0 + 1.0 * (movement1 * 0.5 * PI).sin() - + 1.0 * (movement2 * 0.5 * PI + 0.5 * PI).sin(), + -11.0 + + 11.0 * (movement1 * 0.5 * PI).sin() + + 11.0 * (movement2 * 0.5 * PI + 0.5 * PI).sin(), ); next.torso.orientation = Quaternion::rotation_z(movement1.powi(2) * -6.0 + movement2 * -1.7); diff --git a/voxygen/anim/src/character/staggered.rs b/voxygen/anim/src/character/staggered.rs index fe090df31e..3389e12f73 100644 --- a/voxygen/anim/src/character/staggered.rs +++ b/voxygen/anim/src/character/staggered.rs @@ -253,7 +253,7 @@ impl Animation for StaggeredAnimation { ); next.foot_l.orientation = Quaternion::rotation_z(movement1 * 0.6); }; - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.torso.orientation = Quaternion::rotation_z(0.0); if let (None, Some(Hands::Two)) = hands { diff --git a/voxygen/anim/src/character/stand.rs b/voxygen/anim/src/character/stand.rs index cbd66e2c7d..8301ca655e 100644 --- a/voxygen/anim/src/character/stand.rs +++ b/voxygen/anim/src/character/stand.rs @@ -60,7 +60,6 @@ impl Animation for StandAnimation { next.back.scale = Vec3::one() * 1.02; next.hold.scale = Vec3::one() * 0.0; next.lantern.scale = Vec3::one() * 0.65; - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; next.shoulder_l.scale = Vec3::one() * 1.1; next.shoulder_r.scale = Vec3::one() * 1.1; @@ -178,7 +177,7 @@ impl Animation for StandAnimation { * Quaternion::rotation_y(fast2 * 0.1 + tilt * 3.0); } - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.second.scale = Vec3::one(); next.second.scale = match hands { (Some(Hands::One) | None, Some(Hands::One)) => Vec3::one(), diff --git a/voxygen/anim/src/character/stunned.rs b/voxygen/anim/src/character/stunned.rs index a603507492..9edde52b15 100644 --- a/voxygen/anim/src/character/stunned.rs +++ b/voxygen/anim/src/character/stunned.rs @@ -213,7 +213,7 @@ impl Animation for StunnedAnimation { next.hand_l.orientation = Quaternion::rotation_x(movement1abs * 1.2) * Quaternion::rotation_y(movement1 * 1.2); }; - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.torso.orientation = Quaternion::rotation_z(0.0); if let (None, Some(Hands::Two)) = hands { diff --git a/voxygen/anim/src/character/swim.rs b/voxygen/anim/src/character/swim.rs index a2e39457ad..4bb79c4795 100644 --- a/voxygen/anim/src/character/swim.rs +++ b/voxygen/anim/src/character/swim.rs @@ -232,13 +232,12 @@ impl Animation for SwimAnimation { } else { avgtotal }; - next.torso.position = Vec3::new(0.0, 0.0, 1.0 - avgspeed * 0.05) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 11.0 - avgspeed * 0.55); next.torso.orientation = Quaternion::rotation_x( (((1.0 / switch) * PI / 2.0 + avg_vel.z * 0.12).min(PI / 2.0) - PI / 2.0) + avgspeed * avg_vel.z * -0.003, ) * Quaternion::rotation_y(tilt * 2.0) * Quaternion::rotation_z(tilt * 3.0); - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; match hands { (Some(Hands::One), _) => match active_tool_kind { Some(ToolKind::Axe) | Some(ToolKind::Hammer) | Some(ToolKind::Sword) => { diff --git a/voxygen/anim/src/character/swimwield.rs b/voxygen/anim/src/character/swimwield.rs index 9a325fb8b0..7edf40e562 100644 --- a/voxygen/anim/src/character/swimwield.rs +++ b/voxygen/anim/src/character/swimwield.rs @@ -75,9 +75,8 @@ impl Animation for SwimWieldAnimation { next.hold.scale = Vec3::one() * 0.0; if velocity > 0.01 { - next.torso.position = Vec3::new(0.0, 0.0, 1.0) * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 11.0); next.torso.orientation = Quaternion::rotation_x(velocity * -0.05); - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; next.back.position = Vec3::new(0.0, s_a.back.0, s_a.back.1); next.back.orientation = Quaternion::rotation_x( @@ -92,8 +91,7 @@ impl Animation for SwimWieldAnimation { next.chest.position = Vec3::new(0.0 + slowalt * 0.5, s_a.chest.0, s_a.chest.1 + u_slow * 0.5); - next.torso.position = Vec3::new(0.0, 0.0, 0.0) * s_a.scaler; - next.torso.scale = Vec3::one() / 11.0 * s_a.scaler; + next.torso.position = Vec3::new(0.0, 0.0, 0.0); next.foot_l.position = Vec3::new(-s_a.foot.0, -2.0 + s_a.foot.1, s_a.foot.2); diff --git a/voxygen/anim/src/dragon/mod.rs b/voxygen/anim/src/dragon/mod.rs index 9e5d39d200..bb9d922c12 100644 --- a/voxygen/anim/src/dragon/mod.rs +++ b/voxygen/anim/src/dragon/mod.rs @@ -5,7 +5,7 @@ pub mod run; // Reexports pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation}; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -43,7 +43,9 @@ impl Skeleton for DragonSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(1.0); let chest_front_mat = base_mat * Mat4::::from(self.chest_front); let chest_rear_mat = chest_front_mat * Mat4::::from(self.chest_rear); let head_lower_mat = chest_front_mat * Mat4::::from(self.head_lower); @@ -69,7 +71,17 @@ impl Skeleton for DragonSkeleton { make_bone(chest_rear_mat * Mat4::::from(self.foot_bl)), make_bone(chest_rear_mat * Mat4::::from(self.foot_br)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::Dragon(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/fish_medium/idle.rs b/voxygen/anim/src/fish_medium/idle.rs index fafb57efb5..3770dac15c 100644 --- a/voxygen/anim/src/fish_medium/idle.rs +++ b/voxygen/anim/src/fish_medium/idle.rs @@ -30,14 +30,13 @@ impl Animation for IdleAnimation { let slowalt = (anim_time * 3.5 + PI + 0.2).sin(); next.jaw.scale = Vec3::one() * 0.98; - next.chest_front.scale = Vec3::one() / 11.0; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_z(slowalt * -0.1); next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); - next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1) / 11.0; + next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1); next.chest_front.orientation = Quaternion::rotation_x(0.0); next.chest_back.position = Vec3::new(0.0, s_a.chest_back.0, s_a.chest_back.1); diff --git a/voxygen/anim/src/fish_medium/mod.rs b/voxygen/anim/src/fish_medium/mod.rs index 8c68c9e4d8..03e4b7446f 100644 --- a/voxygen/anim/src/fish_medium/mod.rs +++ b/voxygen/anim/src/fish_medium/mod.rs @@ -4,7 +4,7 @@ pub mod swim; // Reexports pub use self::{idle::IdleAnimation, swim::SwimAnimation}; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -33,7 +33,10 @@ impl Skeleton for FishMediumSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(1.0 / 11.0); + let chest_front_mat = base_mat * Mat4::::from(self.chest_front); let chest_back_mat = Mat4::::from(self.chest_back); let head_mat = Mat4::::from(self.head); @@ -47,7 +50,17 @@ impl Skeleton for FishMediumSkeleton { make_bone(chest_front_mat * Mat4::::from(self.fin_l)), make_bone(chest_front_mat * Mat4::::from(self.fin_r)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::FishMedium(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/fish_medium/swim.rs b/voxygen/anim/src/fish_medium/swim.rs index 657bb27bbd..05828b7ee8 100644 --- a/voxygen/anim/src/fish_medium/swim.rs +++ b/voxygen/anim/src/fish_medium/swim.rs @@ -47,14 +47,12 @@ impl Animation for SwimAnimation { let vel = (velocity.magnitude()).min(s_a.amplitude); let slowvel = vel * 0.1; - next.chest_front.scale = Vec3::one() / 11.0; - next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_z(slowalt * -0.1 + tilt * -2.0); next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); - next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1) / 11.0; + next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1); next.chest_front.orientation = Quaternion::rotation_x(velocity.z.abs() * -0.005 + x_tilt) * Quaternion::rotation_z(fast * vel * -0.02); diff --git a/voxygen/anim/src/fish_small/idle.rs b/voxygen/anim/src/fish_small/idle.rs index c1fca1f348..71ebf6f48d 100644 --- a/voxygen/anim/src/fish_small/idle.rs +++ b/voxygen/anim/src/fish_small/idle.rs @@ -28,9 +28,7 @@ impl Animation for IdleAnimation { let slow = (anim_time * 3.5 + PI).sin(); - next.chest.scale = Vec3::one() / 13.0; - - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) / 13.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1); next.tail.orientation = Quaternion::rotation_z(slow * 0.1); diff --git a/voxygen/anim/src/fish_small/mod.rs b/voxygen/anim/src/fish_small/mod.rs index 0a644da947..e388455d9e 100644 --- a/voxygen/anim/src/fish_small/mod.rs +++ b/voxygen/anim/src/fish_small/mod.rs @@ -4,7 +4,7 @@ pub mod swim; // Reexports pub use self::{idle::IdleAnimation, swim::SwimAnimation}; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -30,7 +30,9 @@ impl Skeleton for FishSmallSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(1.0 / 13.0); let chest_mat = base_mat * Mat4::::from(self.chest); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ @@ -39,7 +41,17 @@ impl Skeleton for FishSmallSkeleton { make_bone(chest_mat * Mat4::::from(self.fin_l)), make_bone(chest_mat * Mat4::::from(self.fin_r)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::FishSmall(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/fish_small/swim.rs b/voxygen/anim/src/fish_small/swim.rs index 8f1d94fe85..68f975519a 100644 --- a/voxygen/anim/src/fish_small/swim.rs +++ b/voxygen/anim/src/fish_small/swim.rs @@ -45,9 +45,7 @@ impl Animation for SwimAnimation { let vel = (velocity.magnitude()).min(s_a.amplitude); let slowvel = vel * 0.1; - next.chest.scale = Vec3::one() / 13.0; - - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) / 13.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_x(velocity.z.abs() * -0.005 + x_tilt) * Quaternion::rotation_z(fast * -0.1); diff --git a/voxygen/anim/src/fixture/mod.rs b/voxygen/anim/src/fixture/mod.rs index edc2c38d80..26f310ae2a 100644 --- a/voxygen/anim/src/fixture/mod.rs +++ b/voxygen/anim/src/fixture/mod.rs @@ -1,4 +1,4 @@ -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; pub type Body = (); @@ -31,9 +31,13 @@ impl Skeleton for FixtureSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + (): Self::Body, + ) -> Offsets { buf[0] = make_bone(base_mat); - Vec3::default() + Offsets { + lantern: Vec3::default(), + mount_bone: Transform::default(), + } } } diff --git a/voxygen/anim/src/golem/alpha.rs b/voxygen/anim/src/golem/alpha.rs index d6a9241161..b0c5e6eb37 100644 --- a/voxygen/anim/src/golem/alpha.rs +++ b/voxygen/anim/src/golem/alpha.rs @@ -79,7 +79,7 @@ impl Animation for AlphaAnimation { next.hand_r.orientation = Quaternion::rotation_y(0.0) * Quaternion::rotation_x(move1 * -1.0 + move2 * 1.8); }; - next.torso.position = Vec3::new(0.0, move1 * 0.7, move1 * -0.3); + next.torso.position = Vec3::new(0.0, move1 * 3.7, move1 * -1.6); next } } diff --git a/voxygen/anim/src/golem/idle.rs b/voxygen/anim/src/golem/idle.rs index 4bf88aa388..e9f70945b0 100644 --- a/voxygen/anim/src/golem/idle.rs +++ b/voxygen/anim/src/golem/idle.rs @@ -41,7 +41,6 @@ impl Animation for IdleAnimation { ); next.head.scale = Vec3::one() * 1.02; next.jaw.scale = Vec3::one() * 1.02; - next.upper_torso.scale = Vec3::one() * s_a.scaler / 8.0; next.hand_l.scale = Vec3::one() * 1.04; next.hand_r.scale = Vec3::one() * 1.04; next.leg_l.scale = Vec3::one() * 1.02; @@ -56,7 +55,7 @@ impl Animation for IdleAnimation { next.jaw.orientation = Quaternion::rotation_x(-0.1 + breathe * 0.1); next.upper_torso.position = - Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1 + breathe * 0.5) * s_a.scaler / 8.0; + Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1 + breathe * 0.5); next.lower_torso.position = Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1 + breathe * -0.2); diff --git a/voxygen/anim/src/golem/mod.rs b/voxygen/anim/src/golem/mod.rs index ef5acd9057..6383dee947 100644 --- a/voxygen/anim/src/golem/mod.rs +++ b/voxygen/anim/src/golem/mod.rs @@ -12,7 +12,7 @@ pub use self::{ shockwave::ShockwaveAnimation, shoot::ShootAnimation, spinmelee::SpinMeleeAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -47,7 +47,10 @@ impl Skeleton for GolemSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 8.0); + let torso_mat = base_mat * Mat4::::from(self.torso); let upper_torso_mat = torso_mat * Mat4::::from(self.upper_torso); let lower_torso_mat = upper_torso_mat * Mat4::::from(self.lower_torso); @@ -70,7 +73,17 @@ impl Skeleton for GolemSkeleton { make_bone(leg_l_mat * Mat4::::from(self.foot_l)), make_bone(leg_r_mat * Mat4::::from(self.foot_r)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::Golem(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/golem/run.rs b/voxygen/anim/src/golem/run.rs index d9f0fe504a..7f5f63f287 100644 --- a/voxygen/anim/src/golem/run.rs +++ b/voxygen/anim/src/golem/run.rs @@ -67,7 +67,6 @@ impl Animation for RunAnimation { next.head.scale = Vec3::one() * 1.02; next.jaw.scale = Vec3::one() * 1.02; - next.upper_torso.scale = Vec3::one() * s_a.scaler / 8.0; next.hand_l.scale = Vec3::one() * 1.04; next.hand_r.scale = Vec3::one() * 1.04; next.leg_l.scale = Vec3::one() * 1.02; @@ -80,7 +79,7 @@ impl Animation for RunAnimation { next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1) * 1.02; next.upper_torso.position = - Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1 + short * 1.0) * s_a.scaler / 8.0; + Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1 + short * 1.0); next.upper_torso.orientation = Quaternion::rotation_z(tilt * -4.0 + short * 0.40); next.lower_torso.position = Vec3::new(0.0, s_a.lower_torso.0, s_a.lower_torso.1); diff --git a/voxygen/anim/src/golem/shockwave.rs b/voxygen/anim/src/golem/shockwave.rs index bd7ea583ff..47efe596cc 100644 --- a/voxygen/anim/src/golem/shockwave.rs +++ b/voxygen/anim/src/golem/shockwave.rs @@ -40,7 +40,7 @@ impl Animation for ShockwaveAnimation { next.head.orientation = Quaternion::rotation_z(move1 * -PI); next.upper_torso.position = - Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1 + move2 * -5.0) * s_a.scaler / 8.0; + Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1 + move2 * -5.0); next.upper_torso.orientation = Quaternion::rotation_z(move1 * -PI); next.lower_torso.position = diff --git a/voxygen/anim/src/golem/spinmelee.rs b/voxygen/anim/src/golem/spinmelee.rs index b551bd8490..aef2b59288 100644 --- a/voxygen/anim/src/golem/spinmelee.rs +++ b/voxygen/anim/src/golem/spinmelee.rs @@ -37,8 +37,7 @@ impl Animation for SpinMeleeAnimation { next.head.orientation = Quaternion::rotation_z(movement2 * -2.0 * PI) * Quaternion::rotation_x(-0.2); - next.upper_torso.position = - Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1) * s_a.scaler / 8.0; + next.upper_torso.position = Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1); next.upper_torso.orientation = Quaternion::rotation_z(movement2 * 2.0 * PI); next.lower_torso.position = diff --git a/voxygen/anim/src/lib.rs b/voxygen/anim/src/lib.rs index ab9d933338..4077a42807 100644 --- a/voxygen/anim/src/lib.rs +++ b/voxygen/anim/src/lib.rs @@ -98,6 +98,12 @@ lazy_static! { #[cfg(feature = "use-dyn-lib")] pub fn init() { lazy_static::initialize(&LIB); } +// Offsets that will be returned after computing the skeleton matrices +pub struct Offsets { + pub lantern: Vec3, + pub mount_bone: Transform, +} + pub trait Skeleton: Send + Sync + 'static { type Attr; type Body; @@ -111,17 +117,19 @@ pub trait Skeleton: Send + Sync + 'static { &self, base_mat: Mat4, buf: &mut [FigureBoneData; MAX_BONE_COUNT], - ) -> Vec3; + body: Self::Body, + ) -> Offsets; } pub fn compute_matrices( skeleton: &S, base_mat: Mat4, buf: &mut [FigureBoneData; MAX_BONE_COUNT], -) -> Vec3 { + body: S::Body, +) -> Offsets { #[cfg(not(feature = "use-dyn-lib"))] { - S::compute_matrices_inner(skeleton, base_mat, buf) + S::compute_matrices_inner(skeleton, base_mat, buf, body) } #[cfg(feature = "use-dyn-lib")] { @@ -130,7 +138,7 @@ pub fn compute_matrices( #[allow(clippy::type_complexity)] let compute_fn: voxygen_dynlib::Symbol< - fn(&S, Mat4, &mut [FigureBoneData; MAX_BONE_COUNT]) -> Vec3, + fn(&S, Mat4, &mut [FigureBoneData; MAX_BONE_COUNT], S::Body) -> Offsets, > = unsafe { lib.get(S::COMPUTE_FN) }.unwrap_or_else(|e| { panic!( "Trying to use: {} but had error: {:?}", @@ -142,7 +150,7 @@ pub fn compute_matrices( ) }); - compute_fn(skeleton, base_mat, buf) + compute_fn(skeleton, base_mat, buf, body) } } diff --git a/voxygen/anim/src/object/beam.rs b/voxygen/anim/src/object/beam.rs index ae81972718..df3a77bf54 100644 --- a/voxygen/anim/src/object/beam.rs +++ b/voxygen/anim/src/object/beam.rs @@ -33,10 +33,10 @@ impl Animation for BeamAnimation { let mut next = (*skeleton).clone(); - next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0; + next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); next.bone0.orientation = Quaternion::rotation_z(0.0); - next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0; + next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2); next.bone1.orientation = Quaternion::rotation_z(0.0); next diff --git a/voxygen/anim/src/object/idle.rs b/voxygen/anim/src/object/idle.rs index 1684db73a8..8a824993c3 100644 --- a/voxygen/anim/src/object/idle.rs +++ b/voxygen/anim/src/object/idle.rs @@ -23,9 +23,9 @@ impl Animation for IdleAnimation { ) -> Self::Skeleton { let mut next = (*skeleton).clone(); - next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0; + next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); - next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0; + next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2); next } diff --git a/voxygen/anim/src/object/mod.rs b/voxygen/anim/src/object/mod.rs index 7a58390ed0..8e0aff9997 100644 --- a/voxygen/anim/src/object/mod.rs +++ b/voxygen/anim/src/object/mod.rs @@ -5,7 +5,7 @@ pub mod shoot; // Reexports pub use self::{beam::BeamAnimation, idle::IdleAnimation, shoot::ShootAnimation}; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -29,14 +29,27 @@ impl Skeleton for ObjectSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { - let bone0_mat = base_mat * Mat4::::from(self.bone0); + body: Self::Body, + ) -> Offsets { + let scale_mat = Mat4::scaling_3d(1.0 / 11.0); + + let bone0_mat = base_mat * scale_mat * Mat4::::from(self.bone0); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ - make_bone(bone0_mat * Mat4::scaling_3d(1.0 / 11.0)), - make_bone(Mat4::::from(self.bone1) * Mat4::scaling_3d(1.0 / 11.0)), /* Decorellated from ori */ + make_bone(bone0_mat), + make_bone(scale_mat * Mat4::::from(self.bone1)), /* Decorellated from ori */ ]; - Vec3::unit_z() * 0.5 + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::Object(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/object/shoot.rs b/voxygen/anim/src/object/shoot.rs index 9d74848a65..f3375a02db 100644 --- a/voxygen/anim/src/object/shoot.rs +++ b/voxygen/anim/src/object/shoot.rs @@ -40,17 +40,17 @@ impl Animation for ShootAnimation { _ => (0.0, 0.0, 0.0), }; - next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0; - next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0; + next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); + next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2); #[allow(clippy::single_match)] match body { Body::Crossbow => { - next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0; + next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); next.bone0.orientation = Quaternion::rotation_x(movement1 * 0.05 + movement2 * 0.1) * (1.0 - movement3); - next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0; + next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2); next.bone1.orientation = Quaternion::rotation_z(0.0); }, _ => {}, diff --git a/voxygen/anim/src/quadruped_low/idle.rs b/voxygen/anim/src/quadruped_low/idle.rs index c0601d27d4..bf08a98e39 100644 --- a/voxygen/anim/src/quadruped_low/idle.rs +++ b/voxygen/anim/src/quadruped_low/idle.rs @@ -40,7 +40,6 @@ impl Animation for IdleAnimation { * 0.1, ); next.jaw.scale = Vec3::one() * 0.98; - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; next.tail_front.scale = Vec3::one() * 0.98; next.tail_rear.scale = Vec3::one() * 0.98; @@ -57,7 +56,7 @@ impl Animation for IdleAnimation { next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); next.jaw.orientation = Quaternion::rotation_x(slow * 0.05 - 0.05); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_y(slow * 0.03); next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1); diff --git a/voxygen/anim/src/quadruped_low/jump.rs b/voxygen/anim/src/quadruped_low/jump.rs index faf2c80c2e..715eb7fb42 100644 --- a/voxygen/anim/src/quadruped_low/jump.rs +++ b/voxygen/anim/src/quadruped_low/jump.rs @@ -23,7 +23,6 @@ impl Animation for JumpAnimation { let mut next = (*skeleton).clone(); next.jaw.scale = Vec3::one() * 0.98; - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; next.tail_front.scale = Vec3::one() * 0.98; next.tail_rear.scale = Vec3::one() * 0.98; @@ -33,7 +32,7 @@ impl Animation for JumpAnimation { next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1); diff --git a/voxygen/anim/src/quadruped_low/mod.rs b/voxygen/anim/src/quadruped_low/mod.rs index a9971df988..8324f102a8 100644 --- a/voxygen/anim/src/quadruped_low/mod.rs +++ b/voxygen/anim/src/quadruped_low/mod.rs @@ -16,7 +16,7 @@ pub use self::{ stunned::StunnedAnimation, tailwhip::TailwhipAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -48,7 +48,10 @@ impl Skeleton for QuadrupedLowSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0); + let chest_mat = base_mat * Mat4::::from(self.chest); let tail_front = chest_mat * Mat4::::from(self.tail_front); let head_lower_mat = chest_mat * Mat4::::from(self.head_lower); @@ -66,7 +69,17 @@ impl Skeleton for QuadrupedLowSkeleton { make_bone(chest_mat * Mat4::::from(self.foot_bl)), make_bone(chest_mat * Mat4::::from(self.foot_br)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::QuadrupedLow(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/quadruped_low/run.rs b/voxygen/anim/src/quadruped_low/run.rs index e70620e5b4..2d4fc85463 100644 --- a/voxygen/anim/src/quadruped_low/run.rs +++ b/voxygen/anim/src/quadruped_low/run.rs @@ -75,7 +75,6 @@ impl Animation for RunAnimation { } * 1.3; next.jaw.scale = Vec3::one() * 0.98; - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; next.tail_front.scale = Vec3::one() * 0.98; next.tail_rear.scale = Vec3::one() * 0.98; @@ -107,7 +106,7 @@ impl Animation for RunAnimation { * Quaternion::rotation_y(shortalt * 0.08) * Quaternion::rotation_x(-0.04 + x_tilt * 0.5); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_z(short * 0.13 + tilt * -1.9) * Quaternion::rotation_y(short * 0.12 + tilt * 0.7) * Quaternion::rotation_x(x_tilt + s_a.lean.0); diff --git a/voxygen/anim/src/quadruped_low/shoot.rs b/voxygen/anim/src/quadruped_low/shoot.rs index 3348541285..9f43cc2463 100644 --- a/voxygen/anim/src/quadruped_low/shoot.rs +++ b/voxygen/anim/src/quadruped_low/shoot.rs @@ -44,7 +44,7 @@ impl Animation for ShootAnimation { next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); next.jaw.orientation = Quaternion::rotation_x(movement1 * -0.5); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_x(0.0); next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1); diff --git a/voxygen/anim/src/quadruped_medium/alpha.rs b/voxygen/anim/src/quadruped_medium/alpha.rs index 65de540295..62c920a8fc 100644 --- a/voxygen/anim/src/quadruped_medium/alpha.rs +++ b/voxygen/anim/src/quadruped_medium/alpha.rs @@ -59,8 +59,7 @@ impl Animation for AlphaAnimation { 0.0, s_a.torso_front.0 + movement1abs * -4.0, s_a.torso_front.1, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_y(movement1 * -0.25 * movement2 * 0.25) * Quaternion::rotation_z(movement1 * 0.35 + movement2 * -0.45); diff --git a/voxygen/anim/src/quadruped_medium/beta.rs b/voxygen/anim/src/quadruped_medium/beta.rs index 94d4e761b7..9ab747861c 100644 --- a/voxygen/anim/src/quadruped_medium/beta.rs +++ b/voxygen/anim/src/quadruped_medium/beta.rs @@ -59,8 +59,7 @@ impl Animation for BetaAnimation { 0.0, s_a.torso_front.0 + movement1abs * -4.0, s_a.torso_front.1, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_y(movement1 * -0.25 * movement2 * 0.25) * Quaternion::rotation_z(movement1 * 0.35 + movement2 * -0.45); diff --git a/voxygen/anim/src/quadruped_medium/feed.rs b/voxygen/anim/src/quadruped_medium/feed.rs index c5b608b945..d49c74aa30 100644 --- a/voxygen/anim/src/quadruped_medium/feed.rs +++ b/voxygen/anim/src/quadruped_medium/feed.rs @@ -79,8 +79,7 @@ impl Animation for FeedAnimation { 0.0, s_a.torso_front.0, s_a.torso_front.1 + slower * 0.3 + transition * -6.0, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_x(transition * -0.7) * Quaternion::rotation_y(slow * 0.02); diff --git a/voxygen/anim/src/quadruped_medium/hoof.rs b/voxygen/anim/src/quadruped_medium/hoof.rs index 7adf0c9403..a48a2dbc06 100644 --- a/voxygen/anim/src/quadruped_medium/hoof.rs +++ b/voxygen/anim/src/quadruped_medium/hoof.rs @@ -57,8 +57,7 @@ impl Animation for HoofAnimation { 0.0, s_a.torso_front.0 + movement1abs * -6.0, s_a.torso_front.1 + movement1abs * 9.0, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_x(movement1abs * 1.2); next.torso_back.orientation = Quaternion::rotation_x(movement1abs * -0.8); diff --git a/voxygen/anim/src/quadruped_medium/idle.rs b/voxygen/anim/src/quadruped_medium/idle.rs index 12d954cda9..1fa199b00c 100644 --- a/voxygen/anim/src/quadruped_medium/idle.rs +++ b/voxygen/anim/src/quadruped_medium/idle.rs @@ -53,7 +53,6 @@ impl Animation for IdleAnimation { next.neck.scale = Vec3::one() * 1.02; next.jaw.scale = Vec3::one() * 1.02; - next.torso_front.scale = Vec3::one() * s_a.scaler / 11.0; next.leg_fl.scale = Vec3::one() * 1.02; next.leg_fr.scale = Vec3::one() * 1.02; next.leg_bl.scale = Vec3::one() * 1.02; @@ -79,7 +78,7 @@ impl Animation for IdleAnimation { Quaternion::rotation_z(0.0 + slow * 0.2 + tailmove.x) * Quaternion::rotation_x(0.0); next.torso_front.position = - Vec3::new(0.0, s_a.torso_front.0, s_a.torso_front.1 + slower * 0.3) * s_a.scaler / 11.0; + Vec3::new(0.0, s_a.torso_front.0, s_a.torso_front.1 + slower * 0.3); next.torso_front.orientation = Quaternion::rotation_y(slow * 0.02); next.torso_back.position = diff --git a/voxygen/anim/src/quadruped_medium/jump.rs b/voxygen/anim/src/quadruped_medium/jump.rs index d03ca09a69..850bdc5dd8 100644 --- a/voxygen/anim/src/quadruped_medium/jump.rs +++ b/voxygen/anim/src/quadruped_medium/jump.rs @@ -24,7 +24,6 @@ impl Animation for JumpAnimation { next.neck.scale = Vec3::one() * 1.02; next.jaw.scale = Vec3::one() * 1.02; - next.torso_front.scale = Vec3::one() * s_a.scaler / 11.0; next.leg_fl.scale = Vec3::one() * 1.02; next.leg_fr.scale = Vec3::one() * 1.02; next.leg_bl.scale = Vec3::one() * 1.02; @@ -44,8 +43,7 @@ impl Animation for JumpAnimation { next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1); - next.torso_front.position = - Vec3::new(0.0, s_a.torso_front.0, s_a.torso_front.1) * s_a.scaler / 11.0; + next.torso_front.position = Vec3::new(0.0, s_a.torso_front.0, s_a.torso_front.1); next.torso_front.orientation = Quaternion::rotation_y(0.0); next.torso_back.position = Vec3::new(0.0, s_a.torso_back.0, s_a.torso_back.1); diff --git a/voxygen/anim/src/quadruped_medium/leapmelee.rs b/voxygen/anim/src/quadruped_medium/leapmelee.rs index 9af1ddfcd9..2b284869c6 100644 --- a/voxygen/anim/src/quadruped_medium/leapmelee.rs +++ b/voxygen/anim/src/quadruped_medium/leapmelee.rs @@ -56,8 +56,7 @@ impl Animation for LeapMeleeAnimation { 0.0, s_a.torso_front.0 + movement1abs * -4.0, s_a.torso_front.1, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_x(movement1abs * 0.3 + movement2abs * -0.3 + movement3abs * 0.3) * Quaternion::rotation_y(twitch1abs * -0.1); diff --git a/voxygen/anim/src/quadruped_medium/mod.rs b/voxygen/anim/src/quadruped_medium/mod.rs index 96cdd6a2ac..0421678fd5 100644 --- a/voxygen/anim/src/quadruped_medium/mod.rs +++ b/voxygen/anim/src/quadruped_medium/mod.rs @@ -16,7 +16,7 @@ pub use self::{ run::RunAnimation, stunned::StunnedAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -38,6 +38,7 @@ skeleton_impls!(struct QuadrupedMediumSkeleton { + foot_fr, + foot_bl, + foot_br, + mount, }); impl Skeleton for QuadrupedMediumSkeleton { @@ -53,7 +54,10 @@ impl Skeleton for QuadrupedMediumSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0); + let torso_front_mat = base_mat * Mat4::::from(self.torso_front); let torso_back_mat = torso_front_mat * Mat4::::from(self.torso_back); let neck_mat = torso_front_mat * Mat4::::from(self.neck); @@ -80,7 +84,32 @@ impl Skeleton for QuadrupedMediumSkeleton { make_bone(leg_bl_mat * Mat4::::from(self.foot_bl)), make_bone(leg_br_mat * Mat4::::from(self.foot_br)), ]; - Vec3::default() + + use comp::quadruped_medium::Species::*; + let (mount_bone_mat, mount_bone_ori) = match (body.species, body.body_type) { + (Mammoth, _) => ( + head_mat, + self.torso_front.orientation * self.neck.orientation * self.head.orientation, + ), + _ => (torso_front_mat, self.torso_front.orientation), + }; + // Offset from the mounted bone's origin. + // Note: This could be its own bone if we need to animate it independently. + let mount_position = (mount_bone_mat * Vec4::from_point(mount_point(&body))) + .homogenized() + .xyz(); + // NOTE: We apply the ori from base_mat externally so we don't need to worry + // about it here for now. + let mount_orientation = mount_bone_ori; + + Offsets { + lantern: Vec3::default(), + mount_bone: Transform { + position: mount_position, + orientation: mount_orientation, + scale: Vec3::one(), + }, + } } } @@ -152,7 +181,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Frostfang, _) => (1.0, -2.0), (Mouflon, _) => (0.5, 1.5), (Catoblepas, _) => (-1.0, -6.5), - (Bonerattler, _) => (1.0, 2.5), + (Bonerattler, _) => (0.0, 1.5), (Deer, Male) => (1.5, 3.5), (Deer, Female) => (1.5, 3.5), (Hirdrasil, _) => (0.0, 5.0), @@ -191,7 +220,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Frostfang, _) => (0.5, 1.5), (Mouflon, _) => (-1.0, 1.0), (Catoblepas, _) => (19.5, -2.0), - (Bonerattler, _) => (9.0, -0.5), + (Bonerattler, _) => (7.0, -0.5), (Deer, _) => (-2.5, 1.0), (Hirdrasil, _) => (-1.0, 0.5), (Roshwalr, _) => (0.0, 1.0), @@ -303,7 +332,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Frostfang, _) => (9.0, 11.5), (Mouflon, _) => (11.0, 14.0), (Catoblepas, _) => (7.5, 19.5), - (Bonerattler, _) => (6.0, 12.5), + (Bonerattler, _) => (6.0, 11.0), (Deer, _) => (11.0, 13.5), (Hirdrasil, _) => (11.0, 14.5), (Roshwalr, _) => (6.0, 12.5), @@ -415,7 +444,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Frostfang, _) => (5.5, -5.5, -2.0), (Mouflon, _) => (4.0, -5.0, -4.0), (Catoblepas, _) => (7.0, 2.0, -5.0), - (Bonerattler, _) => (5.5, 5.0, -4.0), + (Bonerattler, _) => (5.5, 5.0, -2.5), (Deer, _) => (3.5, -4.5, -3.5), (Hirdrasil, _) => (4.5, -5.0, -2.5), (Roshwalr, _) => (8.0, -2.5, -2.5), @@ -452,7 +481,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Frostfang, _) => (3.5, -4.5, -2.0), (Mouflon, _) => (3.5, -8.0, -3.5), (Catoblepas, _) => (6.0, -2.5, -2.5), - (Bonerattler, _) => (6.0, -8.0, -4.0), + (Bonerattler, _) => (6.0, -8.0, -2.5), (Deer, _) => (3.0, -6.5, -3.5), (Hirdrasil, _) => (4.0, -6.5, -3.0), (Roshwalr, _) => (7.0, -7.0, -2.5), @@ -655,3 +684,45 @@ impl<'a> From<&'a Body> for SkeletonAttr { } } } + +fn mount_point(body: &Body) -> Vec3 { + use comp::quadruped_medium::{BodyType::*, Species::*}; + match (body.species, body.body_type) { + (Grolgar, _) => (0.0, -6.0, 6.0), + (Saber, _) => (0.0, -12.0, 4.0), + (Tuskram, _) => (0.0, -17.0, 2.0), + (Lion, _) => (0.0, -8.0, 4.0), + (Tarasque, _) => (0.0, -6.0, 4.0), + (Tiger, _) => (0.0, -8.0, 4.0), + (Wolf, _) => (0.0, -7.0, 3.0), + (Frostfang, _) => (0.0, -3.0, 4.0), + (Mouflon, _) => (0.0, -8.0, 2.0), + (Catoblepas, _) => (0.0, -8.0, 2.0), + (Bonerattler, _) => (0.0, -1.0, 4.0), + (Deer, _) => (0.0, -9.0, 3.0), + (Hirdrasil, _) => (0.0, -11.0, 3.0), + (Roshwalr, _) => (0.0, -1.0, 7.0), + (Donkey, _) => (0.0, -5.0, 2.0), + (Camel, _) => (0.0, -13.0, 5.0), + (Zebra, _) => (0.0, -6.0, 3.0), + (Antelope, _) => (0.0, -8.0, 3.0), + (Kelpie, _) => (0.0, -6.0, 3.0), + (Horse, _) => (0.0, -8.0, 3.0), + (Barghest, _) => (0.0, -8.0, 5.0), + (Cattle, Male) => (0.0, -3.0, 8.0), + (Cattle, Female) => (0.0, -2.0, 6.0), + (Darkhound, _) => (0.0, -2.0, 3.0), + (Highland, _) => (0.0, -3.0, 8.0), + (Yak, _) => (0.0, -8.0, 9.0), + (Panda, _) => (0.0, -10.0, 5.0), + (Bear, _) => (0.0, -11.0, 6.0), + (Dreadhorn, _) => (0.0, 0.0, 10.0), + (Moose, _) => (0.0, -9.0, 6.0), + (Snowleopard, _) => (0.0, -9.0, 4.0), + (Mammoth, _) => (0.0, 5.0, 8.0), + (Ngoubou, _) => (0.0, -7.0, 6.0), + (Llama, _) => (0.0, -6.0, 5.0), + (Alpaca, _) => (0.0, -9.0, 3.0), + } + .into() +} diff --git a/voxygen/anim/src/quadruped_medium/run.rs b/voxygen/anim/src/quadruped_medium/run.rs index 60c663ce2c..041f2cd4f0 100644 --- a/voxygen/anim/src/quadruped_medium/run.rs +++ b/voxygen/anim/src/quadruped_medium/run.rs @@ -91,7 +91,6 @@ impl Animation for RunAnimation { next.neck.scale = Vec3::one() * 1.02; next.jaw.scale = Vec3::one() * 1.02; - next.torso_front.scale = Vec3::one() * s_a.scaler / 11.0; next.leg_fl.scale = Vec3::one() * 1.02; next.leg_fr.scale = Vec3::one() * 1.02; next.leg_bl.scale = Vec3::one() * 1.02; @@ -129,8 +128,7 @@ impl Animation for RunAnimation { + canceler * 1.0 + canceler * shortalt * 2.5 * s_a.spring + x_tilt * 10.0 * canceler, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_x( ((amplitude * (short * -0.13).max(-0.2)) * s_a.spring).min(0.1) + x_tilt * (canceler * 6.0).min(1.0), diff --git a/voxygen/anim/src/quadruped_medium/stunned.rs b/voxygen/anim/src/quadruped_medium/stunned.rs index 1e51088e68..45c24f5d2a 100644 --- a/voxygen/anim/src/quadruped_medium/stunned.rs +++ b/voxygen/anim/src/quadruped_medium/stunned.rs @@ -52,8 +52,7 @@ impl Animation for StunnedAnimation { 0.0, s_a.torso_front.0 + movement1abs * -4.0, s_a.torso_front.1, - ) * s_a.scaler - / 11.0; + ); next.torso_front.orientation = Quaternion::rotation_y(0.0) * Quaternion::rotation_z(movement1 * 0.15); diff --git a/voxygen/anim/src/quadruped_small/feed.rs b/voxygen/anim/src/quadruped_small/feed.rs index f4588c78e5..f2e2b6312f 100644 --- a/voxygen/anim/src/quadruped_small/feed.rs +++ b/voxygen/anim/src/quadruped_small/feed.rs @@ -40,13 +40,12 @@ impl Animation for FeedAnimation { .sin() * 0.5, ); - next.chest.scale = Vec3::one() / 11.0 * s_a.scaler; next.head.position = Vec3::new(0.0, s_a.head.0 + 1.5, s_a.head.1 + slow * 0.2); next.head.orientation = Quaternion::rotation_z(head_look.y) * Quaternion::rotation_x(slow * 0.05 + quick * 0.08 - 0.4 * s_a.feed); - next.chest.position = Vec3::new(slow * 0.02, s_a.chest.0, s_a.chest.1) / 11.0 * s_a.scaler; + next.chest.position = Vec3::new(slow * 0.02, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_x(-0.35 * s_a.feed) * Quaternion::rotation_y(head_look.y * 0.1); diff --git a/voxygen/anim/src/quadruped_small/idle.rs b/voxygen/anim/src/quadruped_small/idle.rs index 88c9d34de5..ef69d55d4a 100644 --- a/voxygen/anim/src/quadruped_small/idle.rs +++ b/voxygen/anim/src/quadruped_small/idle.rs @@ -44,9 +44,8 @@ impl Animation for IdleAnimation { next.head.orientation = Quaternion::rotation_z(head_look.x) * Quaternion::rotation_x(head_look.y + slow_alt * 0.03); - next.chest.position = Vec3::new(slow * 0.05, s_a.chest.0, s_a.chest.1) / 11.0 * s_a.scaler; + next.chest.position = Vec3::new(slow * 0.05, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_y(slow * 0.05); - next.chest.scale = Vec3::one() / 11.0 * s_a.scaler; next.leg_fl.position = Vec3::new(-s_a.feet_f.0, s_a.feet_f.1, s_a.feet_f.2 + slow * -0.2); next.leg_fl.orientation = diff --git a/voxygen/anim/src/quadruped_small/jump.rs b/voxygen/anim/src/quadruped_small/jump.rs index 9647b52007..e5bc7e9729 100644 --- a/voxygen/anim/src/quadruped_small/jump.rs +++ b/voxygen/anim/src/quadruped_small/jump.rs @@ -24,9 +24,8 @@ impl Animation for JumpAnimation { next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); - next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) * s_a.scaler / 11.0; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1); next.chest.orientation = Quaternion::rotation_y(0.0); - next.chest.scale = Vec3::one() * s_a.scaler / 11.0; next.leg_fl.position = Vec3::new(-s_a.feet_f.0, s_a.feet_f.1, s_a.feet_f.2); next.leg_fl.orientation = Quaternion::rotation_x(0.0); diff --git a/voxygen/anim/src/quadruped_small/mod.rs b/voxygen/anim/src/quadruped_small/mod.rs index 5850882906..ea644f4de6 100644 --- a/voxygen/anim/src/quadruped_small/mod.rs +++ b/voxygen/anim/src/quadruped_small/mod.rs @@ -11,7 +11,7 @@ pub use self::{ run::RunAnimation, stunned::StunnedAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -40,8 +40,11 @@ impl Skeleton for QuadrupedSmallSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { - let chest_mat = base_mat * Mat4::::from(self.chest); + body: Self::Body, + ) -> Offsets { + let chest_mat = base_mat + * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0) + * Mat4::::from(self.chest); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ make_bone(chest_mat * Mat4::::from(self.head)), @@ -52,7 +55,17 @@ impl Skeleton for QuadrupedSmallSkeleton { make_bone(chest_mat * Mat4::::from(self.leg_br)), make_bone(chest_mat * Mat4::::from(self.tail)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::QuadrupedSmall(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/quadruped_small/run.rs b/voxygen/anim/src/quadruped_small/run.rs index 15e33f001e..d88d272391 100644 --- a/voxygen/anim/src/quadruped_small/run.rs +++ b/voxygen/anim/src/quadruped_small/run.rs @@ -70,13 +70,11 @@ impl Animation for RunAnimation { 0.0, s_a.chest.0, s_a.chest.1 + 2.0 * speednorm * s_a.spring + shortalt * 3.0 * s_a.spring, - ) / 11.0 - * s_a.scaler; + ); next.chest.orientation = Quaternion::rotation_x(vertcancel * short * 0.2 * s_a.spring + x_tilt) * Quaternion::rotation_y(tilt * 0.8) * Quaternion::rotation_z(s_a.lateral * short * 0.2 + tilt * -1.5); - next.chest.scale = Vec3::one() / 11.0 * s_a.scaler; next.leg_fl.position = Vec3::new( -s_a.feet_f.0, diff --git a/voxygen/anim/src/quadruped_small/stunned.rs b/voxygen/anim/src/quadruped_small/stunned.rs index bf2cfab502..60802f30a0 100644 --- a/voxygen/anim/src/quadruped_small/stunned.rs +++ b/voxygen/anim/src/quadruped_small/stunned.rs @@ -39,8 +39,7 @@ impl Animation for StunnedAnimation { let movement1abs = movement1base * pullback; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); - next.chest.position = - Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + movement1abs * -1.5) / 11.0 * s_a.scaler; + next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + movement1abs * -1.5); next.head.orientation = Quaternion::rotation_x(movement1abs * -0.2) * Quaternion::rotation_y(movement1 * -0.6) * Quaternion::rotation_z(movement1 * 0.4 + twitch * 0.2 * mirror); diff --git a/voxygen/anim/src/ship/idle.rs b/voxygen/anim/src/ship/idle.rs index 3375543052..d12fdf9b2d 100644 --- a/voxygen/anim/src/ship/idle.rs +++ b/voxygen/anim/src/ship/idle.rs @@ -42,15 +42,15 @@ impl Animation for IdleAnimation { } else { 0.0 } * 1.3; - next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0; + next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2); - next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0; + next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2); next.bone1.orientation = Quaternion::rotation_y(acc_vel * 0.8); - next.bone2.position = Vec3::new(s_a.bone2.0, s_a.bone2.1, s_a.bone2.2) / 11.0; + next.bone2.position = Vec3::new(s_a.bone2.0, s_a.bone2.1, s_a.bone2.2); next.bone2.orientation = Quaternion::rotation_y(-acc_vel * 0.8); - next.bone3.position = Vec3::new(s_a.bone3.0, s_a.bone3.1, s_a.bone3.2) / 11.0; + next.bone3.position = Vec3::new(s_a.bone3.0, s_a.bone3.1, s_a.bone3.2); next.bone3.orientation = Quaternion::rotation_z(tilt * 25.0); next } diff --git a/voxygen/anim/src/ship/mod.rs b/voxygen/anim/src/ship/mod.rs index 80ed5ceb05..3b75b0aaf9 100644 --- a/voxygen/anim/src/ship/mod.rs +++ b/voxygen/anim/src/ship/mod.rs @@ -3,7 +3,7 @@ pub mod idle; // Reexports pub use self::idle::IdleAnimation; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -29,16 +29,27 @@ impl Skeleton for ShipSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { - let bone0_mat = base_mat * Mat4::::from(self.bone0); + body: Self::Body, + ) -> Offsets { + let bone0_mat = base_mat * Mat4::scaling_3d(1.0 / 11.0) * Mat4::::from(self.bone0); *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ - make_bone(bone0_mat * Mat4::scaling_3d(1.0 / 11.0)), - make_bone(bone0_mat * Mat4::::from(self.bone1) * Mat4::scaling_3d(1.0 / 11.0)), /* Decorellated from ori */ - make_bone(bone0_mat * Mat4::::from(self.bone2) * Mat4::scaling_3d(1.0 / 11.0)), /* Decorellated from ori */ - make_bone(bone0_mat * Mat4::::from(self.bone3) * Mat4::scaling_3d(1.0 / 11.0)), /* Decorellated from ori */ + make_bone(bone0_mat), + make_bone(bone0_mat * Mat4::::from(self.bone1)), + make_bone(bone0_mat * Mat4::::from(self.bone2)), + make_bone(bone0_mat * Mat4::::from(self.bone3)), ]; - Vec3::unit_z() * 0.5 + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::Ship(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } diff --git a/voxygen/anim/src/theropod/idle.rs b/voxygen/anim/src/theropod/idle.rs index e91b1b895a..65b6ffbf72 100644 --- a/voxygen/anim/src/theropod/idle.rs +++ b/voxygen/anim/src/theropod/idle.rs @@ -47,7 +47,6 @@ impl Animation for IdleAnimation { next.hand_r.scale = Vec3::one() * 0.98; next.tail_front.scale = Vec3::one() * 1.02; next.tail_back.scale = Vec3::one() * 0.98; - next.chest_front.scale = Vec3::one() / s_a.scaler; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1 + breathe * 0.3); next.head.orientation = Quaternion::rotation_x(head_look.y + breathe * 0.1 - 0.1) @@ -60,7 +59,7 @@ impl Animation for IdleAnimation { next.neck.orientation = Quaternion::rotation_x(-0.1); next.chest_front.position = - Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1 + breathe * 0.3) / s_a.scaler; + Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1 + breathe * 0.3); next.chest_front.orientation = Quaternion::rotation_x(breathe * 0.04); next.chest_back.position = Vec3::new(0.0, s_a.chest_back.0, s_a.chest_back.1); diff --git a/voxygen/anim/src/theropod/jump.rs b/voxygen/anim/src/theropod/jump.rs index fde92cdc0f..2bb199434d 100644 --- a/voxygen/anim/src/theropod/jump.rs +++ b/voxygen/anim/src/theropod/jump.rs @@ -26,7 +26,6 @@ impl Animation for JumpAnimation { next.jaw.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 0.96; next.foot_r.scale = Vec3::one() * 0.96; - next.chest_front.scale = Vec3::one() / s_a.scaler; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x(-0.1); @@ -36,8 +35,7 @@ impl Animation for JumpAnimation { next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1); next.neck.orientation = Quaternion::rotation_x(-0.1); - next.chest_front.position = - Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1) / s_a.scaler; + next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1); next.chest_back.position = Vec3::new(0.0, s_a.chest_back.0, s_a.chest_back.1); diff --git a/voxygen/anim/src/theropod/mod.rs b/voxygen/anim/src/theropod/mod.rs index 900b9d7d51..9cb1bef771 100644 --- a/voxygen/anim/src/theropod/mod.rs +++ b/voxygen/anim/src/theropod/mod.rs @@ -11,7 +11,7 @@ pub use self::{ jump::JumpAnimation, run::RunAnimation, }; -use super::{make_bone, vek::*, FigureBoneData, Skeleton}; +use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; use common::comp::{self}; use core::convert::TryFrom; @@ -47,7 +47,10 @@ impl Skeleton for TheropodSkeleton { &self, base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], - ) -> Vec3 { + body: Self::Body, + ) -> Offsets { + let base_mat = base_mat * Mat4::scaling_3d(SkeletonAttr::from(&body).scaler / 11.0); + let chest_front_mat = base_mat * Mat4::::from(self.chest_front); let neck_mat = chest_front_mat * Mat4::::from(self.neck); let head_mat = neck_mat * Mat4::::from(self.head); @@ -71,7 +74,17 @@ impl Skeleton for TheropodSkeleton { make_bone(leg_l_mat * Mat4::::from(self.foot_l)), make_bone(leg_r_mat * Mat4::::from(self.foot_r)), ]; - Vec3::default() + Offsets { + lantern: Vec3::default(), + // TODO: see quadruped_medium for how to animate this + mount_bone: Transform { + position: common::comp::Body::Theropod(body) + .mountee_offset() + .into_tuple() + .into(), + ..Default::default() + }, + } } } @@ -223,14 +236,14 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Ntouka, _) => (1.5, -1.0, -2.5), }, scaler: match (body.species, body.body_type) { - (Archaeos, _) => (3.75), - (Odonto, _) => (3.75), - (Sandraptor, _) => (10.0), - (Snowraptor, _) => (10.0), - (Woodraptor, _) => (10.0), - (Sunlizard, _) => (10.0), - (Yale, _) => (8.75), - (Ntouka, _) => (3.75), + (Archaeos, _) => (2.93), + (Odonto, _) => (2.93), + (Sandraptor, _) => (1.1), + (Snowraptor, _) => (1.1), + (Woodraptor, _) => (1.1), + (Sunlizard, _) => (1.1), + (Yale, _) => (1.26), + (Ntouka, _) => (2.93), }, } } diff --git a/voxygen/anim/src/theropod/run.rs b/voxygen/anim/src/theropod/run.rs index 615bce9e03..8a5dccff6e 100644 --- a/voxygen/anim/src/theropod/run.rs +++ b/voxygen/anim/src/theropod/run.rs @@ -68,7 +68,6 @@ impl Animation for RunAnimation { next.jaw.scale = Vec3::one() * 0.98; next.foot_l.scale = Vec3::one() * 0.96; next.foot_r.scale = Vec3::one() * 0.96; - next.chest_front.scale = Vec3::one() / s_a.scaler; next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); next.head.orientation = Quaternion::rotation_x(-0.1 * speednorm + short * -0.05) @@ -87,7 +86,7 @@ impl Animation for RunAnimation { 0.0, s_a.chest_front.0, s_a.chest_front.1 + short * 0.5 + x_tilt * 10.0 + 0.5 * speednorm, - ) / s_a.scaler; + ); next.chest_front.orientation = Quaternion::rotation_x(short * 0.07 + x_tilt) * Quaternion::rotation_y(tilt * 0.8) * Quaternion::rotation_z(shortalt * 0.15 + tilt * -1.5); diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 79a5ee1304..593a74e29d 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -31,11 +31,12 @@ use common::{ inventory::slot::EquipSlot, item::{Hands, ItemKind, ToolKind}, Body, CharacterState, Controller, Health, Inventory, Item, Last, LightAnimation, - LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Vel, + LightEmitter, Mounting, Ori, PhysicsState, PoiseState, Pos, Scale, Vel, }, resources::DeltaTime, states::utils::StageSection, terrain::TerrainChunk, + uid::UidAllocator, vol::RectRasterableVol, }; use common_base::span; @@ -48,7 +49,7 @@ use core::{ }; use guillotiere::AtlasAllocator; use hashbrown::HashMap; -use specs::{Entity as EcsEntity, Join, LazyUpdate, WorldExt}; +use specs::{saveload::MarkerAllocator, Entity as EcsEntity, Join, LazyUpdate, WorldExt}; use treeculler::{BVol, BoundingSphere}; use vek::*; @@ -572,6 +573,10 @@ impl FigureMgr { let mut update_buf = [Default::default(); anim::MAX_BONE_COUNT]; + let uid_allocator = ecs.read_resource::(); + + let bodies = ecs.read_storage::(); + for ( i, ( @@ -589,6 +594,7 @@ impl FigureMgr { inventory, item, light_emitter, + mountings, ), ) in ( &ecs.entities(), @@ -605,6 +611,7 @@ impl FigureMgr { ecs.read_storage::().maybe(), ecs.read_storage::().maybe(), ecs.read_storage::().maybe(), + ecs.read_storage::().maybe(), ) .join() .enumerate() @@ -687,7 +694,7 @@ impl FigureMgr { // shadow correctly until their next update. For now, we treat this // as an acceptable tradeoff. let radius = scale.unwrap_or(&Scale(1.0)).0 * 2.0; - let (in_frustum, lpindex) = if let Some(mut meta) = state { + let (in_frustum, lpindex) = if let Some(ref mut meta) = state { let (in_frustum, lpindex) = BoundingSphere::new(pos.0.into_array(), radius) .coherent_test_against_frustum(frustum, meta.lpindex); let in_frustum = in_frustum || matches!(body, Body::Ship(_)); @@ -748,12 +755,39 @@ impl FigureMgr { let hands = (active_tool_hand, second_tool_hand); + // If a mountee exists, get its animated mounting transform and its position + let mount_transform_pos = (|| -> Option<_> { + let Mounting(entity) = mountings?; + let entity = uid_allocator.retrieve_entity_internal((*entity).into())?; + let body = *bodies.get(entity)?; + let meta = self.states.get_mut(&body, &entity)?; + Some((meta.mount_transform, meta.mount_world_pos)) + })(); + + let body = *body; + + let common_params = FigureUpdateCommonParameters { + pos: pos.0, + ori, + scale, + mount_transform_pos, + body: Some(body), + col, + dt, + _lpindex: lpindex, + _visible: in_frustum, + is_player, + _camera: camera, + terrain, + ground_vel: physics.ground_vel, + }; + match body { Body::Humanoid(body) => { let (model, skeleton_attr) = self.model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -775,7 +809,11 @@ impl FigureMgr { .character_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, CharacterSkeleton::new(holding_lantern)) + FigureState::new( + renderer, + CharacterSkeleton::new(holding_lantern), + body, + ) }); // Average velocity relative to the current ground @@ -794,62 +832,69 @@ impl FigureMgr { physics.on_ground.is_some(), rel_vel.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving physics.in_liquid().is_some(), // In water + mountings.is_some(), ) { // Standing - (true, false, false) => anim::character::StandAnimation::update_skeleton( - &CharacterSkeleton::new(holding_lantern), - ( - active_tool_kind, - second_tool_kind, - hands, - // TODO: Update to use the quaternion. - ori * anim::vek::Vec3::::unit_y(), - state.last_ori * anim::vek::Vec3::::unit_y(), - time, - rel_avg_vel, - ), - state.state_time, - &mut state_animation_rate, - skeleton_attr, - ), + (true, false, false, false) => { + anim::character::StandAnimation::update_skeleton( + &CharacterSkeleton::new(holding_lantern), + ( + active_tool_kind, + second_tool_kind, + hands, + // TODO: Update to use the quaternion. + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + time, + rel_avg_vel, + ), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, // Running - (true, true, false) => anim::character::RunAnimation::update_skeleton( - &CharacterSkeleton::new(holding_lantern), - ( - active_tool_kind, - second_tool_kind, - hands, - rel_vel, - // TODO: Update to use the quaternion. - ori * anim::vek::Vec3::::unit_y(), - state.last_ori * anim::vek::Vec3::::unit_y(), - time, - rel_avg_vel, - state.acc_vel, - ), - state.state_time, - &mut state_animation_rate, - skeleton_attr, - ), + (true, true, false, false) => { + anim::character::RunAnimation::update_skeleton( + &CharacterSkeleton::new(holding_lantern), + ( + active_tool_kind, + second_tool_kind, + hands, + rel_vel, + // TODO: Update to use the quaternion. + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + time, + rel_avg_vel, + state.acc_vel, + ), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, // In air - (false, _, false) => anim::character::JumpAnimation::update_skeleton( - &CharacterSkeleton::new(holding_lantern), - ( - active_tool_kind, - second_tool_kind, - hands, - rel_vel, - // TODO: Update to use the quaternion. - ori * anim::vek::Vec3::::unit_y(), - state.last_ori * anim::vek::Vec3::::unit_y(), - time, - ), - state.state_time, - &mut state_animation_rate, - skeleton_attr, - ), + (false, _, false, false) => { + anim::character::JumpAnimation::update_skeleton( + &CharacterSkeleton::new(holding_lantern), + ( + active_tool_kind, + second_tool_kind, + hands, + rel_vel, + // TODO: Update to use the quaternion. + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + time, + ), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, // Swim - (_, _, true) => anim::character::SwimAnimation::update_skeleton( + (_, _, true, false) => anim::character::SwimAnimation::update_skeleton( &CharacterSkeleton::new(holding_lantern), ( active_tool_kind, @@ -866,6 +911,24 @@ impl FigureMgr { &mut state_animation_rate, skeleton_attr, ), + // Mount + (_, _, _, true) => anim::character::MountAnimation::update_skeleton( + &CharacterSkeleton::new(holding_lantern), + ( + active_tool_kind, + second_tool_kind, + hands, + time, + rel_vel, + rel_avg_vel, + // TODO: Update to use the quaternion. + ori * anim::vek::Vec3::::unit_y(), + state.last_ori * anim::vek::Vec3::::unit_y(), + ), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ), }; let target_bones = match &character { CharacterState::Roll(s) => { @@ -1528,20 +1591,11 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::QuadrupedSmall(body) => { @@ -1549,7 +1603,7 @@ impl FigureMgr { self.quadruped_small_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -1562,7 +1616,7 @@ impl FigureMgr { .quadruped_small_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, QuadrupedSmallSkeleton::default()) + FigureState::new(renderer, QuadrupedSmallSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -1726,20 +1780,11 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::QuadrupedMedium(body) => { @@ -1747,7 +1792,7 @@ impl FigureMgr { self.quadruped_medium_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -1760,7 +1805,7 @@ impl FigureMgr { .quadruped_medium_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, QuadrupedMediumSkeleton::default()) + FigureState::new(renderer, QuadrupedMediumSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -2049,20 +2094,11 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::QuadrupedLow(body) => { @@ -2070,7 +2106,7 @@ impl FigureMgr { self.quadruped_low_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -2083,7 +2119,7 @@ impl FigureMgr { .quadruped_low_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, QuadrupedLowSkeleton::default()) + FigureState::new(renderer, QuadrupedLowSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -2405,27 +2441,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::BirdMedium(body) => { let (model, skeleton_attr) = self.bird_medium_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -2438,7 +2465,7 @@ impl FigureMgr { .bird_medium_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, BirdMediumSkeleton::default()) + FigureState::new(renderer, BirdMediumSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -2515,27 +2542,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::FishMedium(body) => { let (model, skeleton_attr) = self.fish_medium_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -2548,7 +2566,7 @@ impl FigureMgr { .fish_medium_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, FishMediumSkeleton::default()) + FigureState::new(renderer, FishMediumSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -2604,27 +2622,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_base, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::BipedSmall(body) => { let (model, skeleton_attr) = self.biped_small_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -2637,7 +2646,7 @@ impl FigureMgr { .biped_small_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, BipedSmallSkeleton::default()) + FigureState::new(renderer, BipedSmallSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -2948,27 +2957,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::Dragon(body) => { let (model, skeleton_attr) = self.dragon_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -2976,10 +2976,9 @@ impl FigureMgr { &slow_jobs, ); - let state = - self.states.dragon_states.entry(entity).or_insert_with(|| { - FigureState::new(renderer, DragonSkeleton::default()) - }); + let state = self.states.dragon_states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, DragonSkeleton::default(), body) + }); // Average velocity relative to the current ground let rel_avg_vel = state.avg_vel - physics.ground_vel; @@ -3042,27 +3041,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_base, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::Theropod(body) => { let (model, skeleton_attr) = self.theropod_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -3074,7 +3064,9 @@ impl FigureMgr { .states .theropod_states .entry(entity) - .or_insert_with(|| FigureState::new(renderer, TheropodSkeleton::default())); + .or_insert_with(|| { + FigureState::new(renderer, TheropodSkeleton::default(), body) + }); // Average velocity relative to the current ground let rel_avg_vel = state.avg_vel - physics.ground_vel; @@ -3225,27 +3217,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::BirdLarge(body) => { let (model, skeleton_attr) = self.bird_large_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -3258,7 +3241,7 @@ impl FigureMgr { .bird_large_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, BirdLargeSkeleton::default()) + FigureState::new(renderer, BirdLargeSkeleton::default(), body) }); let (character, last_character) = match (character, last_character) { @@ -3546,27 +3529,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::FishSmall(body) => { let (model, skeleton_attr) = self.fish_small_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -3579,7 +3553,7 @@ impl FigureMgr { .fish_small_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, FishSmallSkeleton::default()) + FigureState::new(renderer, FishSmallSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -3635,27 +3609,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_base, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::BipedLarge(body) => { let (model, skeleton_attr) = self.biped_large_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -3668,7 +3633,7 @@ impl FigureMgr { .biped_large_states .entry(entity) .or_insert_with(|| { - FigureState::new(renderer, BipedLargeSkeleton::default()) + FigureState::new(renderer, BipedLargeSkeleton::default(), body) }); // Average velocity relative to the current ground @@ -4263,27 +4228,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::Golem(body) => { let (model, skeleton_attr) = self.golem_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -4291,10 +4247,9 @@ impl FigureMgr { &slow_jobs, ); - let state = - self.states.golem_states.entry(entity).or_insert_with(|| { - FigureState::new(renderer, GolemSkeleton::default()) - }); + let state = self.states.golem_states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, GolemSkeleton::default(), body) + }); // Average velocity relative to the current ground let _rel_avg_vel = state.avg_vel - physics.ground_vel; @@ -4511,27 +4466,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - in_frustum, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::Object(body) => { let (model, skeleton_attr) = self.object_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -4539,10 +4485,9 @@ impl FigureMgr { &slow_jobs, ); - let state = - self.states.object_states.entry(entity).or_insert_with(|| { - FigureState::new(renderer, ObjectSkeleton::default()) - }); + let state = self.states.object_states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, ObjectSkeleton::default(), body) + }); // Average velocity relative to the current ground let _rel_avg_vel = state.avg_vel - physics.ground_vel; @@ -4600,7 +4545,7 @@ impl FigureMgr { active_tool_kind, second_tool_kind, Some(s.stage_section), - *body, + body, ), stage_progress, &mut state_animation_rate, @@ -4625,7 +4570,7 @@ impl FigureMgr { active_tool_kind, second_tool_kind, Some(s.stage_section), - *body, + body, ), stage_progress, &mut state_animation_rate, @@ -4639,27 +4584,18 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - true, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, Body::Ship(body) => { let (model, skeleton_attr) = self.ship_model_cache.get_or_create_model( renderer, &mut self.col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -4667,11 +4603,9 @@ impl FigureMgr { &slow_jobs, ); - let state = self - .states - .ship_states - .entry(entity) - .or_insert_with(|| FigureState::new(renderer, ShipSkeleton::default())); + let state = self.states.ship_states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, ShipSkeleton::default(), body) + }); // Average velocity relative to the current ground let _rel_avg_vel = state.avg_vel - physics.ground_vel; @@ -4732,20 +4666,11 @@ impl FigureMgr { state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp); state.update( renderer, - pos.0, - ori, - scale, - col, - dt, + &mut update_buf, + &common_params, state_animation_rate, model, - lpindex, - true, - is_player, - camera, - &mut update_buf, - terrain, - physics.ground_vel, + body, ); }, } @@ -4914,6 +4839,8 @@ impl FigureMgr { figure_lod_render_distance: f32, filter_state: impl Fn(&FigureStateMeta) -> bool, ) -> Option { + let body = *body; + let player_camera_mode = if is_player { camera.get_mode() } else { @@ -4969,7 +4896,7 @@ impl FigureMgr { state.bound(), model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -4985,7 +4912,7 @@ impl FigureMgr { state.bound(), quadruped_small_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5001,7 +4928,7 @@ impl FigureMgr { state.bound(), quadruped_medium_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5017,7 +4944,7 @@ impl FigureMgr { state.bound(), quadruped_low_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5033,7 +4960,7 @@ impl FigureMgr { state.bound(), bird_medium_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5049,7 +4976,7 @@ impl FigureMgr { state.bound(), fish_medium_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5065,7 +4992,7 @@ impl FigureMgr { state.bound(), theropod_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5081,7 +5008,7 @@ impl FigureMgr { state.bound(), dragon_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5097,7 +5024,7 @@ impl FigureMgr { state.bound(), bird_large_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5113,7 +5040,7 @@ impl FigureMgr { state.bound(), fish_small_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5129,7 +5056,7 @@ impl FigureMgr { state.bound(), biped_large_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5145,7 +5072,7 @@ impl FigureMgr { state.bound(), biped_small_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5161,7 +5088,7 @@ impl FigureMgr { state.bound(), golem_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5177,7 +5104,7 @@ impl FigureMgr { state.bound(), object_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5193,7 +5120,7 @@ impl FigureMgr { state.bound(), ship_model_cache.get_model( col_lights, - *body, + body, inventory, tick, player_camera_mode, @@ -5331,6 +5258,14 @@ impl FigureColLights { pub struct FigureStateMeta { lantern_offset: anim::vek::Vec3, + // Animation to be applied to mounter of this entity + mount_transform: anim::vek::Transform, + // Contains the position of this figure or if it is a mounter it will contain the mountee's + // mount_world_pos + // Unlike the interpolated position stored in the ecs this will be propagated along + // mount chains + // For use if it is mounted by another figure + mount_world_pos: anim::vek::Vec3, state_time: f32, last_ori: anim::vek::Quaternion, lpindex: u8, @@ -5368,15 +5303,38 @@ impl DerefMut for FigureState { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.meta } } +/// Parameters that don't depend on the body variant or animation results and +/// are also not mutable +pub struct FigureUpdateCommonParameters<'a> { + pub pos: anim::vek::Vec3, + pub ori: anim::vek::Quaternion, + pub scale: f32, + pub mount_transform_pos: Option<(anim::vek::Transform, anim::vek::Vec3)>, + pub body: Option, + pub col: vek::Rgba, + pub dt: f32, + // TODO: evaluate unused variable + pub _lpindex: u8, + // TODO: evaluate unused variable + pub _visible: bool, + pub is_player: bool, + // TODO: evaluate unused variable + pub _camera: &'a Camera, + pub terrain: Option<&'a Terrain>, + pub ground_vel: Vec3, +} + impl FigureState { - pub fn new(renderer: &mut Renderer, skeleton: S) -> Self { + pub fn new(renderer: &mut Renderer, skeleton: S, body: S::Body) -> Self { let mut buf = [Default::default(); anim::MAX_BONE_COUNT]; - let lantern_offset = - anim::compute_matrices(&skeleton, anim::vek::Mat4::identity(), &mut buf); + let offsets = + anim::compute_matrices(&skeleton, anim::vek::Mat4::identity(), &mut buf, body); let bone_consts = figure_bone_data_from_anim(&buf); Self { meta: FigureStateMeta { - lantern_offset, + lantern_offset: offsets.lantern, + mount_transform: offsets.mount_bone, + mount_world_pos: anim::vek::Vec3::zero(), state_time: 0.0, last_ori: Ori::default().into(), lpindex: 0, @@ -5393,24 +5351,31 @@ impl FigureState { } } - #[allow(clippy::too_many_arguments)] // TODO: Pending review in #587 pub fn update( &mut self, renderer: &mut Renderer, - pos: anim::vek::Vec3, - ori: anim::vek::Quaternion, - scale: f32, - col: vek::Rgba, - dt: f32, + buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT], + FigureUpdateCommonParameters { + pos, + ori, + scale, + mount_transform_pos, + body, + col, + dt, + _lpindex, + _visible, + is_player, + _camera, + terrain, + ground_vel, + }: &FigureUpdateCommonParameters, state_animation_rate: f32, model: Option<&FigureModelEntry>, - _lpindex: u8, - _visible: bool, - is_player: bool, - _camera: &Camera, - buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT], - terrain: Option<&Terrain>, - ground_vel: Vec3, + // TODO: there is the potential to drop the optional body from the common params and just + // use this one but we need to add a function to the skelton trait or something in order to + // get the mounter offset + skel_body: S::Body, ) { // NOTE: As long as update() always gets called after get_or_create_model(), and // visibility is not set again until after the model is rendered, we @@ -5438,12 +5403,38 @@ impl FigureState { /* let radius = vek::Extent3::::from(model.bounds.half_size()).reduce_partial_max(); let _bounds = BoundingSphere::new(pos.into_array(), scale * 0.8 * radius); */ - self.last_ori = vek::Lerp::lerp(self.last_ori, ori, 15.0 * dt).normalized(); + self.last_ori = vek::Lerp::lerp(self.last_ori, *ori, 15.0 * dt).normalized(); self.state_time += dt * state_animation_rate; let mat = { - anim::vek::Mat4::from(ori) * anim::vek::Mat4::scaling_3d(anim::vek::Vec3::from(scale)) + let scale_mat = anim::vek::Mat4::scaling_3d(anim::vek::Vec3::from(*scale)); + if let Some((transform, _)) = *mount_transform_pos { + // Note: if we had a way to compute a "default" transform of the bones then in + // the animations we could make use of the mountee_offset from common by + // computing what the offset of the mounter is from the mounted + // bone in its default position when the mounter has the mount + // offset in common applied to it. Since we don't have this + // right now we instead need to recreate the same effect in the + // animations and keep it in sync. + // + // Component of mounting offset specific to the mounter. + let mounter_offset = anim::vek::Mat4::::translation_3d( + body.map_or_else(Vec3::zero, |b| b.mounter_offset()), + ); + + // NOTE: It is kind of a hack to use this entity's ori here if it is + // mounted on another but this happens to match the ori of the + // mountee so it works, change this if it causes jankiness in the future. + let transform = anim::vek::Transform { + orientation: *ori * transform.orientation, + ..transform + }; + anim::vek::Mat4::from(transform) * mounter_offset * scale_mat + } else { + let ori_mat = anim::vek::Mat4::from(*ori); + ori_mat * scale_mat + } }; let atlas_offs = model.allocation.rectangle.min; @@ -5493,30 +5484,33 @@ impl FigureState { let locals = FigureLocals::new( mat, col.rgb(), - pos, + mount_transform_pos.map_or(*pos, |(_, pos)| pos), vek::Vec2::new(atlas_offs.x, atlas_offs.y), - is_player, + *is_player, self.last_light, self.last_glow, ); renderer.update_consts(&mut self.meta.bound.0, &[locals]); - let lantern_offset = anim::compute_matrices(&self.skeleton, mat, buf); + let offsets = anim::compute_matrices(&self.skeleton, mat, buf, skel_body); let new_bone_consts = figure_bone_data_from_anim(buf); renderer.update_consts(&mut self.meta.bound.1, &new_bone_consts[0..S::BONE_COUNT]); - self.lantern_offset = lantern_offset; + self.lantern_offset = offsets.lantern; + // TODO: compute the mount bone only when it is needed + self.mount_transform = offsets.mount_bone; + self.mount_world_pos = mount_transform_pos.map_or(*pos, |(_, pos)| pos); let smoothing = (5.0 * dt).min(1.0); if let Some(last_pos) = self.last_pos { - self.avg_vel = (1.0 - smoothing) * self.avg_vel + smoothing * (pos - last_pos) / dt; + self.avg_vel = (1.0 - smoothing) * self.avg_vel + smoothing * (pos - last_pos) / *dt; } - self.last_pos = Some(pos); + self.last_pos = Some(*pos); // Can potentially overflow if self.avg_vel.magnitude_squared() != 0.0 { - self.acc_vel += (self.avg_vel - ground_vel).magnitude() * dt; + self.acc_vel += (self.avg_vel - *ground_vel).magnitude() * dt; } else { self.acc_vel = 0.0; } diff --git a/voxygen/src/scene/simple.rs b/voxygen/src/scene/simple.rs index 05cfcb1925..50c923385a 100644 --- a/voxygen/src/scene/simple.rs +++ b/voxygen/src/scene/simple.rs @@ -7,7 +7,10 @@ use crate::{ }, scene::{ camera::{self, Camera, CameraMode}, - figure::{load_mesh, FigureColLights, FigureModelCache, FigureModelEntry, FigureState}, + figure::{ + load_mesh, FigureColLights, FigureModelCache, FigureModelEntry, FigureState, + FigureUpdateCommonParameters, + }, }, window::{Event, PressState}, }; @@ -68,7 +71,7 @@ pub struct Scene { col_lights: FigureColLights, backdrop: Option<(FigureModelEntry<1>, FigureState)>, figure_model_cache: FigureModelCache, - figure_state: FigureState, + figure_state: Option>, //turning_camera: bool, turning_character: bool, @@ -126,10 +129,10 @@ impl Scene { map_bounds, figure_model_cache: FigureModelCache::new(), - figure_state: FigureState::new(renderer, CharacterSkeleton::default()), + figure_state: None, backdrop: backdrop.map(|specifier| { - let mut state = FigureState::new(renderer, FixtureSkeleton::default()); + let mut state = FigureState::new(renderer, FixtureSkeleton::default(), ()); let mut greedy = FigureModel::make_greedy(); let mut opaque_mesh = Mesh::new(); let (segment, offset) = load_mesh(specifier, Vec3::new(-55.0, -49.5, -2.0)); @@ -144,26 +147,25 @@ impl Scene { col_lights .create_figure(renderer, greedy.finalize(), (opaque_mesh, bounds), [range]); let mut buf = [Default::default(); anim::MAX_BONE_COUNT]; - state.update( - renderer, - anim::vek::Vec3::zero(), - anim::vek::Quaternion::rotation_from_to_3d( + let common_params = FigureUpdateCommonParameters { + pos: anim::vek::Vec3::zero(), + ori: anim::vek::Quaternion::rotation_from_to_3d( anim::vek::Vec3::unit_y(), anim::vek::Vec3::new(start_angle.sin(), -start_angle.cos(), 0.0), ), - 1.0, - Rgba::broadcast(1.0), - 15.0, // Want to get there immediately. - 1.0, - Some(&model), - 0, - true, - false, - &camera, - &mut buf, - None, - Vec3::zero(), - ); + scale: 1.0, + mount_transform_pos: None, + body: None, + col: Rgba::broadcast(1.0), + dt: 15.0, // Want to get there immediately. + _lpindex: 0, + _visible: true, + is_player: false, + _camera: &camera, + terrain: None, + ground_vel: Vec3::zero(), + }; + state.update(renderer, &mut buf, &common_params, 1.0, Some(&model), ()); (model, state) }), col_lights, @@ -292,8 +294,11 @@ impl Scene { let hands = (active_tool_hand, second_tool_hand); if let Some(body) = scene_data.body { + let figure_state = self.figure_state.get_or_insert_with(|| { + FigureState::new(renderer, CharacterSkeleton::default(), body) + }); let tgt_skeleton = IdleAnimation::update_skeleton( - self.figure_state.skeleton_mut(), + figure_state.skeleton_mut(), ( active_tool_kind, second_tool_kind, @@ -305,8 +310,8 @@ impl Scene { &SkeletonAttr::from(&body), ); let dt_lerp = (scene_data.delta_time * 15.0).min(1.0); - *self.figure_state.skeleton_mut() = - anim::vek::Lerp::lerp(&*self.figure_state.skeleton_mut(), &tgt_skeleton, dt_lerp); + *figure_state.skeleton_mut() = + anim::vek::Lerp::lerp(&*figure_state.skeleton_mut(), &tgt_skeleton, dt_lerp); let model = self .figure_model_cache @@ -322,26 +327,26 @@ impl Scene { ) .0; let mut buf = [Default::default(); anim::MAX_BONE_COUNT]; - self.figure_state.update( - renderer, - anim::vek::Vec3::zero(), - anim::vek::Quaternion::rotation_from_to_3d( + let common_params = FigureUpdateCommonParameters { + pos: anim::vek::Vec3::zero(), + ori: anim::vek::Quaternion::rotation_from_to_3d( anim::vek::Vec3::unit_y(), anim::vek::Vec3::new(self.char_ori.sin(), -self.char_ori.cos(), 0.0), ), - 1.0, - Rgba::broadcast(1.0), - scene_data.delta_time, - 1.0, - model, - 0, - true, - false, - &self.camera, - &mut buf, - None, - Vec3::zero(), - ); + scale: 1.0, + mount_transform_pos: None, + body: None, + col: Rgba::broadcast(1.0), + dt: scene_data.delta_time, + _lpindex: 0, + _visible: true, + is_player: false, + _camera: &self.camera, + terrain: None, + ground_vel: Vec3::zero(), + }; + + figure_state.update(renderer, &mut buf, &common_params, 1.0, model, body); } } @@ -365,13 +370,9 @@ impl Scene { None, ); - if let Some(model) = model { + if let Some((model, figure_state)) = model.zip(self.figure_state.as_ref()) { if let Some(lod) = model.lod_model(0) { - figure_drawer.draw( - lod, - self.figure_state.bound(), - self.col_lights.texture(model), - ); + figure_drawer.draw(lod, figure_state.bound(), self.col_lights.texture(model)); } } }