1use std::cell::Cell;
3use std::sync::Arc;
4use crate::core::camera::{Camera, CameraSample};
6use crate::core::film::Film;
7use crate::core::geometry::{Bounds2f, Point2f, Point3f, Ray, RayDifferential, Vector3f};
8use crate::core::interaction::InteractionCommon;
9use crate::core::light::VisibilityTester;
10use crate::core::medium::Medium;
11use crate::core::paramset::ParamSet;
12use crate::core::pbrt::lerp;
13use crate::core::pbrt::{Float, Spectrum};
14use crate::core::sampling::concentric_sample_disk;
15use crate::core::transform::{AnimatedTransform, Transform};
16
17pub struct OrthographicCamera {
20 pub camera_to_world: AnimatedTransform,
22 pub shutter_open: Float,
23 pub shutter_close: Float,
24 pub film: Arc<Film>,
25 pub medium: Option<Arc<Medium>>,
26 pub camera_to_screen: Transform,
28 pub raster_to_camera: Transform,
29 pub screen_to_raster: Transform,
30 pub raster_to_screen: Transform,
31 pub lens_radius: Float,
32 pub focal_distance: Float,
33 pub dx_camera: Vector3f,
35 pub dy_camera: Vector3f,
36}
37
38impl OrthographicCamera {
39 pub fn new(
40 camera_to_world: AnimatedTransform,
41 screen_window: Bounds2f,
42 shutter_open: Float,
43 shutter_close: Float,
44 lens_radius: Float,
45 focal_distance: Float,
46 film: Arc<Film>,
47 medium: Option<Arc<Medium>>,
48 ) -> Self {
49 let camera_to_screen: Transform = Transform::orthographic(0.0 as Float, 1.0 as Float);
51 let scale1 = Transform::scale(
54 film.full_resolution.x as Float,
55 film.full_resolution.y as Float,
56 1.0,
57 );
58 let scale2 = Transform::scale(
59 1.0 / (screen_window.p_max.x - screen_window.p_min.x),
60 1.0 / (screen_window.p_min.y - screen_window.p_max.y),
61 1.0,
62 );
63 let translate = Transform::translate(&Vector3f {
64 x: -screen_window.p_min.x,
65 y: -screen_window.p_max.y,
66 z: 0.0,
67 });
68 let screen_to_raster = scale1 * scale2 * translate;
69 let raster_to_screen = Transform::inverse(&screen_to_raster);
70 let raster_to_camera = Transform::inverse(&camera_to_screen) * raster_to_screen;
71 let dx_camera: Vector3f = raster_to_camera.transform_vector(&Vector3f {
74 x: 1.0,
75 y: 0.0,
76 z: 0.0,
77 });
78 let dy_camera: Vector3f = raster_to_camera.transform_vector(&Vector3f {
79 x: 0.0,
80 y: 1.0,
81 z: 0.0,
82 });
83 OrthographicCamera {
84 camera_to_world,
85 shutter_open,
86 shutter_close,
87 film,
88 medium,
89 camera_to_screen,
90 raster_to_camera,
91 screen_to_raster,
92 raster_to_screen,
93 lens_radius,
94 focal_distance,
95 dx_camera,
96 dy_camera,
97 }
98 }
99 pub fn create(
100 params: &ParamSet,
101 cam2world: AnimatedTransform,
102 film: Arc<Film>,
103 medium: Option<Arc<Medium>>,
104 ) -> Arc<Camera> {
105 let shutteropen: Float = params.find_one_float("shutteropen", 0.0);
106 let shutterclose: Float = params.find_one_float("shutterclose", 1.0);
107 assert!(shutterclose >= shutteropen);
109 let lensradius: Float = params.find_one_float("lensradius", 0.0);
110 let focaldistance: Float = params.find_one_float("focaldistance", 1e6);
111 let frame: Float = params.find_one_float(
112 "frameaspectratio",
113 (film.full_resolution.x as Float) / (film.full_resolution.y as Float),
114 );
115 let mut screen: Bounds2f = Bounds2f::default();
116 if frame > 1.0 {
117 screen.p_min.x = -frame;
118 screen.p_max.x = frame;
119 screen.p_min.y = -1.0;
120 screen.p_max.y = 1.0;
121 } else {
122 screen.p_min.x = -1.0;
123 screen.p_max.x = 1.0;
124 screen.p_min.y = -1.0 / frame;
125 screen.p_max.y = 1.0 / frame;
126 }
127 let sw: Vec<Float> = params.find_float("screenwindow");
128 if !sw.is_empty() {
129 if sw.len() == 4 {
130 screen.p_min.x = sw[0];
131 screen.p_max.x = sw[1];
132 screen.p_min.y = sw[2];
133 screen.p_max.y = sw[3];
134 } else {
135 panic!("\"screenwindow\" should have four values");
136 }
137 }
138 Arc::new(Camera::Orthographic(Box::new(OrthographicCamera::new(
139 cam2world,
140 screen,
141 shutteropen,
142 shutterclose,
143 lensradius,
144 focaldistance,
145 film,
146 medium,
147 ))))
148 }
149 pub fn generate_ray_differential(&self, sample: &CameraSample, ray: &mut Ray) -> Float {
151 let p_film: Point3f = Point3f {
154 x: sample.p_film.x,
155 y: sample.p_film.y,
156 z: 0.0,
157 };
158 let p_camera: Point3f = self.raster_to_camera.transform_point(&p_film);
159 *ray = Ray {
160 o: p_camera,
161 d: Vector3f {
162 x: 0.0,
163 y: 0.0,
164 z: 1.0,
165 },
166 t_max: Cell::new(std::f32::INFINITY),
167 time: lerp(sample.time, self.shutter_open, self.shutter_close),
168 medium: None,
169 differential: None,
170 };
171 if self.lens_radius > 0.0 as Float {
173 let p_lens: Point2f = concentric_sample_disk(&sample.p_lens) * self.lens_radius;
175 let ft: Float = self.focal_distance / ray.d.z;
177 let p_focus: Point3f = ray.position(ft);
178 ray.o = Point3f {
180 x: p_lens.x,
181 y: p_lens.y,
182 z: 0.0 as Float,
183 };
184 ray.d = (p_focus - ray.o).normalize();
185 }
186 if self.lens_radius > 0.0 as Float {
188 let p_lens: Point2f = concentric_sample_disk(&sample.p_lens) * self.lens_radius;
192 let ft: Float = self.focal_distance / ray.d.z;
193 let p_focus: Point3f = p_camera
194 + self.dx_camera
195 + (Vector3f {
196 x: 0.0 as Float,
197 y: 0.0 as Float,
198 z: 1.0 as Float,
199 } * ft);
200 let rx_origin = Point3f {
201 x: p_lens.x,
202 y: p_lens.y,
203 z: 0.0 as Float,
204 };
205 let ry_origin = Point3f {
206 x: p_lens.x,
207 y: p_lens.y,
208 z: 0.0 as Float,
209 };
210 let diff = RayDifferential {
211 rx_origin,
212 rx_direction: (p_focus - rx_origin).normalize(),
213 ry_origin,
214 ry_direction: (p_focus - ry_origin).normalize(),
215 };
216 ray.differential = Some(diff);
218 } else {
219 let diff: RayDifferential = RayDifferential {
220 rx_origin: ray.o + self.dx_camera,
221 ry_origin: ray.o + self.dy_camera,
222 rx_direction: ray.d,
223 ry_direction: ray.d,
224 };
225 ray.differential = Some(diff);
226 }
227 if let Some(ref medium_arc) = self.medium {
229 ray.medium = Some(medium_arc.clone());
230 } else {
231 ray.medium = None;
232 }
233 *ray = self.camera_to_world.transform_ray(ray);
234 1.0
235 }
236 pub fn we(&self, _ray: &Ray, _p_raster2: Option<&mut Point2f>) -> Spectrum {
237 panic!("camera::we() is not implemented!");
238 }
240 pub fn pdf_we(&self, _ray: &Ray) -> (Float, Float) {
241 panic!("camera::pdf_we() is not implemented!");
244 }
246 pub fn sample_wi(
247 &self,
248 _iref: &InteractionCommon,
249 _lens_intr: &mut InteractionCommon,
250 _u: Point2f,
251 _wi: &mut Vector3f,
252 _pdf: &mut Float,
253 _p_raster: &mut Point2f,
254 _vis: &mut VisibilityTester,
255 ) -> Spectrum {
256 panic!("camera::sample_wi() is not implemented!");
257 }
259 pub fn get_shutter_open(&self) -> Float {
260 self.shutter_open
261 }
262 pub fn get_shutter_close(&self) -> Float {
263 self.shutter_close
264 }
265 pub fn get_film(&self) -> Arc<Film> {
266 self.film.clone()
267 }
268}