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

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

vvs preprocessor update

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
12VssPreprocessor::VssPreprocessor():
13        mPass(0),
14        mVssRays()
15{
16  // this should increase coherence of the samples
17  environment->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass);
18  environment->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples);
19  environment->GetIntValue("VssPreprocessor.vssSamples", mVssSamples);
20        environment->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
21       
22  mStats.open("stats.log");
23}
24
25VssPreprocessor::~VssPreprocessor()
26{
27        CLEAR_CONTAINER(mVssRays);
28}
29
30void
31VssPreprocessor::SetupRay(Ray &ray,
32                                                                                                        const Vector3 &point,
33                                                                                                        const Vector3 &direction
34                                                                                                        )
35{
36  ray.intersections.clear();
37        // do not store anything else then intersections at the ray
38  ray.Init(point, direction, Ray::LOCAL_RAY);
39}
40
41int
42VssPreprocessor::CastRay(
43                                                                                                 Vector3 &viewPoint,
44                                                                                                 Vector3 &direction,
45                                                                                                 VssRayContainer &vssRays
46                                                                                                 )
47{
48        int hits = 0;
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;
56        float bsize = Magnitude(box.Size());
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);
65                if (tmax > bsize) {
66                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
67                        //                      cerr<<"ray"<<ray<<endl;
68                }
69                pointA = ray.Extrap(tmax);
70               
71        }
72
73        bool detectEmptyViewSpace = true;
74       
75        if (detectEmptyViewSpace) {
76                SetupRay(ray, pointA, -direction);
77        } else
78                SetupRay(ray, viewPoint, -direction);
79       
80       
81        if (mKdTree->CastRay(ray)) {
82               
83                objectB = ray.intersections[0].mObject;
84          pointB = ray.Extrap(ray.intersections[0].mT);
85
86        } else {
87                objectB = NULL;
88                float tmin, tmax;
89                box.ComputeMinMaxT(ray, &tmin, &tmax);
90                if (tmax > bsize) {
91                        //                      cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
92                        //                      cerr<<"ray"<<ray<<endl;
93                }
94               
95                pointB = ray.Extrap(tmax);
96        }
97
98        VssRay *vssRay  = NULL;
99
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                }
106        }
107       
108        if (validSample) {
109                if (objectA) {
110                        vssRay = new VssRay(pointB,
111                                                                                                        pointA,
112                                                                                                        objectB,
113                                                                                                        objectA);
114                        vssRays.push_back(vssRay);
115                        hits ++;
116                }
117               
118                if (objectB) {
119                        vssRay = new VssRay(pointA,
120                                                                                                        pointB,
121                                                                                                        objectA,
122                                                                                                        objectB);
123                        vssRays.push_back(vssRay);
124                        hits ++;
125                }
126        }
127       
128        return hits;
129}
130
131
132Vector3
133VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
134{
135        AxisAlignedBox3 box;
136       
137        if (viewSpaceBox)
138                box =*viewSpaceBox;
139        else
140                box = mKdTree->GetBox();
141       
142        // shrink the box in the y direction
143        return box.GetRandomPoint();
144}
145
146Vector3
147VssPreprocessor::GetDirection(const Vector3 &viewpoint)
148{
149        int i = RandomValue(0, mObjects.size()-1);
150        Intersectable *object = mObjects[i];
151        Vector3 point, normal;
152        object->GetRandomSurfacePoint(point, normal);
153        return point - viewpoint;
154}
155
156int
157VssPreprocessor::RandomizedImportanceSampling(VssTree *vssTree,
158                                                                                                                                                                                        const int desiredSamples)
159{
160        float minRayContribution;
161        float maxRayContribution;
162        float avgRayContribution;
163
164        vssTree->GetRayContributionStatistics(minRayContribution,
165                                                                                                                                                                maxRayContribution,
166                                                                                                                                                                avgRayContribution);
167
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
188bool
189VssPreprocessor::ComputeVisibility()
190{
191 
192  mSceneGraph->CollectObjects(&mObjects);
193       
194  long startTime = GetTime();
195 
196  int totalSamples = 0;
197
198        AxisAlignedBox3 *viewSpaceBox = NULL;
199
200        AxisAlignedBox3 box = mKdTree->GetBox();
201
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       
211        bool useViewSpaceBox = false;
212        if (useViewSpaceBox)
213                viewSpaceBox = &box;
214
215        VssTree *vssTree = NULL;
216
217  while (totalSamples < mInitialSamples) {
218                int passContributingSamples = 0;
219                int passSampleContributions = 0;
220                int passSamples = 0;
221                int index = 0;
222               
223                int sampleContributions;
224               
225               
226                for (int k=0; k < mSamplesPerPass; k++) {
227                       
228                        Vector3 viewpoint = GetViewpoint(viewSpaceBox);
229                        Vector3 direction = GetDirection(viewpoint);
230                       
231                        sampleContributions = CastRay(viewpoint, direction, mVssRays);
232                       
233                       
234                        //-- CORR matt: put block inside loop
235                        if (sampleContributions) {
236                                passContributingSamples ++;
237                                passSampleContributions += sampleContributions;
238                        }
239                        passSamples++;
240                        totalSamples++;
241                }
242   
243                mPass++;
244               
245                int pvsSize = 0;
246                float avgRayContrib = (passContributingSamples > 0) ?
247                        passSampleContributions/(float)passContributingSamples : 0;
248               
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="
253                                 << pvsSize/(float)mObjects.size() << endl
254                                 << "avg ray contrib=" << avgRayContrib << endl;
255               
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 <<
262                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
263                        "#AvgRayContrib\n" << avgRayContrib << endl;
264
265
266
267               
268        }
269       
270        cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
271        cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
272
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
299
300
301
302        vssTree = new VssTree;
303       
304        vssTree->Construct(mVssRays, viewSpaceBox);
305
306        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
307
308       
309        int samples = 0;
310        while (1) {
311                int num = mSamplesPerPass;
312                if (!mUseImportanceSampling) {
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;
326                if (samples >= mVssSamples)
327                        break;
328        }
329
330        delete vssTree;
331       
332  return true;
333}
334
Note: See TracBrowser for help on using the repository browser.