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 "environment.h"
00025 #include "sampling.h"
00026 #include "scene.h"
00027 #include "film.h"
00028 #include "paramset.h"
00029
00030 using namespace lux;
00031
00032
00033 EnvironmentCamera::
00034 EnvironmentCamera(const Transform &world2cam,
00035 float hither, float yon, float sopen, float sclose,
00036 Film *film)
00037 : Camera(world2cam, hither, yon, sopen, sclose, film) {
00038 rayOrigin = CameraToWorld(Point(0,0,0));
00039 }
00040 float EnvironmentCamera::GenerateRay(const Sample &sample,
00041 Ray *ray) const {
00042 ray->o = rayOrigin;
00043
00044 float theta = M_PI * sample.imageY / film->yResolution;
00045 float phi = 2 * M_PI * sample.imageX / film->xResolution;
00046 Vector dir(sinf(theta) * cosf(phi), cosf(theta),
00047 sinf(theta) * sinf(phi));
00048 CameraToWorld(dir, &ray->d);
00049
00050 ray->time = Lerp(sample.time, ShutterOpen, ShutterClose);
00051 ray->mint = ClipHither;
00052 ray->maxt = ClipYon;
00053 return 1.f;
00054 }
00055 bool EnvironmentCamera::GenerateSample(const Point &p, Sample *sample) const
00056 {
00057 Vector dir_world(p-rayOrigin);
00058 Vector dir_camera;
00059 WorldToCamera(dir_world, &dir_camera);
00060 dir_camera = Normalize(dir_camera);
00061 float theta, phi;
00062 theta = acosf(dir_camera.y);
00063 phi = acosf(dir_camera.x/sinf(theta));
00064 if (isnan(phi))
00065 phi=atanf(dir_camera.z/dir_camera.x);
00066 if (dir_camera.z<0)
00067 phi = M_PI * 2 - phi;
00068
00069 sample->imageX = min (phi * INV_TWOPI, 1.0f) * film->xResolution ;
00070 sample->imageY = min (theta * INV_PI, 1.0f) * film->yResolution ;
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 return true;
00081 }
00082 bool EnvironmentCamera::IsVisibleFromEyes(const Scene *scene, const Point &lenP, const Point &worldP, Sample* sample_gen, Ray *ray_gen) const
00083 {
00084 bool isVisible;
00085 if (GenerateSample(worldP, sample_gen))
00086 {
00087 GenerateRay(*sample_gen, ray_gen);
00088 ray_gen->maxt = Distance(ray_gen->o, worldP)*(1-RAY_EPSILON);
00089 isVisible = !scene->IntersectP(*ray_gen);
00090 }
00091 else
00092 isVisible = false;
00093 return isVisible;
00094 }
00095 float EnvironmentCamera::GetConnectingFactor(const Point &lenP, const Point &worldP, const Vector &wo, const Normal &n) const
00096 {
00097 return AbsDot(wo, n) / DistanceSquared(lenP, worldP);
00098 }
00099 void EnvironmentCamera::GetFlux2RadianceFactors(Film *film, float *factors, int xPixelCount, int yPixelCount) const
00100 {
00101 float Apixel,R = 100.0f;
00102 int x,y;
00103 for (y = 0; y < yPixelCount; ++y) {
00104 for (x = 0; x < xPixelCount; ++x) {
00105 Apixel = 2*M_PI/film->xResolution*R*sinf(M_PI*(y+0.5f)/film->yResolution) * M_PI/film->yResolution*R;
00106 factors[x+y*xPixelCount] = R*R / Apixel;
00107 }
00108 }
00109 }
00110 void EnvironmentCamera::SamplePosition(float u1, float u2, Point *p, float *pdf) const
00111 {
00112 *p = rayOrigin;
00113 *pdf = 1.0f;
00114 }
00115 float EnvironmentCamera::EvalPositionPdf() const
00116 {
00117 return 1.0f;
00118 }
00119
00120 Camera* EnvironmentCamera::CreateCamera(const ParamSet ¶ms,
00121 const Transform &world2cam, Film *film) {
00122
00123 float hither = max(1e-4f, params.FindOneFloat("hither", 1e-3f));
00124 float yon = min(params.FindOneFloat("yon", 1e30f), 1e30f);
00125 float shutteropen = params.FindOneFloat("shutteropen", 0.f);
00126 float shutterclose = params.FindOneFloat("shutterclose", 1.f);
00127 float lensradius = params.FindOneFloat("lensradius", 0.f);
00128 float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
00129 float frame = params.FindOneFloat("frameaspectratio",
00130 float(film->xResolution)/float(film->yResolution));
00131 float screen[4];
00132 if (frame > 1.f) {
00133 screen[0] = -frame;
00134 screen[1] = frame;
00135 screen[2] = -1.f;
00136 screen[3] = 1.f;
00137 }
00138 else {
00139 screen[0] = -1.f;
00140 screen[1] = 1.f;
00141 screen[2] = -1.f / frame;
00142 screen[3] = 1.f / frame;
00143 }
00144 int swi;
00145 const float *sw = params.FindFloat("screenwindow", &swi);
00146 if (sw && swi == 4)
00147 memcpy(screen, sw, 4*sizeof(float));
00148 (void) lensradius;
00149 (void) focaldistance;
00150 return new EnvironmentCamera(world2cam, hither, yon,
00151 shutteropen, shutterclose, film);
00152 }