source: GTP/trunk/App/Demos/Illum/pathmap/SquareLight.hpp @ 2197

Revision 2197, 2.7 KB checked in by szirmay, 18 years ago (diff)
Line 
1#pragma once
2#include "light.hpp"
3
4class SquareLight :
5        public Light
6{
7        Vector edge1;
8        Vector edge2;
9public:
10        Vector polyNodes[4];
11        unsigned int nPolyNodes;
12
13        SquareLight(Vector* nodes, int nNodes, const Vector& radiance)
14        {
15                if(nNodes < 3) exit(-1);
16                nPolyNodes = nNodes;
17                for(int i=0; i<nPolyNodes; i++)
18                        polyNodes[i] = nodes[i];
19                Vector a; a.setDifference(nodes[0], nodes[1]);
20                Vector b; b.setDifference(nodes[0], nodes[2]);
21                edge1 = a;
22                edge2.setDifference(nodes[0], nodes[nNodes-1]);
23                this->direction.setCrossProduct(b, a);
24                this->direction.normalize();
25                this->radiance = radiance;
26                luminance = radiance.r + radiance.g + radiance.b;
27                this->position.clear();
28                for(int c=0; c<nNodes; c++)
29                        this->position += nodes[c];
30                this->position *= 1.0f / (float)nNodes;
31
32                area = sqrt(edge1.norm2() * edge2.norm2());
33                power = radiance;
34                power *= area;
35        }
36        float getFormFactor(const Vector& lookpoint, const Vector& normal) const
37        {
38                Vector ffxcd, dif[4], cutRemains[5];
39                ffxcd.clear();
40                float acc = 0.0f;
41
42                bool in[4];
43                for(int iCutter=0; iCutter<4; iCutter++)
44                {
45                        dif[iCutter].setDifference(polyNodes[iCutter], lookpoint);
46                        dif[iCutter].normalize();
47                        in[iCutter] = (dif[iCutter] * normal > 0.0f);
48                }
49                int nRemain = 0;
50                for(int iGutter=0;iGutter<4;iGutter++)
51                {
52                        int ta = iGutter & 3;
53                        int tb = (iGutter + 1) & 3;
54                        if(in[ta])
55                        {
56                                cutRemains[nRemain++] = dif[ta];
57                                if(!in[tb])
58                                {
59                                        Vector cutEdgePlaneNormal;
60                                        cutEdgePlaneNormal.setCrossProduct(dif[ta],dif[tb]);
61                                        cutEdgePlaneNormal.normalize();
62                                        cutRemains[nRemain].setCrossProduct(cutEdgePlaneNormal, normal);
63                                        cutRemains[nRemain++].normalize();
64                                }
65                        }
66                        else
67                                if(in[tb])
68                                {
69                                        Vector cutEdgePlaneNormal;
70                                        cutEdgePlaneNormal.setCrossProduct(dif[ta],dif[tb]);
71                                        cutEdgePlaneNormal.normalize();
72                                        cutRemains[nRemain].setCrossProduct(normal, cutEdgePlaneNormal);
73                                        cutRemains[nRemain++].normalize();
74                                }
75                }
76
77                if(nRemain == 0) return 0.0f;
78
79                for(int pir = 0; pir < nRemain; pir++)
80                {
81                        Vector rxr; rxr.setCrossProduct(cutRemains[pir], cutRemains[(pir + 1)%nRemain]);
82                        float sinb = rxr.norm();
83                        rxr *= 1.0f / sinb;
84                        float alfa = asinf(sinb);
85                        if(cutRemains[pir] * cutRemains[(pir + 1)%nRemain] < 0.0f)
86                                alfa = 3.14f - alfa;
87                        rxr *= alfa;
88//                      ffxcd += rxr;
89                        acc += rxr * normal;
90                }
91                return acc * 0.5f;
92//              return ffxcd * normal * 0.5f;
93        }
94        Vector getSample() const
95        {
96                Vector ret = polyNodes[0];
97                ret.addScaled(-(float)rand() / RAND_MAX, edge1 );
98                ret.addScaled(-(float)rand() / RAND_MAX, edge2 );
99                return ret;
100        }
101        bool isPossiblyVisible(const Vector& point) const
102        {
103                Vector diff; diff.setDifference(point, position);
104                return diff * direction > 0;
105        }
106};
Note: See TracBrowser for help on using the repository browser.