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

Revision 387, 6.5 KB checked in by bittner, 19 years ago (diff)

vss preprocessor 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                                                                                                 )
43{
44        int hits = 0;
45        static Ray ray;
46        AxisAlignedBox3 box = mKdTree->GetBox();
47       
48        SetupRay(ray, viewPoint, direction);
49        // cast ray to KD tree to find intersection with other objects
50        Intersectable *objectA, *objectB;
51        Vector3 pointA, pointB;
52        float bsize = Magnitude(box.Size());
53        if (mKdTree->CastRay(ray)) {
54                objectA = ray.intersections[0].mObject;
55                pointA = ray.Extrap(ray.intersections[0].mT);
56        } else {
57                objectA = NULL;
58                // compute intersection with the scene bounding box
59                float tmin, tmax;
60                box.ComputeMinMaxT(ray, &tmin, &tmax);
61                if (tmax > bsize) {
62                        cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
63                        cerr<<"ray"<<ray<<endl;
64                }
65                pointA = ray.Extrap(tmax);
66               
67        }
68
69        bool detectEmptyViewSpace = true;
70       
71        if (detectEmptyViewSpace) {
72                SetupRay(ray, pointA, -direction);
73        } else
74                SetupRay(ray, viewPoint, -direction);
75       
76       
77        if (mKdTree->CastRay(ray)) {
78               
79                objectB = ray.intersections[0].mObject;
80          pointB = ray.Extrap(ray.intersections[0].mT);
81
82        } else {
83                objectB = NULL;
84                float tmin, tmax;
85                box.ComputeMinMaxT(ray, &tmin, &tmax);
86                if (tmax > bsize) {
87                        cerr<<"Warning: tmax > box size tmax="<<tmax<<" tmin="<<tmin<<" size="<<bsize<<endl;
88                        cerr<<"ray"<<ray<<endl;
89                }
90               
91                pointB = ray.Extrap(tmax);
92        }
93
94        VssRay *vssRay  = NULL;
95
96        bool validSample = true;
97        if (detectEmptyViewSpace) {
98                if (Distance(pointA, pointB) <
99                                Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small) {
100                        validSample = false;
101                }
102        }
103       
104        if (validSample) {
105                if (objectA) {
106                        vssRay = new VssRay(pointB,
107                                                                                                        pointA,
108                                                                                                        objectB,
109                                                                                                        objectA);
110                        mVssRays.push_back(vssRay);
111                        hits ++;
112                }
113               
114                if (objectB) {
115                        vssRay = new VssRay(pointA,
116                                                                                                        pointB,
117                                                                                                        objectA,
118                                                                                                        objectB);
119                        mVssRays.push_back(vssRay);
120                        hits ++;
121                }
122        }
123       
124        return hits;
125}
126
127
128Vector3
129VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
130{
131        AxisAlignedBox3 box;
132       
133        if (viewSpaceBox)
134                box =*viewSpaceBox;
135        else
136                box = mKdTree->GetBox();
137       
138        // shrink the box in the y direction
139        return box.GetRandomPoint();
140}
141
142Vector3
143VssPreprocessor::GetDirection(const Vector3 &viewpoint)
144{
145        int i = RandomValue(0, mObjects.size()-1);
146        Intersectable *object = mObjects[i];
147        Vector3 point, normal;
148        object->GetRandomSurfacePoint(point, normal);
149        return point - viewpoint;
150}
151
152
153
154bool
155VssPreprocessor::ComputeVisibility()
156{
157 
158  mSceneGraph->CollectObjects(&mObjects);
159       
160  long startTime = GetTime();
161 
162  int totalSamples = 0;
163
164        AxisAlignedBox3 *viewSpaceBox = NULL;
165
166        AxisAlignedBox3 box = mKdTree->GetBox();
167
168       
169        if (1)
170                box.Enlarge(box.Size()*-Vector3(0.45, 0.45, 0.45));
171        else {
172                // sample city like heights
173                box.SetMin(1, box.Min(1) + box.Size(1)*0.1);
174                box.SetMax(1, box.Min(1) + box.Size(1)*0.2);
175        }
176       
177        bool useViewSpaceBox = true;
178        if (useViewSpaceBox)
179                viewSpaceBox = &box;
180       
181  while (totalSamples < mTotalSamples) {
182                int passContributingSamples = 0;
183                int passSampleContributions = 0;
184                int passSamples = 0;
185                int index = 0;
186               
187                int sampleContributions;
188               
189               
190                for (int k=0; k < mSamplesPerPass; k++) {
191                       
192                        Vector3 viewpoint = GetViewpoint(viewSpaceBox);
193                        Vector3 direction = GetDirection(viewpoint);
194                       
195                        sampleContributions = CastRay(viewpoint, direction);
196                       
197                       
198                        //-- CORR matt: put block inside loop
199                        if (sampleContributions) {
200                                passContributingSamples ++;
201                                passSampleContributions += sampleContributions;
202                        }
203                        passSamples++;
204                        totalSamples++;
205                }
206   
207                mPass++;
208               
209                int pvsSize = 0;
210                float avgRayContrib = (passContributingSamples > 0) ?
211                        passSampleContributions/(float)passContributingSamples : 0;
212               
213                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
214                cout << "#TotalSamples=" << totalSamples/1000
215                                 << "k   #SampleContributions=" << passSampleContributions << " ("
216                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
217                                 << pvsSize/(float)mObjects.size() << endl
218                                 << "avg ray contrib=" << avgRayContrib << endl;
219               
220                mStats <<
221                        "#Pass\n" <<mPass<<endl<<
222                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
223                        "#TotalSamples\n" << totalSamples<< endl<<
224                        "#SampleContributions\n" << passSampleContributions << endl <<
225                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
226                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
227                        "#AvgRayContrib\n" << avgRayContrib << endl;
228        }
229       
230        cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
231        cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
232
233        cout<<"Exporting vss rays..."<<endl<<flush;
234       
235        int exportRays = 10000;
236
237        if (exportRays) {
238                float prob = exportRays/(float)mVssRays.size();
239               
240                Exporter *exporter = NULL;
241                exporter = Exporter::GetExporter("vss-rays.x3d");
242                exporter->SetWireframe();
243                exporter->ExportKdTree(*mKdTree);
244                if (viewSpaceBox) {
245                        exporter->SetForcedMaterial(RgbColor(1,0,0));
246                        exporter->ExportBox(*viewSpaceBox);
247                        exporter->ResetForcedMaterial();
248                }
249                VssRayContainer rays;
250                for (int i=0; i < mVssRays.size(); i++)
251                        if (RandomValue(0,1) < prob)
252                                rays.push_back(mVssRays[i]);
253                exporter->ExportRays(rays, RgbColor(1, 0, 0));
254
255                delete exporter;
256        }
257        cout<<"done."<<endl<<flush;
258
259        VssTree *vssTree = new VssTree;
260
261        vssTree->Construct(mVssRays, viewSpaceBox);
262
263        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
264       
265
266
267  return true;
268}
269
Note: See TracBrowser for help on using the repository browser.