From 8c6f26172187220566730f1a0fd21df6f8b29956 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Mon, 13 May 2019 19:43:10 -0400 Subject: [PATCH 01/21] first quadruped changes Former-commit-id: 71ad084a872c3bf96d5cbab53c376d214f3cdcd0 --- assets/voxygen/voxel/pigchest.vox | Bin 0 -> 2612 bytes assets/voxygen/voxel/pighead.vox | Bin 0 -> 2720 bytes assets/voxygen/voxel/pigleg_l.vox | Bin 0 -> 1144 bytes assets/voxygen/voxel/pigleg_r.vox | Bin 0 -> 1144 bytes common/src/comp/actor.rs | 37 +++ common/src/comp/mod.rs | 1 + server/src/cmd.rs | 2 +- voxygen/src/anim/character/run.rs | 1 + voxygen/src/anim/mod.rs | 2 +- voxygen/src/anim/quadruped/mod.rs | 68 +++++ voxygen/src/anim/quadruped/run.rs | 57 ++++ voxygen/src/scene/figure.rs | 2 + voxygen/src/scene/figure/figure.rs | 360 +++++++++++++++++++++++++ voxygen/src/scene/figure/figurequad.rs | 290 ++++++++++++++++++++ 14 files changed, 818 insertions(+), 2 deletions(-) create mode 100644 assets/voxygen/voxel/pigchest.vox create mode 100644 assets/voxygen/voxel/pighead.vox create mode 100644 assets/voxygen/voxel/pigleg_l.vox create mode 100644 assets/voxygen/voxel/pigleg_r.vox create mode 100644 voxygen/src/anim/quadruped/mod.rs create mode 100644 voxygen/src/anim/quadruped/run.rs create mode 100644 voxygen/src/scene/figure/figure.rs create mode 100644 voxygen/src/scene/figure/figurequad.rs diff --git a/assets/voxygen/voxel/pigchest.vox b/assets/voxygen/voxel/pigchest.vox new file mode 100644 index 0000000000000000000000000000000000000000..7fd1aadf10e4922f945f58217ef4efde78255097 GIT binary patch literal 2612 zcmc(fZ)l#?8OHDP=Q-zjn>ngYQI5My3#t(b)A&rD^`8U%48q9B1Hrd=|qH4M8?>sfggtW?b`1={Wi2;4g9#z zxzByB`#SggzS()t{r$(xY}>}My9w4m&uquo_~70Nl_ zuX6MT?q- zBG4z0^W+@b!FUgOU;103hI{B$O}?y44e#Jijjs$fesb|dP2fC{^NnWFrJlVt^JHH5 z3cN3rJTnQ!BRN+hbE=tz=WV`;_#hXULtu`9c?M>i%6;A$m|bdg=!sTpH0Xt1YP9fH z?lZSQ|BP-%H!#!8-N5{FIcK(k*|*RR%rNlT1U?5VddxNO*#u@>vu}ato=4B4>+$59 z?*P8==+W}%rzTGh%@%!I)FwQq;u#OA$(7oK22=%f8z1P>zlBy!ubN(US<@#K9rlSH zjv9xS64)Eh-^4mKYkINId|owVYBTT3oaH9Zo2YFychIILp_PknO6^u+PKmpT z-yQo10W33*T(zy7XYO&{BA3av65pN7=U46#9r+q!<~Nz>TOjWtlTQ#h3q%hYy#xU~ zROBL5tRp0PR1hIRLa%}d0TQ|uL5A)v8>5^2)x5Xh6EKvsKG(tO@X>p zU|r!iL2lOUi8+yj3TpNaJk-p=LF8^ER!#46r}!~E@Yd!oHN;Hb$XSWpH|jm>M9gsC z9Y5S?@$&!vb?eq?W@bj89x-is>4L8B{zCul?$-J9+f@Eu8~gJWnLpB_-iQ0uzjuX( zPOO)WRBd%nh>S)k|7 zeoLEYOxur|etyQZ=L7C;@6(cr0WF&u*4nudEuQMuz@a`3pIWMw?=07%hfK?!LHn3# z!#R`vnEunX?C3XToo*diezi`2ccDJKZLzfV+d68dv+xo83ywZ*I`ccz`O~I%-(){x zIyq|k%YCLxkD12VKfTj*_!06?nKliXcC9l#wb}Fn`R!}^G%-4$>Ft9$_UJ0j{NxrL zdwi45KlfAp`_zP1T;HP&tCs4{9}MczowsOmt7-OUrW3z3o%^k6?UFu?4KLF}Yj4uj z=Jnb++@py#i*@LZ8#K4;W{uywQIikft(hku)WN-vY5EuAI=p{UbElux#kXHlS67#= zU2wJf`}?(WXh3Ukx>4U>HKfrED|OG0*6Z-EuhW@74(Q`|hjr=w6?&1LbEi!2{nhl( zzni8f2KB=1YF&73lRo>$4ow}LuS2hN>&*{(bxBLV_V=$|y;_r7rgZblle+c5KK0J_ z>YYECK77#h>foS;hK97Of4A=1(vi(hYvI&Fojrc}Gu+$9cW22G?OXn$Zol=29y$1| zuHCgr@4tS7&W`u$2s8Wt`Iow)^}vqzH1)W&=lE&OzC5Sjbl%qQ|8`N|d-8y8-*-ZH z{^6W&Ofy;KmX*3C&aI?`JH`LEQeopR`ORm KYlN?S-~I>LK`;gY literal 0 HcmV?d00001 diff --git a/assets/voxygen/voxel/pighead.vox b/assets/voxygen/voxel/pighead.vox new file mode 100644 index 0000000000000000000000000000000000000000..b54551b43fa849bede4a62bb4537c3414cc07935 GIT binary patch literal 2720 zcmc(gU5H-Q6^8fO`|O|deQin1Wa3P0G99CtnG|h)j7d%Hq{)~}G}@Rp)iDiH6di_G zGl-aB2$*T4X_^|+Fj`P!EFtt0qaMa!@gfEZB8W&TrBH&1NUsXLD5ZCApM7#Cn%fS% z?4PyQTJL(-I^XQN=f1vKW6buAqj$5I-?og|IXX7-jeOuQuL)G(zWc{UcLz57%@*7j zMWp8|3u2VO;Tt+G zpYe4?-g|(JcrM%Wdz=$v6R_Mx_($GG_CCjHYRsI;iEqF+@FrmM5tELd>!%1ywa!AeV__O$HKoXBYO+-UADs)co0AYiMj)Mi_+H? zzLq=&?QG`i0_T!g%p|-#I#*3zdJ+OLm>V>Uc|`};tZ0ZXmixrn(hJ|{h-UEiKGJV^ zqh)CJ^bBnam&hM#Q__EOdiZ-Z@aXEO!xJ;*HTMZWM~v94d47poCiH<9aU6Ac?i_JK zbI*)4_uQeqrx&jD$^=2)&OZBP zZL(j(FUOB{Y`8FE*eZ~+9>lLeqLvEy%o9F=etTxs(+8h>PtO9g>GOOtTPgUILb=b< zN0(Q4SJa^x0+~^oebb6^)zQ0_Hb{j2wn%J{O8_pYOx>l!%jfIN_ZI4tA1s!( zeMcvZ(K+x}@C7*Wl+oGW8(lbK^ue2)hmB5+7`=V3(d9>s#yCH<%jnoc+&^iwY0zlT zI-@5y8$Hkcjy1g+AL-ZBjseX+yh_tQy;ZZ1ZqkKc|4jclJ+2kkcWc9{rMmNn1A2JZ zt(w?oH1l(#lTR3(f7WR2l3tAtEz|C`H)(S7dhHtO*7%ymI=bZs&F#5aV?W-gi3ji2 z^y3fc$bm;R^~*6GJ2auWGtcPKdoQZpZtL0w^VQearJ{?)5jYhvr9ZeDpxw;evHo|zuK|BBHk4;Z~VFrdM~LG9_=tGl+=GBZgp1ab+1HH`7k|jF0`~}^9+i^W~(OyE`?CJ|U5<7C&JQ*D zsI>pNGn)D1oPJlor$4-VNw++HShpWMsXJdfubppP((v%G{<&W=3Ftp^myACB^A&zN kbf~d^X1?0~>0^(Hudw;fzHZINue0U*tJ#{sSNAvn1Bx<1MF0Q* literal 0 HcmV?d00001 diff --git a/assets/voxygen/voxel/pigleg_l.vox b/assets/voxygen/voxel/pigleg_l.vox new file mode 100644 index 0000000000000000000000000000000000000000..11848b935e25dced04b57f7151b05ead7397b291 GIT binary patch literal 1144 zcmc(eUr3W-6vof`1CkY*bGBK!rsX!H@=vB^HPe-|tjw}nB@s%FVa15jF$7&kCYG3} zfn^pV8JUhHMHeO^Aw+~l1R)U-T?Ji4bocB1w5up@JMi$F^E}@<@Atjm`r}pP$F@9C^R>v%&L$8D@UcxOyfIFa{wLq{dd9|z(c-@A;jD;q7%(0;W3EfZ z){}!c=Of+)NbeG4+(1;Z5LYcMYZX=x2@zglQBa6cwc(zSSsY1GbrkOU7%q=2rywAd zv(%TIA$L@e{c3%G1k%13 z3F&D{iKc&DEN?c)L(vM_MHo?dtMFN&y+#(LQ17q~KO{O_|VI zq4aY?zD+347S0t2T}m&>G~sbt@RwNWs7xntU;`ah`HWpU$d^73sYwQM(-Yab)kGpVzakU&F9H(NHfQPF&nrR8zF ze6W%cw~;orXMgU$_MA5BaOn$tRZ!d6Pw-BdE1_pxe>%zfGfix1=wav0QA&poZ9YfG%WMYYl z6=Y^1l9AO|QgmSw5w z$_m`uRFmpiA{B0rYpzaI&6vVW)%Wi6xU+Rp)s!FBM8cXTb)v~>O`9>Gi8dgbg6f(m zu8)R#uUBqvF2P`sPaQ%@_bAH@zxZJ=FfvkxUU%IOr$vm@i0P08OG7I5 zo;<`g8}ZFSdKV(2Mq*)W249%grQutt1B>x98e!brdH;(_8$q1Pom+9`}55j=|5RSNCZ zNM|qwnMrKfXrrcb z4Zcz#bWrFyDGXl}auUtB9myQXNyA^1N2SAvH#>p0;^joD((&vlz;|dH!4vywZ8$>U zxQF&;ACdmEj6LfnIy#y~u?w(REM(ZNPZ37Qpn;0kQzrTN0Ru;YzKj|60tZQk) z6f*Jrrto&ZaK~oDZnslqsbyl&z zb#FOC9upnv%>F!o{W(2rU&TxON1^_5KcQO@E`* Self { + Self { + race: *thread_rng().choose(&ALL_QRACES).unwrap(), + body_type: *thread_rng().choose(&ALL_QBODY_TYPES).unwrap(), + head: *thread_rng().choose(&ALL_QHEADS).unwrap(), + chest: *thread_rng().choose(&ALL_QCHESTS).unwrap(), + hand: *thread_rng().choose(&ALL_QHANDS).unwrap(), + foot: *thread_rng().choose(&ALL_QFEET).unwrap(), + } + } +} #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Body { Humanoid(HumanoidBody), + Quadruped(QuadrupedBody), } #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 1d14704377..e3c35e5ab8 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -9,5 +9,6 @@ pub use actor::Animation; pub use actor::AnimationHistory; pub use actor::Body; pub use actor::HumanoidBody; +pub use actor::QuadrupedBody; pub use agent::{Agent, Control}; pub use player::Player; diff --git a/server/src/cmd.rs b/server/src/cmd.rs index b12ecafe17..58a668a6b1 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -194,7 +194,7 @@ fn handle_pet(server: &mut Server, entity: EcsEntity, args: String, action: &Cha server .create_npc( "Bungo".to_owned(), - comp::Body::Humanoid(comp::HumanoidBody::random()), + comp::Body::Quadruped(comp::QuadrupedBody::random()), ) .with(comp::Control::default()) .with(comp::Agent::Pet { diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index b79751c20b..22b738e27c 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -71,6 +71,7 @@ impl Animation for RunAnimation { next.r_shoulder.offset = Vec3::new(0.0, -3.0, 2.5); next.r_shoulder.ori = Quaternion::rotation_x(0.0); next.r_shoulder.scale = Vec3::one(); + next.torso.offset = Vec3::new(-0.5, -0.2, 0.4); next.torso.ori = Quaternion::rotation_x(-velocity * 0.05 - wavecos * 0.1); next.torso.scale = Vec3::one() / 11.0; diff --git a/voxygen/src/anim/mod.rs b/voxygen/src/anim/mod.rs index 38452e6c65..1c200a4114 100644 --- a/voxygen/src/anim/mod.rs +++ b/voxygen/src/anim/mod.rs @@ -1,5 +1,5 @@ pub mod character; - +pub mod quadruped; // Library use vek::*; diff --git a/voxygen/src/anim/quadruped/mod.rs b/voxygen/src/anim/quadruped/mod.rs new file mode 100644 index 0000000000..a22fe2c19e --- /dev/null +++ b/voxygen/src/anim/quadruped/mod.rs @@ -0,0 +1,68 @@ + +pub mod run; + +// Reexports +pub use self::run::RunAnimation; +// Crate +use crate::render::FigureBoneData; + +// Local +use super::{Bone, Skeleton}; + +const SCALE: f32 = 11.0; + +#[derive(Clone)] +pub struct QuadrupedSkeleton { + head: Bone, + chest: Bone, + lf_leg: Bone, + rf_leg: Bone, + lb_leg: Bone, + rb_leg: Bone, + +} + +impl QuadrupedSkeleton { + pub fn new() -> Self { + Self { + head: Bone::default(), + chest: Bone::default(), + lf_leg: Bone::default(), + rf_leg: Bone::default(), + lb_leg: Bone::default(), + rb_leg: Bone::default(), + } + } +} + +impl Skeleton for QuadrupedSkeleton { + fn compute_matrices(&self) -> [FigureBoneData; 16] { + [ + FigureBoneData::new(self.head.compute_base_matrix()), + FigureBoneData::new(self.chest.compute_base_matrix()), + FigureBoneData::new(self.lf_leg.compute_base_matrix()), + FigureBoneData::new(self.rf_leg.compute_base_matrix()), + FigureBoneData::new(self.lb_leg.compute_base_matrix()), + FigureBoneData::new(self.rb_leg.compute_base_matrix()), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + FigureBoneData::default(), + ] + } + + fn interpolate(&mut self, target: &Self) { + self.head.interpolate(&target.head); + self.chest.interpolate(&target.chest); + self.lf_leg.interpolate(&target.lf_leg); + self.rf_leg.interpolate(&target.rf_leg); + self.lb_leg.interpolate(&target.lb_leg); + self.rb_leg.interpolate(&target.rb_leg); + } +} diff --git a/voxygen/src/anim/quadruped/run.rs b/voxygen/src/anim/quadruped/run.rs new file mode 100644 index 0000000000..1e8a0913e3 --- /dev/null +++ b/voxygen/src/anim/quadruped/run.rs @@ -0,0 +1,57 @@ +// Standard +use std::f32::consts::PI; + +// Library +use vek::*; + +// Local +use super::{super::Animation, QuadrupedSkeleton, SCALE}; + +pub struct RunAnimation; + +impl Animation for RunAnimation { + type Skeleton = QuadrupedSkeleton; + type Dependency = (f32, f64); + + fn update_skeleton( + skeleton: &Self::Skeleton, + (velocity, global_time): Self::Dependency, + anim_time: f64, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave = (anim_time as f32 * 14.0).sin(); + let wavetest = (wave.cbrt()); + let fuzzwave = (anim_time as f32 * 12.0).sin(); + let wavecos = (anim_time as f32 * 14.0).cos(); + let wave_slow = (anim_time as f32 * 7.0 + PI).sin(); + let wavecos_slow = (anim_time as f32 * 8.0 + PI).cos(); + let wave_dip = (wave_slow.abs() - 0.5).abs(); + + next.head.offset = Vec3::new(5.5, 2.0, 11.0 + wavecos * 1.3); + next.head.ori = Quaternion::rotation_x(0.15); + next.head.scale = Vec3::one(); + + next.chest.offset = Vec3::new(5.5, 0.0, 7.0 + wavecos * 1.1); + next.chest.ori = Quaternion::rotation_z(wave * 0.1); + next.chest.scale = Vec3::one(); + + next.lf_leg.offset = Vec3::new(5.5, 0.0, 5.0 + wavecos * 1.1); + next.lf_leg.ori = Quaternion::rotation_z(wave * 0.25); + next.lf_leg.scale = Vec3::one(); + + next.rf_leg.offset = Vec3::new(5.5, 0.0, 2.0 + wavecos * 1.1); + next.rf_leg.ori = Quaternion::rotation_z(wave * 0.6); + next.rf_leg.scale = Vec3::one(); + + next.lb_leg.offset = Vec3::new(-6.0, 0.0 + wavecos * 2.5, 11.0 - wave * 1.5); + next.lb_leg.ori = Quaternion::rotation_x(wavecos * 0.9); + next.lb_leg.scale = Vec3::one(); + + next.rb_leg.offset = Vec3::new(9.0, 0.0 - wavecos * 2.5, 11.0 + wave * 1.5); + next.rb_leg.ori = Quaternion::rotation_x(wavecos * -0.9); + next.rb_leg.scale = Vec3::one(); + + next + } +} diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 9ef9dad08c..8beb0b3661 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -308,7 +308,9 @@ impl FigureMgr { state.bone_consts(), ); } + Body::Quadruped(body) => {..}; } // TODO: Non-humanoid bodies + }, // TODO: Non-character actors } diff --git a/voxygen/src/scene/figure/figure.rs b/voxygen/src/scene/figure/figure.rs new file mode 100644 index 0000000000..9ef9dad08c --- /dev/null +++ b/voxygen/src/scene/figure/figure.rs @@ -0,0 +1,360 @@ +use crate::{ + anim::{ + character::{CharacterSkeleton, IdleAnimation, JumpAnimation, RunAnimation}, + Animation, Skeleton, + }, + mesh::Meshable, + render::{ + Consts, FigureBoneData, FigureLocals, FigurePipeline, Globals, Mesh, Model, Renderer, + }, + Error, +}; +use client::Client; +use common::{ + assets, + comp::{ + self, + actor::{Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Weapon}, + Body, HumanoidBody, + }, + figure::Segment, + msg, +}; +use dot_vox::DotVoxData; +use specs::{Component, Entity as EcsEntity, Join, VecStorage}; +use std::{collections::HashMap, f32}; +use vek::*; + +pub struct FigureModelCache { + models: HashMap, u64)>, +} + +impl FigureModelCache { + pub fn new() -> Self { + Self { + models: HashMap::new(), + } + } + + pub fn get_or_create_model( + &mut self, + renderer: &mut Renderer, + body: HumanoidBody, + tick: u64, + ) -> &Model { + match self.models.get_mut(&body) { + Some((model, last_used)) => { + *last_used = tick; + } + None => { + self.models.insert( + body, + ( + { + let bone_meshes = [ + Some(Self::load_head(body.head)), + Some(Self::load_chest(body.chest)), + Some(Self::load_belt(body.belt)), + Some(Self::load_pants(body.pants)), + Some(Self::load_left_hand(body.hand)), + Some(Self::load_right_hand(body.hand)), + Some(Self::load_left_foot(body.foot)), + Some(Self::load_right_foot(body.foot)), + Some(Self::load_weapon(body.weapon)), + Some(Self::load_left_shoulder(body.shoulder)), + Some(Self::load_right_shoulder(body.shoulder)), + None, + 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) + }) + }); + + renderer.create_model(&mesh).unwrap() + }, + tick, + ), + ); + } + } + + &self.models[&body].0 + } + + pub fn clean(&mut self, tick: u64) { + // TODO: Don't hard-code this + self.models + .retain(|_, (_, last_used)| *last_used + 60 > tick); + } + + // TODO: Don't make this public + pub fn load_mesh(filename: &str, position: Vec3) -> Mesh { + let fullpath: String = ["/voxygen/voxel/", filename].concat(); + Segment::from(assets::load_expect::(fullpath.as_str()).as_ref()) + .generate_mesh(position) + } + + fn load_head(head: Head) -> Mesh { + Self::load_mesh( + match head { + Head::Default => "head.vox", + }, + Vec3::new(-7.0, -5.5, -6.0), + ) + } + + fn load_chest(chest: Chest) -> Mesh { + Self::load_mesh( + match chest { + Chest::Default => "chest.vox", + }, + Vec3::new(-6.0, -3.5, 0.0), + ) + } + + fn load_belt(belt: Belt) -> Mesh { + Self::load_mesh( + match belt { + Belt::Default => "belt.vox", + }, + Vec3::new(-5.0, -3.5, 0.0), + ) + } + + fn load_pants(pants: Pants) -> Mesh { + Self::load_mesh( + match pants { + Pants::Default => "pants.vox", + }, + Vec3::new(-5.0, -3.5, 0.0), + ) + } + + fn load_left_hand(hand: Hand) -> Mesh { + Self::load_mesh( + match hand { + Hand::Default => "hand.vox", + }, + Vec3::new(2.0, 0.0, -7.0), + ) + } + + fn load_right_hand(hand: Hand) -> Mesh { + Self::load_mesh( + match hand { + Hand::Default => "hand.vox", + }, + Vec3::new(2.0, 0.0, -7.0), + ) + } + + fn load_left_foot(foot: Foot) -> Mesh { + Self::load_mesh( + match foot { + Foot::Default => "foot.vox", + }, + Vec3::new(2.5, -3.5, -9.0), + ) + } + + fn load_right_foot(foot: Foot) -> Mesh { + Self::load_mesh( + match foot { + Foot::Default => "foot.vox", + }, + Vec3::new(2.5, -3.5, -9.0), + ) + } + + fn load_weapon(weapon: Weapon) -> Mesh { + 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, -4.0), + ) + } + + fn load_left_shoulder(shoulder: Shoulder) -> Mesh { + Self::load_mesh( + match shoulder { + Shoulder::Default => "shoulder_l.vox", + }, + Vec3::new(2.5, 0.0, 0.0), + ) + } + + fn load_right_shoulder(shoulder: Shoulder) -> Mesh { + Self::load_mesh( + match shoulder { + Shoulder::Default => "shoulder_r.vox", + }, + Vec3::new(2.5, 0.0, 0.0), + ) + } + // fn load_draw(draw: Draw) -> Mesh { + // Self::load_mesh( + // match draw { + // //Draw::DefaultDraw => "sword.vox", + // + // }, + // Vec3::new(0.0, 0.0, -2.0) + // + // + // ) + // } +} + +pub struct FigureMgr { + model_cache: FigureModelCache, + states: HashMap>, +} + +impl FigureMgr { + pub fn new() -> Self { + Self { + model_cache: FigureModelCache::new(), + states: HashMap::new(), + } + } + + pub fn clean(&mut self, tick: u64) { + self.model_cache.clean(tick); + } + + pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) { + let time = client.state().get_time(); + let ecs = client.state().ecs(); + for (entity, pos, vel, dir, actor, animation_history) in ( + &ecs.entities(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + ) + .join() + { + match actor { + comp::Actor::Character { body, .. } => match body { + Body::Humanoid(body) => { + let state = self.states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, CharacterSkeleton::new()) + }); + + let target_skeleton = match animation_history.current { + comp::Animation::Idle => IdleAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_history.time, + ), + comp::Animation::Run => RunAnimation::update_skeleton( + state.skeleton_mut(), + (vel.0.magnitude(), time), + animation_history.time, + ), + comp::Animation::Jump => JumpAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_history.time, + ), + }; + + state.skeleton.interpolate(&target_skeleton); + + state.update(renderer, pos.0, dir.0); + } // TODO: Non-humanoid bodies + }, + // TODO: Non-character actors + } + } + + self.states + .retain(|entity, _| ecs.entities().is_alive(*entity)); + } + + pub fn render( + &mut self, + renderer: &mut Renderer, + client: &mut Client, + globals: &Consts, + ) { + let tick = client.get_tick(); + let ecs = client.state().ecs(); + + for (entity, actor) in (&ecs.entities(), &ecs.read_storage::()).join() { + match actor { + comp::Actor::Character { body, .. } => match body { + Body::Humanoid(body) => { + if let Some(state) = self.states.get(&entity) { + let model = self.model_cache.get_or_create_model(renderer, *body, tick); + renderer.render_figure( + model, + globals, + &state.locals(), + state.bone_consts(), + ); + } + } // TODO: Non-humanoid bodies + }, + // TODO: Non-character actors + } + } + } +} + +pub struct FigureState { + bone_consts: Consts, + locals: Consts, + skeleton: S, +} + +impl FigureState { + 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, + } + } + + pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3) { + let mat = Mat4::::identity() + * Mat4::translation_3d(pos) + * Mat4::rotation_z(-dir.x.atan2(dir.y)); // + 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(); + } + + pub fn locals(&self) -> &Consts { + &self.locals + } + + pub fn bone_consts(&self) -> &Consts { + &self.bone_consts + } + + pub fn skeleton_mut(&mut self) -> &mut S { + &mut self.skeleton + } +} diff --git a/voxygen/src/scene/figure/figurequad.rs b/voxygen/src/scene/figure/figurequad.rs new file mode 100644 index 0000000000..aa76298aa1 --- /dev/null +++ b/voxygen/src/scene/figure/figurequad.rs @@ -0,0 +1,290 @@ +use crate::{ + anim::{ + quadruped::{QuadrupedSkeleton, RunAnimation}, + Animation, Skeleton, + }, + mesh::Meshable, + render::{ + Consts, FigureBoneData, FigureLocals, FigurePipeline, Globals, Mesh, Model, Renderer, + }, + Error, +}; +use client::Client; +use common::{ + assets, + comp::{ + self, + actor::{Head, Chest, l_leg, r_leg}, + Body, QuadrupedBody, + }, + figure::Segment, + msg, +}; +use dot_vox::DotVoxData; +use specs::{Component, Entity as EcsEntity, Join, VecStorage}; +use std::{collections::HashMap, f32}; +use vek::*; + +pub struct FigureModelCache { + models: HashMap, u64)>, +} + +impl FigureModelCache { + pub fn new() -> Self { + Self { + models: HashMap::new(), + } + } + + pub fn get_or_create_model( + &mut self, + renderer: &mut Renderer, + body: QuadrupedBody, + tick: u64, + ) -> &Model { + match self.models.get_mut(&body) { + Some((model, last_used)) => { + *last_used = tick; + } + None => { + self.models.insert( + body, + ( + { + let bone_meshes = [ + Some(Self::load_head(body.head)), + Some(Self::load_chest(body.chest)), + Some(Self::load_lf_leg(body.leg_l)), + Some(Self::load_rf_leg(body.leg_r)), + Some(Self::load_lb_leg(body.leg_l)), + Some(Self::load_rb_leg(body.leg_r)), + None, + None, + None, + None, + None, + None, + 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) + }) + }); + + renderer.create_model(&mesh).unwrap() + }, + tick, + ), + ); + } + } + + &self.models[&body].0 + } + + pub fn clean(&mut self, tick: u64) { + // TODO: Don't hard-code this + self.models + .retain(|_, (_, last_used)| *last_used + 60 > tick); + } + + // TODO: Don't make this public + pub fn load_mesh(filename: &str, position: Vec3) -> Mesh { + let fullpath: String = ["/voxygen/voxel/", filename].concat(); + Segment::from(assets::load_expect::(fullpath.as_str()).as_ref()) + .generate_mesh(position) + } + + fn load_head(head: Head) -> Mesh { + Self::load_mesh( + match head { + Head::Default => "pighead.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_chest(chest: Chest) -> Mesh { + Self::load_mesh( + match chest { + Chest::Default => "pigchest.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_lf_leg(leg_l: Leg_l) -> Mesh { + Self::load_mesh( + match belt { + Belt::Default => "pigleg_l.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_rf_leg(leg_R: Leg_r) -> Mesh { + Self::load_mesh( + match pants { + Pants::Default => "pigleg_r.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_lb_leg(leg_l: Leg_l) -> Mesh { + Self::load_mesh( + match hand { + Hand::Default => "pigleg_l.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_rb_leg(leg_R: Leg_r) -> Mesh { + Self::load_mesh( + match hand { + Hand::Default => "pigleg_r.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } +} + +pub struct FigureMgr { + model_cache: FigureModelCache, + states: HashMap>, +} + +impl FigureMgr { + pub fn new() -> Self { + Self { + model_cache: FigureModelCache::new(), + states: HashMap::new(), + } + } + + pub fn clean(&mut self, tick: u64) { + self.model_cache.clean(tick); + } + + pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) { + let time = client.state().get_time(); + let ecs = client.state().ecs(); + for (entity, pos, vel, dir, actor, animation_history) in ( + &ecs.entities(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + &ecs.read_storage::(), + ) + .join() + { + match actor { + comp::Actor::Quadruped { body, .. } => match body { + Body::Humanoid(body) => { + let state = self.states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, QuadrupedSkeleton::new()) + }); + comp::Animation::Run => RunAnimation::update_skeleton( + state.skeleton_mut(), + (vel.0.magnitude(), time), + animation_history.time, + ), + }; + + state.skeleton.interpolate(&target_skeleton); + + state.update(renderer, pos.0, dir.0); + } // TODO: Non-humanoid bodies + }, + // TODO: Non-character actors + } + } + + self.states + .retain(|entity, _| ecs.entities().is_alive(*entity)); + } + + pub fn render( + &mut self, + renderer: &mut Renderer, + client: &mut Client, + globals: &Consts, + ) { + let tick = client.get_tick(); + let ecs = client.state().ecs(); + + for (entity, actor) in (&ecs.entities(), &ecs.read_storage::()).join() { + match actor { + comp::Actor::Quadruped { body, .. } => match body { + Body::Humanoid(body) => { + if let Some(state) = self.states.get(&entity) { + let model = self.model_cache.get_or_create_model(renderer, *body, tick); + renderer.render_figure( + model, + globals, + &state.locals(), + state.bone_consts(), + ); + } + } // TODO: Non-humanoid bodies + }, + // TODO: Non-character actors + } + } + } +} + +pub struct FigureState { + bone_consts: Consts, + locals: Consts, + skeleton: S, +} + +impl FigureState { + 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, + } + } + + pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3) { + let mat = Mat4::::identity() + * Mat4::translation_3d(pos) + * Mat4::rotation_z(-dir.x.atan2(dir.y)); // + 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(); + } + + pub fn locals(&self) -> &Consts { + &self.locals + } + + pub fn bone_consts(&self) -> &Consts { + &self.bone_consts + } + + pub fn skeleton_mut(&mut self) -> &mut S { + &mut self.skeleton + } +} From 65f0aec8fd6b08e852c52304eea4a8285395c78b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 14 May 2019 01:02:37 +0100 Subject: [PATCH 02/21] Made model cache handle non-humanoids Former-commit-id: 4b3efb70ba24a8e4c8e1d933752e8ea28d3e8dd1 --- voxygen/src/menu/char_selection/scene.rs | 4 +- voxygen/src/scene/figure.rs | 112 +++++++++++++++-------- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index e8511215f0..b295904796 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -13,7 +13,7 @@ use crate::{ }, }; use client::Client; -use common::{comp::HumanoidBody, figure::Segment}; +use common::{comp, figure::Segment}; use vek::*; struct Skybox { @@ -108,7 +108,7 @@ impl Scene { let model = self.figure_model_cache.get_or_create_model( renderer, - HumanoidBody::random(), + comp::Body::Humanoid(comp::HumanoidBody::random()), client.get_tick(), ); renderer.render_figure( diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 8beb0b3661..39359d6ae6 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -1,6 +1,7 @@ use crate::{ anim::{ character::{CharacterSkeleton, IdleAnimation, JumpAnimation, RunAnimation}, + quadruped::{QuadrupedSkeleton}, Animation, Skeleton, }, mesh::Meshable, @@ -26,7 +27,7 @@ use std::{collections::HashMap, f32}; use vek::*; pub struct FigureModelCache { - models: HashMap, u64)>, + models: HashMap, u64)>, } impl FigureModelCache { @@ -39,7 +40,7 @@ impl FigureModelCache { pub fn get_or_create_model( &mut self, renderer: &mut Renderer, - body: HumanoidBody, + body: Body, tick: u64, ) -> &Model { match self.models.get_mut(&body) { @@ -51,24 +52,44 @@ impl FigureModelCache { body, ( { - let bone_meshes = [ - Some(Self::load_head(body.head)), - Some(Self::load_chest(body.chest)), - Some(Self::load_belt(body.belt)), - Some(Self::load_pants(body.pants)), - Some(Self::load_left_hand(body.hand)), - Some(Self::load_right_hand(body.hand)), - Some(Self::load_left_foot(body.foot)), - Some(Self::load_right_foot(body.foot)), - Some(Self::load_weapon(body.weapon)), - Some(Self::load_left_shoulder(body.shoulder)), - Some(Self::load_right_shoulder(body.shoulder)), - None, - None, - None, - None, - None, - ]; + let bone_meshes = match body { + Body::Humanoid(body) => [ + Some(Self::load_head(body.head)), + Some(Self::load_chest(body.chest)), + Some(Self::load_belt(body.belt)), + Some(Self::load_pants(body.pants)), + Some(Self::load_left_hand(body.hand)), + Some(Self::load_right_hand(body.hand)), + Some(Self::load_left_foot(body.foot)), + Some(Self::load_right_foot(body.foot)), + Some(Self::load_weapon(body.weapon)), + Some(Self::load_left_shoulder(body.shoulder)), + Some(Self::load_right_shoulder(body.shoulder)), + None, + None, + None, + None, + None, + ], + Body::Quadruped(body) => [ // TODO + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + ], + }; let mut mesh = Mesh::new(); bone_meshes @@ -220,14 +241,16 @@ impl FigureModelCache { pub struct FigureMgr { model_cache: FigureModelCache, - states: HashMap>, + character_states: HashMap>, + quadruped_states: HashMap>, } impl FigureMgr { pub fn new() -> Self { Self { model_cache: FigureModelCache::new(), - states: HashMap::new(), + character_states: HashMap::new(), + quadruped_states: HashMap::new(), } } @@ -251,7 +274,7 @@ impl FigureMgr { match actor { comp::Actor::Character { body, .. } => match body { Body::Humanoid(body) => { - let state = self.states.entry(entity).or_insert_with(|| { + let state = self.character_states.entry(entity).or_insert_with(|| { FigureState::new(renderer, CharacterSkeleton::new()) }); @@ -276,14 +299,24 @@ impl FigureMgr { state.skeleton.interpolate(&target_skeleton); state.update(renderer, pos.0, dir.0); - } // TODO: Non-humanoid bodies + }, + Body::Quadruped(body) => { + let state = self.quadruped_states.entry(entity).or_insert_with(|| { + FigureState::new(renderer, QuadrupedSkeleton::new()) + }); + + // TODO! Animations here, like above! + + state.update(renderer, pos.0, dir.0); + }, }, // TODO: Non-character actors } } - self.states - .retain(|entity, _| ecs.entities().is_alive(*entity)); + // Clear states that have dead entities + self.character_states.retain(|entity, _| ecs.entities().is_alive(*entity)); + self.quadruped_states.retain(|entity, _| ecs.entities().is_alive(*entity)); } pub fn render( @@ -297,22 +330,21 @@ impl FigureMgr { for (entity, actor) in (&ecs.entities(), &ecs.read_storage::()).join() { match actor { - comp::Actor::Character { body, .. } => match body { - Body::Humanoid(body) => { - if let Some(state) = self.states.get(&entity) { - let model = self.model_cache.get_or_create_model(renderer, *body, tick); - renderer.render_figure( - model, - globals, - &state.locals(), - state.bone_consts(), - ); - } - Body::Quadruped(body) => {..}; - } // TODO: Non-humanoid bodies + comp::Actor::Character { body, .. } => { + if let Some((locals, bone_consts)) = match body { + Body::Humanoid(_) => self.character_states.get(&entity).map(|state| (state.locals(), state.bone_consts())), + Body::Quadruped(_) => self.quadruped_states.get(&entity).map(|state| (state.locals(), state.bone_consts())), + } { + let model = self.model_cache.get_or_create_model(renderer, *body, tick); + renderer.render_figure( + model, + globals, + locals, + bone_consts, + ); + } }, - // TODO: Non-character actors } } } From 5347275c3cdf0a564823a6411004b1abc955439f Mon Sep 17 00:00:00 2001 From: jshipsey Date: Mon, 13 May 2019 22:24:34 -0400 Subject: [PATCH 03/21] added skeleton, needs animation fix Former-commit-id: f2c741426c073f3bfab3cdcd5b7f401a4fc6400e --- common/src/comp/actor.rs | 44 +++++++++++----- voxygen/src/anim/quadruped/mod.rs | 48 +++++++++--------- voxygen/src/anim/quadruped/run.rs | 36 +++++++------- voxygen/src/scene/figure.rs | 83 +++++++++++++++++++++++++++---- 4 files changed, 146 insertions(+), 65 deletions(-) diff --git a/common/src/comp/actor.rs b/common/src/comp/actor.rs index c1e5ca48fc..5772350fa8 100644 --- a/common/src/comp/actor.rs +++ b/common/src/comp/actor.rs @@ -69,6 +69,26 @@ pub enum Shoulder { pub enum Draw { Default, } +//// +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Pighead { + Default, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Pigchest { + Default, +} +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Pigleg_l { + Default, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum Pigleg_r { + Default, +} +//// const ALL_RACES: [Race; 6] = [ Race::Danari, @@ -137,19 +157,19 @@ const ALL_QRACES: [Race; 6] = [ Race::Orc, Race::Undead,]; const ALL_QBODY_TYPES: [BodyType; 3] = [BodyType::Female, BodyType::Male, BodyType::Unspecified]; -const ALL_QHEADS: [Head; 1] = [Head::Default]; -const ALL_QCHESTS: [Chest; 1] = [Chest::Default]; -const ALL_QHANDS: [Hand; 1] = [Hand::Default]; -const ALL_QFEET: [Foot; 1] = [Foot::Default]; +const ALL_QHEADS: [Pighead; 1] = [Pighead::Default]; +const ALL_QCHESTS: [Pigchest; 1] = [Pigchest::Default]; +const ALL_QPIGLEG_LS: [Pigleg_l; 1] = [Pigleg_l::Default]; +const ALL_QPIGLEG_RS: [Pigleg_r; 1] = [Pigleg_r::Default]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct QuadrupedBody { pub race: Race, pub body_type: BodyType, - pub head: Head, - pub chest: Chest, - pub hand: Hand, - pub foot: Foot, + pub pighead: Pighead, + pub pigchest: Pigchest, + pub pigleg_l: Pigleg_l, + pub pigleg_r: Pigleg_r, } @@ -158,10 +178,10 @@ impl QuadrupedBody { Self { race: *thread_rng().choose(&ALL_QRACES).unwrap(), body_type: *thread_rng().choose(&ALL_QBODY_TYPES).unwrap(), - head: *thread_rng().choose(&ALL_QHEADS).unwrap(), - chest: *thread_rng().choose(&ALL_QCHESTS).unwrap(), - hand: *thread_rng().choose(&ALL_QHANDS).unwrap(), - foot: *thread_rng().choose(&ALL_QFEET).unwrap(), + pighead: *thread_rng().choose(&ALL_QHEADS).unwrap(), + pigchest: *thread_rng().choose(&ALL_QCHESTS).unwrap(), + pigleg_l: *thread_rng().choose(&ALL_QPIGLEG_LS).unwrap(), + pigleg_r: *thread_rng().choose(&ALL_QPIGLEG_RS).unwrap(), } } } diff --git a/voxygen/src/anim/quadruped/mod.rs b/voxygen/src/anim/quadruped/mod.rs index a22fe2c19e..ba5db031c0 100644 --- a/voxygen/src/anim/quadruped/mod.rs +++ b/voxygen/src/anim/quadruped/mod.rs @@ -13,24 +13,24 @@ const SCALE: f32 = 11.0; #[derive(Clone)] pub struct QuadrupedSkeleton { - head: Bone, - chest: Bone, - lf_leg: Bone, - rf_leg: Bone, - lb_leg: Bone, - rb_leg: Bone, + pighead: Bone, + pigchest: Bone, + piglf_leg: Bone, + pigrf_leg: Bone, + piglb_leg: Bone, + pigrb_leg: Bone, } impl QuadrupedSkeleton { pub fn new() -> Self { Self { - head: Bone::default(), - chest: Bone::default(), - lf_leg: Bone::default(), - rf_leg: Bone::default(), - lb_leg: Bone::default(), - rb_leg: Bone::default(), + pighead: Bone::default(), + pigchest: Bone::default(), + piglf_leg: Bone::default(), + pigrf_leg: Bone::default(), + piglb_leg: Bone::default(), + pigrb_leg: Bone::default(), } } } @@ -38,12 +38,12 @@ impl QuadrupedSkeleton { impl Skeleton for QuadrupedSkeleton { fn compute_matrices(&self) -> [FigureBoneData; 16] { [ - FigureBoneData::new(self.head.compute_base_matrix()), - FigureBoneData::new(self.chest.compute_base_matrix()), - FigureBoneData::new(self.lf_leg.compute_base_matrix()), - FigureBoneData::new(self.rf_leg.compute_base_matrix()), - FigureBoneData::new(self.lb_leg.compute_base_matrix()), - FigureBoneData::new(self.rb_leg.compute_base_matrix()), + FigureBoneData::new(self.pighead.compute_base_matrix()), + FigureBoneData::new(self.pigchest.compute_base_matrix()), + FigureBoneData::new(self.piglf_leg.compute_base_matrix()), + FigureBoneData::new(self.pigrf_leg.compute_base_matrix()), + FigureBoneData::new(self.piglb_leg.compute_base_matrix()), + FigureBoneData::new(self.pigrb_leg.compute_base_matrix()), FigureBoneData::default(), FigureBoneData::default(), FigureBoneData::default(), @@ -58,11 +58,11 @@ impl Skeleton for QuadrupedSkeleton { } fn interpolate(&mut self, target: &Self) { - self.head.interpolate(&target.head); - self.chest.interpolate(&target.chest); - self.lf_leg.interpolate(&target.lf_leg); - self.rf_leg.interpolate(&target.rf_leg); - self.lb_leg.interpolate(&target.lb_leg); - self.rb_leg.interpolate(&target.rb_leg); + self.pighead.interpolate(&target.pighead); + self.pigchest.interpolate(&target.pigchest); + self.piglf_leg.interpolate(&target.piglf_leg); + self.pigrf_leg.interpolate(&target.pigrf_leg); + self.piglb_leg.interpolate(&target.piglb_leg); + self.pigrb_leg.interpolate(&target.pigrb_leg); } } diff --git a/voxygen/src/anim/quadruped/run.rs b/voxygen/src/anim/quadruped/run.rs index 1e8a0913e3..c1db8eca76 100644 --- a/voxygen/src/anim/quadruped/run.rs +++ b/voxygen/src/anim/quadruped/run.rs @@ -28,29 +28,29 @@ impl Animation for RunAnimation { let wavecos_slow = (anim_time as f32 * 8.0 + PI).cos(); let wave_dip = (wave_slow.abs() - 0.5).abs(); - next.head.offset = Vec3::new(5.5, 2.0, 11.0 + wavecos * 1.3); - next.head.ori = Quaternion::rotation_x(0.15); - next.head.scale = Vec3::one(); + next.pighead.offset = Vec3::new(5.5, 2.0, 11.0 + wavecos * 1.3); + next.pighead.ori = Quaternion::rotation_x(0.15); + next.pighead.scale = Vec3::one(); - next.chest.offset = Vec3::new(5.5, 0.0, 7.0 + wavecos * 1.1); - next.chest.ori = Quaternion::rotation_z(wave * 0.1); - next.chest.scale = Vec3::one(); + next.pigchest.offset = Vec3::new(5.5, 0.0, 7.0 + wavecos * 1.1); + next.pigchest.ori = Quaternion::rotation_z(wave * 0.1); + next.pigchest.scale = Vec3::one(); - next.lf_leg.offset = Vec3::new(5.5, 0.0, 5.0 + wavecos * 1.1); - next.lf_leg.ori = Quaternion::rotation_z(wave * 0.25); - next.lf_leg.scale = Vec3::one(); + next.piglf_leg.offset = Vec3::new(5.5, 0.0, 5.0 + wavecos * 1.1); + next.piglf_leg.ori = Quaternion::rotation_z(wave * 0.25); + next.piglf_leg.scale = Vec3::one(); - next.rf_leg.offset = Vec3::new(5.5, 0.0, 2.0 + wavecos * 1.1); - next.rf_leg.ori = Quaternion::rotation_z(wave * 0.6); - next.rf_leg.scale = Vec3::one(); + next.pigrf_leg.offset = Vec3::new(5.5, 0.0, 2.0 + wavecos * 1.1); + next.pigrf_leg.ori = Quaternion::rotation_z(wave * 0.6); + next.pigrf_leg.scale = Vec3::one(); - next.lb_leg.offset = Vec3::new(-6.0, 0.0 + wavecos * 2.5, 11.0 - wave * 1.5); - next.lb_leg.ori = Quaternion::rotation_x(wavecos * 0.9); - next.lb_leg.scale = Vec3::one(); + next.piglb_leg.offset = Vec3::new(-6.0, 0.0 + wavecos * 2.5, 11.0 - wave * 1.5); + next.piglb_leg.ori = Quaternion::rotation_x(wavecos * 0.9); + next.piglb_leg.scale = Vec3::one(); - next.rb_leg.offset = Vec3::new(9.0, 0.0 - wavecos * 2.5, 11.0 + wave * 1.5); - next.rb_leg.ori = Quaternion::rotation_x(wavecos * -0.9); - next.rb_leg.scale = Vec3::one(); + next.pigrb_leg.offset = Vec3::new(9.0, 0.0 - wavecos * 2.5, 11.0 + wave * 1.5); + next.pigrb_leg.ori = Quaternion::rotation_x(wavecos * -0.9); + next.pigrb_leg.scale = Vec3::one(); next } diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 39359d6ae6..9d3bf34ad0 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -1,7 +1,7 @@ use crate::{ anim::{ character::{CharacterSkeleton, IdleAnimation, JumpAnimation, RunAnimation}, - quadruped::{QuadrupedSkeleton}, + quadruped::{QuadrupedSkeleton,}, Animation, Skeleton, }, mesh::Meshable, @@ -15,8 +15,8 @@ use common::{ assets, comp::{ self, - actor::{Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Weapon}, - Body, HumanoidBody, + actor::{Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Weapon, Pighead, Pigchest, Pigleg_l, Pigleg_r}, + Body, HumanoidBody, QuadrupedBody }, figure::Segment, msg, @@ -71,13 +71,13 @@ impl FigureModelCache { None, None, ], - Body::Quadruped(body) => [ // TODO - None, - None, - None, - None, - None, - None, + Body::Quadruped(body) => [ + Some(Self::load_pighead(body.pighead)), + Some(Self::load_pigchest(body.pigchest)), + Some(Self::load_piglf_leg(body.pigleg_l)), + Some(Self::load_pigrf_leg(body.pigleg_r)), + Some(Self::load_piglb_leg(body.pigleg_l)), + Some(Self::load_pigrb_leg(body.pigleg_r)), None, None, None, @@ -237,8 +237,63 @@ impl FigureModelCache { // // ) // } + + fn load_pighead(pighead: Pighead) -> Mesh { + Self::load_mesh( + match pighead { + Pighead::Default => "pighead.vox", + }, + Vec3::new(0.0, 5.0, 0.0), + ) + } + + fn load_pigchest(pigchest: Pigchest) -> Mesh { + Self::load_mesh( + match pigchest { + Pigchest::Default => "pigchest.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_piglf_leg(pigleg_l: Pigleg_l) -> Mesh { + Self::load_mesh( + match pigleg_l { + Pigleg_l::Default => "pigleg_l.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_pigrf_leg(pigleg_r: Pigleg_r) -> Mesh { + Self::load_mesh( + match pigleg_r { + Pigleg_r::Default => "pigleg_r.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_piglb_leg(pigleg_l: Pigleg_l) -> Mesh { + Self::load_mesh( + match pigleg_l { + Pigleg_l::Default => "pigleg_l.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } + + fn load_pigrb_leg(pigleg_r: Pigleg_r) -> Mesh { + Self::load_mesh( + match pigleg_r { + Pigleg_r::Default => "pigleg_r.vox", + }, + Vec3::new(0.0, 0.0, 0.0), + ) + } } + pub struct FigureMgr { model_cache: FigureModelCache, character_states: HashMap>, @@ -305,7 +360,13 @@ impl FigureMgr { FigureState::new(renderer, QuadrupedSkeleton::new()) }); - // TODO! Animations here, like above! + let target_skeleton = match animation_history.current { + comp::Animation::Run => RunAnimation::update_skeleton( + state.skeleton_mut(), + (vel.0.magnitude(), time), + animation_history.time, + ), + }; state.update(renderer, pos.0, dir.0); }, From 52445612090cbe07b0cc67e7bf0602b1ba4e37a3 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 14 May 2019 12:37:05 +0100 Subject: [PATCH 04/21] Fixed quadruped animation selection Former-commit-id: 03315efa2c88a4ac3517835b25f7a14cd1599cf0 --- voxygen/src/scene/figure.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 9d3bf34ad0..54babc7875 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -1,7 +1,7 @@ use crate::{ anim::{ - character::{CharacterSkeleton, IdleAnimation, JumpAnimation, RunAnimation}, - quadruped::{QuadrupedSkeleton,}, + character::{self, CharacterSkeleton}, + quadruped::{self, QuadrupedSkeleton}, Animation, Skeleton, }, mesh::Meshable, @@ -334,17 +334,17 @@ impl FigureMgr { }); let target_skeleton = match animation_history.current { - comp::Animation::Idle => IdleAnimation::update_skeleton( + comp::Animation::Idle => character::IdleAnimation::update_skeleton( state.skeleton_mut(), time, animation_history.time, ), - comp::Animation::Run => RunAnimation::update_skeleton( + comp::Animation::Run => character::RunAnimation::update_skeleton( state.skeleton_mut(), (vel.0.magnitude(), time), animation_history.time, ), - comp::Animation::Jump => JumpAnimation::update_skeleton( + comp::Animation::Jump => character::JumpAnimation::update_skeleton( state.skeleton_mut(), time, animation_history.time, @@ -361,13 +361,17 @@ impl FigureMgr { }); let target_skeleton = match animation_history.current { - comp::Animation::Run => RunAnimation::update_skeleton( + comp::Animation::Run => quadruped::RunAnimation::update_skeleton( state.skeleton_mut(), (vel.0.magnitude(), time), animation_history.time, ), + // TODO! + _ => state.skeleton_mut().clone(), }; + state.skeleton.interpolate(&target_skeleton); + state.update(renderer, pos.0, dir.0); }, }, From 70a7c78c50fdd9b1a436eb1ece1e9f1ca75f6e48 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Wed, 15 May 2019 00:24:36 -0400 Subject: [PATCH 05/21] idle, run, jump animations Former-commit-id: e476dc3aaf2197876c80eeba17837aee976f8df9 --- assets/voxygen/voxel/pigchest.vox | Bin 2612 -> 2752 bytes voxygen/src/anim/quadruped/idle.rs | 75 +++++++++++++++++++++++++++++ voxygen/src/anim/quadruped/jump.rs | 59 +++++++++++++++++++++++ voxygen/src/anim/quadruped/mod.rs | 6 +++ voxygen/src/anim/quadruped/run.rs | 38 ++++++++------- voxygen/src/scene/figure.rs | 22 ++++++--- 6 files changed, 176 insertions(+), 24 deletions(-) create mode 100644 voxygen/src/anim/quadruped/idle.rs create mode 100644 voxygen/src/anim/quadruped/jump.rs diff --git a/assets/voxygen/voxel/pigchest.vox b/assets/voxygen/voxel/pigchest.vox index 7fd1aadf10e4922f945f58217ef4efde78255097..0c82a2bbd04acbe1c10c7b9117a6504900b8dada 100644 GIT binary patch delta 222 zcmW;EF$w}f429vC$z*m}5Ek9u$~#zETBx0@wqC+Q@C-JV9w6ArdH@^m<*&sfd0!x} z>AP!p+kSQvk@a%5VaVg!PP&?gx Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave = (anim_time as f32 * 14.0).sin(); + let wavetest = (wave.cbrt()); + let waveultra_slow = (anim_time as f32 * 1.0 + PI).sin(); + let waveultracos_slow = (anim_time as f32 * 1.0 + PI).cos(); + let fuzzwave = (anim_time as f32 * 12.0).sin(); + let wavecos = (anim_time as f32 * 14.0).cos(); + let wave_slow = (anim_time as f32 * 3.5 + PI).sin(); + let wavecos_slow = (anim_time as f32 * 3.5 + PI).cos(); + let wave_dip = (wave_slow.abs() - 0.5).abs(); + + let pighead_look = Vec2::new( + ((global_time + anim_time) as f32 / 8.0) + .floor() + .mul(7331.0) + .sin() + * 0.5, + ((global_time + anim_time) as f32 / 8.0) + .floor() + .mul(1337.0) + .sin() + * 0.25, + ); + + next.pighead.offset = Vec3::new(0.0, 7.0, -1.5 + wave * 0.2) / 11.0; + next.pighead.ori = Quaternion::rotation_z(pighead_look.x) * Quaternion::rotation_x(pighead_look.y + wavecos_slow * 0.03); + next.pighead.scale = Vec3::one() / 10.5; + + next.pigchest.offset = Vec3::new(wave_slow * 0.05, 0.0, 1.5 + wavecos_slow * 0.4) / 11.0; + next.pigchest.ori = Quaternion::rotation_y(wave_slow * 0.05); + next.pigchest.scale = Vec3::one() / 11.0; + + next.piglf_leg.offset = Vec3::new(-4.5, 11.0, 1.5) / 11.0; + next.piglf_leg.ori = Quaternion::rotation_x(wave_slow * 0.08); + next.piglf_leg.scale = Vec3::one() / 11.0; + + next.pigrf_leg.offset = Vec3::new(2.5, 11.0, 1.5) / 11.0; + next.pigrf_leg.ori = Quaternion::rotation_x(wavecos_slow * 0.08); + next.pigrf_leg.scale = Vec3::one() / 11.0; + + next.piglb_leg.offset = Vec3::new(-4.5, 6.0, 1.5) / 11.0; + next.piglb_leg.ori = Quaternion::rotation_x(wavecos_slow * 0.08); + next.piglb_leg.scale = Vec3::one() / 11.0; + + next.pigrb_leg.offset = Vec3::new(2.5, 6.0, 1.5) / 11.0; + next.pigrb_leg.ori = Quaternion::rotation_x(wave_slow * 0.08); + next.pigrb_leg.scale = Vec3::one() / 11.0; + + + + + next + } +} diff --git a/voxygen/src/anim/quadruped/jump.rs b/voxygen/src/anim/quadruped/jump.rs new file mode 100644 index 0000000000..da2e17fa76 --- /dev/null +++ b/voxygen/src/anim/quadruped/jump.rs @@ -0,0 +1,59 @@ +// Standard +use std::f32::consts::PI; + +// Library +use vek::*; + +// Local +use super::{super::Animation, QuadrupedSkeleton, SCALE}; + +pub struct JumpAnimation; + +impl Animation for JumpAnimation { + type Skeleton = QuadrupedSkeleton; + type Dependency = (f32, f64); + + fn update_skeleton( + skeleton: &Self::Skeleton, + (velocity, global_time): Self::Dependency, + anim_time: f64, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + + let wave = (anim_time as f32 * 14.0).sin(); + let wavetest = (wave.cbrt()); + let fuzzwave = (anim_time as f32 * 12.0).sin(); + let wavecos = (anim_time as f32 * 14.0).cos(); + let wave_slow = (anim_time as f32 * 7.0 + PI).sin(); + let wavecos_slow = (anim_time as f32 * 8.0 + PI).cos(); + let wave_dip = (wave_slow.abs() - 0.5).abs(); + let wave_stop = (anim_time as f32 * 4.5).min(PI / 2.0).sin(); + + + next.pighead.offset = Vec3::new(0.0, 9.0, -1.5 ) / 11.0; + next.pighead.ori = Quaternion::rotation_x(wave_stop * 0.4); + next.pighead.scale = Vec3::one() / 10.5; + + next.pigchest.offset = Vec3::new(0.0, 0.0, 1.5) / 11.0; + next.pigchest.ori = Quaternion::rotation_x(0.0); + next.pigchest.scale = Vec3::one() / 11.0; + + next.piglf_leg.offset = Vec3::new(-4.5, 12.0, 1.5) / 11.0; + next.piglf_leg.ori = Quaternion::rotation_x(wave_stop * 0.6); + next.piglf_leg.scale = Vec3::one() / 11.0; + + next.pigrf_leg.offset = Vec3::new(2.5, 12.0, 1.5) / 11.0; + next.pigrf_leg.ori = Quaternion::rotation_x(wave_stop * 0.6 - wave_slow * 0.3); + next.pigrf_leg.scale = Vec3::one() / 11.0; + + next.piglb_leg.offset = Vec3::new(-4.5, 5.0, 2.0) / 11.0; + next.piglb_leg.ori = Quaternion::rotation_x(wave_stop * -0.6 + wave_slow * 0.3); + next.piglb_leg.scale = Vec3::one() / 11.0; + + next.pigrb_leg.offset = Vec3::new(2.5, 5.0, 2.0) / 11.0; + next.pigrb_leg.ori = Quaternion::rotation_x(wave_stop * -0.6 + wave_slow * 0.3); + next.pigrb_leg.scale = Vec3::one() / 11.0; + + next + } +} diff --git a/voxygen/src/anim/quadruped/mod.rs b/voxygen/src/anim/quadruped/mod.rs index ba5db031c0..a6b7e4474c 100644 --- a/voxygen/src/anim/quadruped/mod.rs +++ b/voxygen/src/anim/quadruped/mod.rs @@ -1,8 +1,14 @@ pub mod run; +pub mod idle; +pub mod jump; + // Reexports pub use self::run::RunAnimation; +pub use self::idle::IdleAnimation; +pub use self::jump::JumpAnimation; + // Crate use crate::render::FigureBoneData; diff --git a/voxygen/src/anim/quadruped/run.rs b/voxygen/src/anim/quadruped/run.rs index c1db8eca76..9c0db36edd 100644 --- a/voxygen/src/anim/quadruped/run.rs +++ b/voxygen/src/anim/quadruped/run.rs @@ -21,6 +21,8 @@ impl Animation for RunAnimation { let mut next = (*skeleton).clone(); let wave = (anim_time as f32 * 14.0).sin(); + let wavequick = (anim_time as f32 * 20.0).sin(); + let wavequickcos = (anim_time as f32 * 20.0).cos(); let wavetest = (wave.cbrt()); let fuzzwave = (anim_time as f32 * 12.0).sin(); let wavecos = (anim_time as f32 * 14.0).cos(); @@ -28,29 +30,29 @@ impl Animation for RunAnimation { let wavecos_slow = (anim_time as f32 * 8.0 + PI).cos(); let wave_dip = (wave_slow.abs() - 0.5).abs(); - next.pighead.offset = Vec3::new(5.5, 2.0, 11.0 + wavecos * 1.3); - next.pighead.ori = Quaternion::rotation_x(0.15); - next.pighead.scale = Vec3::one(); + next.pighead.offset = Vec3::new(0.0, 9.0, -1.5 + wave * 1.5) / 11.0; + next.pighead.ori = Quaternion::rotation_x(0.2 + wave * 0.05) * Quaternion::rotation_y(wavecos * 0.03); + next.pighead.scale = Vec3::one() / 10.5; - next.pigchest.offset = Vec3::new(5.5, 0.0, 7.0 + wavecos * 1.1); - next.pigchest.ori = Quaternion::rotation_z(wave * 0.1); - next.pigchest.scale = Vec3::one(); + next.pigchest.offset = Vec3::new(0.0, 0.0, 1.5 + wavecos * 1.2) / 11.0; + next.pigchest.ori = Quaternion::rotation_x(wave * 0.1); + next.pigchest.scale = Vec3::one() / 11.0; - next.piglf_leg.offset = Vec3::new(5.5, 0.0, 5.0 + wavecos * 1.1); - next.piglf_leg.ori = Quaternion::rotation_z(wave * 0.25); - next.piglf_leg.scale = Vec3::one(); + next.piglf_leg.offset = Vec3::new(-4.5, 11.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; + next.piglf_leg.ori = Quaternion::rotation_x(wavequick * 0.3); + next.piglf_leg.scale = Vec3::one() / 11.0; - next.pigrf_leg.offset = Vec3::new(5.5, 0.0, 2.0 + wavecos * 1.1); - next.pigrf_leg.ori = Quaternion::rotation_z(wave * 0.6); - next.pigrf_leg.scale = Vec3::one(); + next.pigrf_leg.offset = Vec3::new(2.5, 11.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; + next.pigrf_leg.ori = Quaternion::rotation_x(wavequickcos * -0.3); + next.pigrf_leg.scale = Vec3::one() / 11.0; - next.piglb_leg.offset = Vec3::new(-6.0, 0.0 + wavecos * 2.5, 11.0 - wave * 1.5); - next.piglb_leg.ori = Quaternion::rotation_x(wavecos * 0.9); - next.piglb_leg.scale = Vec3::one(); + next.piglb_leg.offset = Vec3::new(-4.5, 6.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; + next.piglb_leg.ori = Quaternion::rotation_x(wavequickcos * -0.3); + next.piglb_leg.scale = Vec3::one() / 11.0; - next.pigrb_leg.offset = Vec3::new(9.0, 0.0 - wavecos * 2.5, 11.0 + wave * 1.5); - next.pigrb_leg.ori = Quaternion::rotation_x(wavecos * -0.9); - next.pigrb_leg.scale = Vec3::one(); + next.pigrb_leg.offset = Vec3::new(2.5, 6.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; + next.pigrb_leg.ori = Quaternion::rotation_x(wavequick * 0.3); + next.pigrb_leg.scale = Vec3::one() / 11.0; next } diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 54babc7875..b93b72ab3b 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -243,7 +243,7 @@ impl FigureModelCache { match pighead { Pighead::Default => "pighead.vox", }, - Vec3::new(0.0, 5.0, 0.0), + Vec3::new(-6.0, 4.5, 3.0), ) } @@ -252,7 +252,7 @@ impl FigureModelCache { match pigchest { Pigchest::Default => "pigchest.vox", }, - Vec3::new(0.0, 0.0, 0.0), + Vec3::new(-5.0, 4.5, 0.0), ) } @@ -261,7 +261,7 @@ impl FigureModelCache { match pigleg_l { Pigleg_l::Default => "pigleg_l.vox", }, - Vec3::new(0.0, 0.0, 0.0), + Vec3::new(0.0, -1.0, -1.5), ) } @@ -270,7 +270,7 @@ impl FigureModelCache { match pigleg_r { Pigleg_r::Default => "pigleg_r.vox", }, - Vec3::new(0.0, 0.0, 0.0), + Vec3::new(0.0, -1.0, -1.5), ) } @@ -279,7 +279,7 @@ impl FigureModelCache { match pigleg_l { Pigleg_l::Default => "pigleg_l.vox", }, - Vec3::new(0.0, 0.0, 0.0), + Vec3::new(0.0, -1.0, -1.5), ) } @@ -288,7 +288,7 @@ impl FigureModelCache { match pigleg_r { Pigleg_r::Default => "pigleg_r.vox", }, - Vec3::new(0.0, 0.0, 0.0), + Vec3::new(0.0, -1.0, -1.5), ) } } @@ -366,6 +366,16 @@ impl FigureMgr { (vel.0.magnitude(), time), animation_history.time, ), + comp::Animation::Idle => quadruped::IdleAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_history.time, + ), + comp::Animation::Jump => quadruped::JumpAnimation::update_skeleton( + state.skeleton_mut(), + (vel.0.magnitude(), time), + animation_history.time, + ), // TODO! _ => state.skeleton_mut().clone(), }; From b01a94e3848812dcdb453ec523023ea35dc9e5ea Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Mon, 13 May 2019 17:28:17 -0600 Subject: [PATCH 06/21] Change vec to BufReader Former-commit-id: 0e91de7976357c96ac58e4f4293c680b9ab98155 --- common/src/assets/mod.rs | 17 +++++++++-------- voxygen/src/ui/mod.rs | 7 ++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/common/src/assets/mod.rs b/common/src/assets/mod.rs index 685cb5654b..5a98f4e57a 100644 --- a/common/src/assets/mod.rs +++ b/common/src/assets/mod.rs @@ -5,6 +5,7 @@ use std::{ any::Any, collections::HashMap, fs::File, + io::BufReader, io::Read, sync::{Arc, RwLock}, }; @@ -74,13 +75,17 @@ pub trait Asset: Send + Sync + Sized { impl Asset for DynamicImage { fn load(specifier: &str) -> Result { - Ok(image::load_from_memory(load_from_path(specifier)?.as_slice()).unwrap()) + let mut buf = Vec::new(); + load_from_path(specifier)?.read_to_end(&mut buf)?; + Ok(image::load_from_memory(&buf).unwrap()) } } impl Asset for DotVoxData { fn load(specifier: &str) -> Result { - Ok(dot_vox::load_bytes(load_from_path(specifier)?.as_slice()).unwrap()) + let mut buf = Vec::new(); + load_from_path(specifier)?.read_to_end(&mut buf)?; + Ok(dot_vox::load_bytes(&buf).unwrap()) } } @@ -104,13 +109,9 @@ fn try_open_with_path(name: &str) -> Option { .find_map(|ref filename| File::open(filename).ok()) } -pub fn load_from_path(name: &str) -> Result, Error> { +pub fn load_from_path(name: &str) -> Result, Error> { match try_open_with_path(name) { - Some(mut f) => { - let mut content = Vec::::new(); - f.read_to_end(&mut content)?; - Ok(content) - } + Some(mut f) => Ok(BufReader::new(f)), None => Err(Error::NotFound(name.to_owned())), } } diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index 9af2f75d3e..5bf71acd8b 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -36,6 +36,7 @@ use conrod_core::{ }; use graphic::Id as GraphicId; use scale::Scale; +use std::io::Read; use std::ops::Range; use std::sync::Arc; use util::{linear_to_srgb, srgb_to_linear}; @@ -73,9 +74,9 @@ impl DrawCommand { pub struct Font(text::Font); impl assets::Asset for Font { fn load(specifier: &str) -> Result { - Ok(Font( - text::Font::from_bytes(assets::load_from_path(specifier)?).unwrap(), - )) + let mut buf = Vec::new(); + assets::load_from_path(specifier)?.read_to_end(&mut buf)?; + Ok(Font(text::Font::from_bytes(buf.clone()).unwrap())) } } From fe1916d64fc9772cdae7f1c9036fff159e0e8fd2 Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 14 May 2019 03:41:27 -0400 Subject: [PATCH 07/21] add backtrace to panic hook Former-commit-id: c831dfa85ebfa1ace05e5ffdec5cc68954394ae1 --- Cargo.lock | 1 + voxygen/Cargo.toml | 1 + voxygen/src/main.rs | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ef697517e0..9cbd1837a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2350,6 +2350,7 @@ dependencies = [ name = "veloren-voxygen" version = "0.2.0" dependencies = [ + "backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "conrod_core 0.63.0 (git+https://gitlab.com/veloren/conrod.git)", "conrod_winit 0.63.0 (git+https://gitlab.com/veloren/conrod.git)", diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index b622a16a06..9334546e4f 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -48,3 +48,4 @@ msgbox = "0.1" directories = "1.0" portpicker = "0.1" num = "0.2" +backtrace = "0.3" \ No newline at end of file diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs index f57958ba4e..24561d228a 100644 --- a/voxygen/src/main.rs +++ b/voxygen/src/main.rs @@ -138,7 +138,11 @@ The information below is intended for developers and testers. Panic Payload: {:?} PanicInfo: {}", settings_clone.log.file, reason, panic_info); - log::error!("VOXYGEN HAS PANICKED\n\n{}", msg); + log::error!( + "VOXYGEN HAS PANICKED\n\n{}\n\nBacktrace:\n{:?}", + msg, + backtrace::Backtrace::new() + ); msgbox::create("Voxygen has panicked", &msg, msgbox::IconType::ERROR); From 3a17d1ff912e9fca588930657cbbf480c40faa16 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 13 May 2019 14:58:01 +0100 Subject: [PATCH 08/21] Added figure colour to shader and health component Former-commit-id: 222c39bd401ad0a9707eb348d5640717004dbf96 --- common/src/comp/mod.rs | 2 ++ common/src/comp/phys.rs | 6 ++-- common/src/comp/stats.rs | 38 ++++++++++++++++++++++++ common/src/msg/ecs_packet.rs | 2 ++ common/src/state.rs | 1 + server/src/lib.rs | 2 ++ voxygen/shaders/figure.frag | 3 +- voxygen/shaders/figure.vert | 1 + voxygen/src/menu/char_selection/scene.rs | 2 +- voxygen/src/render/pipelines/figure.rs | 11 +++++-- voxygen/src/scene/figure.rs | 19 ++++++++---- 11 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 common/src/comp/stats.rs diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index e3c35e5ab8..a75e09c083 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -2,6 +2,7 @@ pub mod actor; pub mod agent; pub mod phys; pub mod player; +pub mod stats; // Reexports pub use actor::Actor; @@ -12,3 +13,4 @@ pub use actor::HumanoidBody; pub use actor::QuadrupedBody; pub use agent::{Agent, Control}; pub use player::Player; +pub use stats::Stats; diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index dd8b02ced3..67df6ac1ba 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -7,7 +7,7 @@ use vek::*; pub struct Pos(pub Vec3); impl Component for Pos { - type Storage = FlaggedStorage>; + type Storage = VecStorage; } // Vel @@ -16,7 +16,7 @@ impl Component for Pos { pub struct Vel(pub Vec3); impl Component for Vel { - type Storage = FlaggedStorage>; + type Storage = VecStorage; } // Dir @@ -25,7 +25,7 @@ impl Component for Vel { pub struct Dir(pub Vec3); impl Component for Dir { - type Storage = FlaggedStorage>; + type Storage = VecStorage; } // Dir diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs new file mode 100644 index 0000000000..3b6e263af2 --- /dev/null +++ b/common/src/comp/stats.rs @@ -0,0 +1,38 @@ +use specs::{Component, FlaggedStorage, VecStorage}; + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct Health { + pub current: u32, + pub maximum: u32, + pub last_change: Option<(i32, f64)>, +} + +impl Health { + pub fn change_by(&mut self, amount: i32, current_time: f64) { + self.current = (self.current as i32 + amount).max(0) as u32; + self.last_change = Some((amount, current_time)); + } +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct Stats { + pub hp: Health, + pub xp: u32, +} + +impl Default for Stats { + fn default() -> Self { + Self { + hp: Health { + current: 100, + maximum: 100, + last_change: None, + }, + xp: 0, + } + } +} + +impl Component for Stats { + type Storage = FlaggedStorage>; +} diff --git a/common/src/msg/ecs_packet.rs b/common/src/msg/ecs_packet.rs index b7da55f0a8..74ffabacbf 100644 --- a/common/src/msg/ecs_packet.rs +++ b/common/src/msg/ecs_packet.rs @@ -11,6 +11,7 @@ sphynx::sum_type! { Dir(comp::phys::Dir), Actor(comp::Actor), Player(comp::Player), + Stats(comp::Stats), } } // Automatically derive From for Phantom for each variant Phantom::T(PhantomData) @@ -22,6 +23,7 @@ sphynx::sum_type! { Dir(PhantomData), Actor(PhantomData), Player(PhantomData), + Stats(PhantomData), } } impl sphynx::Packet for EcsPacket { diff --git a/common/src/state.rs b/common/src/state.rs index 509ca67ca7..e0054dfa69 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -97,6 +97,7 @@ impl State { // Register synced components ecs.register_synced::(); ecs.register_synced::(); + ecs.register_synced::(); // Register unsynched (or synced by other means) components ecs.register::(); diff --git a/server/src/lib.rs b/server/src/lib.rs index 1430a7f5e1..6fb89abf48 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -125,6 +125,7 @@ impl Server { .with(comp::phys::Dir(Vec3::unit_y())) .with(comp::AnimationHistory::new(comp::Animation::Idle)) .with(comp::Actor::Character { name, body }) + .with(comp::Stats::default()) } pub fn create_player_character( @@ -141,6 +142,7 @@ impl Server { body: comp::Body::Humanoid(body), }, ); + state.write_component(entity, comp::Stats::default()); state.write_component(entity, comp::phys::Pos(Vec3::new(0.0, 0.0, 64.0))); state.write_component(entity, comp::phys::Vel(Vec3::zero())); state.write_component(entity, comp::phys::Dir(Vec3::unit_y())); diff --git a/voxygen/shaders/figure.frag b/voxygen/shaders/figure.frag index 4a933ab4f7..9f35b6b04a 100644 --- a/voxygen/shaders/figure.frag +++ b/voxygen/shaders/figure.frag @@ -10,6 +10,7 @@ flat in uint f_bone_idx; layout (std140) uniform u_locals { mat4 model_mat; + vec4 model_col; }; struct BoneData { @@ -36,5 +37,5 @@ void main() { float sun_diffuse = dot(sun_dir, world_norm) * 0.5; - tgt_color = vec4(f_col * (ambient + sun_diffuse), 1.0); + tgt_color = model_col * vec4(f_col * (ambient + sun_diffuse), 1.0); } diff --git a/voxygen/shaders/figure.vert b/voxygen/shaders/figure.vert index 258f4f1f45..4db80ee7c4 100644 --- a/voxygen/shaders/figure.vert +++ b/voxygen/shaders/figure.vert @@ -10,6 +10,7 @@ in uint v_bone_idx; layout (std140) uniform u_locals { mat4 model_mat; + vec4 model_col; }; struct BoneData { diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index b295904796..7ff104e41f 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -100,7 +100,7 @@ impl Scene { self.figure_state.skeleton_mut().interpolate(&tgt_skeleton); self.figure_state - .update(renderer, Vec3::zero(), -Vec3::unit_y()); + .update(renderer, Vec3::zero(), -Vec3::unit_y(), Rgba::broadcast(1.0)); } pub fn render(&mut self, renderer: &mut Renderer, client: &Client) { diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index e7fc4436bb..d7036f5d3d 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -27,6 +27,7 @@ gfx_defines! { constant Locals { model_mat: [[f32; 4]; 4] = "model_mat", + model_col: [f32; 4] = "model_col", } constant BoneData { @@ -62,13 +63,17 @@ impl Vertex { } impl Locals { - pub fn new(model_mat: Mat4) -> Self { + pub fn new(model_mat: Mat4, col: Rgba) -> Self { Self { model_mat: arr_to_mat(model_mat.into_col_array()), + model_col: col.into_array(), } } - pub fn default() -> Self { - Self::new(Mat4::identity()) +} + +impl Default for Locals { + fn default() -> Self { + Self::new(Mat4::identity(), Rgba::broadcast(1.0)) } } diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index b93b72ab3b..d4e98dee22 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -316,13 +316,14 @@ impl FigureMgr { pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) { let time = client.state().get_time(); let ecs = client.state().ecs(); - for (entity, pos, vel, dir, actor, animation_history) in ( + for (entity, pos, vel, dir, actor, animation_history, stats) in ( &ecs.entities(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), &ecs.read_storage::(), + ecs.read_storage::().maybe(), ) .join() { @@ -353,7 +354,7 @@ impl FigureMgr { state.skeleton.interpolate(&target_skeleton); - state.update(renderer, pos.0, dir.0); + state.update(renderer, pos.0, dir.0, Rgba::white()); }, Body::Quadruped(body) => { let state = self.quadruped_states.entry(entity).or_insert_with(|| { @@ -382,7 +383,15 @@ impl FigureMgr { state.skeleton.interpolate(&target_skeleton); - state.update(renderer, pos.0, dir.0); + // Change in health as color! + let col = stats + .and_then(|stats| stats.hp.last_change) + .map(|(change_by, change_time)| { + Rgba::new(1.0, 0.7, 0.7, 1.0) + }) + .unwrap_or(Rgba::broadcast(1.0)); + + state.update(renderer, pos.0, dir.0, col); }, }, // TODO: Non-character actors @@ -442,12 +451,12 @@ impl FigureState { } } - pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3) { + pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3, col: Rgba) { let mat = Mat4::::identity() * Mat4::translation_3d(pos) * Mat4::rotation_z(-dir.x.atan2(dir.y)); // + f32::consts::PI / 2.0); - let locals = FigureLocals::new(mat); + let locals = FigureLocals::new(mat, col); renderer.update_consts(&mut self.locals, &[locals]).unwrap(); renderer From a2bf4b8b5f65989bb7c05e79fdb15a8df8c194aa Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 13 May 2019 18:26:07 +0100 Subject: [PATCH 09/21] Fixed pet spawning bug Former-commit-id: 78dcd034940a4de1ce7d66a79d9134be6ee281f2 --- client/src/lib.rs | 5 ++--- common/src/sys/agent.rs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index a4cd2cb0f4..01da8675f2 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -201,8 +201,7 @@ impl Client { self.state.terrain().iter().for_each(|(key, _)| { if (Vec2::from(chunk_pos) - Vec2::from(key)) .map(|e: i32| e.abs()) - .reduce_max() - > 6 + .reduce_max() > 10 { chunks_to_remove.push(key); } @@ -213,7 +212,7 @@ impl Client { // Request chunks from the server // TODO: This is really not very efficient - 'outer: for dist in 0..9 { + 'outer: for dist in 0..10 { for i in chunk_pos.x - dist..chunk_pos.x + dist + 1 { for j in chunk_pos.y - dist..chunk_pos.y + dist + 1 { for k in 0..3 { diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index d13d6cc3df..893d6e8f56 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -41,7 +41,7 @@ impl<'a> System<'a> for Sys { let dist = tgt_pos.distance(pos.0); control.move_dir = if dist > 5.0 { Vec2::from(tgt_pos - pos.0).normalized() - } else if dist < 1.5 && pos.0 != tgt_pos { + } else if dist < 1.5 && dist > 0.0 { Vec2::from(pos.0 - tgt_pos).normalized() } else { Vec2::zero() From 3686becf21c002b108c779221747116dd152103f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 13 May 2019 18:59:47 +0100 Subject: [PATCH 10/21] Fixed singleplayer logout crash due to orphaned mesh worker Former-commit-id: 2b8c5aa0c906223ac043db8137ad95a0e29407c5 --- voxygen/src/scene/terrain.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 2a53e879b9..daf0c29327 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -157,8 +157,7 @@ impl Terrain { // Queue the worker thread client.thread_pool().execute(move || { - send.send(mesh_worker(pos, current_tick, volume, aabb)) - .expect("Failed to send chunk mesh to main thread"); + let _ = send.send(mesh_worker(pos, current_tick, volume, aabb)); }); todo.active_worker = true; } From 7d36fbb5eea00e53fb05ffbdfff5a2d67bd4080e Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 13 May 2019 21:59:42 +0100 Subject: [PATCH 11/21] Added test gliding Former-commit-id: 7aa1513511490feec531f10e58ad955c485ac594 --- client/src/input.rs | 2 ++ client/src/lib.rs | 1 + common/src/comp/agent.rs | 2 ++ common/src/sys/control.rs | 4 ++++ voxygen/src/key_state.rs | 2 ++ voxygen/src/session.rs | 3 +++ voxygen/src/settings.rs | 2 ++ voxygen/src/window.rs | 2 ++ 8 files changed, 18 insertions(+) diff --git a/client/src/input.rs b/client/src/input.rs index 840ee46525..a274697e29 100644 --- a/client/src/input.rs +++ b/client/src/input.rs @@ -7,6 +7,7 @@ pub enum InputEvent { pub struct Input { pub move_dir: Vec2, pub jumping: bool, + pub gliding: bool, pub events: Vec, } @@ -15,6 +16,7 @@ impl Default for Input { Input { move_dir: Vec2::zero(), jumping: false, + gliding: false, events: Vec::new(), } } diff --git a/client/src/lib.rs b/client/src/lib.rs index 01da8675f2..cc44d1c6a8 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -156,6 +156,7 @@ impl Client { comp::Control { move_dir: input.move_dir, jumping: input.jumping, + gliding: input.gliding, }, ); diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index f3ff742700..1159316afc 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -18,6 +18,7 @@ impl Component for Agent { pub struct Control { pub move_dir: Vec2, pub jumping: bool, + pub gliding: bool, } impl Default for Control { @@ -25,6 +26,7 @@ impl Default for Control { Self { move_dir: Vec2::zero(), jumping: false, + gliding: false, } } } diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index c8ddf2d2cc..62ff038ee3 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -53,6 +53,10 @@ impl<'a> System<'a> for Sys { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration vel.0 += control.move_dir * 0.2 - vel.0.map(|e| e * e.abs() + e) * 0.002; + + if control.gliding && vel.0.z < 0.0 { + vel.0.z += 9.81 * 3.95 * dt.0; + } } let animation = if on_ground { diff --git a/voxygen/src/key_state.rs b/voxygen/src/key_state.rs index 22e666f0ba..909f1f3490 100644 --- a/voxygen/src/key_state.rs +++ b/voxygen/src/key_state.rs @@ -6,6 +6,7 @@ pub struct KeyState { pub up: bool, pub down: bool, pub jump: bool, + pub glide: bool, } impl KeyState { @@ -16,6 +17,7 @@ impl KeyState { up: false, down: false, jump: false, + glide: false, } } diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index b66d036118..a8c4b2c2d5 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -66,6 +66,7 @@ impl SessionState { Input { move_dir, jumping: self.key_state.jump, + gliding: self.key_state.glide, events: input_events, }, dt, @@ -145,12 +146,14 @@ impl PlayState for SessionState { self.input_events.push(InputEvent::Jump); self.key_state.jump = true; } + Event::KeyDown(Key::Glide) => self.key_state.glide = true, // Movement Key Released Event::KeyUp(Key::MoveForward) => self.key_state.up = false, Event::KeyUp(Key::MoveBack) => self.key_state.down = false, Event::KeyUp(Key::MoveLeft) => self.key_state.left = false, Event::KeyUp(Key::MoveRight) => self.key_state.right = false, Event::KeyUp(Key::Jump) => self.key_state.jump = false, + Event::KeyUp(Key::Glide) => self.key_state.glide = false, // Pass all other events to the scene event => { self.scene.handle_input_event(event); diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 5a22ee9936..b8f9c8b97b 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -25,6 +25,7 @@ pub struct ControlSettings { pub move_back: VirtualKeyCode, pub move_right: VirtualKeyCode, pub jump: VirtualKeyCode, + pub glide: VirtualKeyCode, pub map: VirtualKeyCode, pub bag: VirtualKeyCode, pub quest_log: VirtualKeyCode, @@ -60,6 +61,7 @@ impl Default for Settings { move_back: VirtualKeyCode::S, move_right: VirtualKeyCode::D, jump: VirtualKeyCode::Space, + glide: VirtualKeyCode::LShift, map: VirtualKeyCode::M, bag: VirtualKeyCode::B, quest_log: VirtualKeyCode::L, diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 9f5cdd44fb..0bd0241f13 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -46,6 +46,7 @@ impl Window { key_map.insert(settings.controls.move_back, Key::MoveBack); key_map.insert(settings.controls.move_right, Key::MoveRight); key_map.insert(settings.controls.jump, Key::Jump); + key_map.insert(settings.controls.glide, Key::Glide); key_map.insert(settings.controls.map, Key::Map); key_map.insert(settings.controls.bag, Key::Bag); key_map.insert(settings.controls.quest_log, Key::QuestLog); @@ -182,6 +183,7 @@ pub enum Key { MoveLeft, MoveRight, Jump, + Glide, Enter, Escape, Map, From 8651f8139df551686f95c88f8d7c3073db0f5e1e Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 14 May 2019 00:25:49 +0100 Subject: [PATCH 12/21] Fixed physics Former-commit-id: b4b208754e38aba2150efe99d319638910f64904 --- common/src/sys/control.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index 62ff038ee3..cf18e0826b 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -41,27 +41,39 @@ impl<'a> System<'a> for Sys { .unwrap_or(false) && vel.0.z <= 0.0; - if on_ground { + let friction = if on_ground { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration - vel.0 += control.move_dir * 4.0 - vel.0.map(|e| e * vel.0.magnitude() + e) * 0.05; + vel.0 += control.move_dir * 4.0; if control.jumping { vel.0.z += 16.0; } + + 0.15 } else { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration vel.0 += control.move_dir * 0.2 - vel.0.map(|e| e * e.abs() + e) * 0.002; if control.gliding && vel.0.z < 0.0 { - vel.0.z += 9.81 * 3.95 * dt.0; + // TODO: Don't hard-code this + let anti_grav = 9.81 * 3.95; + vel.0.z += anti_grav * dt.0 * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); } + + 0.006 + }; + + // Friction + vel.0 -= vel.0.map(|e| (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)).min(e.abs()).copysign(e)) * Vec3::new(1.0, 1.0, 0.0); + + if vel.0.magnitude_squared() != 0.0 { + dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); } let animation = if on_ground { if control.move_dir.magnitude() > 0.01 { - dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); Animation::Run } else { Animation::Idle From 6f1a9adba26b87f6c8ace75fecea4ca83d30d981 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 14 May 2019 00:42:50 +0100 Subject: [PATCH 13/21] Fixed friction Former-commit-id: d9ac7fa7fb98c2ac829470fa8deeb314cc0f15f6 --- common/src/sys/control.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index cf18e0826b..7c1f41ce91 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -54,15 +54,17 @@ impl<'a> System<'a> for Sys { } else { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration - vel.0 += control.move_dir * 0.2 - vel.0.map(|e| e * e.abs() + e) * 0.002; + vel.0 += control.move_dir * 0.2; if control.gliding && vel.0.z < 0.0 { // TODO: Don't hard-code this let anti_grav = 9.81 * 3.95; vel.0.z += anti_grav * dt.0 * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); - } - 0.006 + 0.008 + } else { + 0.015 + } }; // Friction From fb9f4114f76e129ae88dc23dccad174554e10e92 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 15 May 2019 17:06:58 +0100 Subject: [PATCH 14/21] Improved quadruped origin Former-commit-id: 35a360bf285f2495dda7859cb8d376d5aa16a1af --- client/src/lib.rs | 2 +- common/src/msg/client.rs | 2 +- server/src/lib.rs | 10 ++-------- voxygen/src/anim/quadruped/idle.rs | 12 ++++++------ voxygen/src/anim/quadruped/jump.rs | 12 ++++++------ voxygen/src/anim/quadruped/run.rs | 12 ++++++------ voxygen/src/menu/char_selection/mod.rs | 8 ++++++-- world/src/lib.rs | 4 ++-- 8 files changed, 30 insertions(+), 32 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index cc44d1c6a8..740f9edc4b 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -216,7 +216,7 @@ impl Client { 'outer: for dist in 0..10 { for i in chunk_pos.x - dist..chunk_pos.x + dist + 1 { for j in chunk_pos.y - dist..chunk_pos.y + dist + 1 { - for k in 0..3 { + for k in 0..6 { let key = Vec3::new(i, j, k); if self.state.terrain().get_key(key).is_none() && !self.pending_chunks.contains(&key) diff --git a/common/src/msg/client.rs b/common/src/msg/client.rs index f90315edd9..530022d4e3 100644 --- a/common/src/msg/client.rs +++ b/common/src/msg/client.rs @@ -9,7 +9,7 @@ pub enum ClientMsg { }, Character { name: String, - body: comp::HumanoidBody, + body: comp::Body, }, RequestState(ClientState), Ping, diff --git a/server/src/lib.rs b/server/src/lib.rs index 6fb89abf48..deaff7ead3 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -133,15 +133,9 @@ impl Server { entity: EcsEntity, client: &mut Client, name: String, - body: comp::HumanoidBody, + body: comp::Body, ) { - state.write_component( - entity, - comp::Actor::Character { - name, - body: comp::Body::Humanoid(body), - }, - ); + state.write_component(entity, comp::Actor::Character { name, body }); state.write_component(entity, comp::Stats::default()); state.write_component(entity, comp::phys::Pos(Vec3::new(0.0, 0.0, 64.0))); state.write_component(entity, comp::phys::Vel(Vec3::zero())); diff --git a/voxygen/src/anim/quadruped/idle.rs b/voxygen/src/anim/quadruped/idle.rs index e41a0dce09..0b8c576c51 100644 --- a/voxygen/src/anim/quadruped/idle.rs +++ b/voxygen/src/anim/quadruped/idle.rs @@ -43,27 +43,27 @@ impl Animation for IdleAnimation { * 0.25, ); - next.pighead.offset = Vec3::new(0.0, 7.0, -1.5 + wave * 0.2) / 11.0; + next.pighead.offset = Vec3::new(0.0, -2.0, -1.5 + wave * 0.2) / 11.0; next.pighead.ori = Quaternion::rotation_z(pighead_look.x) * Quaternion::rotation_x(pighead_look.y + wavecos_slow * 0.03); next.pighead.scale = Vec3::one() / 10.5; - next.pigchest.offset = Vec3::new(wave_slow * 0.05, 0.0, 1.5 + wavecos_slow * 0.4) / 11.0; + next.pigchest.offset = Vec3::new(wave_slow * 0.05, -9.0, 1.5 + wavecos_slow * 0.4) / 11.0; next.pigchest.ori = Quaternion::rotation_y(wave_slow * 0.05); next.pigchest.scale = Vec3::one() / 11.0; - next.piglf_leg.offset = Vec3::new(-4.5, 11.0, 1.5) / 11.0; + next.piglf_leg.offset = Vec3::new(-4.5, 2.0, 1.5) / 11.0; next.piglf_leg.ori = Quaternion::rotation_x(wave_slow * 0.08); next.piglf_leg.scale = Vec3::one() / 11.0; - next.pigrf_leg.offset = Vec3::new(2.5, 11.0, 1.5) / 11.0; + next.pigrf_leg.offset = Vec3::new(2.5, 2.0, 1.5) / 11.0; next.pigrf_leg.ori = Quaternion::rotation_x(wavecos_slow * 0.08); next.pigrf_leg.scale = Vec3::one() / 11.0; - next.piglb_leg.offset = Vec3::new(-4.5, 6.0, 1.5) / 11.0; + next.piglb_leg.offset = Vec3::new(-4.5, -3.0, 1.5) / 11.0; next.piglb_leg.ori = Quaternion::rotation_x(wavecos_slow * 0.08); next.piglb_leg.scale = Vec3::one() / 11.0; - next.pigrb_leg.offset = Vec3::new(2.5, 6.0, 1.5) / 11.0; + next.pigrb_leg.offset = Vec3::new(2.5, -3.0, 1.5) / 11.0; next.pigrb_leg.ori = Quaternion::rotation_x(wave_slow * 0.08); next.pigrb_leg.scale = Vec3::one() / 11.0; diff --git a/voxygen/src/anim/quadruped/jump.rs b/voxygen/src/anim/quadruped/jump.rs index da2e17fa76..a8724c7ce2 100644 --- a/voxygen/src/anim/quadruped/jump.rs +++ b/voxygen/src/anim/quadruped/jump.rs @@ -30,27 +30,27 @@ impl Animation for JumpAnimation { let wave_stop = (anim_time as f32 * 4.5).min(PI / 2.0).sin(); - next.pighead.offset = Vec3::new(0.0, 9.0, -1.5 ) / 11.0; + next.pighead.offset = Vec3::new(0.0, 0.0, -1.5 ) / 11.0; next.pighead.ori = Quaternion::rotation_x(wave_stop * 0.4); next.pighead.scale = Vec3::one() / 10.5; - next.pigchest.offset = Vec3::new(0.0, 0.0, 1.5) / 11.0; + next.pigchest.offset = Vec3::new(0.0, -9.0, 1.5) / 11.0; next.pigchest.ori = Quaternion::rotation_x(0.0); next.pigchest.scale = Vec3::one() / 11.0; - next.piglf_leg.offset = Vec3::new(-4.5, 12.0, 1.5) / 11.0; + next.piglf_leg.offset = Vec3::new(-4.5, 3.0, 1.5) / 11.0; next.piglf_leg.ori = Quaternion::rotation_x(wave_stop * 0.6); next.piglf_leg.scale = Vec3::one() / 11.0; - next.pigrf_leg.offset = Vec3::new(2.5, 12.0, 1.5) / 11.0; + next.pigrf_leg.offset = Vec3::new(2.5, 3.0, 1.5) / 11.0; next.pigrf_leg.ori = Quaternion::rotation_x(wave_stop * 0.6 - wave_slow * 0.3); next.pigrf_leg.scale = Vec3::one() / 11.0; - next.piglb_leg.offset = Vec3::new(-4.5, 5.0, 2.0) / 11.0; + next.piglb_leg.offset = Vec3::new(-4.5, -4.0, 2.0) / 11.0; next.piglb_leg.ori = Quaternion::rotation_x(wave_stop * -0.6 + wave_slow * 0.3); next.piglb_leg.scale = Vec3::one() / 11.0; - next.pigrb_leg.offset = Vec3::new(2.5, 5.0, 2.0) / 11.0; + next.pigrb_leg.offset = Vec3::new(2.5, -4.0, 2.0) / 11.0; next.pigrb_leg.ori = Quaternion::rotation_x(wave_stop * -0.6 + wave_slow * 0.3); next.pigrb_leg.scale = Vec3::one() / 11.0; diff --git a/voxygen/src/anim/quadruped/run.rs b/voxygen/src/anim/quadruped/run.rs index 9c0db36edd..d817a52741 100644 --- a/voxygen/src/anim/quadruped/run.rs +++ b/voxygen/src/anim/quadruped/run.rs @@ -30,27 +30,27 @@ impl Animation for RunAnimation { let wavecos_slow = (anim_time as f32 * 8.0 + PI).cos(); let wave_dip = (wave_slow.abs() - 0.5).abs(); - next.pighead.offset = Vec3::new(0.0, 9.0, -1.5 + wave * 1.5) / 11.0; + next.pighead.offset = Vec3::new(0.0, 0.0, -1.5 + wave * 1.5) / 11.0; next.pighead.ori = Quaternion::rotation_x(0.2 + wave * 0.05) * Quaternion::rotation_y(wavecos * 0.03); next.pighead.scale = Vec3::one() / 10.5; - next.pigchest.offset = Vec3::new(0.0, 0.0, 1.5 + wavecos * 1.2) / 11.0; + next.pigchest.offset = Vec3::new(0.0, -9.0, 1.5 + wavecos * 1.2) / 11.0; next.pigchest.ori = Quaternion::rotation_x(wave * 0.1); next.pigchest.scale = Vec3::one() / 11.0; - next.piglf_leg.offset = Vec3::new(-4.5, 11.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; + next.piglf_leg.offset = Vec3::new(-4.5, 2.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; next.piglf_leg.ori = Quaternion::rotation_x(wavequick * 0.3); next.piglf_leg.scale = Vec3::one() / 11.0; - next.pigrf_leg.offset = Vec3::new(2.5, 11.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; + next.pigrf_leg.offset = Vec3::new(2.5, 2.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; next.pigrf_leg.ori = Quaternion::rotation_x(wavequickcos * -0.3); next.pigrf_leg.scale = Vec3::one() / 11.0; - next.piglb_leg.offset = Vec3::new(-4.5, 6.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; + next.piglb_leg.offset = Vec3::new(-4.5, -3.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; next.piglb_leg.ori = Quaternion::rotation_x(wavequickcos * -0.3); next.piglb_leg.scale = Vec3::one() / 11.0; - next.pigrb_leg.offset = Vec3::new(2.5, 6.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; + next.pigrb_leg.offset = Vec3::new(2.5, -3.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; next.pigrb_leg.ori = Quaternion::rotation_x(wavequick * 0.3); next.pigrb_leg.scale = Vec3::one() / 11.0; diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index 9316ca3682..cbe77c7d6e 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -7,7 +7,11 @@ use crate::{ Direction, GlobalState, PlayState, PlayStateResult, }; use client::{self, Client}; -use common::{clock::Clock, msg::ClientMsg}; +use common::{ + comp, + clock::Clock, + msg::ClientMsg, +}; use scene::Scene; use std::{cell::RefCell, rc::Rc, time::Duration}; use ui::CharSelectionUi; @@ -78,7 +82,7 @@ impl PlayState for CharSelectionState { .postbox .send_message(ClientMsg::Character { name: self.char_selection_ui.character_name.clone(), - body: self.char_selection_ui.character_body, + body: comp::Body::Quadruped(comp::QuadrupedBody::random()), // comp::Body::Humanoid(self.char_selection_ui.character_body), }); return PlayStateResult::Switch(Box::new(SessionState::new( &mut global_state.window, diff --git a/world/src/lib.rs b/world/src/lib.rs index 98242c847c..fb4e613d02 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -42,7 +42,7 @@ impl World { let chaos_freq = 1.0 / 100.0; let freq = 1.0 / 128.0; - let ampl = 32.0; + let ampl = 75.0; let small_freq = 1.0 / 32.0; let small_ampl = 6.0; let offs = 32.0; @@ -55,7 +55,7 @@ impl World { let height = perlin_nz.get(Vec2::from(wposf * freq).into_array()) * ampl * chaos + perlin_nz.get((wposf * small_freq).into_array()) * small_ampl - * 2.0 + * 3.0 * chaos.powf(2.0) + offs; let temp = (temp_nz.get(Vec2::from(wposf * (1.0 / 64.0)).into_array()) + 1.0) * 0.5; From fa6f9136600be0d1c751a9e50521df46171e8fef Mon Sep 17 00:00:00 2001 From: jshipsey Date: Thu, 16 May 2019 00:40:35 -0400 Subject: [PATCH 15/21] glide anim Former-commit-id: b614a672b0a94f2b8803c0c1c22468b889242cc6 --- assets/voxygen/voxel/glider.vox | Bin 0 -> 9040 bytes common/src/comp/actor.rs | 1 + common/src/sys/control.rs | 2 +- voxygen/src/anim/character/gliding.rs | 105 +++++++++++++++++++++++++ voxygen/src/anim/character/idle.rs | 6 +- voxygen/src/anim/character/jump.rs | 3 + voxygen/src/anim/character/mod.rs | 11 ++- voxygen/src/anim/character/run.rs | 6 +- voxygen/src/anim/quadruped/jump.rs | 2 +- voxygen/src/menu/char_selection/mod.rs | 2 +- voxygen/src/scene/figure.rs | 32 +++++--- 11 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 assets/voxygen/voxel/glider.vox create mode 100644 voxygen/src/anim/character/gliding.rs diff --git a/assets/voxygen/voxel/glider.vox b/assets/voxygen/voxel/glider.vox new file mode 100644 index 0000000000000000000000000000000000000000..39f2f1cb9905fd506e44a924e002d94f8f72e3e6 GIT binary patch literal 9040 zcmbW6d#G&JS-|%>XZD^wv*)pAW2d-iMgy!O1#IrqjqY;12#()6ZHYZ@Dy+ZsCO zwj?2lAxLP$rP4-=v82Wr(h9aQN(ds2ZHPhfj~GiRg;Gi^B1kBui2wSBsBq5QAq9bAs5q^IaS?0VGokv?UUz01*%yk@5RG*8aY&FwkHbBsKKL)btZP!4g3Er|7) zb@_t&^mhzLtji&C18!(sjsz3_LkT~E|3+(k}}B{76)5*y1$Jh#t~sZHZBi@ zbv24c&LcB&oyrKODc}V_{^bs7BKBr-w^?dS!t$<;6uni%|YFm-&H2wI@ zy-%AyHu~&8!~-P69@3+|kMxm2Z5svXLnOokJ;dioOVSbUfCuMmCmZ}O zj}`~x>yd`Yr3|7Te$>M!TqJni+DX#FKilZ`v44OM zKwKjav5AD3co19WR_M53k*}kN*hbpaZ_p0nCK6%?32txyvg>j-`rz$tefk?n>uTJh z9sRlmYpH#{11;8EpZzv%q2x^UJo7Z_(q{+S&|)ndWE0sy+Q>Rs);8%dj}Bu(M&J$1 z(?0D7p>;LsVvqA!a<(GQK$LJ6I0F(Qh;13;z>z-C^=gtb1#VtCF@YKCM9c95;q1BzDeEGF;9HPI~ZD5 zC2?91r!)Ll5~BsAI-Q{(nJ1DsElA5_#>IX};a1+X>CKxJPSY)qlJbzEr`)_VxEM=NkNR31M?(fF9mU0 z5~l@mT7n=(OJa3OnIuLF%?uqF#NIvFXG{mk8kisg%8Ap07%fAj9y6H4xjo|VK7Ae_ zH{?yyIsPMv(~>wXiE9F#1dG^O=Zx6UfF?NTT9C8OIdL>67L4$TjI}P1IleJwuS*E1 zAA+F1L|XJ$Cq~=I2C|71#AyjB?Q`}@5ThmJfpseGi0iDiFGxsGe0QxnCU01k%wt$o=rk?Cvtp=I4y|Nk~l3!NaD00PD|pn z7$ZRtrzHqtv?NvwVzdN7jFxjGFiGz8qfrXSlvR7>AR%w3Hvfa z7UXltw2pn5WXzMgA$0{v(iSnc4mLEPN$ho?1=Ex^0dvw6)^3_xXVc6&n`oI>yGd&8 z0@{Ss6-Wt!cr8H?uO;zX5Ub?|d5AvcY!I*I5Ms^>@mfmK#A`{smc(mGyq0SqUduiV zfOsv5*QWL*(>fJ3>on}M-XMwBl6dXmD?a-?V4wT!>i|6P+21bv>$0z1_O;7Cy6j;O z`Y<5xA$_f5UtRXI&6*84uL*QmyDoVbImB-g=&-&$@_qCJNbs8>c<4H;bBA>vGPVTT ztYL@sYin4;Hfz^r4Liso{*yqPwH)F*33OP~Zf5Ob<{2|jsn30v`FDVLEs58XcrA(7 zl6Wm`AYM!2wdk@J)DK{cjp@)jlf*dzVW+kYkdwqZ8>i^o=-cc~3rT#H4iaROJ!~Qy z52G0*GR`)-xUSd1+_otb`mV67(++jIteeYvwFPwpWMu6I#GsHm z0gNdxDenvRO|Yjhm&6qAv>CETUU094(223fm;=&N?78&cmaG+ayNscq;A`CJf_u~r zth1iaSm`gPzeHjistEg$xtl>JVoZ#;BWaJl0qxz;+IdJHdf4q_BcbjPe9zkT=zkGo zCpLF;=o||Uyq-0%&^yIehF=d zuu9CcWn%6YP{Ex141C&p*y>};XC5BySE;#Mri=|Ln8OU6k3En2K6CNtcb%EL6)a(q zQ5QLf8EH?~rJl<;HaYWx6)bb=LPdHGLchZ-Yd2<%5{uZbeTsEx7v^qC`ws0p)NfO_ zZ!^w1`((4$P1d4;FEz-c^R&)kP0+hqk4+DK&%r;~n}Yo;Sr_TxAH30I6F&#Z`%N@h zI~#waAGc}k1Zl}TPk`jzCqVKZ6ejg+)aQ*Tc`pi(`}ih47qIpt_DAr(lrD97Z%W>s zF8yx`<_{Crq{iLQWsEE4H)bD~$b~Lr{VU|0{0w}(Cam${i1i!M9=Sp;kqgL~PlcSr z3=T{4Yy<0(dQh^DOXLDwg`6W>_}q;2(bzmYgnj&OGv*%TjVxh}Zbjb02bZK5q(k~? zQLiFDhocE?VQOdTgk>o-ih4%K339Uy@#cF=H**v#$0X z@^k7PPtCItzEI+e7Iu!N%nhAG-3@Y0euZ2j7sv|E&1eTlGscE&h14az24`-buFx%E zLB7)ZIX33lKrWCK(h=tAx?=v&tQccO8FcXHHn{kI7do7UHuN|rRNv6i%p z>_P|H;4`Pi!aDUhhfCxN*07mdr-yI^$8ZkfJ`BJE9|8zLfP@HQ7(!y54zNAMC;Bbx zwBN9<&Nu@-+q&vm)>XgG9Y4aah=PY<=8vozN+hx^%w zzC~NsWkcDVm{noNwJC!cch;OZv!<+~&O*n)272z}Ib{`PE6Nu5VW)|ncfg$YK*c?^ zplnIml6DpK7wDGgW+Unp+zq-68!PU$S&0sPg}&1Ew4IW6=oaXf z2z!)`*xyxd?behR#H|%?lqGMLl>22qp*?m2-b_pCXWTa>^BXabfcI0O&kt)fVyzBX z!+^I?fxQ%e$k_80_V|&q8EDUjc95l(>^I-h#bI^>}#Sg)rybXS6A(f1b0P;`14G1Kxrubu;Rw zj5)(jrt_prd@kV47ee6i-p602#KsBw39)+0oltNm6vX+Q_+JoL_hyV^U|rou?oU|* z?t%l-2c&B=VoF7NV(n^EYiFXj=GIxgBF~&nbQX2$=xpkl=qz+~>e=WT=xVHmg}#nH z=kCet)>(@;sl(bdSx=kxjXCz%W0O6t)0a)%1~!`5Fxf8)8#Xo?jH!vlr`9!rXC+|M!THSs}*a+9(ab#e*!PJhs28(cE?q$SFRZau5 zbDeW16flAk-B{~cr-{~aS4?%D^ETqHm~!4z;(rDq>zN}<&VIrD5bBtLEMbg(0#iu2 z7c$7X4+Inaa#bR6^4M%Hf zJNR}J8l-Jx9V{48J|?zj+=nT&@OuY8Y(fKUsG}>mD@*Rh6f*9?32~=|Z#vM#Pa9xE zoqUKN2Cya;Z1D3nZ?uXSw!qhO-A>15)+2{8wnqH#oSWD-@$YNkPbOy(8xAy~fnVFm z5I+s@+1%1=flnbr{(ma!=pd`3Lym053^}x@??98b4P=P#29Qx!Hdq5FAct`izlBi~ z9ki(DKocJi@#z4@4s~GUPzNTw*HgZ0O(5fYX$md;-GLCF3-tNrn{&$lUpfE3FWJ*I z@pMBxO!+@GxA+aeyrbt+E zk8JRjL)Lx4{UQ_k;;yN)uJ4CnQ&RnD0Q11}k5#w7^ z?~po2_`(tT9(#XG`j~XWoqP^Cz!!XzciJ_0hvEwZ_Ss{>o3 zA`@hfJ@3PicTU23CR*z6MfkynIC;o{>kGylTI?;qH3b&`OCm?iyX1dM$!}0& z(i6y(&TzFEZ(8AuJ^ zs$#xbMSQ!8_+}OD^V>@khv3@@5<*`Ns=tGaZi|j%N+TgQp z9&0v0_K`hsp-aAlZ0mA<3-I{n-Ngr7ey8yH{^`L0`p^THZ|hy?KwInhoubcg4+DN% z@MpB;w~rEgW9&_kQ)GtS47+3Ome@^cmq88%jG)Bc7$z{)I_wtM&9R$ecZ}T+-|>sL z7`1nP7r*hw8`YI7SJaQ5G1U9M`lc$q|5X3xdFqWf?o#^i>lgp>XX0K6l>9`lqK8UV zJ%5ujZa0)SbWP zs!N|6sNa1pQMX+&)ZNb->f~iZedhbLy*pCrLnAf5vQXE*dO^jHdTR7kq!uq`>iF9; z6@J`M{{oU6^>Y>|5>hZhh>bXyyQ&&E6gL>}4Th$xC^DF9KUVKO`%Rt?HE>rJ+&s=@# z-W$}zcN*%6Up3V8zhS7?f6q{N%tq?sVyr%}nyN={yGh-<2-HK@#p_tE_??A%`+H0ENA&sXi-!8{-x%u0e{ZPAADXMLJaJyV z`Sn}Xzy8xb>d`N{>Zw2T)HlB`)!Qojf6xENUwh#HH2>?<=-T{0e*NZuod5ar=hg4u z@Vq)aenGwK$Sj zp7_&O)t6rRmioiLeM|k^BTuS#fBt#({;$2R?)k=B>cWK!>PLoBh7Ic9)xlea`r%){ zGrk|i_@% literal 0 HcmV?d00001 diff --git a/common/src/comp/actor.rs b/common/src/comp/actor.rs index 5772350fa8..eca896ee17 100644 --- a/common/src/comp/actor.rs +++ b/common/src/comp/actor.rs @@ -223,6 +223,7 @@ pub enum Animation { Idle, Run, Jump, + Gliding, } impl Component for AnimationHistory { diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index 7c1f41ce91..d84d50c410 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -81,7 +81,7 @@ impl<'a> System<'a> for Sys { Animation::Idle } } else { - Animation::Jump + Animation::Gliding }; let last_history = anims.get_mut(entity).cloned(); diff --git a/voxygen/src/anim/character/gliding.rs b/voxygen/src/anim/character/gliding.rs new file mode 100644 index 0000000000..19ebfbece8 --- /dev/null +++ b/voxygen/src/anim/character/gliding.rs @@ -0,0 +1,105 @@ +// Standard +use std::{f32::consts::PI, ops::Mul}; + +// Library +use vek::*; + +// Local +use super::{super::Animation, CharacterSkeleton, SCALE}; +// + +pub struct GlidingAnimation; + +impl Animation for GlidingAnimation { + type Skeleton = CharacterSkeleton; + type Dependency = f64; + + fn update_skeleton( + skeleton: &Self::Skeleton, + global_time: f64, + anim_time: f64, + ) -> Self::Skeleton { + let mut next = (*skeleton).clone(); + let wave = (anim_time as f32 * 14.0).sin(); + let waveslow = (anim_time as f32 * 7.0).sin(); + let wavecos_slow = (anim_time as f32 * 7.0).cos(); + let arcwave = (1.0f32.ln_1p() - 1.5).abs(); + let wavetest = (wave.cbrt()); + let fuzzwave = (anim_time as f32 * 12.0).sin(); + let wavecos = (anim_time as f32 * 14.0).cos(); + let wave_stop = (anim_time as f32 * 1.5).min(PI / 2.0).sin(); + let wave_stopalt = (anim_time as f32 * 5.0).min(PI / 2.0).sin(); + let waveveryslow = (anim_time as f32 * 3.0).sin(); + let waveveryslowalt = (anim_time as f32 * 2.5).sin(); + let waveveryslowcos = (anim_time as f32 * 3.0).cos(); + + + let wave_slowtest = (anim_time as f32).min(PI / 2.0).sin(); + + let head_look = Vec2::new( + ((global_time + anim_time) as f32 / 4.0) + .floor() + .mul(7331.0) + .sin() + * 0.5, + ((global_time + anim_time) as f32 / 4.0) + .floor() + .mul(1337.0) + .sin() + * 0.25, + ); + next.head.offset = Vec3::new(5.5, 2.0, 12.0); + next.head.ori = Quaternion::rotation_x(0.35 - waveveryslow * 0.10 + head_look.y) * Quaternion::rotation_z(head_look.x + waveveryslowcos * 0.15); + next.head.scale = Vec3::one(); + + next.chest.offset = Vec3::new(5.5, 0.0, 8.0); + next.chest.ori = Quaternion::rotation_z(waveveryslowcos * 0.15); + next.chest.scale = Vec3::one(); + + next.belt.offset = Vec3::new(5.5, 0.0, 6.0); + next.belt.ori = Quaternion::rotation_z(waveveryslowcos * 0.20); + next.belt.scale = Vec3::one(); + + next.shorts.offset = Vec3::new(5.5, 0.0, 3.0); + next.shorts.ori = Quaternion::rotation_z(waveveryslowcos * 0.25); + next.shorts.scale = Vec3::one(); + + next.l_hand.offset = Vec3::new(-8.0, -10.0 + waveveryslow * 2.5, 18.5 + waveveryslow * 1.0); + next.l_hand.ori = Quaternion::rotation_x(0.9 - waveveryslow * 0.10); + next.l_hand.scale = Vec3::one(); + + next.r_hand.offset = Vec3::new(11.0, -10.0 + waveveryslow * 2.5, 18.5 + waveveryslow * 1.0); + next.r_hand.ori = Quaternion::rotation_x(0.9 - waveveryslow * 0.10); + next.r_hand.scale = Vec3::one(); + + next.l_foot.offset = Vec3::new(-3.4, 1.0, 8.0); + next.l_foot.ori = Quaternion::rotation_x(wave_stop * -0.7 - wavecos_slow * -0.21 + waveveryslow * 0.19); + next.l_foot.scale = Vec3::one(); + + next.r_foot.offset = Vec3::new(3.4, 1.0, 8.0); + next.r_foot.ori = Quaternion::rotation_x(wave_stop * -0.8 + waveslow * -0.25 + waveveryslowalt * 0.13); + next.r_foot.scale = Vec3::one(); + + next.weapon.offset = Vec3::new(-5.0, -6.0, 19.0); + next.weapon.ori = Quaternion::rotation_y(2.5); + next.weapon.scale = Vec3::one(); + + next.l_shoulder.offset = Vec3::new(-10.0, -3.0, 2.5); + next.l_shoulder.ori = Quaternion::rotation_x(0.0); + next.l_shoulder.scale = Vec3::one(); + + next.r_shoulder.offset = Vec3::new(0.0, -3.0, 2.5); + next.r_shoulder.ori = Quaternion::rotation_x(0.0); + next.r_shoulder.scale = Vec3::one(); + + next.torso.offset = Vec3::new(-0.5, -0.2, 0.0); + next.torso.ori = Quaternion::rotation_x(-0.8 + waveveryslow * 0.10); + next.torso.scale = Vec3::one() / 11.0; + + next.draw.offset = Vec3::new(13.5, 3.0, -1.0); + next.draw.ori = Quaternion::rotation_y(waveveryslowcos * 0.05); + next.draw.scale = Vec3::one(); + + next + } +} diff --git a/voxygen/src/anim/character/idle.rs b/voxygen/src/anim/character/idle.rs index 1a629d3b0b..bef3f44247 100644 --- a/voxygen/src/anim/character/idle.rs +++ b/voxygen/src/anim/character/idle.rs @@ -100,9 +100,9 @@ impl Animation for IdleAnimation { next.torso.ori = Quaternion::rotation_x(0.0); next.torso.scale = Vec3::one() / 11.0; - next.draw.offset = Vec3::new(0.0, 1.0, -8.0); - next.draw.ori = Quaternion::rotation_y(-0.2); - next.draw.scale = Vec3::one(); + next.draw.offset = Vec3::new(0.0, 0.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; next } } diff --git a/voxygen/src/anim/character/jump.rs b/voxygen/src/anim/character/jump.rs index acbd79adb0..ffcbf8b718 100644 --- a/voxygen/src/anim/character/jump.rs +++ b/voxygen/src/anim/character/jump.rs @@ -80,6 +80,9 @@ impl Animation for JumpAnimation { next.torso.ori = Quaternion::rotation_x(-0.2); next.torso.scale = Vec3::one() / 11.0; + next.draw.offset = Vec3::new(0.0, 0.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; next } } diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index 8a348ce769..3605286cfc 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -1,11 +1,14 @@ pub mod idle; pub mod jump; pub mod run; +pub mod gliding; + // Reexports pub use self::idle::IdleAnimation; pub use self::jump::JumpAnimation; pub use self::run::RunAnimation; +pub use self::gliding::GlidingAnimation; // Crate use crate::render::FigureBoneData; @@ -27,8 +30,8 @@ pub struct CharacterSkeleton { weapon: Bone, l_shoulder: Bone, r_shoulder: Bone, - torso: Bone, draw: Bone, + torso: Bone, } impl CharacterSkeleton { @@ -45,8 +48,8 @@ impl CharacterSkeleton { weapon: Bone::default(), l_shoulder: Bone::default(), r_shoulder: Bone::default(), - torso: Bone::default(), draw: Bone::default(), + torso: Bone::default(), } } } @@ -68,8 +71,8 @@ impl Skeleton for CharacterSkeleton { FigureBoneData::new(torso_mat * chest_mat * self.weapon.compute_base_matrix()), FigureBoneData::new(torso_mat * chest_mat * self.l_shoulder.compute_base_matrix()), FigureBoneData::new(torso_mat * chest_mat * self.r_shoulder.compute_base_matrix()), - FigureBoneData::new(torso_mat), FigureBoneData::new(torso_mat * l_hand_mat * self.draw.compute_base_matrix()), + FigureBoneData::new(torso_mat), FigureBoneData::default(), FigureBoneData::default(), FigureBoneData::default(), @@ -88,7 +91,7 @@ impl Skeleton for CharacterSkeleton { self.weapon.interpolate(&target.weapon); self.l_shoulder.interpolate(&target.l_shoulder); self.r_shoulder.interpolate(&target.r_shoulder); - self.torso.interpolate(&target.torso); self.draw.interpolate(&target.draw); + self.torso.interpolate(&target.torso); } } diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index 22b738e27c..f0c6d733a1 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -76,9 +76,9 @@ impl Animation for RunAnimation { next.torso.ori = Quaternion::rotation_x(-velocity * 0.05 - wavecos * 0.1); next.torso.scale = Vec3::one() / 11.0; - next.draw.offset = Vec3::new(0.0, 1.0, -8.0); - next.draw.ori = Quaternion::rotation_y(-0.2); - next.draw.scale = Vec3::one(); + next.draw.offset = Vec3::new(0.0, 0.0, 0.0); + next.draw.ori = Quaternion::rotation_y(0.0); + next.draw.scale = Vec3::one() * 0.0; next } diff --git a/voxygen/src/anim/quadruped/jump.rs b/voxygen/src/anim/quadruped/jump.rs index a8724c7ce2..9d25f69d3e 100644 --- a/voxygen/src/anim/quadruped/jump.rs +++ b/voxygen/src/anim/quadruped/jump.rs @@ -39,7 +39,7 @@ impl Animation for JumpAnimation { next.pigchest.scale = Vec3::one() / 11.0; next.piglf_leg.offset = Vec3::new(-4.5, 3.0, 1.5) / 11.0; - next.piglf_leg.ori = Quaternion::rotation_x(wave_stop * 0.6); + next.piglf_leg.ori = Quaternion::rotation_x(wave_stop * 0.6 - wave_slow * 0.3); next.piglf_leg.scale = Vec3::one() / 11.0; next.pigrf_leg.offset = Vec3::new(2.5, 3.0, 1.5) / 11.0; diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index cbe77c7d6e..e1b86311da 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -82,7 +82,7 @@ impl PlayState for CharSelectionState { .postbox .send_message(ClientMsg::Character { name: self.char_selection_ui.character_name.clone(), - body: comp::Body::Quadruped(comp::QuadrupedBody::random()), // comp::Body::Humanoid(self.char_selection_ui.character_body), + body: comp::Body::Humanoid(self.char_selection_ui.character_body), //body: comp::Body::Quadruped(comp::QuadrupedBody::random()), }); return PlayStateResult::Switch(Box::new(SessionState::new( &mut global_state.window, diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index d4e98dee22..3c771579dc 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -15,7 +15,7 @@ use common::{ assets, comp::{ self, - actor::{Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Weapon, Pighead, Pigchest, Pigleg_l, Pigleg_r}, + actor::{Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Weapon, Draw, Pighead, Pigchest, Pigleg_l, Pigleg_r}, Body, HumanoidBody, QuadrupedBody }, figure::Segment, @@ -65,7 +65,7 @@ impl FigureModelCache { Some(Self::load_weapon(body.weapon)), Some(Self::load_left_shoulder(body.shoulder)), Some(Self::load_right_shoulder(body.shoulder)), - None, + Some(Self::load_draw(body.draw)), None, None, None, @@ -226,17 +226,17 @@ impl FigureModelCache { Vec3::new(2.5, 0.0, 0.0), ) } - // fn load_draw(draw: Draw) -> Mesh { - // Self::load_mesh( - // match draw { - // //Draw::DefaultDraw => "sword.vox", - // - // }, - // Vec3::new(0.0, 0.0, -2.0) - // - // - // ) - // } + fn load_draw(draw: Draw) -> Mesh { + Self::load_mesh( + match draw { + Draw::Default => "glider.vox", + + }, + Vec3::new(-26.0, -26.0, -5.0) + + + ) + } fn load_pighead(pighead: Pighead) -> Mesh { Self::load_mesh( @@ -350,6 +350,11 @@ impl FigureMgr { time, animation_history.time, ), + comp::Animation::Gliding => character::GlidingAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_history.time, + ), }; state.skeleton.interpolate(&target_skeleton); @@ -377,6 +382,7 @@ impl FigureMgr { (vel.0.magnitude(), time), animation_history.time, ), + // TODO! _ => state.skeleton_mut().clone(), }; From 0068d6203b08b71e6dbb45b84da2ad3145cd2d15 Mon Sep 17 00:00:00 2001 From: jshipsey Date: Thu, 16 May 2019 01:29:48 -0400 Subject: [PATCH 16/21] popup origin fix Former-commit-id: 9a7ba69115e7b574bc2f3bf26afad71e3c682c38 --- voxygen/src/anim/character/idle.rs | 2 +- voxygen/src/anim/character/jump.rs | 2 +- voxygen/src/anim/character/run.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/voxygen/src/anim/character/idle.rs b/voxygen/src/anim/character/idle.rs index bef3f44247..bf663488ae 100644 --- a/voxygen/src/anim/character/idle.rs +++ b/voxygen/src/anim/character/idle.rs @@ -100,7 +100,7 @@ impl Animation for IdleAnimation { next.torso.ori = Quaternion::rotation_x(0.0); next.torso.scale = Vec3::one() / 11.0; - next.draw.offset = Vec3::new(0.0, 0.0, 0.0); + next.draw.offset = Vec3::new(13.5, 0.0, 0.0); next.draw.ori = Quaternion::rotation_y(0.0); next.draw.scale = Vec3::one() * 0.0; next diff --git a/voxygen/src/anim/character/jump.rs b/voxygen/src/anim/character/jump.rs index ffcbf8b718..37a898a3c9 100644 --- a/voxygen/src/anim/character/jump.rs +++ b/voxygen/src/anim/character/jump.rs @@ -80,7 +80,7 @@ impl Animation for JumpAnimation { next.torso.ori = Quaternion::rotation_x(-0.2); next.torso.scale = Vec3::one() / 11.0; - next.draw.offset = Vec3::new(0.0, 0.0, 0.0); + next.draw.offset = Vec3::new(13.5, 0.0, 0.0); next.draw.ori = Quaternion::rotation_y(0.0); next.draw.scale = Vec3::one() * 0.0; next diff --git a/voxygen/src/anim/character/run.rs b/voxygen/src/anim/character/run.rs index f0c6d733a1..aae5996564 100644 --- a/voxygen/src/anim/character/run.rs +++ b/voxygen/src/anim/character/run.rs @@ -76,7 +76,7 @@ impl Animation for RunAnimation { next.torso.ori = Quaternion::rotation_x(-velocity * 0.05 - wavecos * 0.1); next.torso.scale = Vec3::one() / 11.0; - next.draw.offset = Vec3::new(0.0, 0.0, 0.0); + next.draw.offset = Vec3::new(13.5, 0.0, 0.0); next.draw.ori = Quaternion::rotation_y(0.0); next.draw.scale = Vec3::one() * 0.0; From 6deaf566d8e28c01a78e5b2a7f2b30c00027cd59 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 16 May 2019 12:04:42 +0100 Subject: [PATCH 17/21] Added correct gliding animation calculation Former-commit-id: 625310820c9cf7a1d37401875db43b5b597eb590 --- common/src/sys/control.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index d84d50c410..b05ce97062 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -41,7 +41,7 @@ impl<'a> System<'a> for Sys { .unwrap_or(false) && vel.0.z <= 0.0; - let friction = if on_ground { + let (gliding, friction) = if on_ground { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration vel.0 += control.move_dir * 4.0; @@ -50,7 +50,7 @@ impl<'a> System<'a> for Sys { vel.0.z += 16.0; } - 0.15 + (false, 0.15) } else { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration @@ -61,9 +61,9 @@ impl<'a> System<'a> for Sys { let anti_grav = 9.81 * 3.95; vel.0.z += anti_grav * dt.0 * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); - 0.008 + (true, 0.008) } else { - 0.015 + (false, 0.015) } }; @@ -80,8 +80,10 @@ impl<'a> System<'a> for Sys { } else { Animation::Idle } - } else { + } else if gliding { Animation::Gliding + } else { + Animation::Jump }; let last_history = anims.get_mut(entity).cloned(); From 4edf2e3a4e913859bba2a22985a2dbb051061003 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 16 May 2019 14:13:28 +0100 Subject: [PATCH 18/21] Improved falling glider physics Former-commit-id: 752c1291c7d38282312446c5391c2fb4fa7cbf6e --- common/src/sys/control.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index b05ce97062..c01ab474fc 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -44,7 +44,7 @@ impl<'a> System<'a> for Sys { let (gliding, friction) = if on_ground { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration - vel.0 += control.move_dir * 4.0; + vel.0 += Vec2::broadcast(dt.0) * control.move_dir * 200.0; if control.jumping { vel.0.z += 16.0; @@ -54,12 +54,12 @@ impl<'a> System<'a> for Sys { } else { // TODO: Don't hard-code this // Apply physics to the player: acceleration and non-linear decceleration - vel.0 += control.move_dir * 0.2; + vel.0 += Vec2::broadcast(dt.0) * control.move_dir * 10.0; if control.gliding && vel.0.z < 0.0 { // TODO: Don't hard-code this - let anti_grav = 9.81 * 3.95; - vel.0.z += anti_grav * dt.0 * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); + let anti_grav = 9.81 * 3.95 + vel.0.z.powf(2.0) * 0.2; + vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); (true, 0.008) } else { @@ -68,7 +68,7 @@ impl<'a> System<'a> for Sys { }; // Friction - vel.0 -= vel.0.map(|e| (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)).min(e.abs()).copysign(e)) * Vec3::new(1.0, 1.0, 0.0); + vel.0 -= Vec2::broadcast(dt.0) * 50.0 * vel.0.map(|e| (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)).min(e.abs()).copysign(e)) * Vec3::new(1.0, 1.0, 0.0); if vel.0.magnitude_squared() != 0.0 { dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); From 37fadf201b1023a6ec3d1b9d279cd698fd99b567 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 16 May 2019 20:23:45 +0100 Subject: [PATCH 19/21] fmt Former-commit-id: 8f0bc964e00bfd9461f752622862de5335678e5b --- client/src/lib.rs | 3 +- common/src/comp/actor.rs | 4 +- common/src/sys/control.rs | 12 ++++- voxygen/src/anim/character/gliding.rs | 10 ++-- voxygen/src/anim/character/mod.rs | 5 +- voxygen/src/anim/quadruped/idle.rs | 6 +-- voxygen/src/anim/quadruped/jump.rs | 3 +- voxygen/src/anim/quadruped/mod.rs | 7 +-- voxygen/src/anim/quadruped/run.rs | 19 ++++--- voxygen/src/menu/char_selection/mod.rs | 6 +-- voxygen/src/menu/char_selection/scene.rs | 8 ++- voxygen/src/scene/figure.rs | 66 +++++++++++++----------- 12 files changed, 83 insertions(+), 66 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 740f9edc4b..11c4266974 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -202,7 +202,8 @@ impl Client { self.state.terrain().iter().for_each(|(key, _)| { if (Vec2::from(chunk_pos) - Vec2::from(key)) .map(|e: i32| e.abs()) - .reduce_max() > 10 + .reduce_max() + > 10 { chunks_to_remove.push(key); } diff --git a/common/src/comp/actor.rs b/common/src/comp/actor.rs index eca896ee17..885f53381e 100644 --- a/common/src/comp/actor.rs +++ b/common/src/comp/actor.rs @@ -155,7 +155,8 @@ const ALL_QRACES: [Race; 6] = [ Race::Elf, Race::Human, Race::Orc, - Race::Undead,]; + Race::Undead, +]; const ALL_QBODY_TYPES: [BodyType; 3] = [BodyType::Female, BodyType::Male, BodyType::Unspecified]; const ALL_QHEADS: [Pighead; 1] = [Pighead::Default]; const ALL_QCHESTS: [Pigchest; 1] = [Pigchest::Default]; @@ -170,7 +171,6 @@ pub struct QuadrupedBody { pub pigchest: Pigchest, pub pigleg_l: Pigleg_l, pub pigleg_r: Pigleg_r, - } impl QuadrupedBody { diff --git a/common/src/sys/control.rs b/common/src/sys/control.rs index c01ab474fc..375d26cbfb 100644 --- a/common/src/sys/control.rs +++ b/common/src/sys/control.rs @@ -59,7 +59,8 @@ impl<'a> System<'a> for Sys { if control.gliding && vel.0.z < 0.0 { // TODO: Don't hard-code this let anti_grav = 9.81 * 3.95 + vel.0.z.powf(2.0) * 0.2; - vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); + vel.0.z += + dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); (true, 0.008) } else { @@ -68,7 +69,14 @@ impl<'a> System<'a> for Sys { }; // Friction - vel.0 -= Vec2::broadcast(dt.0) * 50.0 * vel.0.map(|e| (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)).min(e.abs()).copysign(e)) * Vec3::new(1.0, 1.0, 0.0); + vel.0 -= Vec2::broadcast(dt.0) + * 50.0 + * vel.0.map(|e| { + (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)) + .min(e.abs()) + .copysign(e) + }) + * Vec3::new(1.0, 1.0, 0.0); if vel.0.magnitude_squared() != 0.0 { dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); diff --git a/voxygen/src/anim/character/gliding.rs b/voxygen/src/anim/character/gliding.rs index 19ebfbece8..be2102670d 100644 --- a/voxygen/src/anim/character/gliding.rs +++ b/voxygen/src/anim/character/gliding.rs @@ -33,7 +33,6 @@ impl Animation for GlidingAnimation { let waveveryslowalt = (anim_time as f32 * 2.5).sin(); let waveveryslowcos = (anim_time as f32 * 3.0).cos(); - let wave_slowtest = (anim_time as f32).min(PI / 2.0).sin(); let head_look = Vec2::new( @@ -49,7 +48,8 @@ impl Animation for GlidingAnimation { * 0.25, ); next.head.offset = Vec3::new(5.5, 2.0, 12.0); - next.head.ori = Quaternion::rotation_x(0.35 - waveveryslow * 0.10 + head_look.y) * Quaternion::rotation_z(head_look.x + waveveryslowcos * 0.15); + next.head.ori = Quaternion::rotation_x(0.35 - waveveryslow * 0.10 + head_look.y) + * Quaternion::rotation_z(head_look.x + waveveryslowcos * 0.15); next.head.scale = Vec3::one(); next.chest.offset = Vec3::new(5.5, 0.0, 8.0); @@ -73,11 +73,13 @@ impl Animation for GlidingAnimation { next.r_hand.scale = Vec3::one(); next.l_foot.offset = Vec3::new(-3.4, 1.0, 8.0); - next.l_foot.ori = Quaternion::rotation_x(wave_stop * -0.7 - wavecos_slow * -0.21 + waveveryslow * 0.19); + next.l_foot.ori = + Quaternion::rotation_x(wave_stop * -0.7 - wavecos_slow * -0.21 + waveveryslow * 0.19); next.l_foot.scale = Vec3::one(); next.r_foot.offset = Vec3::new(3.4, 1.0, 8.0); - next.r_foot.ori = Quaternion::rotation_x(wave_stop * -0.8 + waveslow * -0.25 + waveveryslowalt * 0.13); + next.r_foot.ori = + Quaternion::rotation_x(wave_stop * -0.8 + waveslow * -0.25 + waveveryslowalt * 0.13); next.r_foot.scale = Vec3::one(); next.weapon.offset = Vec3::new(-5.0, -6.0, 19.0); diff --git a/voxygen/src/anim/character/mod.rs b/voxygen/src/anim/character/mod.rs index 3605286cfc..d1054716a5 100644 --- a/voxygen/src/anim/character/mod.rs +++ b/voxygen/src/anim/character/mod.rs @@ -1,14 +1,13 @@ +pub mod gliding; pub mod idle; pub mod jump; pub mod run; -pub mod gliding; - // Reexports +pub use self::gliding::GlidingAnimation; pub use self::idle::IdleAnimation; pub use self::jump::JumpAnimation; pub use self::run::RunAnimation; -pub use self::gliding::GlidingAnimation; // Crate use crate::render::FigureBoneData; diff --git a/voxygen/src/anim/quadruped/idle.rs b/voxygen/src/anim/quadruped/idle.rs index 0b8c576c51..0a281c2e19 100644 --- a/voxygen/src/anim/quadruped/idle.rs +++ b/voxygen/src/anim/quadruped/idle.rs @@ -44,7 +44,8 @@ impl Animation for IdleAnimation { ); next.pighead.offset = Vec3::new(0.0, -2.0, -1.5 + wave * 0.2) / 11.0; - next.pighead.ori = Quaternion::rotation_z(pighead_look.x) * Quaternion::rotation_x(pighead_look.y + wavecos_slow * 0.03); + next.pighead.ori = Quaternion::rotation_z(pighead_look.x) + * Quaternion::rotation_x(pighead_look.y + wavecos_slow * 0.03); next.pighead.scale = Vec3::one() / 10.5; next.pigchest.offset = Vec3::new(wave_slow * 0.05, -9.0, 1.5 + wavecos_slow * 0.4) / 11.0; @@ -67,9 +68,6 @@ impl Animation for IdleAnimation { next.pigrb_leg.ori = Quaternion::rotation_x(wave_slow * 0.08); next.pigrb_leg.scale = Vec3::one() / 11.0; - - - next } } diff --git a/voxygen/src/anim/quadruped/jump.rs b/voxygen/src/anim/quadruped/jump.rs index 9d25f69d3e..0567e3c558 100644 --- a/voxygen/src/anim/quadruped/jump.rs +++ b/voxygen/src/anim/quadruped/jump.rs @@ -29,8 +29,7 @@ impl Animation for JumpAnimation { let wave_dip = (wave_slow.abs() - 0.5).abs(); let wave_stop = (anim_time as f32 * 4.5).min(PI / 2.0).sin(); - - next.pighead.offset = Vec3::new(0.0, 0.0, -1.5 ) / 11.0; + next.pighead.offset = Vec3::new(0.0, 0.0, -1.5) / 11.0; next.pighead.ori = Quaternion::rotation_x(wave_stop * 0.4); next.pighead.scale = Vec3::one() / 10.5; diff --git a/voxygen/src/anim/quadruped/mod.rs b/voxygen/src/anim/quadruped/mod.rs index a6b7e4474c..5115133cf2 100644 --- a/voxygen/src/anim/quadruped/mod.rs +++ b/voxygen/src/anim/quadruped/mod.rs @@ -1,13 +1,11 @@ - -pub mod run; pub mod idle; pub mod jump; - +pub mod run; // Reexports -pub use self::run::RunAnimation; pub use self::idle::IdleAnimation; pub use self::jump::JumpAnimation; +pub use self::run::RunAnimation; // Crate use crate::render::FigureBoneData; @@ -25,7 +23,6 @@ pub struct QuadrupedSkeleton { pigrf_leg: Bone, piglb_leg: Bone, pigrb_leg: Bone, - } impl QuadrupedSkeleton { diff --git a/voxygen/src/anim/quadruped/run.rs b/voxygen/src/anim/quadruped/run.rs index d817a52741..21e1fdafc3 100644 --- a/voxygen/src/anim/quadruped/run.rs +++ b/voxygen/src/anim/quadruped/run.rs @@ -31,27 +31,32 @@ impl Animation for RunAnimation { let wave_dip = (wave_slow.abs() - 0.5).abs(); next.pighead.offset = Vec3::new(0.0, 0.0, -1.5 + wave * 1.5) / 11.0; - next.pighead.ori = Quaternion::rotation_x(0.2 + wave * 0.05) * Quaternion::rotation_y(wavecos * 0.03); + next.pighead.ori = + Quaternion::rotation_x(0.2 + wave * 0.05) * Quaternion::rotation_y(wavecos * 0.03); next.pighead.scale = Vec3::one() / 10.5; next.pigchest.offset = Vec3::new(0.0, -9.0, 1.5 + wavecos * 1.2) / 11.0; next.pigchest.ori = Quaternion::rotation_x(wave * 0.1); next.pigchest.scale = Vec3::one() / 11.0; - next.piglf_leg.offset = Vec3::new(-4.5, 2.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; - next.piglf_leg.ori = Quaternion::rotation_x(wavequick * 0.3); + next.piglf_leg.offset = + Vec3::new(-4.5, 2.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; + next.piglf_leg.ori = Quaternion::rotation_x(wavequick * 0.3); next.piglf_leg.scale = Vec3::one() / 11.0; - next.pigrf_leg.offset = Vec3::new(2.5, 2.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; + next.pigrf_leg.offset = + Vec3::new(2.5, 2.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; next.pigrf_leg.ori = Quaternion::rotation_x(wavequickcos * -0.3); next.pigrf_leg.scale = Vec3::one() / 11.0; - next.piglb_leg.offset = Vec3::new(-4.5, -3.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; + next.piglb_leg.offset = + Vec3::new(-4.5, -3.0 - wavequickcos * 0.8, 2.5 + wavequick * 1.5) / 11.0; next.piglb_leg.ori = Quaternion::rotation_x(wavequickcos * -0.3); next.piglb_leg.scale = Vec3::one() / 11.0; - next.pigrb_leg.offset = Vec3::new(2.5, -3.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; - next.pigrb_leg.ori = Quaternion::rotation_x(wavequick * 0.3); + next.pigrb_leg.offset = + Vec3::new(2.5, -3.0 + wavequick * 0.8, 2.5 + wavequickcos * 1.5) / 11.0; + next.pigrb_leg.ori = Quaternion::rotation_x(wavequick * 0.3); next.pigrb_leg.scale = Vec3::one() / 11.0; next diff --git a/voxygen/src/menu/char_selection/mod.rs b/voxygen/src/menu/char_selection/mod.rs index e1b86311da..0bc18f324f 100644 --- a/voxygen/src/menu/char_selection/mod.rs +++ b/voxygen/src/menu/char_selection/mod.rs @@ -7,11 +7,7 @@ use crate::{ Direction, GlobalState, PlayState, PlayStateResult, }; use client::{self, Client}; -use common::{ - comp, - clock::Clock, - msg::ClientMsg, -}; +use common::{clock::Clock, comp, msg::ClientMsg}; use scene::Scene; use std::{cell::RefCell, rc::Rc, time::Duration}; use ui::CharSelectionUi; diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index 7ff104e41f..d29a50d127 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -99,8 +99,12 @@ impl Scene { ); self.figure_state.skeleton_mut().interpolate(&tgt_skeleton); - self.figure_state - .update(renderer, Vec3::zero(), -Vec3::unit_y(), Rgba::broadcast(1.0)); + self.figure_state.update( + renderer, + Vec3::zero(), + -Vec3::unit_y(), + Rgba::broadcast(1.0), + ); } pub fn render(&mut self, renderer: &mut Renderer, client: &Client) { diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index 3c771579dc..39ddc2790e 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -15,8 +15,11 @@ use common::{ assets, comp::{ self, - actor::{Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Weapon, Draw, Pighead, Pigchest, Pigleg_l, Pigleg_r}, - Body, HumanoidBody, QuadrupedBody + actor::{ + Belt, Chest, Draw, Foot, Hand, Head, Pants, Pigchest, Pighead, Pigleg_l, Pigleg_r, + Shoulder, Weapon, + }, + Body, HumanoidBody, QuadrupedBody, }, figure::Segment, msg, @@ -230,11 +233,8 @@ impl FigureModelCache { Self::load_mesh( match draw { Draw::Default => "glider.vox", - }, - Vec3::new(-26.0, -26.0, -5.0) - - + Vec3::new(-26.0, -26.0, -5.0), ) } @@ -293,7 +293,6 @@ impl FigureModelCache { } } - pub struct FigureMgr { model_cache: FigureModelCache, character_states: HashMap>, @@ -350,17 +349,19 @@ impl FigureMgr { time, animation_history.time, ), - comp::Animation::Gliding => character::GlidingAnimation::update_skeleton( - state.skeleton_mut(), - time, - animation_history.time, - ), + comp::Animation::Gliding => { + character::GlidingAnimation::update_skeleton( + state.skeleton_mut(), + time, + animation_history.time, + ) + } }; state.skeleton.interpolate(&target_skeleton); state.update(renderer, pos.0, dir.0, Rgba::white()); - }, + } Body::Quadruped(body) => { let state = self.quadruped_states.entry(entity).or_insert_with(|| { FigureState::new(renderer, QuadrupedSkeleton::new()) @@ -392,21 +393,21 @@ impl FigureMgr { // Change in health as color! let col = stats .and_then(|stats| stats.hp.last_change) - .map(|(change_by, change_time)| { - Rgba::new(1.0, 0.7, 0.7, 1.0) - }) + .map(|(change_by, change_time)| Rgba::new(1.0, 0.7, 0.7, 1.0)) .unwrap_or(Rgba::broadcast(1.0)); state.update(renderer, pos.0, dir.0, col); - }, + } }, // TODO: Non-character actors } } // Clear states that have dead entities - self.character_states.retain(|entity, _| ecs.entities().is_alive(*entity)); - self.quadruped_states.retain(|entity, _| ecs.entities().is_alive(*entity)); + self.character_states + .retain(|entity, _| ecs.entities().is_alive(*entity)); + self.quadruped_states + .retain(|entity, _| ecs.entities().is_alive(*entity)); } pub fn render( @@ -422,19 +423,20 @@ impl FigureMgr { match actor { comp::Actor::Character { body, .. } => { if let Some((locals, bone_consts)) = match body { - Body::Humanoid(_) => self.character_states.get(&entity).map(|state| (state.locals(), state.bone_consts())), - Body::Quadruped(_) => self.quadruped_states.get(&entity).map(|state| (state.locals(), state.bone_consts())), + Body::Humanoid(_) => self + .character_states + .get(&entity) + .map(|state| (state.locals(), state.bone_consts())), + Body::Quadruped(_) => self + .quadruped_states + .get(&entity) + .map(|state| (state.locals(), state.bone_consts())), } { let model = self.model_cache.get_or_create_model(renderer, *body, tick); - renderer.render_figure( - model, - globals, - locals, - bone_consts, - ); + renderer.render_figure(model, globals, locals, bone_consts); } - }, + } } } } @@ -457,7 +459,13 @@ impl FigureState { } } - pub fn update(&mut self, renderer: &mut Renderer, pos: Vec3, dir: Vec3, col: Rgba) { + pub fn update( + &mut self, + renderer: &mut Renderer, + pos: Vec3, + dir: Vec3, + col: Rgba, + ) { let mat = Mat4::::identity() * Mat4::translation_3d(pos) * Mat4::rotation_z(-dir.x.atan2(dir.y)); // + f32::consts::PI / 2.0); From 71089e8c31811b353d607bfbb1ddcfb9962270c8 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 16 May 2019 21:18:48 +0100 Subject: [PATCH 20/21] Fixed occasional chunk load failures Former-commit-id: cf425a925cbcea4800f5e2ab82f8fb455cf96824 --- client/src/lib.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 11c4266974..abf3dfbed1 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -19,7 +19,11 @@ use common::{ terrain::TerrainChunk, }; use specs::Builder; -use std::{collections::HashSet, net::SocketAddr, time::Duration}; +use std::{ + collections::HashMap, + net::SocketAddr, + time::{Duration, Instant}, +}; use threadpool::ThreadPool; use vek::*; @@ -42,7 +46,7 @@ pub struct Client { entity: EcsEntity, view_distance: u64, - pending_chunks: HashSet>, + pending_chunks: HashMap, Instant>, } impl Client { @@ -82,7 +86,7 @@ impl Client { entity, view_distance, - pending_chunks: HashSet::new(), + pending_chunks: HashMap::new(), }) } @@ -220,12 +224,12 @@ impl Client { for k in 0..6 { let key = Vec3::new(i, j, k); if self.state.terrain().get_key(key).is_none() - && !self.pending_chunks.contains(&key) + && !self.pending_chunks.contains_key(&key) { if self.pending_chunks.len() < 4 { self.postbox .send_message(ClientMsg::TerrainChunkRequest { key }); - self.pending_chunks.insert(key); + self.pending_chunks.insert(key, Instant::now()); } else { break 'outer; } @@ -234,6 +238,10 @@ impl Client { } } } + + // If chunks are taking too long, assume they're no longer pending + let now = Instant::now(); + self.pending_chunks.retain(|_, created| now.duration_since(*created) < Duration::from_secs(10)); } // Finish the tick, pass control back to the frontend (step 6) From b14909f5a84b6292a0cb7d89adeed6e1fd80cbc7 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 16 May 2019 22:04:16 +0100 Subject: [PATCH 21/21] fmt Former-commit-id: ba065e557c6309cfd7a743db5b52544ee57c3469 --- client/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index abf3dfbed1..96b182e3f0 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -241,7 +241,8 @@ impl Client { // If chunks are taking too long, assume they're no longer pending let now = Instant::now(); - self.pending_chunks.retain(|_, created| now.duration_since(*created) < Duration::from_secs(10)); + self.pending_chunks + .retain(|_, created| now.duration_since(*created) < Duration::from_secs(10)); } // Finish the tick, pass control back to the frontend (step 6)