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
00035 mNormal = mE1.cross(mE2);
00036
00037
00038 mArea = mNormal.length();
00039
00040
00041 mNormal.normalize();
00042
00043
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 ) const
00063 {
00064
00065 float xi1 = frand();
00066 float xi2 = frand();
00067 Vec3f pos = mP0 + xi1 * mE1 + xi2 * mE2;
00068
00069
00070 Ray ray;
00071 dir = pos - org;
00072 float length = dir.length();
00073 dir.normalize();
00074 ray.init(org, dir, length);
00075
00076
00077 if (mScene->castShadows() && mScene->intersect(ray) && ray.hit()->castShadows() && ray.t() > EPSILON)
00078 return RGBAColor(0.0f);
00079
00080
00081 float att = 1.0f / (length * length * mRaycount);
00082
00083
00084 float cosN = - dir.dot(mNormal);
00085 if (cosN < EPSILON)
00086 return RGBAColor(0.0f);
00087
00088
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