1extern crate nalgebra as na;
2extern crate nalgebra_glm as glm;
3
4use crate::{
5 components::{PosLookat, Projection, ShadowCaster, SpotLightBundle},
6 scene::Scene,
7};
8use gloss_hecs::Entity;
9
10pub struct Light {
13 pub entity: Entity,
14}
15
16impl Light {
17 #[allow(clippy::missing_panics_doc)] pub fn new(name: &str, scene: &mut Scene) -> Self {
20 let entity = scene
21 .get_or_create_hidden_entity(name)
22 .insert_bundle(SpotLightBundle::default())
23 .insert(ShadowCaster::default())
24 .entity();
25
26 Self { entity }
27 }
28
29 pub fn from_entity(entity: Entity) -> Self {
30 Self { entity }
31 }
32
33 pub fn view_matrix(&self, scene: &Scene) -> na::Matrix4<f32> {
36 let pos_lookat = scene.get_comp::<&PosLookat>(&self.entity).unwrap();
37 pos_lookat.view_matrix()
38 }
39
40 pub fn proj_matrix(&self, scene: &Scene) -> na::Matrix4<f32> {
44 let proj = scene.get_comp::<&Projection>(&self.entity).unwrap();
45 match *proj {
46 Projection::WithFov(ref proj) => proj.proj_matrix(),
47 Projection::WithIntrinsics(_) => {
48 panic!("We don't deal with light that have projection as intrinsics")
49 }
50 }
51 }
52
53 pub fn proj_matrix_reverse_z(&self, scene: &Scene) -> na::Matrix4<f32> {
57 let proj = scene.get_comp::<&Projection>(&self.entity).unwrap();
58 match *proj {
59 Projection::WithFov(ref proj) => proj.proj_matrix_reverse_z(),
60 Projection::WithIntrinsics(_) => {
61 panic!("We don't deal with light that have projection as intrinsics")
62 }
63 }
64 }
65
66 pub fn intensity_for_point(light_pos: &na::Point3<f32>, point: &na::Point3<f32>, desired_intensity_at_point: f32) -> f32 {
69 let dist = (light_pos - point).norm();
70 let attenuation = 1.0 / (dist * dist);
71 desired_intensity_at_point / attenuation
75 }
76}