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

Revision 401, 8.0 KB checked in by bittner, 19 years ago (diff)

vsspreprocessor 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
12VssPreprocessor::VssPreprocessor():
13        mPass(0),
[376]14        mVssRays()
[372]15{
16  // this should increase coherence of the samples
[376]17  environment->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass);
18  environment->GetIntValue("VssPreprocessor.totalSamples", mTotalSamples);
[372]19  mStats.open("stats.log");
20}
21
22VssPreprocessor::~VssPreprocessor()
23{
[376]24        CLEAR_CONTAINER(mVssRays);
[372]25}
26
27void
28VssPreprocessor::SetupRay(Ray &ray,
29                                                                                                        const Vector3 &point,
[374]30                                                                                                        const Vector3 &direction
31                                                                                                        )
[372]32{
33  ray.intersections.clear();
[374]34        // do not store anything else then intersections at the ray
35  ray.Init(point, direction, Ray::LOCAL_RAY);
[372]36}
37
[386]38int
[376]39VssPreprocessor::CastRay(
40                                                                                                 Vector3 &viewPoint,
[401]41                                                                                                 Vector3 &direction,
42                                                                                                 VssRayContainer &vssRays
[376]43                                                                                                 )
[372]44{
[386]45        int hits = 0;
[376]46        static Ray ray;
47        AxisAlignedBox3 box = mKdTree->GetBox();
48       
49        SetupRay(ray, viewPoint, direction);
50        // cast ray to KD tree to find intersection with other objects
51        Intersectable *objectA, *objectB;
52        Vector3 pointA, pointB;
[382]53        float bsize = Magnitude(box.Size());
[376]54        if (mKdTree->CastRay(ray)) {
55                objectA = ray.intersections[0].mObject;
56                pointA = ray.Extrap(ray.intersections[0].mT);
57        } else {
58                objectA = NULL;
59                // compute intersection with the scene bounding box
60                float tmin, tmax;
61                box.ComputeMinMaxT(ray, &tmin, &tmax);
[382]62                if (tmax > bsize) {
[401]63                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
64                        //                      cerr<<"ray"<<ray<<endl;
[382]65                }
[376]66                pointA = ray.Extrap(tmax);
[382]67               
[376]68        }
[386]69
70        bool detectEmptyViewSpace = true;
[376]71       
[386]72        if (detectEmptyViewSpace) {
73                SetupRay(ray, pointA, -direction);
74        } else
75                SetupRay(ray, viewPoint, -direction);
[376]76       
[386]77       
[376]78        if (mKdTree->CastRay(ray)) {
[387]79               
[376]80                objectB = ray.intersections[0].mObject;
81          pointB = ray.Extrap(ray.intersections[0].mT);
[387]82
[376]83        } else {
84                objectB = NULL;
85                float tmin, tmax;
86                box.ComputeMinMaxT(ray, &tmin, &tmax);
[382]87                if (tmax > bsize) {
[401]88                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
89                        //                      cerr<<"ray"<<ray<<endl;
[382]90                }
91               
[376]92                pointB = ray.Extrap(tmax);
93        }
[372]94
[376]95        VssRay *vssRay  = NULL;
[386]96
[387]97        bool validSample = true;
98        if (detectEmptyViewSpace) {
99                if (Distance(pointA, pointB) <
100                                Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small) {
101                        validSample = false;
102                }
[386]103        }
[374]104       
[387]105        if (validSample) {
106                if (objectA) {
107                        vssRay = new VssRay(pointB,
108                                                                                                        pointA,
109                                                                                                        objectB,
110                                                                                                        objectA);
[401]111                        vssRays.push_back(vssRay);
[387]112                        hits ++;
113                }
114               
115                if (objectB) {
116                        vssRay = new VssRay(pointA,
117                                                                                                        pointB,
118                                                                                                        objectA,
119                                                                                                        objectB);
[401]120                        vssRays.push_back(vssRay);
[387]121                        hits ++;
122                }
[372]123        }
124       
[386]125        return hits;
[372]126}
127
128
[376]129Vector3
[382]130VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
[372]131{
[382]132        AxisAlignedBox3 box;
133       
134        if (viewSpaceBox)
135                box =*viewSpaceBox;
[387]136        else
[382]137                box = mKdTree->GetBox();
138       
[376]139        // shrink the box in the y direction
140        return box.GetRandomPoint();
[372]141}
142
[376]143Vector3
144VssPreprocessor::GetDirection(const Vector3 &viewpoint)
[372]145{
[382]146        int i = RandomValue(0, mObjects.size()-1);
[376]147        Intersectable *object = mObjects[i];
148        Vector3 point, normal;
149        object->GetRandomSurfacePoint(point, normal);
150        return point - viewpoint;
[372]151}
152
[401]153int
154VssPreprocessor::RandomizedImportanceSampling(VssTree *vssTree,
155                                                                                                                                                                                        const int desiredSamples)
156{
157        float minRayContribution;
158        float maxRayContribution;
159        float avgRayContribution;
[376]160
[401]161        vssTree->GetRayContributionStatistics(minRayContribution,
162                                                                                                                                                                maxRayContribution,
163                                                                                                                                                                avgRayContribution);
[376]164
[401]165        cout<<
166                "#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
167                "#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
168                "#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
169       
170        float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
171        SimpleRayContainer rays;
172        int num = vssTree->GenerateRays(p, rays);
173        cout<<"Generated "<<num<<" rays."<<endl;
174       
175        VssRayContainer  vssRays;
176       
177        for (int i=0; i < rays.size(); i++)
178                CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays);
179
180        vssTree->AddRays(vssRays);
181        return num;
182}
183
184
[372]185bool
186VssPreprocessor::ComputeVisibility()
187{
188 
[376]189  mSceneGraph->CollectObjects(&mObjects);
190       
[372]191  long startTime = GetTime();
192 
193  int totalSamples = 0;
194
[382]195        AxisAlignedBox3 *viewSpaceBox = NULL;
[372]196
[382]197        AxisAlignedBox3 box = mKdTree->GetBox();
198
[387]199       
200        if (1)
201                box.Enlarge(box.Size()*-Vector3(0.45, 0.45, 0.45));
202        else {
203                // sample city like heights
204                box.SetMin(1, box.Min(1) + box.Size(1)*0.1);
205                box.SetMax(1, box.Min(1) + box.Size(1)*0.2);
206        }
207       
[401]208        bool useViewSpaceBox = false;
[382]209        if (useViewSpaceBox)
210                viewSpaceBox = &box;
[401]211
212        VssTree *vssTree = NULL;
213
[372]214  while (totalSamples < mTotalSamples) {
215                int passContributingSamples = 0;
216                int passSampleContributions = 0;
217                int passSamples = 0;
218                int index = 0;
219               
[376]220                int sampleContributions;
[372]221               
222               
[376]223                for (int k=0; k < mSamplesPerPass; k++) {
[382]224                       
225                        Vector3 viewpoint = GetViewpoint(viewSpaceBox);
[376]226                        Vector3 direction = GetDirection(viewpoint);
[382]227                       
[401]228                        sampleContributions = CastRay(viewpoint, direction, mVssRays);
[376]229                       
230                       
231                        //-- CORR matt: put block inside loop
232                        if (sampleContributions) {
233                                passContributingSamples ++;
234                                passSampleContributions += sampleContributions;
235                        }
236                        passSamples++;
237                        totalSamples++;
[372]238                }
239   
240                mPass++;
[382]241               
[372]242                int pvsSize = 0;
243                float avgRayContrib = (passContributingSamples > 0) ?
244                        passSampleContributions/(float)passContributingSamples : 0;
[376]245               
[372]246                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
247                cout << "#TotalSamples=" << totalSamples/1000
248                                 << "k   #SampleContributions=" << passSampleContributions << " ("
249                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
[376]250                                 << pvsSize/(float)mObjects.size() << endl
251                                 << "avg ray contrib=" << avgRayContrib << endl;
252               
[372]253                mStats <<
254                        "#Pass\n" <<mPass<<endl<<
255                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
256                        "#TotalSamples\n" << totalSamples<< endl<<
257                        "#SampleContributions\n" << passSampleContributions << endl <<
258                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
[376]259                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
[372]260                        "#AvgRayContrib\n" << avgRayContrib << endl;
[401]261
262
263
264               
[372]265        }
266       
[374]267        cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
[382]268        cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
[372]269
[386]270        cout<<"Exporting vss rays..."<<endl<<flush;
271       
272        int exportRays = 10000;
273
274        if (exportRays) {
275                float prob = exportRays/(float)mVssRays.size();
276               
277                Exporter *exporter = NULL;
278                exporter = Exporter::GetExporter("vss-rays.x3d");
279                exporter->SetWireframe();
280                exporter->ExportKdTree(*mKdTree);
281                if (viewSpaceBox) {
282                        exporter->SetForcedMaterial(RgbColor(1,0,0));
283                        exporter->ExportBox(*viewSpaceBox);
284                        exporter->ResetForcedMaterial();
285                }
286                VssRayContainer rays;
287                for (int i=0; i < mVssRays.size(); i++)
288                        if (RandomValue(0,1) < prob)
289                                rays.push_back(mVssRays[i]);
290                exporter->ExportRays(rays, RgbColor(1, 0, 0));
291
292                delete exporter;
293        }
294        cout<<"done."<<endl<<flush;
295
[382]296
[401]297
298
299        vssTree = new VssTree;
300       
[382]301        vssTree->Construct(mVssRays, viewSpaceBox);
[386]302
[387]303        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
[401]304
[382]305       
[401]306        int samples = 0;
307        for (int i=0; i < 50; i++) {
308                int num = 100000;
309                if (0) {
310                        VssRayContainer vssRays;
311                        for (int j=0; j < num; j++) {
312                                Vector3 viewpoint = GetViewpoint(viewSpaceBox);
313                                Vector3 direction = GetDirection(viewpoint);
314                                CastRay(viewpoint, direction, vssRays);
315                        }
316                        vssTree->AddRays(vssRays);
317                } else {
318                        num = RandomizedImportanceSampling(vssTree, num);
319                }
320                samples+=num;
321                float pvs = vssTree->GetAvgPvsSize();
322                cout<<samples<<" avgPVS ="<<pvs<<endl;
323        }
[386]324
[401]325        delete vssTree;
326       
[372]327  return true;
328}
329
Note: See TracBrowser for help on using the repository browser.