00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "orthographic.h"
00025 #include "sampling.h"
00026 #include "mc.h"
00027 #include "scene.h"
00028 #include "film.h"
00029 #include "paramset.h"
00030
00031 using namespace lux;
00032
00033
00034 OrthoCamera::OrthoCamera(const Transform &world2cam,
00035 const float Screen[4], float hither, float yon,
00036 float sopen, float sclose, float lensr,
00037 float focald, bool autofocus, Film *f)
00038 : ProjectiveCamera(world2cam, Orthographic(hither, yon),
00039 Screen, hither, yon, sopen, sclose,
00040 lensr, focald, f), autoFocus(autofocus) {
00041 screenDx = Screen[1] - Screen[0];
00042 screenDy = Screen[3] - Screen[2];
00043 }
00044
00045 void OrthoCamera::AutoFocus(Scene* scene)
00046 {
00047 if (autoFocus) {
00048 std::stringstream ss;
00049
00050
00051
00052 int xstart, xend, ystart, yend;
00053 film->GetSampleExtent(&xstart, &xend, &ystart, ¥d);
00054 Point Pras((xend - xstart) / 2, (yend - ystart) / 2, 0);
00055
00056
00057
00058
00059
00060
00061 Point Pcamera;
00062 RasterToCamera(Pras, &Pcamera);
00063 Ray ray;
00064 ray.o = Pcamera;
00065 ray.d = Vector(0,0,1);
00066
00067
00068 ray.time = 0.0f;
00069
00070 ray.mint = 0.f;
00071 ray.maxt = ClipYon - ClipHither;
00072 CameraToWorld(ray, &ray);
00073
00074
00075
00076
00077
00078
00079 Intersection isect;
00080 if (scene->Intersect(ray, &isect))
00081 FocalDistance = ray.maxt;
00082 else
00083 luxError(LUX_NOERROR, LUX_WARNING, "Unable to define the Autofocus focal distance");
00084
00085 ss.str("");
00086 ss << "Autofocus focal distance: " << FocalDistance;
00087 luxError(LUX_NOERROR, LUX_INFO, ss.str().c_str());
00088 }
00089 }
00090
00091 float OrthoCamera::GenerateRay(const Sample &sample, Ray *ray) const
00092 {
00093
00094 Point Pras(sample.imageX, sample.imageY, 0);
00095 Point Pcamera;
00096 RasterToCamera(Pras, &Pcamera);
00097 ray->o = Pcamera;
00098 ray->d = Vector(0,0,1);
00099
00100 ray->time = Lerp(sample.time, ShutterOpen, ShutterClose);
00101
00102
00103 if (LensRadius > 0.) {
00104
00105 float lensU, lensV;
00106 ConcentricSampleDisk(sample.lensU, sample.lensV,
00107 &lensU, &lensV);
00108 lensU *= LensRadius;
00109 lensV *= LensRadius;
00110
00111 float ft = (FocalDistance - ClipHither) / ray->d.z;
00112 Point Pfocus = (*ray)(ft);
00113
00114 ray->o.x += lensU;
00115 ray->o.y += lensV;
00116 ray->d = Pfocus - ray->o;
00117 }
00118
00119 ray->mint = 0.;
00120 ray->maxt = ClipYon - ClipHither;
00121 ray->d = Normalize(ray->d);
00122 CameraToWorld(*ray, ray);
00123 return 1.f;
00124 }
00125
00126 bool OrthoCamera::IsVisibleFromEyes(const Scene *scene, const Point &lenP, const Point &worldP, Sample* sample_gen, Ray *ray_gen) const
00127 {
00128 bool isVisible = false;
00129 if (GenerateSample(worldP, sample_gen))
00130 {
00131 GenerateRay(*sample_gen, ray_gen);
00132 if (WorldToCamera(worldP).z>0)
00133 {
00134 ray_gen->maxt = Distance(ray_gen->o, worldP)*(1-RAY_EPSILON);
00135 isVisible = !scene->IntersectP(*ray_gen);
00136 }
00137 }
00138 return isVisible;
00139 }
00140
00141 float OrthoCamera::GetConnectingFactor(const Point &lenP, const Point &worldP, const Vector &wo, const Normal &n) const
00142 {
00143 return AbsDot(wo, n);
00144 }
00145
00146 void OrthoCamera::GetFlux2RadianceFactors(Film *film, float *factors, int xPixelCount, int yPixelCount) const
00147 {
00148 float Apixel = (screenDx*screenDy/(film->xResolution*film->yResolution));
00149 int x,y;
00150 float invApixel = 1/Apixel;
00151 for (y = 0; y < yPixelCount; ++y) {
00152 for (x = 0; x < xPixelCount; ++x) {
00153 factors[x+y*xPixelCount] = invApixel;
00154 }
00155 }
00156 }
00157
00158 void OrthoCamera::SamplePosition(float u1, float u2, Point *p, float *pdf) const
00159 {
00160
00161 *pdf = 1.0f;
00162 }
00163
00164 float OrthoCamera::EvalPositionPdf() const
00165 {
00166 return 1.0f/(screenDx*screenDy);
00167 }
00168
00169 Camera* OrthoCamera::CreateCamera(const ParamSet ¶ms,
00170 const Transform &world2cam, Film *film) {
00171
00172 float hither = max(1e-4f, params.FindOneFloat("hither", 1e-3f));
00173 float yon = min(params.FindOneFloat("yon", 1e30f), 1e30f);
00174 float shutteropen = params.FindOneFloat("shutteropen", 0.f);
00175 float shutterclose = params.FindOneFloat("shutterclose", 1.f);
00176 float lensradius = params.FindOneFloat("lensradius", 0.f);
00177 float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
00178 bool autofocus = params.FindOneBool("autofocus", false);
00179 float frame = params.FindOneFloat("frameaspectratio",
00180 float(film->xResolution)/float(film->yResolution));
00181 float screen[4];
00182 if (frame > 1.f) {
00183 screen[0] = -frame;
00184 screen[1] = frame;
00185 screen[2] = -1.f;
00186 screen[3] = 1.f;
00187 }
00188 else {
00189 screen[0] = -1.f;
00190 screen[1] = 1.f;
00191 screen[2] = -1.f / frame;
00192 screen[3] = 1.f / frame;
00193 }
00194 int swi;
00195 const float *sw = params.FindFloat("screenwindow", &swi);
00196 if (sw && swi == 4)
00197 memcpy(screen, sw, 4*sizeof(float));
00198 return new OrthoCamera(world2cam, screen, hither, yon,
00199 shutteropen, shutterclose, lensradius, focaldistance, autofocus,
00200 film);
00201 }