From b2bf83e2008cca3dc9a6ffdc2338c8089f9e924e Mon Sep 17 00:00:00 2001 From: Imbris Date: Sat, 26 Jun 2021 02:11:50 -0400 Subject: [PATCH] Rework mounting animation so that full hierarchies of animation transforms can be applied to the mounter, factor out some common code in figure/mod.rs --- common/src/comp/body.rs | 13 +- common/systems/src/mount.rs | 5 +- voxygen/anim/src/character/mod.rs | 76 +---- voxygen/anim/src/quadruped_medium/mod.rs | 17 +- voxygen/src/scene/figure/mod.rs | 368 +++++++++-------------- voxygen/src/scene/simple.rs | 73 ++--- 6 files changed, 205 insertions(+), 347 deletions(-) diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 8958197802..5032b622e0 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -764,8 +764,8 @@ impl Body { ) } - // Physical offset relative to the mountee - pub fn mounting_offset(&self) -> Vec3 { + /// Component of the mounting offset specific to the mountee + pub fn mountee_offset(&self) -> Vec3 { match self { Body::QuadrupedMedium(quadruped_medium) => { match (quadruped_medium.species, quadruped_medium.body_type) { @@ -819,6 +819,15 @@ impl Body { } .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() + } } impl Component for Body { diff --git a/common/systems/src/mount.rs b/common/systems/src/mount.rs index 328f0e93fb..de92936062 100644 --- a/common/systems/src/mount.rs +++ b/common/systems/src/mount.rs @@ -66,8 +66,9 @@ 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 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(Vec3 { diff --git a/voxygen/anim/src/character/mod.rs b/voxygen/anim/src/character/mod.rs index 8bcbc22a62..cd393610af 100644 --- a/voxygen/anim/src/character/mod.rs +++ b/voxygen/anim/src/character/mod.rs @@ -73,20 +73,12 @@ skeleton_impls!(struct CharacterSkeleton { control_r, :: // Begin non-bone fields holding_lantern: bool, - offsets: Option>, - mountee_body: Option, }); impl CharacterSkeleton { - pub fn new( - holding_lantern: bool, - offsets: Option>, - mountee_body: Option, - ) -> Self { + pub fn new(holding_lantern: bool) -> Self { Self { holding_lantern, - offsets, - mountee_body, ..Self::default() } } @@ -107,21 +99,7 @@ impl Skeleton for CharacterSkeleton { base_mat: Mat4, buf: &mut [FigureBoneData; super::MAX_BONE_COUNT], ) -> Offsets { - let torso_mat = base_mat - * if let Some((offset, body)) = self.offsets.zip(self.mountee_body) { - let hitbox_offsets = body.mounting_offset(); - let visual_offset = mounting_offset(body); - - Mat4::::from(Transform { - position: offset.position - - Vec3::from([0.0, hitbox_offsets.y, hitbox_offsets.z]), - orientation: offset.orientation, - scale: Vec3::::one(), - }) * Mat4::::from(self.torso).translated_3d(visual_offset) - } else { - Mat4::::from(self.torso) - }; - + 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); let shorts_mat = chest_mat * Mat4::::from(self.shorts); @@ -356,53 +334,3 @@ impl<'a> From<&'a Body> for SkeletonAttr { } } } - -pub fn mounting_offset(body: comp::Body) -> Vec3 { - match body { - comp::Body::QuadrupedMedium(quadruped_medium) => { - match (quadruped_medium.species, quadruped_medium.body_type) { - (comp::quadruped_medium::Species::Grolgar, _) => Vec3::from([0.0, -0.6, 0.5]), - (comp::quadruped_medium::Species::Saber, _) => Vec3::from([0.0, -0.75, 0.23]), - (comp::quadruped_medium::Species::Tiger, _) => Vec3::from([0.0, -0.75, 0.23]), - (comp::quadruped_medium::Species::Tuskram, _) => Vec3::from([0.0, -0.75, 0.25]), - (comp::quadruped_medium::Species::Lion, _) => Vec3::from([0.0, -0.9, 0.25]), - (comp::quadruped_medium::Species::Tarasque, _) => Vec3::from([0.0, -1.1, 0.3]), - (comp::quadruped_medium::Species::Wolf, _) => Vec3::from([0.0, -0.7, 0.15]), - (comp::quadruped_medium::Species::Frostfang, _) => Vec3::from([0.0, -0.8, 0.1]), - (comp::quadruped_medium::Species::Mouflon, _) => Vec3::from([0.0, -0.8, 0.1]), - (comp::quadruped_medium::Species::Catoblepas, _) => Vec3::from([0.0, -0.4, 0.4]), - (comp::quadruped_medium::Species::Bonerattler, _) => Vec3::from([0.0, -0.3, 0.2]), - (comp::quadruped_medium::Species::Deer, _) => Vec3::from([0.0, -0.9, 0.1]), - (comp::quadruped_medium::Species::Hirdrasil, _) => Vec3::from([0.0, -1.0, 0.0]), - (comp::quadruped_medium::Species::Roshwalr, _) => Vec3::from([0.0, -0.2, 0.7]), - (comp::quadruped_medium::Species::Donkey, _) => Vec3::from([0.0, -0.5, 0.15]), - (comp::quadruped_medium::Species::Camel, _) => Vec3::from([0.0, -1.4, 0.3]), - (comp::quadruped_medium::Species::Zebra, _) => Vec3::from([0.0, -0.6, 0.1]), - (comp::quadruped_medium::Species::Antelope, _) => Vec3::from([0.0, -0.8, 0.1]), - (comp::quadruped_medium::Species::Kelpie, _) => Vec3::from([0.0, -0.8, 0.05]), - (comp::quadruped_medium::Species::Horse, _) => Vec3::from([0.0, -0.8, 0.1]), - (comp::quadruped_medium::Species::Barghest, _) => Vec3::from([0.0, -0.8, 0.6]), - ( - comp::quadruped_medium::Species::Cattle, - comp::quadruped_medium::BodyType::Male, - ) => Vec3::from([0.0, -0.4, 0.7]), - ( - comp::quadruped_medium::Species::Cattle, - comp::quadruped_medium::BodyType::Female, - ) => Vec3::from([0.0, -0.3, 0.5]), - (comp::quadruped_medium::Species::Darkhound, _) => Vec3::from([0.0, -0.5, 0.2]), - (comp::quadruped_medium::Species::Highland, _) => Vec3::from([0.0, -0.2, 0.8]), - (comp::quadruped_medium::Species::Yak, _) => Vec3::from([0.0, -0.2, 0.8]), - (comp::quadruped_medium::Species::Panda, _) => Vec3::from([0.0, -0.8, 0.2]), - (comp::quadruped_medium::Species::Bear, _) => Vec3::from([0.0, -1.5, 0.6]), - (comp::quadruped_medium::Species::Dreadhorn, _) => Vec3::from([0.0, -1.5, 1.6]), - (comp::quadruped_medium::Species::Moose, _) => Vec3::from([0.0, -0.9, 0.3]), - (comp::quadruped_medium::Species::Snowleopard, _) => Vec3::from([0.0, -0.9, 0.2]), - } - }, - - comp::Body::Ship(comp::ship::Body::DefaultAirship) => Vec3::from([0.0, 0.0, 10.0]), - comp::Body::Dragon(_) => Vec3::from([0.0, -0.7, 6.4]), - _ => Vec3::unit_z(), - } -} diff --git a/voxygen/anim/src/quadruped_medium/mod.rs b/voxygen/anim/src/quadruped_medium/mod.rs index 865138373c..9ac7da9031 100644 --- a/voxygen/anim/src/quadruped_medium/mod.rs +++ b/voxygen/anim/src/quadruped_medium/mod.rs @@ -81,9 +81,24 @@ impl Skeleton for QuadrupedMediumSkeleton { make_bone(leg_bl_mat * Mat4::::from(self.foot_bl)), make_bone(leg_br_mat * Mat4::::from(self.foot_br)), ]; + + // Offset from the mounted bone's origin. + // Note: This could be its own bone if we need to animate it. + let mount_point = Vec3::new(0.0, -7.0, 3.0); + let mount_position = (torso_front_mat * Vec4::from_point(mount_point)) + .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_front.orientation; + Offsets { lantern: Vec3::default(), - mount_bone: self.torso_front, + mount_bone: Transform { + position: mount_position, + orientation: mount_orientation, + scale: Vec3::one(), + }, } } } diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 8294612c10..92c9a26433 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -755,15 +755,30 @@ impl FigureMgr { let hands = (active_tool_hand, second_tool_hand); - // If a mountee exists, get its physical mounting offsets and its body - let (mountee_offsets, mountee_body) = (|| -> Option<_> { + // 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((Some(meta.mountee_offset), Some(body))) - })() - .unwrap_or((None, None)); + Some((meta.mount_transform, meta.mount_world_pos)) + })(); + + 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) => { @@ -792,14 +807,7 @@ impl FigureMgr { .character_states .entry(entity) .or_insert_with(|| { - FigureState::new( - renderer, - CharacterSkeleton::new( - holding_lantern, - mountee_offsets, - mountee_body, - ), - ) + FigureState::new(renderer, CharacterSkeleton::new(holding_lantern)) }); // Average velocity relative to the current ground @@ -823,11 +831,7 @@ impl FigureMgr { // Standing (true, false, false, false) => { anim::character::StandAnimation::update_skeleton( - &CharacterSkeleton::new( - holding_lantern, - mountee_offsets, - mountee_body, - ), + &CharacterSkeleton::new(holding_lantern), ( active_tool_kind, second_tool_kind, @@ -846,11 +850,7 @@ impl FigureMgr { // Running (true, true, false, false) => { anim::character::RunAnimation::update_skeleton( - &CharacterSkeleton::new( - holding_lantern, - mountee_offsets, - mountee_body, - ), + &CharacterSkeleton::new(holding_lantern), ( active_tool_kind, second_tool_kind, @@ -871,11 +871,7 @@ impl FigureMgr { // In air (false, _, false, false) => { anim::character::JumpAnimation::update_skeleton( - &CharacterSkeleton::new( - holding_lantern, - mountee_offsets, - mountee_body, - ), + &CharacterSkeleton::new(holding_lantern), ( active_tool_kind, second_tool_kind, @@ -893,7 +889,7 @@ impl FigureMgr { }, // Swim (_, _, true, false) => anim::character::SwimAnimation::update_skeleton( - &CharacterSkeleton::new(holding_lantern, mountee_offsets, mountee_body), + &CharacterSkeleton::new(holding_lantern), ( active_tool_kind, second_tool_kind, @@ -911,7 +907,7 @@ impl FigureMgr { ), // Mount (_, _, _, true) => anim::character::MountAnimation::update_skeleton( - &CharacterSkeleton::new(holding_lantern, mountee_offsets, mountee_body), + &CharacterSkeleton::new(holding_lantern), ( active_tool_kind, second_tool_kind, @@ -1589,20 +1585,10 @@ 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::QuadrupedSmall(body) => { @@ -1787,20 +1773,10 @@ 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::QuadrupedMedium(body) => { @@ -2110,20 +2086,10 @@ 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::QuadrupedLow(body) => { @@ -2466,20 +2432,10 @@ 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::BirdMedium(body) => { @@ -2576,20 +2532,10 @@ 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::FishMedium(body) => { @@ -2665,20 +2611,10 @@ 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::BipedSmall(body) => { @@ -3009,20 +2945,10 @@ 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::Dragon(body) => { @@ -3103,20 +3029,10 @@ 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::Theropod(body) => { @@ -3286,20 +3202,10 @@ 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::BirdLarge(body) => { @@ -3607,20 +3513,10 @@ 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::FishSmall(body) => { @@ -3696,20 +3592,10 @@ 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::BipedLarge(body) => { @@ -4324,20 +4210,10 @@ 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::Golem(body) => { @@ -4572,20 +4448,10 @@ 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::Object(body) => { @@ -4700,20 +4566,10 @@ 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::Ship(body) => { @@ -4793,20 +4649,10 @@ 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, ); }, } @@ -5392,7 +5238,14 @@ impl FigureColLights { pub struct FigureStateMeta { lantern_offset: anim::vek::Vec3, - mountee_offset: anim::vek::Transform, + // 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, @@ -5430,6 +5283,27 @@ 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 { let mut buf = [Default::default(); anim::MAX_BONE_COUNT]; @@ -5438,7 +5312,8 @@ impl FigureState { Self { meta: FigureStateMeta { lantern_offset: offsets.lantern, - mountee_offset: offsets.mount_bone, + mount_transform: offsets.mount_bone, + mount_world_pos: anim::vek::Vec3::zero(), state_time: 0.0, last_ori: Ori::default().into(), lpindex: 0, @@ -5455,24 +5330,27 @@ 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, ) { // 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 @@ -5500,12 +5378,34 @@ 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 ori_scale = anim::vek::Mat4::from(*ori) + * anim::vek::Mat4::scaling_3d(anim::vek::Vec3::from(*scale)); + // 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. + 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()), + ); + + anim::vek::Mat4::from(transform) * ori_scale * mounter_offset + } else { + ori_scale + } }; let atlas_offs = model.allocation.rectangle.min; @@ -5555,9 +5455,9 @@ 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, ); @@ -5569,17 +5469,19 @@ impl FigureState { renderer.update_consts(&mut self.meta.bound.1, &new_bone_consts[0..S::BONE_COUNT]); self.lantern_offset = offsets.lantern; - self.mountee_offset = offsets.mount_bone; + // 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..df6ef56439 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}, }; @@ -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, @@ -322,26 +324,27 @@ 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(), + }; + + self.figure_state + .update(renderer, &mut buf, &common_params, 1.0, model); } }