diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 3dc58d54e8..03209dbaeb 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -1012,7 +1012,9 @@ impl Body { /// Component of the mounting offset specific to the mount pub fn mount_offset(&self) -> Vec3 { match self { - Body::Humanoid(_) => (self.dimensions() * Vec3::new(0.7, 0.0, 0.6)).into_array(), + Body::Humanoid(_) | Body::BipedLarge(_) => { + (self.dimensions() * Vec3::new(0.5, 0.0, 0.6)).into_array() + }, Body::QuadrupedMedium(quadruped_medium) => { match (quadruped_medium.species, quadruped_medium.body_type) { (quadruped_medium::Species::Grolgar, _) => [0.0, 0.5, 1.8], diff --git a/common/src/comp/pet.rs b/common/src/comp/pet.rs index 47aab87d9e..83ba6022c1 100644 --- a/common/src/comp/pet.rs +++ b/common/src/comp/pet.rs @@ -63,6 +63,7 @@ pub fn is_mountable(mount: &Body, rider: Option<&Body>) -> bool { match mount { Body::Humanoid(_) => matches!(rider, Some(Body::BirdMedium(_))), + Body::BipedLarge(_) => is_light_enough(rider), Body::QuadrupedMedium(body) => match body.species { quadruped_medium::Species::Alpaca | quadruped_medium::Species::Antelope diff --git a/voxygen/anim/src/biped_large/mod.rs b/voxygen/anim/src/biped_large/mod.rs index 9631b80597..7be0e999b1 100644 --- a/voxygen/anim/src/biped_large/mod.rs +++ b/voxygen/anim/src/biped_large/mod.rs @@ -130,16 +130,28 @@ 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)), ]; + + // Offset from the mounted bone's origin. + // Note: This could be its own bone if we need to animate it independently. + let mount_position = (arm_control_r + * Mat4::::from(self.shoulder_r) + * 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 = self.torso.orientation + * self.upper_torso.orientation + * self.arm_control_r.orientation + * self.shoulder_r.orientation; + Offsets { lantern: None, viewpoint: Some((jaw_mat * Vec4::new(0.0, 4.0, 0.0, 1.0)).xyz()), - // TODO: see quadruped_medium for how to animate this mount_bone: Transform { - position: comp::Body::BipedLarge(body) - .mount_offset() - .into_tuple() - .into(), - ..Default::default() + position: mount_position, + orientation: mount_orientation, + scale: Vec3::one(), }, primary_trail_mat: None, secondary_trail_mat: None, @@ -567,3 +579,33 @@ impl<'a> From<&'a Body> for SkeletonAttr { } } } + +fn mount_point(body: &Body) -> Vec3 { + use comp::biped_large::Species::*; + match (body.species, body.body_type) { + (Ogre, _) => (0.0, 3.0, 1.0), + (Cyclops, _) => (0.0, 3.0, 1.0), + (Wendigo, _) => (0.0, 0.0, -1.0), + (Cavetroll, _) => (0.0, 1.0, 2.0), + (Mountaintroll, _) => (0.0, 4.0, 2.0), + (Swamptroll, _) => (0.0, 0.0, 3.0), + (Dullahan, _) => (0.0, 0.0, 3.0), + (Werewolf, _) => (-1.0, 0.0, 0.0), + (Occultsaurok, _) => (0.0, 0.0, -1.0), + (Mightysaurok, _) => (0.0, 0.0, -1.0), + (Slysaurok, _) => (0.0, 0.0, -1.0), + (Mindflayer, _) => (1.0, 1.0, 1.0), + (Minotaur, _) => (0.0, 2.0, 0.0), + (Tidalwarrior, _) => (-4.5, 0.0, 5.0), + (Yeti, _) => (0.0, 2.0, 3.0), + (Harvester, _) => (0.0, 1.5, 2.0), + (Blueoni, _) => (0.0, 1.0, 3.0), + (Redoni, _) => (0.0, 1.0, 3.0), + (Cultistwarlord, _) => (-2.5, 2.0, -1.5), + (Cultistwarlock, _) => (0.0, 1.5, 1.0), + (Huskbrute, _) => (0.0, 3.0, 3.0), + (Tursus, _) => (0.0, 2.0, 3.0), + (Gigasfrost, _) => (1.0, 2.0, 4.0), + } + .into() +}