source: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp @ 315

Revision 315, 13.7 KB checked in by mattausch, 19 years ago (diff)

deleted debug messages

Line 
1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "SamplingPreprocessor.h"
4#include "X3dExporter.h"
5#include "Environment.h"
6#include "MutualVisibility.h"
7#include "Polygon3.h"
8#include "ViewCell.h"
9
10SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
11{
12  // this should increase coherence of the samples
13  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
14  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
15 
16  mKdPvsDepth = 100;
17  mStats.open("stats.log");
18
19}
20
21void
22SamplingPreprocessor::SetupRay(Ray &ray, const Vector3 &point, const Vector3 &direction)
23{
24  ray.intersections.clear();
25  ray.leaves.clear();
26  ray.meshes.clear();
27  ray.viewCells.clear();
28
29  //  cout<<point<<" "<<direction<<endl;
30  ray.Init(point, direction, Ray::LOCAL_RAY);
31}
32
33KdNode *
34SamplingPreprocessor::GetNodeForPvs(KdLeaf *leaf)
35{
36  KdNode *node = leaf;
37  while (node->mParent && node->mDepth > mKdPvsDepth)
38    node = node->mParent;
39  return node;
40}
41
42int
43SamplingPreprocessor::AddNodeSamples(Intersectable *object,
44                                                                                                                                                 const Ray &ray
45                                                                                                                                                 )
46{
47  int contributingSamples = 0;
48  int j;
49  for (j=0; j < ray.leaves.size(); j++) {
50    KdNode *node = GetNodeForPvs( ray.leaves[j] );
51    contributingSamples += object->mKdPvs.AddSample(node);
52  }
53   
54  if (mPass > 10)
55    for (j=1; j < ((int)ray.leaves.size() - 1); j++) {
56      ray.leaves[j]->AddPassingRay(ray, contributingSamples ? 1 : 0);
57  }
58 
59  return contributingSamples;
60}
61
62
63int SamplingPreprocessor::AddObjectSamples(Intersectable *obj, const Ray &ray)
64{
65        int contributingSamples = 0;
66        int j;
67 
68        // add object to view cell
69        for (j=0; j < ray.viewCells.size(); ++ j)
70        {
71                ViewCell *vc = ray.viewCells[j];
72
73                contributingSamples += vc->GetPvs().AddSample(obj);
74        }
75 
76        if (mPass > 1)
77                for (j=1; j < ((int)ray.viewCells.size() - 1); ++ j)
78                {
79            ray.viewCells[j]->AddPassingRay(ray, contributingSamples ? 1 : 0);
80                }
81 
82        return contributingSamples;
83}
84
85
86void
87SamplingPreprocessor::HoleSamplingPass()
88{
89  vector<KdLeaf *> leaves;
90  mKdTree->CollectLeaves(leaves);
91 
92  // go through all the leaves and evaluate their passing contribution
93  for (int i=0 ; i < leaves.size(); i++) {
94    KdLeaf *leaf = leaves[i];
95    cout<<leaf->mPassingRays<<endl;
96  }
97}
98
99
100int
101SamplingPreprocessor::CastRay(Intersectable *object, Ray &ray)
102{
103        int sampleContributions = 0;
104
105        if (mViewCellsType == BSP_VIEW_CELLS)
106        {
107                // cast ray to KD tree to find intersection with other objects
108                mKdTree->CastRay(ray);
109               
110                // cast ray to BSP tree to get intersection with view cells
111                mBspTree->CastRay(ray);
112               
113                sampleContributions += AddObjectSamples(object, ray);
114                               
115                if (ray.intersections.size() > 0) // second intersection found
116                {
117                        sampleContributions +=
118                                AddObjectSamples(ray.intersections[0].mObject, ray);
119                }
120        }
121        else
122        {
123                mKdTree->CastRay(ray);
124       
125                if (ray.leaves.size()) {
126                        sampleContributions += AddNodeSamples(object, ray);
127               
128                        if (ray.intersections.size()) {
129                                sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray);
130                        }
131                }
132        }       
133       
134        return sampleContributions;
135}
136
137//  void
138//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
139//  {
140//    int objId = RandomValue(0, mObjects.size());
141//    Intersectable *object = objects[objId];
142//    object->GetRandomSurfacePoint(point, normal);
143//    direction = UniformRandomVector(normal);
144//    SetupRay(ray, point, direction);
145//  }
146
147//  void
148//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
149//  {
150//    int sampleContributions = 0;
151
152//    mKdTree->CastRay(ray);
153 
154//    if (ray.leaves.size()) {
155//      sampleContributions += AddNodeSamples(object, ray, pass);
156   
157//      if (ray.intersections.size()) {
158//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
159//      }
160//    }
161//  }
162
163//  void
164//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
165//  {
166 
167
168//  }
169
170//  void
171//  SamplingPreprocessor::AvsPass()
172//  {
173//    Ray ray;
174//    while (1) {
175//      AvsGenerateRay(ray);
176//      HandleRay(ray);
177//      while ( !mRayQueue.empty() ) {
178//        Ray ray = mRayQueue.pop();
179//        mRayQueue.pop();
180//        AdaptiveBorderSampling(ray);
181//      }
182//    }
183 
184 
185
186//  }
187
188
189void
190SamplingPreprocessor::CastEdgeSamples(
191                                                                                                                                                        Intersectable *object,
192                                                                                                                                                        const Vector3 &point,
193                                                                                                                                                        Mesh &mesh,
194                                                                                                                                                        const int samples
195                                                                                                                                                        )
196{
197        Ray ray;
198        int i;
199        for (i=0; i < samples; i++) {
200                // pickup a random face of each mesh
201                int face = RandomValue(0, mesh.mFaces.size()-1);
202               
203                Polygon3 poly(mesh.mFaces[face], &mesh);
204                poly.Scale(1.001);
205                // now extend a random edge of the face
206                int edge = RandomValue(0, poly.mVertices.size()-1);
207                float t = RandomValue(0.0f,1.0f);
208                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
209                                                                                                                                                                                                                                                                                 poly.mVertices.size()];
210                SetupRay(ray, point, target - point);
211          CastRay(object, ray);
212        }
213}
214
215bool
216SamplingPreprocessor::ComputeVisibility()
217{
218 
219  // pickup an object
220  ObjectContainer objects;
221 
222  mSceneGraph->CollectObjects(&objects);
223
224  Vector3 point, normal, direction;
225  Ray ray;
226
227  long startTime = GetTime();
228 
229  int i;
230  int totalSamples = 0;
231
232  int pvsOut = Min((int)objects.size(), 10);
233  int vcPvsOut = Min((int)mViewCells.size(), 5);
234
235  vector<Ray> rays[10];
236  vector<Ray> vcRays[5];
237
238  while (totalSamples < mTotalSamples) {
239                int passContributingSamples = 0;
240                int passSampleContributions = 0;
241                int passSamples = 0;
242                int index = 0;
243                               
244                for (i = 0; i < objects.size(); i++) {
245                        KdNode *nodeToSample = NULL;
246                        Intersectable *object = objects[i];
247               
248                        int pvsSize = 0;
249                        if (mViewCellsType == KD_VIEW_CELLS)
250                                pvsSize = object->mKdPvs.GetSize();
251                                               
252                        if (0 && pvsSize) {
253                                // mail all nodes from the pvs
254                                Intersectable::NewMail();
255                                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
256                         
257                                for (; i != object->mKdPvs.mEntries.end(); i++) {
258                                        KdNode *node = (*i).first;
259                                        node->Mail();
260                                }
261                               
262                                int maxTries = 2*pvsSize;
263                                Debug << "Finding random neighbour" << endl;   
264                                for (int tries = 0; tries < 10; tries++) {
265                                        index = RandomValue(0, pvsSize - 1);
266                                        KdPvsData data;
267                                        KdNode *node;
268                                        object->mKdPvs.GetData(index, node, data);
269                                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
270                                        if (nodeToSample)
271                                                break;
272                                }
273                        }
274                       
275                        if (0 && pvsSize && mPass == 1000 ) {
276                                // mail all nodes from the pvs
277                                Intersectable::NewMail();
278                                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
279                                for (; i != object->mKdPvs.mEntries.end(); i++) {
280                                        KdNode *node = (*i).first;
281                                        node->Mail();
282                                }
283                                Debug << "Get all neighbours from PVS" << endl;
284                                vector<KdNode *> invisibleNeighbors;
285                                // get all neighbors of all PVS nodes
286                                i = object->mKdPvs.mEntries.begin();
287                                for (; i != object->mKdPvs.mEntries.end(); i++) {
288                                        KdNode *node = (*i).first;
289                                        mKdTree->FindNeighbors(node, invisibleNeighbors, true);
290                                        AxisAlignedBox3 box = object->GetBox();
291                                        for (int j=0; j < invisibleNeighbors.size(); j++) {
292                                                int visibility = ComputeBoxVisibility(mSceneGraph,
293                                                                                                                                                                                                        mKdTree,
294                                                                                                                                                                                                        box,
295                                                                                                                                                                                                        mKdTree->GetBox(invisibleNeighbors[j]),
296                                                                                                                                                                                                        1e-6f);
297                                                //            exit(0);
298                                        }
299                                        // now rank all the neighbors according to probability that a new
300                                        // sample creates some contribution
301                                }
302                        }
303                       
304                        object->GetRandomSurfacePoint(point, normal);
305                        bool viewcellSample = true;
306                        int sampleContributions;
307                        if (viewcellSample) {
308                                nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
309                               
310                                for (int k=0; k < mSamplesPerPass; k++) {
311                                       
312                                        if (nodeToSample) {
313                                                int maxTries = 5;
314                                               
315                                                for (int tries = 0; tries < maxTries; tries++) {
316                                                        direction = mKdTree->GetBox(nodeToSample).GetRandomPoint() - point;
317                                                       
318                                                        if (DotProd(direction, normal) > Limits::Small)
319                                                                break;
320                                                }
321                                               
322                                                if (tries == maxTries)
323                                                        direction = UniformRandomVector(normal);
324                                        }
325                                        else {
326                                                direction = UniformRandomVector(normal);
327                                        }
328                                       
329                                        // construct a ray
330
331                                        SetupRay(ray, point, direction);
332                                       
333                                        sampleContributions = CastRay(object, ray);
334                                       
335                                        if (mViewCellsType == BSP_VIEW_CELLS)
336                                        {
337                                                // check whether we can add this to the rays
338                                                for (int k = 0; k < ray.viewCells.size(); ++ k)
339                                                        for (int j = 0; j < vcPvsOut; ++ j)
340                                                                if (mViewCells[j] == ray.viewCells[k])
341                                                                {
342                                                                        vcRays[j].push_back(ray);
343                                                                }
344                                        }
345                                }
346                        } else {
347                                // edge samples
348                                // get random visible mesh
349                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
350                               
351                               
352                        }
353                               
354                        // NOTE: should be inside loop
355                        if ( i < pvsOut )
356                                rays[i].push_back(ray);
357                       
358                        if (ray.intersections.size()) {
359                                        // check whether we can add this to the rays
360                                for (int j = 0; j < pvsOut; j++) {
361                                        if (objects[j] == ray.intersections[0].mObject) {
362                                                rays[j].push_back(ray);
363                                        }
364                                }
365                        }
366                       
367                        passSamples++;
368                       
369                        if (sampleContributions) {
370                                passContributingSamples++;
371                                passSampleContributions += sampleContributions;
372                        }
373                }
374               
375                totalSamples += passSamples;
376               
377                //    if (pass>10)
378                //      HoleSamplingPass();
379   
380               
381                mPass++;
382
383                int pvsSize = 0;
384       
385                if (mViewCellsType == BSP_VIEW_CELLS) {
386                        for (i=0; i < mViewCells.size(); i++) {
387                                ViewCell *vc = mViewCells[i];
388                                pvsSize += vc->GetPvs().GetSize();
389                        }
390                } else  {
391                        for (i=0; i < objects.size(); i++) {
392                                Intersectable *object = objects[i];
393                                pvsSize += object->mKdPvs.GetSize();
394                        }
395                }
396
397                cout << "#Pass " << mPass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
398                cout << "#TotalSamples=" << totalSamples/1000
399                                 << "k   #SampleContributions=" << passSampleContributions << " ("
400                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
401                                 << pvsSize/(float)objects.size() << endl
402                                 << "avg ray contrib=" << passSampleContributions/(float)passContributingSamples << endl;
403               
404               
405                mStats <<
406                        "#Pass\n" <<mPass<<endl<<
407                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
408                        "#TotalSamples\n" << totalSamples<< endl<<
409                        "#SampleContributions\n" << passSampleContributions << endl <<
410                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
411                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
412                        "#AvgRayContrib\n" << passSampleContributions/(float)passContributingSamples << endl;
413        }
414 
415        if (mViewCellsType == KD_VIEW_CELLS)   
416                cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
417 
418  //  HoleSamplingPass();
419  if (1) {
420    Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
421    exporter->SetExportRayDensity(true);
422    exporter->ExportKdTree(*mKdTree);
423
424        if (mViewCellsType == BSP_VIEW_CELLS)   
425                exporter->ExportBspTree(*mBspTree);
426
427    delete exporter;
428  }
429 
430  bool exportRays = false;
431  if (exportRays) {
432    Exporter *exporter = NULL;
433    exporter = Exporter::GetExporter("sample-rays.x3d");
434    exporter->SetWireframe();
435    exporter->ExportKdTree(*mKdTree);
436        exporter->ExportBspTree(*mBspTree);
437
438    for (i=0; i < pvsOut; i++)
439      exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
440    exporter->SetFilled();
441         
442    delete exporter;
443  }
444
445  if (1) {
446       
447      if (mViewCellsType == BSP_VIEW_CELLS)
448          {
449                   for (int j = 0; j < vcPvsOut; ++ j)
450                   {
451                           ViewCell *vc = mViewCells[j];
452
453                           Intersectable::NewMail();
454   
455                           char s[64]; sprintf(s, "bsp-pvs%04d.x3d", j);
456                           Exporter *exporter = Exporter::GetExporter(s);
457                           exporter->SetFilled();
458
459                           ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
460
461                           Material m;//= RandomMaterial();
462                           m.mDiffuseColor = RgbColor(0, 1, 0);
463                           exporter->SetForcedMaterial(m);
464
465                           exporter->ExportViewCell(vc);
466
467                           Debug << "pvs size: " << (int)vc->GetPvs().GetSize() << " of " << objects.size();
468                           Debug << " exporting rays: " << (int)vcRays[j].size() << endl;
469
470                           exporter->SetWireframe();
471                           
472                           m.mDiffuseColor = RgbColor(1, 0, 1);
473                           exporter->SetForcedMaterial(m);
474
475                           exporter->ExportBspTree(*mBspTree);
476                           exporter->ExportRays(vcRays[j], 1000, RgbColor(0, 1, 0));
477
478                           m.mDiffuseColor = RgbColor(1, 0, 0);
479                           exporter->SetForcedMaterial(m);
480
481                           // output pvs of view cell
482                           for (; it != vc->GetPvs().mEntries.end(); ++ it)
483                           {
484                                   Intersectable *intersect = (*it).first;
485                                   if (!intersect->Mailed())
486                                   {
487                                           exporter->ExportIntersectable(intersect);
488                                           intersect->Mail();
489                                   }                   
490                           }
491
492                           // output rest of the objects
493                           if (1)
494                           {
495                                   Material m;//= RandomMaterial();
496                                   m.mDiffuseColor = RgbColor(0, 0, 1);
497                                   exporter->SetForcedMaterial(m);
498                 
499                                   for (int j = 0; j < objects.size(); ++ j)
500                                           if (!objects[j]->Mailed())
501                                           {
502                                                   exporter->ExportIntersectable(objects[j]);
503                                                   objects[j]->Mail();
504                                           }
505                           }
506                           DEL_PTR(exporter);
507                   }
508          }       
509
510    for (int k=0; k < pvsOut; k++) {
511      Intersectable *object = objects[k];
512      char s[64];
513      sprintf(s, "sample-pvs%04d.x3d", k);
514      Exporter *exporter = Exporter::GetExporter(s);
515      exporter->SetWireframe();
516
517       
518          KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
519          Intersectable::NewMail();
520                 
521          // avoid adding the object to the list
522          object->Mail();
523          ObjectContainer visibleObjects;
524
525          for (; i != object->mKdPvs.mEntries.end(); i++)
526          {
527                  KdNode *node = (*i).first;
528                  exporter->ExportBox(mKdTree->GetBox(node));
529                  mKdTree->CollectObjects(node, visibleObjects);
530          }
531
532          exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
533          exporter->SetFilled();
534
535          for (int j = 0; j < visibleObjects.size(); j++)
536                  exporter->ExportIntersectable(visibleObjects[j]);
537       
538
539          Material m;
540          m.mDiffuseColor = RgbColor(1, 0, 0);
541          exporter->SetForcedMaterial(m);
542          exporter->ExportIntersectable(object);
543
544          delete exporter;
545    }
546  }
547 
548  return true;
549}
Note: See TracBrowser for help on using the repository browser.