velocity tilt

Former-commit-id: 34443765d993ec5036d2b3e08e7dff5a68193de6
This commit is contained in:
jshipsey 2019-04-21 13:35:43 -04:00
parent 97603120a2
commit 9510edd148
4 changed files with 38 additions and 306 deletions

View File

@ -13,7 +13,6 @@ use super::{
pub struct IdleAnimation;
//TODO: Make it actually good, possibly add the head rotating slightly, add breathing, etc.
impl Animation for IdleAnimation {
type Skeleton = CharacterSkeleton;
type Dependency = f64;
@ -64,10 +63,9 @@ impl Animation for IdleAnimation {
next.r_foot.ori = Quaternion::rotation_y(0.04 + waveultra_slow * 0.04);
next.r_foot.scale = Vec3::one();
next.back.offset = Vec3::new(-4.5, 14.0, 13.0);
next.back.ori = Quaternion::rotation_x(2.5);
next.back.scale = Vec3::one();
next.weapon.offset = Vec3::new(-4.5, 14.0, 13.0);
next.weapon.ori = Quaternion::rotation_x(2.5);
next.weapon.scale = Vec3::one();
next.torso.offset = Vec3::new(0.0, 0.0, 0.0);

View File

@ -26,11 +26,10 @@ pub struct CharacterSkeleton {
r_hand: Bone,
l_foot: Bone,
r_foot: Bone,
back: Bone,
weapon: Bone,
torso: Bone,
l_shoulder: Bone,
r_shoulder: Bone,
}
impl CharacterSkeleton {
@ -44,7 +43,7 @@ impl CharacterSkeleton {
r_hand: Bone::default(),
l_foot: Bone::default(),
r_foot: Bone::default(),
back: Bone::default(),
weapon: Bone::default(),
torso: Bone::default(),
l_shoulder: Bone::default(),
r_shoulder: Bone::default(),
@ -66,10 +65,12 @@ impl Skeleton for CharacterSkeleton {
FigureBoneData::new(torso_mat * self.r_hand.compute_base_matrix()),
FigureBoneData::new(torso_mat * self.l_foot.compute_base_matrix()),
FigureBoneData::new(torso_mat * self.r_foot.compute_base_matrix()),
FigureBoneData::new(torso_mat * chest_mat * self.back.compute_base_matrix()),
FigureBoneData::new(torso_mat * chest_mat * self.weapon.compute_base_matrix()),
FigureBoneData::new(torso_mat),
FigureBoneData::new(torso_mat * self.l_shoulder.compute_base_matrix()),
FigureBoneData::new(torso_mat * self.r_shoulder.compute_base_matrix()),
//FigureBoneData::new(torso_mat * self.l_shoulder.compute_base_matrix()),
//FigureBoneData::new(torso_mat * self.r_shoulder.compute_base_matrix()),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
@ -87,7 +88,7 @@ impl Skeleton for CharacterSkeleton {
self.r_hand.interpolate(&target.r_hand);
self.l_foot.interpolate(&target.l_foot);
self.r_foot.interpolate(&target.r_foot);
self.back.interpolate(&target.back);
self.weapon.interpolate(&target.weapon);
self.torso.interpolate(&target.torso);
self.l_shoulder.interpolate(&target.l_shoulder);
self.r_shoulder.interpolate(&target.r_shoulder);

View File

@ -31,10 +31,9 @@ impl Animation for RunAnimation {
let wavecos_slow = (time as f32 * 8.0 + PI).cos();
let wave_dip = (wave_slow.abs() - 0.5).abs();
next.head.offset = Vec3::new(6.0, 0.0, 12.0 + wavecos * 1.3); // / SCALE;
next.head.offset = Vec3::new(6.0, 0.0, 12.0 + wavecos * 1.3);
next.head.ori = Quaternion::rotation_y(-0.15);
next.head.scale = Vec3::one(); // / SCALE;
next.head.scale = Vec3::one();
next.chest.offset = Vec3::new(2.5, 0.0, 8.0 + wavecos * 1.1);
next.chest.ori = Quaternion::rotation_z(wave * 0.1);
@ -64,15 +63,14 @@ impl Animation for RunAnimation {
next.r_foot.ori = Quaternion::rotation_y(-0.0 + wave * 1.5);
next.r_foot.scale = Vec3::one();
next.back.offset = Vec3::new(-5.0, 14.0, 13.0);
next.back.ori = Quaternion::rotation_x(2.5);
next.back.scale = Vec3::one();
next.weapon.offset = Vec3::new(-5.0, 14.0, 13.0);
next.weapon.ori = Quaternion::rotation_x(2.5);
next.weapon.scale = Vec3::one();
next.torso.offset = Vec3::new(0.0, 0.0, 0.0);
next.torso.ori = Quaternion::rotation_y(0.25 + wavecos * 0.1);
next.torso.scale = Vec3::one() / 11.0;
next.l_shoulder.offset = Vec3::new(3.0, 6.0, 18.0);
next.l_shoulder.ori = Quaternion::rotation_y(0.0);
next.l_shoulder.scale = Vec3::one();

View File

@ -52,105 +52,6 @@ pub struct FigureCache {
states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
}
impl FigureCache {
pub fn new() -> Self {
Self {
models: HashMap::new(),
states: HashMap::new(),
}
}
<<<<<<< HEAD
pub fn get_or_create_model<'a>(
models: &'a mut HashMap<Character, (Model<FigurePipeline>, u64)>,
renderer: &mut Renderer,
tick: u64,
character: Character)
-> &'a (Model<FigurePipeline>, u64) {
match models.get_mut(&character) {
Some((model, last_used)) => {
*last_used = tick;
}
None => {
models.insert(character, ({
let bone_meshes = [
Some(Self::load_head(character.head)),
Some(Self::load_chest(character.chest)),
Some(Self::load_belt(character.belt)),
Some(Self::load_pants(character.pants)),
Some(Self::load_left_hand(character.hand)),
Some(Self::load_right_hand(character.hand)),
Some(Self::load_left_foot(character.foot)),
Some(Self::load_right_foot(character.foot)),
Some(Self::load_weapon(character.weapon)),
None,
None,
None,
None,
None,
None,
None,
];
=======
let bone_meshes = [
Some(load_segment("head.vox").generate_mesh(Vec3::new(-5.5, -7.0, -6.0))),
Some(load_segment("chest.vox").generate_mesh(Vec3::new(-2.5, -6.0, 0.0))),
use std::{
collections::HashMap,
f32,
};
use specs::{Entity as EcsEntity, Component, VecStorage, Join};
use vek::*;
use client::Client;
use common::{
comp::{
self,
character::{
Character,
Head,
Chest,
Belt,
Pants,
Hand,
Foot,
Weapon,
}
},
figure::Segment,
msg,
assets,
};
use crate::{
Error,
render::{
Consts,
Globals,
Mesh,
Model,
Renderer,
FigurePipeline,
FigureBoneData,
FigureLocals,
},
anim::{
Animation,
Skeleton,
character::{
CharacterSkeleton,
RunAnimation,
IdleAnimation,
},
},
mesh::Meshable,
};
pub struct FigureCache {
models: HashMap<Character, (Model<FigurePipeline>, u64)>,
states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
}
impl FigureCache {
pub fn new() -> Self {
Self {
@ -189,6 +90,28 @@ impl FigureCache {
None,
None,
];
// let bone_meshes = [
//
//
// Some(load_segment("head.vox").generate_mesh(Vec3::new(-5.5, -7.0, -6.0))),
// Some(load_segment("chest.vox").generate_mesh(Vec3::new(-2.5, -6.0, 0.0))),
// Some(load_segment("belt.vox").generate_mesh(Vec3::new(-2.5, -5.0, 0.0))),
// Some(load_segment("pants.vox").generate_mesh(Vec3::new(-2.5, -5.0, 0.0))),
// Some(load_segment("hand.vox").generate_mesh(Vec3::new(0.0, -2.0, -7.0))),
// Some(load_segment("hand.vox").generate_mesh(Vec3::new(0.0, -2.0, -7.0))),
// Some(load_segment("foot.vox").generate_mesh(Vec3::new(-3.5, -2.5, -8.0))),
// Some(load_segment("foot.vox").generate_mesh(Vec3::new(-3.5, -2.5, -8.0))),
// Some(load_segment("sword.vox").generate_mesh(Vec3::new(0.0, -0.0, -4.0))),
// None,
//Some(load_segment("shoulder_left.vox").generate_mesh(Vec3::new(-3.0, -2.5, -8.0))),
//Some(load_segment("shoulder_right.vox").generate_mesh(Vec3::new(-3.0, -2.5, -8.0))),
// None,
// None,
// None,
// None,
// None,
// None,
// ];
let mut mesh = Mesh::new();
bone_meshes
@ -342,194 +265,6 @@ pub struct FigureState<S: Skeleton> {
skeleton: S,
}
impl<S: Skeleton> FigureState<S> {
pub fn new(renderer: &mut Renderer, skeleton: S) -> Self {
Self {
bone_consts: renderer.create_consts(&skeleton.compute_matrices()).unwrap(),
locals: renderer.create_consts(&[FigureLocals::default()]).unwrap(),
skeleton,
}
}
fn update(&mut self, renderer: &mut Renderer, pos: Vec3<f32>, dir: Vec3<f32>) {
let mat =
Mat4::<f32>::identity() *
Mat4::translation_3d(pos) *
Mat4::rotation_z(dir.y.atan2(dir.x));// + f32//::consts)::PI / 2.0);
let locals = FigureLocals::new(mat);
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
renderer.update_consts(&mut self.bone_consts, &self.skeleton.compute_matrices()).unwrap();
}
}
Some(load_segment("pants.vox").generate_mesh(Vec3::new(-2.5, -5.0, 0.0))),
Some(load_segment("hand.vox").generate_mesh(Vec3::new(0.0, -2.0, -7.0))),
Some(load_segment("hand.vox").generate_mesh(Vec3::new(0.0, -2.0, -7.0))),
Some(load_segment("foot.vox").generate_mesh(Vec3::new(-3.5, -2.5, -8.0))),
Some(load_segment("foot.vox").generate_mesh(Vec3::new(-3.5, -2.5, -8.0))),
Some(load_segment("sword.vox").generate_mesh(Vec3::new(0.0, -0.0, -4.0))),
None,
//Some(load_segment("shoulder_left.vox").generate_mesh(Vec3::new(-3.0, -2.5, -8.0))),
//Some(load_segment("shoulder_right.vox").generate_mesh(Vec3::new(-3.0, -2.5, -8.0))),
None,
None,
None,
None,
];
let mut mesh = Mesh::new();
bone_meshes
.iter()
.enumerate()
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i, bm)))
.for_each(|(i, bone_mesh)| {
mesh.push_mesh_map(bone_mesh, |vert| vert.with_bone_idx(i as u8))
});
>>>>>>> velocity tilt
let mut mesh = Mesh::new();
bone_meshes
.iter()
.enumerate()
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i, bm)))
.for_each(|(i, bone_mesh)| {
mesh.push_mesh_map(bone_mesh, |vert| vert.with_bone_idx(i as u8))
});
renderer.create_model(&mesh).unwrap()
}, tick));
}
}
&models[&character]
}
pub fn clean(&mut self, tick: u64) {
// TODO: Don't hard-code this
self.models.retain(|_, (_, last_used)| *last_used + 60 > tick);
}
fn load_mesh(filename: &'static str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
let fullpath: String = ["/voxygen/voxel/", filename].concat();
Segment::from(dot_vox::load_bytes(
assets::load(fullpath.as_str())
.expect("Error loading file")
.as_slice(),
).unwrap())
.generate_mesh(position)
}
fn load_head(head: Head) -> Mesh<FigurePipeline> {
Self::load_mesh(match head {
Head::DefaultHead => "head.vox",
}, Vec3::new(-3.5, -7.0, -6.0))
}
fn load_chest(chest: Chest) -> Mesh<FigurePipeline> {
Self::load_mesh(match chest {
Chest::DefaultChest => "chest.vox",
}, Vec3::new(-3.0, -6.0, 0.0))
}
fn load_belt(belt: Belt) -> Mesh<FigurePipeline> {
Self::load_mesh(match belt {
Belt::DefaultBelt => "belt.vox",
}, Vec3::new(-3.0, -5.0, 0.0))
}
fn load_pants(pants: Pants) -> Mesh<FigurePipeline> {
Self::load_mesh(match pants {
Pants::DefaultPants => "pants.vox",
}, Vec3::new(-3.0, -5.0, 0.0))
}
fn load_left_hand(hand: Hand) -> Mesh<FigurePipeline> {
Self::load_mesh(match hand {
Hand::DefaultHand => "hand.vox",
}, Vec3::new(0.0, -2.0, -6.0))
}
fn load_right_hand(hand: Hand) -> Mesh<FigurePipeline> {
Self::load_mesh(match hand {
Hand::DefaultHand => "hand.vox",
}, Vec3::new(0.0, -2.0, -6.0))
}
fn load_left_foot(foot: Foot) -> Mesh<FigurePipeline> {
Self::load_mesh(match foot {
Foot::DefaultFoot => "foot.vox",
}, Vec3::new(-4.0, -2.5, -6.0))
}
fn load_right_foot(foot: Foot) -> Mesh<FigurePipeline> {
Self::load_mesh(match foot {
Foot::DefaultFoot => "foot.vox",
}, Vec3::new(-4.0, -2.5, -6.0))
}
fn load_weapon(weapon: Weapon) -> Mesh<FigurePipeline> {
Self::load_mesh(match weapon {
Weapon::Sword => "sword.vox",
// TODO actually match against other weapons and set the right model
_ => "sword.vox",
}, Vec3::new(0.0, 0.0, 0.0))
}
pub fn maintain(&mut self, renderer: &mut Renderer, client: &mut Client) {
let time = client.state().get_time();
let ecs = client.state_mut().ecs_mut();
for (entity, pos, dir, character, animation_history) in (
&ecs.entities(),
&ecs.read_storage::<comp::phys::Pos>(),
&ecs.read_storage::<comp::phys::Dir>(),
&ecs.read_storage::<comp::Character>(),
&ecs.read_storage::<comp::AnimationHistory>(),
).join() {
let state = self.states
.entry(entity)
.or_insert_with(|| FigureState::new(renderer, CharacterSkeleton::new()));
let target_skeleton = match animation_history.current {
comp::character::Animation::Idle => IdleAnimation::update_skeleton(&mut state.skeleton, time),
comp::character::Animation::Run => RunAnimation::update_skeleton(&mut state.skeleton, time),
};
state.skeleton.interpolate(&target_skeleton);
state.update(renderer, pos.0, dir.0);
}
self.states.retain(|entity, _| ecs.entities().is_alive(*entity));
}
pub fn render(&mut self, renderer: &mut Renderer, client: &mut Client, globals: &Consts<Globals>) {
let tick = client.get_tick();
let ecs = client.state().ecs();
let models = &mut self.models;
for (entity, &character) in (
&ecs.entities(),
&ecs.read_storage::<comp::Character>(),
).join() {
let model = Self::get_or_create_model(models, renderer, tick, character);
let state = self.states.get(&entity).unwrap();
renderer.render_figure(
&model.0,
globals,
&state.locals,
&state.bone_consts,
);
}
}
}
pub struct FigureState<S: Skeleton> {
bone_consts: Consts<FigureBoneData>,
locals: Consts<FigureLocals>,
skeleton: S,
}
impl<S: Skeleton> FigureState<S> {
pub fn new(renderer: &mut Renderer, skeleton: S) -> Self {
Self {