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