use crate::color::Color;
use glamx::Vec2;
use std::cell::RefCell;
pub const MAX_LIGHTS_2D: usize = 16;
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub enum Light2dKind {
#[default]
Point,
Spot,
}
#[derive(Copy, Clone, Debug)]
pub struct Light2d {
pub position: Vec2,
pub height: f32,
pub color: Color,
pub intensity: f32,
pub radius: f32,
pub kind: Light2dKind,
pub direction: Vec2,
pub inner_angle: f32,
pub outer_angle: f32,
}
impl Default for Light2d {
fn default() -> Self {
Light2d {
position: Vec2::ZERO,
height: 60.0,
color: Color::new(1.0, 1.0, 1.0, 1.0),
intensity: 1.0,
radius: 300.0,
kind: Light2dKind::Point,
direction: Vec2::new(0.0, -1.0),
inner_angle: 0.3,
outer_angle: 0.6,
}
}
}
impl Light2d {
pub fn point(position: Vec2, color: Color, intensity: f32, radius: f32) -> Self {
Light2d {
position,
color,
intensity,
radius,
kind: Light2dKind::Point,
..Default::default()
}
}
pub fn spot(
position: Vec2,
direction: Vec2,
color: Color,
intensity: f32,
radius: f32,
inner: f32,
outer: f32,
) -> Self {
Light2d {
position,
direction,
color,
intensity,
radius,
kind: Light2dKind::Spot,
inner_angle: inner,
outer_angle: outer,
..Default::default()
}
}
pub fn with_height(mut self, height: f32) -> Self {
self.height = height;
self
}
}
pub struct Light2dManager {
lights: Vec<Light2d>,
ambient: Color,
}
thread_local!(static KEY_LIGHT2D_MANAGER: RefCell<Light2dManager> = RefCell::new(Light2dManager::new()));
impl Default for Light2dManager {
fn default() -> Self {
Self::new()
}
}
impl Light2dManager {
pub fn new() -> Self {
Light2dManager {
lights: Vec::new(),
ambient: Color::new(0.1, 0.1, 0.1, 1.0),
}
}
pub fn get_global_manager<T, F: FnMut(&mut Light2dManager) -> T>(mut f: F) -> T {
KEY_LIGHT2D_MANAGER.with(|m| f(&mut m.borrow_mut()))
}
pub fn set_lights(&mut self, lights: &[Light2d]) {
self.lights.clear();
self.lights
.extend(lights.iter().take(MAX_LIGHTS_2D).copied());
}
pub fn push(&mut self, light: Light2d) {
if self.lights.len() < MAX_LIGHTS_2D {
self.lights.push(light);
}
}
pub fn clear(&mut self) {
self.lights.clear();
}
pub fn lights(&self) -> &[Light2d] {
&self.lights
}
pub fn set_ambient(&mut self, ambient: Color) {
self.ambient = ambient;
}
pub fn ambient(&self) -> Color {
self.ambient
}
}