body/anim tweaks

This commit is contained in:
Justin Shipsey 2020-04-26 01:09:03 +00:00
parent e690efe717
commit 6fa13bcb7e
90 changed files with 1501 additions and 236 deletions

View File

@ -474,9 +474,23 @@
]
},
"species": {
"giant": {
"keyword": "giant",
"generic": "Giant"
"ogre": {
"keyword": "ogre",
"generic": "Ogre"
}
}
},
"golem": {
"body": {
"keyword": "golem",
"names": [
"phil"
]
},
"species": {
"stonegolem": {
"keyword": "stonegolem",
"generic": "StoneGolem"
}
}
},

View File

@ -1,30 +1,30 @@
({
(Giant, Male): (
(Ogre, Male): (
head: (
offset: (-9.0, -6.0, -6.5),
center: ("npc.giant.male.head"),
offset: (-8.0, -5.0, -6.0),
center: ("npc.ogre.male.head"),
),
torso_upper: (
offset: (-8.0, -4.5, -5.0),
center: ("npc.giant.male.torso_upper"),
center: ("npc.ogre.male.torso_upper"),
),
torso_lower: (
offset: (-5.0, -4.5, -4.5),
center: ("npc.giant.male.torso_lower"),
center: ("npc.ogre.male.torso_lower"),
)
),
(Giant, Female): (
(Ogre, Female): (
head: (
offset: (-9.0, -6.0, -6.5),
center: ("npc.giant.female.head"),
offset: (-8.0, -5.0, -6.0),
center: ("npc.ogre.female.head"),
),
torso_upper: (
offset: (-8.0, -4.5, -5.0),
center: ("npc.giant.female.torso_upper"),
center: ("npc.ogre.female.torso_upper"),
),
torso_lower: (
offset: (-5.0, -4.5, -4.5),
center: ("npc.giant.female.torso_lower"),
center: ("npc.ogre.female.torso_lower"),
)
),
})

View File

@ -1,70 +1,70 @@
({
(Giant, Male): (
(Ogre, Male): (
shoulder_l: (
offset: (-4.0, -5.5, -4.0),
lateral: ("armor.empty"),
),
shoulder_r: (
offset: (-4.0, -5.5, -4.0),
lateral: ("npc.giant.male.shoulder_r"),
lateral: ("npc.ogre.male.shoulder_r"),
),
hand_l: (
offset: (-2.5, -2.5, -14.0),
lateral: ("npc.giant.male.hand_l"),
offset: (-2.5, -2.5, -11.0),
lateral: ("npc.ogre.male.hand_l"),
),
hand_r: (
offset: (-2.5, -2.5, -14.0),
lateral: ("npc.giant.male.hand_r"),
offset: (-2.5, -2.5, -11.0),
lateral: ("npc.ogre.male.hand_r"),
),
leg_l: (
offset: (-6.0, -3.5, -7.0),
lateral: ("npc.giant.male.leg_l"),
lateral: ("npc.ogre.male.leg_l"),
),
leg_r: (
offset: (0.0, -3.5, -7.0),
lateral: ("npc.giant.male.leg_r"),
lateral: ("npc.ogre.male.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.giant.male.foot_l"),
offset: (-3.0, -5.0, -3.0),
lateral: ("npc.ogre.male.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.giant.male.foot_r"),
offset: (-3.0, -5.0, -3.0),
lateral: ("npc.ogre.male.foot_r"),
)
),
(Giant, Female): (
(Ogre, Female): (
shoulder_l: (
offset: (-4.0, -5.5, -4.0),
lateral: ("armor.empty"),
),
shoulder_r: (
offset: (-4.0, -5.5, -4.0),
lateral: ("npc.giant.female.shoulder_r"),
lateral: ("npc.ogre.female.shoulder_r"),
),
hand_l: (
offset: (-2.5, -2.5, -14.0),
lateral: ("npc.giant.female.hand_l"),
offset: (-2.5, -2.5, -11.0),
lateral: ("npc.ogre.female.hand_l"),
),
hand_r: (
offset: (-2.5, -2.5, -14.0),
lateral: ("npc.giant.female.hand_r"),
offset: (-2.5, -2.5, -11.0),
lateral: ("npc.ogre.female.hand_r"),
),
leg_l: (
offset: (-6.0, -3.5, -7.0),
lateral: ("npc.giant.female.leg_l"),
lateral: ("npc.ogre.female.leg_l"),
),
leg_r: (
offset: (0.0, -3.5, -7.0),
lateral: ("npc.giant.female.leg_r"),
lateral: ("npc.ogre.female.leg_r"),
),
foot_l: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.giant.female.foot_l"),
offset: (-3.0, -5.0, -3.0),
lateral: ("npc.ogre.female.foot_l"),
),
foot_r: (
offset: (-3.0, -5.0, -2.5),
lateral: ("npc.giant.female.foot_r"),
offset: (-3.0, -5.0, -3.0),
lateral: ("npc.ogre.female.foot_r"),
)
),
})

View File

@ -1,11 +1,11 @@
({
(Duck, Male): (
wing_l: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.duck.male.wing"),
),
wing_r: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.duck.male.wing"),
),
foot_l: (
@ -19,11 +19,11 @@
),
(Duck, Female): (
wing_l: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.duck.female.wing"),
),
wing_r: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.duck.female.wing"),
),
foot_l: (
@ -37,11 +37,11 @@
),
(Chicken, Male): (
wing_l: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.chicken.male.wing"),
),
wing_r: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.chicken.male.wing"),
),
foot_l: (
@ -55,11 +55,11 @@
),
(Chicken, Female): (
wing_l: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.chicken.female.wing"),
),
wing_r: (
offset: (-0.5, -2.5, -8.0),
offset: (-0.5, -2.5, -3.0),
lateral: ("npc.chicken.female.wing"),
),
foot_l: (
@ -73,11 +73,11 @@
),
(Goose, Male): (
wing_l: (
offset: (-0.5, -2.5, -11.0),
offset: (-0.5, -2.5, -4.0),
lateral: ("npc.goose.male.wing"),
),
wing_r: (
offset: (-0.5, -2.5, -11.0),
offset: (-0.5, -2.5, -4.0),
lateral: ("npc.goose.male.wing"),
),
foot_l: (
@ -91,11 +91,11 @@
),
(Goose, Female): (
wing_l: (
offset: (-0.5, -2.5, -11.0),
offset: (-0.5, -2.5, -4.0),
lateral: ("npc.goose.female.wing"),
),
wing_r: (
offset: (-0.5, -2.5, -11.0),
offset: (-0.5, -2.5, -4.0),
lateral: ("npc.goose.female.wing"),
),
foot_l: (
@ -109,11 +109,11 @@
),
(Peacock, Male): (
wing_l: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -5.0),
lateral: ("npc.peacock.male.wing_l"),
),
wing_r: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -5.0),
lateral: ("npc.peacock.male.wing_r"),
),
foot_l: (
@ -127,11 +127,11 @@
),
(Peacock, Female): (
wing_l: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -5.0),
lateral: ("npc.peacock.female.wing_l"),
),
wing_r: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -5.0),
lateral: ("npc.peacock.female.wing_r"),
),
foot_l: (
@ -145,11 +145,11 @@
),
(Eagle, Male): (
wing_l: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -12.0),
lateral: ("npc.eagle.male.wing_l"),
),
wing_r: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -12.0),
lateral: ("npc.eagle.male.wing_r"),
),
foot_l: (
@ -163,11 +163,11 @@
),
(Eagle, Female): (
wing_l: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -12.0),
lateral: ("npc.eagle.female.wing_l"),
),
wing_r: (
offset: (-1.0, -3.5, -13.0),
offset: (-1.0, -3.5, -12.0),
lateral: ("npc.eagle.female.wing_r"),
),
foot_l: (

View File

@ -0,0 +1,22 @@
({
(StoneGolem, Male): (
head: (
offset: (-5.0, -5.5, -7.5),
center: ("npc.stonegolem.male.head"),
),
torso_upper: (
offset: (-6.0, -3.5, -10.0),
center: ("npc.stonegolem.male.torso_upper"),
),
),
(StoneGolem, Female): (
head: (
offset: (-5.0, -5.5, -7.5),
center: ("npc.stonegolem.female.head"),
),
torso_upper: (
offset: (-6.0, -3.5, -10.0),
center: ("npc.stonegolem.female.torso_upper"),
),
),
})

View File

@ -0,0 +1,70 @@
({
(StoneGolem, Male): (
shoulder_l: (
offset: (-4.5, -4.0, -5.0),
lateral: ("npc.stonegolem.male.shoulder_l"),
),
shoulder_r: (
offset: (-4.5, -4.0, -5.0),
lateral: ("npc.stonegolem.male.shoulder_r"),
),
hand_l: (
offset: (-3.0, -3.5, -14.0),
lateral: ("npc.stonegolem.male.hand_l"),
),
hand_r: (
offset: (-3.0, -3.5, -14.0),
lateral: ("npc.stonegolem.male.hand_r"),
),
leg_l: (
offset: (-2.5, -2.5, -6.0),
lateral: ("npc.stonegolem.male.leg_l"),
),
leg_r: (
offset: (-2.5, -2.5, -6.0),
lateral: ("npc.stonegolem.male.leg_r"),
),
foot_l: (
offset: (-3.0, -3.5, -9.5),
lateral: ("npc.stonegolem.male.foot_l"),
),
foot_r: (
offset: (-3.0, -3.5, -9.5),
lateral: ("npc.stonegolem.male.foot_r"),
)
),
(StoneGolem, Female): (
shoulder_l: (
offset: (-4.5, -4.0, -5.0),
lateral: ("npc.stonegolem.male.shoulder_l"),
),
shoulder_r: (
offset: (-4.5, -4.0, -5.0),
lateral: ("npc.stonegolem.female.shoulder_r"),
),
hand_l: (
offset: (-3.0, -3.5, -14.0),
lateral: ("npc.stonegolem.female.hand_l"),
),
hand_r: (
offset: (-3.0, -3.5, -14.0),
lateral: ("npc.stonegolem.female.hand_r"),
),
leg_l: (
offset: (-2.5, -2.5, -6.0),
lateral: ("npc.stonegolem.female.leg_l"),
),
leg_r: (
offset: (-2.5, -2.5, -6.0),
lateral: ("npc.stonegolem.female.leg_r"),
),
foot_l: (
offset: (-3.0, -3.5, -10.5),
lateral: ("npc.stonegolem.female.foot_l"),
),
foot_r: (
offset: (-3.0, -3.5, -10.5),
lateral: ("npc.stonegolem.female.foot_r"),
)
),
})

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/belt.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/chest.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/foot.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/hand-l.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/hand-r.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/head.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/legs.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/oger/shoulder.vox (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/female/club_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/female/club_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/female/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/female/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/female/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/female/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/male/club_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/male/club_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/male/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/male/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/ogre/male/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/hand_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/hand_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/leg_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/shoulder_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/shoulder_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/female/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/foot_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/foot_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/hand_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/hand_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/head.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/leg_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/leg_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/shoulder_l.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/shoulder_r.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/npc/stonegolem/male/torso_upper.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -5,6 +5,7 @@ pub mod critter;
pub mod dragon;
pub mod fish_medium;
pub mod fish_small;
pub mod golem;
pub mod humanoid;
pub mod object;
pub mod quadruped_medium;
@ -31,7 +32,8 @@ pub enum Body {
FishSmall(fish_small::Body) = 7,
BipedLarge(biped_large::Body) = 8,
Object(object::Body) = 9,
Critter(critter::Body) = 10,
Golem(golem::Body) = 10,
Critter(critter::Body) = 11,
}
/// Data representing data generic to the body together with per-species data.
@ -56,6 +58,7 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
pub quadruped_medium: BodyData<BodyMeta, quadruped_medium::AllSpecies<SpeciesMeta>>,
pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
pub critter: BodyData<BodyMeta, critter::AllSpecies<SpeciesMeta>>,
}
@ -70,7 +73,8 @@ impl<BodyMeta, SpeciesMeta> core::ops::Index<NpcKind> for AllBodies<BodyMeta, Sp
NpcKind::Pig => &self.quadruped_small.body,
NpcKind::Wolf => &self.quadruped_medium.body,
NpcKind::Duck => &self.bird_medium.body,
NpcKind::Giant => &self.biped_large.body,
NpcKind::Ogre => &self.biped_large.body,
NpcKind::StoneGolem => &self.golem.body,
NpcKind::Rat => &self.critter.body,
}
}
@ -110,7 +114,8 @@ impl Body {
Body::Dragon(_) => 2.5,
Body::BirdSmall(_) => 0.2,
Body::FishSmall(_) => 0.2,
Body::BipedLarge(_) => 1.0,
Body::BipedLarge(_) => 2.0,
Body::Golem(_) => 2.5,
Body::Object(_) => 0.3,
}
}

View File

@ -27,7 +27,7 @@ impl From<Body> for super::Body {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Species {
Giant = 0,
Ogre = 0,
}
/// Data representing per-species generic data.
@ -35,7 +35,7 @@ pub enum Species {
/// NOTE: Deliberately don't (yet?) implement serialize.
#[derive(Clone, Debug, Deserialize)]
pub struct AllSpecies<SpeciesMeta> {
pub giant: SpeciesMeta,
pub ogre: SpeciesMeta,
}
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
@ -44,12 +44,12 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
#[inline]
fn index(&self, &index: &'a Species) -> &Self::Output {
match index {
Species::Giant => &self.giant,
Species::Ogre => &self.ogre,
}
}
}
pub const ALL_SPECIES: [Species; 1] = [Species::Giant];
pub const ALL_SPECIES: [Species; 1] = [Species::Ogre];
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
type Item = Species;

View File

@ -0,0 +1,68 @@
use rand::{seq::SliceRandom, thread_rng};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Body {
pub species: Species,
pub body_type: BodyType,
}
impl Body {
pub fn random() -> Self {
let mut rng = thread_rng();
let species = *(&ALL_SPECIES).choose(&mut rng).unwrap();
Self::random_with(&mut rng, &species)
}
#[inline]
pub fn random_with(rng: &mut impl rand::Rng, &species: &Species) -> Self {
let body_type = *(&ALL_BODY_TYPES).choose(rng).unwrap();
Self { species, body_type }
}
}
impl From<Body> for super::Body {
fn from(body: Body) -> Self { super::Body::Golem(body) }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Species {
StoneGolem = 0,
}
/// Data representing per-species generic data.
///
/// NOTE: Deliberately don't (yet?) implement serialize.
#[derive(Clone, Debug, Deserialize)]
pub struct AllSpecies<SpeciesMeta> {
pub stonegolem: SpeciesMeta,
}
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
type Output = SpeciesMeta;
#[inline]
fn index(&self, &index: &'a Species) -> &Self::Output {
match index {
Species::StoneGolem => &self.stonegolem,
}
}
}
pub const ALL_SPECIES: [Species; 1] = [Species::StoneGolem];
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
type Item = Species;
type IntoIter = impl Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum BodyType {
Female = 0,
Male = 1,
}
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];

View File

@ -20,8 +20,8 @@ pub use ability::{CharacterAbility, ItemConfig, Loadout};
pub use admin::Admin;
pub use agent::{Agent, Alignment};
pub use body::{
biped_large, bird_medium, bird_small, critter, dragon, fish_medium, fish_small, humanoid,
object, quadruped_medium, quadruped_small, AllBodies, Body, BodyData,
biped_large, bird_medium, bird_small, critter, dragon, fish_medium, fish_small, golem,
humanoid, object, quadruped_medium, quadruped_small, AllBodies, Body, BodyData,
};
pub use character_state::{Attacking, CharacterState, StateUpdate};
pub use controller::{

View File

@ -12,17 +12,19 @@ pub enum NpcKind {
Wolf,
Pig,
Duck,
Giant,
Ogre,
Rat,
StoneGolem,
}
pub const ALL_NPCS: [NpcKind; 6] = [
pub const ALL_NPCS: [NpcKind; 7] = [
NpcKind::Humanoid,
NpcKind::Wolf,
NpcKind::Pig,
NpcKind::Duck,
NpcKind::Giant,
NpcKind::Ogre,
NpcKind::Rat,
NpcKind::StoneGolem,
];
/// Body-specific NPC name metadata.
@ -86,8 +88,9 @@ pub fn kind_to_body(kind: NpcKind) -> Body {
NpcKind::Pig => comp::quadruped_small::Body::random().into(),
NpcKind::Wolf => comp::quadruped_medium::Body::random().into(),
NpcKind::Duck => comp::bird_medium::Body::random().into(),
NpcKind::Giant => comp::biped_large::Body::random().into(),
NpcKind::Ogre => comp::biped_large::Body::random().into(),
NpcKind::Rat => comp::critter::Body::random().into(),
NpcKind::StoneGolem => comp::golem::Body::random().into(),
}
}
@ -188,7 +191,7 @@ impl NpcBody {
.or_else(|| {
parse(
s,
NpcKind::Giant,
NpcKind::Ogre,
&npc_names.biped_large,
comp::biped_large::Body::random_with,
)
@ -201,6 +204,14 @@ impl NpcBody {
comp::critter::Body::random_with,
)
})
.or_else(|| {
parse(
s,
NpcKind::StoneGolem,
&npc_names.golem,
comp::golem::Body::random_with,
)
})
.ok_or(())
}
}

View File

@ -15,8 +15,8 @@ const BASE_HUMANOID_ACCEL: f32 = 100.0;
const BASE_HUMANOID_SPEED: f32 = 170.0;
const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0;
const BASE_HUMANOID_AIR_SPEED: f32 = 8.0;
const BASE_HUMANOID_WATER_ACCEL: f32 = 70.0;
const BASE_HUMANOID_WATER_SPEED: f32 = 120.0;
const BASE_HUMANOID_WATER_ACCEL: f32 = 150.0;
const BASE_HUMANOID_WATER_SPEED: f32 = 180.0;
// const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0;
// const ROLL_SPEED: f32 = 17.0;
// const CHARGE_SPEED: f32 = 20.0;

View File

@ -13,53 +13,97 @@ impl Animation for JumpAnimation {
_global_time: Self::Dependency,
_anim_time: f64,
_rate: &mut f32,
_skeleton_attr: &SkeletonAttr,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
next.head.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.head.offset = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1) * 1.02;
next.head.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.head.scale = Vec3::one() / 10.88;
next.head.scale = Vec3::one() * 1.02;
next.upper_torso.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.upper_torso.offset = Vec3::new(
0.0,
skeleton_attr.upper_torso.0,
skeleton_attr.upper_torso.1,
) / 8.0;
next.upper_torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.upper_torso.scale = Vec3::one() / 10.88;
next.upper_torso.scale = Vec3::one() / 8.0;
next.lower_torso.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.lower_torso.offset = Vec3::new(
0.0,
skeleton_attr.lower_torso.0,
skeleton_attr.lower_torso.1,
);
next.lower_torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.lower_torso.scale = Vec3::one() / 10.88;
next.lower_torso.scale = Vec3::one() * 1.02;
next.shoulder_l.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.shoulder_l.offset = Vec3::new(
-skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.shoulder_l.scale = Vec3::one() / 10.88;
next.shoulder_l.scale = Vec3::one();
next.shoulder_r.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.shoulder_r.offset = Vec3::new(
skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.shoulder_r.scale = Vec3::one() / 10.88;
next.shoulder_r.scale = Vec3::one();
next.hand_l.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.hand_l.offset = Vec3::new(
-skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2,
);
next.hand_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.hand_l.scale = Vec3::one() / 10.88;
next.hand_l.scale = Vec3::one() * 1.02;
next.hand_r.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.hand_r.offset = Vec3::new(
skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2,
);
next.hand_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.hand_r.scale = Vec3::one() / 10.88;
next.hand_r.scale = Vec3::one() * 1.02;
next.leg_l.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.leg_l.offset = Vec3::new(
-skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_l.scale = Vec3::one() / 10.88;
next.leg_l.scale = Vec3::one() * 1.02;
next.leg_r.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.leg_r.offset = Vec3::new(
skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_r.scale = Vec3::one() / 10.88;
next.leg_r.scale = Vec3::one() * 1.02;
next.foot_l.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.foot_l.offset = Vec3::new(
-skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 8.0;
next.foot_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.foot_l.scale = Vec3::one() / 10.88;
next.foot_l.scale = Vec3::one() / 8.0;
next.foot_r.offset = Vec3::new(0.0, 7.5, 15.0) / 11.0;
next.foot_r.offset = Vec3::new(
skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 8.0;
next.foot_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.foot_r.scale = Vec3::one() / 10.88;
next.foot_r.scale = Vec3::one() / 8.0;
next.torso.offset = Vec3::new(0.0, 0.0, 0.0);
next.torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.torso.scale = Vec3::one();
next
}
}

View File

@ -135,25 +135,25 @@ impl<'a> From<&'a comp::biped_large::Body> for SkeletonAttr {
use comp::biped_large::Species::*;
Self {
head: match (body.species, body.body_type) {
(Giant, _) => (0.0, 10.0),
(Ogre, _) => (3.0, 6.0),
},
upper_torso: match (body.species, body.body_type) {
(Giant, _) => (0.0, 20.0),
(Ogre, _) => (0.0, 20.0),
},
lower_torso: match (body.species, body.body_type) {
(Giant, _) => (1.0, -9.5),
(Ogre, _) => (1.0, -9.5),
},
shoulder: match (body.species, body.body_type) {
(Giant, _) => (6.0, 0.5, 2.5),
(Ogre, _) => (6.1, 0.5, 2.5),
},
hand: match (body.species, body.body_type) {
(Giant, _) => (10.5, -1.0, 3.5),
(Ogre, _) => (10.5, -1.0, 0.5),
},
leg: match (body.species, body.body_type) {
(Giant, _) => (0.0, 0.0, -6.0),
(Ogre, _) => (0.0, 0.0, -6.0),
},
foot: match (body.species, body.body_type) {
(Giant, _) => (4.0, 0.5, 2.5),
(Ogre, _) => (4.0, 0.5, 2.5),
},
}
}

View File

@ -20,7 +20,10 @@ impl Animation for RunAnimation {
let lab = 10.0;
let belt = (anim_time as f32 * lab as f32 + 1.5 * PI).sin();
let beltsnap = (((5.0)
/ (1.0 + (4.0) * ((anim_time as f32 * lab as f32 + PI * 1.5).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 + PI * 1.5).sin());
let foothoril = (anim_time as f32 * lab as f32 + PI * 1.4).sin();
let foothorir = (anim_time as f32 * lab as f32 + PI * 0.4).sin();
@ -81,7 +84,7 @@ impl Animation for RunAnimation {
skeleton_attr.hand.2,
);
next.hand_l.ori =
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + footrotl * -0.8);
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + foothoril * -0.6);
next.hand_l.scale = Vec3::one() * 1.02;
next.hand_r.offset = Vec3::new(
@ -90,7 +93,7 @@ impl Animation for RunAnimation {
skeleton_attr.hand.2,
);
next.hand_r.ori =
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + footrotr * -0.8);
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + foothorir * -0.6);
next.hand_r.scale = Vec3::one() * 1.02;
next.leg_l.offset = Vec3::new(
@ -128,7 +131,7 @@ impl Animation for RunAnimation {
next.foot_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotr * 0.5);
next.foot_r.scale = Vec3::one() / 8.0 * 0.98;
next.torso.offset = Vec3::new(0.0, 0.0, belt * 0.15);
next.torso.offset = Vec3::new(0.0, 0.0, beltsnap * 0.25);
next.torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.2);
next.torso.scale = Vec3::one();
next

View File

@ -0,0 +1,84 @@
use super::{super::Animation, BirdMediumSkeleton, SkeletonAttr};
use std::f32::consts::PI;
use vek::*;
pub struct FlyAnimation;
impl Animation for FlyAnimation {
type Dependency = (f32, f64);
type Skeleton = BirdMediumSkeleton;
fn update_skeleton(
skeleton: &Self::Skeleton,
_global_time: Self::Dependency,
anim_time: f64,
_rate: &mut f32,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let lab = 12.0; //14.0
let footl = (anim_time as f32 * lab as f32 + PI).sin();
let footr = (anim_time as f32 * lab as f32).sin();
let center = (anim_time as f32 * lab as f32 + PI / 2.0).sin();
let centeroffset = (anim_time as f32 * lab as f32 + PI * 1.5).sin();
next.head.offset = Vec3::new(
0.0,
skeleton_attr.head.0 + 0.5,
skeleton_attr.head.1 + center * 0.5 - 1.0,
);
next.head.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0 + center * 0.03);
next.head.scale = Vec3::one();
next.torso.offset = Vec3::new(
0.0,
skeleton_attr.chest.0 + centeroffset * 0.6,
center * 0.6 + skeleton_attr.chest.1,
) / 11.0;
next.torso.ori = Quaternion::rotation_y(center * 0.05);
next.torso.scale = Vec3::one() / 11.0;
next.tail.offset = Vec3::new(
0.0,
skeleton_attr.tail.0,
skeleton_attr.tail.1 + centeroffset * 0.6,
);
next.tail.ori = Quaternion::rotation_x(center * 0.03);
next.tail.scale = Vec3::one();
next.wing_l.offset = Vec3::new(
-skeleton_attr.wing.0,
skeleton_attr.wing.1,
skeleton_attr.wing.2,
);
next.wing_l.ori = Quaternion::rotation_y((0.57 + footl * 1.2).max(0.0));
next.wing_l.scale = Vec3::one() * 1.05;
next.wing_r.offset = Vec3::new(
skeleton_attr.wing.0,
skeleton_attr.wing.1,
skeleton_attr.wing.2,
);
next.wing_r.ori = Quaternion::rotation_y((-0.57 + footr * 1.2).min(0.0));
next.wing_r.scale = Vec3::one() * 1.05;
next.leg_l.offset = Vec3::new(
-skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 11.0;
next.leg_l.ori = Quaternion::rotation_x(-1.3 + footl * 0.06);
next.leg_l.scale = Vec3::one() / 11.0;
next.leg_r.offset = Vec3::new(
skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 11.0;
next.leg_r.ori = Quaternion::rotation_x(-1.3 + footr * 0.06);
next.leg_r.scale = Vec3::one() / 11.0;
next
}
}

View File

@ -1,49 +0,0 @@
use super::{super::Animation, BirdMediumSkeleton, SkeletonAttr};
//use std::f32::consts::PI;
use vek::*;
pub struct JumpAnimation;
impl Animation for JumpAnimation {
type Dependency = (f32, f64);
type Skeleton = BirdMediumSkeleton;
fn update_skeleton(
skeleton: &Self::Skeleton,
_global_time: Self::Dependency,
_anim_time: f64,
_rate: &mut f32,
_skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
next.head.offset = Vec3::new(0.0, 0.0, 0.0) / 11.0;
next.head.ori = Quaternion::rotation_z(0.0);
next.head.scale = Vec3::one();
next.torso.offset = Vec3::new(0.0, 0.0, 0.0);
next.torso.ori = Quaternion::rotation_x(0.0);
next.torso.scale = Vec3::one() / 11.0;
next.tail.offset = Vec3::new(0.0, 0.0, 0.0);
next.tail.ori = Quaternion::rotation_z(0.0);
next.tail.scale = Vec3::one();
next.wing_l.offset = Vec3::new(0.0, 0.0, 0.0) / 11.0;
next.wing_l.ori = Quaternion::rotation_z(0.0);
next.wing_l.scale = Vec3::one();
next.wing_r.offset = Vec3::new(0.0, 0.0, 0.0) / 11.0;
next.wing_r.ori = Quaternion::rotation_y(0.0);
next.wing_r.scale = Vec3::one();
next.leg_l.offset = Vec3::new(0.0, 0.0, 0.0) / 11.0;
next.leg_l.ori = Quaternion::rotation_y(0.0);
next.leg_l.scale = Vec3::one() / 11.0;
next.leg_r.offset = Vec3::new(0.0, 0.0, 0.0) / 11.0;
next.leg_r.ori = Quaternion::rotation_x(0.0);
next.leg_r.scale = Vec3::one() / 11.0;
next
}
}

View File

@ -1,9 +1,9 @@
pub mod fly;
pub mod idle;
pub mod jump;
pub mod run;
// Reexports
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation};
use super::{Bone, Skeleton};
use crate::render::FigureBoneData;
@ -120,11 +120,11 @@ impl<'a> From<&'a comp::bird_medium::Body> for SkeletonAttr {
(Eagle, _) => (-8.0, -4.0),
},
wing: match (body.species, body.body_type) {
(Duck, _) => (2.75, 0.0, 6.0),
(Chicken, _) => (2.75, 0.0, 6.0),
(Goose, _) => (3.75, -1.0, 9.0),
(Peacock, _) => (3.0, 0.0, 9.0),
(Eagle, _) => (3.0, -8.0, 5.0),
(Duck, _) => (2.75, 0.0, 1.0),
(Chicken, _) => (2.75, 0.0, 1.0),
(Goose, _) => (3.75, -1.0, 2.0),
(Peacock, _) => (3.0, 0.0, 1.0),
(Eagle, _) => (3.0, -8.0, 4.0),
},
foot: match (body.species, body.body_type) {
(Duck, _) => (2.0, -1.5, 4.0),

View File

@ -53,7 +53,7 @@ impl Animation for RunAnimation {
skeleton_attr.wing.1,
skeleton_attr.wing.2,
);
next.wing_l.ori = Quaternion::rotation_y(footl * 0.1);
next.wing_l.ori = Quaternion::rotation_y((footl * 0.35).max(0.0));
next.wing_l.scale = Vec3::one() * 1.05;
next.wing_r.offset = Vec3::new(
@ -61,7 +61,7 @@ impl Animation for RunAnimation {
skeleton_attr.wing.1,
skeleton_attr.wing.2,
);
next.wing_r.ori = Quaternion::rotation_y(footr * 0.1);
next.wing_r.ori = Quaternion::rotation_y((footr * 0.35).min(0.0));
next.wing_r.scale = Vec3::one() * 1.05;
next.leg_l.offset = Vec3::new(

View File

@ -23,15 +23,13 @@ impl Animation for SwimAnimation {
let lab = 1.0;
let short = (anim_time as f32 * lab as f32 * 2.0 * speed / 5.0).sin();
let short = (anim_time as f32 * lab as f32 * 6.0).sin();
let shortalt = (anim_time as f32 * lab as f32 * 2.0 * speed / 5.0 + PI / 2.0).sin();
let shortalt = (anim_time as f32 * lab as f32 * 6.0 + PI / 2.0).sin();
let foot = (anim_time as f32 * lab as f32 * 2.0 * speed / 5.0).sin();
let foot = (anim_time as f32 * lab as f32 * 6.0).sin();
let wave_stop = (anim_time as f32 * 3.0 * speed / 5.0)
.min(PI / 2.0 / 2.0)
.sin();
let wave_stop = (anim_time as f32 * 9.0).min(PI / 2.0 / 2.0).sin();
let head_look = Vec2::new(
((global_time + anim_time) as f32 / 18.0)
@ -51,16 +49,16 @@ impl Animation for SwimAnimation {
-3.0 + skeleton_attr.neck_forward,
skeleton_attr.neck_height + 13.0 + short * 0.3,
);
next.head.ori = Quaternion::rotation_z(head_look.x - short * 0.3)
* Quaternion::rotation_x(head_look.y + 0.35);
next.head.ori = Quaternion::rotation_z(head_look.x - short * 0.4)
* Quaternion::rotation_x(head_look.y + 0.35 + speed * 0.045);
next.head.scale = Vec3::one() * skeleton_attr.head_scale;
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + short * 1.1);
next.chest.ori = Quaternion::rotation_z(short * 0.3);
next.chest.offset = Vec3::new(0.0, 0.0, 7.0 + short * 1.3);
next.chest.ori = Quaternion::rotation_z(short * 0.4);
next.chest.scale = Vec3::one();
next.belt.offset = Vec3::new(0.0, 0.0, -2.0);
next.belt.ori = Quaternion::rotation_z(short * 0.25);
next.belt.ori = Quaternion::rotation_z(short * 0.30);
next.belt.scale = Vec3::one();
next.back.offset = Vec3::new(0.0, -2.8, 7.25);
@ -68,23 +66,23 @@ impl Animation for SwimAnimation {
next.back.scale = Vec3::one() * 1.02;
next.shorts.offset = Vec3::new(0.0, 0.0, -5.0);
next.shorts.ori = Quaternion::rotation_z(short * 0.4);
next.shorts.ori = Quaternion::rotation_z(short * 0.5);
next.shorts.scale = Vec3::one();
next.l_hand.offset = Vec3::new(-6.0, -0.25 - foot * 1.0, 5.0 + foot * -2.5);
next.l_hand.ori = Quaternion::rotation_x(0.8 + foot * -0.5) * Quaternion::rotation_y(0.2);
next.l_hand.offset = Vec3::new(-6.0, -0.25 - foot * 1.2, 5.0 + foot * -3.0);
next.l_hand.ori = Quaternion::rotation_x(0.8 + foot * -0.6) * Quaternion::rotation_y(0.2);
next.l_hand.scale = Vec3::one();
next.r_hand.offset = Vec3::new(6.0, -0.25 + foot * 1.0, 5.0 + foot * 2.5);
next.r_hand.ori = Quaternion::rotation_x(0.8 + foot * 0.5) * Quaternion::rotation_y(-0.2);
next.r_hand.offset = Vec3::new(6.0, -0.25 + foot * 1.2, 5.0 + foot * 3.0);
next.r_hand.ori = Quaternion::rotation_x(0.8 + foot * 0.6) * Quaternion::rotation_y(-0.2);
next.r_hand.scale = Vec3::one();
next.l_foot.offset = Vec3::new(-3.4, 6.0 + foot * 1.0, 0.0 + foot * 5.5);
next.l_foot.ori = Quaternion::rotation_x(-1.40 + foot * 0.5);
next.l_foot.offset = Vec3::new(-3.4, 6.0 + foot * 1.2, 0.0 + foot * 6.5);
next.l_foot.ori = Quaternion::rotation_x(-1.40 + foot * 0.6);
next.l_foot.scale = Vec3::one();
next.r_foot.offset = Vec3::new(3.4, 6.0 - foot * 1.0, 0.0 + foot * -5.5);
next.r_foot.ori = Quaternion::rotation_x(-1.40 + foot * -0.5);
next.r_foot.offset = Vec3::new(3.4, 6.0 - foot * 1.2, 0.0 + foot * -6.5);
next.r_foot.ori = Quaternion::rotation_x(-1.40 + foot * -0.6);
next.r_foot.scale = Vec3::one();
next.l_shoulder.offset = Vec3::new(-5.0, -1.0, 4.7);
@ -121,7 +119,7 @@ impl Animation for SwimAnimation {
next.torso.offset = Vec3::new(0.0, -0.3 + shortalt * -0.065, 0.4) * skeleton_attr.scaler;
next.torso.ori =
Quaternion::rotation_x(speed * -0.190 * wave_stop * 1.6) * Quaternion::rotation_y(0.0);
Quaternion::rotation_x(speed * -0.190 * wave_stop * 1.05) * Quaternion::rotation_y(0.0);
next.torso.scale = Vec3::one() / 11.0 * skeleton_attr.scaler;
next.control.offset = Vec3::new(0.0, 0.0, 0.0);

View File

@ -0,0 +1,121 @@
use super::{super::Animation, GolemSkeleton, SkeletonAttr};
use std::{f32::consts::PI, ops::Mul};
use vek::*;
pub struct IdleAnimation;
impl Animation for IdleAnimation {
type Dependency = f64;
type Skeleton = GolemSkeleton;
fn update_skeleton(
skeleton: &Self::Skeleton,
global_time: Self::Dependency,
anim_time: f64,
_rate: &mut f32,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let lab = 1.0;
let torso = (anim_time as f32 * lab as f32 + 1.5 * PI).sin();
let 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.head.offset = Vec3::new(
0.0,
skeleton_attr.head.0,
skeleton_attr.head.1 + torso * 0.2,
) * 1.02;
next.head.ori = Quaternion::rotation_z(look.x * 0.6) * Quaternion::rotation_x(look.y * 0.6);
next.head.scale = Vec3::one() * 1.02;
next.upper_torso.offset = Vec3::new(
0.0,
skeleton_attr.upper_torso.0,
skeleton_attr.upper_torso.1 + torso * 0.5,
) / 8.0;
next.upper_torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.upper_torso.scale = Vec3::one() / 8.0;
next.shoulder_l.offset = Vec3::new(
-skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.shoulder_l.scale = Vec3::one();
next.shoulder_r.offset = Vec3::new(
skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.shoulder_r.scale = Vec3::one();
next.hand_l.offset = Vec3::new(
-skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2 + torso * 0.6,
);
next.hand_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.hand_l.scale = Vec3::one() * 1.02;
next.hand_r.offset = Vec3::new(
skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2 + torso * 0.6,
);
next.hand_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.hand_r.scale = Vec3::one() * 1.02;
next.leg_l.offset = Vec3::new(
-skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_l.scale = Vec3::one() * 1.02;
next.leg_r.offset = Vec3::new(
skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_r.scale = Vec3::one() * 1.02;
next.foot_l.offset = Vec3::new(
-skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 8.0;
next.foot_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.foot_l.scale = Vec3::one() / 8.0;
next.foot_r.offset = Vec3::new(
skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 8.0;
next.foot_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.foot_r.scale = Vec3::one() / 8.0;
next.torso.offset = Vec3::new(0.0, 0.0, 0.0);
next.torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.torso.scale = Vec3::one();
next
}
}

View File

@ -0,0 +1,101 @@
use super::{super::Animation, GolemSkeleton, SkeletonAttr};
//use std::f32::consts::PI;
use vek::*;
pub struct JumpAnimation;
impl Animation for JumpAnimation {
type Dependency = (f32, f64);
type Skeleton = GolemSkeleton;
fn update_skeleton(
skeleton: &Self::Skeleton,
_global_time: Self::Dependency,
_anim_time: f64,
_rate: &mut f32,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
next.head.offset = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1) * 1.02;
next.head.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.head.scale = Vec3::one() * 1.02;
next.upper_torso.offset = Vec3::new(
0.0,
skeleton_attr.upper_torso.0,
skeleton_attr.upper_torso.1,
) / 8.0;
next.upper_torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.upper_torso.scale = Vec3::one() / 8.0;
next.shoulder_l.offset = Vec3::new(
-skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.shoulder_l.scale = Vec3::one();
next.shoulder_r.offset = Vec3::new(
skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.shoulder_r.scale = Vec3::one();
next.hand_l.offset = Vec3::new(
-skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2,
);
next.hand_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.hand_l.scale = Vec3::one() * 1.02;
next.hand_r.offset = Vec3::new(
skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2,
);
next.hand_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.hand_r.scale = Vec3::one() * 1.02;
next.leg_l.offset = Vec3::new(
-skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_l.scale = Vec3::one() * 1.02;
next.leg_r.offset = Vec3::new(
skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_r.scale = Vec3::one() * 1.02;
next.foot_l.offset = Vec3::new(
-skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 8.0;
next.foot_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.foot_l.scale = Vec3::one() / 8.0;
next.foot_r.offset = Vec3::new(
skeleton_attr.foot.0,
skeleton_attr.foot.1,
skeleton_attr.foot.2,
) / 8.0;
next.foot_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.foot_r.scale = Vec3::one() / 8.0;
next.torso.offset = Vec3::new(0.0, 0.0, 0.0);
next.torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.torso.scale = Vec3::one();
next
}
}

View File

@ -0,0 +1,149 @@
pub mod idle;
pub mod jump;
pub mod run;
// Reexports
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
use super::{Bone, Skeleton};
use crate::render::FigureBoneData;
use common::comp::{self};
#[derive(Clone)]
pub struct GolemSkeleton {
head: Bone,
upper_torso: Bone,
shoulder_l: Bone,
shoulder_r: Bone,
hand_l: Bone,
hand_r: Bone,
leg_l: Bone,
leg_r: Bone,
foot_l: Bone,
foot_r: Bone,
torso: Bone,
}
impl GolemSkeleton {
pub fn new() -> Self {
Self {
head: Bone::default(),
upper_torso: Bone::default(),
shoulder_l: Bone::default(),
shoulder_r: Bone::default(),
hand_l: Bone::default(),
hand_r: Bone::default(),
leg_l: Bone::default(),
leg_r: Bone::default(),
foot_l: Bone::default(),
foot_r: Bone::default(),
torso: Bone::default(),
}
}
}
impl Skeleton for GolemSkeleton {
type Attr = SkeletonAttr;
fn compute_matrices(&self) -> [FigureBoneData; 16] {
let upper_torso_mat = self.upper_torso.compute_base_matrix();
let shoulder_l_mat = self.shoulder_l.compute_base_matrix();
let shoulder_r_mat = self.shoulder_r.compute_base_matrix();
let leg_l_mat = self.leg_l.compute_base_matrix();
let leg_r_mat = self.leg_r.compute_base_matrix();
let torso_mat = self.torso.compute_base_matrix();
let foot_l_mat = self.foot_l.compute_base_matrix();
let foot_r_mat = self.foot_r.compute_base_matrix();
[
FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()),
FigureBoneData::new(torso_mat * upper_torso_mat),
FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat),
FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat),
FigureBoneData::new(torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix()),
FigureBoneData::new(torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix()),
FigureBoneData::new(foot_l_mat * leg_l_mat),
FigureBoneData::new(foot_r_mat * leg_r_mat),
FigureBoneData::new(foot_l_mat),
FigureBoneData::new(foot_r_mat),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
FigureBoneData::default(),
]
}
fn interpolate(&mut self, target: &Self, dt: f32) {
self.head.interpolate(&target.head, dt);
self.upper_torso.interpolate(&target.upper_torso, dt);
self.shoulder_l.interpolate(&target.shoulder_l, dt);
self.shoulder_r.interpolate(&target.shoulder_r, dt);
self.hand_l.interpolate(&target.hand_l, dt);
self.hand_r.interpolate(&target.hand_r, dt);
self.leg_l.interpolate(&target.leg_l, dt);
self.leg_r.interpolate(&target.leg_r, dt);
self.foot_l.interpolate(&target.foot_l, dt);
self.foot_r.interpolate(&target.foot_r, dt);
self.torso.interpolate(&target.torso, dt);
}
}
pub struct SkeletonAttr {
head: (f32, f32),
upper_torso: (f32, f32),
shoulder: (f32, f32, f32),
hand: (f32, f32, f32),
leg: (f32, f32, f32),
foot: (f32, f32, f32),
}
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
type Error = ();
fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
match body {
comp::Body::Golem(body) => Ok(SkeletonAttr::from(body)),
_ => Err(()),
}
}
}
impl Default for SkeletonAttr {
fn default() -> Self {
Self {
head: (0.0, 0.0),
upper_torso: (0.0, 0.0),
shoulder: (0.0, 0.0, 0.0),
hand: (0.0, 0.0, 0.0),
leg: (0.0, 0.0, 0.0),
foot: (0.0, 0.0, 0.0),
}
}
}
impl<'a> From<&'a comp::golem::Body> for SkeletonAttr {
fn from(body: &'a comp::golem::Body) -> Self {
use comp::golem::Species::*;
Self {
head: match (body.species, body.body_type) {
(StoneGolem, _) => (0.0, 16.0),
},
upper_torso: match (body.species, body.body_type) {
(StoneGolem, _) => (0.0, 33.0),
},
shoulder: match (body.species, body.body_type) {
(StoneGolem, _) => (8.0, -0.5, 7.5),
},
hand: match (body.species, body.body_type) {
(StoneGolem, _) => (9.5, -1.0, 4.5),
},
leg: match (body.species, body.body_type) {
(StoneGolem, _) => (-1.0, 0.0, 9.0),
},
foot: match (body.species, body.body_type) {
(StoneGolem, _) => (4.0, 0.5, 11.0),
},
}
}
}

View File

@ -0,0 +1,126 @@
use super::{super::Animation, GolemSkeleton, SkeletonAttr};
use std::f32::consts::PI;
use vek::*;
pub struct RunAnimation;
impl Animation for RunAnimation {
type Dependency = (f32, f64);
type Skeleton = GolemSkeleton;
fn update_skeleton(
skeleton: &Self::Skeleton,
(_velocity, _global_time): Self::Dependency,
anim_time: f64,
_rate: &mut f32,
skeleton_attr: &SkeletonAttr,
) -> Self::Skeleton {
let mut next = (*skeleton).clone();
let lab = 10.0;
let belt = (anim_time as f32 * lab as f32 + 1.5 * PI).sin();
let foothoril = (anim_time as f32 * lab as f32 + PI * 1.4).sin();
let foothorir = (anim_time as f32 * lab as f32 + PI * 0.4).sin();
let footvertl = (anim_time as f32 * lab as f32).sin().max(0.1);
let footvertr = (anim_time as f32 * lab as f32 + PI).sin().max(0.1);
let footrotl = (((5.0)
/ (1.0 + (4.0) * ((anim_time as f32 * lab as f32 + PI * 1.4).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 + PI * 1.4).sin());
let footrotr = (((5.0)
/ (1.0 + (4.0) * ((anim_time as f32 * lab as f32 + PI * 0.4).sin()).powf(2.0 as f32)))
.sqrt())
* ((anim_time as f32 * lab as f32 + PI * 0.4).sin());
next.head.offset = Vec3::new(0.0, skeleton_attr.head.0, skeleton_attr.head.1) * 1.02;
next.head.ori = Quaternion::rotation_z(belt * -0.3) * Quaternion::rotation_x(0.3);
next.head.scale = Vec3::one() * 1.02;
next.upper_torso.offset = Vec3::new(
0.0,
skeleton_attr.upper_torso.0,
skeleton_attr.upper_torso.1 + belt * 1.0,
) / 8.0;
next.upper_torso.ori = Quaternion::rotation_z(belt * 0.40) * Quaternion::rotation_x(0.0);
next.upper_torso.scale = Vec3::one() / 8.0;
next.shoulder_l.offset = Vec3::new(
-skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_l.ori =
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotl * -0.15);
next.shoulder_l.scale = Vec3::one();
next.shoulder_r.offset = Vec3::new(
skeleton_attr.shoulder.0,
skeleton_attr.shoulder.1,
skeleton_attr.shoulder.2,
);
next.shoulder_r.ori =
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotr * -0.15);
next.shoulder_r.scale = Vec3::one();
next.hand_l.offset = Vec3::new(
-skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2,
);
next.hand_l.ori =
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + footrotl * -0.8);
next.hand_l.scale = Vec3::one() * 1.02;
next.hand_r.offset = Vec3::new(
skeleton_attr.hand.0,
skeleton_attr.hand.1,
skeleton_attr.hand.2,
);
next.hand_r.ori =
Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.3 + footrotr * -0.8);
next.hand_r.scale = Vec3::one() * 1.02;
next.leg_l.offset = Vec3::new(
-skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_l.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_l.scale = Vec3::one() * 1.02;
next.leg_r.offset = Vec3::new(
skeleton_attr.leg.0,
skeleton_attr.leg.1,
skeleton_attr.leg.2,
) * 1.02;
next.leg_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
next.leg_r.scale = Vec3::one() * 1.02;
next.foot_l.offset = Vec3::new(
-skeleton_attr.foot.0,
skeleton_attr.foot.1 + foothoril * 8.0 + 3.0,
skeleton_attr.foot.2 + footvertl * 4.0,
) / 8.0;
next.foot_l.ori = Quaternion::rotation_x(footrotl * 0.7);
next.foot_l.scale = Vec3::one() / 8.0 * 0.98;
next.foot_r.offset = Vec3::new(
skeleton_attr.foot.0,
skeleton_attr.foot.1 + foothorir * 8.0 + 3.0,
skeleton_attr.foot.2 + footvertr * 4.0,
) / 8.0;
next.foot_r.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(footrotr * 0.7);
next.foot_r.scale = Vec3::one() / 8.0 * 0.98;
next.torso.offset = Vec3::new(0.0, 0.0, belt * 0.15);
next.torso.ori = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(-0.2);
next.torso.scale = Vec3::one();
next
}
}

View File

@ -7,6 +7,7 @@ pub mod dragon;
pub mod fish_medium;
pub mod fish_small;
pub mod fixture;
pub mod golem;
pub mod object;
pub mod quadruped_medium;
pub mod quadruped_small;

View File

@ -533,6 +533,65 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
None,
]
},
Body::Golem(body) => {
let golem_center_spec = GolemCenterSpec::load_watched(manifest_indicator);
let golem_lateral_spec = GolemLateralSpec::load_watched(manifest_indicator);
[
Some(golem_center_spec.mesh_head(body.species, body.body_type, generate_mesh)),
Some(golem_center_spec.mesh_torso_upper(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_shoulder_l(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_shoulder_r(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_hand_l(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_hand_r(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_leg_l(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_leg_r(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_foot_l(
body.species,
body.body_type,
generate_mesh,
)),
Some(golem_lateral_spec.mesh_foot_r(
body.species,
body.body_type,
generate_mesh,
)),
None,
None,
None,
None,
None,
None,
]
},
Body::Critter(body) => {
let critter_center_spec = CritterCenterSpec::load_watched(manifest_indicator);

View File

@ -7,6 +7,7 @@ use common::{
bird_small,
critter::{BodyType as CBodyType, Species as CSpecies},
dragon, fish_medium, fish_small,
golem::{BodyType as GBodyType, Species as GSpecies},
humanoid::{Body, BodyType, EyeColor, Eyebrows, Race, Skin},
item::{
armor::{Armor, Back, Belt, Chest, Foot, Hand, Head, Pants, Shoulder, Tabard},
@ -2367,6 +2368,276 @@ impl BipedLargeLateralSpec {
}
}
////
#[derive(Serialize, Deserialize)]
pub struct GolemCenterSpec(HashMap<(GSpecies, GBodyType), SidedGCenterVoxSpec>);
#[derive(Serialize, Deserialize)]
struct SidedGCenterVoxSpec {
head: GolemCenterSubSpec,
torso_upper: GolemCenterSubSpec,
}
#[derive(Serialize, Deserialize)]
struct GolemCenterSubSpec {
offset: [f32; 3], // Should be relative to initial origin
center: VoxSimple,
}
#[derive(Serialize, Deserialize)]
pub struct GolemLateralSpec(HashMap<(GSpecies, GBodyType), SidedGLateralVoxSpec>);
#[derive(Serialize, Deserialize)]
struct SidedGLateralVoxSpec {
shoulder_l: GolemLateralSubSpec,
shoulder_r: GolemLateralSubSpec,
hand_l: GolemLateralSubSpec,
hand_r: GolemLateralSubSpec,
leg_l: GolemLateralSubSpec,
leg_r: GolemLateralSubSpec,
foot_l: GolemLateralSubSpec,
foot_r: GolemLateralSubSpec,
}
#[derive(Serialize, Deserialize)]
struct GolemLateralSubSpec {
offset: [f32; 3], // Should be relative to initial origin
lateral: VoxSimple,
}
impl Asset for GolemCenterSpec {
const ENDINGS: &'static [&'static str] = &["ron"];
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
}
}
impl Asset for GolemLateralSpec {
const ENDINGS: &'static [&'static str] = &["ron"];
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
}
}
impl GolemCenterSpec {
pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc<Self> {
assets::load_watched::<Self>("voxygen.voxel.golem_center_manifest", indicator).unwrap()
}
pub fn mesh_head(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No head specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.head.center.0);
generate_mesh(&center, Vec3::from(spec.head.offset))
}
pub fn mesh_torso_upper(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No torso upper specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.torso_upper.center.0);
generate_mesh(&center, Vec3::from(spec.torso_upper.offset))
}
}
impl GolemLateralSpec {
pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc<Self> {
assets::load_watched::<Self>("voxygen.voxel.golem_lateral_manifest", indicator).unwrap()
}
pub fn mesh_shoulder_l(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No shoulder specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.shoulder_l.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.shoulder_l.offset))
}
pub fn mesh_shoulder_r(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No shoulder specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.shoulder_r.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.shoulder_r.offset))
}
pub fn mesh_hand_l(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No hand specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.hand_l.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.hand_l.offset))
}
pub fn mesh_hand_r(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No hand specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.hand_r.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.hand_r.offset))
}
pub fn mesh_leg_l(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No leg specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.leg_l.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.leg_l.offset))
}
pub fn mesh_leg_r(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No leg specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.leg_r.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.leg_r.offset))
}
pub fn mesh_foot_l(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No foot specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.foot_l.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.foot_l.offset))
}
pub fn mesh_foot_r(
&self,
species: GSpecies,
body_type: GBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No foot specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.foot_r.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.foot_r.offset))
}
}
pub fn mesh_object(
obj: object::Body,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,

View File

@ -9,7 +9,7 @@ use crate::{
self, biped_large::BipedLargeSkeleton, bird_medium::BirdMediumSkeleton,
bird_small::BirdSmallSkeleton, character::CharacterSkeleton, critter::CritterSkeleton,
dragon::DragonSkeleton, fish_medium::FishMediumSkeleton, fish_small::FishSmallSkeleton,
object::ObjectSkeleton, quadruped_medium::QuadrupedMediumSkeleton,
golem::GolemSkeleton, object::ObjectSkeleton, quadruped_medium::QuadrupedMediumSkeleton,
quadruped_small::QuadrupedSmallSkeleton, Animation, Skeleton,
},
ecs::comp::Interpolated,
@ -50,6 +50,7 @@ pub struct FigureMgr {
fish_medium_model_cache: FigureModelCache<FishMediumSkeleton>,
fish_small_model_cache: FigureModelCache<FishSmallSkeleton>,
biped_large_model_cache: FigureModelCache<BipedLargeSkeleton>,
golem_model_cache: FigureModelCache<GolemSkeleton>,
character_states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
quadruped_small_states: HashMap<EcsEntity, FigureState<QuadrupedSmallSkeleton>>,
quadruped_medium_states: HashMap<EcsEntity, FigureState<QuadrupedMediumSkeleton>>,
@ -60,6 +61,7 @@ pub struct FigureMgr {
bird_small_states: HashMap<EcsEntity, FigureState<BirdSmallSkeleton>>,
fish_small_states: HashMap<EcsEntity, FigureState<FishSmallSkeleton>>,
biped_large_states: HashMap<EcsEntity, FigureState<BipedLargeSkeleton>>,
golem_states: HashMap<EcsEntity, FigureState<GolemSkeleton>>,
object_states: HashMap<EcsEntity, FigureState<ObjectSkeleton>>,
}
@ -76,6 +78,7 @@ impl FigureMgr {
fish_medium_model_cache: FigureModelCache::new(),
fish_small_model_cache: FigureModelCache::new(),
biped_large_model_cache: FigureModelCache::new(),
golem_model_cache: FigureModelCache::new(),
character_states: HashMap::new(),
quadruped_small_states: HashMap::new(),
quadruped_medium_states: HashMap::new(),
@ -86,6 +89,7 @@ impl FigureMgr {
bird_small_states: HashMap::new(),
fish_small_states: HashMap::new(),
biped_large_states: HashMap::new(),
golem_states: HashMap::new(),
object_states: HashMap::new(),
}
}
@ -101,6 +105,7 @@ impl FigureMgr {
self.fish_medium_model_cache.clean(tick);
self.fish_small_model_cache.clean(tick);
self.biped_large_model_cache.clean(tick);
self.golem_model_cache.clean(tick);
}
pub fn maintain(&mut self, renderer: &mut Renderer, scene_data: &SceneData, camera: &Camera) {
@ -212,6 +217,9 @@ impl FigureMgr {
Body::BipedLarge(_) => {
self.biped_large_states.remove(&entity);
},
Body::Golem(_) => {
self.biped_large_states.remove(&entity);
},
Body::Object(_) => {
self.object_states.remove(&entity);
},
@ -269,6 +277,11 @@ impl FigureMgr {
.get_mut(&entity)
.map(|state| state.visible = false);
},
Body::Golem(_) => {
self.golem_states
.get_mut(&entity)
.map(|state| state.visible = false);
},
Body::Object(_) => {
self.object_states
.get_mut(&entity)
@ -322,6 +335,9 @@ impl FigureMgr {
.biped_large_states
.get(&entity)
.map(|state| state.lpindex),
Body::Golem(_) => {
self.golem_states.get(&entity).map(|state| state.lpindex)
},
Body::Object(_) => {
self.object_states.get(&entity).map(|state| state.lpindex)
},
@ -391,6 +407,12 @@ impl FigureMgr {
state.visible = false
});
},
Body::Golem(_) => {
self.golem_states.get_mut(&entity).map(|state| {
state.lpindex = lpindex;
state.visible = false
});
},
Body::Object(_) => {
self.object_states.get_mut(&entity).map(|state| {
state.lpindex = lpindex;
@ -867,7 +889,7 @@ impl FigureMgr {
skeleton_attr,
),
// In air
(false, _, false) => anim::bird_medium::JumpAnimation::update_skeleton(
(false, _, false) => anim::bird_medium::FlyAnimation::update_skeleton(
&BirdMediumSkeleton::new(),
(vel.0.magnitude(), time),
state.state_time,
@ -1343,6 +1365,81 @@ impl FigureMgr {
is_player,
);
},
Body::Golem(_) => {
let skeleton_attr = &self
.golem_model_cache
.get_or_create_model(
renderer,
*body,
loadout,
tick,
CameraMode::default(),
None,
)
.1;
let state = self
.golem_states
.entry(entity)
.or_insert_with(|| FigureState::new(renderer, GolemSkeleton::new()));
let (character, last_character) = match (character, last_character) {
(Some(c), Some(l)) => (c, l),
_ => continue,
};
if !character.same_variant(&last_character.0) {
state.state_time = 0.0;
}
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid, // In water
) {
// Standing
(true, false, false) => anim::golem::IdleAnimation::update_skeleton(
&GolemSkeleton::new(),
time,
state.state_time,
&mut state_animation_rate,
skeleton_attr,
),
// Running
(true, true, false) => anim::golem::RunAnimation::update_skeleton(
&GolemSkeleton::new(),
(vel.0.magnitude(), time),
state.state_time,
&mut state_animation_rate,
skeleton_attr,
),
// In air
(false, _, false) => anim::golem::JumpAnimation::update_skeleton(
&GolemSkeleton::new(),
(vel.0.magnitude(), time),
state.state_time,
&mut state_animation_rate,
skeleton_attr,
),
// TODO!
_ => state.skeleton_mut().clone(),
};
state.skeleton.interpolate(&target_base, dt);
state.update(
renderer,
pos.0,
ori,
scale,
col,
dt,
state_animation_rate,
lpindex,
true,
is_player,
);
},
Body::Object(_) => {
let state = self
.object_states
@ -1387,6 +1484,8 @@ impl FigureMgr {
.retain(|entity, _| ecs.entities().is_alive(*entity));
self.biped_large_states
.retain(|entity, _| ecs.entities().is_alive(*entity));
self.golem_states
.retain(|entity, _| ecs.entities().is_alive(*entity));
self.object_states
.retain(|entity, _| ecs.entities().is_alive(*entity));
}
@ -1521,6 +1620,7 @@ impl FigureMgr {
fish_medium_model_cache,
fish_small_model_cache,
biped_large_model_cache,
golem_model_cache,
character_states,
quadruped_small_states,
quadruped_medium_states,
@ -1531,6 +1631,7 @@ impl FigureMgr {
bird_small_states,
fish_small_states,
biped_large_states,
golem_states,
object_states,
} = self;
if let Some((locals, bone_consts, model)) = match body {
@ -1697,6 +1798,22 @@ impl FigureMgr {
.0,
)
}),
Body::Golem(_) => golem_states.get(&entity).map(|state| {
(
state.locals(),
state.bone_consts(),
&golem_model_cache
.get_or_create_model(
renderer,
*body,
loadout,
tick,
player_camera_mode,
character_state,
)
.0,
)
}),
Body::Object(_) => object_states.get(&entity).map(|state| {
(
state.locals(),
@ -1750,6 +1867,7 @@ impl FigureMgr {
+ self.bird_small_states.len()
+ self.fish_small_states.len()
+ self.biped_large_states.len()
+ self.golem_states.len()
+ self.object_states.len()
}
@ -1799,6 +1917,7 @@ impl FigureMgr {
.iter()
.filter(|(_, c)| c.visible)
.count()
+ self.golem_states.iter().filter(|(_, c)| c.visible).count()
+ self.object_states.iter().filter(|(_, c)| c.visible).count()
}
}