Fix 1h models in character select idle animation #662

This commit is contained in:
scott-c 2020-07-06 00:21:12 +08:00
parent 6014bd8364
commit b72d817cf7
4 changed files with 82 additions and 15 deletions

View File

@ -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();

View File

@ -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<ToolKind>, Option<ToolKind>, 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
}
}

View File

@ -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(),

View File

@ -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),