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

Revision 327, 14.6 KB checked in by mattausch, 19 years ago (diff)

worked on the ray based subdivision. finished extracting polygons from rays

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