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

Revision 363, 21.6 KB checked in by bittner, 19 years ago (diff)

default.env updated

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
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                        if (ray.bspLeaves[j]->GetViewCell() != &mUnbounded)
124                                ray.bspLeaves[j]->GetViewCell()->
125                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
126                }
127 
128        return contributingSamples;
129}
130
131
132void
133SamplingPreprocessor::HoleSamplingPass()
134{
135  vector<KdLeaf *> leaves;
136  mKdTree->CollectLeaves(leaves);
137 
138  // go through all the leaves and evaluate their passing contribution
139  for (int i=0 ; i < leaves.size(); i++) {
140    KdLeaf *leaf = leaves[i];
141    cout<<leaf->mPassingRays<<endl;
142  }
143}
144
145
146int
147SamplingPreprocessor::CastRay(Intersectable *object,
148                                                                                                                        Ray &ray,
149                                                                                                                        const bool reverseRay
150                                                                                                                        )
151{
152        int sampleContributions = 0;
153
154        long t1 = GetRealTime();
155        // cast ray to KD tree to find intersection with other objects
156        mKdTree->CastRay(ray);
157        long t2 = GetRealTime();
158
159        if (0 && object->GetId() > 2197) {
160                object->Describe(cout)<<endl;
161                cout<<ray<<endl;
162        }
163
164        if (mViewCellsType == BSP_VIEW_CELLS)
165        {
166                // cast ray to BSP tree to get intersection with view cells
167                if (mBspTree)
168                {
169                        mBspTree->CastRay(ray);
170                       
171                        if (!reverseRay)
172                                sampleContributions += AddObjectSamples(object, ray);
173                       
174                        if (!ray.intersections.empty()) // second intersection found
175                                {
176                                        sampleContributions +=
177                                                AddObjectSamples(ray.intersections[0].mObject, ray);
178                                }
179                }
180        }
181        else
182                {
183                        if (ray.kdLeaves.size()) {
184                                if (!reverseRay)
185                                        sampleContributions += AddNodeSamples(object, ray);
186                               
187                                if (ray.intersections.size()) {
188                                        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray);
189                                }
190                        }
191                }       
192       
193        return sampleContributions;
194}
195
196//  void
197//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
198//  {
199//    int objId = RandomValue(0, mObjects.size());
200//    Intersectable *object = objects[objId];
201//    object->GetRandomSurfacePoint(point, normal);
202//    direction = UniformRandomVector(normal);
203//    SetupRay(ray, point, direction);
204//  }
205
206//  void
207//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
208//  {
209//    int sampleContributions = 0;
210
211//    mKdTree->CastRay(ray);
212 
213//    if (ray.leaves.size()) {
214//      sampleContributions += AddNodeSamples(object, ray, pass);
215   
216//      if (ray.intersections.size()) {
217//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
218//      }
219//    }
220//  }
221
222//  void
223//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
224//  {
225 
226
227//  }
228
229//  void
230//  SamplingPreprocessor::AvsPass()
231//  {
232//    Ray ray;
233//    while (1) {
234//      AvsGenerateRay(ray);
235//      HandleRay(ray);
236//      while ( !mRayQueue.empty() ) {
237//        Ray ray = mRayQueue.pop();
238//        mRayQueue.pop();
239//        AdaptiveBorderSampling(ray);
240//      }
241//    }
242 
243 
244
245//  }
246
247
248int
249SamplingPreprocessor::CastEdgeSamples(
250                                                                                                                                                        Intersectable *object,
251                                                                                                                                                        const Vector3 &point,
252                                                                                                                                                        MeshInstance *mi,
253                                                                                                                                                        const int samples
254                                                                                                                                                        )
255{
256        Ray ray;
257        int maxTries = samples*10;
258        int i;
259        int rays = 0;
260        int edgeSamplesContributions = 0;
261        for (i=0; i < maxTries && rays < samples; i++) {
262                // pickup a random face of each mesh
263                Mesh *mesh = mi->GetMesh();
264                int face = RandomValue(0, mesh->mFaces.size()-1);
265               
266                Polygon3 poly(mesh->mFaces[face], mesh);
267                poly.Scale(1.001);
268                // now extend a random edge of the face
269                int edge = RandomValue(0, poly.mVertices.size()-1);
270                float t = RandomValue(0.0f,1.0f);
271                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
272                                                                                                                                                                                                                                                                                 poly.mVertices.size()];
273                SetupRay(ray, point, target - point, Ray::LOCAL_RAY);
274                if (!mesh->CastRay(ray, mi)) {
275                        // the rays which intersect the mesh have been discarded since they are not tangent
276                        // to the mesh
277                        rays++;
278                        edgeSamplesContributions += CastRay(object, ray, false);
279                }
280        }
281        return edgeSamplesContributions;
282}
283
284KdNode *
285SamplingPreprocessor::GetNodeToSample(Intersectable *object)
286{
287        int pvsSize = object->mKdPvs.GetSize();
288        KdNode *nodeToSample = NULL;
289       
290        bool samplePvsBoundary = false;
291        if (pvsSize && samplePvsBoundary) {
292                // this samples the nodes from the boundary of the current PVS
293                // mail all nodes from the pvs
294                Intersectable::NewMail();
295                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
296               
297                for (; i != object->mKdPvs.mEntries.end(); i++) {
298                        KdNode *node = (*i).first;
299                        node->Mail();
300                }
301               
302                int maxTries = 2*pvsSize;
303                Debug << "Finding random neighbour" << endl;   
304                for (int tries = 0; tries < 10; tries++) {
305                        int index = RandomValue(0, pvsSize - 1);
306                        KdPvsData data;
307                        KdNode *node;
308                        object->mKdPvs.GetData(index, node, data);
309                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
310                        if (nodeToSample)
311                                break;
312                }
313        } else {
314                // just pickup a random node
315                //              nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
316                nodeToSample = mKdTree->GetRandomLeaf();
317        }
318        return nodeToSample;
319}
320
321void
322SamplingPreprocessor::VerifyVisibility(Intersectable *object)
323{
324        // mail all nodes from the pvs
325        Intersectable::NewMail();
326        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
327        for (; i != object->mKdPvs.mEntries.end(); i++) {
328                KdNode *node = (*i).first;
329                node->Mail();
330        }
331        Debug << "Get all neighbours from PVS" << endl;
332        vector<KdNode *> invisibleNeighbors;
333        // get all neighbors of all PVS nodes
334        i = object->mKdPvs.mEntries.begin();
335        for (; i != object->mKdPvs.mEntries.end(); i++) {
336                KdNode *node = (*i).first;
337                mKdTree->FindNeighbors(node, invisibleNeighbors, true);
338                AxisAlignedBox3 box = object->GetBox();
339                for (int j=0; j < invisibleNeighbors.size(); j++) {
340                        int visibility = ComputeBoxVisibility(mSceneGraph,
341                                                              mKdTree,
342                                                              box,
343                                                              mKdTree->GetBox(invisibleNeighbors[j]),
344                                                              1e-6f);
345                        //            exit(0);
346                }
347                // now rank all the neighbors according to probability that a new
348                // sample creates some contribution
349        }
350}
351
352bool
353SamplingPreprocessor::ComputeVisibility()
354{
355 
356  // pickup an object
357  ObjectContainer objects;
358 
359  mSceneGraph->CollectObjects(&objects);
360
361  Vector3 point, normal, direction;
362  Ray ray;
363
364  long startTime = GetTime();
365 
366  int i;
367  int totalSamples = 0;
368
369  int pvsOut = Min((int)objects.size(), 10);
370
371  vector<Ray> rays[10];
372
373  while (totalSamples < mTotalSamples) {
374                int passContributingSamples = 0;
375                int passSampleContributions = 0;
376                int passSamples = 0;
377                int index = 0;
378                Real maxTime = 0;
379                int maxTimeIdx = 0;
380                int reverseSamples = 0;
381                bool collectSamplesForBsp =
382                        (mViewCellsType == BSP_VIEW_CELLS) &&
383                        (BspTree::sConstructionMethod == BspTree::FROM_RAYS) &&
384                        (totalSamples < mBspConstructionSamples);
385                       
386                cout << "totalSamples: "  << totalSamples << endl;
387
388                for (i = 0; i < objects.size(); i++) {
389                                               
390                        KdNode *nodeToSample = NULL;
391                        Intersectable *object = objects[i];
392               
393                        int pvsSize = 0;
394                        if (mViewCellsType == KD_VIEW_CELLS)
395                                pvsSize = object->mKdPvs.GetSize();
396                                               
397                       
398                        if (0 && pvsSize && mPass == 1000 ) {
399                                VerifyVisibility(object);
400                        }
401                       
402                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
403                       
404                        long samplesPerObjStart = GetTime();
405
406                        bool viewcellSample = true;
407                        int sampleContributions;
408                        bool debug = false; //(object->GetId() >= 2199);
409                        if (viewcellSample) {
410                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
411
412                               
413                                for (int k=0; k < mSamplesPerPass; k++) {
414                                        bool reverseSample = false;
415
416                                        nodeToSample = GetNodeToSample(object);
417
418                                        if (nodeToSample) {
419                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
420                                                Vector3 pointToSample = box.GetRandomPoint();
421                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
422                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
423                                                        direction = pointToSample - point;
424                                                } else {
425                                                        reverseSamples++;
426                                                        reverseSample = true;
427                                                        direction = point - pointToSample;
428                                                        point = pointToSample;
429                                                }
430                                        }
431                                        else {
432                                                direction = UniformRandomVector(normal);
433                                        }
434                                       
435                                        // construct a ray
436                                        SetupRay(ray, point, direction, Ray::LOCAL_RAY);
437                                       
438                                        sampleContributions = CastRay(object, ray, reverseSample);
439                                       
440                                        //-- CORR matt: put block inside loop
441                                        if (sampleContributions) {
442                                                passContributingSamples ++;
443                                                passSampleContributions += sampleContributions;
444                                        }
445
446                                        if ( i < pvsOut )
447                                                rays[i].push_back(ray);
448               
449                                        if (!ray.intersections.empty()) {
450                                                // check whether we can add this to the rays
451                                                for (int j = 0; j < pvsOut; j++) {
452                                                        if (objects[j] == ray.intersections[0].mObject) {
453                                                                rays[j].push_back(ray);
454                                                        }
455                                                }
456                                        }
457                                        //-------------------
458                                        if (mViewCellsType == BSP_VIEW_CELLS)
459                                        {
460                                                ProcessBspViewCells(collectSamplesForBsp,
461                                                                                        ray,
462                                                                                        object,
463                                                                                        faceIndex,
464                                                                                        passContributingSamples,
465                                                                                        passSampleContributions);
466                                        }
467                                }
468                        } else {
469                                // edge samples
470                                // get random visible mesh
471                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
472                        }
473                               
474                        // measure maximal time for samples per object
475                        Real t = TimeDiff(samplesPerObjStart, GetTime());
476
477                        if (t > maxTime)
478                        {
479                                maxTime = t;
480                                maxTimeIdx = i;
481                        }
482       
483                        // CORR matt: must add all samples
484                        passSamples += mSamplesPerPass;
485                }
486       
487                totalSamples += passSamples;
488               
489                //    if (pass>10)
490                //      HoleSamplingPass();
491   
492                mPass++;
493
494                int pvsSize = 0;
495       
496                if (mViewCellsType == BSP_VIEW_CELLS) {
497                        for (i=0; i < mViewCells.size(); i++) {
498                                ViewCell *vc = mViewCells[i];
499                                pvsSize += vc->GetPvs().GetSize();
500                        }
501                } else  {
502                        for (i=0; i < objects.size(); i++) {
503                                Intersectable *object = objects[i];
504                                pvsSize += object->mKdPvs.GetSize();
505                        }
506                }
507
508                Debug << "maximal time needed for pass: " << maxTime << " (object " << maxTimeIdx << ")" << endl;
509
510                float avgRayContrib = (passContributingSamples > 0) ?
511                        passSampleContributions/(float)passContributingSamples : 0;
512
513                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
514                cout << "#TotalSamples=" << totalSamples/1000
515                                 << "k   #SampleContributions=" << passSampleContributions << " ("
516                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
517                                 << pvsSize/(float)objects.size() << endl
518                                 << "avg ray contrib=" << avgRayContrib << endl
519                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
520
521                mStats <<
522                        "#Pass\n" <<mPass<<endl<<
523                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
524                        "#TotalSamples\n" << totalSamples<< endl<<
525                        "#SampleContributions\n" << passSampleContributions << endl <<
526                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
527                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
528                        "#AvgRayContrib\n" << avgRayContrib << endl;
529        }
530       
531        if (mViewCellsType == KD_VIEW_CELLS)   
532                cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
533 
534        // merge or subdivide view cells
535        if (mBspTree)
536        {
537                int merged = PostprocessViewCells(mSampleRays);
538                Debug << "merged " << merged << " view cells" << endl;
539
540                ViewCellContainer vc;
541                mBspTree->CollectViewCells(vc);
542
543                ViewCellContainer::const_iterator it, it_end = vc.end();
544
545                int mergedPvs = 0;
546                for (it = vc.begin(); it != it_end; ++ it)
547                        mergedPvs += (*it)->GetPvs().GetSize();
548
549                Debug << "merged pvs size: " << mergedPvs << endl;
550
551        }
552       
553  //  HoleSamplingPass();
554        if (0) {
555                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
556                exporter->SetExportRayDensity(true);
557                exporter->ExportKdTree(*mKdTree);
558
559                if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS))
560                        exporter->ExportBspTree(*mBspTree);
561
562                delete exporter;
563        }
564 
565        bool exportRays = false;
566        if (exportRays) {
567                Exporter *exporter = NULL;
568                exporter = Exporter::GetExporter("sample-rays.x3d");
569                exporter->SetWireframe();
570                exporter->ExportKdTree(*mKdTree);
571                exporter->ExportBspTree(*mBspTree);
572
573                for (i=0; i < pvsOut; i++)
574                exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
575                exporter->SetFilled();
576                 
577                delete exporter;
578        }
579
580        //-- several visualizations and statistics
581        if (1) {
582        if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS))
583        {
584                bool exportSplits = false;
585                environment->GetBoolValue("BspTree.exportSplits", exportSplits);
586
587                // export the bsp splits
588                if (exportSplits)
589                        ExportSplits(objects);
590               
591                ExportBspPvs(objects);
592        }
593   for (int k=0; k < pvsOut; k++) {
594      Intersectable *object = objects[k];
595      char s[64];
596      sprintf(s, "sample-pvs%04d.x3d", k);
597      Exporter *exporter = Exporter::GetExporter(s);
598      exporter->SetWireframe();
599
600       
601          KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
602          Intersectable::NewMail();
603                 
604          // avoid adding the object to the list
605          object->Mail();
606          ObjectContainer visibleObjects;
607
608          for (; i != object->mKdPvs.mEntries.end(); i++)
609          {
610                  KdNode *node = (*i).first;
611                  exporter->ExportBox(mKdTree->GetBox(node));
612                  mKdTree->CollectObjects(node, visibleObjects);
613          }
614
615          exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
616          exporter->SetFilled();
617
618          for (int j = 0; j < visibleObjects.size(); j++)
619                  exporter->ExportIntersectable(visibleObjects[j]);
620       
621
622          Material m;
623          m.mDiffuseColor = RgbColor(1, 0, 0);
624          exporter->SetForcedMaterial(m);
625          exporter->ExportIntersectable(object);
626
627          delete exporter;
628    }
629  }
630 
631  return true;
632}
633
634bool SamplingPreprocessor::ProcessBspViewCells(bool collectSamplesForBsp,
635                                                                                           Ray &ray,
636                                                                                           Intersectable *object,
637                                                                                           int faceIndex,
638                                                                                           int &contributingSamples,
639                                                                                           int &sampleContributions)
640{
641        // save rays for bsp tree construction
642        if (collectSamplesForBsp)
643        {
644                // also add origin to sample in order to extract it as input polygons
645                MeshInstance *mi = dynamic_cast<MeshInstance *>(object);
646                ray.sourceObject = Ray::Intersection(0.0, mi, faceIndex);
647                                                       
648        mSampleRays.push_back(new Ray(ray));
649               
650                return false;
651        }
652       
653        // construct BSP tree using the samples
654        if (!mBspTree)
655        {
656                BuildBspTree();
657               
658                contributingSamples += mBspTree->GetStat().contributingSamples;
659                sampleContributions += mBspTree->GetStat().sampleContributions;
660
661                BspTreeStatistics(Debug);       
662                if (0) Export("vc_bsptree.x3d", false, false, true);
663        }
664
665        return true;
666}
667
668// merge or subdivide view cells
669int SamplingPreprocessor::PostprocessViewCells(const RayContainer &rays)
670{
671        int merged = 0;
672        RayContainer::const_iterator rit, rit_end = rays.end();
673        vector<BspLeaf *>::const_iterator lit;
674if (0)
675        for (rit = rays.begin(); rit != rays.end(); ++ rit)
676        { 
677                // traverse leaves stored in the rays and compare and merge consecutive
678                // leaves (i.e., the neighbors in the tree)
679                lit = (*rit)->bspLeaves.begin();
680
681                BspLeaf *previousLeaf = *lit;
682                ++ lit;
683               
684                for (; lit != (*rit)->bspLeaves.end(); ++ lit)
685                {
686                        BspLeaf *leaf = *lit;
687                        if (mBspTree->ShouldMerge(leaf, previousLeaf))
688                        {                       
689                                mBspTree->MergeViewCells(leaf, previousLeaf);
690                                ++ merged;
691                        }
692                        previousLeaf = leaf;
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] == ray->bspLeaves[j])
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                Material m;//= RandomMaterial();
802                m.mDiffuseColor = RgbColor(0, 1, 0);
803                exporter->SetForcedMaterial(m);
804
805                exporter->SetWireframe();
806
807                if (vc->GetMesh())
808                        exporter->ExportViewCell(vc);
809                else
810                {
811            PolygonContainer cell;
812
813                        mBspTree->ConstructGeometry(bspLeaves[i], cell);
814                        exporter->ExportPolygons(cell);
815                        CLEAR_CONTAINER(cell);
816
817                        /*vector<BspLeaf *> neighbors;
818                        mBspTree->FindNeighbors(bspLeaves[j], neighbors);
819                        for (int j = 0; j < (int)neighbors.size(); ++ j)
820                        {       if (neighbors[j]->mViewCell == bspLeaves[j]->mViewCell)
821                                {}}*/
822                }
823
824                Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
825                                << ", piercing rays=" << (int)vcRays[i].size() << endl;
826
827                // export view cells
828                if (0)
829                {
830                        m.mDiffuseColor = RgbColor(1, 0, 1);
831                        exporter->SetForcedMaterial(m);
832                        exporter->ExportViewCells(mViewCells);
833                }
834
835                // export rays piercing this view cell
836                exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
837
838                m.mDiffuseColor = RgbColor(1, 0, 0);
839                exporter->SetForcedMaterial(m);
840
841                // output PVS of view cell
842                for (; it != vc->GetPvs().mEntries.end(); ++ it)
843                {
844                        Intersectable *intersect = (*it).first;
845                        if (!intersect->Mailed())
846                        {
847                                exporter->ExportIntersectable(intersect);
848                                intersect->Mail();
849                        }                       
850                }
851                       
852                // output rest of the objects
853                if (0)
854                {
855                        Material m;//= RandomMaterial();
856                        m.mDiffuseColor = RgbColor(0, 0, 1);
857                        exporter->SetForcedMaterial(m);
858
859                        for (int j = 0; j < objects.size(); ++ j)
860                                if (!objects[j]->Mailed())
861                                {
862                                        //if (j == 2198)m.mDiffuseColor = RgbColor(1, 0, 1);
863                                        //else m.mDiffuseColor = RgbColor(1, 1, 0);
864                                        exporter->SetForcedMaterial(m);
865                                        exporter->ExportIntersectable(objects[j]);
866                                        objects[j]->Mail();
867                                }
868                }
869                DEL_PTR(exporter);
870        }
871}
Note: See TracBrowser for help on using the repository browser.