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

Revision 403, 8.2 KB checked in by bittner, 19 years ago (diff)

vvs preprocessor update

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