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

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

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