source: obsolete/tags/VUT/0.4/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp @ 367

Revision 367, 21.6 KB checked in by mattausch, 19 years ago (diff)

started pvs surface area heuristics

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), mSampleRays(NULL)
11{
12  // this should increase coherence of the samples
13  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
14  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
15  environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
16  environment->GetIntValue("BspTree.PostProcessing.samples", mPostProcessSamples);
17  mKdPvsDepth = 100;
18  mStats.open("stats.log");
19
20}
21
22SamplingPreprocessor::~SamplingPreprocessor()
23{
24        CLEAR_CONTAINER(mSampleRays);
25}
26
27void
28SamplingPreprocessor::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  ray.bspLeaves.clear();
37
38  //  cout<<point<<" "<<direction<<endl;
39  ray.Init(point, direction, type);
40}
41
42KdNode *
43SamplingPreprocessor::GetNodeForPvs(KdLeaf *leaf)
44{
45  KdNode *node = leaf;
46  while (node->mParent && node->mDepth > mKdPvsDepth)
47    node = node->mParent;
48  return node;
49}
50
51bool
52SamplingPreprocessor::BuildBspTree()
53{
54        // delete old tree
55        DEL_PTR(mBspTree);
56        mBspTree = new BspTree(&mUnbounded);
57        ObjectContainer objects;
58       
59        switch (BspTree::sConstructionMethod)
60        {
61        case BspTree::FROM_INPUT_VIEW_CELLS:
62                mBspTree->SetGenerateViewCells(false);
63                mBspTree->Construct(mViewCells);
64                break;
65        case BspTree::FROM_SCENE_GEOMETRY:
66                DeleteViewCells(); // we generate new view cells
67                mBspTree->SetGenerateViewCells(true);
68                mSceneGraph->CollectObjects(&objects);
69                mBspTree->Construct(objects);
70                break;
71        case BspTree::FROM_RAYS:
72                DeleteViewCells(); // we generate new view cells
73                mBspTree->SetGenerateViewCells(true);
74                mBspTree->Construct(mSampleRays);
75                break;
76        default:
77                Debug << "Error: Method not available\n";
78                break;
79        }
80       
81       
82        return true;
83}
84
85int
86SamplingPreprocessor::AddNodeSamples(Intersectable *object,
87                                                                                                                                                 const Ray &ray
88                                                                                                                                                 )
89{
90  int contributingSamples = 0;
91  int j;
92  for (j=0; j < ray.kdLeaves.size(); j++) {
93    KdNode *node = GetNodeForPvs( ray.kdLeaves[j] );
94    contributingSamples += object->mKdPvs.AddSample(node);
95  }
96   
97  if (mPass > 10)
98    for (j=1; j < ((int)ray.kdLeaves.size() - 1); j++) {
99      ray.kdLeaves[j]->AddPassingRay(ray, contributingSamples ? 1 : 0);
100  }
101 
102  return contributingSamples;
103}
104
105
106int SamplingPreprocessor::AddObjectSamples(Intersectable *obj, const Ray &ray)
107{
108        int contributingSamples = 0;
109        int j;
110 
111        // object can be seen from the view cell => add to view cell pvs
112        for (j=0; j < ray.bspLeaves.size(); ++ j)
113        {       // if ray not in unbounded space
114                if (ray.bspLeaves[j]->GetViewCell() != &mUnbounded)
115                        contributingSamples +=
116                                ray.bspLeaves[j]->GetViewCell()->GetPvs().AddSample(obj);
117        }
118 
119        // rays passing through this viewcell
120        if (mPass > 1)
121                for (j=1; j < ((int)ray.bspLeaves.size() - 1); ++ j)
122                {
123                        BspLeaf *leaf = ray.bspLeaves[j];
124
125                        if (leaf->GetViewCell() != &mUnbounded)
126                                leaf->GetViewCell()->
127                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
128                }
129 
130        return contributingSamples;
131}
132
133
134void
135SamplingPreprocessor::HoleSamplingPass()
136{
137  vector<KdLeaf *> leaves;
138  mKdTree->CollectLeaves(leaves);
139 
140  // go through all the leaves and evaluate their passing contribution
141  for (int i=0 ; i < leaves.size(); i++) {
142    KdLeaf *leaf = leaves[i];
143    cout<<leaf->mPassingRays<<endl;
144  }
145}
146
147
148int
149SamplingPreprocessor::CastRay(Intersectable *object,
150                                                                                                                        Ray &ray,
151                                                                                                                        const bool reverseRay
152                                                                                                                        )
153{
154        int sampleContributions = 0;
155
156        long t1 = GetRealTime();
157        // cast ray to KD tree to find intersection with other objects
158        mKdTree->CastRay(ray);
159        long t2 = GetRealTime();
160
161        if (0 && object->GetId() > 2197) {
162                object->Describe(cout)<<endl;
163                cout<<ray<<endl;
164        }
165
166        if (ViewCell::sHierarchy == ViewCell::BSP)
167        {
168                // cast ray to BSP tree to get intersection with view cells
169                if (mBspTree)
170                {
171                        mBspTree->CastRay(ray);
172                       
173                        if (!reverseRay)
174                                sampleContributions += AddObjectSamples(object, ray);
175                       
176                        if (!ray.intersections.empty()) // second intersection found
177                                {
178                                        sampleContributions +=
179                                                AddObjectSamples(ray.intersections[0].mObject, ray);
180                                }
181                }
182        }
183        else
184                {
185                        if (ray.kdLeaves.size()) {
186                                if (!reverseRay)
187                                        sampleContributions += AddNodeSamples(object, ray);
188                               
189                                if (ray.intersections.size()) {
190                                        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray);
191                                }
192                        }
193                }       
194       
195        return sampleContributions;
196}
197
198//  void
199//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
200//  {
201//    int objId = RandomValue(0, mObjects.size());
202//    Intersectable *object = objects[objId];
203//    object->GetRandomSurfacePoint(point, normal);
204//    direction = UniformRandomVector(normal);
205//    SetupRay(ray, point, direction);
206//  }
207
208//  void
209//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
210//  {
211//    int sampleContributions = 0;
212
213//    mKdTree->CastRay(ray);
214 
215//    if (ray.leaves.size()) {
216//      sampleContributions += AddNodeSamples(object, ray, pass);
217   
218//      if (ray.intersections.size()) {
219//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
220//      }
221//    }
222//  }
223
224//  void
225//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
226//  {
227 
228
229//  }
230
231//  void
232//  SamplingPreprocessor::AvsPass()
233//  {
234//    Ray ray;
235//    while (1) {
236//      AvsGenerateRay(ray);
237//      HandleRay(ray);
238//      while ( !mRayQueue.empty() ) {
239//        Ray ray = mRayQueue.pop();
240//        mRayQueue.pop();
241//        AdaptiveBorderSampling(ray);
242//      }
243//    }
244 
245 
246
247//  }
248
249
250int
251SamplingPreprocessor::CastEdgeSamples(
252                                                                                                                                                        Intersectable *object,
253                                                                                                                                                        const Vector3 &point,
254                                                                                                                                                        MeshInstance *mi,
255                                                                                                                                                        const int samples
256                                                                                                                                                        )
257{
258        Ray ray;
259        int maxTries = samples*10;
260        int i;
261        int rays = 0;
262        int edgeSamplesContributions = 0;
263        for (i=0; i < maxTries && rays < samples; i++) {
264                // pickup a random face of each mesh
265                Mesh *mesh = mi->GetMesh();
266                int face = RandomValue(0, mesh->mFaces.size()-1);
267               
268                Polygon3 poly(mesh->mFaces[face], mesh);
269                poly.Scale(1.001);
270                // now extend a random edge of the face
271                int edge = RandomValue(0, poly.mVertices.size()-1);
272                float t = RandomValue(0.0f,1.0f);
273                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
274                                                                                                                                                                                                                                                                                 poly.mVertices.size()];
275                SetupRay(ray, point, target - point, Ray::LOCAL_RAY);
276                if (!mesh->CastRay(ray, mi)) {
277                        // the rays which intersect the mesh have been discarded since they are not tangent
278                        // to the mesh
279                        rays++;
280                        edgeSamplesContributions += CastRay(object, ray, false);
281                }
282        }
283        return edgeSamplesContributions;
284}
285
286KdNode *
287SamplingPreprocessor::GetNodeToSample(Intersectable *object)
288{
289        int pvsSize = object->mKdPvs.GetSize();
290        KdNode *nodeToSample = NULL;
291       
292        bool samplePvsBoundary = false;
293        if (pvsSize && samplePvsBoundary) {
294                // this samples the nodes from the boundary of the current PVS
295                // mail all nodes from the pvs
296                Intersectable::NewMail();
297                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
298               
299                for (; i != object->mKdPvs.mEntries.end(); i++) {
300                        KdNode *node = (*i).first;
301                        node->Mail();
302                }
303               
304                int maxTries = 2*pvsSize;
305                Debug << "Finding random neighbour" << endl;   
306                for (int tries = 0; tries < 10; tries++) {
307                        int index = RandomValue(0, pvsSize - 1);
308                        KdPvsData data;
309                        KdNode *node;
310                        object->mKdPvs.GetData(index, node, data);
311                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
312                        if (nodeToSample)
313                                break;
314                }
315        } else {
316                // just pickup a random node
317                //              nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
318                nodeToSample = mKdTree->GetRandomLeaf();
319        }
320        return nodeToSample;
321}
322
323void
324SamplingPreprocessor::VerifyVisibility(Intersectable *object)
325{
326        // mail all nodes from the pvs
327        Intersectable::NewMail();
328        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
329        for (; i != object->mKdPvs.mEntries.end(); i++) {
330                KdNode *node = (*i).first;
331                node->Mail();
332        }
333        Debug << "Get all neighbours from PVS" << endl;
334        vector<KdNode *> invisibleNeighbors;
335        // get all neighbors of all PVS nodes
336        i = object->mKdPvs.mEntries.begin();
337        for (; i != object->mKdPvs.mEntries.end(); i++) {
338                KdNode *node = (*i).first;
339                mKdTree->FindNeighbors(node, invisibleNeighbors, true);
340                AxisAlignedBox3 box = object->GetBox();
341                for (int j=0; j < invisibleNeighbors.size(); j++) {
342                        int visibility = ComputeBoxVisibility(mSceneGraph,
343                                                              mKdTree,
344                                                              box,
345                                                              mKdTree->GetBox(invisibleNeighbors[j]),
346                                                              1e-6f);
347                        //            exit(0);
348                }
349                // now rank all the neighbors according to probability that a new
350                // sample creates some contribution
351        }
352}
353
354bool
355SamplingPreprocessor::ComputeVisibility()
356{
357 
358  // pickup an object
359  ObjectContainer objects;
360 
361  mSceneGraph->CollectObjects(&objects);
362
363  Vector3 point, normal, direction;
364  Ray ray;
365
366  long startTime = GetTime();
367 
368  int i;
369  int totalSamples = 0;
370
371  int pvsOut = Min((int)objects.size(), 10);
372
373  vector<Ray> rays[10];
374
375  while (totalSamples < mTotalSamples) {
376                int passContributingSamples = 0;
377                int passSampleContributions = 0;
378                int passSamples = 0;
379                int index = 0;
380               
381                int reverseSamples = 0;
382               
383                       
384                //cout << "totalSamples: "  << totalSamples << endl;
385
386                for (i = 0; i < objects.size(); i++) {
387                                               
388                        KdNode *nodeToSample = NULL;
389                        Intersectable *object = objects[i];
390               
391                        int pvsSize = 0;
392                        if (ViewCell::sHierarchy == ViewCell::KD)
393                                pvsSize = object->mKdPvs.GetSize();
394                                               
395                       
396                        if (0 && pvsSize && mPass == 1000 ) {
397                                VerifyVisibility(object);
398                        }
399                       
400                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
401                       
402                        bool viewcellSample = true;
403                        int sampleContributions;
404                        bool debug = false; //(object->GetId() >= 2199);
405                        if (viewcellSample) {
406                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
407
408                                nodeToSample = GetNodeToSample(object);
409
410                                for (int k=0; k < mSamplesPerPass; k++) {
411                                        bool reverseSample = false;
412
413
414                                        if (nodeToSample) {
415                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
416                                                Vector3 pointToSample = box.GetRandomPoint();
417                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
418                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
419                                                        direction = pointToSample - point;
420                                                } else {
421                                                        reverseSamples++;
422                                                        reverseSample = true;
423                                                        direction = point - pointToSample;
424                                                        point = pointToSample;
425                                                }
426                                        }
427                                        else {
428                                                direction = UniformRandomVector(normal);
429                                        }
430                                       
431                                        // construct a ray
432                                        SetupRay(ray, point, direction, Ray::LOCAL_RAY);
433                                       
434                                        sampleContributions = CastRay(object, ray, reverseSample);
435                                       
436                                        //-- CORR matt: put block inside loop
437                                        if (sampleContributions) {
438                                                passContributingSamples ++;
439                                                passSampleContributions += sampleContributions;
440                                        }
441
442                                        if ( i < pvsOut )
443                                                rays[i].push_back(ray);
444               
445                                        if (!ray.intersections.empty()) {
446                                                // check whether we can add this to the rays
447                                                for (int j = 0; j < pvsOut; j++) {
448                                                        if (objects[j] == ray.intersections[0].mObject) {
449                                                                rays[j].push_back(ray);
450                                                        }
451                                                }
452                                        }
453                                        //-------------------
454                                        if (ViewCell::sHierarchy == ViewCell::BSP)
455                                        {
456                                                ProcessBspViewCells(ray,
457                                                                                        object,
458                                                                                        faceIndex,
459                                                                                        passContributingSamples,
460                                                                                        passSampleContributions);
461                                        }
462                                }
463                        } else {
464                                // edge samples
465                                // get random visible mesh
466                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
467                        }
468       
469                        // CORR matt: must add all samples
470                        passSamples += mSamplesPerPass;
471                }
472       
473                totalSamples += passSamples;
474               
475                //    if (pass>10)
476                //      HoleSamplingPass();
477   
478                mPass++;
479
480                int pvsSize = 0;
481       
482                if (ViewCell::sHierarchy == ViewCell::BSP) {
483                        for (i=0; i < mViewCells.size(); i++) {
484                                ViewCell *vc = mViewCells[i];
485                                pvsSize += vc->GetPvs().GetSize();
486                        }
487                } else  {
488                        for (i=0; i < objects.size(); i++) {
489                                Intersectable *object = objects[i];
490                                pvsSize += object->mKdPvs.GetSize();
491                        }
492                }
493
494                float avgRayContrib = (passContributingSamples > 0) ?
495                        passSampleContributions/(float)passContributingSamples : 0;
496
497                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
498                cout << "#TotalSamples=" << totalSamples/1000
499                                 << "k   #SampleContributions=" << passSampleContributions << " ("
500                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
501                                 << pvsSize/(float)objects.size() << endl
502                                 << "avg ray contrib=" << avgRayContrib << endl
503                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
504
505                mStats <<
506                        "#Pass\n" <<mPass<<endl<<
507                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
508                        "#TotalSamples\n" << totalSamples<< endl<<
509                        "#SampleContributions\n" << passSampleContributions << endl <<
510                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
511                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
512                        "#AvgRayContrib\n" << avgRayContrib << endl;
513        }
514       
515        if (ViewCell::sHierarchy == ViewCell::KD)       
516                cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
517 
518        // merge or subdivide view cells
519        if (mBspTree)
520        {
521                cout << "starting post processing using " << mSampleRays.size() << " samples ... ";
522
523                Debug << "original pvs size: " << mBspTree->CountViewCellPvs() << endl;
524
525                long startTime = GetTime();
526                int merged = PostprocessViewCells(mSampleRays);
527               
528                cout << "finished" << endl;
529                cout << "merged " << merged << " view cells in "
530                         << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
531
532                //-- recount pvs
533                Debug << "merged pvs size: " << mBspTree->CountViewCellPvs() << endl;
534
535        }
536       
537  //  HoleSamplingPass();
538        if (0) {
539                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
540                exporter->SetExportRayDensity(true);
541                exporter->ExportKdTree(*mKdTree);
542
543                if (mBspTree && (ViewCell::sHierarchy == ViewCell::BSP))
544                        exporter->ExportBspTree(*mBspTree);
545
546                delete exporter;
547        }
548 
549        bool exportRays = false;
550        if (exportRays) {
551                Exporter *exporter = NULL;
552                exporter = Exporter::GetExporter("sample-rays.x3d");
553                exporter->SetWireframe();
554                exporter->ExportKdTree(*mKdTree);
555                exporter->ExportBspTree(*mBspTree);
556
557                for (i=0; i < pvsOut; i++)
558                exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
559                exporter->SetFilled();
560                 
561                delete exporter;
562        }
563
564        //-- several visualizations and statistics
565        if (1) {
566                if (mBspTree && (ViewCell::sHierarchy == ViewCell::BSP))
567        {
568                bool exportSplits = false;
569                environment->GetBoolValue("BspTree.exportSplits", exportSplits);
570
571                // export the bsp splits
572                if (exportSplits)
573                        ExportSplits(objects);
574               
575                ExportBspPvs(objects);
576        }
577   for (int k=0; k < pvsOut; k++) {
578      Intersectable *object = objects[k];
579      char s[64];
580      sprintf(s, "sample-pvs%04d.x3d", k);
581      Exporter *exporter = Exporter::GetExporter(s);
582      exporter->SetWireframe();
583
584       
585          KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
586          Intersectable::NewMail();
587                 
588          // avoid adding the object to the list
589          object->Mail();
590          ObjectContainer visibleObjects;
591
592          for (; i != object->mKdPvs.mEntries.end(); i++)
593          {
594                  KdNode *node = (*i).first;
595                  exporter->ExportBox(mKdTree->GetBox(node));
596                  mKdTree->CollectObjects(node, visibleObjects);
597          }
598
599          exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
600          exporter->SetFilled();
601
602          for (int j = 0; j < visibleObjects.size(); j++)
603                  exporter->ExportIntersectable(visibleObjects[j]);
604       
605
606          Material m;
607          m.mDiffuseColor = RgbColor(1, 0, 0);
608          exporter->SetForcedMaterial(m);
609          exporter->ExportIntersectable(object);
610
611          delete exporter;
612    }
613  }
614 
615  return true;
616}
617
618bool SamplingPreprocessor::ProcessBspViewCells(Ray &ray,
619                                                                                           Intersectable *object,
620                                                                                           int faceIndex,
621                                                                                           int &contributingSamples,
622                                                                                           int &sampleContributions)
623{
624        // save rays for bsp tree construction
625        if ((BspTree::sConstructionMethod == BspTree::FROM_RAYS) &&
626                (mSampleRays.size() < mBspConstructionSamples))
627        {
628                // also add origin to sample in order to extract it as input polygons
629                MeshInstance *mi = dynamic_cast<MeshInstance *>(object);
630                ray.sourceObject = Ray::Intersection(0.0, mi, faceIndex);
631                                                       
632        mSampleRays.push_back(new Ray(ray));
633               
634                return false;
635        }
636       
637        if (!mBspTree) // construct BSP tree using the samples
638        {
639        cout << "building bsp tree from " << mSampleRays.size() << " samples " << endl;
640                BuildBspTree();
641               
642                // add contributions of saved samples to PVS
643                contributingSamples += mBspTree->GetStat().contributingSamples;
644                sampleContributions += mBspTree->GetStat().sampleContributions;
645
646                BspTreeStatistics(Debug);       
647
648                if (0) Export("vc_bsptree.x3d", false, false, true);
649
650                // throw away samples because BSP leaves not stored in order
651                // Need ordered rays for post processing => collect new rays
652                CLEAR_CONTAINER(mSampleRays);
653        }
654       
655        if ((int)mSampleRays.size() < mPostProcessSamples)
656        {
657                mSampleRays.push_back(new Ray(ray));
658        }
659
660        return true;
661}
662
663// merge or subdivide view cells
664int SamplingPreprocessor::PostprocessViewCells(const RayContainer &rays)
665{
666        int merged = 0;
667        RayContainer::const_iterator rit, rit_end = rays.end();
668        vector<BspLeaf *>::const_iterator lit;
669
670        for (rit = rays.begin(); rit != rays.end(); ++ rit)
671        { 
672                // traverse leaves stored in the rays and compare and merge consecutive
673                // leaves (i.e., the neighbors in the tree)
674                if ((*rit)->bspLeaves.empty())
675                        continue;
676
677                lit = (*rit)->bspLeaves.begin();
678
679                BspLeaf *previousLeaf = *lit;
680                ++ lit;
681               
682                for (; lit != (*rit)->bspLeaves.end(); ++ lit)
683                {
684                        BspLeaf *leaf = *lit;
685
686                        if (mBspTree->ShouldMerge(leaf, previousLeaf))
687                        {                       
688                                mBspTree->MergeViewCells(leaf, previousLeaf);
689                                ++ merged;
690                        }
691                        previousLeaf = leaf;
692                }
693        }
694
695        return merged;
696}
697
698void SamplingPreprocessor::ExportSplits(const ObjectContainer &objects)
699{
700        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
701
702        if (exporter)
703        {       
704                cout << "exporting splits ... ";
705
706                Material m;
707                m.mDiffuseColor = RgbColor(1, 0, 0);
708                exporter->SetForcedMaterial(m);
709                exporter->SetWireframe();
710                exporter->ExportBspSplits(*mBspTree);
711
712                // take forced material, else big scenes cannot be viewed
713                m.mDiffuseColor = RgbColor(0, 1, 0);
714                exporter->SetForcedMaterial(m);
715                exporter->SetFilled();
716
717                exporter->ResetForcedMaterial();
718               
719                // export rays
720                if (0)
721                {
722                        RayContainer outRays;
723               
724                        for (int i = 0; i < mSampleRays.size(); ++ i)
725                        {
726                                // only rays piercing geometry
727                                if (!mSampleRays[i]->intersections.empty())
728                                        outRays.push_back(mSampleRays[i]);
729                        }
730                        if (BspTree::sConstructionMethod == BspTree::FROM_RAYS)
731                        {
732                                // export rays
733                                exporter->ExportRays(outRays, 1000, RgbColor(1, 1, 0));
734                        }
735                }
736
737                // export scene geometry
738                if (0)
739                {
740                        Material m;//= RandomMaterial();
741                        m.mDiffuseColor = RgbColor(0, 1, 0);
742                        exporter->SetForcedMaterial(m);
743            exporter->SetWireframe();
744
745                        for (int j = 0; j < objects.size(); ++ j)
746                                exporter->ExportIntersectable(objects[j]);
747                }
748
749                delete exporter;
750
751                cout << "finished" << endl;
752        }
753}
754
755void SamplingPreprocessor::ExportBspPvs(const ObjectContainer &objects)
756{
757        //-- some random view cells and rays for output
758        const int leafOut = 10;
759
760        vector<Ray> vcRays[leafOut];
761        vector<BspLeaf *> bspLeaves;
762                       
763        for (int i = 0; i < leafOut; ++ i)
764                bspLeaves.push_back(mBspTree->GetRandomLeaf());
765       
766        const int raysOut = min((int)mSampleRays.size(), 20000);
767
768        // check whether we can add the current ray to the output rays
769        for (int k = 0; k < raysOut; ++ k)
770        {
771                Ray *ray = mSampleRays[k];
772
773                for (int j = 0; j < (int)ray->bspLeaves.size(); ++ j)
774                {
775                        for (int i = 0; i < (int)bspLeaves.size(); ++ i)
776                        {
777                                if (bspLeaves[i]->GetViewCell() == ray->bspLeaves[j]->GetViewCell())
778                                {
779                                        vcRays[i].push_back(*ray);
780                                }
781                        }
782                }
783        }
784
785        ViewCell::NewMail();
786
787        for (int i = 0; i < bspLeaves.size(); ++ i)
788        {
789                Intersectable::NewMail();
790
791                ViewCell *vc = bspLeaves[i]->GetViewCell();
792
793                //bspLeaves[j]->Mail();
794                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
795
796                Exporter *exporter = Exporter::GetExporter(s);
797                exporter->SetFilled();
798
799                ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
800
801                exporter->SetWireframe();
802
803                Material m;//= RandomMaterial();
804                m.mDiffuseColor = RgbColor(0, 1, 0);
805                exporter->SetForcedMaterial(m);
806
807                if (vc->GetMesh())
808                        exporter->ExportViewCell(vc);
809                else
810                {
811            PolygonContainer cell;
812                        // export view cell
813                        mBspTree->ConstructGeometry(bspLeaves[i]->GetViewCell(), cell);
814                        exporter->ExportPolygons(cell);
815                        CLEAR_CONTAINER(cell);
816                }
817
818                Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
819                                << ", piercing rays=" << (int)vcRays[i].size() << endl;
820
821                // export view cells
822                if (0)
823                {
824                        m.mDiffuseColor = RgbColor(1, 0, 1);
825                        exporter->SetForcedMaterial(m);
826                        exporter->ExportViewCells(mViewCells);
827                }
828
829                // export rays piercing this view cell
830                exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
831
832                m.mDiffuseColor = RgbColor(1, 0, 0);
833                exporter->SetForcedMaterial(m);
834
835                // output PVS of view cell
836                for (; it != vc->GetPvs().mEntries.end(); ++ it)
837                {
838                        Intersectable *intersect = (*it).first;
839                        if (!intersect->Mailed())
840                        {
841                                exporter->ExportIntersectable(intersect);
842                                intersect->Mail();
843                        }                       
844                }
845                       
846                // output rest of the objects
847                if (0)
848                {
849                        Material m;//= RandomMaterial();
850                        m.mDiffuseColor = RgbColor(0, 0, 1);
851                        exporter->SetForcedMaterial(m);
852
853                        for (int j = 0; j < objects.size(); ++ j)
854                                if (!objects[j]->Mailed())
855                                {
856                                        //if (j == 2198)m.mDiffuseColor = RgbColor(1, 0, 1);
857                                        //else m.mDiffuseColor = RgbColor(1, 1, 0);
858                                        exporter->SetForcedMaterial(m);
859                                        exporter->ExportIntersectable(objects[j]);
860                                        objects[j]->Mail();
861                                }
862                }
863                DEL_PTR(exporter);
864        }
865}
Note: See TracBrowser for help on using the repository browser.