mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'timo-animations' into 'master'
Split animations See merge request veloren/veloren!466
This commit is contained in:
commit
367e7f2351
@ -100,12 +100,6 @@ impl Client {
|
||||
// We reduce the thread count by 1 to keep rendering smooth
|
||||
thread_pool.set_num_threads((num_cpus::get() - 1).max(1));
|
||||
|
||||
// Set client-only components
|
||||
let _ = state
|
||||
.ecs_mut()
|
||||
.write_storage()
|
||||
.insert(entity, comp::AnimationInfo::default());
|
||||
|
||||
Ok(Self {
|
||||
client_state,
|
||||
thread_pool,
|
||||
@ -279,10 +273,30 @@ impl Client {
|
||||
// 2) Build up a list of events for this frame, to be passed to the frontend.
|
||||
let mut frontend_events = Vec::new();
|
||||
|
||||
// Prepare for new events
|
||||
{
|
||||
let ecs = self.state.ecs_mut();
|
||||
for (entity, _) in (&ecs.entities(), &ecs.read_storage::<comp::Body>()).join() {
|
||||
let mut last_character_states =
|
||||
ecs.write_storage::<comp::Last<comp::CharacterState>>();
|
||||
if let Some(client_character_state) =
|
||||
ecs.read_storage::<comp::CharacterState>().get(entity)
|
||||
{
|
||||
if last_character_states
|
||||
.get(entity)
|
||||
.map(|&l| !client_character_state.is_same_state(&l.0))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
let _ = last_character_states
|
||||
.insert(entity, comp::Last(*client_character_state));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle new messages from the server.
|
||||
frontend_events.append(&mut self.handle_new_messages()?);
|
||||
|
||||
// 3)
|
||||
// 3) Update client local data
|
||||
|
||||
// 4) Tick the client's LocalState
|
||||
self.state.tick(dt);
|
||||
@ -395,7 +409,6 @@ impl Client {
|
||||
}
|
||||
|
||||
// 7) Finish the tick, pass control back to the frontend.
|
||||
|
||||
self.tick += 1;
|
||||
Ok(frontend_events)
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
use specs::{Component, FlaggedStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Animation {
|
||||
Idle,
|
||||
Run,
|
||||
Jump,
|
||||
Gliding,
|
||||
Attack,
|
||||
Block,
|
||||
Roll,
|
||||
Crun,
|
||||
Cidle,
|
||||
Cjump,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AnimationInfo {
|
||||
pub animation: Animation,
|
||||
pub time: f64,
|
||||
}
|
||||
|
||||
impl Default for AnimationInfo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
animation: Animation::Idle,
|
||||
time: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for AnimationInfo {
|
||||
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||
}
|
@ -63,6 +63,20 @@ pub struct CharacterState {
|
||||
pub action: ActionState,
|
||||
}
|
||||
|
||||
impl CharacterState {
|
||||
pub fn is_same_movement(&self, other: &Self) -> bool {
|
||||
// Check if enum item is the same without looking at the inner data
|
||||
std::mem::discriminant(&self.movement) == std::mem::discriminant(&other.movement)
|
||||
}
|
||||
pub fn is_same_action(&self, other: &Self) -> bool {
|
||||
// Check if enum item is the same without looking at the inner data
|
||||
std::mem::discriminant(&self.action) == std::mem::discriminant(&other.action)
|
||||
}
|
||||
pub fn is_same_state(&self, other: &Self) -> bool {
|
||||
self.is_same_movement(other) && self.is_same_action(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CharacterState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
@ -7,9 +7,3 @@ pub struct Last<C: Component + PartialEq>(pub C);
|
||||
impl<C: Component + Send + Sync + PartialEq> Component for Last<C> {
|
||||
type Storage = VecStorage<Self>;
|
||||
}
|
||||
|
||||
impl<C: Component + PartialEq> PartialEq<C> for Last<C> {
|
||||
fn eq(&self, other: &C) -> bool {
|
||||
self.0 == *other
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
mod admin;
|
||||
mod agent;
|
||||
mod animation;
|
||||
mod body;
|
||||
mod character_state;
|
||||
mod controller;
|
||||
@ -15,7 +14,6 @@ mod visual;
|
||||
// Reexports
|
||||
pub use admin::Admin;
|
||||
pub use agent::Agent;
|
||||
pub use animation::{Animation, AnimationInfo};
|
||||
pub use body::{humanoid, object, quadruped, quadruped_medium, Body};
|
||||
pub use character_state::{ActionState, CharacterState, MovementState};
|
||||
pub use controller::Controller;
|
||||
|
@ -133,9 +133,6 @@ impl State {
|
||||
ecs.register::<comp::Ori>();
|
||||
ecs.register::<comp::Inventory>();
|
||||
|
||||
// Register client-local components
|
||||
ecs.register::<comp::AnimationInfo>();
|
||||
|
||||
// Register server-local components
|
||||
ecs.register::<comp::Last<comp::Pos>>();
|
||||
ecs.register::<comp::Last<comp::Vel>>();
|
||||
|
@ -1,63 +0,0 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
ActionState::*, Animation, AnimationInfo, CharacterState, MovementState::*, PhysicsState,
|
||||
Stats,
|
||||
},
|
||||
state::DeltaTime,
|
||||
};
|
||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use std::fmt::Debug;
|
||||
|
||||
/// This system will apply the animation that fits best to the users actions
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
Read<'a, DeltaTime>,
|
||||
ReadStorage<'a, Stats>,
|
||||
ReadStorage<'a, CharacterState>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
WriteStorage<'a, AnimationInfo>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(entities, dt, stats, character_states, physics_states, mut animation_infos): Self::SystemData,
|
||||
) {
|
||||
for (entity, stats, character, physics) in
|
||||
(&entities, &stats, &character_states, &physics_states).join()
|
||||
{
|
||||
if stats.is_dead {
|
||||
continue;
|
||||
}
|
||||
|
||||
let animation = match (physics.on_ground, &character.movement, &character.action) {
|
||||
(_, Roll { .. }, Idle) => Animation::Roll,
|
||||
(true, Stand, Idle) => Animation::Idle,
|
||||
(true, Run, Idle) => Animation::Run,
|
||||
(false, Jump, Idle) => Animation::Jump,
|
||||
(true, Stand, Wield { .. }) => Animation::Cidle,
|
||||
(true, Run, Wield { .. }) => Animation::Crun,
|
||||
(false, Jump, Wield { .. }) => Animation::Cjump,
|
||||
(_, Glide, Idle) => Animation::Gliding,
|
||||
(_, _, Attack { .. }) => Animation::Attack,
|
||||
(_, _, Block { .. }) => Animation::Block,
|
||||
// Impossible animation (Caused by missing animations or syncing delays)
|
||||
_ => Animation::Gliding,
|
||||
};
|
||||
|
||||
let new_time = animation_infos
|
||||
.get(entity)
|
||||
.filter(|i| i.animation == animation)
|
||||
.map(|i| i.time + f64::from(dt.0));
|
||||
|
||||
let _ = animation_infos.insert(
|
||||
entity,
|
||||
AnimationInfo {
|
||||
animation,
|
||||
time: new_time.unwrap_or(0.0),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
pub mod agent;
|
||||
pub mod animation;
|
||||
mod cleanup;
|
||||
pub mod combat;
|
||||
pub mod controller;
|
||||
@ -16,7 +15,6 @@ const CONTROLLER_SYS: &str = "controller_sys";
|
||||
const PHYS_SYS: &str = "phys_sys";
|
||||
const MOVEMENT_SYS: &str = "movement_sys";
|
||||
const COMBAT_SYS: &str = "combat_sys";
|
||||
const ANIMATION_SYS: &str = "animation_sys";
|
||||
const STATS_SYS: &str = "stats_sys";
|
||||
const CLEANUP_SYS: &str = "cleanup_sys";
|
||||
|
||||
@ -26,7 +24,6 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
dispatch_builder.add(phys::Sys, PHYS_SYS, &[CONTROLLER_SYS]);
|
||||
dispatch_builder.add(movement::Sys, MOVEMENT_SYS, &[PHYS_SYS]);
|
||||
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[CONTROLLER_SYS]);
|
||||
dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[MOVEMENT_SYS]);
|
||||
dispatch_builder.add(stats::Sys, STATS_SYS, &[COMBAT_SYS]);
|
||||
dispatch_builder.add(cleanup::Sys, CLEANUP_SYS, &[STATS_SYS, ANIMATION_SYS]);
|
||||
dispatch_builder.add(cleanup::Sys, CLEANUP_SYS, &[STATS_SYS, MOVEMENT_SYS]);
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ const HUMANOID_AIR_SPEED: f32 = 100.0;
|
||||
const ROLL_SPEED: f32 = 13.0;
|
||||
const GLIDE_ACCEL: f32 = 15.0;
|
||||
const GLIDE_SPEED: f32 = 45.0;
|
||||
const BLOCK_ACCEL: f32 = 30.0;
|
||||
const BLOCK_SPEED: f32 = 75.0;
|
||||
// Gravity is 9.81 * 4, so this makes gravity equal to .15
|
||||
const GLIDE_ANTIGRAV: f32 = 9.81 * 3.95;
|
||||
|
||||
@ -80,6 +82,14 @@ impl<'a> System<'a> for Sys {
|
||||
.try_normalized()
|
||||
.unwrap_or(Vec2::from(vel.0).try_normalized().unwrap_or_default())
|
||||
* ROLL_SPEED
|
||||
}
|
||||
if character.action.is_block() || character.action.is_attack() {
|
||||
vel.0 += Vec2::broadcast(dt.0)
|
||||
* controller.move_dir
|
||||
* match (physics.on_ground) {
|
||||
(true) if vel.0.magnitude_squared() < BLOCK_SPEED.powf(2.0) => BLOCK_ACCEL,
|
||||
_ => 0.0,
|
||||
}
|
||||
} else {
|
||||
// Move player according to move_dir
|
||||
vel.0 += Vec2::broadcast(dt.0)
|
||||
|
@ -243,6 +243,8 @@ impl Server {
|
||||
let state = &mut self.state;
|
||||
let clients = &mut self.clients;
|
||||
|
||||
let mut todo_remove = None;
|
||||
|
||||
match event {
|
||||
ServerEvent::Explosion { pos, radius } => {
|
||||
const RAYS: usize = 500;
|
||||
@ -306,23 +308,21 @@ impl Server {
|
||||
clients.notify_registered(ServerMsg::kill(msg));
|
||||
}
|
||||
|
||||
{
|
||||
// Give EXP to the client
|
||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
||||
// Give EXP to the client
|
||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
||||
|
||||
if let Some(entity_stats) = stats.get(entity).cloned() {
|
||||
if let comp::HealthSource::Attack { by } = cause {
|
||||
ecs.entity_from_uid(by.into()).map(|attacker| {
|
||||
if let Some(attacker_stats) = stats.get_mut(attacker) {
|
||||
// TODO: Discuss whether we should give EXP by Player Killing or not.
|
||||
attacker_stats.exp.change_by(
|
||||
(entity_stats.health.maximum() as f64 / 10.0
|
||||
+ entity_stats.level.level() as f64 * 10.0)
|
||||
as i64,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
if let Some(entity_stats) = stats.get(entity).cloned() {
|
||||
if let comp::HealthSource::Attack { by } = cause {
|
||||
ecs.entity_from_uid(by.into()).map(|attacker| {
|
||||
if let Some(attacker_stats) = stats.get_mut(attacker) {
|
||||
// TODO: Discuss whether we should give EXP by Player Killing or not.
|
||||
attacker_stats.exp.change_by(
|
||||
(entity_stats.health.maximum() as f64 / 10.0
|
||||
+ entity_stats.level.level() as f64 * 10.0)
|
||||
as i64,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,7 +331,7 @@ impl Server {
|
||||
let _ = ecs.write_storage().insert(entity, comp::ForceUpdate);
|
||||
client.force_state(ClientState::Dead);
|
||||
} else {
|
||||
let _ = state.ecs_mut().delete_entity_synced(entity);
|
||||
todo_remove = Some(entity.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,6 +356,10 @@ impl Server {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(entity) = todo_remove {
|
||||
let _ = state.ecs_mut().delete_entity_synced(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,7 +1105,7 @@ impl Server {
|
||||
if let Some(client_pos) = ecs.read_storage::<comp::Pos>().get(entity) {
|
||||
if last_pos
|
||||
.get(entity)
|
||||
.map(|&l| l != *client_pos)
|
||||
.map(|&l| l.0 != *client_pos)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
let _ = last_pos.insert(entity, comp::Last(*client_pos));
|
||||
@ -1119,7 +1123,7 @@ impl Server {
|
||||
if let Some(client_vel) = ecs.read_storage::<comp::Vel>().get(entity) {
|
||||
if last_vel
|
||||
.get(entity)
|
||||
.map(|&l| l != *client_vel)
|
||||
.map(|&l| l.0 != *client_vel)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
let _ = last_vel.insert(entity, comp::Last(*client_vel));
|
||||
@ -1137,7 +1141,7 @@ impl Server {
|
||||
if let Some(client_ori) = ecs.read_storage::<comp::Ori>().get(entity) {
|
||||
if last_ori
|
||||
.get(entity)
|
||||
.map(|&l| l != *client_ori)
|
||||
.map(|&l| l.0 != *client_ori)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
let _ = last_ori.insert(entity, comp::Last(*client_ori));
|
||||
@ -1157,7 +1161,7 @@ impl Server {
|
||||
{
|
||||
if last_character_state
|
||||
.get(entity)
|
||||
.map(|&l| l != *client_character_state)
|
||||
.map(|&l| !client_character_state.is_same_state(&l.0))
|
||||
.unwrap_or(true)
|
||||
{
|
||||
let _ =
|
||||
|
@ -107,23 +107,23 @@ impl Animation for BlockAnimation {
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Hammer => {
|
||||
next.l_hand.offset = Vec3::new(-5.5, 9.0, 5.5);
|
||||
next.l_hand.offset = Vec3::new(-5.5, 10.0, 9.5);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.57)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(0.5);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(8.4, 9.3, 5.5);
|
||||
next.r_hand.offset = Vec3::new(8.4, 9.3, 7.5);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.57)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(0.5);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
7.0 + skeleton_attr.weapon_x,
|
||||
10.75 + skeleton_attr.weapon_y,
|
||||
5.5,
|
||||
7.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.57)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(0.5);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
@ -224,13 +224,13 @@ impl Animation for BlockAnimation {
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
next.l_foot.offset = Vec3::new(-3.4, 0.3, 8.0 + wave_ultra_slow_cos * 0.1);
|
||||
next.l_foot.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_foot.scale = Vec3::one();
|
||||
//next.l_foot.offset = Vec3::new(-3.4, 0.3, 8.0 + wave_ultra_slow_cos * 0.1);
|
||||
//next.l_foot.ori = Quaternion::rotation_x(-0.3);
|
||||
//next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, 1.2, 8.0 + wave_ultra_slow * 0.1);
|
||||
next.r_foot.ori = Quaternion::rotation_x(0.3);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
//next.r_foot.offset = Vec3::new(3.4, 1.2, 8.0 + wave_ultra_slow * 0.1);
|
||||
//next.r_foot.ori = Quaternion::rotation_x(0.3);
|
||||
//next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
|
252
voxygen/src/anim/character/blockidle.rs
Normal file
252
voxygen/src/anim/character/blockidle.rs
Normal file
@ -0,0 +1,252 @@
|
||||
use super::{
|
||||
super::{Animation, SkeletonAttr},
|
||||
CharacterSkeleton,
|
||||
};
|
||||
use common::comp::item::Tool;
|
||||
use std::{f32::consts::PI, ops::Mul};
|
||||
use vek::*;
|
||||
|
||||
pub struct Input {
|
||||
pub attack: bool,
|
||||
}
|
||||
pub struct BlockIdleAnimation;
|
||||
|
||||
impl Animation for BlockIdleAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = f64;
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
global_time: f64,
|
||||
anim_time: f64,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave_ultra_slow = (anim_time as f32 * 3.0 + PI).sin();
|
||||
let wave_ultra_slow_cos = (anim_time as f32 * 3.0 + PI).cos();
|
||||
let wave_slow_cos = (anim_time as f32 * 6.0 + PI).cos();
|
||||
|
||||
let _head_look = Vec2::new(
|
||||
((global_time + anim_time) as f32 / 1.5)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.3,
|
||||
((global_time + anim_time) as f32 / 1.5)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.15,
|
||||
);
|
||||
next.head.offset = Vec3::new(
|
||||
0.0 + skeleton_attr.neck_right + wave_slow_cos * 0.2,
|
||||
1.0 + skeleton_attr.neck_forward,
|
||||
skeleton_attr.neck_height + 13.5 + wave_ultra_slow * 0.2,
|
||||
);
|
||||
next.head.ori = Quaternion::rotation_x(-0.25);
|
||||
next.head.scale = Vec3::one() * 1.01 * skeleton_attr.head_scale;
|
||||
|
||||
next.chest.offset = Vec3::new(0.0 + wave_slow_cos * 0.2, 0.0, 5.0 + wave_ultra_slow * 0.2);
|
||||
next.chest.ori =
|
||||
Quaternion::rotation_x(-0.15) * Quaternion::rotation_y(wave_ultra_slow_cos * 0.01);
|
||||
next.chest.scale = Vec3::one();
|
||||
|
||||
next.belt.offset = Vec3::new(0.0 + wave_slow_cos * 0.2, 0.0, 3.0 + wave_ultra_slow * 0.2);
|
||||
next.belt.ori =
|
||||
Quaternion::rotation_x(0.0) * Quaternion::rotation_y(wave_ultra_slow_cos * 0.008);
|
||||
next.belt.scale = Vec3::one() * 1.01;
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0 + wave_slow_cos * 0.2, 0.0, 1.0 + wave_ultra_slow * 0.2);
|
||||
next.shorts.ori = Quaternion::rotation_x(0.1);
|
||||
next.shorts.scale = Vec3::one();
|
||||
|
||||
match Tool::Hammer {
|
||||
//TODO: Inventory
|
||||
Tool::Sword => {
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0 + wave_ultra_slow * 1.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Axe => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.0 + wave_ultra_slow_cos * 0.5,
|
||||
-2.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Hammer => {
|
||||
next.l_hand.offset = Vec3::new(-5.5, 10.0 + wave_ultra_slow * 2.0, 9.5);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(0.5);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(8.4, 9.3 + wave_ultra_slow * 2.0, 7.5);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(0.5);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
7.0 + skeleton_attr.weapon_x,
|
||||
10.75 + skeleton_attr.weapon_y + wave_ultra_slow * 2.0,
|
||||
7.5,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.35)
|
||||
* Quaternion::rotation_z(0.5);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Staff => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.0 + wave_ultra_slow_cos * 0.5,
|
||||
-2.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::SwordShield => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.0 + wave_ultra_slow_cos * 0.5,
|
||||
-2.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Bow => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.0 + wave_ultra_slow_cos * 0.5,
|
||||
-2.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x + wave_ultra_slow_cos * 1.0,
|
||||
4.5 + skeleton_attr.weapon_y + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Daggers => {
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-6.0 + wave_ultra_slow_cos * 1.0,
|
||||
3.5 + wave_ultra_slow_cos * 0.5,
|
||||
0.0 + wave_ultra_slow * 1.0,
|
||||
);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
next.l_foot.offset = Vec3::new(-3.4, 0.3, 8.0 + wave_ultra_slow_cos * 0.1);
|
||||
next.l_foot.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, 1.2, 8.0 + wave_ultra_slow * 0.1);
|
||||
next.r_foot.ori = Quaternion::rotation_x(0.3);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.l_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7);
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -7,9 +7,9 @@ use std::f32::consts::PI;
|
||||
use std::ops::Mul;
|
||||
use vek::*;
|
||||
|
||||
pub struct CrunAnimation;
|
||||
pub struct WieldAnimation;
|
||||
|
||||
impl Animation for CrunAnimation {
|
||||
impl Animation for WieldAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = (f32, f64);
|
||||
|
||||
@ -40,26 +40,6 @@ impl Animation for CrunAnimation {
|
||||
* 0.1,
|
||||
);
|
||||
|
||||
next.head.offset = Vec3::new(
|
||||
0.0,
|
||||
0.0 + skeleton_attr.neck_forward,
|
||||
skeleton_attr.neck_height + 15.0 + wave_cos * 1.3,
|
||||
);
|
||||
next.head.ori = Quaternion::rotation_z(head_look.x + wave * 0.1)
|
||||
* Quaternion::rotation_x(head_look.y + 0.35);
|
||||
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
|
||||
|
||||
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 1.1);
|
||||
next.chest.ori = Quaternion::rotation_z(wave * 0.15);
|
||||
next.chest.scale = Vec3::one();
|
||||
|
||||
next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_cos * 1.1);
|
||||
next.belt.ori = Quaternion::rotation_z(wave * 0.25);
|
||||
next.belt.scale = Vec3::one();
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_cos * 1.1);
|
||||
next.shorts.ori = Quaternion::rotation_z(wave * 0.4);
|
||||
next.shorts.scale = Vec3::one();
|
||||
|
||||
match Tool::Hammer {
|
||||
//TODO: Inventory
|
||||
@ -187,30 +167,6 @@ impl Animation for CrunAnimation {
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
}
|
||||
next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7);
|
||||
next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.5);
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0 - wave_cos_dub * 0.7);
|
||||
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.5);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(wave_cos * 0.15);
|
||||
next.l_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7);
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(wave * 0.15);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2 + wave * -0.08, 0.2) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
Quaternion::rotation_x(wave_stop * velocity * -0.04 + wave_diff * velocity * -0.005);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next
|
||||
}
|
||||
|
@ -1,25 +1,27 @@
|
||||
pub mod attack;
|
||||
pub mod block;
|
||||
pub mod blockidle;
|
||||
pub mod cidle;
|
||||
pub mod cjump;
|
||||
pub mod crun;
|
||||
pub mod gliding;
|
||||
pub mod idle;
|
||||
pub mod jump;
|
||||
pub mod roll;
|
||||
pub mod run;
|
||||
pub mod stand;
|
||||
pub mod wield;
|
||||
|
||||
// Reexports
|
||||
pub use self::attack::AttackAnimation;
|
||||
pub use self::block::BlockAnimation;
|
||||
pub use self::blockidle::BlockIdleAnimation;
|
||||
pub use self::cidle::CidleAnimation;
|
||||
pub use self::cjump::CjumpAnimation;
|
||||
pub use self::crun::CrunAnimation;
|
||||
pub use self::gliding::GlidingAnimation;
|
||||
pub use self::idle::IdleAnimation;
|
||||
pub use self::jump::JumpAnimation;
|
||||
pub use self::roll::RollAnimation;
|
||||
pub use self::run::RunAnimation;
|
||||
pub use self::stand::StandAnimation;
|
||||
pub use self::wield::WieldAnimation;
|
||||
|
||||
use super::{Bone, Skeleton};
|
||||
use crate::render::FigureBoneData;
|
||||
|
@ -10,22 +10,22 @@ pub struct RunAnimation;
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = (f32, f64);
|
||||
type Dependency = (f32, f32, f64);
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
(velocity, global_time): Self::Dependency,
|
||||
(velocity, orientation, global_time): Self::Dependency,
|
||||
anim_time: f64,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave = (anim_time as f32 * 12.0).sin();
|
||||
let wave_cos = (anim_time as f32 * 12.0).cos();
|
||||
let wave_diff = (anim_time as f32 * 12.0 + PI / 2.0).sin();
|
||||
let wave_cos_dub = (anim_time as f32 * 24.0).cos();
|
||||
let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin();
|
||||
let wave = (anim_time as f32 * velocity * 1.2).sin();
|
||||
let wave_cos = (anim_time as f32 * velocity * 1.2).cos();
|
||||
|
||||
let wave_diff = (anim_time as f32 * velocity * 0.6).sin();
|
||||
let wave_cos_dub = (anim_time as f32 * velocity * 2.4).cos();
|
||||
let wave_stop = (anim_time as f32 * 2.6).min(PI / 2.0).sin();
|
||||
let head_look = Vec2::new(
|
||||
((global_time + anim_time) as f32 / 2.0)
|
||||
.floor()
|
||||
@ -39,6 +39,19 @@ impl Animation for RunAnimation {
|
||||
* 0.1,
|
||||
);
|
||||
|
||||
let vel = Vec2::from(velocity);
|
||||
let ori = (Vec2::from(orientation)).normalized();
|
||||
|
||||
let _tilt = if Vec2::new(ori, vel)
|
||||
.map(|v| Vec2::<f32>::from(v).magnitude_squared())
|
||||
.reduce_partial_min()
|
||||
> 0.001
|
||||
{
|
||||
vel.normalized().dot(ori.normalized()).min(1.0).acos()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
next.head.offset = Vec3::new(
|
||||
0.0,
|
||||
-1.0 + skeleton_attr.neck_forward,
|
||||
@ -107,7 +120,8 @@ impl Animation for RunAnimation {
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2 + wave * -0.08, 0.4) * skeleton_attr.scaler;
|
||||
next.torso.ori =
|
||||
Quaternion::rotation_x(wave_stop * velocity * -0.06 + wave_diff * velocity * -0.005);
|
||||
Quaternion::rotation_x(wave_stop * velocity * -0.06 + wave_diff * velocity * -0.005)
|
||||
* Quaternion::rotation_y(0.0);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next
|
||||
|
112
voxygen/src/anim/character/stand.rs
Normal file
112
voxygen/src/anim/character/stand.rs
Normal file
@ -0,0 +1,112 @@
|
||||
use super::{
|
||||
super::{Animation, SkeletonAttr},
|
||||
CharacterSkeleton,
|
||||
};
|
||||
use std::{f32::consts::PI, ops::Mul};
|
||||
use vek::*;
|
||||
|
||||
pub struct Input {
|
||||
pub attack: bool,
|
||||
}
|
||||
pub struct StandAnimation;
|
||||
|
||||
impl Animation for StandAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = f64;
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
global_time: f64,
|
||||
anim_time: f64,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave_ultra_slow = (anim_time as f32 * 1.0 + PI).sin();
|
||||
let wave_ultra_slow_cos = (anim_time as f32 * 1.0 + PI).cos();
|
||||
|
||||
let head_look = Vec2::new(
|
||||
((global_time + anim_time) as f32 / 12.0)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.5,
|
||||
((global_time + anim_time) as f32 / 12.0)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.25,
|
||||
);
|
||||
next.head.offset = Vec3::new(
|
||||
0.0 + skeleton_attr.neck_right,
|
||||
0.0 + skeleton_attr.neck_forward,
|
||||
skeleton_attr.neck_height + 15.0 + wave_ultra_slow * 0.3,
|
||||
);
|
||||
next.head.ori =
|
||||
Quaternion::rotation_z(head_look.x) * Quaternion::rotation_x(head_look.y.abs());
|
||||
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
|
||||
|
||||
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_ultra_slow * 0.3);
|
||||
next.chest.ori = Quaternion::rotation_x(0.0);
|
||||
next.chest.scale = Vec3::one();
|
||||
|
||||
next.belt.offset = Vec3::new(0.0, 0.0, 5.0 + wave_ultra_slow * 0.3);
|
||||
next.belt.ori = Quaternion::rotation_x(0.0);
|
||||
next.belt.scale = Vec3::one();
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0, 0.0, 2.0 + wave_ultra_slow * 0.3);
|
||||
next.shorts.ori = Quaternion::rotation_x(0.0);
|
||||
next.shorts.scale = Vec3::one();
|
||||
|
||||
next.l_hand.offset = Vec3::new(
|
||||
-7.5,
|
||||
0.0 + wave_ultra_slow_cos * 0.15,
|
||||
0.0 + wave_ultra_slow * 0.5,
|
||||
);
|
||||
|
||||
next.l_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * -0.06);
|
||||
next.l_hand.scale = Vec3::one();
|
||||
|
||||
next.r_hand.offset = Vec3::new(
|
||||
7.5,
|
||||
0.0 + wave_ultra_slow_cos * 0.15,
|
||||
0.0 + wave_ultra_slow * 0.5,
|
||||
);
|
||||
next.r_hand.ori = Quaternion::rotation_x(0.0 + wave_ultra_slow * -0.06);
|
||||
next.r_hand.scale = Vec3::one();
|
||||
|
||||
next.l_foot.offset = Vec3::new(-3.4, -0.1, 8.0);
|
||||
next.l_foot.ori = Quaternion::identity();
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, -0.1, 8.0);
|
||||
next.r_foot.ori = Quaternion::identity();
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.weapon.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-5.0 + skeleton_attr.weapon_y,
|
||||
15.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
|
||||
next.weapon.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.l_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7);
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -3,59 +3,37 @@ use super::{
|
||||
CharacterSkeleton,
|
||||
};
|
||||
use common::comp::item::Tool;
|
||||
use std::f32::consts::PI;
|
||||
use vek::*;
|
||||
|
||||
pub struct CjumpAnimation;
|
||||
pub struct WieldAnimation;
|
||||
|
||||
impl Animation for CjumpAnimation {
|
||||
impl Animation for WieldAnimation {
|
||||
type Skeleton = CharacterSkeleton;
|
||||
type Dependency = f64;
|
||||
type Dependency = (f32, f64);
|
||||
|
||||
fn update_skeleton(
|
||||
skeleton: &Self::Skeleton,
|
||||
_global_time: f64,
|
||||
(_velocity, _global_time): Self::Dependency,
|
||||
anim_time: f64,
|
||||
skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave_slow = (anim_time as f32 * 7.0).sin();
|
||||
let wave_stop = (anim_time as f32 * 4.5).min(PI / 2.0).sin();
|
||||
|
||||
next.head.offset = Vec3::new(
|
||||
0.0 + skeleton_attr.neck_right,
|
||||
0.0 + skeleton_attr.neck_forward,
|
||||
skeleton_attr.neck_height + 15.0,
|
||||
);
|
||||
next.head.ori = Quaternion::rotation_x(0.25 + wave_stop * 0.1 + wave_slow * 0.04);
|
||||
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
|
||||
|
||||
next.chest.offset = Vec3::new(0.0, 0.0, 8.0);
|
||||
next.chest.ori = Quaternion::rotation_z(0.0);
|
||||
next.chest.scale = Vec3::one();
|
||||
|
||||
next.belt.offset = Vec3::new(0.0, 0.0, 6.0);
|
||||
next.belt.ori = Quaternion::rotation_z(0.0);
|
||||
next.belt.scale = Vec3::one();
|
||||
|
||||
next.shorts.offset = Vec3::new(0.0, 0.0, 3.0);
|
||||
next.shorts.ori = Quaternion::rotation_z(0.0);
|
||||
next.shorts.scale = Vec3::one();
|
||||
let wave = (anim_time as f32 * 12.0).sin();
|
||||
|
||||
match Tool::Hammer {
|
||||
//TODO: Inventory
|
||||
Tool::Sword => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 3.25, 0.25 + wave_stop * 2.0);
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.75, 0.25);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(-7.0, 3.0, -2.0 + wave_stop * 2.0);
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
-7.0 + skeleton_attr.weapon_x,
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.0 + skeleton_attr.weapon_y,
|
||||
0.0 + wave_stop * 2.0,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(0.0)
|
||||
@ -80,45 +58,41 @@ impl Animation for CjumpAnimation {
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Hammer => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 8.25, 2.0 + wave_stop * 2.0);
|
||||
next.l_hand.offset = Vec3::new(-7.0, 8.25, 3.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.2)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
* Quaternion::rotation_z(wave * -0.25);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(7.0, 7.0, -3.0 + wave_stop * 2.0);
|
||||
next.r_hand.offset = Vec3::new(7.0, 7.0, -1.5);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.2)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
* Quaternion::rotation_z(wave * -0.25);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.75 + skeleton_attr.weapon_y,
|
||||
-2.5 + wave_stop * 2.0,
|
||||
-2.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.2)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
* Quaternion::rotation_z(wave * -0.25);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::Staff => {
|
||||
next.l_hand.offset = Vec3::new(-7.0, 7.5, 0.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(1.0);
|
||||
next.l_hand.offset = Vec3::new(-6.0, 3.5, 0.0);
|
||||
next.l_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.l_hand.scale = Vec3::one() * 1.01;
|
||||
next.r_hand.offset = Vec3::new(7.0, 6.25, 1.5);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(1.0);
|
||||
next.r_hand.offset = Vec3::new(-6.0, 3.0, -2.0);
|
||||
next.r_hand.ori = Quaternion::rotation_x(-0.3);
|
||||
next.r_hand.scale = Vec3::one() * 1.01;
|
||||
next.weapon.offset = Vec3::new(
|
||||
5.0 + skeleton_attr.weapon_x,
|
||||
8.0 + skeleton_attr.weapon_y,
|
||||
1.0,
|
||||
-6.0 + skeleton_attr.weapon_x,
|
||||
4.5 + skeleton_attr.weapon_y,
|
||||
0.0,
|
||||
);
|
||||
next.weapon.ori = Quaternion::rotation_x(-0.3)
|
||||
* Quaternion::rotation_y(-1.7)
|
||||
* Quaternion::rotation_z(1.0);
|
||||
* Quaternion::rotation_y(0.0)
|
||||
* Quaternion::rotation_z(0.0);
|
||||
next.weapon.scale = Vec3::one();
|
||||
}
|
||||
Tool::SwordShield => {
|
||||
@ -174,30 +148,6 @@ impl Animation for CjumpAnimation {
|
||||
}
|
||||
}
|
||||
|
||||
next.l_foot.offset = Vec3::new(-3.4, 1.0, 6.0);
|
||||
next.l_foot.ori = Quaternion::rotation_x(wave_stop * -1.2 - wave_slow * 0.2);
|
||||
next.l_foot.scale = Vec3::one();
|
||||
|
||||
next.r_foot.offset = Vec3::new(3.4, -1.0, 6.0);
|
||||
next.r_foot.ori = Quaternion::rotation_x(wave_stop * 1.2 + wave_slow * 0.2);
|
||||
next.r_foot.scale = Vec3::one();
|
||||
|
||||
next.l_shoulder.offset = Vec3::new(-5.0, 0.0, 4.7);
|
||||
next.l_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.l_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.r_shoulder.offset = Vec3::new(5.0, 0.0, 4.7);
|
||||
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
|
||||
next.r_shoulder.scale = Vec3::one() * 1.1;
|
||||
|
||||
next.draw.offset = Vec3::new(0.0, 5.0, 0.0);
|
||||
next.draw.ori = Quaternion::rotation_y(0.0);
|
||||
next.draw.scale = Vec3::one() * 0.0;
|
||||
|
||||
next.torso.offset = Vec3::new(0.0, -0.2, 0.0) * skeleton_attr.scaler;
|
||||
next.torso.ori = Quaternion::rotation_x(-0.2);
|
||||
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
anim::{
|
||||
self, character::CharacterSkeleton, object::ObjectSkeleton, quadruped::QuadrupedSkeleton,
|
||||
quadrupedmedium::QuadrupedMediumSkeleton, Animation, Skeleton, SkeletonAttr,
|
||||
quadrupedmedium::QuadrupedMediumSkeleton, Animation as _, Skeleton, SkeletonAttr,
|
||||
},
|
||||
mesh::Meshable,
|
||||
render::{
|
||||
@ -13,7 +13,8 @@ use client::Client;
|
||||
use common::{
|
||||
assets,
|
||||
comp::{
|
||||
self, humanoid, item::Tool, object, quadruped, quadruped_medium, Body, Equipment, Item,
|
||||
humanoid, item::Tool, object, quadruped, quadruped_medium, ActionState::*, Body,
|
||||
CharacterState, Equipment, Item, Last, MovementState::*, Ori, Pos, Scale, Stats, Vel,
|
||||
},
|
||||
figure::Segment,
|
||||
terrain::TerrainChunkSize,
|
||||
@ -23,7 +24,7 @@ use dot_vox::DotVoxData;
|
||||
use hashbrown::HashMap;
|
||||
use log::debug;
|
||||
use specs::{Entity as EcsEntity, Join};
|
||||
use std::f32;
|
||||
use std::{f32, time::Instant};
|
||||
use vek::*;
|
||||
|
||||
const DAMAGE_FADE_COEFFICIENT: f64 = 5.0;
|
||||
@ -618,19 +619,20 @@ impl FigureMgr {
|
||||
let dt = client.state().get_delta_time();
|
||||
// Get player position.
|
||||
let player_pos = ecs
|
||||
.read_storage::<comp::Pos>()
|
||||
.read_storage::<Pos>()
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
for (entity, pos, vel, ori, scale, body, animation_info, stats) in (
|
||||
for (entity, pos, vel, ori, scale, body, character, last_character, stats) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::Pos>(),
|
||||
&ecs.read_storage::<comp::Vel>(),
|
||||
&ecs.read_storage::<comp::Ori>(),
|
||||
ecs.read_storage::<comp::Scale>().maybe(),
|
||||
&ecs.read_storage::<comp::Body>(),
|
||||
ecs.read_storage::<comp::AnimationInfo>().maybe(),
|
||||
ecs.read_storage::<comp::Stats>().maybe(),
|
||||
&ecs.read_storage::<Pos>(),
|
||||
&ecs.read_storage::<Vel>(),
|
||||
&ecs.read_storage::<Ori>(),
|
||||
ecs.read_storage::<Scale>().maybe(),
|
||||
&ecs.read_storage::<Body>(),
|
||||
ecs.read_storage::<CharacterState>().maybe(),
|
||||
ecs.read_storage::<Last<CharacterState>>().maybe(),
|
||||
ecs.read_storage::<Stats>().maybe(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -683,80 +685,92 @@ impl FigureMgr {
|
||||
.character_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| FigureState::new(renderer, CharacterSkeleton::new()));
|
||||
|
||||
let animation_info = match animation_info {
|
||||
Some(a_i) => a_i,
|
||||
None => continue,
|
||||
let (character, last_character) = match (character, last_character) {
|
||||
(Some(c), Some(l)) => (c, l),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Idle => anim::character::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
if !character.is_same_movement(&last_character.0) {
|
||||
state.last_movement_change = Instant::now();
|
||||
}
|
||||
if !character.is_same_action(&last_character.0) {
|
||||
state.last_action_change = Instant::now();
|
||||
}
|
||||
|
||||
let time_since_movement_change =
|
||||
state.last_movement_change.elapsed().as_secs_f64();
|
||||
let time_since_action_change = state.last_action_change.elapsed().as_secs_f64();
|
||||
|
||||
let target_base = match &character.movement {
|
||||
Stand => anim::character::StandAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
time,
|
||||
animation_info.time,
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Run => anim::character::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
Run => anim::character::RunAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
(vel.0.magnitude(), ori.0.magnitude(), time),
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Jump => anim::character::JumpAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
time,
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Roll { .. } => anim::character::RollAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
time,
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Glide => anim::character::GlidingAnimation::update_skeleton(
|
||||
&CharacterSkeleton::new(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Jump => anim::character::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
};
|
||||
|
||||
let target_bones = match (&character.movement, &character.action) {
|
||||
(Stand, Wield { .. }) => anim::character::CidleAnimation::update_skeleton(
|
||||
&target_base,
|
||||
time,
|
||||
animation_info.time,
|
||||
time_since_action_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Attack => {
|
||||
anim::character::AttackAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(Stand, Block { .. }) => {
|
||||
anim::character::BlockIdleAnimation::update_skeleton(
|
||||
&target_base,
|
||||
time,
|
||||
animation_info.time,
|
||||
time_since_action_change,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Block => anim::character::BlockAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(_, Attack { .. }) => anim::character::AttackAnimation::update_skeleton(
|
||||
&target_base,
|
||||
time,
|
||||
animation_info.time,
|
||||
time_since_action_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Cjump => anim::character::CjumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Roll => anim::character::RollAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Crun => anim::character::CrunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(_, Wield { .. }) => anim::character::WieldAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
time_since_action_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Cidle => anim::character::CidleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(_, Block { .. }) => anim::character::BlockAnimation::update_skeleton(
|
||||
&target_base,
|
||||
time,
|
||||
animation_info.time,
|
||||
time_since_action_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
comp::Animation::Gliding => {
|
||||
anim::character::GlidingAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
_ => target_base,
|
||||
};
|
||||
state.skeleton.interpolate(&target_bones, dt);
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||
}
|
||||
Body::Quadruped(_) => {
|
||||
@ -765,42 +779,43 @@ impl FigureMgr {
|
||||
.entry(entity)
|
||||
.or_insert_with(|| FigureState::new(renderer, QuadrupedSkeleton::new()));
|
||||
|
||||
let animation_info = match animation_info {
|
||||
Some(a_i) => a_i,
|
||||
None => continue,
|
||||
let (character, last_character) = match (character, last_character) {
|
||||
(Some(c), Some(l)) => (c, l),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Run | comp::Animation::Crun => {
|
||||
anim::quadruped::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Idle | comp::Animation::Cidle => {
|
||||
anim::quadruped::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Jump | comp::Animation::Cjump => {
|
||||
anim::quadruped::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
if !character.is_same_movement(&last_character.0) {
|
||||
state.last_movement_change = Instant::now();
|
||||
}
|
||||
|
||||
let time_since_movement_change =
|
||||
state.last_movement_change.elapsed().as_secs_f64();
|
||||
|
||||
let target_base = match character.movement {
|
||||
Stand => anim::quadruped::IdleAnimation::update_skeleton(
|
||||
&QuadrupedSkeleton::new(),
|
||||
time,
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Run => anim::quadruped::RunAnimation::update_skeleton(
|
||||
&QuadrupedSkeleton::new(),
|
||||
(vel.0.magnitude(), time),
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Jump => anim::quadruped::JumpAnimation::update_skeleton(
|
||||
&QuadrupedSkeleton::new(),
|
||||
(vel.0.magnitude(), time),
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
|
||||
// TODO!
|
||||
_ => state.skeleton_mut().clone(),
|
||||
};
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.skeleton.interpolate(&target_base, dt);
|
||||
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||
}
|
||||
Body::QuadrupedMedium(_) => {
|
||||
@ -811,42 +826,43 @@ impl FigureMgr {
|
||||
FigureState::new(renderer, QuadrupedMediumSkeleton::new())
|
||||
});
|
||||
|
||||
let animation_info = match animation_info {
|
||||
Some(a_i) => a_i,
|
||||
None => continue,
|
||||
let (character, last_character) = match (character, last_character) {
|
||||
(Some(c), Some(l)) => (c, l),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let target_skeleton = match animation_info.animation {
|
||||
comp::Animation::Run | comp::Animation::Crun => {
|
||||
anim::quadrupedmedium::RunAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Idle | comp::Animation::Cidle => {
|
||||
anim::quadrupedmedium::IdleAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
time,
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
comp::Animation::Jump | comp::Animation::Cjump => {
|
||||
anim::quadrupedmedium::JumpAnimation::update_skeleton(
|
||||
state.skeleton_mut(),
|
||||
(vel.0.magnitude(), time),
|
||||
animation_info.time,
|
||||
skeleton_attr,
|
||||
)
|
||||
}
|
||||
if !character.is_same_movement(&last_character.0) {
|
||||
state.last_movement_change = Instant::now();
|
||||
}
|
||||
|
||||
let time_since_movement_change =
|
||||
state.last_movement_change.elapsed().as_secs_f64();
|
||||
|
||||
let target_base = match character.movement {
|
||||
Stand => anim::quadrupedmedium::IdleAnimation::update_skeleton(
|
||||
&QuadrupedMediumSkeleton::new(),
|
||||
time,
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Run => anim::quadrupedmedium::RunAnimation::update_skeleton(
|
||||
&QuadrupedMediumSkeleton::new(),
|
||||
(vel.0.magnitude(), time),
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
Jump => anim::quadrupedmedium::JumpAnimation::update_skeleton(
|
||||
&QuadrupedMediumSkeleton::new(),
|
||||
(vel.0.magnitude(), time),
|
||||
time_since_movement_change,
|
||||
skeleton_attr,
|
||||
),
|
||||
|
||||
// TODO!
|
||||
_ => state.skeleton_mut().clone(),
|
||||
};
|
||||
|
||||
state.skeleton.interpolate(&target_skeleton, dt);
|
||||
state.skeleton.interpolate(&target_base, dt);
|
||||
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||
}
|
||||
Body::Object(_) => {
|
||||
@ -887,12 +903,12 @@ impl FigureMgr {
|
||||
|
||||
for (entity, _, _, _, body, stats, _) in (
|
||||
&ecs.entities(),
|
||||
&ecs.read_storage::<comp::Pos>(),
|
||||
&ecs.read_storage::<comp::Vel>(),
|
||||
&ecs.read_storage::<comp::Ori>(),
|
||||
&ecs.read_storage::<comp::Body>(),
|
||||
ecs.read_storage::<comp::Stats>().maybe(),
|
||||
ecs.read_storage::<comp::Scale>().maybe(),
|
||||
&ecs.read_storage::<Pos>(),
|
||||
&ecs.read_storage::<Vel>(),
|
||||
&ecs.read_storage::<Ori>(),
|
||||
&ecs.read_storage::<Body>(),
|
||||
ecs.read_storage::<Stats>().maybe(),
|
||||
ecs.read_storage::<Scale>().maybe(),
|
||||
)
|
||||
.join()
|
||||
// Don't render figures outside of frustum (camera viewport, max draw distance is farplane)
|
||||
@ -901,7 +917,7 @@ impl FigureMgr {
|
||||
&pos.0.x,
|
||||
&pos.0.y,
|
||||
&pos.0.z,
|
||||
&(scale.unwrap_or(&comp::Scale(1.0)).0 * 2.0),
|
||||
&(scale.unwrap_or(&Scale(1.0)).0 * 2.0),
|
||||
)
|
||||
})
|
||||
// Don't render dead entities
|
||||
@ -934,7 +950,7 @@ impl FigureMgr {
|
||||
if camera.get_mode() == CameraMode::FirstPerson
|
||||
&& client
|
||||
.state()
|
||||
.read_storage::<comp::Body>()
|
||||
.read_storage::<Body>()
|
||||
.get(client.entity())
|
||||
.is_some()
|
||||
&& entity == client.entity()
|
||||
@ -953,6 +969,8 @@ impl FigureMgr {
|
||||
pub struct FigureState<S: Skeleton> {
|
||||
bone_consts: Consts<FigureBoneData>,
|
||||
locals: Consts<FigureLocals>,
|
||||
last_movement_change: Instant,
|
||||
last_action_change: Instant,
|
||||
skeleton: S,
|
||||
pos: Vec3<f32>,
|
||||
ori: Vec3<f32>,
|
||||
@ -965,6 +983,8 @@ impl<S: Skeleton> FigureState<S> {
|
||||
.create_consts(&skeleton.compute_matrices())
|
||||
.unwrap(),
|
||||
locals: renderer.create_consts(&[FigureLocals::default()]).unwrap(),
|
||||
last_movement_change: Instant::now(),
|
||||
last_action_change: Instant::now(),
|
||||
skeleton,
|
||||
pos: Vec3::zero(),
|
||||
ori: Vec3::zero(),
|
||||
|
Loading…
Reference in New Issue
Block a user