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 "light.h"
00025 #include "scene.h"
00026 #include "reflection/bxdf.h"
00027
00028 using namespace lux;
00029
00030
00031 Light::~Light() {
00032 }
00033 bool VisibilityTester::Unoccluded(const Scene *scene) const {
00034
00035
00036
00037 return !scene->IntersectP(r);
00038 }
00039 bool VisibilityTester::TestOcclusion(const Scene *scene, SWCSpectrum *f) const
00040 {
00041 *f = 1.f;
00042 RayDifferential ray(r);
00043 Intersection isect;
00044 while (true) {
00045 if (!scene->Intersect(ray, &isect))
00046 return true;
00047 BSDF *bsdf = isect.GetBSDF(ray, lux::random::floatValue());
00048 const float pdf = bsdf->Pdf(-ray.d, ray.d, BSDF_ALL_TRANSMISSION);
00049 if (!(pdf > 0.f))
00050 return false;
00051 *f *= AbsDot(Normalize(bsdf->dgShading.nn), Normalize(ray.d)) / pdf;
00052 *f *= bsdf->f(-ray.d, ray.d);
00053 if (f->Black())
00054 return false;
00055 ray.mint = ray.maxt + RAY_EPSILON;
00056 ray.maxt = r.maxt;
00057 }
00058 }
00059 SWCSpectrum VisibilityTester::
00060 Transmittance(const Scene *scene) const {
00061 return scene->Transmittance(r);
00062 }
00063 SWCSpectrum Light::Le(const RayDifferential &) const {
00064 return SWCSpectrum(0.);
00065 }
00066 SWCSpectrum Light::Le(const Scene *scene, const Ray &r,
00067 const Normal &n, BSDF **bsdf, float *pdf, float *pdfDirect) const
00068 {
00069 return SWCSpectrum(0.f);
00070 }
00071
00072 void Light::AddPortalShape(boost::shared_ptr<Shape> s) {
00073 boost::shared_ptr<Shape> PortalShape;
00074
00075 if (s->CanIntersect())
00076 PortalShape = s;
00077 else {
00078
00079 boost::shared_ptr<Shape> shapeSet = s;
00080 vector<boost::shared_ptr<Shape> > todo, done;
00081 todo.push_back(shapeSet);
00082 while (todo.size()) {
00083 boost::shared_ptr<Shape> sh = todo.back();
00084 todo.pop_back();
00085 if (sh->CanIntersect())
00086 done.push_back(sh);
00087 else
00088 sh->Refine(todo);
00089 }
00090 if (done.size() == 1) PortalShape = done[0];
00091 else {
00092 boost::shared_ptr<Shape> o (new ShapeSet(done, s->ObjectToWorld, s->reverseOrientation));
00093 PortalShape = o;
00094 }
00095 }
00096 havePortalShape = true;
00097
00098 PortalArea += PortalShape->Area();
00099 PortalShapes.push_back(PortalShape);
00100 ++nrPortalShapes;
00101 }