source: trunk/BUTE/src/PreComputingRuns/HdriSampler.cpp @ 126

Revision 126, 7.4 KB checked in by barsi, 19 years ago (diff)

Added a folder remotely

Line 
1#include "dxstdafx.h"
2#include ".\hdrisampler.h"
3#include "Vector.hpp"
4#include "color.h"
5#include "resolu.h"
6
7#define M_PI       3.14159265358979323846
8#define M_PI_2     1.57079632679489661923
9#define M_PI_4     0.785398163397448309616
10
11
12HdriSampler::HdriSampler(void)
13{
14        h2.SetBase(2);
15        h3.SetBase(3);
16        h5.SetBase(5);
17        hdriMap = NULL;
18}
19
20HdriSampler::~HdriSampler(void)
21{
22}
23
24
25Vector HdriSampler::getRadianceAt(const Vector& dir) const
26{
27        bool edge = false;
28        float xval, yval;
29        int upper, left;
30        float fx, fy, fz;
31        fx = fabsf(dir.x);
32        fy = fabsf(dir.y);
33        fz = fabsf(dir.z);
34        if(dir.z > 0.0 && fz >= fy && fz >= fx)
35        {
36                upper = resolutiony / 4;
37                left = resolutionx / 3;
38                xval = dir.x / dir.z;
39                yval = dir.y / dir.z;
40        }
41        else
42        if(dir.z < 0.0 && fz >= fy && fz >= fx)
43        {
44                upper = 3 * resolutiony / 4;
45                left = resolutionx / 3;
46                xval = - dir.x / dir.z;
47                yval = dir.y / dir.z;
48        }
49        else
50        if(dir.x > 0.0 && fx >= fy && fx >= fz)
51        {
52                upper = resolutiony / 4;
53                left = 2 * resolutionx / 3;
54                xval = - dir.z / dir.x;
55                yval = dir.y / dir.x;
56        }
57        else
58        if(dir.x < 0.0 && fx >= fy && fx >= fz)
59        {
60                upper = resolutiony / 4;
61                left = 0;
62                xval = - dir.z / dir.x;
63                yval = - dir.y / dir.x;
64        }
65        else
66        if(dir.y > 0.0 && fy >= fx && fy >= fz)
67        {
68                upper = 0;
69                left = resolutionx / 3;
70                xval = dir.x / dir.y;
71                yval = - dir.z / dir.y;
72        }
73        else
74        if(dir.y < 0.0 && fy >= fx && fy >= fz)
75        {
76                upper = resolutiony / 2;
77                left = resolutionx / 3;
78                xval = - dir.x / dir.y;
79                yval = - dir.z / dir.y;
80        }
81        else
82                edge = true;
83
84        if(!edge)
85        {
86                upper += ((-yval + 1.0f) * resolutiony) / 8.0;
87                left += ((xval + 1.0f) * resolutionx) / 6.0;
88                return hdriMap[left + upper * resolutionx];
89        }
90        else
91                return Vector::RGBBLACK;
92}
93
94double HdriSampler::getImportance(const Vector& px)
95{
96//      return 1.0;
97        Vector rad = getRadianceAt(px);
98        return rad.sum();
99}
100// HdriSampler commands
101
102
103void HdriSampler::findMaxImportance()
104{
105        maxImportance = 0.0;
106        for(int k=0; k<resolutionx; k++)
107                for(int j=0; j<resolutiony; j++)
108                {
109                        double c = hdriMap[k + j * resolutionx].sum();
110                        if(c > maxImportance)
111                                maxImportance = c;
112                }
113}
114
115void HdriSampler::calculatePowers()
116{
117        powers.clear();
118        calculateRadii();
119        for(int i=0; i<samplePoints.size(); i++)
120        {
121                Vector bpower = getRadianceAt( samplePoints[i] );
122                bpower *= 3.14 * voronoiRadii[i] * voronoiRadii[i];
123                powers.push_back(bpower);
124        }
125        return;
126        int kbase = resolutionx/3;
127        int jbase = 0;
128        for(int k=0; k<resolutionx/3; k++)
129                for(int j=0; j<resolutiony/4; j++)
130                {
131                        Vector pixdir;
132                        pixdir.y = 1.0;
133                        pixdir.x = ((double)k / resolutionx) * 6.0 - 1.0;
134                        pixdir.z = (((double)j / resolutiony) * 8.0 - 1.0);
135                        double formfactor = 1.0 / pixdir.norm2();
136                        pixdir.normalize();
137                        formfactor *= pixdir.y;
138                        int di = voro.getNearestDirIndex(pixdir);
139                        powers[di] += hdriMap[k + kbase + (j + jbase) * resolutionx] * formfactor;
140                }
141        kbase = resolutionx/3;
142        jbase = resolutiony/2;
143        for(int k=0; k<resolutionx/3; k++)
144                for(int j=0; j<resolutiony/4; j++)
145                {
146                        Vector pixdir;
147                        pixdir.y = -1.0;
148                        pixdir.x = (((double)k / resolutionx) * 6.0 - 1.0);
149                        pixdir.z = -(((double)j / resolutiony) * 8.0 - 1.0);
150                        double formfactor = 1.0 / pixdir.norm2();
151                        pixdir.normalize();
152                        formfactor *= -pixdir.y;
153                        int di = voro.getNearestDirIndex(pixdir);
154                        powers[di] += hdriMap[k + kbase + (j + jbase) * resolutionx] * formfactor;
155                }
156        kbase = resolutionx/3;
157        jbase = resolutiony/4;
158        for(int k=0; k<resolutionx/3; k++)
159                for(int j=0; j<resolutiony/4; j++)
160                {
161                        Vector pixdir;
162                        pixdir.z = 1.0;
163                        pixdir.x = ((double)k / resolutionx) * 6.0 - 1.0;
164                        pixdir.y = -(((double)j / resolutiony) * 8.0 - 1.0);
165                        double formfactor = 1.0 / pixdir.norm2();
166                        pixdir.normalize();
167                        formfactor *= pixdir.z;
168                        int di = voro.getNearestDirIndex(pixdir);
169                        powers[di] += hdriMap[k + kbase + (j + jbase) * resolutionx] * formfactor;
170                }
171        kbase = resolutionx/3;
172        jbase = resolutiony/4*3;
173        for(int k=0; k<resolutionx/3; k++)
174                for(int j=0; j<resolutiony/4; j++)
175
176                {
177                        Vector pixdir;
178                        pixdir.z = -1.0;
179                        pixdir.x = (((double)k / resolutionx) * 6.0 - 1.0);
180                        pixdir.y = ((double)j / resolutiony) * 8.0 - 1.0;
181                        double formfactor = 1.0 / pixdir.norm2();
182                        pixdir.normalize();
183                        formfactor *= -pixdir.z;
184                        int di = voro.getNearestDirIndex(pixdir);
185                        powers[di] += hdriMap[k + kbase + (j + jbase) * resolutionx] * formfactor;
186                }
187        kbase = resolutionx/3*2;
188        jbase = resolutiony/4;
189        for(int k=0; k<resolutionx/3; k++)
190                for(int j=0; j<resolutiony/4; j++)
191                {
192                        Vector pixdir;
193                        pixdir.x = 1.0;
194                        pixdir.z = -(((double)k / resolutionx) * 6.0 - 1.0);
195                        pixdir.y = -(((double)j / resolutiony) * 8.0 - 1.0);
196                        double formfactor = 1.0 / pixdir.norm2();
197                        pixdir.normalize();
198                        formfactor *= pixdir.x;
199                        int di = voro.getNearestDirIndex(pixdir);
200                        powers[di] += hdriMap[k + kbase + (j + jbase) * resolutionx] * formfactor;
201                }
202        kbase = 0;
203        jbase = resolutiony/4;
204        for(int k=0; k<resolutionx/3; k++)
205                for(int j=0; j<resolutiony/4; j++)
206                {
207                        Vector pixdir;
208                        pixdir.x = -1.0;
209                        pixdir.z = (((double)k / resolutionx) * 6.0 - 1.0);
210                        pixdir.y = -(((double)j / resolutiony) * 8.0 - 1.0);
211                        double formfactor = 1.0 / pixdir.norm2();
212                        pixdir.normalize();
213                        formfactor *= -pixdir.x;
214                        int di = voro.getNearestDirIndex(pixdir);
215                        powers[di] += hdriMap[k + kbase + (j + jbase) * resolutionx] * formfactor;
216                }
217}
218
219bool HdriSampler::loadHdrFile(char* filename)
220{
221        FILE* file = fopen(filename, "r+b");
222        if(!file)
223                return false;
224        getheader(file, NULL, NULL);
225        RESOLU rs;
226        fgetsresolu(&rs, file);
227        resolutionx = scanlen(&rs);
228        resolutiony = numscans(&rs);
229        hdriMap = new Vector[resolutionx * resolutiony];
230        COLOR* loadhere = (COLOR*)hdriMap;
231        while(!feof(file))
232        {
233                freadscan(loadhere, resolutionx, file);
234                loadhere += resolutionx;
235        }
236        findMaxImportance();
237        return true;
238}
239
240void HdriSampler::generatePoints(int nSamples)
241{
242        //ASSERT(nSamples >= 4);
243        for(int i=0; i<nSamples; i++)
244        {
245                double fi = h2.Next() * 2.0 * M_PI;
246                double theta = asin(h3.Next() * 2.0 - 1);
247
248                Vector np(cos(fi) * cos(theta), sin(fi) * cos(theta), sin(theta));
249                while(getImportance(np) / maxImportance < h5.Next())
250                {
251                        rejectedPoints.push_back(np);
252                        fi = h2.Next() * 2.0 * M_PI;
253                        theta = asin(h3.Next() * 2.0 - 1);
254                        np = Vector(cos(fi) * cos(theta), sin(fi) * cos(theta), sin(theta));
255                }
256                samplePoints.push_back(np);
257                voro.addDir(np);
258        }
259//      calculatePowers();
260
261}
262
263void HdriSampler::relax(int nSteps)
264{
265        for(int i=0; i < nSteps; i++)
266                voro.relaxLloyd();
267        calculatePowers();
268}
269
270void HdriSampler::calculateRadii()
271{
272        voronoiRadii.clear();
273        for(int i=0; i<samplePoints.size(); i++)
274                voronoiRadii.push_back(0.0f);
275
276        std::vector<VoronoiGenerator::Tri>::iterator a = voro.tris.begin();
277        std::vector<VoronoiGenerator::Tri>::iterator end = voro.tris.end();
278        while(a != end)
279        {
280                Vector la = (voro.dirs[a->bi] - voro.dirs[a->ai]);
281                Vector lb = (voro.dirs[a->ci] - voro.dirs[a->ai]);
282                double lcos = la * lb;
283                if(lcos >= 1.0)
284                        lcos = 1.0;
285                double triArea =
286                        sqrt(la.norm2() * la.norm2() * (1.0 - lcos * lcos)) / 4.0;
287                voronoiRadii[a->ai] += triArea;
288                voronoiRadii[a->bi] += triArea;
289                voronoiRadii[a->ci] += triArea;
290                a++;
291        }
292        float xx;
293        for(int g=0; g < samplePoints.size(); g++)
294        {       
295                xx = sqrt(voronoiRadii[g] / 3.14);
296                voronoiRadii[g] = xx;
297        }
298        return;
299}
Note: See TracBrowser for help on using the repository browser.