1 #ifndef QUADAREALIGHT_HXX
  2 #define QUADAREALIGHT_HXX
  3 
  4 #define RECTANGULAR_QAL
  5 
  6 #include "Light.hxx"
  7 #include "Randomizer.hxx"
  8 
  9 class QuadAreaLight : public Light
 10 {
 11 private:
 12 	Randomizer randomizer;
 13 public:
 14 	Vec3f normal;         // normal
 15 	float area;           // size of the light
 16 	Vec3f C1, C2, C3, C4; // Four courner points
 17 	Vec3f D1, D2;         // Vectors spanning the coordinate system (diagonals)
 18 	Vec3f H1, H2, V1;     // Edge vectors
 19 	float r1, r2;         // Random scales
 20 	float scale;          // Dot product of ray.dir and normal
 21 
 22 	/********************
 23 	        --H1->
 24 	    3-----------4
 25 	  ^ |°D2.    °° |
 26 	 V1 |   ..°°    |
 27 	  | |.D1    °.. |
 28 	    2-----------1
 29 	        --H2->
 30 	********************/
 31 
 32 	QuadAreaLight(Scene *scene, Vec3f intensity, Vec3f C1, Vec3f C2, Vec3f C3, Vec3f C4)
 33 		: Light(scene, intensity),C1(C1),C2(C2),C3(C3),C4(C4)
 34 	{
 35 		D1 = C2 - C4;
 36 		D2 = C3 - C1;
 37 
 38 		H1 = C4 - C3;
 39 		H2 = C1 - C2;
 40 
 41 		V1 = C3 - C2;
 42 
 43 		normal = Cross(D1, D2);
 44 		area   = Length(normal);
 45 
 46 		Normalize(normal);
 47 	};  
 48 
 49 	virtual void Illuminate(Ray &ray, Vec3f &intensity)
 50 	{
 51 		// Create random position on quadrangle
 52 		r1 = randomizer.drand();
 53 		r2 = randomizer.drand();
 54 
 55 #ifdef RECTANGULAR_QAL
 56 		Vec3f position = C2 + r1 * V1 + r2 * H2;
 57 #else
 58 		Vec3f position = r2 * (r1 * (H1 - H2) + C3 - C2) + H2 * r1 + C2;
 59 #endif
 60 
 61 		ray.dir = position - ray.org;
 62 		ray.t   = Length(ray.dir) - Epsilon;
 63 		ray.hit = NULL;
 64 
 65 		intensity = this->intensity / Dot(ray.dir, ray.dir) * area;
 66 
 67 		Normalize(ray.dir);
 68 		scale = Dot(ray.dir, normal);
 69 
 70 		if (scale >= 0)
 71 			intensity *= scale;
 72 		else
 73 			intensity = Vec3f(0,0,0);
 74 	};
 75 
 76 	virtual void Initialize(TravellingPhoton &photon, Vec3f &intensity)
 77 	{
 78 		// Create random position on quadrangle
 79 		r1 = randomizer.drand();
 80 		r2 = randomizer.drand();
 81 
 82 		// Optionally create non-equirectangular QALs (costly!)
 83 #ifdef RECTANGULAR_QAL
 84 		Vec3f position = C2 + r1 * V1 + r2 * H2;
 85 #else
 86 		Vec3f position = r2 * (r1 * (H1 - H2) + C3 - C2) + H2 * r1 + C2;
 87 #endif
 88 
 89 		photon.org = position;
 90 
 91 		scale = Dot(-photon.dir, normal);
 92 
 93 		intensity = this->intensity * area;
 94 
 95 		if (scale >= 0)
 96 			intensity *= scale;
 97 		else
 98 			intensity = Vec3f(0,0,0);
 99 	};
100 };
101 
102 #endif


syntax highlighted by Code2HTML, v. 0.9.1