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

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

vss updates

RevLine 
[372]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"
[376]9#include "VssRay.h"
[382]10#include "VssTree.h"
[372]11
[427]12
13bool useViewSpaceBox = true;
14bool use2dSampling = false;
15bool useViewspacePlane = false;
16
[372]17VssPreprocessor::VssPreprocessor():
18        mPass(0),
[376]19        mVssRays()
[372]20{
21  // this should increase coherence of the samples
[376]22  environment->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass);
[403]23  environment->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples);
24  environment->GetIntValue("VssPreprocessor.vssSamples", mVssSamples);
[427]25  environment->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass);
[403]26        environment->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
27       
[372]28  mStats.open("stats.log");
29}
30
31VssPreprocessor::~VssPreprocessor()
32{
[376]33        CLEAR_CONTAINER(mVssRays);
[372]34}
35
36void
37VssPreprocessor::SetupRay(Ray &ray,
38                                                                                                        const Vector3 &point,
[374]39                                                                                                        const Vector3 &direction
40                                                                                                        )
[372]41{
42  ray.intersections.clear();
[374]43        // do not store anything else then intersections at the ray
44  ray.Init(point, direction, Ray::LOCAL_RAY);
[372]45}
46
[386]47int
[376]48VssPreprocessor::CastRay(
49                                                                                                 Vector3 &viewPoint,
[401]50                                                                                                 Vector3 &direction,
51                                                                                                 VssRayContainer &vssRays
[376]52                                                                                                 )
[372]53{
[386]54        int hits = 0;
[376]55        static Ray ray;
56        AxisAlignedBox3 box = mKdTree->GetBox();
[427]57
58        AxisAlignedBox3 sbox = box;
59        sbox.Enlarge(Vector3(-Limits::Small));
60        if (!sbox.IsInside(viewPoint))
61                return 0;
[376]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;
[382]67        float bsize = Magnitude(box.Size());
[376]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);
[382]76                if (tmax > bsize) {
[401]77                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
78                        //                      cerr<<"ray"<<ray<<endl;
[382]79                }
[376]80                pointA = ray.Extrap(tmax);
[382]81               
[376]82        }
[386]83
84        bool detectEmptyViewSpace = true;
[376]85       
[386]86        if (detectEmptyViewSpace) {
87                SetupRay(ray, pointA, -direction);
88        } else
89                SetupRay(ray, viewPoint, -direction);
[376]90       
[386]91       
[376]92        if (mKdTree->CastRay(ray)) {
[387]93               
[376]94                objectB = ray.intersections[0].mObject;
95          pointB = ray.Extrap(ray.intersections[0].mT);
[387]96
[376]97        } else {
98                objectB = NULL;
99                float tmin, tmax;
100                box.ComputeMinMaxT(ray, &tmin, &tmax);
[382]101                if (tmax > bsize) {
[401]102                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
103                        //                      cerr<<"ray"<<ray<<endl;
[382]104                }
105               
[376]106                pointB = ray.Extrap(tmax);
107        }
[372]108
[376]109        VssRay *vssRay  = NULL;
[386]110
[387]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                }
[386]117        }
[374]118       
[387]119        if (validSample) {
120                if (objectA) {
121                        vssRay = new VssRay(pointB,
122                                                                                                        pointA,
123                                                                                                        objectB,
124                                                                                                        objectA);
[401]125                        vssRays.push_back(vssRay);
[387]126                        hits ++;
127                }
128               
129                if (objectB) {
130                        vssRay = new VssRay(pointA,
131                                                                                                        pointB,
132                                                                                                        objectA,
133                                                                                                        objectB);
[401]134                        vssRays.push_back(vssRay);
[387]135                        hits ++;
136                }
[372]137        }
138       
[386]139        return hits;
[372]140}
141
142
[376]143Vector3
[382]144VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
[372]145{
[382]146        AxisAlignedBox3 box;
147       
148        if (viewSpaceBox)
149                box =*viewSpaceBox;
[387]150        else
[382]151                box = mKdTree->GetBox();
152       
[376]153        // shrink the box in the y direction
154        return box.GetRandomPoint();
[372]155}
156
[376]157Vector3
[427]158VssPreprocessor::GetDirection(const Vector3 &viewpoint,
159                                                                                                                        AxisAlignedBox3 *viewSpaceBox
160                                                                                                                        )
[372]161{
[427]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       
[376]180        return point - viewpoint;
[372]181}
182
[401]183int
[427]184VssPreprocessor::GenerateImportanceRays(VssTree *vssTree,
185                                                                                                                                                                const int desiredSamples,
186                                                                                                                                                                SimpleRayContainer &rays
187                                                                                                                                                                )
[401]188{
[427]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}
[376]215
216
[427]217bool
218VssPreprocessor::ExportRays(const char *filename,
219                                                                                                                const VssRayContainer &vssRays,
220                                                                                                                const int number
221                                                                                                                )
222{
223        cout<<"Exporting vss rays..."<<endl<<flush;
[401]224       
[427]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        }
[401]241       
[427]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));
[401]247       
[427]248        delete exporter;
[401]249
[427]250        cout<<"done."<<endl<<flush;
251
252        return true;
[401]253}
254
255
[372]256bool
[427]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
[372]317VssPreprocessor::ComputeVisibility()
318{
319 
[376]320  mSceneGraph->CollectObjects(&mObjects);
321       
[372]322  long startTime = GetTime();
323 
324  int totalSamples = 0;
325
326
[427]327        AxisAlignedBox3 *box = new AxisAlignedBox3(mKdTree->GetBox());
[382]328
[427]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               
[387]339                // sample city like heights
[427]340                box->SetMin(1, box->Min(1) + box->Size(1)*0.1);
341                box->SetMax(1, box->Min(1) + box->Size(1)*0.2);
[387]342        }
[427]343
344        if (use2dSampling)
345                box->SetMax(1, box->Min(1));
[387]346       
[382]347        if (useViewSpaceBox)
[427]348                mViewSpaceBox = box;
349        else
350                mViewSpaceBox = NULL;
351               
[401]352
353        VssTree *vssTree = NULL;
354
[403]355  while (totalSamples < mInitialSamples) {
[372]356                int passContributingSamples = 0;
357                int passSampleContributions = 0;
358                int passSamples = 0;
359                int index = 0;
360               
[376]361                int sampleContributions;
[372]362               
[427]363                int s = Min(mSamplesPerPass, mInitialSamples);
364                for (int k=0; k < s; k++) {
[382]365                       
[427]366                        Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
367                        Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
[382]368                       
[401]369                        sampleContributions = CastRay(viewpoint, direction, mVssRays);
[376]370                       
371                       
372                        //-- CORR matt: put block inside loop
373                        if (sampleContributions) {
374                                passContributingSamples ++;
375                                passSampleContributions += sampleContributions;
376                        }
377                        passSamples++;
378                        totalSamples++;
[372]379                }
380   
381                mPass++;
[382]382               
[372]383                int pvsSize = 0;
384                float avgRayContrib = (passContributingSamples > 0) ?
385                        passSampleContributions/(float)passContributingSamples : 0;
[376]386               
[372]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="
[376]391                                 << pvsSize/(float)mObjects.size() << endl
392                                 << "avg ray contrib=" << avgRayContrib << endl;
393               
[372]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 <<
[376]400                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
[372]401                        "#AvgRayContrib\n" << avgRayContrib << endl;
[401]402
403
404
405               
[372]406        }
407       
[374]408        cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
[382]409        cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
[372]410
[386]411       
[427]412        //      int numExportRays = 10000;
[386]413
[427]414        int numExportRays = 0;
[386]415
[427]416        if (numExportRays) {
417                char filename[64];
418                sprintf(filename, "vss-rays-initial.x3d");
419                ExportRays(filename, mVssRays, numExportRays);
[386]420        }
421
[382]422
[401]423
424
425        vssTree = new VssTree;
426       
[427]427        vssTree->Construct(mVssRays, mViewSpaceBox);
[386]428
[387]429        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
[401]430
[427]431        ExportVssTreeLeaves(vssTree, 10);
[382]432       
[401]433        int samples = 0;
[427]434        int pass = 0;
[403]435        while (1) {
[427]436                int num = mVssSamplesPerPass;
437                SimpleRayContainer rays;
438                VssRayContainer vssRays;
439               
[403]440                if (!mUseImportanceSampling) {
[401]441                        for (int j=0; j < num; j++) {
[427]442                                Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
443                                Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
444                                rays.push_back(SimpleRay(viewpoint, direction));
[401]445                        }
446                } else {
[427]447                        num = GenerateImportanceRays(vssTree, num, rays);
[401]448                }
[427]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               
[401]472                samples+=num;
473                float pvs = vssTree->GetAvgPvsSize();
[427]474                cout<<"*****************************\n";
[401]475                cout<<samples<<" avgPVS ="<<pvs<<endl;
[427]476                cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
477                cout<<"*****************************\n";
[403]478                if (samples >= mVssSamples)
479                        break;
[427]480                pass++;
[401]481        }
[386]482
[401]483        delete vssTree;
484       
[372]485  return true;
486}
487
Note: See TracBrowser for help on using the repository browser.