ray_tracing_utility/serialization/
texture.rs1use crate::serialization::RayTracingObject;
2use ray_tracing_core::texture;
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::error::Error;
6use std::rc::Rc;
7use std::sync::Arc;
8
9mod constant_texture;
10pub use self::constant_texture::*;
11
12mod bitmap_file;
13pub use self::bitmap_file::*;
14
15mod checker_texture;
16pub use self::checker_texture::*;
17
18mod blend_texture;
19pub use self::blend_texture::*;
20
21mod noise_texture;
22pub use self::noise_texture::*;
23
24mod color_filter;
25pub use self::color_filter::*;
26
27pub struct SerializeTexture {
28 pub object_map: Rc<RefCell<HashMap<usize, RayTracingObject>>>,
29}
30
31impl SerializeTexture {
32 fn add_texture(&mut self, t: Arc<dyn texture::Texture>) -> Result<(), Box<dyn Error>> {
33 if !self.object_map.borrow().contains_key(&t.get_id()) {
34 t.accept(self)?;
35 }
36 Ok(())
37 }
38}
39
40impl texture::Visitor for SerializeTexture {
41 fn visit_constant_texture(
42 &mut self,
43 t: &texture::ConstantTexture,
44 ) -> Result<(), Box<dyn Error>> {
45 self.object_map.borrow_mut().insert(
46 t.id,
47 RayTracingObject::ConstantTexture(ConstantTexture::from_texture(t)?),
48 );
49 Ok(())
50 }
51
52 fn visit_bitmap_texture(&mut self, _: &texture::BitmapTexture) -> Result<(), Box<dyn Error>> {
53 Err("not yet implemented".into())
54 }
55
56 fn visit_checker_texture(&mut self, t: &texture::CheckerTexture) -> Result<(), Box<dyn Error>> {
57 self.add_texture(t.even_texture.clone())?;
58 self.add_texture(t.odd_texture.clone())?;
59
60 self.object_map.borrow_mut().insert(
61 t.id,
62 RayTracingObject::CheckerTexture(CheckerTexture::from_texture(t)?),
63 );
64 Ok(())
65 }
66
67 fn visit_blend_texture(&mut self, t: &texture::BlendTexture) -> Result<(), Box<dyn Error>> {
68 self.add_texture(t.first_texture.clone())?;
69 self.add_texture(t.second_texture.clone())?;
70 self.add_texture(t.mask_texture.clone())?;
71
72 self.object_map.borrow_mut().insert(
73 t.id,
74 RayTracingObject::BlendTexture(BlendTexture::from_texture(t)?),
75 );
76 Ok(())
77 }
78
79 fn visit_noise_texture(&mut self, t: &texture::NoiseTexture) -> Result<(), Box<dyn Error>> {
80 self.add_texture(t.min_texture.clone())?;
81 self.add_texture(t.max_texture.clone())?;
82
83 self.object_map.borrow_mut().insert(
84 t.id,
85 RayTracingObject::NoiseTexture(NoiseTexture::from_texture(t)?),
86 );
87 Ok(())
88 }
89
90 fn visit_color_filter(&mut self, t: &texture::ColorFilter) -> Result<(), Box<dyn Error>> {
91 self.add_texture(t.texture.clone())?;
92
93 self.object_map.borrow_mut().insert(
94 t.id,
95 RayTracingObject::ColorFilter(ColorFilter::from_texture(t)?),
96 );
97 Ok(())
98 }
99}
100
101#[cfg(test)]
102mod serialize_texture_test {
103 use super::*;
104 use ray_tracing_core::texture::Texture;
105 use ray_tracing_core::types::{ColorRGBA, Vector3};
106
107 #[test]
108 fn visit_constant_texture_test() {
109 let mut s = SerializeTexture {
110 object_map: Rc::new(RefCell::new(HashMap::default())),
111 };
112 let ct = texture::ConstantTexture::new(ColorRGBA::new(0.0, 0.0, 0.0, 1.0));
113 ct.accept(&mut s).unwrap();
114 assert_eq!(s.object_map.borrow_mut().len(), 1);
115 match &s.object_map.borrow_mut()[&ct.id] {
116 RayTracingObject::ConstantTexture(_) => (),
117 _ => panic!("unexpected ray tracing object"),
118 };
119 }
120
121 #[test]
122 fn visit_checker_texture_test() {
123 let mut s = SerializeTexture {
124 object_map: Rc::new(RefCell::new(HashMap::default())),
125 };
126 let ct1 = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
127 0.0, 0.0, 0.0, 1.0,
128 )));
129 let ct1_id = ct1.clone().id;
130 let ct2 = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
131 1.0, 1.0, 1.0, 1.0,
132 )));
133 let ct2_id = ct2.clone().id;
134 let ct = texture::CheckerTexture::new(Vector3::new(1.0, 1.0, 1.0), ct1, ct2);
135 ct.accept(&mut s).unwrap();
136 assert_eq!(s.object_map.borrow_mut().len(), 3);
137 match &s.object_map.borrow_mut()[&ct1_id] {
138 RayTracingObject::ConstantTexture(_) => (),
139 _ => panic!("unexpected ray tracing object"),
140 };
141 match &s.object_map.borrow_mut()[&ct2_id] {
142 RayTracingObject::ConstantTexture(_) => (),
143 _ => panic!("unexpected ray tracing object"),
144 };
145 match &s.object_map.borrow_mut()[&ct.id] {
146 RayTracingObject::CheckerTexture(_) => (),
147 _ => panic!("unexpected ray tracing object"),
148 };
149 }
150
151 #[test]
152 fn visit_blend_texture_test() {
153 let mut s = SerializeTexture {
154 object_map: Rc::new(RefCell::new(HashMap::default())),
155 };
156 let ct1 = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
157 0.0, 0.0, 0.0, 1.0,
158 )));
159 let ct1_id = ct1.clone().id;
160 let ct2 = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
161 1.0, 1.0, 1.0, 1.0,
162 )));
163 let ct2_id = ct2.clone().id;
164 let mt = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
165 0.5, 0.5, 0.5, 0.5,
166 )));
167 let mt_id = mt.clone().id;
168 let ct = texture::BlendTexture::new(Vector3::new(0.5, 0.5, 0.5), ct1, ct2, mt);
169 ct.accept(&mut s).unwrap();
170 assert_eq!(s.object_map.borrow_mut().len(), 4);
171 match &s.object_map.borrow_mut()[&ct1_id] {
172 RayTracingObject::ConstantTexture(_) => (),
173 _ => panic!("unexpected ray tracing object"),
174 };
175 match &s.object_map.borrow_mut()[&ct2_id] {
176 RayTracingObject::ConstantTexture(_) => (),
177 _ => panic!("unexpected ray tracing object"),
178 };
179 match &s.object_map.borrow_mut()[&mt_id] {
180 RayTracingObject::ConstantTexture(_) => (),
181 _ => panic!("unexpected ray tracing object"),
182 };
183 match &s.object_map.borrow_mut()[&ct.id] {
184 RayTracingObject::BlendTexture(_) => (),
185 _ => panic!("unexpected ray tracing object"),
186 };
187 }
188
189 #[test]
190 fn visit_noise_texture_test() {
191 let mut s = SerializeTexture {
192 object_map: Rc::new(RefCell::new(HashMap::default())),
193 };
194 let ct1 = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
195 0.0, 0.0, 0.0, 1.0,
196 )));
197 let ct1_id = ct1.clone().id;
198 let ct2 = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
199 1.0, 1.0, 1.0, 1.0,
200 )));
201 let ct2_id = ct2.clone().id;
202 let ct = texture::NoiseTexture::new(1.0, texture::NoiseType::Default, ct1, ct2);
203 ct.accept(&mut s).unwrap();
204 assert_eq!(s.object_map.borrow_mut().len(), 3);
205 match &s.object_map.borrow_mut()[&ct1_id] {
206 RayTracingObject::ConstantTexture(_) => (),
207 _ => panic!("unexpected ray tracing object"),
208 };
209 match &s.object_map.borrow_mut()[&ct2_id] {
210 RayTracingObject::ConstantTexture(_) => (),
211 _ => panic!("unexpected ray tracing object"),
212 };
213 match &s.object_map.borrow_mut()[&ct.id] {
214 RayTracingObject::NoiseTexture(_) => (),
215 _ => panic!("unexpected ray tracing object"),
216 };
217 }
218
219 #[test]
220 fn visit_color_filter_test() {
221 let mut s = SerializeTexture {
222 object_map: Rc::new(RefCell::new(HashMap::default())),
223 };
224 let ct = Arc::new(texture::ConstantTexture::new(ColorRGBA::new(
225 1.0, 1.0, 1.0, 1.0,
226 )));
227 let ct_id = ct.clone().id;
228 let cf = texture::ColorFilter::new(
229 ColorRGBA::new(0.0, 0.0, 0.0, 0.0),
230 ColorRGBA::new(1.0, 0.5, 0.25, 1.0),
231 ColorRGBA::new(0.0, 0.0, 0.0, 0.0),
232 ct,
233 );
234 cf.accept(&mut s).unwrap();
235 assert_eq!(s.object_map.borrow_mut().len(), 2);
236 match &s.object_map.borrow_mut()[&ct_id] {
237 RayTracingObject::ConstantTexture(_) => (),
238 _ => panic!("unexpected ray tracing object"),
239 };
240 match &s.object_map.borrow_mut()[&cf.id] {
241 RayTracingObject::ColorFilter(_) => (),
242 _ => panic!("unexpected ray tracing object"),
243 };
244 }
245}