Merge branch 'cities-charcreation-frankenbranch' into 'master'

Alternate heads

See merge request veloren/veloren!252
This commit is contained in:
Marcel 2019-06-28 08:24:14 +00:00
commit 42c5e671a1
64 changed files with 667 additions and 284 deletions

BIN
assets/voxygen/voxel/figure/beard/human/1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/body/empty.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/body/hand.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/figure/empty.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_danari_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_danari_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_dwarf_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_dwarf_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_elf_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_elf_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_human_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_orc_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_orc_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_test2.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_undead_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/head_undead_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head/human/1.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_danari_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_danari_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_dwarf_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_dwarf_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_elf_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_elf_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_human_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_human_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_orc_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_orc_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_test1.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_undead_female.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/figure/head_undead_male.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/axe/axe.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/axe/rusty_2h.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/hammer/rusty_2h.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/weapon/sword/wood_2h.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -18,14 +18,8 @@ pub enum BodyType {
Unspecified,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Head {
Default,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Chest {
Default,
Blue,
Brown,
Dark,
@ -35,13 +29,11 @@ pub enum Chest {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Belt {
//Default,
Dark,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Pants {
Default,
Blue,
Brown,
Dark,
@ -56,13 +48,13 @@ pub enum Hand {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Foot {
Default,
Dark,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Shoulder {
Default,
None,
Brown1,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
@ -165,9 +157,7 @@ pub const ALL_RACES: [Race; 6] = [
Race::Undead,
];
pub const ALL_BODY_TYPES: [BodyType; 3] = [BodyType::Female, BodyType::Male, BodyType::Unspecified];
pub const ALL_HEADS: [Head; 1] = [Head::Default];
pub const ALL_CHESTS: [Chest; 6] = [
Chest::Default,
pub const ALL_CHESTS: [Chest; 5] = [
Chest::Blue,
Chest::Brown,
Chest::Dark,
@ -178,8 +168,7 @@ pub const ALL_BELTS: [Belt; 1] = [
//Belt::Default,
Belt::Dark,
];
pub const ALL_PANTS: [Pants; 6] = [
Pants::Default,
pub const ALL_PANTS: [Pants; 5] = [
Pants::Blue,
Pants::Brown,
Pants::Dark,
@ -187,7 +176,7 @@ pub const ALL_PANTS: [Pants; 6] = [
Pants::Orange,
];
pub const ALL_HANDS: [Hand; 1] = [Hand::Default];
pub const ALL_FEET: [Foot; 2] = [Foot::Default, Foot::Dark];
pub const ALL_FEET: [Foot; 1] = [Foot::Dark];
pub const ALL_WEAPONS: [Weapon; 7] = [
Weapon::Daggers,
Weapon::SwordShield,
@ -197,14 +186,13 @@ pub const ALL_WEAPONS: [Weapon; 7] = [
Weapon::Bow,
Weapon::Staff,
];
pub const ALL_SHOULDERS: [Shoulder; 1] = [Shoulder::Default];
pub const ALL_SHOULDERS: [Shoulder; 2] = [Shoulder::None, Shoulder::Brown1];
pub const ALL_DRAW: [Draw; 1] = [Draw::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct HumanoidBody {
pub race: Race,
pub body_type: BodyType,
pub head: Head,
pub chest: Chest,
pub belt: Belt,
pub pants: Pants,
@ -221,7 +209,6 @@ impl HumanoidBody {
Self {
race: *(&ALL_RACES).choose(&mut rng).unwrap(),
body_type: *(&ALL_BODY_TYPES).choose(&mut rng).unwrap(),
head: *(&ALL_HEADS).choose(&mut rng).unwrap(),
chest: *(&ALL_CHESTS).choose(&mut rng).unwrap(),
belt: *(&ALL_BELTS).choose(&mut rng).unwrap(),
pants: *(&ALL_PANTS).choose(&mut rng).unwrap(),
@ -234,14 +221,6 @@ impl HumanoidBody {
}
}
///////////
const ALL_QRACES: [Race; 6] = [
Race::Danari,
Race::Dwarf,
Race::Elf,
Race::Human,
Race::Orc,
Race::Undead,
];
const ALL_QBODY_TYPES: [BodyType; 3] = [BodyType::Female, BodyType::Male, BodyType::Unspecified];
const ALL_QPIG_HEADS: [PigHead; 1] = [PigHead::Default];
const ALL_QPIG_CHESTS: [PigChest; 1] = [PigChest::Default];
@ -250,7 +229,6 @@ const ALL_QPIG_LEG_RS: [PigLegR; 1] = [PigLegR::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct QuadrupedBody {
pub race: Race,
pub body_type: BodyType,
pub pig_head: PigHead,
pub pig_chest: PigChest,
@ -262,7 +240,6 @@ impl QuadrupedBody {
pub fn random() -> Self {
let mut rng = thread_rng();
Self {
race: *(&ALL_QRACES).choose(&mut rng).unwrap(),
body_type: *(&ALL_QBODY_TYPES).choose(&mut rng).unwrap(),
pig_head: *(&ALL_QPIG_HEADS).choose(&mut rng).unwrap(),
pig_chest: *(&ALL_QPIG_CHESTS).choose(&mut rng).unwrap(),
@ -272,14 +249,6 @@ impl QuadrupedBody {
}
}
/////////////
const ALL_QMRACES: [Race; 6] = [
Race::Danari,
Race::Dwarf,
Race::Elf,
Race::Human,
Race::Orc,
Race::Undead,
];
const ALL_QMBODY_TYPES: [BodyType; 3] = [BodyType::Female, BodyType::Male, BodyType::Unspecified];
const ALL_QMWOLF_HEADS_UPPER: [WolfHeadUpper; 1] = [WolfHeadUpper::Default];
const ALL_QMWOLF_JAWS: [WolfJaw; 1] = [WolfJaw::Default];
@ -295,7 +264,6 @@ const ALL_QMWOLF_FEET_RB: [WolfFootRB; 1] = [WolfFootRB::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct QuadrupedMediumBody {
pub race: Race,
pub body_type: BodyType,
pub wolf_head_upper: WolfHeadUpper,
pub wolf_jaw: WolfJaw,
@ -314,7 +282,6 @@ impl QuadrupedMediumBody {
pub fn random() -> Self {
let mut rng = thread_rng();
Self {
race: *(&ALL_QMRACES).choose(&mut rng).unwrap(),
body_type: *(&ALL_QMBODY_TYPES).choose(&mut rng).unwrap(),
wolf_head_upper: *(&ALL_QMWOLF_HEADS_UPPER).choose(&mut rng).unwrap(),
wolf_jaw: *(&ALL_QMWOLF_JAWS).choose(&mut rng).unwrap(),

View File

@ -4,7 +4,7 @@ use specs::{Component, VecStorage};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Armor {
// TODO: Don't make armor be a body part. Wearing enemy's head is funny but also creepy thing to do.
Helmet(actor::Head),
Helmet,
Shoulders(actor::Shoulder),
Chestplate(actor::Chest),
Belt(actor::Belt),

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -15,6 +18,7 @@ impl Animation for AttackAnimation {
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
@ -24,11 +28,15 @@ impl Animation for AttackAnimation {
let wave_quick = (anim_time as f32 * 0.5).sin();
let wave_stop_quick = (anim_time as f32 * 16.0).min(PI / 2.0).sin();
next.head.offset = Vec3::new(0.0, 2.0, 11.0);
next.head.offset = Vec3::new(
0.0,
0.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 15.0,
);
next.head.ori = Quaternion::rotation_z(wave_stop_quick * -0.25)
* Quaternion::rotation_x(0.0 + wave_stop_quick * -0.1)
* Quaternion::rotation_y(wave_stop_quick * 0.1);
next.head.scale = Vec3::one();
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 7.0);
next.chest.ori = Quaternion::rotation_x(0.0);
@ -72,7 +80,11 @@ impl Animation for AttackAnimation {
next.r_foot.ori = Quaternion::rotation_x(wave_stop_quick * 1.2);
next.r_foot.scale = Vec3::one();
next.weapon.offset = Vec3::new(-7.0, -2.0, 5.0);
next.weapon.offset = Vec3::new(
-7.0 + skeleton_attr.weapon_x,
-2.0 + skeleton_attr.weapon_y,
5.0,
);
next.weapon.ori = Quaternion::rotation_y(2.5);
next.weapon.scale = Vec3::one() * 0.0;
@ -89,30 +101,32 @@ impl Animation for AttackAnimation {
next.draw.scale = Vec3::one() * 0.0;
next.left_equip.offset = Vec3::new(
-8.0 + wave_quicken_slow * 10.0,
-8.0 + wave_quicken_slow * 10.0 + skeleton_attr.weapon_x,
4.0 + wave_quicken_double * 3.0,
9.0,
) / 11.0;
) / 11.0
* skeleton_attr.scaler;
next.left_equip.ori = Quaternion::rotation_z(-0.8)
* Quaternion::rotation_x(0.0 + wave_quicken * -0.8)
* Quaternion::rotation_y(0.0 + wave_quicken * -0.4);
next.left_equip.scale = Vec3::one() / 11.0;
next.left_equip.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next.right_equip.offset = Vec3::new(
-8.0 + wave_quicken_slow * 10.0,
4.0 + wave_quicken_double * 3.0,
9.0,
) / 11.0;
) / 11.0
* skeleton_attr.scaler;
next.right_equip.ori = Quaternion::rotation_z(-0.8)
* Quaternion::rotation_x(0.0 + wave_quicken * -0.8)
* Quaternion::rotation_y(0.0 + wave_quicken * -0.4);
next.right_equip.scale = Vec3::one() / 11.0;
next.right_equip.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next.torso.offset = Vec3::new(0.0, -0.2, 0.1);
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
next.torso.ori = Quaternion::rotation_z(wave_stop_quick * -0.2)
* Quaternion::rotation_x(0.0 + wave_stop_quick * -0.2)
* Quaternion::rotation_y(wave_stop_quick * 0.2);
next.torso.scale = Vec3::one() / 11.0;
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}
}

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -12,6 +15,7 @@ impl Animation for CidleAnimation {
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::ops::Mul;
use vek::*;
@ -12,6 +15,7 @@ impl Animation for CrunAnimation {
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -12,6 +15,7 @@ impl Animation for GlidingAnimation {
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let wave_slow = (anim_time as f32 * 7.0).sin();
@ -35,44 +39,54 @@ impl Animation for GlidingAnimation {
.sin()
* 0.25,
);
next.head.offset = Vec3::new(0.0, 2.0, 2.0);
next.head.offset = Vec3::new(
0.0,
0.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 6.0,
);
next.head.ori = Quaternion::rotation_x(0.35 - wave_very_slow * 0.10 + head_look.y)
* Quaternion::rotation_z(head_look.x + wave_very_slow_cos * 0.15);
next.head.scale = Vec3::one();
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, -2.0);
next.chest.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.15);
next.chest.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.2);
next.chest.scale = Vec3::one();
next.belt.offset = Vec3::new(0.0, 0.0, -4.0);
next.belt.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.20);
next.belt.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.25);
next.belt.scale = Vec3::one();
next.shorts.offset = Vec3::new(0.0, 0.0, -7.0);
next.shorts.ori = Quaternion::rotation_z(wave_very_slow_cos * 0.25);
next.shorts.scale = Vec3::one();
next.l_hand.offset = Vec3::new(-10.0, -2.0 + wave_very_slow * 0.10, 10.5);
next.l_hand.ori = Quaternion::rotation_x(1.0 + wave_very_slow_cos * -0.10);
next.l_hand.offset = Vec3::new(-10.0, -5.0 + wave_very_slow * 0.1, 8.5);
next.l_hand.ori =
Quaternion::rotation_x(1.0 + wave_very_slow_cos * -0.1) * skeleton_attr.scaler;
next.l_hand.scale = Vec3::one();
next.r_hand.offset = Vec3::new(10.0, -2.0 + wave_very_slow * 0.10, 10.5);
next.r_hand.offset = Vec3::new(10.0, -5.0 + wave_very_slow * 0.1, 8.5);
next.r_hand.ori = Quaternion::rotation_x(1.0 + wave_very_slow_cos * -0.10);
next.r_hand.scale = Vec3::one();
next.l_foot.offset = Vec3::new(-3.4, 1.0, -2.0);
next.l_foot.ori = Quaternion::rotation_x(
(wave_stop * -0.7 - wave_slow_cos * -0.21 + wave_very_slow * 0.19) * velocity * 0.07,
(wave_stop * -0.7 - wave_slow_cos * -0.21 + wave_very_slow * 0.19) * velocity * 0.04,
);
next.l_foot.scale = Vec3::one();
next.r_foot.offset = Vec3::new(3.4, 1.0, -2.0);
next.r_foot.ori = Quaternion::rotation_x(
(wave_stop * -0.8 + wave_slow * -0.25 + wave_very_slow_alt * 0.13) * velocity * 0.07,
(wave_stop * -0.8 + wave_slow * -0.25 + wave_very_slow_alt * 0.13) * velocity * 0.04,
);
next.r_foot.scale = Vec3::one();
next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0);
next.weapon.offset = Vec3::new(
-7.0 + skeleton_attr.weapon_x,
-5.0 + skeleton_attr.weapon_y,
15.0,
);
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
next.weapon.scale = Vec3::one();
@ -84,7 +98,7 @@ impl Animation for GlidingAnimation {
next.r_shoulder.ori = Quaternion::rotation_x(0.0);
next.r_shoulder.scale = Vec3::one() * 1.04;
next.draw.offset = Vec3::new(0.0, -9.0 + wave_very_slow * 0.10, 8.0);
next.draw.offset = Vec3::new(0.0, -13.0 + wave_very_slow * 0.10, 6.0);
next.draw.ori = Quaternion::rotation_x(1.0)//0.95 - wave_very_slow * 0.08)
* Quaternion::rotation_y(wave_very_slow_cos * 0.04);
next.draw.scale = Vec3::one();
@ -94,12 +108,12 @@ impl Animation for GlidingAnimation {
next.left_equip.scale = Vec3::one() * 0.0;
next.right_equip.offset = Vec3::new(0.0, 0.0, -5.0) / 11.0;
next.right_equip.ori = Quaternion::rotation_x(0.0);;
next.right_equip.ori = Quaternion::rotation_x(0.0);
next.right_equip.scale = Vec3::one() * 0.0;
next.torso.offset = Vec3::new(0.0, -0.2, 10.0) / 11.0;
next.torso.offset = Vec3::new(0.0, 6.0, 15.0) / 11.0 * skeleton_attr.scaler;
next.torso.ori = Quaternion::rotation_x(-0.05 * velocity + wave_very_slow * 0.10);
next.torso.scale = Vec3::one() / 11.0;
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -15,27 +18,35 @@ impl Animation for IdleAnimation {
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let wave = (anim_time as f32 * 4.0).sin();
let wave_ultra_slow = (anim_time as f32 * 1.0 + PI).sin();
let wave_ultra_slow_cos = (anim_time as f32 * 1.0 + PI).cos();
let head_look = Vec2::new(
((global_time + anim_time) as f32 / 8.0)
((global_time + anim_time) as f32 / 12.0)
.floor()
.mul(7331.0)
.sin()
* 0.5,
((global_time + anim_time) as f32 / 8.0)
((global_time + anim_time) as f32 / 12.0)
.floor()
.mul(1337.0)
.sin()
* 0.25,
);
next.head.offset = Vec3::new(0.0, 2.0, 11.0 + wave_ultra_slow * 0.3);
next.head.ori = Quaternion::rotation_z(head_look.x) * Quaternion::rotation_x(head_look.y);
next.head.scale = Vec3::one();
next.head.offset = Vec3::new(
0.0,
0.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 15.0 + wave_ultra_slow * 0.3,
);
next.head.ori =
Quaternion::rotation_z(head_look.x) * Quaternion::rotation_x(head_look.y.abs());
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_ultra_slow * 0.3);
next.chest.ori = Quaternion::rotation_x(0.0);
@ -74,7 +85,11 @@ impl Animation for IdleAnimation {
next.r_foot.ori = Quaternion::identity();
next.r_foot.scale = Vec3::one();
next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0);
next.weapon.offset = Vec3::new(
-7.0 + skeleton_attr.weapon_x,
-5.0 + skeleton_attr.weapon_y,
15.0,
);
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
next.weapon.scale = Vec3::one();
@ -98,9 +113,9 @@ impl Animation for IdleAnimation {
next.right_equip.ori = Quaternion::rotation_x(0.0);;
next.right_equip.scale = Vec3::one() * 0.0;
next.torso.offset = Vec3::new(0.0, -0.2, 0.1);
next.torso.offset = Vec3::new(0.0, -0.2, 0.1) * skeleton_attr.scaler;
next.torso.ori = Quaternion::rotation_x(0.0);
next.torso.scale = Vec3::one() / 11.0;
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::f32::consts::PI;
use vek::*;
@ -12,6 +15,7 @@ impl Animation for JumpAnimation {
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let wave = (anim_time as f32 * 14.0).sin();
@ -19,9 +23,13 @@ impl Animation for JumpAnimation {
let wave_stop = (anim_time as f32 * 4.5).min(PI / 2.0).sin();
let wave_stop_alt = (anim_time as f32 * 5.0).min(PI / 2.0).sin();
next.head.offset = Vec3::new(0.0, 3.0, 13.0);
next.head.offset = Vec3::new(
0.0,
0.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 15.0,
);
next.head.ori = Quaternion::rotation_x(0.25 + wave_stop * 0.1 + wave_slow * 0.04);
next.head.scale = Vec3::one();
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 8.0);
next.chest.ori = Quaternion::rotation_z(0.0);
@ -59,7 +67,11 @@ impl Animation for JumpAnimation {
next.r_foot.ori = Quaternion::rotation_x(wave_stop * 1.2 + wave_slow * 0.2);
next.r_foot.scale = Vec3::one();
next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0);
next.weapon.offset = Vec3::new(
-7.0 + skeleton_attr.weapon_x,
-5.0 + skeleton_attr.weapon_y,
15.0,
);
next.weapon.ori = Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57);
next.weapon.scale = Vec3::one();
@ -83,9 +95,9 @@ impl Animation for JumpAnimation {
next.right_equip.ori = Quaternion::rotation_x(0.0);;
next.right_equip.scale = Vec3::one() * 0.0;
next.torso.offset = Vec3::new(0.0, -0.2, 0.0);
next.torso.offset = Vec3::new(0.0, -0.2, 0.0) * skeleton_attr.scaler;
next.torso.ori = Quaternion::rotation_x(-0.2);
next.torso.scale = Vec3::one() / 11.0;
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}

View File

@ -69,8 +69,9 @@ impl Skeleton for CharacterSkeleton {
let torso_mat = self.torso.compute_base_matrix();
let l_hand_mat = self.l_hand.compute_base_matrix();
let weapon_mat = self.weapon.compute_base_matrix();
let head_mat = self.head.compute_base_matrix();
[
FigureBoneData::new(torso_mat * self.head.compute_base_matrix()),
FigureBoneData::new(torso_mat * head_mat),
FigureBoneData::new(torso_mat * chest_mat),
FigureBoneData::new(torso_mat * self.belt.compute_base_matrix()),
FigureBoneData::new(torso_mat * self.shorts.compute_base_matrix()),

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -12,6 +15,7 @@ impl Animation for RollAnimation {
skeleton: &Self::Skeleton,
global_time: f64,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
@ -22,20 +26,24 @@ impl Animation for RollAnimation {
let wave_slow = (anim_time as f32 * 2.8 + PI).sin();
let wave_dub = (anim_time as f32 * 5.5).sin();
next.head.offset = Vec3::new(0.0, 0.0 + wave_slow * -3.0, 9.0 + wave_dub * -5.0);
next.head.offset = Vec3::new(
0.0,
-2.0 + wave_slow * -3.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 9.0 + wave_dub * -5.0,
);
next.head.ori = Quaternion::rotation_x(wave_dub * -0.4);
next.head.scale = Vec3::one();
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_dub * -2.5);
next.chest.ori = Quaternion::rotation_x(wave_dub * -0.5);
next.chest.ori = Quaternion::rotation_x(wave_dub * -0.5 + wave_slow * 4.0);
next.chest.scale = Vec3::one() * 1.01;
next.belt.offset = Vec3::new(0.0, 0.0, 5.0);
next.belt.ori = Quaternion::rotation_x(0.0);
next.belt.ori = Quaternion::rotation_x(0.0 + wave_slow * 4.0);
next.belt.scale = Vec3::one();
next.shorts.offset = Vec3::new(0.0, 0.0, 2.0);
next.shorts.ori = Quaternion::rotation_x(0.0);
next.shorts.ori = Quaternion::rotation_x(0.0 + wave_slow * 4.0);
next.shorts.scale = Vec3::one();
next.l_hand.offset = Vec3::new(
@ -65,9 +73,14 @@ impl Animation for RollAnimation {
next.r_foot.ori = Quaternion::rotation_x(wave * -0.4);
next.r_foot.scale = Vec3::one();
next.weapon.offset = Vec3::new(-7.0, -7.0, 15.0);
next.weapon.ori =
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_quick * 1.0);
next.weapon.offset = Vec3::new(
-7.0 + skeleton_attr.weapon_x,
-5.0 + skeleton_attr.weapon_y,
15.0,
);
next.weapon.ori = Quaternion::rotation_y(2.5)
* Quaternion::rotation_z(1.57)
* Quaternion::rotation_x(0.0);
next.weapon.scale = Vec3::one();
next.l_shoulder.offset = Vec3::new(-10.0, -3.2, 2.5);
@ -90,9 +103,10 @@ impl Animation for RollAnimation {
next.right_equip.ori = Quaternion::rotation_x(0.0);;
next.right_equip.scale = Vec3::one() * 0.0;
next.torso.offset = Vec3::new(0.0, -2.2, 0.1 + wave_dub * 16.0) / 11.0;
next.torso.offset =
Vec3::new(0.0, -2.2, 0.1 + wave_dub * 16.0) / 11.0 * skeleton_attr.scaler;
next.torso.ori = Quaternion::rotation_x(wave_slow * 6.0);
next.torso.scale = Vec3::one() / 11.0;
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}
}

View File

@ -1,4 +1,7 @@
use super::{super::Animation, CharacterSkeleton};
use super::{
super::{Animation, SkeletonAttr},
CharacterSkeleton,
};
use std::f32::consts::PI;
use std::ops::Mul;
use vek::*;
@ -13,6 +16,7 @@ impl Animation for RunAnimation {
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
@ -35,10 +39,14 @@ impl Animation for RunAnimation {
* 0.1,
);
next.head.offset = Vec3::new(0.0, 3.0, 12.0 + wave_cos * 1.3);
next.head.offset = Vec3::new(
0.0,
-1.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 15.0 + wave_cos * 1.3,
);
next.head.ori = Quaternion::rotation_z(head_look.x + wave * 0.1)
* Quaternion::rotation_x(head_look.y + 0.35);
next.head.scale = Vec3::one();
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + wave_cos * 1.1);
next.chest.ori = Quaternion::rotation_z(wave * 0.1);
@ -58,7 +66,7 @@ impl Animation for RunAnimation {
7.0 - wave * 1.5,
);
next.l_hand.ori = Quaternion::rotation_x(wave_cos * 0.8);
next.l_hand.scale = Vec3::one() * 1.0;
next.l_hand.scale = Vec3::one();
next.r_hand.offset = Vec3::new(
7.5 - wave_cos_dub * 1.0,
@ -66,17 +74,21 @@ impl Animation for RunAnimation {
7.0 + wave * 1.5,
);
next.r_hand.ori = Quaternion::rotation_x(wave_cos * -0.8);
next.r_hand.scale = Vec3::one() * 1.0;
next.r_hand.scale = Vec3::one();
next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 7.0);
next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.3);
next.l_foot.offset = Vec3::new(-3.4, 0.0 + wave_cos * 1.0, 6.0 - wave_cos_dub * 0.11);
next.l_foot.ori = Quaternion::rotation_x(-0.0 - wave_cos * 1.5);
next.l_foot.scale = Vec3::one();
next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 7.0);
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.3);
next.r_foot.offset = Vec3::new(3.4, 0.0 - wave_cos * 1.0, 6.0 - wave_cos_dub * 0.11);
next.r_foot.ori = Quaternion::rotation_x(-0.0 + wave_cos * 1.5);
next.r_foot.scale = Vec3::one();
next.weapon.offset = Vec3::new(-7.0, -5.0, 15.0);
next.weapon.offset = Vec3::new(
-7.0 + skeleton_attr.weapon_x,
-5.0 + skeleton_attr.weapon_y,
15.0,
);
next.weapon.ori =
Quaternion::rotation_y(2.5) * Quaternion::rotation_z(1.57 + wave_cos * 0.25);
next.weapon.scale = Vec3::one();
@ -101,10 +113,11 @@ impl Animation for RunAnimation {
next.right_equip.ori = Quaternion::rotation_x(0.0);;
next.right_equip.scale = Vec3::one() * 0.0;
next.torso.offset = Vec3::new(0.0, -0.2, 0.4);
next.torso.offset =
Vec3::new(0.0, -0.2 + wave * -0.08, 0.4 + wave_cos_dub * 0.11) * skeleton_attr.scaler;
next.torso.ori =
Quaternion::rotation_x(wave_stop * velocity * -0.06 + wave_diff * velocity * -0.005);
next.torso.scale = Vec3::one() / 11.0;
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next
}

View File

@ -4,6 +4,7 @@ pub mod quadruped;
pub mod quadrupedmedium;
use crate::render::FigureBoneData;
use common::comp::actor::{BodyType, HumanoidBody, Race, Weapon};
use vek::*;
#[derive(Copy, Clone)]
@ -45,6 +46,117 @@ pub trait Skeleton: Send + Sync + 'static {
fn interpolate(&mut self, target: &Self, dt: f32);
}
pub struct SkeletonAttr {
scaler: f32,
head_scale: f32,
neck_height: f32,
neck_forward: f32,
weapon_x: f32,
weapon_y: f32,
}
impl Default for SkeletonAttr {
fn default() -> Self {
Self {
scaler: 1.0,
head_scale: 1.0,
neck_height: 1.0,
neck_forward: 1.0,
weapon_x: 1.0,
weapon_y: 1.0,
}
}
}
impl<'a> From<&'a HumanoidBody> for SkeletonAttr {
fn from(body: &'a HumanoidBody) -> Self {
Self {
scaler: match (body.race, body.body_type) {
(Race::Orc, BodyType::Male) => 1.2,
(Race::Orc, BodyType::Female) => 1.0,
(Race::Human, BodyType::Male) => 1.0,
(Race::Human, BodyType::Female) => 0.90,
(Race::Elf, BodyType::Male) => 1.10,
(Race::Elf, BodyType::Female) => 1.0,
(Race::Dwarf, BodyType::Male) => 0.92,
(Race::Dwarf, BodyType::Female) => 0.89,
(Race::Undead, BodyType::Male) => 1.0,
(Race::Undead, BodyType::Female) => 0.90,
(Race::Danari, BodyType::Male) => 0.85,
(Race::Danari, BodyType::Female) => 0.82,
_ => 1.0,
},
head_scale: match (body.race, body.body_type) {
(Race::Orc, BodyType::Male) => 0.9,
(Race::Orc, BodyType::Female) => 0.88,
(Race::Human, BodyType::Male) => 1.0,
(Race::Human, BodyType::Female) => 1.0,
(Race::Elf, BodyType::Male) => 0.9,
(Race::Elf, BodyType::Female) => 0.9,
(Race::Dwarf, BodyType::Male) => 1.0,
(Race::Dwarf, BodyType::Female) => 1.0,
(Race::Undead, BodyType::Male) => 1.0,
(Race::Undead, BodyType::Female) => 1.0,
(Race::Danari, BodyType::Male) => 1.11,
(Race::Danari, BodyType::Female) => 1.11,
_ => 1.0,
},
neck_height: match (body.race, body.body_type) {
(Race::Orc, BodyType::Male) => -1.0,
(Race::Orc, BodyType::Female) => -2.0,
(Race::Human, BodyType::Male) => 0.0,
(Race::Human, BodyType::Female) => -2.0,
(Race::Elf, BodyType::Male) => -0.5,
(Race::Elf, BodyType::Female) => -1.5,
(Race::Dwarf, BodyType::Male) => -0.0,
(Race::Dwarf, BodyType::Female) => -1.0,
(Race::Undead, BodyType::Male) => -1.0,
(Race::Undead, BodyType::Female) => -1.0,
(Race::Danari, BodyType::Male) => 0.5,
(Race::Danari, BodyType::Female) => -0.5,
_ => 1.0,
},
neck_forward: match (body.race, body.body_type) {
(Race::Orc, BodyType::Male) => -1.0,
(Race::Orc, BodyType::Female) => 2.0,
(Race::Human, BodyType::Male) => 1.0,
(Race::Human, BodyType::Female) => 1.0,
(Race::Elf, BodyType::Male) => -0.5,
(Race::Elf, BodyType::Female) => -0.5,
(Race::Dwarf, BodyType::Male) => 0.0,
(Race::Dwarf, BodyType::Female) => 2.0,
(Race::Undead, BodyType::Male) => 1.0,
(Race::Undead, BodyType::Female) => 1.0,
(Race::Danari, BodyType::Male) => 0.5,
(Race::Danari, BodyType::Female) => 0.0,
_ => 1.0,
},
weapon_x: match body.weapon {
Weapon::Sword => 0.0,
Weapon::Axe => 3.0,
Weapon::Hammer => 0.0,
Weapon::SwordShield => 3.0,
Weapon::Staff => 3.0,
Weapon::Bow => 0.0,
Weapon::Daggers => 0.0,
_ => 1.0,
},
weapon_y: match body.weapon {
Weapon::Sword => -1.0,
Weapon::Axe => 0.0,
Weapon::Hammer => -2.0,
Weapon::SwordShield => 0.0,
Weapon::Staff => 0.0,
Weapon::Bow => -2.0,
Weapon::Daggers => -2.0,
_ => 1.0,
},
}
}
}
pub trait Animation {
type Skeleton;
type Dependency;
@ -54,5 +166,6 @@ pub trait Animation {
skeleton: &Self::Skeleton,
dependency: Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton;
}

View File

@ -1,4 +1,7 @@
use super::{super::Animation, QuadrupedSkeleton};
use super::{
super::{Animation, SkeletonAttr},
QuadrupedSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -12,6 +15,7 @@ impl Animation for IdleAnimation {
skeleton: &Self::Skeleton,
global_time: Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, QuadrupedSkeleton};
use super::{
super::{Animation, SkeletonAttr},
QuadrupedSkeleton,
};
use std::f32::consts::PI;
use vek::*;
@ -12,6 +15,7 @@ impl Animation for JumpAnimation {
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, QuadrupedSkeleton};
use super::{
super::{Animation, SkeletonAttr},
QuadrupedSkeleton,
};
use std::f32::consts::PI;
use vek::*;
@ -12,6 +15,7 @@ impl Animation for RunAnimation {
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, QuadrupedMediumSkeleton};
use super::{
super::{Animation, SkeletonAttr},
QuadrupedMediumSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -12,6 +15,7 @@ impl Animation for IdleAnimation {
skeleton: &Self::Skeleton,
global_time: Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, QuadrupedMediumSkeleton};
use super::{
super::{Animation, SkeletonAttr},
QuadrupedMediumSkeleton,
};
use std::f32::consts::PI;
use vek::*;
@ -12,6 +15,7 @@ impl Animation for JumpAnimation {
skeleton: &Self::Skeleton,
global_time: Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -1,4 +1,7 @@
use super::{super::Animation, QuadrupedMediumSkeleton};
use super::{
super::{Animation, SkeletonAttr},
QuadrupedMediumSkeleton,
};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
@ -12,6 +15,7 @@ impl Animation for RunAnimation {
skeleton: &Self::Skeleton,
(velocity, global_time): Self::Dependency,
anim_time: f64,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();

View File

@ -90,8 +90,11 @@ impl PlayState for CharSelectionState {
global_state.maintain();
// Maintain the scene.
self.scene
.maintain(global_state.window.renderer_mut(), &self.client.borrow());
self.scene.maintain(
global_state.window.renderer_mut(),
&self.client.borrow(),
self.char_selection_ui.character_body,
);
// Render the scene.
self.scene.render(

View File

@ -2,7 +2,7 @@ use crate::{
anim::{
character::{CharacterSkeleton, IdleAnimation},
fixture::FixtureSkeleton,
Animation, Skeleton,
Animation, Skeleton, SkeletonAttr,
},
render::{
create_pp_mesh, create_skybox_mesh, Consts, FigurePipeline, Globals, Model,
@ -14,7 +14,10 @@ use crate::{
},
};
use client::Client;
use common::{comp, state::DeltaTime};
use common::{
comp::{Body, HumanoidBody},
state::DeltaTime,
};
use log::error;
use vek::*;
@ -76,7 +79,7 @@ impl Scene {
&self.globals
}
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client, body: HumanoidBody) {
self.camera.set_focus_pos(Vec3::unit_z() * 2.0);
self.camera.update(client.state().get_time());
self.camera.set_distance(4.2);
@ -107,6 +110,7 @@ impl Scene {
self.figure_state.skeleton_mut(),
client.state().get_time(),
client.state().get_time(),
&SkeletonAttr::from(&body),
);
self.figure_state.skeleton_mut().interpolate(
&tgt_skeleton,
@ -122,14 +126,13 @@ impl Scene {
);
}
pub fn render(&mut self, renderer: &mut Renderer, client: &Client, body: comp::HumanoidBody) {
pub fn render(&mut self, renderer: &mut Renderer, client: &Client, body: HumanoidBody) {
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
let model = self.figure_model_cache.get_or_create_model(
renderer,
comp::Body::Humanoid(body),
client.get_tick(),
);
let model = &self
.figure_model_cache
.get_or_create_model(renderer, Body::Humanoid(body), client.get_tick())
.0;
renderer.render_figure(
model,

View File

@ -493,7 +493,7 @@ impl MainMenuUi {
.set(self.ids.servers_button, ui_widgets)
.was_clicked()
{
self.show_servers = true;
self.show_servers = !self.show_servers;
};
}

View File

@ -3,7 +3,7 @@ use crate::{
character::{self, CharacterSkeleton},
quadruped::{self, QuadrupedSkeleton},
quadrupedmedium::{self, QuadrupedMediumSkeleton},
Animation, Skeleton,
Animation, Skeleton, SkeletonAttr,
},
mesh::Meshable,
render::{
@ -16,8 +16,8 @@ use common::{
comp::{
self,
actor::{
Belt, Chest, Draw, Foot, Hand, Head, Pants, PigChest, PigHead, PigLegL, PigLegR,
Shoulder, Weapon, WolfEars, WolfFootLB, WolfFootLF, WolfFootRB, WolfFootRF,
Belt, BodyType, Chest, Draw, Foot, Hand, Pants, PigChest, PigHead, PigLegL, PigLegR,
Race, Shoulder, Weapon, WolfEars, WolfFootLB, WolfFootLF, WolfFootRB, WolfFootRF,
WolfHeadLower, WolfHeadUpper, WolfJaw, WolfTail, WolfTorsoBack, WolfTorsoMid,
},
Body,
@ -36,7 +36,7 @@ use vek::*;
const DAMAGE_FADE_COEFFICIENT: f64 = 5.0;
pub struct FigureModelCache {
models: HashMap<Body, (Model<FigurePipeline>, u64)>,
models: HashMap<Body, ((Model<FigurePipeline>, SkeletonAttr), u64)>,
}
impl FigureModelCache {
@ -51,7 +51,7 @@ impl FigureModelCache {
renderer: &mut Renderer,
body: Body,
tick: u64,
) -> &Model<FigurePipeline> {
) -> &(Model<FigurePipeline>, SkeletonAttr) {
match self.models.get_mut(&body) {
Some((_model, last_used)) => {
*last_used = tick;
@ -63,7 +63,7 @@ impl FigureModelCache {
{
let bone_meshes = match body {
Body::Humanoid(body) => [
Some(Self::load_head(body.head)),
Some(Self::load_head(body.race, body.body_type)),
Some(Self::load_chest(body.chest)),
Some(Self::load_belt(body.belt)),
Some(Self::load_pants(body.pants)),
@ -118,6 +118,11 @@ impl FigureModelCache {
],
};
let skeleton_attr = match body {
Body::Humanoid(body) => SkeletonAttr::from(&body),
_ => SkeletonAttr::default(),
};
let mut mesh = Mesh::new();
bone_meshes
.iter()
@ -129,7 +134,7 @@ impl FigureModelCache {
})
});
renderer.create_model(&mesh).unwrap()
(renderer.create_model(&mesh).unwrap(), skeleton_attr)
},
tick,
),
@ -153,19 +158,75 @@ impl FigureModelCache {
.generate_mesh(position)
}
fn load_head(head: Head) -> Mesh<FigurePipeline> {
Self::load_mesh(
match head {
Head::Default => "figure/head.vox",
},
Vec3::new(-7.0, -5.5, -6.0),
)
fn load_head(race: Race, body_type: BodyType) -> Mesh<FigurePipeline> {
let (name, offset) = match (race, body_type) {
(Race::Human, BodyType::Male) => (
"figure/head/head_human_male.vox",
Vec3::new(-7.0, -5.5, -9.25),
),
(Race::Human, BodyType::Female) => (
"figure/head/head_human_female.vox",
Vec3::new(-7.0, -7.5, -3.25),
),
(Race::Elf, BodyType::Male) => (
"figure/head/head_elf_male.vox",
Vec3::new(-9.0, -6.5, -3.75),
),
(Race::Elf, BodyType::Female) => (
"figure/head/head_elf_female.vox",
Vec3::new(-8.0, -5.5, -3.0),
),
(Race::Dwarf, BodyType::Male) => (
"figure/head/head_dwarf_male.vox",
Vec3::new(-6.0, -5.0, -12.5),
),
(Race::Dwarf, BodyType::Female) => (
"figure/head/head_dwarf_female.vox",
Vec3::new(-6.0, -6.0, -9.25),
),
(Race::Orc, BodyType::Male) => (
"figure/head/head_orc_male.vox",
Vec3::new(-8.0, -6.0, -2.75),
),
(Race::Orc, BodyType::Female) => (
"figure/head/head_orc_female.vox",
Vec3::new(-8.0, -5.5, -2.75),
),
(Race::Undead, BodyType::Male) => (
"figure/head/head_undead_male.vox",
Vec3::new(-5.5, -5.0, -2.5),
),
(Race::Undead, BodyType::Female) => (
"figure/head/head_undead_female.vox",
Vec3::new(-6.0, -5.0, -2.5),
),
(Race::Danari, BodyType::Male) => (
"figure/head/head_danari_male.vox",
Vec3::new(-9.0, -5.0, -2.75),
),
(Race::Danari, BodyType::Female) => (
"figure/head/head_danari_female.vox",
Vec3::new(-9.0, -5.5, -2.5),
),
_ => {
warn!("Invalid race, body_type combination for figure head");
("figure/head/head_human_male", Vec3::new(-7.0, -7.0, -9.25))
}
};
Self::load_mesh(name, offset)
}
// loads models with different offsets
// fn load_beard(beard: Beard) -> Mesh<FigurePipeline> {
// let (name, offset) = match beard {
// Beard::None => ("figure/body/empty.vox", Vec3::new(0.0, 0.0, 0.0)),
// Beard::Human1 => ("figure/empty.vox", Vec3::new(0.0, 0.0, 0.0)),
// };
// Self::load_mesh(name, offset)
// }
fn load_chest(chest: Chest) -> Mesh<FigurePipeline> {
Self::load_mesh(
match chest {
Chest::Default => "figure/body/chest_male.vox",
Chest::Blue => "armor/chest/chest_blue.vox",
Chest::Brown => "armor/chest/chest_brown.vox",
Chest::Dark => "armor/chest/chest_dark.vox",
@ -189,7 +250,6 @@ impl FigureModelCache {
fn load_pants(pants: Pants) -> Mesh<FigurePipeline> {
Self::load_mesh(
match pants {
Pants::Default => "figure/body/pants_male.vox",
Pants::Blue => "armor/pants/pants_blue.vox",
Pants::Brown => "armor/pants/pants_brown.vox",
Pants::Dark => "armor/pants/pants_dark.vox",
@ -221,7 +281,6 @@ impl FigureModelCache {
fn load_left_foot(foot: Foot) -> Mesh<FigurePipeline> {
Self::load_mesh(
match foot {
Foot::Default => "figure/body/foot.vox",
Foot::Dark => "armor/foot/foot_dark.vox",
},
Vec3::new(-2.5, -3.5, -9.0),
@ -231,7 +290,6 @@ impl FigureModelCache {
fn load_right_foot(foot: Foot) -> Mesh<FigurePipeline> {
Self::load_mesh(
match foot {
Foot::Default => "figure/body/foot.vox",
Foot::Dark => "armor/foot/foot_dark.vox",
},
Vec3::new(-2.5, -3.5, -9.0),
@ -239,20 +297,24 @@ impl FigureModelCache {
}
fn load_weapon(weapon: Weapon) -> Mesh<FigurePipeline> {
Self::load_mesh(
match weapon {
Weapon::Sword => "weapon/sword/sword_rusty_2h.vox",
// TODO actually match against other weapons and set the right model
_ => "weapon/sword/sword_rusty_2h.vox",
},
Vec3::new(-1.5, -6.5, -4.0),
)
let (name, offset) = match weapon {
Weapon::Sword => ("weapon/sword/rusty_2h.vox", Vec3::new(-1.5, -6.5, -4.0)),
Weapon::Hammer => ("weapon/hammer/rusty_2h.vox", Vec3::new(-2.5, -5.5, -4.0)),
Weapon::Axe => ("weapon/axe/rusty_2h.vox", Vec3::new(-1.5, -6.5, -4.0)),
Weapon::Sword => ("weapon/sword/wood_2h.vox", Vec3::new(-1.5, -6.5, -4.0)),
Weapon::Daggers => ("weapon/hammer/rusty_2h.vox", Vec3::new(-2.5, -5.5, -4.0)),
Weapon::SwordShield => ("weapon/axe/rusty_2h.vox", Vec3::new(-2.5, -6.5, -2.0)),
Weapon::Bow => ("weapon/hammer/rusty_2h.vox", Vec3::new(-2.5, -5.5, -4.0)),
Weapon::Staff => ("weapon/axe/rusty_2h.vox", Vec3::new(-2.5, -6.5, -2.0)),
};
Self::load_mesh(name, offset)
}
fn load_left_shoulder(shoulder: Shoulder) -> Mesh<FigurePipeline> {
Self::load_mesh(
match shoulder {
Shoulder::Default => "armor/shoulder/shoulder_l_brown.vox",
Shoulder::None => "figure/empty.vox",
Shoulder::Brown1 => "armor/shoulder/shoulder_l_brown.vox",
},
Vec3::new(2.5, -0.5, 0.0),
)
@ -261,7 +323,8 @@ impl FigureModelCache {
fn load_right_shoulder(shoulder: Shoulder) -> Mesh<FigurePipeline> {
Self::load_mesh(
match shoulder {
Shoulder::Default => "armor/shoulder/shoulder_r_brown.vox",
Shoulder::None => "figure/empty.vox",
Shoulder::Brown1 => "armor/shoulder/shoulder_r_brown.vox",
},
Vec3::new(2.5, -0.5, 0.0),
)
@ -277,13 +340,17 @@ impl FigureModelCache {
}
fn load_left_equip(weapon: Weapon) -> Mesh<FigurePipeline> {
Self::load_mesh(
match weapon {
Weapon::Sword => "weapon/sword/sword_rusty_2h.vox",
_ => "weapon/sword/sword_rusty_2h.vox",
},
Vec3::new(-1.5, -6.5, -4.5),
)
let (name, offset) = match weapon {
Weapon::Sword => ("weapon/sword/rusty_2h.vox", Vec3::new(-1.5, -6.5, -4.0)),
Weapon::Hammer => ("weapon/hammer/rusty_2h.vox", Vec3::new(-2.5, -5.5, -4.0)),
Weapon::Axe => ("weapon/axe/rusty_2h.vox", Vec3::new(-2.5, -6.5, -4.0)),
Weapon::Sword => ("weapon/sword/wood_2h.vox", Vec3::new(-1.5, -6.5, -4.0)),
Weapon::Daggers => ("weapon/hammer/rusty_2h.vox", Vec3::new(-2.5, -5.5, -4.0)),
Weapon::SwordShield => ("weapon/axe/rusty_2h.vox", Vec3::new(-2.5, -6.5, -2.0)),
Weapon::Bow => ("weapon/hammer/rusty_2h.vox", Vec3::new(-2.5, -5.5, -4.0)),
Weapon::Staff => ("weapon/axe/rusty_2h.vox", Vec3::new(-2.5, -6.5, -2.0)),
};
Self::load_mesh(name, offset)
}
fn load_right_equip(hand: Hand) -> Mesh<FigurePipeline> {
@ -294,6 +361,7 @@ impl FigureModelCache {
Vec3::new(-2.0, -2.5, -5.0),
)
}
/////////
fn load_pig_head(pig_head: PigHead) -> Mesh<FigurePipeline> {
Self::load_mesh(
@ -472,6 +540,7 @@ impl FigureMgr {
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
let time = client.state().get_time();
let tick = client.get_tick();
let ecs = client.state().ecs();
let view_distance = client.view_distance().unwrap_or(1);
let dt = client.state().get_delta_time();
@ -528,127 +597,153 @@ impl FigureMgr {
.unwrap_or(Rgba::broadcast(1.0));
match actor {
comp::Actor::Character { body, .. } => match body {
Body::Humanoid(_) => {
let state = self.character_states.entry(entity).or_insert_with(|| {
FigureState::new(renderer, CharacterSkeleton::new())
});
comp::Actor::Character { body, .. } => {
let skeleton_attr = &self
.model_cache
.get_or_create_model(renderer, *body, tick)
.1;
let target_skeleton = match animation_info.animation {
comp::Animation::Idle => character::IdleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
),
comp::Animation::Run => character::RunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
),
comp::Animation::Jump => character::JumpAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
),
comp::Animation::Attack => character::AttackAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
),
comp::Animation::Roll => character::RollAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
),
comp::Animation::Crun => character::CrunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
),
comp::Animation::Cidle => character::CidleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
),
comp::Animation::Gliding => {
character::GlidingAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
)
}
};
match body {
Body::Humanoid(_) => {
let state = self.character_states.entry(entity).or_insert_with(|| {
FigureState::new(renderer, CharacterSkeleton::new())
});
state.skeleton.interpolate(&target_skeleton, dt);
state.update(renderer, pos.0, ori.0, col, dt);
}
Body::Quadruped(_) => {
let state = self.quadruped_states.entry(entity).or_insert_with(|| {
FigureState::new(renderer, QuadrupedSkeleton::new())
});
let target_skeleton = match animation_info.animation {
comp::Animation::Run => quadruped::RunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
),
comp::Animation::Idle => quadruped::IdleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
),
comp::Animation::Jump => quadruped::JumpAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
),
// TODO!
_ => state.skeleton_mut().clone(),
};
state.skeleton.interpolate(&target_skeleton, dt);
state.update(renderer, pos.0, ori.0, col, dt);
}
Body::QuadrupedMedium(_) => {
let state =
self.quadruped_medium_states
.entry(entity)
.or_insert_with(|| {
FigureState::new(renderer, QuadrupedMediumSkeleton::new())
});
let target_skeleton = match animation_info.animation {
comp::Animation::Run => quadrupedmedium::RunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
),
comp::Animation::Idle => {
quadrupedmedium::IdleAnimation::update_skeleton(
let target_skeleton = match animation_info.animation {
comp::Animation::Idle => character::IdleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
)
}
comp::Animation::Jump => {
quadrupedmedium::JumpAnimation::update_skeleton(
skeleton_attr,
),
comp::Animation::Run => character::RunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
)
}
skeleton_attr,
),
comp::Animation::Jump => character::JumpAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
skeleton_attr,
),
comp::Animation::Attack => {
character::AttackAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
skeleton_attr,
)
}
comp::Animation::Roll => character::RollAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
skeleton_attr,
),
comp::Animation::Crun => character::CrunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
skeleton_attr,
),
comp::Animation::Cidle => {
character::CidleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
skeleton_attr,
)
}
comp::Animation::Gliding => {
character::GlidingAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
skeleton_attr,
)
}
};
// TODO!
_ => state.skeleton_mut().clone(),
};
state.skeleton.interpolate(&target_skeleton, dt);
state.update(renderer, pos.0, ori.0, col, dt);
}
Body::Quadruped(_) => {
let state = self.quadruped_states.entry(entity).or_insert_with(|| {
FigureState::new(renderer, QuadrupedSkeleton::new())
});
state.skeleton.interpolate(&target_skeleton, dt);
state.update(renderer, pos.0, ori.0, col, dt);
let target_skeleton = match animation_info.animation {
comp::Animation::Run => quadruped::RunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
skeleton_attr,
),
comp::Animation::Idle => quadruped::IdleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
skeleton_attr,
),
comp::Animation::Jump => quadruped::JumpAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
skeleton_attr,
),
// TODO!
_ => state.skeleton_mut().clone(),
};
state.skeleton.interpolate(&target_skeleton, dt);
state.update(renderer, pos.0, ori.0, col, dt);
}
Body::QuadrupedMedium(_) => {
let state =
self.quadruped_medium_states
.entry(entity)
.or_insert_with(|| {
FigureState::new(renderer, QuadrupedMediumSkeleton::new())
});
let target_skeleton = match animation_info.animation {
comp::Animation::Run => {
quadrupedmedium::RunAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
skeleton_attr,
)
}
comp::Animation::Idle => {
quadrupedmedium::IdleAnimation::update_skeleton(
state.skeleton_mut(),
time,
animation_info.time,
skeleton_attr,
)
}
comp::Animation::Jump => {
quadrupedmedium::JumpAnimation::update_skeleton(
state.skeleton_mut(),
(vel.0.magnitude(), time),
animation_info.time,
skeleton_attr,
)
}
// TODO!
_ => state.skeleton_mut().clone(),
};
state.skeleton.interpolate(&target_skeleton, dt);
state.update(renderer, pos.0, ori.0, col, dt);
}
}
},
// TODO: Non-character actors
} // TODO: Non-character actors
}
}
@ -715,7 +810,10 @@ impl FigureMgr {
.get(&entity)
.map(|state| (state.locals(), state.bone_consts())),
} {
let model = self.model_cache.get_or_create_model(renderer, *body, tick);
let model = &self
.model_cache
.get_or_create_model(renderer, *body, tick)
.0;
renderer.render_figure(model, globals, locals, bone_consts);
} else {