diff --git a/voxygen/examples/character_renderer.rs b/voxygen/examples/character_renderer.rs index 3a70178704..cf0aee4f53 100644 --- a/voxygen/examples/character_renderer.rs +++ b/voxygen/examples/character_renderer.rs @@ -62,7 +62,7 @@ fn main() { scene .camera_mut() .update(0.0, 1.0 / 60.0, scene_data.mouse_smoothing); - scene.maintain(&mut renderer, scene_data); + scene.maintain(&mut renderer, scene_data, Some(&loadout)); // Render renderer.clear(); diff --git a/voxygen/src/anim/src/character/idle.rs b/voxygen/src/anim/src/character/idle.rs index 5b294b84a1..4a73cede6a 100644 --- a/voxygen/src/anim/src/character/idle.rs +++ b/voxygen/src/anim/src/character/idle.rs @@ -1,11 +1,12 @@ use super::{super::Animation, CharacterSkeleton, SkeletonAttr}; +use common::comp::item::{Hands, ToolKind}; use std::f32::consts::PI; use vek::*; pub struct IdleAnimation; impl Animation for IdleAnimation { - type Dependency = f64; + type Dependency = (Option, Option, f64); type Skeleton = CharacterSkeleton; #[cfg(feature = "use-dyn-lib")] @@ -14,7 +15,7 @@ impl Animation for IdleAnimation { #[cfg_attr(feature = "be-dyn-lib", export_name = "character_idle")] fn update_skeleton_inner( skeleton: &Self::Skeleton, - _global_time: f64, + (active_tool_kind, second_tool_kind, _global_time): Self::Dependency, anim_time: f64, _rate: &mut f32, skeleton_attr: &SkeletonAttr, @@ -105,12 +106,41 @@ impl Animation for IdleAnimation { next.glider.scale = Vec3::one() * 0.0; - next.main.offset = Vec3::new(-7.0, -5.0, 15.0); - next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); - next.main.scale = Vec3::one() + head_abs * -0.05; + match active_tool_kind { + Some(ToolKind::Dagger(_)) => { + next.main.offset = Vec3::new(-4.0, -5.0, 7.0); + next.main.ori = + Quaternion::rotation_y(0.25 * PI) * Quaternion::rotation_z(1.5 * PI); + }, + Some(ToolKind::Shield(_)) => { + next.main.offset = Vec3::new(-0.0, -5.0, 3.0); + next.main.ori = + Quaternion::rotation_y(0.25 * PI) * Quaternion::rotation_z(-1.5 * PI); + }, + _ => { + next.main.offset = Vec3::new(-7.0, -5.0, 15.0); + next.main.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + }, + } + next.main.scale = Vec3::one(); - next.second.offset = Vec3::new(0.0, 0.0, 0.0); - next.second.scale = Vec3::one() * 0.0; + match second_tool_kind { + Some(ToolKind::Dagger(_)) => { + next.second.offset = Vec3::new(4.0, -6.0, 7.0); + next.second.ori = + Quaternion::rotation_y(-0.25 * PI) * Quaternion::rotation_z(-1.5 * PI); + }, + Some(ToolKind::Shield(_)) => { + next.second.offset = Vec3::new(0.0, -4.0, 3.0); + next.second.ori = + Quaternion::rotation_y(-0.25 * PI) * Quaternion::rotation_z(1.5 * PI); + }, + _ => { + next.second.offset = Vec3::new(-7.0, -5.0, 15.0); + next.second.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57); + }, + } + next.second.scale = Vec3::one(); next.lantern.offset = Vec3::new( skeleton_attr.lantern.0, @@ -135,6 +165,15 @@ impl Animation for IdleAnimation { next.r_control.offset = Vec3::new(0.0, 0.0, 0.0); next.r_control.ori = Quaternion::rotation_x(0.0); next.r_control.scale = Vec3::one(); + + next.second.scale = match ( + active_tool_kind.map(|tk| tk.into_hands()), + second_tool_kind.map(|tk| tk.into_hands()), + ) { + (Some(Hands::OneHand), Some(Hands::OneHand)) => Vec3::one(), + (_, _) => Vec3::zero(), + }; + next } } diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index afe22828a1..bb8962d6f8 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -117,6 +117,8 @@ impl PlayState for CharSelectionState { } }); + let loadout = self.char_selection_ui.get_loadout(); + // Maintain the scene. { let client = self.client.borrow(); @@ -133,12 +135,13 @@ impl PlayState for CharSelectionState { .figure_lod_render_distance as f32, }; - self.scene - .maintain(global_state.window.renderer_mut(), scene_data); + self.scene.maintain( + global_state.window.renderer_mut(), + scene_data, + loadout.as_ref(), + ); } - // Render the scene. - let loadout = self.char_selection_ui.get_loadout(); self.scene.render( global_state.window.renderer_mut(), self.client.borrow().get_tick(), diff --git a/voxygen/src/scene/figure/cache.rs b/voxygen/src/scene/figure/cache.rs index 68c2ac550f..a65d6fd31c 100644 --- a/voxygen/src/scene/figure/cache.rs +++ b/voxygen/src/scene/figure/cache.rs @@ -32,6 +32,7 @@ enum FigureKey { struct CharacterCacheKey { state: Option>, // TODO: Can this be simplified? active_tool: Option, + second_tool: Option, shoulder: Option, chest: Option, belt: Option, @@ -53,6 +54,13 @@ impl CharacterCacheKey { } else { None }, + second_tool: if let Some(ItemKind::Tool(tool)) = + loadout.second_item.as_ref().map(|i| &i.item.kind) + { + Some(tool.kind) + } else { + None + }, shoulder: loadout.shoulder.clone(), chest: loadout.chest.clone(), belt: loadout.belt.clone(), diff --git a/voxygen/src/scene/simple.rs b/voxygen/src/scene/simple.rs index 3988e64739..192ffc008e 100644 --- a/voxygen/src/scene/simple.rs +++ b/voxygen/src/scene/simple.rs @@ -16,7 +16,7 @@ use anim::{ Animation, Skeleton, }; use common::{ - comp::{humanoid, Body, Loadout}, + comp::{humanoid, item::ItemKind, Body, Loadout}, figure::Segment, terrain::BlockKind, vol::{BaseVol, ReadVol, Vox}, @@ -157,7 +157,12 @@ impl Scene { } } - pub fn maintain(&mut self, renderer: &mut Renderer, scene_data: SceneData) { + pub fn maintain( + &mut self, + renderer: &mut Renderer, + scene_data: SceneData, + loadout: Option<&Loadout>, + ) { self.camera .update(scene_data.time, 1.0 / 60.0, scene_data.mouse_smoothing); @@ -191,10 +196,30 @@ impl Scene { self.figure_model_cache.clean(scene_data.tick); + let active_item_kind = loadout + .and_then(|l| l.active_item.as_ref()) + .map(|i| &i.item.kind); + + let active_tool_kind = if let Some(ItemKind::Tool(tool)) = active_item_kind { + Some(tool.kind) + } else { + None + }; + + let second_item_kind = loadout + .and_then(|l| l.second_item.as_ref()) + .map(|i| &i.item.kind); + + let second_tool_kind = if let Some(ItemKind::Tool(tool)) = second_item_kind { + Some(tool.kind) + } else { + None + }; + if let Some(body) = scene_data.body { let tgt_skeleton = IdleAnimation::update_skeleton( self.figure_state.skeleton_mut(), - scene_data.time, + (active_tool_kind, second_tool_kind, scene_data.time), scene_data.time, &mut 0.0, &SkeletonAttr::from(&body),