Dragon work

This commit is contained in:
Robin Gilh 2020-04-25 15:20:37 +02:00 committed by jshipsey
parent 59c97731ad
commit 40360ff149
41 changed files with 713 additions and 318 deletions

View File

@ -539,5 +539,19 @@
"generic": "Fungome"
}
}
},
"dragon": {
"body": {
"keyword": "dragon",
"names": [
"Smaug"
]
},
"species": {
"reddragon": {
"keyword": "reddragon",
"generic": "Reddragon"
}
}
}
}

View File

@ -0,0 +1,46 @@
({
(Reddragon, Male): (
head: (
offset: (-7.0, -9.0, -5.5),
center: ("npc.reddragon.male.head"),
),
chest_front: (
offset: (-7.0, 4.5, 5.0),
center: ("npc.reddragon.male.chest_front"),
),
chest_rear: (
offset: (-7.0, -4.5, 5.0),
center: ("npc.reddragon.male.chest_rear"),
),
tail_front: (
offset: (-7.0, -4.5, -5.0),
center: ("npc.reddragon.male.tail_front"),
),
tail_rear: (
offset: (-7.0, -4.5, -5.0),
center: ("npc.reddragon.male.tail_rear"),
)
),
(Reddragon, Female): (
head: (
offset: (-7.0, -9.0, -5.5),
center: ("npc.reddragon.female.head"),
),
chest_front: (
offset: (-7.0, 4.5, 5.0),
center: ("npc.reddragon.female.chest_front"),
),
chest_rear: (
offset: (-7.0, -4.5, 5.0),
center: ("npc.reddragon.female.chest_rear"),
),
tail_front: (
offset: (-7.0, -4.5, -5.0),
center: ("npc.reddragon.female.tail_front"),
),
tail_rear: (
offset: (-7.0, -4.5, -5.0),
center: ("npc.reddragon.female.tail_rear"),
)
),
})

View File

@ -0,0 +1,70 @@
({
(Reddragon, Male): (
wing_in_l: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.male.wing_in_l"),
),
wing_in_r: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.male.wing_in_r"),
),
wing_out_l: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.male.wing_out_l"),
),
wing_out_r: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.male.wing_out_r"),
),
foot_fl: (
offset: (-2.5, -4.0, -1.5),
lateral: ("npc.reddragon.male.foot_fl"),
),
foot_fr: (
offset: (-2.5, -4.0, -1.5),
lateral: ("npc.reddragon.male.foot_fr"),
),
foot_bl: (
offset: (-2.5, -4.0, -3.0),
lateral: ("npc.reddragon.male.foot_bl"),
),
foot_br: (
offset: (-2.5, -4.0, -3.0),
lateral: ("npc.reddragon.male.foot_br"),
)
),
(Reddragon, Female): (
wing_in_l: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.female.wing_in_l"),
),
wing_in_r: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.female.wing_in_r"),
),
wing_out_l: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.female.wing_out_l"),
),
wing_out_r: (
offset: (20.0, 20.0, 5.0),
lateral: ("npc.reddragon.female.wing_out_r"),
),
foot_fl: (
offset: (-2.5, -4.0, -1.5),
lateral: ("npc.reddragon.female.foot_fl"),
),
foot_fr: (
offset: (-2.5, -4.0, -1.5),
lateral: ("npc.reddragon.female.foot_fr"),
),
foot_bl: (
offset: (-2.5, -4.0, -3.0),
lateral: ("npc.reddragon.female.foot_bl"),
),
foot_br: (
offset: (-2.5, -4.0, -3.0),
lateral: ("npc.reddragon.female.foot_br"),
)
),
})

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

View File

@ -60,6 +60,7 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
pub critter: BodyData<BodyMeta, critter::AllSpecies<SpeciesMeta>>,
pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
}
/// Can only retrieve body metadata by direct index.
@ -76,6 +77,7 @@ impl<BodyMeta, SpeciesMeta> core::ops::Index<NpcKind> for AllBodies<BodyMeta, Sp
NpcKind::Ogre => &self.biped_large.body,
NpcKind::StoneGolem => &self.golem.body,
NpcKind::Rat => &self.critter.body,
NpcKind::Reddragon => &self.dragon.body,
}
}
}

View File

@ -2,128 +2,69 @@ use rand::{seq::SliceRandom, thread_rng};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Body {
pub head: Head,
pub chest_front: ChestFront,
pub chest_rear: ChestRear,
pub tail_front: TailFront,
pub tail_rear: TailRear,
pub wing_in_l: WingInL,
pub wing_in_r: WingInR,
pub wing_out_l: WingOutL,
pub wing_out_r: WingOutR,
pub foot_fl: FootFL,
pub foot_fr: FootFR,
pub foot_bl: FootBL,
pub foot_br: FootBR,
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(),
chest_front: *(&ALL_CHEST_FRONTS).choose(&mut rng).unwrap(),
chest_rear: *(&ALL_CHEST_REARS).choose(&mut rng).unwrap(),
tail_front: *(&ALL_TAIL_FRONTS).choose(&mut rng).unwrap(),
tail_rear: *(&ALL_TAIL_REARS).choose(&mut rng).unwrap(),
wing_in_l: *(&ALL_WING_IN_LS).choose(&mut rng).unwrap(),
wing_in_r: *(&ALL_WING_IN_RS).choose(&mut rng).unwrap(),
wing_out_l: *(&ALL_WING_OUT_LS).choose(&mut rng).unwrap(),
wing_out_r: *(&ALL_WING_OUT_RS).choose(&mut rng).unwrap(),
foot_fl: *(&ALL_FOOT_FLS).choose(&mut rng).unwrap(),
foot_fr: *(&ALL_FOOT_FRS).choose(&mut rng).unwrap(),
foot_bl: *(&ALL_FOOT_BLS).choose(&mut rng).unwrap(),
foot_br: *(&ALL_FOOT_BRS).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::Dragon(body) }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Species {
Reddragon = 0,
}
/// Data representing per-species generic data.
///
/// NOTE: Deliberately don't (yet?) implement serialize.
#[derive(Clone, Debug, Deserialize)]
pub struct AllSpecies<SpeciesMeta> {
pub reddragon: 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::Reddragon => &self.reddragon,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Head {
Default,
pub const ALL_SPECIES: [Species; 1] = [
Species::Reddragon,
];
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
type Item = Species;
type IntoIter = impl Iterator<Item = Self::Item>;
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
}
const ALL_HEADS: [Head; 1] = [Head::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum ChestFront {
Default,
pub enum BodyType {
Female = 0,
Male = 1,
}
const ALL_CHEST_FRONTS: [ChestFront; 1] = [ChestFront::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum ChestRear {
Default,
}
const ALL_CHEST_REARS: [ChestRear; 1] = [ChestRear::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum TailFront {
Default,
}
const ALL_TAIL_FRONTS: [TailFront; 1] = [TailFront::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum TailRear {
Default,
}
const ALL_TAIL_REARS: [TailRear; 1] = [TailRear::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum WingInL {
Default,
}
const ALL_WING_IN_LS: [WingInL; 1] = [WingInL::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum WingInR {
Default,
}
const ALL_WING_IN_RS: [WingInR; 1] = [WingInR::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum WingOutL {
Default,
}
const ALL_WING_OUT_LS: [WingOutL; 1] = [WingOutL::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum WingOutR {
Default,
}
const ALL_WING_OUT_RS: [WingOutR; 1] = [WingOutR::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum FootFL {
Default,
}
const ALL_FOOT_FLS: [FootFL; 1] = [FootFL::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum FootFR {
Default,
}
const ALL_FOOT_FRS: [FootFR; 1] = [FootFR::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum FootBL {
Default,
}
const ALL_FOOT_BLS: [FootBL; 1] = [FootBL::Default];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum FootBR {
Default,
}
const ALL_FOOT_BRS: [FootBR; 1] = [FootBR::Default];
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];

View File

@ -79,6 +79,9 @@ impl EntityInfo {
Body::QuadrupedSmall(body) => {
Some(get_npc_name(&NPC_NAMES.quadruped_small, body.species))
},
Body::Dragon(body) => {
Some(get_npc_name(&NPC_NAMES.dragon, body.species))
},
_ => None,
}
.map(|s| {

View File

@ -15,9 +15,10 @@ pub enum NpcKind {
Ogre,
Rat,
StoneGolem,
Reddragon,
}
pub const ALL_NPCS: [NpcKind; 7] = [
pub const ALL_NPCS: [NpcKind; 8] = [
NpcKind::Humanoid,
NpcKind::Wolf,
NpcKind::Pig,
@ -25,6 +26,7 @@ pub const ALL_NPCS: [NpcKind; 7] = [
NpcKind::Ogre,
NpcKind::Rat,
NpcKind::StoneGolem,
NpcKind::Reddragon,
];
/// Body-specific NPC name metadata.
@ -91,6 +93,7 @@ pub fn kind_to_body(kind: NpcKind) -> Body {
NpcKind::Ogre => comp::biped_large::Body::random().into(),
NpcKind::Rat => comp::critter::Body::random().into(),
NpcKind::StoneGolem => comp::golem::Body::random().into(),
NpcKind::Reddragon => comp::critter::Body::random().into(),
}
}
@ -212,6 +215,14 @@ impl NpcBody {
comp::golem::Body::random_with,
)
})
.or_else(|| {
parse(
s,
NpcKind::Reddragon,
&npc_names.dragon,
comp::dragon::Body::random_with,
)
})
.ok_or(())
}
}

View File

@ -10,7 +10,7 @@ use crate::render::FigureBoneData;
use common::comp::{self};
use vek::Vec3;
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct DragonSkeleton {
head: Bone,
chest_front: Bone,
@ -28,23 +28,7 @@ pub struct DragonSkeleton {
}
impl DragonSkeleton {
pub fn new() -> Self {
Self {
head: Bone::default(),
chest_front: Bone::default(),
chest_rear: Bone::default(),
tail_front: Bone::default(),
tail_rear: Bone::default(),
wing_in_l: Bone::default(),
wing_in_r: Bone::default(),
wing_out_l: Bone::default(),
wing_out_r: Bone::default(),
foot_fl: Bone::default(),
foot_fr: Bone::default(),
foot_bl: Bone::default(),
foot_br: Bone::default(),
}
}
pub fn new() -> Self { Self::default() }
}
impl Skeleton for DragonSkeleton {
@ -98,7 +82,17 @@ impl Skeleton for DragonSkeleton {
}
}
pub struct SkeletonAttr;
pub struct SkeletonAttr {
head: (f32, f32),
chest_front: (f32, f32),
chest_rear: (f32, f32),
tail_front: (f32, f32),
tail_rear: (f32, f32),
wing_in: (f32, f32),
wing_out: (f32, f32),
feet_f: (f32, f32, f32),
feet_b: (f32, f32, f32),
}
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
type Error = ();
@ -112,9 +106,52 @@ 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),
chest_front: (0.0, 0.0),
chest_rear: (0.0, 0.0),
tail_front: (0.0, 0.0),
tail_rear: (0.0, 0.0),
wing_in: (0.0, 0.0),
wing_out: (0.0, 0.0),
feet_f: (0.0, 0.0, 0.0),
feet_b: (0.0, 0.0, 0.0),
}
}
}
impl<'a> From<&'a comp::dragon::Body> for SkeletonAttr {
fn from(_body: &'a comp::dragon::Body) -> Self { Self }
}
fn from(body: &'a comp::dragon::Body) -> Self {
use comp::dragon::Species::*;
Self {
head: match (body.species, body.body_type) {
(Reddragon, _) => (4.0, 3.0),
},
chest_front: match (body.species, body.body_type) {
(Reddragon, _) => (0.0, 5.0),
},
chest_rear: match (body.species, body.body_type) {
(Reddragon, _) => (0.0, 5.0),
},
tail_front: match (body.species, body.body_type) {
(Reddragon, _) => (-3.0, 1.5),
},
tail_rear: match (body.species, body.body_type) {
(Reddragon, _) => (-3.0, 1.5),
},
wing_in: match (body.species, body.body_type) {
(Reddragon, _) => (2.75, 0.0),
},
wing_out: match (body.species, body.body_type) {
(Reddragon, _) => (2.75, 0.0),
},
feet_f: match (body.species, body.body_type) {
(Reddragon, _) => (2.0, -1.5, 4.0),
},
feet_b: match (body.species, body.body_type) {
(Reddragon, _) => (2.0, -1.5, 4.0),
},
}
}
}

View File

@ -410,24 +410,83 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
None,
None,
],
Body::Dragon(body) => [
Some(mesh_dragon_head(body.head, generate_mesh)),
Some(mesh_dragon_chest_front(body.chest_front, generate_mesh)),
Some(mesh_dragon_chest_rear(body.chest_rear, generate_mesh)),
Some(mesh_dragon_tail_front(body.tail_front, generate_mesh)),
Some(mesh_dragon_tail_rear(body.tail_rear, generate_mesh)),
Some(mesh_dragon_wing_in_l(body.wing_in_l, generate_mesh)),
Some(mesh_dragon_wing_in_r(body.wing_in_r, generate_mesh)),
Some(mesh_dragon_wing_out_l(body.wing_out_l, generate_mesh)),
Some(mesh_dragon_wing_out_r(body.wing_out_r, generate_mesh)),
Some(mesh_dragon_foot_fl(body.foot_fl, generate_mesh)),
Some(mesh_dragon_foot_fr(body.foot_fr, generate_mesh)),
Some(mesh_dragon_foot_bl(body.foot_bl, generate_mesh)),
Some(mesh_dragon_foot_br(body.foot_br, generate_mesh)),
None,
None,
None,
],
Body::Dragon(body) => {
let dragon_center_spec =
DragonCenterSpec::load_watched(manifest_indicator);
let dragon_lateral_spec =
DragonLateralSpec::load_watched(manifest_indicator);
[
Some(dragon_center_spec.mesh_head(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_center_spec.mesh_chest_front(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_center_spec.mesh_chest_rear(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_center_spec.mesh_tail_front(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_center_spec.mesh_tail_rear(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_wing_in_l(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_wing_in_r(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_wing_out_l(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_wing_out_r(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_foot_fl(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_foot_fr(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_foot_bl(
body.species,
body.body_type,
generate_mesh,
)),
Some(dragon_lateral_spec.mesh_foot_br(
body.species,
body.body_type,
generate_mesh,
)),
None,
None,
None,
]
},
Body::BirdSmall(body) => [
Some(mesh_bird_small_head(body.head, generate_mesh)),
Some(mesh_bird_small_torso(body.torso, generate_mesh)),

View File

@ -6,7 +6,8 @@ use common::{
bird_medium::{BodyType as BMBodyType, Species as BMSpecies},
bird_small,
critter::{BodyType as CBodyType, Species as CSpecies},
dragon, fish_medium, fish_small,
dragon::{BodyType as DBodyType, Species as DSpecies},
fish_medium, fish_small,
golem::{BodyType as GBodyType, Species as GSpecies},
humanoid::{Body, BodyType, EyeColor, Race, Skin},
item::{
@ -1865,173 +1866,345 @@ pub fn mesh_fish_medium_fin_r(
)
}
pub fn mesh_dragon_head(
head: dragon::Head,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match head {
dragon::Head::Default => "npc.dragon.head",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
////
#[derive(Serialize, Deserialize)]
pub struct DragonCenterSpec(HashMap<(DSpecies, DBodyType), SidedDCenterVoxSpec>);
#[derive(Serialize, Deserialize)]
struct SidedDCenterVoxSpec {
head: DragonCenterSubSpec,
chest_front: DragonCenterSubSpec,
chest_rear: DragonCenterSubSpec,
tail_front: DragonCenterSubSpec,
tail_rear: DragonCenterSubSpec,
}
#[derive(Serialize, Deserialize)]
struct DragonCenterSubSpec {
offset: [f32; 3], // Should be relative to initial origin
center: VoxSimple,
}
pub fn mesh_dragon_chest_front(
chest_front: dragon::ChestFront,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match chest_front {
dragon::ChestFront::Default => "npc.dragon.chest_front",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
#[derive(Serialize, Deserialize)]
pub struct DragonLateralSpec(HashMap<(DSpecies, DBodyType), SidedDLateralVoxSpec>);
#[derive(Serialize, Deserialize)]
struct SidedDLateralVoxSpec {
wing_in_l: DragonLateralSubSpec,
wing_in_r: DragonLateralSubSpec,
wing_out_l: DragonLateralSubSpec,
wing_out_r: DragonLateralSubSpec,
foot_fl: DragonLateralSubSpec,
foot_fr: DragonLateralSubSpec,
foot_bl: DragonLateralSubSpec,
foot_br: DragonLateralSubSpec,
}
#[derive(Serialize, Deserialize)]
struct DragonLateralSubSpec {
offset: [f32; 3], // Should be relative to initial origin
lateral: VoxSimple,
}
pub fn mesh_dragon_chest_rear(
chest_rear: dragon::ChestRear,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match chest_rear {
dragon::ChestRear::Default => "npc.dragon.chest_rear",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
impl Asset for DragonCenterSpec {
const ENDINGS: &'static [&'static str] = &["ron"];
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
}
}
pub fn mesh_dragon_tail_front(
tail_front: dragon::TailFront,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match tail_front {
dragon::TailFront::Default => "npc.dragon.tail_front",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
impl Asset for DragonLateralSpec {
const ENDINGS: &'static [&'static str] = &["ron"];
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
}
}
pub fn mesh_dragon_tail_rear(
tail_rear: dragon::TailRear,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match tail_rear {
dragon::TailRear::Default => "npc.dragon.tail_rear",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
impl DragonCenterSpec {
pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc<Self> {
assets::load_watched::<Self>("voxygen.voxel.dragon_center_manifest", indicator)
.unwrap()
}
pub fn mesh_dragon_wing_in_l(
wing_in_l: dragon::WingInL,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match wing_in_l {
dragon::WingInL::Default => "npc.dragon.wing_in_l",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
pub fn mesh_head(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No head specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.head.center.0);
pub fn mesh_dragon_wing_in_r(
wing_in_r: dragon::WingInR,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match wing_in_r {
dragon::WingInR::Default => "npc.dragon.wing_in_r",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
generate_mesh(&center, Vec3::from(spec.head.offset))
}
pub fn mesh_dragon_wing_out_l(
wing_out_l: dragon::WingOutL,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match wing_out_l {
dragon::WingOutL::Default => "npc.dragon.wing_out_l",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
pub fn mesh_chest_front(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No chest front specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.chest_front.center.0);
pub fn mesh_dragon_wing_out_r(
wing_out_r: dragon::WingOutR,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match wing_out_r {
dragon::WingOutR::Default => "npc.dragon.wing_out_r",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
generate_mesh(&center, Vec3::from(spec.chest_front.offset))
}
pub fn mesh_chest_rear(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No chest rear specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.chest_rear.center.0);
pub fn mesh_dragon_foot_fl(
foot_fl: dragon::FootFL,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match foot_fl {
dragon::FootFL::Default => "npc.dragon.foot_fl",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
generate_mesh(&center, Vec3::from(spec.chest_rear.offset))
}
pub fn mesh_dragon_foot_fr(
foot_fr: dragon::FootFR,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match foot_fr {
dragon::FootFR::Default => "npc.dragon.foot_fr",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
pub fn mesh_tail_front(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No tail front specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.tail_front.center.0);
pub fn mesh_dragon_foot_bl(
foot_bl: dragon::FootBL,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match foot_bl {
dragon::FootBL::Default => "npc.dragon.foot_bl",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
}
generate_mesh(&center, Vec3::from(spec.tail_front.offset))
}
pub fn mesh_dragon_foot_br(
foot_br: dragon::FootBR,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
load_mesh(
match foot_br {
dragon::FootBR::Default => "npc.dragon.foot_br",
},
Vec3::new(-7.0, -6.0, -6.0),
generate_mesh,
)
pub fn mesh_tail_rear(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No tail rear specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let center = graceful_load_segment(&spec.tail_rear.center.0);
generate_mesh(&center, Vec3::from(spec.tail_rear.offset))
}
}
impl DragonLateralSpec {
pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc<Self> {
assets::load_watched::<Self>("voxygen.voxel.dragon_lateral_manifest", indicator)
.unwrap()
}
pub fn mesh_wing_in_l(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No wing specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.wing_in_l.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.wing_in_l.offset))
}
pub fn mesh_wing_in_r(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No wing specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.wing_in_r.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.wing_in_r.offset))
}
pub fn mesh_wing_out_l(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No wing specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.wing_out_l.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.wing_out_l.offset))
}
pub fn mesh_wing_out_r(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No wing specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.wing_out_r.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.wing_out_r.offset))
}
pub fn mesh_foot_fl(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No foot specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.foot_fl.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.foot_fl.offset))
}
pub fn mesh_foot_fr(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No foot specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.foot_fr.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.foot_fr.offset))
}
pub fn mesh_foot_bl(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No foot specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.foot_bl.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.foot_bl.offset))
}
pub fn mesh_foot_br(
&self,
species: DSpecies,
body_type: DBodyType,
generate_mesh: impl FnOnce(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
) -> Mesh<FigurePipeline> {
let spec = match self.0.get(&(species, body_type)) {
Some(spec) => spec,
None => {
error!(
"No foot specification exists for the combination of {:?} and {:?}",
species, body_type
);
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5), generate_mesh);
},
};
let lateral = graceful_load_segment(&spec.foot_br.lateral.0);
generate_mesh(&lateral, Vec3::from(spec.foot_br.offset))
}
}
////

View File

@ -21,7 +21,7 @@ use crate::{
util::{Grid, Sampler},
};
use common::{
comp::{self, bird_medium, critter, quadruped_medium, quadruped_small},
comp::{self, bird_medium, critter, quadruped_medium, quadruped_small, dragon},
generation::{ChunkSupplement, EntityInfo},
terrain::{Block, BlockKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
vol::{ReadVol, RectVolSize, Vox, WriteVol},