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 #include "camera.h"
00026 #include "film.h"
00027 #include "paramset.h"
00028
00029 class PerspectiveCamera : public ProjectiveCamera {
00030 public:
00031
00032 PerspectiveCamera(const Transform &world2cam,
00033 const float Screen[4], float hither, float yon,
00034 float sopen, float sclose,
00035 float lensr, float focald, float fov,
00036 Film *film);
00037 float GenerateRay(const Sample &sample, Ray *) const;
00038 };
00039
00040 PerspectiveCamera::
00041 PerspectiveCamera(const Transform &world2cam,
00042 const float Screen[4], float hither, float yon,
00043 float sopen, float sclose,
00044 float lensr, float focald,
00045 float fov, Film *f)
00046 : ProjectiveCamera(world2cam,
00047 Perspective(fov, hither, yon),
00048 Screen, hither, yon, sopen, sclose,
00049 lensr, focald, f) {
00050 }
00051 float PerspectiveCamera::GenerateRay(const Sample &sample,
00052 Ray *ray) const {
00053
00054 Point Pras(sample.imageX, sample.imageY, 0);
00055 Point Pcamera;
00056 RasterToCamera(Pras, &Pcamera);
00057 ray->o = Pcamera;
00058 ray->d = Vector(Pcamera.x, Pcamera.y, Pcamera.z);
00059
00060 ray->time = Lerp(sample.time, ShutterOpen, ShutterClose);
00061
00062 if (LensRadius > 0.) {
00063
00064 float lensU, lensV;
00065 ConcentricSampleDisk(sample.lensU, sample.lensV,
00066 &lensU, &lensV);
00067 lensU *= LensRadius;
00068 lensV *= LensRadius;
00069
00070 float ft = (FocalDistance - ClipHither) / ray->d.z;
00071 Point Pfocus = (*ray)(ft);
00072
00073 ray->o.x = lensU * (FocalDistance - ClipHither) / FocalDistance;
00074 ray->o.y = lensV * (FocalDistance - ClipHither) / FocalDistance;
00075 ray->d = Pfocus - ray->o;
00076 }
00077 ray->d = Normalize(ray->d);
00078 ray->mint = 0.;
00079 ray->maxt = (ClipYon - ClipHither) / ray->d.z;
00080 CameraToWorld(*ray, ray);
00081 return 1.f;
00082 }
00083 extern "C" DLLEXPORT Camera *CreateCamera(const ParamSet ¶ms,
00084 const Transform &world2cam, Film *film) {
00085
00086 float hither = max(1e-4f, params.FindOneFloat("hither", 1e-3f));
00087 float yon = min(params.FindOneFloat("yon", 1e30f), 1e30f);
00088 float shutteropen = params.FindOneFloat("shutteropen", 0.f);
00089 float shutterclose = params.FindOneFloat("shutterclose", 1.f);
00090 float lensradius = params.FindOneFloat("lensradius", 0.f);
00091 float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
00092 float frame = params.FindOneFloat("frameaspectratio",
00093 float(film->xResolution)/float(film->yResolution));
00094 float screen[4];
00095 if (frame > 1.f) {
00096 screen[0] = -frame;
00097 screen[1] = frame;
00098 screen[2] = -1.f;
00099 screen[3] = 1.f;
00100 }
00101 else {
00102 screen[0] = -1.f;
00103 screen[1] = 1.f;
00104 screen[2] = -1.f / frame;
00105 screen[3] = 1.f / frame;
00106 }
00107 int swi;
00108 const float *sw = params.FindFloat("screenwindow", &swi);
00109 if (sw && swi == 4)
00110 memcpy(screen, sw, 4*sizeof(float));
00111 float fov = params.FindOneFloat("fov", 90.);
00112 return new PerspectiveCamera(world2cam, screen, hither, yon,
00113 shutteropen, shutterclose, lensradius, focaldistance,
00114 fov, film);
00115 }