mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'snowram/fishes' into 'master'
Add fishes See merge request veloren/veloren!1577
This commit is contained in:
commit
c42cdc685c
@ -686,7 +686,7 @@
|
||||
"species": {
|
||||
"reddragon": {
|
||||
"keyword": "reddragon",
|
||||
"generic": "Reddragon"
|
||||
"generic": "Red Dragon"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -700,16 +700,30 @@
|
||||
"fish_small": {
|
||||
"body": {
|
||||
"keyword": "fish_small",
|
||||
"names": []
|
||||
"names": [
|
||||
"Dagon"
|
||||
]
|
||||
},
|
||||
"species": null
|
||||
"species": {
|
||||
"clownfish": {
|
||||
"keyword": "clownfish",
|
||||
"generic": "Clownfish"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fish_medium": {
|
||||
"body": {
|
||||
"keyword": "fish_medium",
|
||||
"names": []
|
||||
"names": [
|
||||
"Njord"
|
||||
]
|
||||
},
|
||||
"species": null
|
||||
"species": {
|
||||
"marlin": {
|
||||
"keyword": "marlin",
|
||||
"generic": "Marlin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bird_small": {
|
||||
"body": {
|
||||
|
46
assets/voxygen/voxel/fish_medium_central_manifest.ron
Normal file
46
assets/voxygen/voxel/fish_medium_central_manifest.ron
Normal file
@ -0,0 +1,46 @@
|
||||
({
|
||||
(Marlin, Male): (
|
||||
head: (
|
||||
offset: (-2.5, 0.0, -3.0),
|
||||
central: ("npc.marlin.male.head"),
|
||||
),
|
||||
jaw: (
|
||||
offset: (-4.0, 0.0, -1.5),
|
||||
central: ("armor.empty"),
|
||||
),
|
||||
chest_front: (
|
||||
offset: (-2.5, -5.0, -2.5),
|
||||
central: ("npc.marlin.male.chest_front"),
|
||||
),
|
||||
chest_back: (
|
||||
offset: (-2.5, -7.0, -3.5),
|
||||
central: ("npc.marlin.male.chest_back"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-0.5, -11.0, -4.5),
|
||||
central: ("npc.marlin.male.tail"),
|
||||
),
|
||||
),
|
||||
(Marlin, Female): (
|
||||
head: (
|
||||
offset: (-2.5, 0.0, -3.0),
|
||||
central: ("npc.marlin.male.head"),
|
||||
),
|
||||
jaw: (
|
||||
offset: (-4.0, 0.0, -1.5),
|
||||
central: ("armor.empty"),
|
||||
),
|
||||
chest_front: (
|
||||
offset: (-2.5, -5.0, -2.5),
|
||||
central: ("npc.marlin.male.chest_front"),
|
||||
),
|
||||
chest_back: (
|
||||
offset: (-2.5, -7.0, -3.5),
|
||||
central: ("npc.marlin.male.chest_back"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-0.5, -11.0, -4.5),
|
||||
central: ("npc.marlin.male.tail"),
|
||||
),
|
||||
),
|
||||
})
|
22
assets/voxygen/voxel/fish_medium_lateral_manifest.ron
Normal file
22
assets/voxygen/voxel/fish_medium_lateral_manifest.ron
Normal file
@ -0,0 +1,22 @@
|
||||
({
|
||||
(Marlin, Male): (
|
||||
fin_l: (
|
||||
offset: (-3.0, -5.0, -4.0),
|
||||
lateral: ("npc.marlin.male.fin_l"),
|
||||
),
|
||||
fin_r: (
|
||||
offset: (0.0, -5.0, -4.0),
|
||||
lateral: ("npc.marlin.male.fin_r"),
|
||||
),
|
||||
),
|
||||
(Marlin, Female): (
|
||||
fin_l: (
|
||||
offset: (-3.0, -5.0, -4.0),
|
||||
lateral: ("npc.marlin.male.fin_l"),
|
||||
),
|
||||
fin_r: (
|
||||
offset: (0.0, -5.0, -4.0),
|
||||
lateral: ("npc.marlin.male.fin_r"),
|
||||
),
|
||||
),
|
||||
})
|
22
assets/voxygen/voxel/fish_small_central_manifest.ron
Normal file
22
assets/voxygen/voxel/fish_small_central_manifest.ron
Normal file
@ -0,0 +1,22 @@
|
||||
({
|
||||
(Clownfish, Male): (
|
||||
chest: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.clownfish.male.chest"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-0.5, -5.0, -2.5),
|
||||
central: ("npc.clownfish.male.tail"),
|
||||
),
|
||||
),
|
||||
(Clownfish, Female): (
|
||||
chest: (
|
||||
offset: (-1.5, -7.5, -5.0),
|
||||
central: ("npc.clownfish.male.chest"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-0.5, -5.0, -2.5),
|
||||
central: ("npc.clownfish.male.tail"),
|
||||
),
|
||||
),
|
||||
})
|
22
assets/voxygen/voxel/fish_small_lateral_manifest.ron
Normal file
22
assets/voxygen/voxel/fish_small_lateral_manifest.ron
Normal file
@ -0,0 +1,22 @@
|
||||
({
|
||||
(Clownfish, Male): (
|
||||
fin_l: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.clownfish.male.fin_l"),
|
||||
),
|
||||
fin_r: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.clownfish.male.fin_r"),
|
||||
),
|
||||
),
|
||||
(Clownfish, Female): (
|
||||
fin_l: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.clownfish.male.fin_l"),
|
||||
),
|
||||
fin_r: (
|
||||
offset: (-0.5, -3.0, -4.0),
|
||||
lateral: ("npc.clownfish.male.fin_r"),
|
||||
),
|
||||
),
|
||||
})
|
BIN
assets/voxygen/voxel/npc/clownfish/male/chest.vox
Normal file
BIN
assets/voxygen/voxel/npc/clownfish/male/chest.vox
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/clownfish/male/fin_l.vox
Normal file
BIN
assets/voxygen/voxel/npc/clownfish/male/fin_l.vox
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/clownfish/male/fin_r.vox
Normal file
BIN
assets/voxygen/voxel/npc/clownfish/male/fin_r.vox
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/clownfish/male/tail.vox
Normal file
BIN
assets/voxygen/voxel/npc/clownfish/male/tail.vox
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/voxygen/voxel/npc/marlin/male/chest_front.vox
Normal file
BIN
assets/voxygen/voxel/npc/marlin/male/chest_front.vox
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/voxygen/voxel/npc/marlin/male/head.vox
Normal file
BIN
assets/voxygen/voxel/npc/marlin/male/head.vox
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/marlin/male/tail.vox
Normal file
BIN
assets/voxygen/voxel/npc/marlin/male/tail.vox
Normal file
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/roshwalr/female/head.vox
Normal file
BIN
assets/voxygen/voxel/npc/roshwalr/female/head.vox
Normal file
Binary file not shown.
@ -812,7 +812,7 @@
|
||||
(Roshwalr, Female): (
|
||||
head: (
|
||||
offset: (-13.0, 0.0, -12.0),
|
||||
central: ("npc.roshwalr.male.head"),
|
||||
central: ("npc.roshwalr.female.head"),
|
||||
),
|
||||
neck: (
|
||||
offset: (-7.0, -2.0, -11.5),
|
||||
|
@ -65,10 +65,10 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
|
||||
pub quadruped_small: BodyData<BodyMeta, quadruped_small::AllSpecies<SpeciesMeta>>,
|
||||
pub quadruped_medium: BodyData<BodyMeta, quadruped_medium::AllSpecies<SpeciesMeta>>,
|
||||
pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
|
||||
pub fish_medium: BodyData<BodyMeta, ()>,
|
||||
pub fish_medium: BodyData<BodyMeta, fish_medium::AllSpecies<SpeciesMeta>>,
|
||||
pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
|
||||
pub bird_small: BodyData<BodyMeta, ()>,
|
||||
pub fish_small: BodyData<BodyMeta, ()>,
|
||||
pub fish_small: BodyData<BodyMeta, fish_small::AllSpecies<SpeciesMeta>>,
|
||||
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
||||
pub object: BodyData<BodyMeta, ()>,
|
||||
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
|
||||
@ -87,6 +87,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::Marlin => &self.fish_medium.body,
|
||||
NpcKind::Clownfish => &self.fish_small.body,
|
||||
NpcKind::Ogre => &self.biped_large.body,
|
||||
NpcKind::StoneGolem => &self.golem.body,
|
||||
NpcKind::Archaeos => &self.theropod.body,
|
||||
@ -231,10 +233,10 @@ impl Body {
|
||||
bird_medium::Species::Cockatrice => 1.8,
|
||||
_ => 1.1,
|
||||
},
|
||||
Body::FishMedium(_) => 1.1,
|
||||
Body::FishMedium(_) => 0.8,
|
||||
Body::Dragon(_) => 16.0,
|
||||
Body::BirdSmall(_) => 1.1,
|
||||
Body::FishSmall(_) => 0.9,
|
||||
Body::FishSmall(_) => 0.6,
|
||||
Body::BipedLarge(body) => match body.species {
|
||||
biped_large::Species::Slysaurok => 2.3,
|
||||
biped_large::Species::Occultsaurok => 2.8,
|
||||
|
@ -6,86 +6,73 @@ make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub head: Head,
|
||||
pub torso: Torso,
|
||||
pub rear: Rear,
|
||||
pub tail: Tail,
|
||||
pub fin_l: FinL,
|
||||
pub fin_r: FinR,
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
Self {
|
||||
head: *(&ALL_HEADS).choose(&mut rng).unwrap(),
|
||||
torso: *(&ALL_TORSOS).choose(&mut rng).unwrap(),
|
||||
rear: *(&ALL_REARS).choose(&mut rng).unwrap(),
|
||||
tail: *(&ALL_TAILS).choose(&mut rng).unwrap(),
|
||||
fin_l: *(&ALL_FIN_LS).choose(&mut rng).unwrap(),
|
||||
fin_r: *(&ALL_FIN_RS).choose(&mut rng).unwrap(),
|
||||
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::FishMedium(body) }
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Marlin = 0,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
/// NOTE: Deliberately don't (yet?) implement serialize.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AllSpecies<SpeciesMeta> {
|
||||
pub marlin: 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::Marlin => &self.marlin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
head,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Head {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
pub const ALL_SPECIES: [Species; 1] = [Species::Marlin];
|
||||
|
||||
const ALL_HEADS: [Head; 1] = [Head::Default];
|
||||
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!(
|
||||
torso,
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default = 0,
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
const ALL_TORSOS: [Torso; 1] = [Torso::Default];
|
||||
|
||||
make_case_elim!(
|
||||
rear,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Rear {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_REARS: [Rear; 1] = [Rear::Default];
|
||||
|
||||
make_case_elim!(
|
||||
tail,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Tail {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_TAILS: [Tail; 1] = [Tail::Default];
|
||||
|
||||
make_case_elim!(
|
||||
fin_l,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum FinL {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_FIN_LS: [FinL; 1] = [FinL::Default];
|
||||
|
||||
make_case_elim!(
|
||||
fin_r,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum FinR {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_FIN_RS: [FinR; 1] = [FinR::Default];
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -6,39 +6,73 @@ make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub torso: Torso,
|
||||
pub tail: Tail,
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
Self {
|
||||
torso: *(&ALL_TORSOS).choose(&mut rng).unwrap(),
|
||||
tail: *(&ALL_TAILS).choose(&mut rng).unwrap(),
|
||||
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::FishSmall(body) }
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Clownfish = 0,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
/// NOTE: Deliberately don't (yet?) implement serialize.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AllSpecies<SpeciesMeta> {
|
||||
pub clownfish: 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::Clownfish => &self.clownfish,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
torso,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
pub const ALL_SPECIES: [Species; 1] = [Species::Clownfish];
|
||||
|
||||
const ALL_TORSOS: [Torso; 1] = [Torso::Default];
|
||||
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!(
|
||||
tail,
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Tail {
|
||||
Default = 0,
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
const ALL_TAILS: [Tail; 1] = [Tail::Default];
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
||||
|
@ -121,6 +121,8 @@ impl EntityInfo {
|
||||
Some(get_npc_name(&NPC_NAMES.quadruped_medium, body.species))
|
||||
},
|
||||
Body::BirdMedium(body) => Some(get_npc_name(&NPC_NAMES.bird_medium, body.species)),
|
||||
Body::FishSmall(body) => Some(get_npc_name(&NPC_NAMES.fish_small, body.species)),
|
||||
Body::FishMedium(body) => Some(get_npc_name(&NPC_NAMES.fish_medium, body.species)),
|
||||
Body::Theropod(body) => Some(get_npc_name(&NPC_NAMES.theropod, body.species)),
|
||||
Body::QuadrupedSmall(body) => {
|
||||
Some(get_npc_name(&NPC_NAMES.quadruped_small, body.species))
|
||||
|
@ -13,6 +13,8 @@ pub enum NpcKind {
|
||||
Wolf,
|
||||
Pig,
|
||||
Duck,
|
||||
Clownfish,
|
||||
Marlin,
|
||||
Ogre,
|
||||
Archaeos,
|
||||
StoneGolem,
|
||||
@ -20,11 +22,13 @@ pub enum NpcKind {
|
||||
Crocodile,
|
||||
}
|
||||
|
||||
pub const ALL_NPCS: [NpcKind; 9] = [
|
||||
pub const ALL_NPCS: [NpcKind; 11] = [
|
||||
NpcKind::Humanoid,
|
||||
NpcKind::Wolf,
|
||||
NpcKind::Pig,
|
||||
NpcKind::Duck,
|
||||
NpcKind::Clownfish,
|
||||
NpcKind::Marlin,
|
||||
NpcKind::Ogre,
|
||||
NpcKind::Archaeos,
|
||||
NpcKind::StoneGolem,
|
||||
@ -93,6 +97,8 @@ 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::Clownfish => comp::fish_small::Body::random().into(),
|
||||
NpcKind::Marlin => comp::fish_medium::Body::random().into(),
|
||||
NpcKind::Ogre => comp::biped_large::Body::random().into(),
|
||||
NpcKind::Archaeos => comp::theropod::Body::random().into(),
|
||||
NpcKind::StoneGolem => comp::golem::Body::random().into(),
|
||||
@ -195,6 +201,22 @@ impl NpcBody {
|
||||
comp::bird_medium::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
NpcKind::Clownfish,
|
||||
&npc_names.fish_small,
|
||||
comp::fish_small::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
NpcKind::Marlin,
|
||||
&npc_names.fish_medium,
|
||||
comp::fish_medium::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
|
@ -58,10 +58,10 @@ impl Body {
|
||||
quadruped_medium::Species::Horse => 180.0,
|
||||
},
|
||||
Body::BirdMedium(_) => 80.0,
|
||||
Body::FishMedium(_) => 50.0,
|
||||
Body::FishMedium(_) => 80.0,
|
||||
Body::Dragon(_) => 250.0,
|
||||
Body::BirdSmall(_) => 75.0,
|
||||
Body::FishSmall(_) => 40.0,
|
||||
Body::FishSmall(_) => 60.0,
|
||||
Body::BipedLarge(_) => 75.0,
|
||||
Body::Object(_) => 40.0,
|
||||
Body::Golem(_) => 60.0,
|
||||
|
@ -1,50 +1,55 @@
|
||||
use super::{super::Animation, FishMediumSkeleton, SkeletonAttr};
|
||||
//use std::{f32::consts::PI, ops::Mul};
|
||||
use super::super::vek::*;
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
FishMediumSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct IdleAnimation;
|
||||
|
||||
type IdleAnimationDependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64, Vec3<f32>);
|
||||
|
||||
impl Animation for IdleAnimation {
|
||||
type Dependency = f64;
|
||||
type Dependency = IdleAnimationDependency;
|
||||
type Skeleton = FishMediumSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_medium_idle\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_medium_idle")]
|
||||
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
_global_time: Self::Dependency,
|
||||
_anim_time: f64,
|
||||
(_velocity, _orientation, _last_ori, _global_time, _avg_vel): Self::Dependency,
|
||||
anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.head.scale = Vec3::one() / 10.88;
|
||||
next.torso.scale = Vec3::one() * 1.01;
|
||||
next.rear.scale = Vec3::one() * 0.98;
|
||||
next.tail.scale = Vec3::one() / 11.0;
|
||||
next.fin_l.scale = Vec3::one() / 11.0;
|
||||
next.fin_r.scale = Vec3::one() / 10.5;
|
||||
let slow = (anim_time as f32 * 3.5 + PI).sin();
|
||||
let slowalt = (anim_time as f32 * 3.5 + PI + 0.2).sin();
|
||||
|
||||
next.head.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.chest_front.scale = Vec3::one() / 11.0;
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 4.5, 2.0);
|
||||
next.torso.orientation = Quaternion::rotation_x(0.0);
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_z(slowalt * -0.1);
|
||||
|
||||
next.rear.position = Vec3::new(0.0, 3.1, -4.5);
|
||||
next.rear.orientation = Quaternion::rotation_z(0.0);
|
||||
next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, -13.0, 8.0) / 11.0;
|
||||
next.tail.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1) / 11.0;
|
||||
next.chest_front.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.fin_l.position = Vec3::new(0.0, -11.7, 11.0) / 11.0;
|
||||
next.fin_l.orientation = Quaternion::rotation_y(0.0);
|
||||
next.chest_back.position = Vec3::new(0.0, s_a.chest_back.0, s_a.chest_back.1);
|
||||
next.chest_back.orientation = Quaternion::rotation_z(slowalt * 0.1);
|
||||
|
||||
next.fin_r.position = Vec3::new(0.0, 0.0, 12.0) / 11.0;
|
||||
next.fin_r.orientation = Quaternion::rotation_y(0.0);
|
||||
next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
|
||||
next.tail.orientation = Quaternion::rotation_z(slow * 0.1);
|
||||
|
||||
next.fin_l.position = Vec3::new(-s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_l.orientation = Quaternion::rotation_z(slow * 0.1 - 0.1);
|
||||
|
||||
next.fin_r.position = Vec3::new(s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_r.orientation = Quaternion::rotation_z(-slow * 0.1 + 0.1);
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
use super::{super::Animation, FishMediumSkeleton, SkeletonAttr};
|
||||
//use std::f32::consts::PI;
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct JumpAnimation;
|
||||
|
||||
impl Animation for JumpAnimation {
|
||||
type Dependency = (f32, f64);
|
||||
type Skeleton = FishMediumSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_medium_jump\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_medium_jump")]
|
||||
fn update_skeleton_inner(
|
||||
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.scale = Vec3::one() / 10.88;
|
||||
next.torso.scale = Vec3::one() * 1.01;
|
||||
next.rear.scale = Vec3::one() * 0.98;
|
||||
next.tail.scale = Vec3::one() / 11.0;
|
||||
next.fin_l.scale = Vec3::one() / 11.0;
|
||||
next.fin_r.scale = Vec3::one() / 10.5;
|
||||
|
||||
next.head.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 4.5, 2.0);
|
||||
next.torso.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.rear.position = Vec3::new(0.0, 3.1, -4.5);
|
||||
next.rear.orientation = Quaternion::rotation_z(0.0);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, -13.0, 8.0) / 11.0;
|
||||
next.tail.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
|
||||
next.fin_l.position = Vec3::new(0.0, -11.7, 11.0) / 11.0;
|
||||
next.fin_l.orientation = Quaternion::rotation_y(0.0);
|
||||
|
||||
next.fin_r.position = Vec3::new(0.0, 0.0, 12.0) / 11.0;
|
||||
next.fin_r.orientation = Quaternion::rotation_y(0.0);
|
||||
next
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
pub mod idle;
|
||||
pub mod jump;
|
||||
pub mod run;
|
||||
pub mod swim;
|
||||
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
pub use self::{idle::IdleAnimation, swim::SwimAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
@ -13,8 +12,9 @@ pub type Body = comp::fish_medium::Body;
|
||||
|
||||
skeleton_impls!(struct FishMediumSkeleton {
|
||||
+ head,
|
||||
+ torso,
|
||||
+ rear,
|
||||
+ jaw,
|
||||
+ chest_front,
|
||||
+ chest_back,
|
||||
+ tail,
|
||||
+ fin_l,
|
||||
+ fin_r,
|
||||
@ -24,7 +24,7 @@ impl Skeleton for FishMediumSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 6;
|
||||
const BONE_COUNT: usize = 7;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const COMPUTE_FN: &'static [u8] = b"fish_medium_compute_mats\0";
|
||||
|
||||
@ -34,22 +34,33 @@ impl Skeleton for FishMediumSkeleton {
|
||||
base_mat: Mat4<f32>,
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
) -> Vec3<f32> {
|
||||
let torso_mat = base_mat * Mat4::<f32>::from(self.torso);
|
||||
let rear_mat = torso_mat * Mat4::<f32>::from(self.rear);
|
||||
let chest_front_mat = base_mat * Mat4::<f32>::from(self.chest_front);
|
||||
let chest_back_mat = Mat4::<f32>::from(self.chest_back);
|
||||
let head_mat = Mat4::<f32>::from(self.head);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.head)),
|
||||
make_bone(torso_mat),
|
||||
make_bone(rear_mat),
|
||||
make_bone(rear_mat * Mat4::<f32>::from(self.tail)),
|
||||
make_bone(rear_mat * Mat4::<f32>::from(self.fin_l)),
|
||||
make_bone(rear_mat * Mat4::<f32>::from(self.fin_r)),
|
||||
make_bone(chest_front_mat * head_mat),
|
||||
make_bone(chest_front_mat * head_mat * Mat4::<f32>::from(self.jaw)),
|
||||
make_bone(chest_front_mat),
|
||||
make_bone(chest_front_mat * chest_back_mat),
|
||||
make_bone(chest_front_mat * chest_back_mat * Mat4::<f32>::from(self.tail)),
|
||||
make_bone(chest_front_mat * Mat4::<f32>::from(self.fin_l)),
|
||||
make_bone(chest_front_mat * Mat4::<f32>::from(self.fin_r)),
|
||||
];
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkeletonAttr;
|
||||
pub struct SkeletonAttr {
|
||||
head: (f32, f32),
|
||||
jaw: (f32, f32),
|
||||
chest_front: (f32, f32),
|
||||
chest_back: (f32, f32),
|
||||
tail: (f32, f32),
|
||||
fin: (f32, f32, f32),
|
||||
tempo: f32,
|
||||
amplitude: f32,
|
||||
}
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
type Error = ();
|
||||
@ -63,9 +74,48 @@ impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
head: (0.0, 0.0),
|
||||
jaw: (0.0, 0.0),
|
||||
chest_front: (0.0, 0.0),
|
||||
chest_back: (0.0, 0.0),
|
||||
tail: (0.0, 0.0),
|
||||
fin: (0.0, 0.0, 0.0),
|
||||
tempo: 0.0,
|
||||
amplitude: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::fish_medium::Species::*;
|
||||
Self {
|
||||
head: match (body.species, body.body_type) {
|
||||
(Marlin, _) => (2.0, 1.5),
|
||||
},
|
||||
jaw: match (body.species, body.body_type) {
|
||||
(Marlin, _) => (2.5, -3.0),
|
||||
},
|
||||
chest_front: match (body.species, body.body_type) {
|
||||
(Marlin, _) => (0.0, 2.5),
|
||||
},
|
||||
chest_back: match (body.species, body.body_type) {
|
||||
(Marlin, _) => (-1.0, 1.0),
|
||||
},
|
||||
tail: match (body.species, body.body_type) {
|
||||
(Marlin, _) => (-7.0, 0.0),
|
||||
},
|
||||
fin: match (body.species, body.body_type) {
|
||||
(Marlin, _) => (2.5, 1.0, 3.5),
|
||||
},
|
||||
tempo: match (body.species, body.body_type) {
|
||||
(Marlin, _) => 4.0,
|
||||
},
|
||||
amplitude: match (body.species, body.body_type) {
|
||||
(Marlin, _) => 4.0,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
use super::{super::Animation, FishMediumSkeleton, SkeletonAttr};
|
||||
//use std::f32::consts::PI;
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct RunAnimation;
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Dependency = (f32, f64);
|
||||
type Skeleton = FishMediumSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_medium_run\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_medium_run")]
|
||||
fn update_skeleton_inner(
|
||||
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.scale = Vec3::one() / 10.88;
|
||||
next.torso.scale = Vec3::one() * 1.01;
|
||||
next.rear.scale = Vec3::one() * 0.98;
|
||||
next.tail.scale = Vec3::one() / 11.0;
|
||||
next.fin_l.scale = Vec3::one() / 11.0;
|
||||
next.fin_r.scale = Vec3::one() / 10.5;
|
||||
|
||||
next.head.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 4.5, 2.0);
|
||||
next.torso.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.rear.position = Vec3::new(0.0, 3.1, -4.5);
|
||||
next.rear.orientation = Quaternion::rotation_z(0.0);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, -13.0, 8.0) / 11.0;
|
||||
next.tail.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
|
||||
next.fin_l.position = Vec3::new(0.0, -11.7, 11.0) / 11.0;
|
||||
next.fin_l.orientation = Quaternion::rotation_y(0.0);
|
||||
|
||||
next.fin_r.position = Vec3::new(0.0, 0.0, 12.0) / 11.0;
|
||||
next.fin_r.orientation = Quaternion::rotation_y(0.0);
|
||||
next
|
||||
}
|
||||
}
|
74
voxygen/anim/src/fish_medium/swim.rs
Normal file
74
voxygen/anim/src/fish_medium/swim.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
FishMediumSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct SwimAnimation;
|
||||
|
||||
type SwimAnimationDependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64, Vec3<f32>, f32);
|
||||
|
||||
impl Animation for SwimAnimation {
|
||||
type Dependency = SwimAnimationDependency;
|
||||
type Skeleton = FishMediumSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_medium_swim\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_medium_swim")]
|
||||
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(velocity, orientation, last_ori, _global_time, avg_vel, acc_vel): Self::Dependency,
|
||||
_anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let slowalt = (acc_vel as f32 * s_a.tempo / 1.5 + PI + 0.2).sin();
|
||||
let fast = (acc_vel * s_a.tempo + PI).sin();
|
||||
let fastalt = (acc_vel * s_a.tempo + PI + 0.2).sin();
|
||||
|
||||
let ori: Vec2<f32> = Vec2::from(orientation);
|
||||
let last_ori = Vec2::from(last_ori);
|
||||
let tilt = if ::vek::Vec2::new(ori, last_ori)
|
||||
.map(|o| o.magnitude_squared())
|
||||
.map(|m| m > 0.001 && m.is_finite())
|
||||
.reduce_and()
|
||||
&& ori.angle_between(last_ori).is_finite()
|
||||
{
|
||||
ori.angle_between(last_ori).min(0.8)
|
||||
* last_ori.determine_side(Vec2::zero(), ori).signum()
|
||||
} else {
|
||||
0.0
|
||||
} * 1.3;
|
||||
let x_tilt = avg_vel.z.atan2(avg_vel.xy().magnitude());
|
||||
let vel = (velocity.magnitude()).min(s_a.amplitude);
|
||||
let slowvel = vel * 0.1;
|
||||
|
||||
next.chest_front.scale = Vec3::one() / 11.0;
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_z(slowalt * -0.1 + tilt * -2.0);
|
||||
|
||||
next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1);
|
||||
|
||||
next.chest_front.position = Vec3::new(0.0, s_a.chest_front.0, s_a.chest_front.1) / 11.0;
|
||||
next.chest_front.orientation = Quaternion::rotation_x(velocity.z.abs() * -0.005 + x_tilt)
|
||||
* Quaternion::rotation_z(fast * vel * -0.02);
|
||||
|
||||
next.chest_back.position = Vec3::new(0.0, s_a.chest_back.0, s_a.chest_back.1);
|
||||
next.chest_back.orientation = Quaternion::rotation_z(fastalt * slowvel + tilt * 2.0);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
|
||||
next.tail.orientation = Quaternion::rotation_z(fast * slowvel + tilt * 2.0);
|
||||
|
||||
next.fin_l.position = Vec3::new(-s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_l.orientation = Quaternion::rotation_z(fast * slowvel - 0.1 + tilt * -0.5);
|
||||
|
||||
next.fin_r.position = Vec3::new(s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_r.orientation = Quaternion::rotation_z(fast * -slowvel + 0.1 + tilt * -0.5);
|
||||
next
|
||||
}
|
||||
}
|
@ -1,34 +1,45 @@
|
||||
use super::{super::Animation, FishSmallSkeleton, SkeletonAttr};
|
||||
//use std::{f32::consts::PI, ops::Mul};
|
||||
use super::super::vek::*;
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
FishSmallSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct IdleAnimation;
|
||||
|
||||
type IdleAnimationDependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64, Vec3<f32>);
|
||||
|
||||
impl Animation for IdleAnimation {
|
||||
type Dependency = f64;
|
||||
type Dependency = IdleAnimationDependency;
|
||||
type Skeleton = FishSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_small_idle\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_small_idle")]
|
||||
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
_global_time: Self::Dependency,
|
||||
_anim_time: f64,
|
||||
(_velocity, _orientation, _last_ori, _global_time, _avg_vel): Self::Dependency,
|
||||
anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 10.88;
|
||||
let slow = (anim_time as f32 * 3.5 + PI).sin();
|
||||
|
||||
next.tail.position = Vec3::new(0.0, 4.5, 2.0);
|
||||
next.tail.orientation = Quaternion::rotation_x(0.0);
|
||||
next.tail.scale = Vec3::one() * 1.01;
|
||||
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.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
|
||||
next.tail.orientation = Quaternion::rotation_z(slow * 0.1);
|
||||
|
||||
next.fin_l.position = Vec3::new(-s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_l.orientation = Quaternion::rotation_z(slow * 0.1 - 0.1);
|
||||
|
||||
next.fin_r.position = Vec3::new(s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_r.orientation = Quaternion::rotation_z(-slow * 0.1 + 0.1);
|
||||
next
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
use super::{super::Animation, FishSmallSkeleton, SkeletonAttr};
|
||||
//use std::f32::consts::PI;
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct JumpAnimation;
|
||||
|
||||
impl Animation for JumpAnimation {
|
||||
type Dependency = (f32, f64);
|
||||
type Skeleton = FishSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_small_jump\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_small_jump")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
_global_time: Self::Dependency,
|
||||
_anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.tail.position = Vec3::new(0.0, 4.5, 2.0);
|
||||
next.tail.orientation = Quaternion::rotation_x(0.0);
|
||||
next.tail.scale = Vec3::one() * 1.01;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
pub mod idle;
|
||||
pub mod jump;
|
||||
pub mod run;
|
||||
pub mod swim;
|
||||
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
pub use self::{idle::IdleAnimation, swim::SwimAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
@ -12,36 +11,45 @@ use core::convert::TryFrom;
|
||||
pub type Body = comp::fish_small::Body;
|
||||
|
||||
skeleton_impls!(struct FishSmallSkeleton {
|
||||
+ torso,
|
||||
+ chest,
|
||||
+ tail,
|
||||
+ fin_l,
|
||||
+ fin_r,
|
||||
});
|
||||
|
||||
impl Skeleton for FishSmallSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 2;
|
||||
const BONE_COUNT: usize = 4;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const COMPUTE_FN: &'static [u8] = b"fish_small_compute_mats\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_small_compute_mats")]
|
||||
|
||||
fn compute_matrices_inner(
|
||||
&self,
|
||||
base_mat: Mat4<f32>,
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
) -> Vec3<f32> {
|
||||
let torso_mat = base_mat * Mat4::<f32>::from(self.torso);
|
||||
let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(torso_mat),
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.tail)),
|
||||
make_bone(chest_mat),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.tail)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.fin_l)),
|
||||
make_bone(chest_mat * Mat4::<f32>::from(self.fin_r)),
|
||||
];
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkeletonAttr;
|
||||
pub struct SkeletonAttr {
|
||||
chest: (f32, f32),
|
||||
tail: (f32, f32),
|
||||
fin: (f32, f32, f32),
|
||||
tempo: f32,
|
||||
amplitude: f32,
|
||||
}
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
type Error = ();
|
||||
@ -55,9 +63,36 @@ impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
chest: (0.0, 0.0),
|
||||
tail: (0.0, 0.0),
|
||||
fin: (0.0, 0.0, 0.0),
|
||||
tempo: 0.0,
|
||||
amplitude: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::fish_small::Species::*;
|
||||
Self {
|
||||
chest: match (body.species, body.body_type) {
|
||||
(Clownfish, _) => (0.0, 5.0),
|
||||
},
|
||||
tail: match (body.species, body.body_type) {
|
||||
(Clownfish, _) => (-7.5, -0.5),
|
||||
},
|
||||
fin: match (body.species, body.body_type) {
|
||||
(Clownfish, _) => (2.0, 0.5, 1.0),
|
||||
},
|
||||
tempo: match (body.species, body.body_type) {
|
||||
(Clownfish, _) => 5.0,
|
||||
},
|
||||
amplitude: match (body.species, body.body_type) {
|
||||
(Clownfish, _) => 4.0,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
use super::{super::Animation, FishSmallSkeleton, SkeletonAttr};
|
||||
//use std::{f32::consts::PI, ops::Mul};
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct RunAnimation;
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Dependency = (f32, f64);
|
||||
type Skeleton = FishSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_small_run\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_small_run")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(_velocity, _global_time): Self::Dependency,
|
||||
_anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.tail.position = Vec3::new(0.0, 4.5, 2.0);
|
||||
next.tail.orientation = Quaternion::rotation_x(0.0);
|
||||
next.tail.scale = Vec3::one() * 1.01;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
64
voxygen/anim/src/fish_small/swim.rs
Normal file
64
voxygen/anim/src/fish_small/swim.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
FishSmallSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct SwimAnimation;
|
||||
|
||||
type SwimAnimationDependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f64, Vec3<f32>, f32);
|
||||
|
||||
impl Animation for SwimAnimation {
|
||||
type Dependency = SwimAnimationDependency;
|
||||
type Skeleton = FishSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"fish_small_swim\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "fish_small_swim")]
|
||||
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(velocity, orientation, last_ori, _global_time, avg_vel, acc_vel): Self::Dependency,
|
||||
_anim_time: f64,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let fast = (acc_vel * s_a.tempo + PI).sin();
|
||||
|
||||
let ori: Vec2<f32> = Vec2::from(orientation);
|
||||
let last_ori = Vec2::from(last_ori);
|
||||
let tilt = if ::vek::Vec2::new(ori, last_ori)
|
||||
.map(|o| o.magnitude_squared())
|
||||
.map(|m| m > 0.001 && m.is_finite())
|
||||
.reduce_and()
|
||||
&& ori.angle_between(last_ori).is_finite()
|
||||
{
|
||||
ori.angle_between(last_ori).min(0.8)
|
||||
* last_ori.determine_side(Vec2::zero(), ori).signum()
|
||||
} else {
|
||||
0.0
|
||||
} * 1.3;
|
||||
let x_tilt = avg_vel.z.atan2(avg_vel.xy().magnitude());
|
||||
let vel = (velocity.magnitude()).min(s_a.amplitude);
|
||||
let slowvel = vel * 0.1;
|
||||
|
||||
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.chest.orientation = Quaternion::rotation_x(velocity.z.abs() * -0.005 + x_tilt)
|
||||
* Quaternion::rotation_z(fast * -0.1);
|
||||
|
||||
next.tail.position = Vec3::new(0.0, s_a.tail.0, s_a.tail.1);
|
||||
next.tail.orientation = Quaternion::rotation_z(fast * -1.0 * slowvel + tilt * 2.0);
|
||||
|
||||
next.fin_l.position = Vec3::new(-s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_l.orientation = Quaternion::rotation_z(fast * 0.6 * slowvel - 0.3 + tilt * -0.5);
|
||||
|
||||
next.fin_r.position = Vec3::new(s_a.fin.0, s_a.fin.1, s_a.fin.2);
|
||||
next.fin_r.orientation = Quaternion::rotation_z(fast * -0.6 * slowvel + 0.3 + tilt * -0.5);
|
||||
next
|
||||
}
|
||||
}
|
@ -6,7 +6,8 @@ use common::{
|
||||
bird_medium::{self, BodyType as BMBodyType, Species as BMSpecies},
|
||||
bird_small,
|
||||
dragon::{self, BodyType as DBodyType, Species as DSpecies},
|
||||
fish_medium, fish_small,
|
||||
fish_medium::{self, BodyType as FMBodyType, Species as FMSpecies},
|
||||
fish_small::{self, BodyType as FSBodyType, Species as FSSpecies},
|
||||
golem::{self, BodyType as GBodyType, Species as GSpecies},
|
||||
humanoid::{self, Body, BodyType, EyeColor, Skin, Species},
|
||||
object,
|
||||
@ -2086,17 +2087,253 @@ impl TheropodLateralSpec {
|
||||
}
|
||||
}
|
||||
////
|
||||
#[derive(Deserialize)]
|
||||
struct FishMediumCentralSpec(HashMap<(FMSpecies, FMBodyType), SidedFMCentralVoxSpec>);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SidedFMCentralVoxSpec {
|
||||
head: FishMediumCentralSubSpec,
|
||||
jaw: FishMediumCentralSubSpec,
|
||||
chest_front: FishMediumCentralSubSpec,
|
||||
chest_back: FishMediumCentralSubSpec,
|
||||
tail: FishMediumCentralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct FishMediumCentralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
central: VoxSimple,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct FishMediumLateralSpec(HashMap<(FMSpecies, FMBodyType), SidedFMLateralVoxSpec>);
|
||||
#[derive(Deserialize)]
|
||||
struct SidedFMLateralVoxSpec {
|
||||
fin_l: FishMediumLateralSubSpec,
|
||||
fin_r: FishMediumLateralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct FishMediumLateralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
lateral: VoxSimple,
|
||||
}
|
||||
|
||||
make_vox_spec!(
|
||||
fish_medium::Body,
|
||||
struct FishMediumSpec {},
|
||||
|FigureKey { body, .. }, _spec| {
|
||||
struct FishMediumSpec {
|
||||
central: FishMediumCentralSpec = "voxygen.voxel.fish_medium_central_manifest",
|
||||
lateral: FishMediumLateralSpec = "voxygen.voxel.fish_medium_lateral_manifest",
|
||||
},
|
||||
|FigureKey { body, .. }, spec| {
|
||||
[
|
||||
Some(mesh_fish_medium_head(body.head)),
|
||||
Some(mesh_fish_medium_torso(body.torso)),
|
||||
Some(mesh_fish_medium_rear(body.rear)),
|
||||
Some(mesh_fish_medium_tail(body.tail)),
|
||||
Some(mesh_fish_medium_fin_l(body.fin_l)),
|
||||
Some(mesh_fish_medium_fin_r(body.fin_r)),
|
||||
Some(spec.central.asset.mesh_head(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.asset.mesh_jaw(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.asset.mesh_chest_front(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.asset.mesh_chest_back(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.asset.mesh_tail(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.asset.mesh_fin_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.asset.mesh_fin_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
impl FishMediumCentralSpec {
|
||||
fn mesh_head(&self, species: FMSpecies, body_type: FMBodyType) -> 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_jaw(&self, species: FMSpecies, body_type: FMBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No jaw 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.jaw.central.0);
|
||||
|
||||
(central, Vec3::from(spec.jaw.offset))
|
||||
}
|
||||
|
||||
fn mesh_chest_front(&self, species: FMSpecies, body_type: FMBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No front 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_front.central.0);
|
||||
|
||||
(central, Vec3::from(spec.chest_front.offset))
|
||||
}
|
||||
|
||||
fn mesh_chest_back(&self, species: FMSpecies, body_type: FMBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No back 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_back.central.0);
|
||||
|
||||
(central, Vec3::from(spec.chest_back.offset))
|
||||
}
|
||||
|
||||
fn mesh_tail(&self, species: FMSpecies, body_type: FMBodyType) -> 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))
|
||||
}
|
||||
}
|
||||
|
||||
impl FishMediumLateralSpec {
|
||||
fn mesh_fin_l(&self, species: FMSpecies, body_type: FMBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No fin 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.fin_l.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.fin_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_fin_r(&self, species: FMSpecies, body_type: FMBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No fin 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.fin_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.fin_r.offset))
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
#[derive(Deserialize)]
|
||||
struct FishSmallCentralSpec(HashMap<(FSSpecies, FSBodyType), SidedFSCentralVoxSpec>);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SidedFSCentralVoxSpec {
|
||||
chest: FishSmallCentralSubSpec,
|
||||
tail: FishSmallCentralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct FishSmallCentralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
central: VoxSimple,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct FishSmallLateralSpec(HashMap<(FSSpecies, FSBodyType), SidedFSLateralVoxSpec>);
|
||||
#[derive(Deserialize)]
|
||||
struct SidedFSLateralVoxSpec {
|
||||
fin_l: FishSmallLateralSubSpec,
|
||||
fin_r: FishSmallLateralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct FishSmallLateralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
lateral: VoxSimple,
|
||||
}
|
||||
|
||||
make_vox_spec!(
|
||||
fish_small::Body,
|
||||
struct FishSmallSpec {
|
||||
central: FishSmallCentralSpec = "voxygen.voxel.fish_small_central_manifest",
|
||||
lateral: FishSmallLateralSpec = "voxygen.voxel.fish_small_lateral_manifest",
|
||||
},
|
||||
|FigureKey { body, .. }, spec| {
|
||||
[
|
||||
Some(spec.central.asset.mesh_chest(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.asset.mesh_tail(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.asset.mesh_fin_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.asset.mesh_fin_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
@ -2111,58 +2348,72 @@ make_vox_spec!(
|
||||
},
|
||||
);
|
||||
|
||||
fn mesh_fish_medium_head(head: fish_medium::Head) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match head {
|
||||
fish_medium::Head::Default => "npc.marlin.head",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
impl FishSmallCentralSpec {
|
||||
fn mesh_chest(&self, species: FSSpecies, body_type: FSBodyType) -> 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_tail(&self, species: FSSpecies, body_type: FSBodyType) -> 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_fish_medium_torso(torso: fish_medium::Torso) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match torso {
|
||||
fish_medium::Torso::Default => "npc.marlin.torso",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
impl FishSmallLateralSpec {
|
||||
fn mesh_fin_l(&self, species: FSSpecies, body_type: FSBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No fin 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.fin_l.lateral.0);
|
||||
|
||||
fn mesh_fish_medium_rear(rear: fish_medium::Rear) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match rear {
|
||||
fish_medium::Rear::Default => "npc.marlin.rear",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
(lateral, Vec3::from(spec.fin_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_fish_medium_tail(tail: fish_medium::Tail) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match tail {
|
||||
fish_medium::Tail::Default => "npc.marlin.tail",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
fn mesh_fin_r(&self, species: FSSpecies, body_type: FSBodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No fin 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.fin_r.lateral.0);
|
||||
|
||||
fn mesh_fish_medium_fin_l(fin_l: fish_medium::FinL) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match fin_l {
|
||||
fish_medium::FinL::Default => "npc.marlin.fin_l",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
|
||||
fn mesh_fish_medium_fin_r(fin_r: fish_medium::FinR) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match fin_r {
|
||||
fish_medium::FinR::Default => "npc.marlin.fin_r",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
(lateral, Vec3::from(spec.fin_r.offset))
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
@ -2583,49 +2834,7 @@ fn mesh_bird_small_wing_r(wing_r: bird_small::WingR) -> BoneMeshes {
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
////
|
||||
make_vox_spec!(
|
||||
fish_small::Body,
|
||||
struct FishSmallSpec {},
|
||||
|FigureKey { body, .. }, _spec| {
|
||||
[
|
||||
Some(mesh_fish_small_torso(body.torso)),
|
||||
Some(mesh_fish_small_tail(body.tail)),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
fn mesh_fish_small_torso(torso: fish_small::Torso) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match torso {
|
||||
fish_small::Torso::Default => "npc.cardinalfish.torso",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
|
||||
fn mesh_fish_small_tail(tail: fish_small::Tail) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match tail {
|
||||
fish_small::Tail::Default => "npc.cardinalfish.tail",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
////
|
||||
#[derive(Deserialize)]
|
||||
struct BipedLargeCentralSpec(HashMap<(BLSpecies, BLBodyType), SidedBLCentralVoxSpec>);
|
||||
|
@ -2179,35 +2179,25 @@ impl FigureMgr {
|
||||
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||
physics.in_liquid.is_some(), // In water
|
||||
) {
|
||||
// Standing
|
||||
(true, false, false) => anim::fish_medium::IdleAnimation::update_skeleton(
|
||||
// Idle
|
||||
(_, false, _) => anim::fish_medium::IdleAnimation::update_skeleton(
|
||||
&FishMediumSkeleton::default(),
|
||||
time,
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Running
|
||||
(true, true, false) => anim::fish_medium::RunAnimation::update_skeleton(
|
||||
// Swim
|
||||
(_, true, _) => anim::fish_medium::SwimAnimation::update_skeleton(
|
||||
&FishMediumSkeleton::default(),
|
||||
(vel.0.magnitude(), time),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// In air
|
||||
(false, _, false) => anim::fish_medium::JumpAnimation::update_skeleton(
|
||||
&FishMediumSkeleton::default(),
|
||||
(vel.0.magnitude(), time),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
|
||||
// TODO!
|
||||
_ => anim::fish_medium::IdleAnimation::update_skeleton(
|
||||
&FishMediumSkeleton::default(),
|
||||
time,
|
||||
(
|
||||
vel.0,
|
||||
ori,
|
||||
state.last_ori,
|
||||
time,
|
||||
state.avg_vel,
|
||||
state.acc_vel,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
@ -2574,35 +2564,25 @@ impl FigureMgr {
|
||||
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||
physics.in_liquid.is_some(), // In water
|
||||
) {
|
||||
// Standing
|
||||
(true, false, false) => anim::fish_small::IdleAnimation::update_skeleton(
|
||||
// Idle
|
||||
(_, false, _) => anim::fish_small::IdleAnimation::update_skeleton(
|
||||
&FishSmallSkeleton::default(),
|
||||
time,
|
||||
(vel.0, ori, state.last_ori, time, state.avg_vel),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Running
|
||||
(true, true, false) => anim::fish_small::RunAnimation::update_skeleton(
|
||||
// Swim
|
||||
(_, true, _) => anim::fish_small::SwimAnimation::update_skeleton(
|
||||
&FishSmallSkeleton::default(),
|
||||
(vel.0.magnitude(), time),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// In air
|
||||
(false, _, false) => anim::fish_small::JumpAnimation::update_skeleton(
|
||||
&FishSmallSkeleton::default(),
|
||||
(vel.0.magnitude(), time),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
|
||||
// TODO!
|
||||
_ => anim::fish_small::IdleAnimation::update_skeleton(
|
||||
&FishSmallSkeleton::default(),
|
||||
time,
|
||||
(
|
||||
vel.0,
|
||||
ori,
|
||||
state.last_ori,
|
||||
time,
|
||||
state.avg_vel,
|
||||
state.acc_vel,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
@ -3761,6 +3741,7 @@ pub struct FigureStateMeta {
|
||||
avg_vel: anim::vek::Vec3<f32>,
|
||||
last_light: f32,
|
||||
last_glow: f32,
|
||||
acc_vel: f32,
|
||||
}
|
||||
|
||||
impl FigureStateMeta {
|
||||
@ -3807,6 +3788,7 @@ impl<S: Skeleton> FigureState<S> {
|
||||
avg_vel: anim::vek::Vec3::zero(),
|
||||
last_light: 1.0,
|
||||
last_glow: 0.0,
|
||||
acc_vel: 0.0,
|
||||
},
|
||||
skeleton,
|
||||
}
|
||||
@ -3935,6 +3917,13 @@ impl<S: Skeleton> FigureState<S> {
|
||||
self.avg_vel = (1.0 - smoothing) * self.avg_vel + smoothing * (pos - last_pos) / dt;
|
||||
}
|
||||
self.last_pos = Some(pos);
|
||||
|
||||
// Can potentially overflow
|
||||
if self.avg_vel.magnitude_squared() != 0.0 {
|
||||
self.acc_vel += self.avg_vel.magnitude() * dt;
|
||||
} else {
|
||||
self.acc_vel = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn locals(&self) -> &Consts<FigureLocals> { &self.locals }
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{column::ColumnSample, sim::SimChunk, IndexRef, CONFIG};
|
||||
use common::{
|
||||
comp::{
|
||||
biped_large, bird_medium, quadruped_low, quadruped_medium, quadruped_small, theropod,
|
||||
Alignment,
|
||||
biped_large, bird_medium, fish_medium, fish_small, quadruped_low, quadruped_medium,
|
||||
quadruped_small, theropod, Alignment,
|
||||
},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
terrain::Block,
|
||||
@ -50,10 +50,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
1 => {
|
||||
theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into()
|
||||
},
|
||||
_ => quadruped_medium::Body::random_with(
|
||||
rng,
|
||||
&quadruped_medium::Species::Roshwalr,
|
||||
)
|
||||
_ => quadruped_medium::Body {
|
||||
species: quadruped_medium::Species::Roshwalr,
|
||||
body_type: quadruped_medium::BodyType::Male,
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
.with_alignment(Alignment::Enemy)
|
||||
@ -697,7 +697,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
* 0.2
|
||||
},
|
||||
},
|
||||
// Desert river solitary wild
|
||||
// Desert river solitary enemy
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
@ -718,6 +718,28 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
}
|
||||
},
|
||||
},
|
||||
// Desert secret solitary enemy
|
||||
Entry {
|
||||
make_entity: |pos, _rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(
|
||||
quadruped_medium::Body {
|
||||
species: quadruped_medium::Species::Roshwalr,
|
||||
body_type: quadruped_medium::BodyType::Female,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.with_alignment(Alignment::Enemy)
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: false,
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.5)
|
||||
* BASE_DENSITY
|
||||
* 0.01
|
||||
},
|
||||
},
|
||||
// Desert solitary wild
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
@ -761,6 +783,24 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 5.0
|
||||
},
|
||||
},
|
||||
// Underwater
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(match rng.gen_range(0, 2) {
|
||||
0 => fish_medium::Body::random_with(rng, &fish_medium::Species::Marlin)
|
||||
.into(),
|
||||
_ => fish_small::Body::random_with(rng, &fish_small::Species::Clownfish)
|
||||
.into(),
|
||||
})
|
||||
.with_alignment(Alignment::Wild)
|
||||
},
|
||||
group_size: 3..5,
|
||||
is_underwater: true,
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.temperate_temp, 1.0) * col.tree_density * BASE_DENSITY * 5.0
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
for y in 0..vol.size_xy().y as i32 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user