use crate::core::film::Film; use crate::core::geometry::{Point2f, Point3f, Ray, RayDifferential}; use crate::core::medium::Medium; use crate::core::pbrt::{Float, RenderingCoordinateSystem}; use crate::core::spectrum::SampledSpectrum; use crate::core::transform::{Transform, AnimatedTransform}; pub enum Camera { Perspective(PerspectiveCamera), Ortographic(OrtographicCamera), Spherical(SphericalCamera), Realistic(RealisticCamera), } impl Camera { pub fn create(&self, name: str, medium: Medium, camera_transform: CameraTransform, film: Film) -> Float { match self { Camera::Perspective(s) => s.create(name, medium, camera_transform, film), Camera::Ortographic(s) => s.create(name, medium, camera_transform, film), Camera::Spherical(s) => s.create(name, medium, camera_transform, film), Camera::Realistic(s) => s.create(name, medium, camera_transform, film), } } } pub struct CameraSample { p_film: Point2f, p_lens: Point2f, time: Float, filter_weight: Float, } pub struct CameraRay { ray: Ray, weight: SampledSpectrum, } pub struct CameraDifferential { ray: RayDifferential, weight: SampledSpectrum, } pub struct CameraTransform { render_from_camera: AnimatedTransform, world_from_render: Transform, } impl CameraTransform { pub fn from_world(world_from_camera: AnimatedTransform, rendering_space: RenderingCoordinateSystem) -> Self { let world_from_render = match rendering_space { RenderingCoordinateSystem::Camera => { let t_mid = (world_from_camera.start_time + world_from_camera.end_time) / 2.; world_from_camera.interpolate(t_mid); } RenderingCoordinateSystem::CameraWorld => { let t_mid = (world_from_camera.start_time + world_from_camera.end_time) / 2.; let p_camera = world_from_camera.apply_point(Point3f::default(), t_mid); Transform::translate(p_camera.to_vec()); } RenderingCoordinateSystem::World => Transform::identity(), }; } pub fn render_from_camera(&self, p: Point3f, time: Float) -> Point3f { self.render_from_camera.apply_point(p, time) } pub fn camera_from_render(&self, p: Point3f, time: Float) -> Point3f { self.render_from_camera.apply_inverse_point(p, time) } } pub struct PerspectiveCamera; pub struct OrtographicCamera; pub struct SphericalCamera; pub struct RealisticCamera;