Hotloading colors, part 1: colors in common.

Currently, this just entails humanoid colors.  There are only three
colors not handled; the light emitter colors in
common/src/comp/inventory/item/tool.rs.  These don't seem important
enough to me to warrant making hotloadable, at least not right now, but
if it's needed later we can always add them to the file.
This commit is contained in:
Joshua Yanovski 2020-08-19 05:14:34 +02:00
parent 63b5e0e553
commit d71003acda
11 changed files with 672 additions and 576 deletions

12
Cargo.lock generated
View File

@ -3818,6 +3818,17 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_repr"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
dependencies = [
"proc-macro2 1.0.18",
"quote 1.0.7",
"syn 1.0.33",
]
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.6.0" version = "0.6.0"
@ -4725,6 +4736,7 @@ dependencies = [
"roots", "roots",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr",
"slab", "slab",
"specs", "specs",
"specs-idvs", "specs-idvs",

View File

@ -0,0 +1,283 @@
(
// NOTE: You can't change the legnths of these arrays without updating num_hair_colors() in
// common/src/comp/body/humanoid.rs. That's because this is a hack; we should really use enum
// variants for hair colors like we do all the other stuff. Once we fix that, this will no
// longer be something you need to worry about.
hair_colors: (
Danari: [
(198, 169, 113), // Philosopher's Grey
//(245, 232, 175), // Cream Blonde
//(228, 208, 147), // Gold Blonde
//(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
//(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(107, 32, 60), // Grape Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
//(146, 32, 32), // Autumn Red
(20, 19, 17), // Black
],
Dwarf: [
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice NobleBlue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(174, 148, 161), // Matte Pink
(163, 186, 192), // Matte Green
(0, 139, 58), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
],
Elf: [
(66, 83, 113), // Mysterious Blue
(13, 76, 41), // Rainforest Green
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice Blue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(163, 186, 192), // Matte Green
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
],
Human: [
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice Blue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(163, 186, 192), // Matte Green
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
],
Orc: [
(66, 66, 59), // Wise Grey
//(107, 76, 51), // Oak Skin4
//(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(54, 30, 26), // Dark Skin7
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(66, 83, 113), // Mysterious Blue
(20, 19, 17), // Black
],
Undead: [
//(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
//(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(111, 54, 117), // Punky Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice Blue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(66, 66, 59), // Decayed Grey
//(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(0, 131, 122), // Rotten Green
(163, 186, 192), // Matte Green
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
],
),
eye_colors_light: (
VigorousBlack: (71, 59, 49),
NobleBlue: (75, 158, 191),
CuriousGreen: (110, 167, 113),
LoyalBrown: (73, 42, 36),
ViciousRed: (182, 0, 0),
PumpkinOrange: (220, 156, 19),
GhastlyYellow: (221, 225, 31),
MagicPurple: (137, 4, 177),
ToxicGreen: (1, 223, 1),
ExoticPurple: (95, 32, 111),
SulfurYellow: (235, 198, 94),
AmberOrange: (137, 46, 1),
PineGreen: (0, 78, 56),
CornflowerBlue: (18, 66, 90),
),
eye_colors_dark: (
VigorousBlack: (32, 32, 32),
NobleBlue: (62, 130, 159),
CuriousGreen: (81, 124, 84),
LoyalBrown: (54, 30, 26),
ViciousRed: (148, 0, 0),
PumpkinOrange: (209, 145, 18),
GhastlyYellow: (205, 212, 29),
MagicPurple: (110, 3, 143),
ToxicGreen: (1, 185, 1),
ExoticPurple: (69, 23, 80),
SulfurYellow: (209, 176, 84),
AmberOrange: (112, 40, 1),
PineGreen: (0, 54, 38),
CornflowerBlue: (13, 47, 64),
),
eye_white: (255, 255, 255),
skin_colors_plain: (
Skin1: (255, 229, 200),
Skin2: (255, 218, 190),
Skin3: (255, 206, 180),
Skin4: (255, 195, 170),
Skin5: (240, 184, 160),
Skin6: (225, 172, 150),
Skin7: (210, 161, 140),
Skin8: (195, 149, 130),
Skin9: (180, 138, 120),
Skin10: (165, 126, 110),
Skin11: (150, 114, 100),
Skin12: (135, 103, 90),
Skin13: (120, 92, 80),
Skin14: (105, 80, 70),
Skin15: (90, 69, 60),
Skin16: (75, 57, 50),
Skin17: (60, 46, 40),
Skin18: (45, 34, 30),
Iron: (135, 113, 95),
Steel: (108, 94, 86),
DanariOne: (104, 168, 196),
DanariTwo: (30, 149, 201),
DanariThree: (57, 120, 148),
DanariFour: (40, 85, 105),
ElfOne: (159, 136, 173),
ElfTwo: (99, 114, 161),
// ElfThree: (230, 188, 198),
OrcOne: (61, 130, 42),
OrcTwo: (82, 117, 36),
OrcThree: (71, 94, 42),
OrcFour: (97, 54, 29),
UndeadOne: (240, 243, 239),
UndeadTwo: (178, 178, 178),
UndeadThree: (145, 135, 121),
),
skin_colors_light: (
Skin1: (255, 229, 200),
Skin2: (255, 218, 190),
Skin3: (255, 206, 180),
Skin4: (255, 195, 170),
Skin5: (240, 184, 160),
Skin6: (225, 172, 150),
Skin7: (210, 161, 140),
Skin8: (195, 149, 130),
Skin9: (180, 138, 120),
Skin10: (165, 126, 110),
Skin11: (150, 114, 100),
Skin12: (135, 103, 90),
Skin13: (120, 92, 80),
Skin14: (105, 80, 70),
Skin15: (90, 69, 60),
Skin16: (75, 57, 50),
Skin17: (60, 46, 40),
Skin18: (45, 34, 30),
Iron: (144, 125, 106),
Steel: (120, 107, 99),
DanariOne: (116, 176, 208),
DanariTwo: (42, 158, 206),
DanariThree: (70, 133, 160),
DanariFour: (53, 96, 116),
ElfOne: (183, 155, 199), //178, 164, 186
ElfTwo: (137, 144, 167),
//ElfThree: (242, 199, 209),
OrcOne: (83, 165, 56),
OrcTwo: (92, 132, 46),
OrcThree: (84, 110, 54),
OrcFour: (97, 54, 29),
UndeadOne: (254, 252, 251),
UndeadTwo: (190, 192, 191),
UndeadThree: (160, 151, 134),
),
skin_colors_dark: (
Skin1: (242, 217, 189),
Skin2: (242, 207, 189),
Skin3: (242, 197, 172),
Skin4: (242, 186, 162),
Skin5: (212, 173, 150),
Skin6: (212, 163, 142),
Skin7: (196, 151, 132),
Skin8: (181, 139, 121),
Skin9: (168, 129, 113),
Skin10: (153, 117, 103),
Skin11: (138, 105, 92),
Skin12: (122, 93, 82),
Skin13: (107, 82, 72),
Skin14: (92, 70, 62),
Skin15: (77, 59, 51),
Skin16: (61, 47, 41),
Skin17: (48, 37, 32),
Skin18: (33, 25, 22),
Iron: (124, 99, 82),
Steel: (96, 81, 72),
DanariOne: (92, 155, 183),
DanariTwo: (25, 142, 192),
DanariThree: (52, 115, 143),
DanariFour: (34, 80, 99),
ElfOne: (148, 125, 161), //170, 157, 179
ElfTwo: (126, 132, 153),
//ElfThree: (217, 178, 187),
OrcOne: (55, 114, 36),
OrcTwo: (70, 104, 29),
OrcThree: (60, 83, 32),
OrcFour: (84, 47, 25),
UndeadOne: (229, 231, 230),
UndeadTwo: (165, 166, 164),
UndeadThree: (130, 122, 106),
),
)

View File

@ -18,6 +18,7 @@ dot_vox = "4.0"
image = { version = "0.23.8", default-features = false, features = ["png"] } image = { version = "0.23.8", default-features = false, features = ["png"] }
serde = { version = "1.0.110", features = ["derive"] } serde = { version = "1.0.110", features = ["derive"] }
serde_json = "1.0.50" serde_json = "1.0.50"
serde_repr = "0.1.6"
ron = { version = "0.6", default-features = false } ron = { version = "0.6", default-features = false }
tracing = { version = "0.1", default-features = false } tracing = { version = "0.1", default-features = false }
rand = "0.7" rand = "0.7"

View File

@ -14,6 +14,7 @@ pub mod quadruped_small;
use crate::{ use crate::{
assets::{self, Asset}, assets::{self, Asset},
make_case_elim,
npc::NpcKind, npc::NpcKind,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -21,96 +22,26 @@ use specs::{Component, FlaggedStorage};
use specs_idvs::IdvStorage; use specs_idvs::IdvStorage;
use std::{fs::File, io::BufReader}; use std::{fs::File, io::BufReader};
/* pub trait PerBody { make_case_elim!(
type Humanoid; body,
type QuadrupedSmall; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
type QuadrupedMedium; #[repr(u32)]
type BirdMedium; pub enum Body {
type FishMedium; Humanoid(body: humanoid::Body) = 0,
type Dragon; QuadrupedSmall(body: quadruped_small::Body) = 1,
type BirdSmall; QuadrupedMedium(body: quadruped_medium::Body) = 2,
type FishSmall; BirdMedium(body: bird_medium::Body) = 3,
type BipedLarge; FishMedium(body: fish_medium::Body) = 4,
type Object; Dragon(body: dragon::Body) = 5,
type Golem; BirdSmall(body: bird_small::Body) = 6,
type Critter; FishSmall(body: fish_small::Body) = 7,
} BipedLarge(body: biped_large::Body)= 8,
Object(body: object::Body) = 9,
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] Golem(body: golem::Body) = 10,
#[repr(u32)] Critter(body: critter::Body) = 11,
pub enum Body<Meta = BodyType, BodyMeta = ()> QuadrupedLow(body: quadruped_low::Body) = 12,
where Meta: PerBody, }
{ );
Humanoid(Meta::Humanoid) = 0,
QuadrupedSmall(Meta::QuadrupedSmall) = 1,
QuadrupedMedium(Meta::QuadrupedMedium) = 2,
BirdMedium(Meta::BirdMedium) = 3,
FishMedium(Meta::FishMedium) = 4,
Dragon(Meta::Dragon) = 5,
BirdSmall(Meta::BirdSmall) = 6,
FishSmall(Meta::FishSmall) = 7,
BipedLarge(Meta::BipedLarge) = 8,
Object(Meta::Object) = 9,
Golem(Meta::Golem) = 10,
Critter(Meta::Critter) = 11,
}
/// Metadata intended to be stored per-body, together with data intended to be
/// stored for each species for each body.
///
/// NOTE: Deliberately don't (yet?) implement serialize.
#[derive(Clone, Debug, Deserialize)]
pub struct AllBodies<BodyMeta, PerBodyMeta: Meta> {
pub humanoid: BodyData<BodyMeta, humanoid::AllSpecies<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 dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
pub bird_small: BodyData<BodyMeta, ()>,
pub fish_small: BodyData<BodyMeta, ()>
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
pub object: BodyData<BodyMeta, ()>,
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
pub critter: BodyData<BodyMeta, critter::AllSpecies<SpeciesMeta>>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct BodyType;
impl PerBody for BodyType {
type Humanoid = humanoid::Body;
type QuadrupedSmall = quadruped_small::Body;
type QuadrupedMedium = quadruped_medium::Body;
type BirdMedium = bird_medium::Body;
type FishMedium = fish_medium::Body;
type Dragon = dragon::Body;
type BirdSmall = bird_small::Body;
type FishSmall = fish_small::Body;
type BipedLarge = biped_large::Body;
type Object = object::Body;
type Golem = golem::Body;
type Critter = critter::Body;
}
*/
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Body {
Humanoid(humanoid::Body) = 0,
QuadrupedSmall(quadruped_small::Body) = 1,
QuadrupedMedium(quadruped_medium::Body) = 2,
BirdMedium(bird_medium::Body) = 3,
FishMedium(fish_medium::Body) = 4,
Dragon(dragon::Body) = 5,
BirdSmall(bird_small::Body) = 6,
FishSmall(fish_small::Body) = 7,
BipedLarge(biped_large::Body) = 8,
Object(object::Body) = 9,
Golem(golem::Body) = 10,
Critter(critter::Body) = 11,
QuadrupedLow(quadruped_low::Body) = 12,
}
/// Data representing data generic to the body together with per-species data. /// Data representing data generic to the body together with per-species data.
/// ///

View File

@ -1,6 +1,7 @@
use crate::make_case_elim;
use rand::{seq::SliceRandom, thread_rng, Rng}; use rand::{seq::SliceRandom, thread_rng, Rng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vek::Rgb; use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Body { pub struct Body {
@ -58,16 +59,19 @@ impl From<Body> for super::Body {
fn from(body: Body) -> Self { super::Body::Humanoid(body) } fn from(body: Body) -> Self { super::Body::Humanoid(body) }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] make_case_elim!(
#[repr(u32)] species,
pub enum Species { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
Danari = 0, #[repr(u32)]
Dwarf = 1, pub enum Species {
Elf = 2, Danari = 0,
Human = 3, Dwarf = 1,
Orc = 4, Elf = 2,
Undead = 5, Human = 3,
} Orc = 4,
Undead = 5,
}
);
/// Data representing per-species generic data. /// Data representing per-species generic data.
/// ///
@ -114,142 +118,6 @@ impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() } fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
} }
// Hair Colors
pub const DANARI_HAIR_COLORS: [(u8, u8, u8); 12] = [
(198, 169, 113), // Philosopher's Grey
//(245, 232, 175), // Cream Blonde
//(228, 208, 147), // Gold Blonde
//(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
//(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(107, 32, 60), // Grape Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
//(146, 32, 32), // Autumn Red
(20, 19, 17), // Black
];
pub const DWARF_HAIR_COLORS: [(u8, u8, u8); 21] = [
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice NobleBlue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(174, 148, 161), // Matte Pink
(163, 186, 192), // Matte Green
(0, 139, 58), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
];
pub const ELF_HAIR_COLORS: [(u8, u8, u8); 24] = [
(66, 83, 113), // Mysterious Blue
(13, 76, 41), // Rainforest Green
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice Blue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(163, 186, 192), // Matte Green
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
];
pub const HUMAN_HAIR_COLORS: [(u8, u8, u8); 22] = [
(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice Blue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(163, 186, 192), // Matte Green
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
];
pub const ORC_HAIR_COLORS: [(u8, u8, u8); 11] = [
(66, 66, 59), // Wise Grey
//(107, 76, 51), // Oak Skin4
//(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(54, 30, 26), // Dark Skin7
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(66, 83, 113), // Mysterious Blue
(20, 19, 17), // Black
];
pub const UNDEAD_HAIR_COLORS: [(u8, u8, u8); 22] = [
//(245, 232, 175), // Cream Blonde
(228, 208, 147), // Gold Blonde
//(228, 223, 141), // Platinum Blonde
(199, 131, 58), // Summer Blonde
(107, 76, 51), // Oak Skin4
(203, 154, 98), // Light Skin4
(64, 32, 18), // Skin7 Skin4
(86, 72, 71), // Ash Skin4
(57, 56, 61), // Raven Black
(101, 83, 95), // Matte Purple
(101, 57, 90), // Witch Purple
(111, 54, 117), // Punky Purple
(135, 38, 39), // Dark Red
(88, 26, 29), // Wine Red
(191, 228, 254), // Ice Blue
(92, 80, 144), // Kingfisher Blue
(146, 198, 238), // Lagoon Blue
(66, 66, 59), // Decayed Grey
//(224, 182, 184), // Candy Pink
(174, 148, 161), // Matte Pink
(0, 131, 122), // Rotten Green
(163, 186, 192), // Matte Green
(84, 139, 107), // Grass Green
(48, 61, 52), // Dark Green
(20, 19, 17), // Black
];
// Skin colors // Skin colors
pub const DANARI_SKIN_COLORS: [Skin; 4] = [ pub const DANARI_SKIN_COLORS: [Skin; 4] = [
Skin::DanariOne, Skin::DanariOne,
@ -352,17 +220,6 @@ pub const UNDEAD_EYE_COLORS: [EyeColor; 5] = [
]; ];
impl Species { impl Species {
fn hair_colors(self) -> &'static [(u8, u8, u8)] {
match self {
Species::Danari => &DANARI_HAIR_COLORS,
Species::Dwarf => &DWARF_HAIR_COLORS,
Species::Elf => &ELF_HAIR_COLORS,
Species::Human => &HUMAN_HAIR_COLORS,
Species::Orc => &ORC_HAIR_COLORS,
Species::Undead => &UNDEAD_HAIR_COLORS,
}
}
fn skin_colors(self) -> &'static [Skin] { fn skin_colors(self) -> &'static [Skin] {
match self { match self {
Species::Danari => &DANARI_SKIN_COLORS, Species::Danari => &DANARI_SKIN_COLORS,
@ -385,16 +242,22 @@ impl Species {
} }
} }
pub fn hair_color(self, val: u8) -> Rgb<u8> { /// FIXME: This is a hack! The only reason we need to do this is because
self.hair_colors() /// hair colors are currently just indices into an array, not enum
.get(val as usize) /// variants. Once we have proper variants for hair colors, we won't
.copied() /// need to do this anymore, since we will use locally defined arrays to
.unwrap_or((0, 0, 0)) /// represent per-species stuff (or have some other solution for validity).
.into() pub fn num_hair_colors(self) -> u8 {
match self {
Species::Danari => 12,
Species::Dwarf => 21,
Species::Elf => 24,
Species::Human => 22,
Species::Orc => 11,
Species::Undead => 22,
}
} }
pub fn num_hair_colors(self) -> u8 { self.hair_colors().len() as u8 }
pub fn skin_color(self, val: u8) -> Skin { pub fn skin_color(self, val: u8) -> Skin {
self.skin_colors() self.skin_colors()
.get(val as usize) .get(val as usize)
@ -484,238 +347,78 @@ impl Species {
} }
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] make_case_elim!(
#[repr(u32)] body_type,
pub enum BodyType { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
Female = 0, #[repr(u32)]
Male = 1, pub enum BodyType {
} Female = 0,
Male = 1,
}
);
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male]; pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] make_case_elim!(
#[repr(u32)] eye_color,
pub enum EyeColor { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
VigorousBlack = 0, #[repr(u32)]
NobleBlue = 1, pub enum EyeColor {
CuriousGreen = 2, VigorousBlack = 0,
LoyalBrown = 3, NobleBlue = 1,
ViciousRed = 4, CuriousGreen = 2,
PumpkinOrange = 5, LoyalBrown = 3,
GhastlyYellow = 6, ViciousRed = 4,
MagicPurple = 7, PumpkinOrange = 5,
ToxicGreen = 8, GhastlyYellow = 6,
ExoticPurple = 9, MagicPurple = 7,
SulfurYellow = 10, ToxicGreen = 8,
AmberOrange = 11, ExoticPurple = 9,
PineGreen = 12, SulfurYellow = 10,
CornflowerBlue = 13, AmberOrange = 11,
} PineGreen = 12,
impl EyeColor { CornflowerBlue = 13,
pub fn light_rgb(self) -> Rgb<u8> {
match self {
EyeColor::VigorousBlack => Rgb::new(71, 59, 49),
EyeColor::NobleBlue => Rgb::new(75, 158, 191),
EyeColor::CuriousGreen => Rgb::new(110, 167, 113),
EyeColor::LoyalBrown => Rgb::new(73, 42, 36),
EyeColor::ViciousRed => Rgb::new(182, 0, 0),
EyeColor::PumpkinOrange => Rgb::new(220, 156, 19),
EyeColor::GhastlyYellow => Rgb::new(221, 225, 31),
EyeColor::MagicPurple => Rgb::new(137, 4, 177),
EyeColor::ToxicGreen => Rgb::new(1, 223, 1),
EyeColor::ExoticPurple => Rgb::new(95, 32, 111),
EyeColor::SulfurYellow => Rgb::new(235, 198, 94),
EyeColor::AmberOrange => Rgb::new(137, 46, 1),
EyeColor::PineGreen => Rgb::new(0, 78, 56),
EyeColor::CornflowerBlue => Rgb::new(18, 66, 90),
}
} }
);
pub fn dark_rgb(self) -> Rgb<u8> { make_case_elim!(
match self { skin,
EyeColor::VigorousBlack => Rgb::new(32, 32, 32), #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)]
EyeColor::NobleBlue => Rgb::new(62, 130, 159), #[repr(u32)]
EyeColor::CuriousGreen => Rgb::new(81, 124, 84), pub enum Skin {
EyeColor::LoyalBrown => Rgb::new(54, 30, 26), Skin1 = 0,
EyeColor::ViciousRed => Rgb::new(148, 0, 0), Skin2 = 1,
EyeColor::PumpkinOrange => Rgb::new(209, 145, 18), Skin3 = 2,
EyeColor::GhastlyYellow => Rgb::new(205, 212, 29), Skin4 = 3,
EyeColor::MagicPurple => Rgb::new(110, 3, 143), Skin5 = 4,
EyeColor::ToxicGreen => Rgb::new(1, 185, 1), Skin6 = 5,
EyeColor::ExoticPurple => Rgb::new(69, 23, 80), Iron = 6,
EyeColor::SulfurYellow => Rgb::new(209, 176, 84), Steel = 7,
EyeColor::AmberOrange => Rgb::new(112, 40, 1), DanariOne = 8,
EyeColor::PineGreen => Rgb::new(0, 54, 38), DanariTwo = 9,
EyeColor::CornflowerBlue => Rgb::new(13, 47, 64), DanariThree = 10,
} DanariFour = 11,
ElfOne = 12,
ElfTwo = 13,
//ElfThree = 14,
OrcOne = 14,
OrcTwo = 15,
OrcThree = 16,
UndeadOne = 17,
UndeadTwo = 18,
UndeadThree = 19,
Skin7 = 20,
Skin8 = 21,
Skin9 = 22,
Skin10 = 23,
Skin11 = 24,
Skin12 = 25,
Skin13 = 26,
Skin14 = 27,
Skin15 = 28,
Skin16 = 29,
Skin17 = 30,
Skin18 = 31,
OrcFour = 32,
} }
);
pub fn white_rgb(self) -> Rgb<u8> { Rgb::new(255, 255, 255) }
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Accessory {
Nothing = 0,
Some = 1,
}
pub const ALL_ACCESSORIES: [Accessory; 2] = [Accessory::Nothing, Accessory::Some];
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum Skin {
Skin1 = 0,
Skin2 = 1,
Skin3 = 2,
Skin4 = 3,
Skin5 = 4,
Skin6 = 5,
Iron = 6,
Steel = 7,
DanariOne = 8,
DanariTwo = 9,
DanariThree = 10,
DanariFour = 11,
ElfOne = 12,
ElfTwo = 13,
//ElfThree = 14,
OrcOne = 14,
OrcTwo = 15,
OrcThree = 16,
UndeadOne = 17,
UndeadTwo = 18,
UndeadThree = 19,
Skin7 = 20,
Skin8 = 21,
Skin9 = 22,
Skin10 = 23,
Skin11 = 24,
Skin12 = 25,
Skin13 = 26,
Skin14 = 27,
Skin15 = 28,
Skin16 = 29,
Skin17 = 30,
Skin18 = 31,
OrcFour = 32,
}
impl Skin {
pub fn rgb(self) -> Rgb<u8> {
let color = match self {
Self::Skin1 => (255, 229, 200),
Self::Skin2 => (255, 218, 190),
Self::Skin3 => (255, 206, 180),
Self::Skin4 => (255, 195, 170),
Self::Skin5 => (240, 184, 160),
Self::Skin6 => (225, 172, 150),
Self::Skin7 => (210, 161, 140),
Self::Skin8 => (195, 149, 130),
Self::Skin9 => (180, 138, 120),
Self::Skin10 => (165, 126, 110),
Self::Skin11 => (150, 114, 100),
Self::Skin12 => (135, 103, 90),
Self::Skin13 => (120, 92, 80),
Self::Skin14 => (105, 80, 70),
Self::Skin15 => (90, 69, 60),
Self::Skin16 => (75, 57, 50),
Self::Skin17 => (60, 46, 40),
Self::Skin18 => (45, 34, 30),
Self::Iron => (135, 113, 95),
Self::Steel => (108, 94, 86),
Self::DanariOne => (104, 168, 196),
Self::DanariTwo => (30, 149, 201),
Self::DanariThree => (57, 120, 148),
Self::DanariFour => (40, 85, 105),
Self::ElfOne => (159, 136, 173),
Self::ElfTwo => (99, 114, 161),
//Self::ElfThree => (230, 188, 198),
Self::OrcOne => (61, 130, 42),
Self::OrcTwo => (82, 117, 36),
Self::OrcThree => (71, 94, 42),
Self::OrcFour => (97, 54, 29),
Self::UndeadOne => (240, 243, 239),
Self::UndeadTwo => (178, 178, 178),
Self::UndeadThree => (145, 135, 121),
};
Rgb::from(color)
}
pub fn light_rgb(self) -> Rgb<u8> {
let color = match self {
Self::Skin1 => (255, 229, 200),
Self::Skin2 => (255, 218, 190),
Self::Skin3 => (255, 206, 180),
Self::Skin4 => (255, 195, 170),
Self::Skin5 => (240, 184, 160),
Self::Skin6 => (225, 172, 150),
Self::Skin7 => (210, 161, 140),
Self::Skin8 => (195, 149, 130),
Self::Skin9 => (180, 138, 120),
Self::Skin10 => (165, 126, 110),
Self::Skin11 => (150, 114, 100),
Self::Skin12 => (135, 103, 90),
Self::Skin13 => (120, 92, 80),
Self::Skin14 => (105, 80, 70),
Self::Skin15 => (90, 69, 60),
Self::Skin16 => (75, 57, 50),
Self::Skin17 => (60, 46, 40),
Self::Skin18 => (45, 34, 30),
Self::Iron => (144, 125, 106),
Self::Steel => (120, 107, 99),
Self::DanariOne => (116, 176, 208),
Self::DanariTwo => (42, 158, 206),
Self::DanariThree => (70, 133, 160),
Self::DanariFour => (53, 96, 116),
Self::ElfOne => (183, 155, 199), //178, 164, 186
Self::ElfTwo => (137, 144, 167),
//Self::ElfThree => (242, 199, 209),
Self::OrcOne => (83, 165, 56),
Self::OrcTwo => (92, 132, 46),
Self::OrcThree => (84, 110, 54),
Self::OrcFour => (97, 54, 29),
Self::UndeadOne => (254, 252, 251),
Self::UndeadTwo => (190, 192, 191),
Self::UndeadThree => (160, 151, 134),
};
Rgb::from(color)
}
pub fn dark_rgb(self) -> Rgb<u8> {
let color = match self {
Self::Skin1 => (242, 217, 189),
Self::Skin2 => (242, 207, 189),
Self::Skin3 => (242, 197, 172),
Self::Skin4 => (242, 186, 162),
Self::Skin5 => (212, 173, 150),
Self::Skin6 => (212, 163, 142),
Self::Skin7 => (196, 151, 132),
Self::Skin8 => (181, 139, 121),
Self::Skin9 => (168, 129, 113),
Self::Skin10 => (153, 117, 103),
Self::Skin11 => (138, 105, 92),
Self::Skin12 => (122, 93, 82),
Self::Skin13 => (107, 82, 72),
Self::Skin14 => (92, 70, 62),
Self::Skin15 => (77, 59, 51),
Self::Skin16 => (61, 47, 41),
Self::Skin17 => (48, 37, 32),
Self::Skin18 => (33, 25, 22),
Self::Iron => (124, 99, 82),
Self::Steel => (96, 81, 72),
Self::DanariOne => (92, 155, 183),
Self::DanariTwo => (25, 142, 192),
Self::DanariThree => (52, 115, 143),
Self::DanariFour => (34, 80, 99),
Self::ElfOne => (148, 125, 161), //170, 157, 179
Self::ElfTwo => (126, 132, 153),
//Self::ElfThree => (217, 178, 187),
Self::OrcOne => (55, 114, 36),
Self::OrcTwo => (70, 104, 29),
Self::OrcThree => (60, 83, 32),
Self::OrcFour => (84, 47, 25),
Self::UndeadOne => (229, 231, 230),
Self::UndeadTwo => (165, 166, 164),
Self::UndeadThree => (130, 122, 106),
};
Rgb::from(color)
}
}

View File

@ -1,5 +1,6 @@
mod color; mod color;
mod dir; mod dir;
mod typed;
pub const GIT_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/githash")); pub const GIT_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/githash"));
@ -10,3 +11,4 @@ lazy_static::lazy_static! {
pub use color::*; pub use color::*;
pub use dir::*; pub use dir::*;
pub use typed::*;

113
common/src/util/typed.rs Normal file
View File

@ -0,0 +1,113 @@
use core::marker::PhantomData;
pub trait SubContext<Context> {
fn sub_context(self) -> Context;
}
impl<Context> SubContext<Context> for Context {
fn sub_context(self) -> Context { self }
}
impl<Head, Tail> SubContext<Tail> for (Head, Tail) {
fn sub_context(self) -> Tail { self.1 }
}
pub trait Typed<Context, Type, S> {
fn reduce(self, context: Context) -> (Type, S);
}
pub struct Pure<T>(pub T);
impl<Context: SubContext<S>, T, S> Typed<Context, Pure<T>, S> for T {
fn reduce(self, context: Context) -> (Pure<T>, S) { (Pure(self), context.sub_context()) }
}
pub struct ElimCase<Expr, Cases, Type> {
pub expr: Expr,
pub cases: Cases,
pub ty: PhantomData<Type>,
}
#[macro_export]
macro_rules! as_item {
($i:item) => {
$i
};
}
#[macro_export]
macro_rules! make_case_elim {
($mod:ident, $( #[$ty_attr:meta] )* $vis:vis enum $ty:ident {
$( $constr:ident $( ( $( $arg_name:ident : $arg_ty:ty ),* ) )? = $index:tt ),* $(,)?
}) => {
$crate::as_item! {
$( #[$ty_attr] )*
$vis enum $ty {
$( $constr $( ($( $arg_ty, )*) )? = $index, )*
}
}
#[allow(non_snake_case)]
$vis mod $mod {
use ::serde::{Deserialize, Serialize};
pub trait PackedElim {
$( type $constr; )*
}
#[derive(Serialize, Deserialize)]
pub struct Cases<Elim: PackedElim> {
$( pub $constr : Elim::$constr, )*
}
impl<T> PackedElim for $crate::util::Pure<T> {
$( type $constr = T; )*
}
pub type PureCases<Elim> = Cases<$crate::util::Pure<Elim>>;
}
#[allow(unused_parens)]
impl<'a, Elim: $mod::PackedElim, Context, Type, S>
$crate::util::Typed<Context, Type, S> for $crate::util::ElimCase<&'a $ty, &'a $mod::Cases<Elim>, Type>
where
$( &'a Elim::$constr: $crate::util::Typed<($( ($( &'a $arg_ty, )*), )? Context), Type, S>, )*
{
fn reduce(self, context: Context) -> (Type, S)
{
let Self { expr, cases, .. } = self;
match expr {
$( $ty::$constr $( ($( $arg_name, )*) )? =>
<_ as $crate::util::Typed<_, Type, _>>::reduce(
&cases.$constr,
($( ($( $arg_name, )*), )? context),
),
)*
}
}
}
impl $ty {
pub fn elim_case<'a, Elim: $mod::PackedElim, Context, S, Type>(&'a self, cases: &'a $mod::Cases<Elim>, context: Context) ->
(Type, S)
where
$crate::util::ElimCase<&'a $ty, &'a $mod::Cases<Elim>, Type> : $crate::util::Typed<Context, Type, S>,
{
use $crate::util::Typed;
let case = $crate::util::ElimCase {
expr: self,
cases,
ty: ::core::marker::PhantomData,
};
case.reduce(context)
}
pub fn elim_case_pure<'a, Type>(&'a self, cases: &'a $mod::PureCases<Type>) -> &'a Type
{
let ($crate::util::Pure(expr), ()) = self.elim_case(cases, ());
expr
}
}
}
}

View File

@ -1977,20 +1977,21 @@ impl<'a> Widget for SettingsWindow<'a> {
.color(TEXT_COLOR) .color(TEXT_COLOR)
.set(state.ids.aa_mode_text, ui); .set(state.ids.aa_mode_text, ui);
// NOTE: MSAA modes are currently disabled from the UI due to poor
// interaction with greedy meshing, and may eventually be removed.
let mode_list = [ let mode_list = [
AaMode::None, AaMode::None,
AaMode::Fxaa, AaMode::Fxaa,
AaMode::MsaaX4, /* AaMode::MsaaX4,
AaMode::MsaaX8, AaMode::MsaaX8,
AaMode::MsaaX16, AaMode::MsaaX16, */
AaMode::SsaaX4, AaMode::SsaaX4,
]; ];
let mode_label_list = [ let mode_label_list = [
"No AA", "No AA", "FXAA",
"FXAA", /* "MSAA x4",
"MSAA x4",
"MSAA x8", "MSAA x8",
"MSAA x16 (experimental)", "MSAA x16 (experimental)", */
"SSAA x4", "SSAA x4",
]; ];

View File

@ -222,6 +222,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
) -> [Option<BoneMeshes>; 16] { ) -> [Option<BoneMeshes>; 16] {
match body { match body {
Body::Humanoid(body) => { Body::Humanoid(body) => {
let humanoid_color_spec = HumColorSpec::load_watched(manifest_indicator);
let humanoid_head_spec = HumHeadSpec::load_watched(manifest_indicator); let humanoid_head_spec = HumHeadSpec::load_watched(manifest_indicator);
let humanoid_armor_shoulder_spec = let humanoid_armor_shoulder_spec =
HumArmorShoulderSpec::load_watched(manifest_indicator); HumArmorShoulderSpec::load_watched(manifest_indicator);
@ -253,12 +254,16 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
[ [
third_person.map(|_| { third_person.map(|_| {
humanoid_head_spec humanoid_head_spec.mesh_head(
.mesh_head(body, |segment, offset| generate_mesh(segment, offset)) body,
&humanoid_color_spec,
|segment, offset| generate_mesh(segment, offset),
)
}), }),
third_person.map(|loadout| { third_person.map(|loadout| {
humanoid_armor_chest_spec.mesh_chest( humanoid_armor_chest_spec.mesh_chest(
body, body,
&humanoid_color_spec,
loadout.chest.as_deref(), loadout.chest.as_deref(),
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
) )
@ -266,6 +271,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
third_person.map(|loadout| { third_person.map(|loadout| {
humanoid_armor_belt_spec.mesh_belt( humanoid_armor_belt_spec.mesh_belt(
body, body,
&humanoid_color_spec,
loadout.belt.as_deref(), loadout.belt.as_deref(),
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
) )
@ -273,6 +279,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
third_person.map(|loadout| { third_person.map(|loadout| {
humanoid_armor_back_spec.mesh_back( humanoid_armor_back_spec.mesh_back(
body, body,
&humanoid_color_spec,
loadout.back.as_deref(), loadout.back.as_deref(),
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
) )
@ -280,33 +287,39 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
third_person.map(|loadout| { third_person.map(|loadout| {
humanoid_armor_pants_spec.mesh_pants( humanoid_armor_pants_spec.mesh_pants(
body, body,
&humanoid_color_spec,
loadout.pants.as_deref(), loadout.pants.as_deref(),
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
) )
}), }),
Some( Some(humanoid_armor_hand_spec.mesh_left_hand(
humanoid_armor_hand_spec.mesh_left_hand(body, hand, |segment, offset| {
generate_mesh(segment, offset)
}),
),
Some(humanoid_armor_hand_spec.mesh_right_hand(
body, body,
&humanoid_color_spec,
hand, hand,
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
)), )),
Some( Some(humanoid_armor_hand_spec.mesh_right_hand(
humanoid_armor_foot_spec.mesh_left_foot(body, foot, |segment, offset| { body,
generate_mesh(segment, offset) &humanoid_color_spec,
}), hand,
), |segment, offset| generate_mesh(segment, offset),
)),
Some(humanoid_armor_foot_spec.mesh_left_foot(
body,
&humanoid_color_spec,
foot,
|segment, offset| generate_mesh(segment, offset),
)),
Some(humanoid_armor_foot_spec.mesh_right_foot( Some(humanoid_armor_foot_spec.mesh_right_foot(
body, body,
&humanoid_color_spec,
foot, foot,
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
)), )),
third_person.map(|loadout| { third_person.map(|loadout| {
humanoid_armor_shoulder_spec.mesh_left_shoulder( humanoid_armor_shoulder_spec.mesh_left_shoulder(
body, body,
&humanoid_color_spec,
loadout.shoulder.as_deref(), loadout.shoulder.as_deref(),
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
) )
@ -314,6 +327,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
third_person.map(|loadout| { third_person.map(|loadout| {
humanoid_armor_shoulder_spec.mesh_right_shoulder( humanoid_armor_shoulder_spec.mesh_right_shoulder(
body, body,
&humanoid_color_spec,
loadout.shoulder.as_deref(), loadout.shoulder.as_deref(),
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
) )
@ -337,6 +351,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
}), }),
Some(humanoid_armor_lantern_spec.mesh_lantern( Some(humanoid_armor_lantern_spec.mesh_lantern(
body, body,
&humanoid_color_spec,
lantern, lantern,
|segment, offset| generate_mesh(segment, offset), |segment, offset| generate_mesh(segment, offset),
)), )),

View File

@ -9,7 +9,7 @@ use common::{
dragon::{BodyType as DBodyType, Species as DSpecies}, dragon::{BodyType as DBodyType, Species as DSpecies},
fish_medium, fish_small, fish_medium, fish_small,
golem::{BodyType as GBodyType, Species as GSpecies}, golem::{BodyType as GBodyType, Species as GSpecies},
humanoid::{Body, BodyType, EyeColor, Skin, Species}, humanoid::{self, Body, BodyType, EyeColor, Skin, Species},
item::tool::ToolKind, item::tool::ToolKind,
object, object,
quadruped_low::{BodyType as QLBodyType, Species as QLSpecies}, quadruped_low::{BodyType as QLBodyType, Species as QLSpecies},
@ -60,25 +60,6 @@ pub fn load_mesh(
generate_mesh(load_segment(mesh_name), position) generate_mesh(load_segment(mesh_name), position)
} }
fn color_segment(
mat_segment: MatSegment,
skin: Skin,
hair_color: Rgb<u8>,
eye_color: EyeColor,
) -> Segment {
// TODO move some of the colors to common
mat_segment.to_segment(|mat| match mat {
Material::Skin => skin.rgb(),
Material::SkinDark => skin.dark_rgb(),
Material::SkinLight => skin.light_rgb(),
Material::Hair => hair_color,
// TODO add back multiple colors
Material::EyeLight => eye_color.light_rgb(),
Material::EyeDark => eye_color.dark_rgb(),
Material::EyeWhite => eye_color.white_rgb(),
})
}
fn recolor_grey(rgb: Rgb<u8>, color: Rgb<u8>) -> Rgb<u8> { fn recolor_grey(rgb: Rgb<u8>, color: Rgb<u8>) -> Rgb<u8> {
use common::util::{linear_to_srgb, srgb_to_linear}; use common::util::{linear_to_srgb, srgb_to_linear};
@ -121,6 +102,63 @@ struct MobSidedVoxSpec {
right: ArmorVoxSpec, right: ArmorVoxSpec,
} }
/// Color information not found in voxels, for humanoids.
#[derive(Serialize, Deserialize)]
pub struct HumColorSpec {
hair_colors: humanoid::species::PureCases<Vec<(u8, u8, u8)>>,
eye_colors_light: humanoid::eye_color::PureCases<(u8, u8, u8)>,
eye_colors_dark: humanoid::eye_color::PureCases<(u8, u8, u8)>,
eye_white: (u8, u8, u8),
skin_colors_plain: humanoid::skin::PureCases<(u8, u8, u8)>,
skin_colors_light: humanoid::skin::PureCases<(u8, u8, u8)>,
skin_colors_dark: humanoid::skin::PureCases<(u8, u8, u8)>,
}
impl Asset for HumColorSpec {
const ENDINGS: &'static [&'static str] = &["ron"];
fn parse(buf_reader: BufReader<File>) -> Result<Self, assets::Error> {
ron::de::from_reader(buf_reader).map_err(assets::Error::parse_error)
}
}
impl HumColorSpec {
pub fn load_watched(indicator: &mut ReloadIndicator) -> Arc<Self> {
assets::load_watched::<Self>("voxygen.voxel.humanoid_color_manifest", indicator).unwrap()
}
fn hair_color(&self, species: Species, val: u8) -> (u8, u8, u8) {
species
.elim_case_pure(&self.hair_colors)
.get(val as usize)
.copied()
.unwrap_or((0, 0, 0))
}
fn color_segment(
&self,
mat_segment: MatSegment,
skin: Skin,
hair_color: (u8, u8, u8),
eye_color: EyeColor,
) -> Segment {
// TODO move some of the colors to common
mat_segment.to_segment(|mat| {
match mat {
Material::Skin => *skin.elim_case_pure(&self.skin_colors_plain),
Material::SkinDark => *skin.elim_case_pure(&self.skin_colors_dark),
Material::SkinLight => *skin.elim_case_pure(&self.skin_colors_light),
Material::Hair => hair_color,
// TODO add back multiple colors
Material::EyeLight => *eye_color.elim_case_pure(&self.eye_colors_light),
Material::EyeDark => *eye_color.elim_case_pure(&self.eye_colors_dark),
Material::EyeWhite => self.eye_white,
}
.into()
})
}
}
// All reliant on humanoid::Species and humanoid::BodyType // All reliant on humanoid::Species and humanoid::BodyType
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct HumHeadSubSpec { struct HumHeadSubSpec {
@ -150,6 +188,7 @@ impl HumHeadSpec {
pub fn mesh_head( pub fn mesh_head(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
let spec = match self.0.get(&(body.species, body.body_type)) { let spec = match self.0.get(&(body.species, body.body_type)) {
@ -164,7 +203,8 @@ impl HumHeadSpec {
}, },
}; };
let hair_rgb = body.species.hair_color(body.hair_color); let hair_color = color_spec.hair_color(body.species, body.hair_color);
let hair_rgb = hair_color.into();
let skin_rgb = body.species.skin_color(body.skin); let skin_rgb = body.species.skin_color(body.skin);
let eye_rgb = body.species.eye_color(body.eye_color); let eye_rgb = body.species.eye_color(body.eye_color);
@ -173,10 +213,10 @@ impl HumHeadSpec {
let eyes = match spec.eyes.get(body.eyes as usize) { let eyes = match spec.eyes.get(body.eyes as usize) {
Some(Some(spec)) => Some(( Some(Some(spec)) => Some((
color_segment( color_spec.color_segment(
graceful_load_mat_segment(&spec.0).map_rgb(|rgb| recolor_grey(rgb, hair_rgb)), graceful_load_mat_segment(&spec.0).map_rgb(|rgb| recolor_grey(rgb, hair_rgb)),
skin_rgb, skin_rgb,
hair_rgb, hair_color,
eye_rgb, eye_rgb,
), ),
Vec3::from(spec.1), Vec3::from(spec.1),
@ -220,7 +260,7 @@ impl HumHeadSpec {
let (head, origin_offset) = DynaUnionizer::new() let (head, origin_offset) = DynaUnionizer::new()
.add( .add(
color_segment(bare_head, skin_rgb, hair_rgb, eye_rgb), color_spec.color_segment(bare_head, skin_rgb, hair_color, eye_rgb),
spec.head.1.into(), spec.head.1.into(),
) )
.maybe_add(eyes) .maybe_add(eyes)
@ -356,6 +396,7 @@ impl HumArmorShoulderSpec {
fn mesh_shoulder( fn mesh_shoulder(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
shoulder: Option<&str>, shoulder: Option<&str>,
flipped: bool, flipped: bool,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
@ -372,14 +413,14 @@ impl HumArmorShoulderSpec {
&self.0.default &self.0.default
}; };
let mut shoulder_segment = color_segment( let mut shoulder_segment = color_spec.color_segment(
if flipped { if flipped {
graceful_load_mat_segment_flipped(&spec.left.vox_spec.0) graceful_load_mat_segment_flipped(&spec.left.vox_spec.0)
} else { } else {
graceful_load_mat_segment(&spec.right.vox_spec.0) graceful_load_mat_segment(&spec.right.vox_spec.0)
}, },
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
); );
@ -410,19 +451,21 @@ impl HumArmorShoulderSpec {
pub fn mesh_left_shoulder( pub fn mesh_left_shoulder(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
shoulder: Option<&str>, shoulder: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
self.mesh_shoulder(body, shoulder, true, generate_mesh) self.mesh_shoulder(body, color_spec, shoulder, true, generate_mesh)
} }
pub fn mesh_right_shoulder( pub fn mesh_right_shoulder(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
shoulder: Option<&str>, shoulder: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
self.mesh_shoulder(body, shoulder, false, generate_mesh) self.mesh_shoulder(body, color_spec, shoulder, false, generate_mesh)
} }
} }
// Chest // Chest
@ -435,6 +478,7 @@ impl HumArmorChestSpec {
pub fn mesh_chest( pub fn mesh_chest(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
chest: Option<&str>, chest: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -451,10 +495,10 @@ impl HumArmorChestSpec {
}; };
let color = |mat_segment| { let color = |mat_segment| {
color_segment( color_spec.color_segment(
mat_segment, mat_segment,
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
) )
}; };
@ -487,6 +531,7 @@ impl HumArmorHandSpec {
fn mesh_hand( fn mesh_hand(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
hand: Option<&str>, hand: Option<&str>,
flipped: bool, flipped: bool,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
@ -503,14 +548,14 @@ impl HumArmorHandSpec {
&self.0.default &self.0.default
}; };
let mut hand_segment = color_segment( let mut hand_segment = color_spec.color_segment(
if flipped { if flipped {
graceful_load_mat_segment_flipped(&spec.left.vox_spec.0) graceful_load_mat_segment_flipped(&spec.left.vox_spec.0)
} else { } else {
graceful_load_mat_segment(&spec.right.vox_spec.0) graceful_load_mat_segment(&spec.right.vox_spec.0)
}, },
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
); );
@ -535,19 +580,21 @@ impl HumArmorHandSpec {
pub fn mesh_left_hand( pub fn mesh_left_hand(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
hand: Option<&str>, hand: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
self.mesh_hand(body, hand, true, generate_mesh) self.mesh_hand(body, color_spec, hand, true, generate_mesh)
} }
pub fn mesh_right_hand( pub fn mesh_right_hand(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
hand: Option<&str>, hand: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
self.mesh_hand(body, hand, false, generate_mesh) self.mesh_hand(body, color_spec, hand, false, generate_mesh)
} }
} }
// Belt // Belt
@ -560,6 +607,7 @@ impl HumArmorBeltSpec {
pub fn mesh_belt( pub fn mesh_belt(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
belt: Option<&str>, belt: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -575,10 +623,10 @@ impl HumArmorBeltSpec {
&self.0.default &self.0.default
}; };
let mut belt_segment = color_segment( let mut belt_segment = color_spec.color_segment(
graceful_load_mat_segment(&spec.vox_spec.0), graceful_load_mat_segment(&spec.vox_spec.0),
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
); );
@ -600,6 +648,7 @@ impl HumArmorBackSpec {
pub fn mesh_back( pub fn mesh_back(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
back: Option<&str>, back: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -615,10 +664,10 @@ impl HumArmorBackSpec {
&self.0.default &self.0.default
}; };
let mut back_segment = color_segment( let mut back_segment = color_spec.color_segment(
graceful_load_mat_segment(&spec.vox_spec.0), graceful_load_mat_segment(&spec.vox_spec.0),
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
); );
if let Some(color) = spec.color { if let Some(color) = spec.color {
@ -639,6 +688,7 @@ impl HumArmorPantsSpec {
pub fn mesh_pants( pub fn mesh_pants(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
pants: Option<&str>, pants: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -655,10 +705,10 @@ impl HumArmorPantsSpec {
}; };
let color = |mat_segment| { let color = |mat_segment| {
color_segment( color_spec.color_segment(
mat_segment, mat_segment,
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
) )
}; };
@ -691,6 +741,7 @@ impl HumArmorFootSpec {
fn mesh_foot( fn mesh_foot(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
foot: Option<&str>, foot: Option<&str>,
flipped: bool, flipped: bool,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
@ -707,14 +758,14 @@ impl HumArmorFootSpec {
&self.0.default &self.0.default
}; };
let mut foot_segment = color_segment( let mut foot_segment = color_spec.color_segment(
if flipped { if flipped {
graceful_load_mat_segment_flipped(&spec.vox_spec.0) graceful_load_mat_segment_flipped(&spec.vox_spec.0)
} else { } else {
graceful_load_mat_segment(&spec.vox_spec.0) graceful_load_mat_segment(&spec.vox_spec.0)
}, },
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
); );
@ -729,19 +780,21 @@ impl HumArmorFootSpec {
pub fn mesh_left_foot( pub fn mesh_left_foot(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
foot: Option<&str>, foot: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
self.mesh_foot(body, foot, true, generate_mesh) self.mesh_foot(body, color_spec, foot, true, generate_mesh)
} }
pub fn mesh_right_foot( pub fn mesh_right_foot(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
foot: Option<&str>, foot: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
self.mesh_foot(body, foot, false, generate_mesh) self.mesh_foot(body, color_spec, foot, false, generate_mesh)
} }
} }
@ -802,6 +855,7 @@ impl HumArmorLanternSpec {
pub fn mesh_lantern( pub fn mesh_lantern(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
lantern: Option<&str>, lantern: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -817,10 +871,10 @@ impl HumArmorLanternSpec {
&self.0.default &self.0.default
}; };
let mut lantern_segment = color_segment( let mut lantern_segment = color_spec.color_segment(
graceful_load_mat_segment(&spec.vox_spec.0), graceful_load_mat_segment(&spec.vox_spec.0),
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
); );
if let Some(color) = spec.color { if let Some(color) = spec.color {
@ -841,6 +895,7 @@ impl HumArmorHeadSpec {
pub fn mesh_head( pub fn mesh_head(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
head: Option<&str>, head: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -857,10 +912,10 @@ impl HumArmorHeadSpec {
}; };
let color = |mat_segment| { let color = |mat_segment| {
color_segment( color_spec.color_segment(
mat_segment, mat_segment,
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
) )
}; };
@ -892,6 +947,7 @@ impl HumArmorTabardSpec {
pub fn mesh_tabard( pub fn mesh_tabard(
&self, &self,
body: &Body, body: &Body,
color_spec: &HumColorSpec,
tabard: Option<&str>, tabard: Option<&str>,
generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes, generate_mesh: impl FnOnce(Segment, Vec3<f32>) -> BoneMeshes,
) -> BoneMeshes { ) -> BoneMeshes {
@ -908,10 +964,10 @@ impl HumArmorTabardSpec {
}; };
let color = |mat_segment| { let color = |mat_segment| {
color_segment( color_spec.color_segment(
mat_segment, mat_segment,
body.species.skin_color(body.skin), body.species.skin_color(body.skin),
body.species.hair_color(body.hair_color), color_spec.hair_color(body.species, body.hair_color),
body.species.eye_color(body.eye_color), body.species.eye_color(body.eye_color),
) )
}; };

View File

@ -663,16 +663,6 @@ impl Scene {
// Construct matrices to transform from world space to light space for the sun // Construct matrices to transform from world space to light space for the sun
// and moon. // and moon.
let directed_light_dir = math::Vec3::from(sun_dir); let directed_light_dir = math::Vec3::from(sun_dir);
// First, add a projected matrix for our directed hard lights.
// NOTE: This can be hard, so we should probably look at techniques for
// restricting what's in the light frustum for things like sunlight
// (i.e. potential shadow receivers and potential shadow casters, as
// well as other culling). The sun position is currently scaled so
// that the focus is halfway between the near plane and far plane;
// however, there is probably a much smarter way to do this.
// NOTE: Multiplying by 1.5 as an approxmiation for √(2)/2, to make sure we
// capture all chunks.
let radius = 0.75;
// Optimal warping for directed lights: // Optimal warping for directed lights:
// //
@ -680,8 +670,6 @@ impl Scene {
// //
// where n is near plane, f is far plane, y is the tilt angle between view and // where n is near plane, f is far plane, y is the tilt angle between view and
// light directon, and n_opt is the optimal near plane. // light directon, and n_opt is the optimal near plane.
let directed_near = 1.0;
let _directed_far = directed_near + 2.0 * radius;
// We also want a way to transform and scale this matrix (* 0.5 + 0.5) in order // We also want a way to transform and scale this matrix (* 0.5 + 0.5) in order
// to transform it correctly into texture coordinates, as well as // to transform it correctly into texture coordinates, as well as
// OpenGL coordinates. Note that the matrix for directional light // OpenGL coordinates. Note that the matrix for directional light
@ -692,7 +680,6 @@ impl Scene {
// matrix; this helps avoid precision loss during the // matrix; this helps avoid precision loss during the
// multiplication. // multiplication.
let look_at = math::Vec3::from(cam_pos); let look_at = math::Vec3::from(cam_pos);
let _light_scale = 1.5 * radius;
// We upload view matrices as well, to assist in linearizing vertex positions. // We upload view matrices as well, to assist in linearizing vertex positions.
// (only for directional lights, so far). // (only for directional lights, so far).
let mut directed_shadow_mats = Vec::with_capacity(6); let mut directed_shadow_mats = Vec::with_capacity(6);
@ -710,9 +697,6 @@ impl Scene {
// Now, construct the full projection matrices in the first two directed light // Now, construct the full projection matrices in the first two directed light
// slots. // slots.
let mut shadow_mats = Vec::with_capacity(6 * (lights.len() + 1)); let mut shadow_mats = Vec::with_capacity(6 * (lights.len() + 1));
let z_n = 1.0;
let _z_f = f64::from(camera::FAR_PLANE);
let _scalar_fov = compute_scalar_fov(z_n, f64::from(fov), f64::from(aspect_ratio));
shadow_mats.extend(directed_shadow_mats.iter().enumerate().map( shadow_mats.extend(directed_shadow_mats.iter().enumerate().map(
move |(idx, &light_view_mat)| { move |(idx, &light_view_mat)| {
if idx >= NUM_DIRECTED_LIGHTS { if idx >= NUM_DIRECTED_LIGHTS {
@ -847,11 +831,6 @@ impl Scene {
light_focus_pos.z, light_focus_pos.z,
)); ));
let shadow_view_mat: math::Mat4<f32> = w_v * light_all_mat; let shadow_view_mat: math::Mat4<f32> = w_v * light_all_mat;
let _bounds0 = math::fit_psr(
shadow_view_mat,
visible_light_volume.iter().copied(),
math::Vec4::homogenized,
);
let w_p: math::Mat4<f32> = { let w_p: math::Mat4<f32> = {
if factor > EPSILON_UPSILON { if factor > EPSILON_UPSILON {
// Projection for y // Projection for y