src/QuadAreaLight.h

Go to the documentation of this file.
00001 #ifndef AREALIGHT_H
00002 #define AREALIGHT_H
00003 
00004 
00005 #include "Light.h"
00006 #include "Ray.h"
00007 
00008 
00014 class QuadAreaLight : public Light
00015 {
00016 public:
00023     QuadAreaLight(  const RGBAColor &   power,
00024                     const Vec3f &       pos,
00025                     const Vec3f &       d1,
00026                     const Vec3f &       d2)
00027         : Light(),
00028             mPower(power),
00029             mP0(pos),
00030             mE1(d1),
00031             mE2(d2),
00032             mRaycount(1)
00033     {
00034         // compute normal by computing the cross product of both expansion vectors
00035         mNormal = mE1.cross(mE2);
00036 
00037         // the area of a quad is the length of the cross product vector
00038         mArea = mNormal.length();
00039 
00040         // we have always to normalize the normal
00041         mNormal.normalize();
00042 
00043         // precalculate power
00044         mPower *= mArea;
00045     }
00046 
00049     unsigned int numberOfRays() const { return mRaycount; }
00050 
00053     void setNumberOfRays(unsigned int i) { mRaycount = i; }
00054 
00062     RGBAColor illuminate(Vec3f & dir, const Vec3f & org, unsigned int /*index = 0*/) const
00063     {
00064         // compute random position of a point light on the quad
00065         float xi1 = frand();
00066         float xi2 = frand();
00067         Vec3f pos = mP0 + xi1 * mE1 + xi2 * mE2;
00068 
00069         // the new ray direction is the direction to this point
00070         Ray ray;
00071         dir = pos - org;
00072         float length = dir.length();
00073         dir.normalize();
00074         ray.init(org, dir, length);
00075 
00076         // check for occlusion
00077         if (mScene->castShadows() && mScene->intersect(ray) && ray.hit()->castShadows() && ray.t() > EPSILON)
00078             return RGBAColor(0.0f);
00079 
00080         // compute attenuation factor
00081         float att = 1.0f / (length * length * mRaycount);
00082         
00083         // sample quad light
00084         float cosN = - dir.dot(mNormal);
00085         if (cosN < EPSILON)
00086             return RGBAColor(0.0f);
00087         
00088         // compute intensity based on the area of the light source
00089         return att * cosN * mPower;
00090     }
00091 
00094     const Vec3f & normal() const
00095     {
00096         return mNormal;
00097     }
00098 
00099 
00100 private:
00102     RGBAColor       mPower;
00103 
00105     Vec3f           mP0;
00106 
00108     Vec3f           mE1;
00109 
00111     Vec3f           mE2;
00112 
00114     float           mArea;
00115 
00117     Vec3f           mNormal;
00118 
00120     unsigned int    mRaycount;
00121 };
00122 
00123 #endif

Generated on Fri Feb 1 00:01:42 2008 for Grayfall by  doxygen 1.5.1