pub mod colorspace;
pub mod time;
use rgb::RGB;
use crate::{
map::{Angles, Entity},
source::ColorBrightness,
};
#[derive(Clone, Debug, PartialEq)]
pub struct GlobalLighting {
pub sun_color: ColorBrightness,
pub sun_dir: Angles,
pub amb_color: ColorBrightness,
pub amb_dir: Angles, pub dir_lights: Vec<(ColorBrightness, Angles)>,
}
impl GlobalLighting {
pub fn to_entity(&self) -> Entity<String> {
todo!()
}
}
impl Default for GlobalLighting {
fn default() -> Self {
Self {
sun_color: ColorBrightness::new(255, 255, 255, 200),
sun_dir: Angles::default(),
amb_color: ColorBrightness::new(255, 255, 255, 50),
amb_dir: Angles::default(),
dir_lights: Default::default(),
}
}
}
pub fn pitch_to_rgb(pitch: f64) -> RGB<u8> {
let rgb = if pitch < 0.0 {
let mut srgb_linear =
colorspace::cct_to_xy(night_pitch_to_temp(-pitch)).to_xyz(50.0).to_rgb();
srgb_linear.normalize_mut();
srgb_linear.to_srgb()
} else {
let mut srgb_linear =
colorspace::cct_to_xy(day_pitch_to_temp(pitch)).to_xyz(50.0).to_rgb();
srgb_linear.normalize_mut();
srgb_linear.to_srgb()
};
rgb
}
fn day_pitch_to_temp(pitch: f64) -> f64 {
debug_assert!(pitch >= 0.0);
const STEEP_EXP: f64 = 1.0 / 3.0;
const FLAT_EXP: f64 = 0.07477_47707_7302;
if pitch < 1.0 {
2500.0
} else if pitch < 14.5969 {
2500.0 * pitch.powf(STEEP_EXP)
} else {
5000.0 * pitch.powf(FLAT_EXP)
}
}
fn night_pitch_to_temp(pitch: f64) -> f64 {
if pitch < 1.0 {
2500.0
} else if pitch < 3.1637 {
2500.0 * pitch
} else {
5000.0 * pitch.powf(0.39818561239203)
}
}