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

Revision 372, 9.3 KB checked in by bittner, 19 years ago (diff)

preparation for vss preprocessor. converted all .cpp and .h to dos new line format

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
10VssPreprocessor::VssPreprocessor():
11        mPass(0),
12        mSampleRays(NULL)
13{
14  // this should increase coherence of the samples
15  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
16  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
17  mKdPvsDepth = 100;
18  mStats.open("stats.log");
19
20}
21
22VssPreprocessor::~VssPreprocessor()
23{
24        CLEAR_CONTAINER(mSampleRays);
25}
26
27void
28VssPreprocessor::SetupRay(Ray &ray,
29                                                                                                        const Vector3 &point,
30                                                                                                        const Vector3 &direction,
31                                                                                                        const int type)
32{
33  ray.intersections.clear();
34  ray.kdLeaves.clear();
35  ray.meshes.clear();
36
37  //  cout<<point<<" "<<direction<<endl;
38  ray.Init(point, direction, type);
39}
40
41KdNode *
42VssPreprocessor::GetNodeForPvs(KdLeaf *leaf)
43{
44  KdNode *node = leaf;
45  while (node->mParent && node->mDepth > mKdPvsDepth)
46    node = node->mParent;
47  return node;
48}
49
50
51int
52VssPreprocessor::AddNodeSamples(const Ray &ray,
53                                                                                                                                                 Intersectable *sObject,
54                                                                                                                                                 Intersectable *tObject
55                                                                                                                                                 )
56{
57  int contributingSamples = 0;
58  int j;
59        int objects = 0;
60        if (sObject)
61                objects++;
62        if (tObject)
63                objects++;
64
65        if (objects) {
66                for (j=0; j < ray.kdLeaves.size(); j++) {
67                        KdNode *node = GetNodeForPvs( ray.kdLeaves[j] );
68                        if (sObject)
69                                contributingSamples += sObject->mKdPvs.AddSample(node);
70                        if (tObject)
71                                contributingSamples += tObject->mKdPvs.AddSample(node);
72                }
73        }
74       
75        for (j=1; j < ((int)ray.kdLeaves.size() - 1); j++) {
76                ray.kdLeaves[j]->AddPassingRay2(ray,
77                                                                                                                                                objects,
78                                                                                                                                                ray.kdLeaves.size()
79                                                                                                                                                );
80  }
81 
82  return contributingSamples;
83}
84
85
86
87
88int
89VssPreprocessor::CastRay(Intersectable *object,
90                                                                                                 Ray &ray
91                                                                                                 )
92{
93        int sampleContributions = 0;
94
95        long t1 = GetRealTime();
96        // cast ray to KD tree to find intersection with other objects
97        mKdTree->CastRay(ray);
98        long t2 = GetRealTime();
99
100        if (0 && object && object->GetId() > 2197) {
101                object->Describe(cout)<<endl;
102                cout<<ray<<endl;
103        }
104
105        if (ray.kdLeaves.size()) {
106                Intersectable *terminator =
107                        ray.intersections.size() ? ray.intersections[0].mObject: NULL;
108               
109                sampleContributions += AddNodeSamples(ray,
110                                                                                                                                                                        object,
111                                                                                                                                                                        terminator);
112        }
113       
114       
115        return sampleContributions;
116}
117
118
119KdNode *
120VssPreprocessor::GetNodeToSample(Intersectable *object)
121{
122        int pvsSize = object->mKdPvs.GetSize();
123        KdNode *nodeToSample = NULL;
124       
125        bool samplePvsBoundary = false;
126        if (pvsSize && samplePvsBoundary) {
127                // this samples the nodes from the boundary of the current PVS
128                // mail all nodes from the pvs
129                Intersectable::NewMail();
130                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
131               
132                for (; i != object->mKdPvs.mEntries.end(); i++) {
133                        KdNode *node = (*i).first;
134                        node->Mail();
135                }
136               
137                int maxTries = 2*pvsSize;
138                Debug << "Finding random neighbour" << endl;   
139                for (int tries = 0; tries < 10; tries++) {
140                        int index = RandomValue(0, pvsSize - 1);
141                        KdPvsData data;
142                        KdNode *node;
143                        object->mKdPvs.GetData(index, node, data);
144                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
145                        if (nodeToSample)
146                                break;
147                }
148        } else {
149                // just pickup a random node
150                //              nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
151                nodeToSample = mKdTree->GetRandomLeaf();
152        }
153        return nodeToSample;
154}
155
156bool
157VssPreprocessor::ComputeVisibility()
158{
159 
160  // pickup an object
161  ObjectContainer objects;
162 
163  mSceneGraph->CollectObjects(&objects);
164
165  Vector3 point, normal, direction;
166  Ray ray;
167
168  long startTime = GetTime();
169 
170  int i;
171  int totalSamples = 0;
172
173  int pvsOut = Min((int)objects.size(), 10);
174
175  vector<Ray> rays[10];
176
177  while (totalSamples < mTotalSamples) {
178                int passContributingSamples = 0;
179                int passSampleContributions = 0;
180                int passSamples = 0;
181                int index = 0;
182               
183                int reverseSamples = 0;
184               
185                       
186                //cout << "totalSamples: "  << totalSamples << endl;
187
188                for (i = 0; i < objects.size(); i++) {
189                                               
190                        KdNode *nodeToSample = NULL;
191                        Intersectable *object = objects[i];
192               
193                        int pvsSize = 0;
194                        if (ViewCell::sHierarchy == ViewCell::KD)
195                                pvsSize = object->mKdPvs.GetSize();
196                                               
197                       
198                       
199                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
200                       
201                        bool viewcellSample = true;
202                        int sampleContributions;
203                        bool debug = false; //(object->GetId() >= 2199);
204                        if (viewcellSample) {
205                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
206
207                                nodeToSample = GetNodeToSample(object);
208
209                                for (int k=0; k < mSamplesPerPass; k++) {
210                                        bool reverseSample = false;
211                                       
212
213                                        if (nodeToSample) {
214                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
215                                                Vector3 pointToSample = box.GetRandomPoint();
216                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
217                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
218                                                        direction = pointToSample - point;
219                                                } else {
220                                                        reverseSamples++;
221                                                        reverseSample = true;
222                                                        direction = point - pointToSample;
223                                                        point = pointToSample;
224                                                }
225                                        }
226                                        else {
227                                                direction = UniformRandomVector(normal);
228                                        }
229                                       
230                                        // construct a ray
231                                        SetupRay(ray, point, direction, Ray::LOCAL_RAY);
232                                       
233                                        sampleContributions = CastRay(reverseSample ? NULL : object, ray);
234                                       
235                                        //-- CORR matt: put block inside loop
236                                        if (sampleContributions) {
237                                                passContributingSamples ++;
238                                                passSampleContributions += sampleContributions;
239                                        }
240
241                                        if ( i < pvsOut )
242                                                rays[i].push_back(ray);
243               
244                                        if (!ray.intersections.empty()) {
245                                                // check whether we can add this to the rays
246                                                for (int j = 0; j < pvsOut; j++) {
247                                                        if (objects[j] == ray.intersections[0].mObject) {
248                                                                rays[j].push_back(ray);
249                                                        }
250                                                }
251                                        }
252                                        //-------------------
253                                }
254                        } else {
255                                // edge samples
256                                // get random visible mesh
257                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
258                        }
259       
260                        // CORR matt: must add all samples
261                        passSamples += mSamplesPerPass;
262                }
263       
264                totalSamples += passSamples;
265               
266                //    if (pass>10)
267                //      HoleSamplingPass();
268   
269                mPass++;
270
271                int pvsSize = 0;
272       
273                for (i=0; i < objects.size(); i++) {
274                        Intersectable *object = objects[i];
275                        pvsSize += object->mKdPvs.GetSize();
276                }
277               
278               
279                float avgRayContrib = (passContributingSamples > 0) ?
280                        passSampleContributions/(float)passContributingSamples : 0;
281
282                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
283                cout << "#TotalSamples=" << totalSamples/1000
284                                 << "k   #SampleContributions=" << passSampleContributions << " ("
285                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
286                                 << pvsSize/(float)objects.size() << endl
287                                 << "avg ray contrib=" << avgRayContrib << endl
288                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
289
290                mStats <<
291                        "#Pass\n" <<mPass<<endl<<
292                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
293                        "#TotalSamples\n" << totalSamples<< endl<<
294                        "#SampleContributions\n" << passSampleContributions << endl <<
295                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
296                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
297                        "#AvgRayContrib\n" << avgRayContrib << endl;
298        }
299       
300        if (ViewCell::sHierarchy == ViewCell::KD)       
301                cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
302 
303       
304  //  HoleSamplingPass();
305        if (0) {
306                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
307                exporter->SetExportRayDensity(true);
308                exporter->ExportKdTree(*mKdTree);
309
310                delete exporter;
311        }
312 
313        bool exportRays = false;
314        if (exportRays) {
315                Exporter *exporter = NULL;
316                exporter = Exporter::GetExporter("sample-rays.x3d");
317                exporter->SetWireframe();
318                exporter->ExportKdTree(*mKdTree);
319
320                for (i=0; i < pvsOut; i++)
321                exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
322                exporter->SetFilled();
323                 
324                delete exporter;
325        }
326
327        //-- several visualizations and statistics
328        if (1) {
329                for (int k=0; k < pvsOut; k++) {
330                        Intersectable *object = objects[k];
331                        char s[64];
332                        sprintf(s, "sample-pvs%04d.x3d", k);
333                        Exporter *exporter = Exporter::GetExporter(s);
334                        exporter->SetWireframe();
335                       
336                       
337                        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
338                        Intersectable::NewMail();
339                       
340                        // avoid adding the object to the list
341                        object->Mail();
342                        ObjectContainer visibleObjects;
343                       
344                        for (; i != object->mKdPvs.mEntries.end(); i++)
345                                {
346                                        KdNode *node = (*i).first;
347                                        exporter->ExportBox(mKdTree->GetBox(node));
348                                        mKdTree->CollectObjects(node, visibleObjects);
349                                }
350                       
351                        exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
352                        exporter->SetFilled();
353                       
354                        for (int j = 0; j < visibleObjects.size(); j++)
355                                exporter->ExportIntersectable(visibleObjects[j]);
356                       
357                       
358                        Material m;
359                        m.mDiffuseColor = RgbColor(1, 0, 0);
360                        exporter->SetForcedMaterial(m);
361                        exporter->ExportIntersectable(object);
362                       
363                        delete exporter;
364                }
365  }
366 
367  return true;
368}
369
Note: See TracBrowser for help on using the repository browser.