gltf_v1/
light.rs

1use json::extensions::light::Type;
2
3use crate::Document;
4
5#[derive(Clone, Debug)]
6pub struct Light<'a> {
7    /// The parent `Document` struct.
8    #[allow(dead_code)]
9    document: &'a Document,
10
11    /// The corresponding JSON index.
12    index: &'a String,
13
14    /// The corresponding JSON struct.
15    json: &'a json::extensions::light::Light,
16}
17
18impl<'a> Light<'a> {
19    /// Constructs a `Buffer`.
20    pub(crate) fn new(
21        document: &'a Document,
22        index: &'a String,
23        json: &'a json::extensions::light::Light,
24    ) -> Self {
25        Self {
26            document,
27            index,
28            json,
29        }
30    }
31
32    /// Returns the internal JSON index.
33    pub fn index(&self) -> &str {
34        self.index
35    }
36    pub fn name(&self) -> Option<&'a str> {
37        self.json.name.as_deref()
38    }
39    pub fn color(&self) -> [f32; 4] {
40        match self.json.type_ {
41            json::validation::Checked::Valid(Type::Ambient) => {
42                self.json.ambient.as_ref().unwrap().color
43            }
44            json::validation::Checked::Valid(Type::Directional) => {
45                self.json.directional.as_ref().unwrap().color
46            }
47            json::validation::Checked::Valid(Type::Point) => {
48                self.json.point.as_ref().unwrap().color
49            }
50            json::validation::Checked::Valid(Type::Spot) => self.json.spot.as_ref().unwrap().color,
51            _ => [0.0, 0.0, 0.0, 1.0],
52        }
53    }
54    pub fn constant_attenuation(&self) -> f32 {
55        match self.json.type_ {
56            json::validation::Checked::Valid(Type::Point) => {
57                self.json.point.as_ref().unwrap().constant_attenuation
58            }
59            json::validation::Checked::Valid(Type::Spot) => {
60                self.json.spot.as_ref().unwrap().constant_attenuation
61            }
62            _ => 0.0,
63        }
64    }
65    pub fn linear_attenuation(&self) -> f32 {
66        match self.json.type_ {
67            json::validation::Checked::Valid(Type::Point) => {
68                self.json.point.as_ref().unwrap().linear_attenuation
69            }
70            json::validation::Checked::Valid(Type::Spot) => {
71                self.json.spot.as_ref().unwrap().linear_attenuation
72            }
73            _ => 1.0,
74        }
75    }
76    pub fn quadratic_attenuation(&self) -> f32 {
77        match self.json.type_ {
78            json::validation::Checked::Valid(Type::Point) => {
79                self.json.point.as_ref().unwrap().quadratic_attenuation
80            }
81            json::validation::Checked::Valid(Type::Spot) => {
82                self.json.spot.as_ref().unwrap().quadratic_attenuation
83            }
84            _ => 1.0,
85        }
86    }
87    pub fn distance(&self) -> f32 {
88        match self.json.type_ {
89            json::validation::Checked::Valid(Type::Point) => {
90                self.json.point.as_ref().unwrap().distance
91            }
92            json::validation::Checked::Valid(Type::Spot) => {
93                self.json.spot.as_ref().unwrap().distance
94            }
95            _ => 0.0,
96        }
97    }
98    pub fn falloff_angle(&self) -> f32 {
99        match self.json.type_ {
100            json::validation::Checked::Valid(Type::Spot) => {
101                self.json.spot.as_ref().unwrap().falloff_angle
102            }
103            _ => std::f32::consts::PI / 2.0,
104        }
105    }
106    pub fn falloff_exponent(&self) -> f32 {
107        match self.json.type_ {
108            json::validation::Checked::Valid(Type::Spot) => {
109                self.json.spot.as_ref().unwrap().falloff_exponent
110            }
111            _ => 0.0,
112        }
113    }
114    pub fn kind(&self) -> Kind {
115        match self.json.type_ {
116            json::validation::Checked::Valid(Type::Ambient) => Kind::Ambient,
117            json::validation::Checked::Valid(Type::Directional) => Kind::Directional,
118            json::validation::Checked::Valid(Type::Point) => Kind::Point,
119            json::validation::Checked::Valid(Type::Spot) => Kind::Spot,
120            _ => Kind::Ambient,
121        }
122    }
123}
124
125pub enum Kind {
126    Ambient,
127    Directional,
128    Point,
129    Spot,
130}
131
132/// An `Iterator` that visits every buffer in a glTF asset.
133#[derive(Clone, Debug)]
134pub struct Lights<'a> {
135    /// Internal buffer iterator.
136    pub(crate) iter: indexmap::map::Iter<'a, String, gltf_v1_json::extensions::Light>,
137
138    /// The internal root glTF object.
139    pub(crate) document: &'a Document,
140}
141
142impl ExactSizeIterator for Lights<'_> {}
143impl<'a> Iterator for Lights<'a> {
144    type Item = Light<'a>;
145    fn next(&mut self) -> Option<Self::Item> {
146        self.iter
147            .next()
148            .map(|(index, json)| Light::new(self.document, index, json))
149    }
150    fn size_hint(&self) -> (usize, Option<usize>) {
151        self.iter.size_hint()
152    }
153    fn count(self) -> usize {
154        self.iter.count()
155    }
156    fn last(self) -> Option<Self::Item> {
157        let document = self.document;
158        self.iter
159            .last()
160            .map(|(index, json)| Light::new(document, index, json))
161    }
162    fn nth(&mut self, n: usize) -> Option<Self::Item> {
163        self.iter
164            .nth(n)
165            .map(|(index, json)| Light::new(self.document, index, json))
166    }
167}