easy_gltf/scene/
light.rs

1use cgmath::*;
2use gltf::khr_lights_punctual::{Kind, Light as GltfLight};
3
4/// Represents a light.
5#[derive(Clone, Debug)]
6pub enum Light {
7    /// Directional lights are light sources that act as though they are
8    /// infinitely far away and emit light in the `direction`. Because it is at
9    /// an infinite distance, the light is not attenuated. Its intensity is
10    /// defined in lumens per metre squared, or lux (lm/m2).
11    Directional {
12        #[cfg(feature = "names")]
13        /// Light name. Requires the `names` feature.
14        name: Option<String>,
15        #[cfg(feature = "extras")]
16        /// Light extra data. Requires the `extras` feature
17        extras: gltf::json::extras::Extras,
18        /// Direction of the directional light
19        direction: Vector3<f32>,
20        /// Color of the directional light
21        color: Vector3<f32>,
22        /// Intensity of the directional light
23        intensity: f32,
24    },
25
26    /// Point lights emit light in all directions from their `position` in space;
27    /// The brightness of the light attenuates in a physically correct manner as
28    /// distance increases from the light's position (i.e.  brightness goes like
29    /// the inverse square of the distance). Point light intensity is defined in
30    /// candela, which is lumens per square radian (lm/sr).
31    Point {
32        #[cfg(feature = "names")]
33        /// Light name. Requires the `names` feature.
34        name: Option<String>,
35        #[cfg(feature = "extras")]
36        /// Light extra data. Requires the `extras` feature
37        extras: gltf::json::extras::Extras,
38        /// Position of the point light
39        position: Vector3<f32>,
40        /// Color of the point light
41        color: Vector3<f32>,
42        /// Intensity of the point light
43        intensity: f32,
44    },
45
46    /// Spot lights emit light in a cone in `direction`. The angle and falloff
47    /// of the cone is defined using two numbers, the `inner_cone_angle` and
48    /// `outer_cone_angle`. As with point lights, the brightness also attenuates
49    /// in a physically correct manner as distance increases from the light's
50    /// position (i.e. brightness goes like the inverse square of the distance).
51    /// Spot light intensity refers to the brightness inside the
52    /// `inner_cone_angle` (and at the location of the light) and is defined in
53    /// candela, which is lumens per square radian (lm/sr). Engines that don't
54    /// support two angles for spotlights should use outer_cone_angle as the
55    /// spotlight angle (leaving `inner_cone_angle` to implicitly be `0`).
56    Spot {
57        #[cfg(feature = "names")]
58        /// Light name. Requires the `names` feature.
59        name: Option<String>,
60        #[cfg(feature = "extras")]
61        /// Light extra data. Requires the `extras` feature
62        extras: gltf::json::extras::Extras,
63        /// Position of the spot light
64        position: Vector3<f32>,
65        /// Direction of the spot light
66        direction: Vector3<f32>,
67        /// Color of the spot light
68        color: Vector3<f32>,
69        /// Intensity of the spot light
70        intensity: f32,
71        /// Inner cone angle of the spot light
72        inner_cone_angle: f32,
73        /// Outer cone angle of the spot light
74        outer_cone_angle: f32,
75    },
76}
77
78impl Light {
79    pub(crate) fn load(gltf_light: GltfLight, transform: &Matrix4<f32>) -> Self {
80        match gltf_light.kind() {
81            Kind::Directional => Light::Directional {
82                #[cfg(feature = "names")]
83                name: gltf_light.name().map(String::from),
84                #[cfg(feature = "extras")]
85                extras: gltf_light.extras().clone(),
86                direction: -1.
87                    * Vector3::new(transform[2][0], transform[2][1], transform[2][2]).normalize(),
88                intensity: gltf_light.intensity(),
89                color: Vector3::from(gltf_light.color()),
90            },
91            Kind::Point => Light::Point {
92                #[cfg(feature = "names")]
93                name: gltf_light.name().map(String::from),
94                #[cfg(feature = "extras")]
95                extras: gltf_light.extras().clone(),
96                position: Vector3::new(transform[3][0], transform[3][1], transform[3][2]),
97                intensity: gltf_light.intensity(),
98                color: Vector3::from(gltf_light.color()),
99            },
100            Kind::Spot {
101                inner_cone_angle,
102                outer_cone_angle,
103            } => Light::Spot {
104                #[cfg(feature = "names")]
105                name: gltf_light.name().map(String::from),
106                #[cfg(feature = "extras")]
107                extras: gltf_light.extras().clone(),
108                position: Vector3::new(transform[3][0], transform[3][1], transform[3][2]),
109                direction: -1.
110                    * Vector3::new(transform[2][0], transform[2][1], transform[2][2]).normalize(),
111                intensity: gltf_light.intensity(),
112                color: Vector3::from(gltf_light.color()),
113                inner_cone_angle,
114                outer_cone_angle,
115            },
116        }
117    }
118}