source: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp @ 427

Revision 427, 11.8 KB checked in by bittner, 19 years ago (diff)

vss updates

Line 
1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "VssPreprocessor.h"
4#include "X3dExporter.h"
5#include "Environment.h"
6#include "MutualVisibility.h"
7#include "Polygon3.h"
8#include "ViewCell.h"
9#include "VssRay.h"
10#include "VssTree.h"
11
12
13bool useViewSpaceBox = true;
14bool use2dSampling = false;
15bool useViewspacePlane = false;
16
17VssPreprocessor::VssPreprocessor():
18        mPass(0),
19        mVssRays()
20{
21  // this should increase coherence of the samples
22  environment->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass);
23  environment->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples);
24  environment->GetIntValue("VssPreprocessor.vssSamples", mVssSamples);
25  environment->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass);
26        environment->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
27       
28  mStats.open("stats.log");
29}
30
31VssPreprocessor::~VssPreprocessor()
32{
33        CLEAR_CONTAINER(mVssRays);
34}
35
36void
37VssPreprocessor::SetupRay(Ray &ray,
38                                                                                                        const Vector3 &point,
39                                                                                                        const Vector3 &direction
40                                                                                                        )
41{
42  ray.intersections.clear();
43        // do not store anything else then intersections at the ray
44  ray.Init(point, direction, Ray::LOCAL_RAY);
45}
46
47int
48VssPreprocessor::CastRay(
49                                                                                                 Vector3 &viewPoint,
50                                                                                                 Vector3 &direction,
51                                                                                                 VssRayContainer &vssRays
52                                                                                                 )
53{
54        int hits = 0;
55        static Ray ray;
56        AxisAlignedBox3 box = mKdTree->GetBox();
57
58        AxisAlignedBox3 sbox = box;
59        sbox.Enlarge(Vector3(-Limits::Small));
60        if (!sbox.IsInside(viewPoint))
61                return 0;
62       
63        SetupRay(ray, viewPoint, direction);
64        // cast ray to KD tree to find intersection with other objects
65        Intersectable *objectA, *objectB;
66        Vector3 pointA, pointB;
67        float bsize = Magnitude(box.Size());
68        if (mKdTree->CastRay(ray)) {
69                objectA = ray.intersections[0].mObject;
70                pointA = ray.Extrap(ray.intersections[0].mT);
71        } else {
72                objectA = NULL;
73                // compute intersection with the scene bounding box
74                float tmin, tmax;
75                box.ComputeMinMaxT(ray, &tmin, &tmax);
76                if (tmax > bsize) {
77                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
78                        //                      cerr<<"ray"<<ray<<endl;
79                }
80                pointA = ray.Extrap(tmax);
81               
82        }
83
84        bool detectEmptyViewSpace = true;
85       
86        if (detectEmptyViewSpace) {
87                SetupRay(ray, pointA, -direction);
88        } else
89                SetupRay(ray, viewPoint, -direction);
90       
91       
92        if (mKdTree->CastRay(ray)) {
93               
94                objectB = ray.intersections[0].mObject;
95          pointB = ray.Extrap(ray.intersections[0].mT);
96
97        } else {
98                objectB = NULL;
99                float tmin, tmax;
100                box.ComputeMinMaxT(ray, &tmin, &tmax);
101                if (tmax > bsize) {
102                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
103                        //                      cerr<<"ray"<<ray<<endl;
104                }
105               
106                pointB = ray.Extrap(tmax);
107        }
108
109        VssRay *vssRay  = NULL;
110
111        bool validSample = true;
112        if (detectEmptyViewSpace) {
113                if (Distance(pointA, pointB) <
114                                Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small) {
115                        validSample = false;
116                }
117        }
118       
119        if (validSample) {
120                if (objectA) {
121                        vssRay = new VssRay(pointB,
122                                                                                                        pointA,
123                                                                                                        objectB,
124                                                                                                        objectA);
125                        vssRays.push_back(vssRay);
126                        hits ++;
127                }
128               
129                if (objectB) {
130                        vssRay = new VssRay(pointA,
131                                                                                                        pointB,
132                                                                                                        objectA,
133                                                                                                        objectB);
134                        vssRays.push_back(vssRay);
135                        hits ++;
136                }
137        }
138       
139        return hits;
140}
141
142
143Vector3
144VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
145{
146        AxisAlignedBox3 box;
147       
148        if (viewSpaceBox)
149                box =*viewSpaceBox;
150        else
151                box = mKdTree->GetBox();
152       
153        // shrink the box in the y direction
154        return box.GetRandomPoint();
155}
156
157Vector3
158VssPreprocessor::GetDirection(const Vector3 &viewpoint,
159                                                                                                                        AxisAlignedBox3 *viewSpaceBox
160                                                                                                                        )
161{
162        Vector3 point;
163        if (!use2dSampling) {
164                Vector3 normal;
165                int i = RandomValue(0, mObjects.size()-1);
166                Intersectable *object = mObjects[i];
167                object->GetRandomSurfacePoint(point, normal);
168        } else {
169                AxisAlignedBox3 box;
170               
171                if (viewSpaceBox)
172                        box =*viewSpaceBox;
173                else
174                        box = mKdTree->GetBox();
175               
176                point = box.GetRandomPoint();
177                point.y = viewpoint.y;
178        }
179       
180        return point - viewpoint;
181}
182
183int
184VssPreprocessor::GenerateImportanceRays(VssTree *vssTree,
185                                                                                                                                                                const int desiredSamples,
186                                                                                                                                                                SimpleRayContainer &rays
187                                                                                                                                                                )
188{
189        int num;
190        if (0) {
191                float minRayContribution;
192                float maxRayContribution;
193                float avgRayContribution;
194               
195                vssTree->GetRayContributionStatistics(minRayContribution,
196                                                                                                                                                                        maxRayContribution,
197                                                                                                                                                                        avgRayContribution);
198               
199                cout<<
200                        "#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
201                        "#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
202                        "#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
203               
204                float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
205                num = vssTree->GenerateRays(p, rays);
206        } else {
207                int leaves = vssTree->stat.Leaves()/2;
208                num = vssTree->GenerateRays(desiredSamples, leaves, rays);
209        }
210       
211        cout<<"Generated "<<num<<" rays."<<endl;
212       
213        return num;
214}
215
216
217bool
218VssPreprocessor::ExportRays(const char *filename,
219                                                                                                                const VssRayContainer &vssRays,
220                                                                                                                const int number
221                                                                                                                )
222{
223        cout<<"Exporting vss rays..."<<endl<<flush;
224       
225        float prob = number/(float)vssRays.size();
226
227
228        Exporter *exporter = NULL;
229        exporter = Exporter::GetExporter(filename);
230        //      exporter->SetWireframe();
231        //      exporter->ExportKdTree(*mKdTree);
232        exporter->SetFilled();
233        exporter->ExportScene(mSceneGraph->mRoot);
234        exporter->SetWireframe();
235
236        if (mViewSpaceBox) {
237                exporter->SetForcedMaterial(RgbColor(1,0,0));
238                exporter->ExportBox(*mViewSpaceBox);
239                exporter->ResetForcedMaterial();
240        }
241       
242        VssRayContainer rays;   for (int i=0; i < vssRays.size(); i++)
243                if (RandomValue(0,1) < prob)
244                        rays.push_back(vssRays[i]);
245
246        exporter->ExportRays(rays, RgbColor(1, 0, 0));
247       
248        delete exporter;
249
250        cout<<"done."<<endl<<flush;
251
252        return true;
253}
254
255
256bool
257VssPreprocessor::ExportVssTreeLeaf(char *filename,
258                                                                                                                                         VssTree *tree,
259                                                                                                                                         VssTreeLeaf *leaf)
260{
261        Exporter *exporter = NULL;
262        exporter = Exporter::GetExporter(filename);
263        exporter->SetWireframe();
264        exporter->ExportKdTree(*mKdTree);
265       
266        if (mViewSpaceBox) {
267                exporter->SetForcedMaterial(RgbColor(1,0,0));
268                exporter->ExportBox(*mViewSpaceBox);
269                exporter->ResetForcedMaterial();
270        }
271       
272        exporter->SetForcedMaterial(RgbColor(0,0,1));
273        exporter->ExportBox(tree->GetBBox(leaf));
274        exporter->ResetForcedMaterial();
275       
276        VssRayContainer rays[4];
277        for (int i=0; i < leaf->rays.size(); i++) {
278                int k = leaf->rays[i].GetRayClass();
279                rays[k].push_back(leaf->rays[i].mRay);
280        }
281       
282        // SOURCE RAY
283        exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
284        // TERMINATION RAY
285        exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
286        // PASSING_RAY
287        exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
288        // CONTAINED_RAY
289        exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
290
291        delete exporter;
292        return true;
293}
294
295void
296VssPreprocessor::ExportVssTreeLeaves(VssTree *tree, const int number)
297{
298        vector<VssTreeLeaf *> leaves;
299        tree->CollectLeaves(leaves);
300
301        int num = 0;
302        int i;
303        float p = number / (float)leaves.size();
304        for (i=0; i < leaves.size(); i++) {
305                if (RandomValue(0,1) < p) {
306                        char filename[64];
307                        sprintf(filename, "vss-leaf-%04d.x3d", num);
308                        ExportVssTreeLeaf(filename, tree, leaves[i]);
309                        num++;
310                }
311                if (num >= number)
312                        break;
313        }
314}
315
316bool
317VssPreprocessor::ComputeVisibility()
318{
319 
320  mSceneGraph->CollectObjects(&mObjects);
321       
322  long startTime = GetTime();
323 
324  int totalSamples = 0;
325
326
327        AxisAlignedBox3 *box = new AxisAlignedBox3(mKdTree->GetBox());
328
329        if (!useViewspacePlane) {
330                float size = 0.01f;
331                float s = 0.5f - size;
332                float olds = Magnitude(box->Size());
333                box->Enlarge(box->Size()*Vector3(-s));
334                Vector3 translation = Vector3(-olds*0.1f, 0, 0);
335                box->SetMin(box->Min() + translation);
336                box->SetMax(box->Max() + translation);
337        } else {
338               
339                // sample city like heights
340                box->SetMin(1, box->Min(1) + box->Size(1)*0.1);
341                box->SetMax(1, box->Min(1) + box->Size(1)*0.2);
342        }
343
344        if (use2dSampling)
345                box->SetMax(1, box->Min(1));
346       
347        if (useViewSpaceBox)
348                mViewSpaceBox = box;
349        else
350                mViewSpaceBox = NULL;
351               
352
353        VssTree *vssTree = NULL;
354
355  while (totalSamples < mInitialSamples) {
356                int passContributingSamples = 0;
357                int passSampleContributions = 0;
358                int passSamples = 0;
359                int index = 0;
360               
361                int sampleContributions;
362               
363                int s = Min(mSamplesPerPass, mInitialSamples);
364                for (int k=0; k < s; k++) {
365                       
366                        Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
367                        Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
368                       
369                        sampleContributions = CastRay(viewpoint, direction, mVssRays);
370                       
371                       
372                        //-- CORR matt: put block inside loop
373                        if (sampleContributions) {
374                                passContributingSamples ++;
375                                passSampleContributions += sampleContributions;
376                        }
377                        passSamples++;
378                        totalSamples++;
379                }
380   
381                mPass++;
382               
383                int pvsSize = 0;
384                float avgRayContrib = (passContributingSamples > 0) ?
385                        passSampleContributions/(float)passContributingSamples : 0;
386               
387                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
388                cout << "#TotalSamples=" << totalSamples/1000
389                                 << "k   #SampleContributions=" << passSampleContributions << " ("
390                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
391                                 << pvsSize/(float)mObjects.size() << endl
392                                 << "avg ray contrib=" << avgRayContrib << endl;
393               
394                mStats <<
395                        "#Pass\n" <<mPass<<endl<<
396                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
397                        "#TotalSamples\n" << totalSamples<< endl<<
398                        "#SampleContributions\n" << passSampleContributions << endl <<
399                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
400                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
401                        "#AvgRayContrib\n" << avgRayContrib << endl;
402
403
404
405               
406        }
407       
408        cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
409        cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
410
411       
412        //      int numExportRays = 10000;
413
414        int numExportRays = 0;
415
416        if (numExportRays) {
417                char filename[64];
418                sprintf(filename, "vss-rays-initial.x3d");
419                ExportRays(filename, mVssRays, numExportRays);
420        }
421
422
423
424
425        vssTree = new VssTree;
426       
427        vssTree->Construct(mVssRays, mViewSpaceBox);
428
429        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
430
431        ExportVssTreeLeaves(vssTree, 10);
432       
433        int samples = 0;
434        int pass = 0;
435        while (1) {
436                int num = mVssSamplesPerPass;
437                SimpleRayContainer rays;
438                VssRayContainer vssRays;
439               
440                if (!mUseImportanceSampling) {
441                        for (int j=0; j < num; j++) {
442                                Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
443                                Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
444                                rays.push_back(SimpleRay(viewpoint, direction));
445                        }
446                } else {
447                        num = GenerateImportanceRays(vssTree, num, rays);
448                }
449               
450               
451                for (int i=0; i < rays.size(); i++)
452                        CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays);
453               
454                vssTree->AddRays(vssRays);
455               
456                if (1) {
457                        int subdivided = vssTree->UpdateSubdivision();
458                        cout<<"subdivided leafs = "<<subdivided<<endl;
459                }
460               
461                if (numExportRays) {
462                        char filename[64];
463                        if (mUseImportanceSampling)
464                                sprintf(filename, "vss-rays-i%04d.x3d", pass);
465                        else
466                                sprintf(filename, "vss-rays-%04d.x3d", pass);
467                       
468                        ExportRays(filename, vssRays, numExportRays);
469                }
470
471               
472                samples+=num;
473                float pvs = vssTree->GetAvgPvsSize();
474                cout<<"*****************************\n";
475                cout<<samples<<" avgPVS ="<<pvs<<endl;
476                cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
477                cout<<"*****************************\n";
478                if (samples >= mVssSamples)
479                        break;
480                pass++;
481        }
482
483        delete vssTree;
484       
485  return true;
486}
487
Note: See TracBrowser for help on using the repository browser.