diff --git a/assets/voxygen/voxel/armor/belt/belt_dark.vox b/assets/voxygen/voxel/armor/belt/dark.vox similarity index 100% rename from assets/voxygen/voxel/armor/belt/belt_dark.vox rename to assets/voxygen/voxel/armor/belt/dark.vox diff --git a/assets/voxygen/voxel/armor/hand/hand_left.vox b/assets/voxygen/voxel/armor/hand/bare_left.vox similarity index 100% rename from assets/voxygen/voxel/armor/hand/hand_left.vox rename to assets/voxygen/voxel/armor/hand/bare_left.vox diff --git a/assets/voxygen/voxel/armor/hand/hand_right.vox b/assets/voxygen/voxel/armor/hand/bare_right.vox similarity index 100% rename from assets/voxygen/voxel/armor/hand/hand_right.vox rename to assets/voxygen/voxel/armor/hand/bare_right.vox diff --git a/assets/voxygen/voxel/armor/shoulder/shoulder_l_brown.vox b/assets/voxygen/voxel/armor/shoulder/brown_left.vox similarity index 100% rename from assets/voxygen/voxel/armor/shoulder/shoulder_l_brown.vox rename to assets/voxygen/voxel/armor/shoulder/brown_left.vox diff --git a/assets/voxygen/voxel/armor/shoulder/shoulder_r_brown.vox b/assets/voxygen/voxel/armor/shoulder/brown_right.vox similarity index 100% rename from assets/voxygen/voxel/armor/shoulder/shoulder_r_brown.vox rename to assets/voxygen/voxel/armor/shoulder/brown_right.vox diff --git a/assets/voxygen/voxel/armor/shoulder/shoulder_l_chain.vox b/assets/voxygen/voxel/armor/shoulder/chain_left.vox similarity index 100% rename from assets/voxygen/voxel/armor/shoulder/shoulder_l_chain.vox rename to assets/voxygen/voxel/armor/shoulder/chain_left.vox diff --git a/assets/voxygen/voxel/armor/shoulder/shoulder_r_chain.vox b/assets/voxygen/voxel/armor/shoulder/chain_right.vox similarity index 100% rename from assets/voxygen/voxel/armor/shoulder/shoulder_r_chain.vox rename to assets/voxygen/voxel/armor/shoulder/chain_right.vox diff --git a/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron b/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron new file mode 100644 index 0000000000..393fd07bad --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron @@ -0,0 +1,10 @@ +({ + Dark:( + vox_spec: ("armor.belt.dark", (-4.0, -3.5, 2.0)), + color: None + ), + Cloth:( + vox_spec: ("armor.belt.cloth_turq", (-4.0, -3.5, -6.0)), + color: None + ) +}) \ No newline at end of file diff --git a/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron b/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron new file mode 100644 index 0000000000..651e5364c3 --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron @@ -0,0 +1,30 @@ +({ + Blue: ( + vox_spec: ("armor.chest.grayscale", (-7.0, -3.5, 2.0)), + color: Some((44, 74, 109)) + ), + Brown: ( + vox_spec: ("armor.chest.grayscale", (-7.0, -3.5, 2.0)), + color: Some((90, 49, 43)) + ), + Dark: ( + vox_spec: ("armor.chest.grayscale", (-7.0, -3.5, 2.0)), + color: Some((73, 63, 59)) + ), + Green: ( + vox_spec: ("armor.chest.grayscale", (-7.0, -3.5, 2.0)), + color: Some((59, 95, 67)) + ), + Orange: ( + vox_spec: ("armor.chest.grayscale", (-7.0, -3.5, 2.0)), + color: Some((109, 58, 58)) + ), + Midnight: ( + vox_spec: ("armor.chest.grayscale", (-7.0, -3.5, 2.0)), + color: Some((29, 26, 33)) + ), + Kimono: ( + vox_spec: ("armor.chest.cloth_red_kimono", (-7.0, -3.5, 2.0)), + color: None + ) +}) \ No newline at end of file diff --git a/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron b/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron new file mode 100644 index 0000000000..3f22aabd81 --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron @@ -0,0 +1,19 @@ +({ + //This shouldn't be bare, but what is? + Bare: ( + vox_spec: ("armor.foot.cloth_sandals", (-2.5, -3.5, -9.0)), + color: None + ), + Dark: ( + vox_spec: ("armor.foot.dark-0", (-2.5, -3.5, -9.0)), + color: None + ), + Sandal: ( + vox_spec: ("armor.foot.cloth_sandals", (-2.5, -3.5, -9.0)), + color: None + ), + Jester: ( + vox_spec: ("armor.foot.dark_jester-elf_shoe", (-2.5, -3.5, -9.0)), + color: None + ) +}) \ No newline at end of file diff --git a/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron b/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron new file mode 100644 index 0000000000..897d6a8a66 --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron @@ -0,0 +1,22 @@ +({ + Bare: ( + left: ( + vox_spec: ("armor.hand.bare_left", (-1.5, -1.5, -7.0)), + color: None + ), + right: ( + vox_spec: ("armor.hand.bare_right", (-1.5, -1.5, -7.0)), + color: None + ) + ), + Cloth: ( + left: ( + vox_spec: ("armor.hand.cloth_basic_left", (-1.5, -1.5, -7.0)), + color: None + ), + right: ( + vox_spec: ("armor.hand.cloth_basic_right", (-1.5, -1.5, -7.0)), + color: None + ) + ) +}) \ No newline at end of file diff --git a/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron b/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron new file mode 100644 index 0000000000..3e7810448f --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron @@ -0,0 +1,26 @@ +({ + Blue: ( + vox_spec: ("armor.pants.grayscale", (-5.0, -3.5, 1.0)), + color: Some((28, 66, 109)) + ), + Brown: ( + vox_spec: ("armor.pants.grayscale", (-5.0, -3.5, 1.0)), + color: Some((54, 30, 26)) + ), + Dark: ( + vox_spec: ("armor.pants.grayscale", (-5.0, -3.5, 1.0)), + color: Some((24, 19, 17)) + ), + Green: ( + vox_spec: ("armor.pants.grayscale", (-5.0, -3.5, 1.0)), + color: Some((49, 95, 59)) + ), + Orange: ( + vox_spec: ("armor.pants.grayscale", (-5.0, -3.5, 1.0)), + color: Some((148, 52, 33)) + ), + Kimono: ( + vox_spec: ("armor.pants.cloth_red_kimono", (-5.0, -3.5, 1.0)), + color: None + ) +}) \ No newline at end of file diff --git a/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron b/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron new file mode 100644 index 0000000000..81cc061c03 --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron @@ -0,0 +1,33 @@ +({ + //This shouldn't be the none option, but what is? + None: ( + left: ( + vox_spec: ("armor.shoulder.brown_left", (-3.0, -3.5, 0.1)), + color: None + ), + right: ( + vox_spec: ("armor.shoulder.brown_right", (-2.0, -3.5, 0.1)), + color: None + ) + ), + Brown1: ( + left: ( + vox_spec: ("armor.shoulder.brown_left", (-3.0, -3.5, 0.1)), + color: None + ), + right: ( + vox_spec: ("armor.shoulder.brown_right", (-2.0, -3.5, 0.1)), + color: None + ) + ), + Chain: ( + left: ( + vox_spec: ("armor.shoulder.chain_left", (-3.0, -3.5, 0.1)), + color: None + ), + right: ( + vox_spec: ("armor.shoulder.chain_right", (-2.0, -3.5, 0.1)), + color: None + ) + ) +}) \ No newline at end of file diff --git a/common/src/comp/body/humanoid.rs b/common/src/comp/body/humanoid.rs index 9a5e0a4bf7..c027f90dca 100644 --- a/common/src/comp/body/humanoid.rs +++ b/common/src/comp/body/humanoid.rs @@ -393,24 +393,24 @@ pub enum Chest { Green, Orange, Midnight, + Kimono, } -pub const ALL_CHESTS: [Chest; 6] = [ +pub const ALL_CHESTS: [Chest; 7] = [ Chest::Blue, Chest::Brown, Chest::Dark, Chest::Green, Chest::Orange, Chest::Midnight, + Chest::Kimono, ]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Belt { Dark, + Cloth, } -pub const ALL_BELTS: [Belt; 1] = [ - //Belt::Default, - Belt::Dark, -]; +pub const ALL_BELTS: [Belt; 2] = [Belt::Dark, Belt::Cloth]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Pants { @@ -419,35 +419,40 @@ pub enum Pants { Dark, Green, Orange, + Kimono, } -pub const ALL_PANTS: [Pants; 5] = [ +pub const ALL_PANTS: [Pants; 6] = [ Pants::Blue, Pants::Brown, Pants::Dark, Pants::Green, Pants::Orange, + Pants::Kimono, ]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Hand { Bare, - Dark, + Cloth, } -pub const ALL_HANDS: [Hand; 2] = [Hand::Bare, Hand::Dark]; +pub const ALL_HANDS: [Hand; 2] = [Hand::Bare, Hand::Cloth]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Foot { Bare, Dark, + Sandal, + Jester, } -pub const ALL_FEET: [Foot; 2] = [Foot::Bare, Foot::Dark]; +pub const ALL_FEET: [Foot; 4] = [Foot::Bare, Foot::Dark, Foot::Sandal, Foot::Jester]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Shoulder { None, Brown1, + Chain, } -pub const ALL_SHOULDERS: [Shoulder; 2] = [Shoulder::None, Shoulder::Brown1]; +pub const ALL_SHOULDERS: [Shoulder; 3] = [Shoulder::None, Shoulder::Brown1, Shoulder::Chain]; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Eyebrows { diff --git a/voxygen/src/scene/figure/cache.rs b/voxygen/src/scene/figure/cache.rs index ddeb9f3fba..5063b50a14 100644 --- a/voxygen/src/scene/figure/cache.rs +++ b/voxygen/src/scene/figure/cache.rs @@ -81,6 +81,19 @@ impl FigureModelCache { { let humanoid_head_spec = HumHeadSpec::load_watched(&mut self.manifest_indicator); + let humanoid_armor_shoulder_spec = + HumArmorShoulderSpec::load_watched(&mut self.manifest_indicator); + let humanoid_armor_chest_spec = + HumArmorChestSpec::load_watched(&mut self.manifest_indicator); + let humanoid_armor_hand_spec = + HumArmorHandSpec::load_watched(&mut self.manifest_indicator); + let humanoid_armor_belt_spec = + HumArmorBeltSpec::load_watched(&mut self.manifest_indicator); + let humanoid_armor_pants_spec = + HumArmorPantsSpec::load_watched(&mut self.manifest_indicator); + let humanoid_armor_foot_spec = + HumArmorFootSpec::load_watched(&mut self.manifest_indicator); + let bone_meshes = match body { Body::Humanoid(body) => [ match camera_mode { @@ -100,27 +113,21 @@ impl FigureModelCache { CameraMode::FirstPerson => None, }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_chest( - body.chest, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )), + CameraMode::ThirdPerson => { + Some(humanoid_armor_chest_spec.mesh_chest(&body)) + } CameraMode::FirstPerson => None, }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_belt(body.belt)), + CameraMode::ThirdPerson => { + Some(humanoid_armor_belt_spec.mesh_belt(&body)) + } CameraMode::FirstPerson => None, }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_pants( - body.pants, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )), + CameraMode::ThirdPerson => { + Some(humanoid_armor_pants_spec.mesh_pants(&body)) + } CameraMode::FirstPerson => None, }, if camera_mode == CameraMode::FirstPerson @@ -130,13 +137,7 @@ impl FigureModelCache { { None } else { - Some(mesh_left_hand( - body.hand, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )) + Some(humanoid_armor_hand_spec.mesh_left_hand(&body)) }, if character_state .map(|cs| cs.movement.is_roll()) @@ -144,32 +145,18 @@ impl FigureModelCache { { None } else { - Some(mesh_right_hand( - body.hand, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )) + Some(humanoid_armor_hand_spec.mesh_right_hand(&body)) }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_left_foot( - body.foot, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )), + CameraMode::ThirdPerson => { + Some(humanoid_armor_foot_spec.mesh_left_foot(&body)) + } CameraMode::FirstPerson => None, }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_right_foot( - body.foot, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )), + CameraMode::ThirdPerson => { + Some(humanoid_armor_foot_spec.mesh_right_foot(&body)) + } CameraMode::FirstPerson => None, }, if camera_mode != CameraMode::FirstPerson @@ -186,23 +173,15 @@ impl FigureModelCache { None }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_left_shoulder( - body.shoulder, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )), + CameraMode::ThirdPerson => Some( + humanoid_armor_shoulder_spec.mesh_left_shoulder(&body), + ), CameraMode::FirstPerson => None, }, match camera_mode { - CameraMode::ThirdPerson => Some(mesh_right_shoulder( - body.shoulder, - body.race, - body.skin, - body.hair_color, - body.eye_color, - )), + CameraMode::ThirdPerson => Some( + humanoid_armor_shoulder_spec.mesh_right_shoulder(&body), + ), CameraMode::FirstPerson => None, }, Some(mesh_draw()), diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index 670d3e5bbe..7c9b16458a 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -2,6 +2,7 @@ use crate::{ mesh::Meshable, render::{FigurePipeline, Mesh}, }; +use common::comp::humanoid::Body; use common::{ assets::{self, watch::ReloadIndicator, Asset}, comp::{ @@ -84,16 +85,31 @@ fn recolor_grey(rgb: Rgb, color: Rgb) -> Rgb { // All offsets should be relative to an initial origin that doesn't change when combining segments #[derive(Serialize, Deserialize)] -struct VoxSpec(String, [i32; 3]); +struct VoxSpec(String, [T; 3]); + +// Armor can have the color modified. +#[derive(Serialize, Deserialize)] +struct ArmorVoxSpec { + vox_spec: VoxSpec, + color: Option<[u8; 3]>, +} + +// For use by armor with a left and right component +#[derive(Serialize, Deserialize)] +struct SidedArmorVoxSpec { + left: ArmorVoxSpec, + right: ArmorVoxSpec, +} + // All reliant on humanoid::Race and humanoid::BodyType #[derive(Serialize, Deserialize)] struct HumHeadSubSpec { offset: [f32; 3], // Should be relative to initial origin - head: VoxSpec, - eyes: VoxSpec, - hair: Vec>, - beard: Vec>, - accessory: Vec>, + head: VoxSpec, + eyes: VoxSpec, + hair: Vec>>, + beard: Vec>>, + accessory: Vec>>, } #[derive(Serialize, Deserialize)] pub struct HumHeadSpec(HashMap<(Race, BodyType), HumHeadSubSpec>); @@ -192,160 +208,305 @@ impl HumHeadSpec { ) } } +// Armor spects should be in the same order, top to bottom. +// These seem overly split up, but wanted to keep the armor seperated +// unlike head which is done above. -pub fn mesh_chest( - chest: Chest, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let chest_color = match chest { - Chest::Blue => (44, 74, 109), - Chest::Brown => (90, 49, 43), - Chest::Dark => (73, 63, 59), - Chest::Green => (59, 95, 67), - Chest::Orange => (109, 58, 58), - Chest::Midnight => (29, 26, 33), - }; +#[derive(Serialize, Deserialize)] +pub struct HumArmorShoulderSpec(HashMap); +#[derive(Serialize, Deserialize)] +pub struct HumArmorChestSpec(HashMap); +#[derive(Serialize, Deserialize)] +pub struct HumArmorHandSpec(HashMap); +#[derive(Serialize, Deserialize)] +pub struct HumArmorBeltSpec(HashMap); +#[derive(Serialize, Deserialize)] +pub struct HumArmorPantsSpec(HashMap); +#[derive(Serialize, Deserialize)] +pub struct HumArmorFootSpec(HashMap); - let color = |mat_segment| { - color_segment( - mat_segment, - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ) - }; - - let bare_chest = graceful_load_mat_segment("armor.chest.grayscale"); - let chest_armor = graceful_load_mat_segment("armor.chest.grayscale"); - let chest = DynaUnionizer::new() - .add(color(bare_chest), Vec3::new(0, 0, 0)) - .add( - color(chest_armor.map_rgb(|rgb| recolor_grey(rgb, Rgb::from(chest_color)))), - Vec3::new(0, 0, 0), - ) - .unify() - .0; - - generate_mesh(&chest, Vec3::new(-7.0, -3.5, 2.0)) +impl Asset for HumArmorShoulderSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + fn parse(buf_reader: BufReader) -> Result { + Ok(ron::de::from_reader(buf_reader).expect("Error parsing humanoid armor shoulder spec")) + } +} +impl Asset for HumArmorChestSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + fn parse(buf_reader: BufReader) -> Result { + Ok(ron::de::from_reader(buf_reader).expect("Error parsing humanoid armor chest spec")) + } +} +impl Asset for HumArmorHandSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + fn parse(buf_reader: BufReader) -> Result { + Ok(ron::de::from_reader(buf_reader).expect("Error parsing humanoid armor hand spec")) + } +} +impl Asset for HumArmorBeltSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + fn parse(buf_reader: BufReader) -> Result { + Ok(ron::de::from_reader(buf_reader).expect("Error parsing humanoid armor belt spec")) + } +} +impl Asset for HumArmorPantsSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + fn parse(buf_reader: BufReader) -> Result { + Ok(ron::de::from_reader(buf_reader).expect("Error parsing humanoid armor pants spec")) + } +} +impl Asset for HumArmorFootSpec { + const ENDINGS: &'static [&'static str] = &["ron"]; + fn parse(buf_reader: BufReader) -> Result { + Ok(ron::de::from_reader(buf_reader).expect("Error parsing humanoid armor foot spec")) + } } -pub fn mesh_belt(belt: Belt) -> Mesh { - load_mesh( - match belt { - //Belt::Default => "figure/body/belt_male", - Belt::Dark => "armor.belt.belt_dark", - }, - Vec3::new(-4.0, -3.5, 2.0), - ) +impl HumArmorShoulderSpec { + pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc { + assets::load_watched::("voxygen.voxel.humanoid_armor_shoulder_manifest", indicator) + .unwrap() + } + + pub fn mesh_left_shoulder(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.shoulder) { + Some(spec) => spec, + None => { + error!("No shoulder specification exists for {:?}", body.shoulder); + return load_mesh("not_found", Vec3::new(-3.0, -3.5, 0.1)); + } + }; + + let shoulder_segment = color_segment( + graceful_load_mat_segment(&spec.left.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&shoulder_segment, Vec3::from(spec.left.vox_spec.1)) + } + + pub fn mesh_right_shoulder(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.shoulder) { + Some(spec) => spec, + None => { + error!("No shoulder specification exists for {:?}", body.shoulder); + return load_mesh("not_found", Vec3::new(-2.0, -3.5, 0.1)); + } + }; + + let shoulder_segment = color_segment( + graceful_load_mat_segment(&spec.right.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&shoulder_segment, Vec3::from(spec.right.vox_spec.1)) + } } -pub fn mesh_pants( - pants: Pants, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let color = match pants { - Pants::Blue => (28, 66, 109), - Pants::Brown => (54, 30, 26), - Pants::Dark => (24, 19, 17), - Pants::Green => (49, 95, 59), - Pants::Orange => (148, 52, 33), - }; +impl HumArmorChestSpec { + pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc { + assets::load_watched::("voxygen.voxel.humanoid_armor_chest_manifest", indicator) + .unwrap() + } - let pants_segment = color_segment( - graceful_load_mat_segment("armor.pants.grayscale") - .map_rgb(|rgb| recolor_grey(rgb, Rgb::from(color))), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); + pub fn mesh_chest(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.chest) { + Some(spec) => spec, + None => { + error!("No chest specification exists for {:?}", body.chest); + return load_mesh("not_found", Vec3::new(-7.0, -3.5, 2.0)); + } + }; - generate_mesh(&pants_segment, Vec3::new(-5.0, -3.5, 1.0)) + let color = |mat_segment| { + color_segment( + mat_segment, + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ) + }; + + let bare_chest = graceful_load_mat_segment("armor.chest.grayscale"); + + let mut chest_armor = graceful_load_mat_segment(&spec.vox_spec.0); + + if let Some(color) = spec.color { + let chest_color = Vec3::from(color); + chest_armor = chest_armor.map_rgb(|rgb| recolor_grey(rgb, Rgb::from(chest_color))); + } + + let chest = DynaUnionizer::new() + .add(color(bare_chest), Vec3::new(0, 0, 0)) + .add(color(chest_armor), Vec3::new(0, 0, 0)) + .unify() + .0; + + generate_mesh(&chest, Vec3::from(spec.vox_spec.1)) + } } -pub fn mesh_left_hand( - hand: Hand, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let hand_segment = color_segment( - graceful_load_mat_segment(match hand { - Hand::Bare => "armor.hand.hand_left", - Hand::Dark => "armor.hand.hand_left", - }), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); +impl HumArmorHandSpec { + pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc { + assets::load_watched::("voxygen.voxel.humanoid_armor_hand_manifest", indicator) + .unwrap() + } - generate_mesh(&hand_segment, Vec3::new(-1.5, -1.5, -7.0)) + pub fn mesh_left_hand(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.hand) { + Some(spec) => spec, + None => { + error!("No hand specification exists for {:?}", body.hand); + return load_mesh("not_found", Vec3::new(-1.5, -1.5, -7.0)); + } + }; + + let hand_segment = color_segment( + graceful_load_mat_segment(&spec.left.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&hand_segment, Vec3::from(spec.left.vox_spec.1)) + } + + pub fn mesh_right_hand(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.hand) { + Some(spec) => spec, + None => { + error!("No hand specification exists for {:?}", body.hand); + return load_mesh("not_found", Vec3::new(-1.5, -1.5, -7.0)); + } + }; + + let hand_segment = color_segment( + graceful_load_mat_segment(&spec.left.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&hand_segment, Vec3::from(spec.left.vox_spec.1)) + } } -pub fn mesh_right_hand( - hand: Hand, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let hand_segment = color_segment( - graceful_load_mat_segment(match hand { - Hand::Bare => "armor.hand.hand_right", - Hand::Dark => "armor.hand.hand_right", - }), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); +impl HumArmorBeltSpec { + pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc { + assets::load_watched::("voxygen.voxel.humanoid_armor_belt_manifest", indicator) + .unwrap() + } - generate_mesh(&hand_segment, Vec3::new(-1.5, -1.5, -7.0)) + pub fn mesh_belt(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.belt) { + Some(spec) => spec, + None => { + error!("No belt specification exists for {:?}", body.belt); + return load_mesh("not_found", Vec3::new(-4.0, -3.5, 2.0)); + } + }; + + let belt_segment = color_segment( + graceful_load_mat_segment(&spec.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&belt_segment, Vec3::from(spec.vox_spec.1)) + } } -pub fn mesh_left_foot( - foot: Foot, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let foot_segment = color_segment( - graceful_load_mat_segment(match foot { - Foot::Bare => "armor.foot.dark-0", - Foot::Dark => "armor.foot.dark-0", - }), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); +impl HumArmorPantsSpec { + pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc { + assets::load_watched::("voxygen.voxel.humanoid_armor_pants_manifest", indicator) + .unwrap() + } - generate_mesh(&foot_segment, Vec3::new(-2.5, -3.5, -9.0)) + pub fn mesh_pants(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.pants) { + Some(spec) => spec, + None => { + error!("No pants specification exists for {:?}", body.pants); + return load_mesh("not_found", Vec3::new(-5.0, -3.5, 1.0)); + } + }; + + let color = |mat_segment| { + color_segment( + mat_segment, + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ) + }; + + let bare_pants = graceful_load_mat_segment("armor.pants.grayscale"); + + let mut pants_armor = graceful_load_mat_segment(&spec.vox_spec.0); + + if let Some(color) = spec.color { + let pants_color = Vec3::from(color); + pants_armor = pants_armor.map_rgb(|rgb| recolor_grey(rgb, Rgb::from(pants_color))); + } + + let pants = DynaUnionizer::new() + .add(color(bare_pants), Vec3::new(0, 0, 0)) + .add(color(pants_armor), Vec3::new(0, 0, 0)) + .unify() + .0; + + generate_mesh(&pants, Vec3::from(spec.vox_spec.1)) + } } -pub fn mesh_right_foot( - foot: Foot, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let foot_segment = color_segment( - graceful_load_mat_segment(match foot { - Foot::Bare => "armor.foot.dark-0", - Foot::Dark => "armor.foot.dark-0", - }), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); +impl HumArmorFootSpec { + pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc { + assets::load_watched::("voxygen.voxel.humanoid_armor_foot_manifest", indicator) + .unwrap() + } - generate_mesh(&foot_segment, Vec3::new(-2.5, -3.5, -9.0)) + pub fn mesh_left_foot(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.foot) { + Some(spec) => spec, + None => { + error!("No foot specification exists for {:?}", body.foot); + return load_mesh("not_found", Vec3::new(-2.5, -3.5, -9.0)); + } + }; + + let foot_segment = color_segment( + graceful_load_mat_segment(&spec.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&foot_segment, Vec3::from(spec.vox_spec.1)) + } + + pub fn mesh_right_foot(&self, body: &Body) -> Mesh { + let spec = match self.0.get(&body.foot) { + Some(spec) => spec, + None => { + error!("No foot specification exists for {:?}", body.foot); + return load_mesh("not_found", Vec3::new(-2.5, -3.5, -9.0)); + } + }; + + let foot_segment = color_segment( + graceful_load_mat_segment(&spec.vox_spec.0), + body.race.skin_color(body.skin), + body.race.hair_color(body.hair_color), + body.race.eye_color(body.eye_color), + ); + + generate_mesh(&foot_segment, Vec3::from(spec.vox_spec.1)) + } } pub fn mesh_main(item: Option<&Item>) -> Mesh { @@ -369,46 +530,6 @@ pub fn mesh_main(item: Option<&Item>) -> Mesh { } } -pub fn mesh_left_shoulder( - shoulder: Shoulder, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let shoulder_segment = color_segment( - graceful_load_mat_segment(match shoulder { - Shoulder::None => return Mesh::new(), - Shoulder::Brown1 => "armor.shoulder.shoulder_l_brown", - }), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); - - generate_mesh(&shoulder_segment, Vec3::new(-3.0, -3.5, 0.1)) -} - -pub fn mesh_right_shoulder( - shoulder: Shoulder, - race: Race, - skin: u8, - hair_color: u8, - eye_color: u8, -) -> Mesh { - let shoulder_segment = color_segment( - graceful_load_mat_segment(match shoulder { - Shoulder::None => return Mesh::new(), - Shoulder::Brown1 => "armor.shoulder.shoulder_r_brown", - }), - race.skin_color(skin), - race.hair_color(hair_color), - race.eye_color(eye_color), - ); - - generate_mesh(&shoulder_segment, Vec3::new(-2.0, -3.5, 0.1)) -} - // TODO: Inventory pub fn mesh_draw() -> Mesh { load_mesh("object.glider", Vec3::new(-26.0, -26.0, -5.0))