use crate::color::Color;
use glamx::Vec3;
pub const MAX_LIGHTS: usize = 8;
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LightType {
Point {
attenuation_radius: f32,
},
Directional(Vec3),
Spot {
inner_cone_angle: f32,
outer_cone_angle: f32,
attenuation_radius: f32,
},
}
impl Default for LightType {
fn default() -> Self {
LightType::Point {
attenuation_radius: 100.0,
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Light {
pub light_type: LightType,
pub color: Color,
pub intensity: f32,
pub enabled: bool,
}
impl Default for Light {
fn default() -> Self {
Self {
light_type: LightType::default(),
color: crate::color::WHITE,
intensity: 3.0,
enabled: true,
}
}
}
impl Light {
pub fn point(attenuation_radius: f32) -> Self {
Self {
light_type: LightType::Point { attenuation_radius },
..Default::default()
}
}
pub fn directional(dir: Vec3) -> Self {
Self {
light_type: LightType::Directional(dir),
..Default::default()
}
}
pub fn spot(inner_cone_angle: f32, outer_cone_angle: f32, attenuation_radius: f32) -> Self {
Self {
light_type: LightType::Spot {
inner_cone_angle,
outer_cone_angle,
attenuation_radius,
},
..Default::default()
}
}
pub fn with_color(mut self, color: Color) -> Self {
self.color = color;
self
}
pub fn with_intensity(mut self, intensity: f32) -> Self {
self.intensity = intensity;
self
}
pub fn with_enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
}
#[derive(Clone, Debug)]
pub struct CollectedLight {
pub light_type: LightType,
pub color: Vec3,
pub intensity: f32,
pub world_position: Vec3,
pub world_direction: Vec3,
}
#[derive(Clone, Debug)]
pub struct LightCollection {
pub lights: Vec<CollectedLight>,
pub ambient: f32,
}
impl Default for LightCollection {
fn default() -> Self {
Self::new()
}
}
impl LightCollection {
pub fn new() -> Self {
Self {
lights: Vec::with_capacity(MAX_LIGHTS),
ambient: 0.2,
}
}
pub fn with_ambient(ambient: f32) -> Self {
Self {
lights: Vec::with_capacity(MAX_LIGHTS),
ambient,
}
}
pub fn add(&mut self, light: CollectedLight) -> bool {
if self.lights.len() < MAX_LIGHTS {
self.lights.push(light);
true
} else {
false
}
}
pub fn is_full(&self) -> bool {
self.lights.len() >= MAX_LIGHTS
}
pub fn len(&self) -> usize {
self.lights.len()
}
pub fn is_empty(&self) -> bool {
self.lights.is_empty()
}
pub fn clear(&mut self) {
self.lights.clear();
}
}