Fix first person weapon visible while not wielding

This commit is contained in:
scott-c 2019-08-18 17:01:57 +08:00
parent d045dbb2f6
commit bc1ccfc99b
5 changed files with 119 additions and 54 deletions

View File

@ -2,7 +2,7 @@ use specs::{Component, FlaggedStorage, HashMapStorage};
use specs_idvs::IDVStorage;
use std::time::Duration;
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub enum MovementState {
Stand,
Run,
@ -22,7 +22,7 @@ impl MovementState {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub enum ActionState {
Idle,
Wield { time_left: Duration },
@ -57,7 +57,7 @@ impl ActionState {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub struct CharacterState {
pub movement: MovementState,
pub action: ActionState,

View File

@ -164,8 +164,8 @@ impl Scene {
Body::Humanoid(body),
Some(equipment),
client.get_tick(),
false,
false,
None,
None,
)
.0;

View File

@ -12,12 +12,18 @@ const THIRD_PERSON_INTERP_TIME: f32 = 0.1;
pub const MIN_ZOOM: f32 = 0.1;
// Possible TODO: Add more modes
#[derive(PartialEq, Clone, Copy)]
#[derive(PartialEq, Clone, Copy, Eq, Hash)]
pub enum CameraMode {
FirstPerson,
ThirdPerson,
}
impl Default for CameraMode {
fn default() -> Self {
Self::ThirdPerson
}
}
pub struct Camera {
tgt_focus: Vec3<f32>,
focus: Vec3<f32>,

View File

@ -2,17 +2,23 @@ use super::load::*;
use crate::{
anim::SkeletonAttr,
render::{FigurePipeline, Mesh, Model, Renderer},
scene::camera::CameraMode,
};
use common::{
assets::watch::ReloadIndicator,
comp::{Body, Equipment},
comp::{ActionState, Body, CharacterState, Equipment},
};
use hashbrown::HashMap;
#[derive(PartialEq, Eq, Hash, Clone)]
enum FigureKey {
Simple(Body),
Complex(Body, Option<Equipment>, bool, bool),
Complex(
Body,
Option<Equipment>,
Option<CameraMode>,
Option<CharacterState>,
),
}
pub struct FigureModelCache {
@ -34,11 +40,16 @@ impl FigureModelCache {
body: Body,
equipment: Option<&Equipment>,
tick: u64,
first_person: bool,
gliding: bool,
camera_mode: Option<CameraMode>,
character_state: Option<&CharacterState>,
) -> &(Model<FigurePipeline>, SkeletonAttr) {
let key = if equipment.is_some() {
FigureKey::Complex(body, equipment.cloned(), first_person, gliding)
FigureKey::Complex(
body,
equipment.cloned(),
camera_mode,
character_state.cloned(),
)
} else {
FigureKey::Simple(body)
};
@ -56,36 +67,69 @@ impl FigureModelCache {
HumHeadSpec::load_watched(&mut self.manifest_indicator);
let bone_meshes = match body {
Body::Humanoid(body) => [
if !first_person {
Some(humanoid_head_spec.mesh_head(
body.race,
body.body_type,
body.hair_color,
body.hair_style,
body.beard,
body.eye_color,
body.skin,
body.eyebrows,
body.accessory,
))
} else {
None
}
,
Some(mesh_chest(body.chest)),
Some(mesh_belt(body.belt)),
Some(mesh_pants(body.pants)),
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => {
Some(humanoid_head_spec.mesh_head(
body.race,
body.body_type,
body.hair_color,
body.hair_style,
body.beard,
body.eye_color,
body.skin,
body.eyebrows,
body.accessory,
))
}
CameraMode::FirstPerson => None,
},
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => Some(mesh_chest(body.chest)),
CameraMode::FirstPerson => None,
},
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => Some(mesh_belt(body.belt)),
CameraMode::FirstPerson => None,
},
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => Some(mesh_pants(body.pants)),
CameraMode::FirstPerson => None,
},
Some(mesh_left_hand(body.hand)),
Some(mesh_right_hand(body.hand)),
Some(mesh_left_foot(body.foot)),
Some(mesh_right_foot(body.foot)),
Some(mesh_main(equipment.and_then(|e| e.main.as_ref()))),
Some(mesh_left_shoulder(body.shoulder)),
Some(mesh_right_shoulder(body.shoulder)),
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => Some(mesh_left_foot(body.foot)),
CameraMode::FirstPerson => None,
},
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => Some(mesh_right_foot(body.foot)),
CameraMode::FirstPerson => None,
},
if camera_mode.unwrap_or_default() != CameraMode::FirstPerson
|| character_state
.map(|cs| {
cs.action.is_attack()
|| cs.action.is_block()
|| cs.action.is_wield()
})
.unwrap_or_default()
{
Some(mesh_main(equipment.and_then(|e| e.main.as_ref())))
} else {
None
},
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => {
Some(mesh_left_shoulder(body.shoulder))
}
CameraMode::FirstPerson => None,
},
match camera_mode.unwrap_or_default() {
CameraMode::ThirdPerson => {
Some(mesh_right_shoulder(body.shoulder))
}
CameraMode::FirstPerson => None,
},
Some(mesh_draw()),
None,
None,

View File

@ -116,7 +116,14 @@ impl FigureMgr {
let skeleton_attr = &self
.model_cache
.get_or_create_model(renderer, *body, stats.map(|s| &s.equipment), tick, false, false)
.get_or_create_model(
renderer,
*body,
stats.map(|s| &s.equipment),
tick,
None,
None,
)
.1;
match body {
@ -382,25 +389,33 @@ impl FigureMgr {
.map(|state| (state.locals(), state.bone_consts())),
} {
// Don't render the player's body while in first person mode
let fp =
camera.get_mode() == CameraMode::FirstPerson
&& client
.state()
.read_storage::<Body>()
.get(client.entity())
.is_some()
&& entity == client.entity();
let gliding = client
let player_camera_mode = if client
.state()
.read_storage::<common::comp::CharacterState>()
.read_storage::<common::comp::Body>()
.get(client.entity())
.unwrap_or(&common::comp::CharacterState::default())
.movement == common::comp::MovementState::Glide;
.is_some()
&& entity == client.entity()
{
Some(camera.get_mode())
} else {
None
};
let character_state_storage = client
.state()
.read_storage::<common::comp::CharacterState>();
let character_state = character_state_storage.get(client.entity());
let model = &self
.model_cache
.get_or_create_model(renderer, *body, stats.map(|s| &s.equipment), tick, fp, gliding)
.get_or_create_model(
renderer,
*body,
stats.map(|s| &s.equipment),
tick,
player_camera_mode,
character_state,
)
.0;
renderer.render_figure(model, globals, locals, bone_consts, lights);