mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
biped_small setup
This commit is contained in:
parent
a99a78abdb
commit
266986626d
@ -881,6 +881,20 @@
|
||||
),
|
||||
species: ()
|
||||
),
|
||||
biped_small: (
|
||||
body: (
|
||||
keyword: "biped_small",
|
||||
names: [
|
||||
"Harvey"
|
||||
]
|
||||
),
|
||||
species: (
|
||||
clownfish: (
|
||||
keyword: "gremlin",
|
||||
generic: "Gremlin"
|
||||
)
|
||||
)
|
||||
),
|
||||
fish_small: (
|
||||
body: (
|
||||
keyword: "fish_small",
|
||||
|
46
assets/voxygen/voxel/biped_small_central_manifest.ron
Normal file
46
assets/voxygen/voxel/biped_small_central_manifest.ron
Normal file
@ -0,0 +1,46 @@
|
||||
({
|
||||
(Gremlin, Male): (
|
||||
head: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
chest: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
shorts: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-0.5, -5.0, -2.5),
|
||||
central: ("npc.gremlin.male.tail"),
|
||||
),
|
||||
main: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
),
|
||||
(Gremlin, Female): (
|
||||
head: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
chest: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
shorts: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-0.5, -5.0, -2.5),
|
||||
central: ("npc.gremlin.male.tail"),
|
||||
),
|
||||
main: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.gremlin.male.chest"),
|
||||
),
|
||||
),
|
||||
})
|
38
assets/voxygen/voxel/biped_small_lateral_manifest.ron
Normal file
38
assets/voxygen/voxel/biped_small_lateral_manifest.ron
Normal file
@ -0,0 +1,38 @@
|
||||
({
|
||||
(Gremlin, Male): (
|
||||
hand_l: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.hand_l"),
|
||||
),
|
||||
hand_r: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.hand_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.fooot_l"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.foot_r"),
|
||||
),
|
||||
),
|
||||
(Gremlin, Female): (
|
||||
hand_l: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.hand_l"),
|
||||
),
|
||||
hand_r: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.hand_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.fooot_l"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.gremlin.male.foot_r"),
|
||||
),
|
||||
),
|
||||
})
|
@ -150,6 +150,7 @@ impl<'a> From<&'a Body> for Psyche {
|
||||
quadruped_low::Species::Pangolin => 0.4,
|
||||
_ => 0.6,
|
||||
},
|
||||
Body::BipedSmall(_) => 0.5,
|
||||
Body::BirdMedium(_) => 0.5,
|
||||
Body::BirdSmall(_) => 0.4,
|
||||
Body::FishMedium(_) => 0.15,
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod biped_large;
|
||||
pub mod biped_small;
|
||||
pub mod bird_medium;
|
||||
pub mod bird_small;
|
||||
pub mod dragon;
|
||||
@ -38,10 +39,11 @@ make_case_elim!(
|
||||
BirdSmall(body: bird_small::Body) = 6,
|
||||
FishSmall(body: fish_small::Body) = 7,
|
||||
BipedLarge(body: biped_large::Body)= 8,
|
||||
Object(body: object::Body) = 9,
|
||||
Golem(body: golem::Body) = 10,
|
||||
Theropod(body: theropod::Body) = 11,
|
||||
QuadrupedLow(body: quadruped_low::Body) = 12,
|
||||
BipedSmall(body: biped_small::Body)= 9,
|
||||
Object(body: object::Body) = 10,
|
||||
Golem(body: golem::Body) = 11,
|
||||
Theropod(body: theropod::Body) = 12,
|
||||
QuadrupedLow(body: quadruped_low::Body) = 13,
|
||||
}
|
||||
);
|
||||
|
||||
@ -71,6 +73,7 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
|
||||
pub bird_small: BodyData<BodyMeta, ()>,
|
||||
pub fish_small: BodyData<BodyMeta, fish_small::AllSpecies<SpeciesMeta>>,
|
||||
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
||||
pub biped_small: BodyData<BodyMeta, biped_small::AllSpecies<SpeciesMeta>>,
|
||||
pub object: BodyData<BodyMeta, ()>,
|
||||
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
|
||||
pub theropod: BodyData<BodyMeta, theropod::AllSpecies<SpeciesMeta>>,
|
||||
@ -91,6 +94,7 @@ impl<BodyMeta, SpeciesMeta> core::ops::Index<NpcKind> for AllBodies<BodyMeta, Sp
|
||||
NpcKind::Marlin => &self.fish_medium.body,
|
||||
NpcKind::Clownfish => &self.fish_small.body,
|
||||
NpcKind::Ogre => &self.biped_large.body,
|
||||
NpcKind::Gremlin => &self.biped_small.body,
|
||||
NpcKind::StoneGolem => &self.golem.body,
|
||||
NpcKind::Archaeos => &self.theropod.body,
|
||||
NpcKind::Reddragon => &self.dragon.body,
|
||||
@ -115,6 +119,7 @@ impl<'a, BodyMeta, SpeciesMeta> core::ops::Index<&'a Body> for AllBodies<BodyMet
|
||||
Body::BirdSmall(_) => &self.bird_small.body,
|
||||
Body::FishSmall(_) => &self.fish_small.body,
|
||||
Body::BipedLarge(_) => &self.biped_large.body,
|
||||
Body::BipedSmall(_) => &self.biped_small.body,
|
||||
Body::Object(_) => &self.object.body,
|
||||
Body::Golem(_) => &self.golem.body,
|
||||
Body::Theropod(_) => &self.theropod.body,
|
||||
@ -200,6 +205,7 @@ impl Body {
|
||||
_ => 4.6,
|
||||
},
|
||||
Body::Golem(_) => 2.5,
|
||||
Body::BipedSmall(_) => 0.75,
|
||||
Body::Object(_) => 0.4,
|
||||
}
|
||||
}
|
||||
@ -262,6 +268,7 @@ impl Body {
|
||||
_ => 4.6,
|
||||
},
|
||||
Body::Golem(_) => 5.0,
|
||||
Body::BipedSmall(_) => 1.5,
|
||||
Body::Object(object) => match object {
|
||||
object::Body::Crossbow => 1.7,
|
||||
_ => 1.0,
|
||||
@ -339,6 +346,7 @@ impl Body {
|
||||
biped_large::Species::Mindflayer => 8000,
|
||||
_ => 1000,
|
||||
},
|
||||
Body::BipedSmall(_) => 10000,
|
||||
Body::Object(object) => match object {
|
||||
object::Body::TrainingDummy => 10000,
|
||||
object::Body::Crossbow => 800,
|
||||
@ -428,6 +436,7 @@ impl Body {
|
||||
biped_large::Species::Mindflayer => 250,
|
||||
_ => 100,
|
||||
},
|
||||
Body::BipedSmall(_) => 10,
|
||||
Body::Object(_) => 10,
|
||||
Body::Golem(_) => 260,
|
||||
Body::Theropod(_) => 20,
|
||||
|
78
common/src/comp/body/biped_small.rs
Normal file
78
common/src/comp/body/biped_small.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[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::BipedSmall(body) }
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Gremlin = 0,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
/// NOTE: Deliberately don't (yet?) implement serialize.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AllSpecies<SpeciesMeta> {
|
||||
pub gremlin: 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::Gremlin => &self.gremlin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const ALL_SPECIES: [Species; 1] = [Species::Gremlin];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[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];
|
@ -46,7 +46,7 @@ pub use self::{
|
||||
aura::{Aura, AuraChange, AuraKind, Auras},
|
||||
beam::{Beam, BeamSegment},
|
||||
body::{
|
||||
biped_large, bird_medium, bird_small, dragon, fish_medium, fish_small, golem, humanoid,
|
||||
biped_large, biped_small, bird_medium, bird_small, dragon, fish_medium, fish_small, golem, humanoid,
|
||||
object, quadruped_low, quadruped_medium, quadruped_small, theropod, AllBodies, Body,
|
||||
BodyData,
|
||||
},
|
||||
|
@ -16,13 +16,14 @@ pub enum NpcKind {
|
||||
Clownfish,
|
||||
Marlin,
|
||||
Ogre,
|
||||
Gremlin,
|
||||
Archaeos,
|
||||
StoneGolem,
|
||||
Reddragon,
|
||||
Crocodile,
|
||||
}
|
||||
|
||||
pub const ALL_NPCS: [NpcKind; 11] = [
|
||||
pub const ALL_NPCS: [NpcKind; 12] = [
|
||||
NpcKind::Humanoid,
|
||||
NpcKind::Wolf,
|
||||
NpcKind::Pig,
|
||||
@ -30,6 +31,7 @@ pub const ALL_NPCS: [NpcKind; 11] = [
|
||||
NpcKind::Clownfish,
|
||||
NpcKind::Marlin,
|
||||
NpcKind::Ogre,
|
||||
NpcKind::Gremlin,
|
||||
NpcKind::Archaeos,
|
||||
NpcKind::StoneGolem,
|
||||
NpcKind::Reddragon,
|
||||
@ -123,6 +125,7 @@ pub fn kind_to_body(kind: NpcKind) -> Body {
|
||||
NpcKind::Clownfish => comp::fish_small::Body::random().into(),
|
||||
NpcKind::Marlin => comp::fish_medium::Body::random().into(),
|
||||
NpcKind::Ogre => comp::biped_large::Body::random().into(),
|
||||
NpcKind::Gremlin => comp::biped_small::Body::random().into(),
|
||||
NpcKind::Archaeos => comp::theropod::Body::random().into(),
|
||||
NpcKind::StoneGolem => comp::golem::Body::random().into(),
|
||||
NpcKind::Reddragon => comp::dragon::Body::random().into(),
|
||||
@ -249,6 +252,14 @@ impl NpcBody {
|
||||
comp::biped_large::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
NpcKind::Gremlin,
|
||||
&npc_names.biped_small,
|
||||
comp::biped_small::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
|
@ -60,6 +60,7 @@ impl Body {
|
||||
quadruped_medium::Species::Kelpie => 180.0,
|
||||
quadruped_medium::Species::Horse => 180.0,
|
||||
},
|
||||
Body::BipedSmall(_) => 100.0,
|
||||
Body::BirdMedium(_) => 80.0,
|
||||
Body::FishMedium(_) => 80.0,
|
||||
Body::Dragon(_) => 250.0,
|
||||
@ -116,6 +117,7 @@ impl Body {
|
||||
Body::BirdSmall(_) => 35.0,
|
||||
Body::FishSmall(_) => 10.0,
|
||||
Body::BipedLarge(_) => 12.0,
|
||||
Body::BipedSmall(_) => 12.0,
|
||||
Body::Object(_) => 10.0,
|
||||
Body::Golem(_) => 8.0,
|
||||
Body::Theropod(theropod) => match theropod.species {
|
||||
|
44
voxygen/anim/src/biped_small/idle.rs
Normal file
44
voxygen/anim/src/biped_small/idle.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BipedSmallSkeleton, SkeletonAttr,
|
||||
};
|
||||
|
||||
pub struct IdleAnimation;
|
||||
|
||||
type IdleAnimationDependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64, Vec3<f32>);
|
||||
|
||||
impl Animation for IdleAnimation {
|
||||
type Dependency = IdleAnimationDependency;
|
||||
type Skeleton = BipedSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"biped_small_idle\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "Biped_small_idle")]
|
||||
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(_velocity, _orientation, _last_ori, _global_time, _avg_vel): Self::Dependency,
|
||||
anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.head.scale = Vec3::one();
|
||||
|
||||
next.chest.scale = Vec3::one() / 13.0;
|
||||
|
||||
next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) / 13.0;
|
||||
next.shorts.position = Vec3::new(0.0, s_a.shorts.0, s_a.shorts.1);
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
|
||||
next.hand_l.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
|
||||
next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
|
||||
next.foot_l.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
114
voxygen/anim/src/biped_small/mod.rs
Normal file
114
voxygen/anim/src/biped_small/mod.rs
Normal file
@ -0,0 +1,114 @@
|
||||
pub mod idle;
|
||||
pub mod run;
|
||||
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::biped_small::Body;
|
||||
|
||||
skeleton_impls!(struct BipedSmallSkeleton {
|
||||
+ head,
|
||||
+ chest,
|
||||
+ shorts,
|
||||
+ tail,
|
||||
+ main,
|
||||
+ hand_l,
|
||||
+ hand_r,
|
||||
+ foot_l,
|
||||
+ foot_r,
|
||||
});
|
||||
|
||||
impl Skeleton for BipedSmallSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 9;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const COMPUTE_FN: &'static [u8] = b"biped_small_compute_mats\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "biped_small_compute_mats")]
|
||||
fn compute_matrices_inner(
|
||||
&self,
|
||||
base_mat: Mat4<f32>,
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
) -> Vec3<f32> {
|
||||
let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
|
||||
let shorts_mat = chest_mat * Mat4::<f32>::from(self.chest);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.head)),
|
||||
make_bone(chest_mat),
|
||||
make_bone(shorts_mat),
|
||||
make_bone(shorts_mat * Mat4::<f32>::from(self.tail)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.main)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.hand_l)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.hand_l)),
|
||||
make_bone(base_mat * Mat4::<f32>::from(self.foot_l)),
|
||||
make_bone(base_mat * Mat4::<f32>::from(self.foot_l)),
|
||||
];
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkeletonAttr {
|
||||
head: (f32, f32),
|
||||
chest: (f32, f32),
|
||||
shorts: (f32, f32),
|
||||
tail: (f32, f32),
|
||||
hand: (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::BipedSmall(body) => Ok(SkeletonAttr::from(body)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
head: (0.0, 0.0),
|
||||
chest: (0.0, 0.0),
|
||||
shorts: (0.0, 0.0),
|
||||
tail: (0.0, 0.0),
|
||||
hand: (0.0, 0.0, 0.0),
|
||||
foot: (0.0, 0.0, 0.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::biped_small::Species::*;
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
(Gremlin, _) => (0.0, 5.0),
|
||||
},
|
||||
chest: match (body.species, body.body_type) {
|
||||
(Gremlin, _) => (0.0, 5.0),
|
||||
},
|
||||
shorts: match (body.species, body.body_type) {
|
||||
(Gremlin, _) => (0.0, 5.0),
|
||||
},
|
||||
tail: match (body.species, body.body_type) {
|
||||
(Gremlin, _) => (-7.5, -0.5),
|
||||
},
|
||||
hand: match (body.species, body.body_type) {
|
||||
(Gremlin, _) => (2.0, 0.5, 1.0),
|
||||
},
|
||||
foot: match (body.species, body.body_type) {
|
||||
(Gremlin, _) => (2.0, 0.5, 1.0),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
44
voxygen/anim/src/biped_small/run.rs
Normal file
44
voxygen/anim/src/biped_small/run.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BipedSmallSkeleton, SkeletonAttr,
|
||||
};
|
||||
|
||||
pub struct RunAnimation;
|
||||
|
||||
type RunAnimationDependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64, Vec3<f32>);
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Dependency = RunAnimationDependency;
|
||||
type Skeleton = BipedSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"biped_small_run\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "Biped_small_run")]
|
||||
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(_velocity, _orientation, _last_ori, _global_time, _avg_vel): Self::Dependency,
|
||||
anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.head.scale = Vec3::one();
|
||||
|
||||
next.chest.scale = Vec3::one() / 13.0;
|
||||
|
||||
next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1) / 13.0;
|
||||
next.shorts.position = Vec3::new(0.0, s_a.shorts.0, s_a.shorts.1);
|
||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
|
||||
next.hand_l.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
|
||||
next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
|
||||
next.foot_l.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -40,6 +40,7 @@ macro_rules! skeleton_impls {
|
||||
}
|
||||
|
||||
pub mod biped_large;
|
||||
pub mod biped_small;
|
||||
pub mod bird_medium;
|
||||
pub mod bird_small;
|
||||
pub mod character;
|
||||
|
@ -3,6 +3,7 @@ use common::{
|
||||
assets::{self, AssetExt, AssetHandle, DotVoxAsset, Ron},
|
||||
comp::{
|
||||
biped_large::{self, BodyType as BLBodyType, Species as BLSpecies},
|
||||
biped_small::{self, BodyType as BSBodyType, Species as BSSpecies},
|
||||
bird_medium::{self, BodyType as BMBodyType, Species as BMSpecies},
|
||||
bird_small,
|
||||
dragon::{self, BodyType as DBodyType, Species as DSpecies},
|
||||
@ -2468,6 +2469,241 @@ impl FishSmallLateralSpec {
|
||||
|
||||
////
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct BipedSmallCentralSpec(HashMap<(BSSpecies, BSBodyType), SidedBSCentralVoxSpec>);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SidedBSCentralVoxSpec {
|
||||
head: BipedSmallCentralSubSpec,
|
||||
chest: BipedSmallCentralSubSpec,
|
||||
shorts: BipedSmallCentralSubSpec,
|
||||
tail: BipedSmallCentralSubSpec,
|
||||
main: BipedSmallCentralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct BipedSmallCentralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
central: VoxSimple,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct BipedSmallLateralSpec(HashMap<(BSSpecies, BSBodyType), SidedBSLateralVoxSpec>);
|
||||
#[derive(Deserialize)]
|
||||
struct SidedBSLateralVoxSpec {
|
||||
hand_l: BipedSmallLateralSubSpec,
|
||||
hand_r: BipedSmallLateralSubSpec,
|
||||
foot_l: BipedSmallLateralSubSpec,
|
||||
foot_r: BipedSmallLateralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct BipedSmallLateralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
lateral: VoxSimple,
|
||||
}
|
||||
|
||||
make_vox_spec!(
|
||||
biped_small::Body,
|
||||
struct BipedSmallSpec {
|
||||
central: BipedSmallCentralSpec = "voxygen.voxel.biped_small_central_manifest",
|
||||
lateral: BipedSmallLateralSpec = "voxygen.voxel.biped_small_lateral_manifest",
|
||||
},
|
||||
|FigureKey { body, .. }, spec| {
|
||||
[
|
||||
Some(spec.central.read().0.mesh_head(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_chest(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_shorts(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_tail(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_main(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_hand_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_hand_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_foot_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_foot_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
impl BipedSmallCentralSpec {
|
||||
fn mesh_head(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
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));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.head.central.0);
|
||||
|
||||
(central, Vec3::from(spec.head.offset))
|
||||
}
|
||||
|
||||
fn mesh_chest(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No chest specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.chest.central.0);
|
||||
|
||||
(central, Vec3::from(spec.chest.offset))
|
||||
}
|
||||
|
||||
fn mesh_shorts(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No shorts specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.shorts.central.0);
|
||||
|
||||
(central, Vec3::from(spec.shorts.offset))
|
||||
}
|
||||
|
||||
fn mesh_tail(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No tail specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.tail.central.0);
|
||||
|
||||
(central, Vec3::from(spec.tail.offset))
|
||||
}
|
||||
|
||||
fn mesh_main(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No main specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.main.central.0);
|
||||
|
||||
(central, Vec3::from(spec.main.offset))
|
||||
}
|
||||
}
|
||||
|
||||
impl BipedSmallLateralSpec {
|
||||
fn mesh_hand_l(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
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));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.hand_l.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.hand_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_hand_r(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
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));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.hand_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.hand_r.offset))
|
||||
}
|
||||
|
||||
fn mesh_foot_l(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
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));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.foot_l.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.foot_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_foot_r(&self, species: BSSpecies, body_type: BSBodyType) -> BoneMeshes {
|
||||
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));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.foot_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.foot_r.offset))
|
||||
}
|
||||
}
|
||||
////
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DragonCentralSpec(HashMap<(DSpecies, DBodyType), SidedDCentralVoxSpec>);
|
||||
|
||||
|
@ -18,10 +18,10 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use anim::{
|
||||
biped_large::BipedLargeSkeleton, bird_medium::BirdMediumSkeleton,
|
||||
bird_small::BirdSmallSkeleton, character::CharacterSkeleton, dragon::DragonSkeleton,
|
||||
fish_medium::FishMediumSkeleton, fish_small::FishSmallSkeleton, golem::GolemSkeleton,
|
||||
object::ObjectSkeleton, quadruped_low::QuadrupedLowSkeleton,
|
||||
biped_large::BipedLargeSkeleton, biped_small::BipedSmallSkeleton,
|
||||
bird_medium::BirdMediumSkeleton, bird_small::BirdSmallSkeleton, character::CharacterSkeleton,
|
||||
dragon::DragonSkeleton, fish_medium::FishMediumSkeleton, fish_small::FishSmallSkeleton,
|
||||
golem::GolemSkeleton, object::ObjectSkeleton, quadruped_low::QuadrupedLowSkeleton,
|
||||
quadruped_medium::QuadrupedMediumSkeleton, quadruped_small::QuadrupedSmallSkeleton,
|
||||
theropod::TheropodSkeleton, Animation, Skeleton,
|
||||
};
|
||||
@ -98,6 +98,7 @@ struct FigureMgrStates {
|
||||
bird_small_states: HashMap<EcsEntity, FigureState<BirdSmallSkeleton>>,
|
||||
fish_small_states: HashMap<EcsEntity, FigureState<FishSmallSkeleton>>,
|
||||
biped_large_states: HashMap<EcsEntity, FigureState<BipedLargeSkeleton>>,
|
||||
biped_small_states: HashMap<EcsEntity, FigureState<BipedSmallSkeleton>>,
|
||||
golem_states: HashMap<EcsEntity, FigureState<GolemSkeleton>>,
|
||||
object_states: HashMap<EcsEntity, FigureState<ObjectSkeleton>>,
|
||||
}
|
||||
@ -116,6 +117,7 @@ impl FigureMgrStates {
|
||||
bird_small_states: HashMap::new(),
|
||||
fish_small_states: HashMap::new(),
|
||||
biped_large_states: HashMap::new(),
|
||||
biped_small_states: HashMap::new(),
|
||||
golem_states: HashMap::new(),
|
||||
object_states: HashMap::new(),
|
||||
}
|
||||
@ -172,6 +174,10 @@ impl FigureMgrStates {
|
||||
.biped_large_states
|
||||
.get_mut(&entity)
|
||||
.map(DerefMut::deref_mut),
|
||||
Body::BipedSmall(_) => self
|
||||
.biped_small_states
|
||||
.get_mut(&entity)
|
||||
.map(DerefMut::deref_mut),
|
||||
Body::Golem(_) => self.golem_states.get_mut(&entity).map(DerefMut::deref_mut),
|
||||
Body::Object(_) => self.object_states.get_mut(&entity).map(DerefMut::deref_mut),
|
||||
}
|
||||
@ -196,6 +202,7 @@ impl FigureMgrStates {
|
||||
Body::BirdSmall(_) => self.bird_small_states.remove(&entity).map(|e| e.meta),
|
||||
Body::FishSmall(_) => self.fish_small_states.remove(&entity).map(|e| e.meta),
|
||||
Body::BipedLarge(_) => self.biped_large_states.remove(&entity).map(|e| e.meta),
|
||||
Body::BipedSmall(_) => self.biped_small_states.remove(&entity).map(|e| e.meta),
|
||||
Body::Golem(_) => self.golem_states.remove(&entity).map(|e| e.meta),
|
||||
Body::Object(_) => self.object_states.remove(&entity).map(|e| e.meta),
|
||||
}
|
||||
@ -214,6 +221,7 @@ impl FigureMgrStates {
|
||||
self.bird_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.fish_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.biped_large_states.retain(|k, v| f(k, &mut *v));
|
||||
self.biped_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.golem_states.retain(|k, v| f(k, &mut *v));
|
||||
self.object_states.retain(|k, v| f(k, &mut *v));
|
||||
}
|
||||
@ -231,6 +239,7 @@ impl FigureMgrStates {
|
||||
+ self.bird_small_states.len()
|
||||
+ self.fish_small_states.len()
|
||||
+ self.biped_large_states.len()
|
||||
+ self.biped_small_states.len()
|
||||
+ self.golem_states.len()
|
||||
+ self.object_states.len()
|
||||
}
|
||||
@ -290,6 +299,11 @@ impl FigureMgrStates {
|
||||
.iter()
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
+ self
|
||||
.biped_small_states
|
||||
.iter()
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
+ self
|
||||
.golem_states
|
||||
.iter()
|
||||
@ -316,6 +330,7 @@ pub struct FigureMgr {
|
||||
fish_medium_model_cache: FigureModelCache<FishMediumSkeleton>,
|
||||
fish_small_model_cache: FigureModelCache<FishSmallSkeleton>,
|
||||
biped_large_model_cache: FigureModelCache<BipedLargeSkeleton>,
|
||||
biped_small_model_cache: FigureModelCache<BipedSmallSkeleton>,
|
||||
object_model_cache: FigureModelCache<ObjectSkeleton>,
|
||||
golem_model_cache: FigureModelCache<GolemSkeleton>,
|
||||
states: FigureMgrStates,
|
||||
@ -336,6 +351,7 @@ impl FigureMgr {
|
||||
fish_medium_model_cache: FigureModelCache::new(),
|
||||
fish_small_model_cache: FigureModelCache::new(),
|
||||
biped_large_model_cache: FigureModelCache::new(),
|
||||
biped_small_model_cache: FigureModelCache::new(),
|
||||
object_model_cache: FigureModelCache::new(),
|
||||
golem_model_cache: FigureModelCache::new(),
|
||||
states: FigureMgrStates::default(),
|
||||
@ -365,6 +381,8 @@ impl FigureMgr {
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.biped_large_model_cache
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.biped_small_model_cache
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.object_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.golem_model_cache.clean(&mut self.col_lights, tick);
|
||||
}
|
||||
@ -2519,6 +2537,99 @@ impl FigureMgr {
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::BipedSmall(body) => {
|
||||
let (model, skeleton_attr) = self.biped_small_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
*body,
|
||||
inventory,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
player_character_state,
|
||||
scene_data.thread_pool,
|
||||
);
|
||||
|
||||
let state = self
|
||||
.states
|
||||
.biped_small_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| {
|
||||
FigureState::new(renderer, BipedSmallSkeleton::default())
|
||||
});
|
||||
|
||||
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_liquid.is_some(), // In water
|
||||
) {
|
||||
// Idle
|
||||
(true, false, false) => anim::biped_small::IdleAnimation::update_skeleton(
|
||||
&BipedSmallSkeleton::default(),
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Run
|
||||
(true, true, _) => anim::biped_small::RunAnimation::update_skeleton(
|
||||
&BipedSmallSkeleton::default(),
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Jump
|
||||
(false, _, false) => anim::biped_small::RunAnimation::update_skeleton(
|
||||
&BipedSmallSkeleton::default(),
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Swim
|
||||
(false, _, true) => anim::biped_small::RunAnimation::update_skeleton(
|
||||
&BipedSmallSkeleton::default(),
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
_ => anim::biped_small::RunAnimation::update_skeleton(
|
||||
&BipedSmallSkeleton::default(),
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
};
|
||||
|
||||
state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_base, dt_lerp);
|
||||
state.update(
|
||||
renderer,
|
||||
pos.0,
|
||||
ori,
|
||||
scale,
|
||||
col,
|
||||
dt,
|
||||
state_animation_rate,
|
||||
model,
|
||||
lpindex,
|
||||
in_frustum,
|
||||
is_player,
|
||||
camera,
|
||||
&mut update_buf,
|
||||
terrain,
|
||||
);
|
||||
},
|
||||
Body::Dragon(body) => {
|
||||
let (model, skeleton_attr) = self.dragon_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
@ -3808,6 +3919,7 @@ impl FigureMgr {
|
||||
fish_medium_model_cache,
|
||||
fish_small_model_cache,
|
||||
biped_large_model_cache,
|
||||
biped_small_model_cache,
|
||||
object_model_cache,
|
||||
golem_model_cache,
|
||||
states:
|
||||
@ -3823,6 +3935,7 @@ impl FigureMgr {
|
||||
bird_small_states,
|
||||
fish_small_states,
|
||||
biped_large_states,
|
||||
biped_small_states,
|
||||
golem_states,
|
||||
object_states,
|
||||
},
|
||||
@ -4016,6 +4129,23 @@ impl FigureMgr {
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::BipedSmall(body) => biped_small_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
biped_small_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
inventory,
|
||||
tick,
|
||||
player_camera_mode,
|
||||
character_state,
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::Golem(body) => golem_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
|
Loading…
Reference in New Issue
Block a user