1use json::extensions::light::Type;
2
3use crate::Document;
4
5#[derive(Clone, Debug)]
6pub struct Light<'a> {
7 #[allow(dead_code)]
9 document: &'a Document,
10
11 index: &'a String,
13
14 json: &'a json::extensions::light::Light,
16}
17
18impl<'a> Light<'a> {
19 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 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#[derive(Clone, Debug)]
134pub struct Lights<'a> {
135 pub(crate) iter: indexmap::map::Iter<'a, String, gltf_v1_json::extensions::Light>,
137
138 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}