00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 #include "stdafx.h"
00027 #include "cameras/perspective.h"
00028 #include "paramset.h"
00029 #include "sampler.h"
00030 #include "montecarlo.h"
00031 
00032 
00033 PerspectiveCamera:: PerspectiveCamera(const AnimatedTransform &cam2world,
00034         const float screenWindow[4], float sopen, float sclose,
00035         float lensr, float focald, float fov, Film *f)
00036     : ProjectiveCamera(cam2world, Perspective(fov, 1e-2f, 1000.f),
00037                        screenWindow, sopen, sclose, lensr, focald, f) {
00038     
00039     dxCamera = RasterToCamera(Point(1,0,0)) - RasterToCamera(Point(0,0,0));
00040     dyCamera = RasterToCamera(Point(0,1,0)) - RasterToCamera(Point(0,0,0));
00041 }
00042 
00043 
00044 float PerspectiveCamera::GenerateRay(const CameraSample &sample,
00045                                      Ray *ray) const {
00046     
00047     Point Pras(sample.imageX, sample.imageY, 0);
00048     Point Pcamera;
00049     RasterToCamera(Pras, &Pcamera);
00050     *ray = Ray(Point(0,0,0), Vector(Pcamera), 0.f, INFINITY);
00051     
00052     if (lensRadius > 0.) {
00053         
00054         float lensU, lensV;
00055         ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
00056         lensU *= lensRadius;
00057         lensV *= lensRadius;
00058 
00059         
00060         float ft = focalDistance / ray->d.z;
00061         Point Pfocus = (*ray)(ft);
00062 
00063         
00064         ray->o = Point(lensU, lensV, 0.f);
00065         ray->d = Normalize(Pfocus - ray->o);
00066     }
00067     ray->time = Lerp(sample.time, shutterOpen, shutterClose);
00068     CameraToWorld(*ray, ray);
00069     return 1.f;
00070 }
00071 
00072 
00073 float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
00074                                                  RayDifferential *ray) const {
00075     
00076     Point Pras(sample.imageX, sample.imageY, 0);
00077     Point Pcamera;
00078     RasterToCamera(Pras, &Pcamera);
00079     Vector dir = Normalize(Vector(Pcamera.x, Pcamera.y, Pcamera.z));
00080     *ray = RayDifferential(Point(0,0,0), dir, 0.f, INFINITY);
00081     
00082     if (lensRadius > 0.) {
00083         
00084         float lensU, lensV;
00085         ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
00086         lensU *= lensRadius;
00087         lensV *= lensRadius;
00088 
00089         
00090         float ft = focalDistance / ray->d.z;
00091         Point Pfocus = (*ray)(ft);
00092 
00093         
00094         ray->o = Point(lensU, lensV, 0.f);
00095         ray->d = Normalize(Pfocus - ray->o);
00096     }
00097 
00098     
00099     ray->rxOrigin = ray->ryOrigin = ray->o;
00100     ray->rxDirection = Normalize(Vector(Pcamera) + dxCamera);
00101     ray->ryDirection = Normalize(Vector(Pcamera) + dyCamera);
00102     ray->time = Lerp(sample.time, shutterOpen, shutterClose);
00103     CameraToWorld(*ray, ray);
00104     ray->hasDifferentials = true;
00105     return 1.f;
00106 }
00107 
00108 
00109 PerspectiveCamera *CreatePerspectiveCamera(const ParamSet ¶ms,
00110         const AnimatedTransform &cam2world, Film *film) {
00111     
00112     float shutteropen = params.FindOneFloat("shutteropen", 0.f);
00113     float shutterclose = params.FindOneFloat("shutterclose", 1.f);
00114     float lensradius = params.FindOneFloat("lensradius", 0.f);
00115     float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
00116     float frame = params.FindOneFloat("frameaspectratio",
00117         float(film->xResolution)/float(film->yResolution));
00118     float screen[4];
00119     if (frame > 1.f) {
00120         screen[0] = -frame;
00121         screen[1] =  frame;
00122         screen[2] = -1.f;
00123         screen[3] =  1.f;
00124     }
00125     else {
00126         screen[0] = -1.f;
00127         screen[1] =  1.f;
00128         screen[2] = -1.f / frame;
00129         screen[3] =  1.f / frame;
00130     }
00131     int swi;
00132     const float *sw = params.FindFloat("screenwindow", &swi);
00133     if (sw && swi == 4)
00134         memcpy(screen, sw, 4*sizeof(float));
00135     float fov = params.FindOneFloat("fov", 90.);
00136     float halffov = params.FindOneFloat("halffov", -1.f);
00137     if (halffov > 0.f)
00138         
00139         fov = 2.f * halffov;
00140     return new PerspectiveCamera(cam2world, screen, shutteropen,
00141         shutterclose, lensradius, focaldistance, fov, film);
00142 }
00143 
00144