source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp @ 444

Revision 444, 40.2 KB checked in by mattausch, 19 years ago (diff)

fixed error in ray to vssray conversion

Line 
1#include "ViewCellsManager.h"
2#include "RenderSimulator.h"
3#include "Mesh.h"
4#include "Triangle3.h"
5#include "ViewCell.h"
6#include "Environment.h"
7#include "X3dParser.h"
8#include "ViewCellBsp.h"
9#include "KdTree.h"
10#include "VspKdTree.h"
11#include "Exporter.h"
12#include "VspBspTree.h"
13
14
15ViewCellsManager::ViewCellsManager():
16mRenderSimulator(NULL),
17mConstructionSamples(0),
18mPostProcessSamples(0),
19mVisualizationSamples(0)
20{
21        // post processing stuff
22        environment->GetIntValue("ViewCells.PostProcessing.minPvsDif", mMinPvsDif);
23        environment->GetIntValue("ViewCells.PostProcessing.minPvs", mMinPvs);
24        environment->GetIntValue("ViewCells.PostProcessing.maxPvs", mMaxPvs);
25}
26
27ViewCellsManager::ViewCellsManager(int constructionSamples):
28mConstructionSamples(constructionSamples),
29mRenderSimulator(NULL),
30mPostProcessSamples(0),
31mVisualizationSamples(0)
32{
33        // post processing stuff
34        environment->GetIntValue("ViewCells.PostProcessing.minPvsDif", mMinPvsDif);
35        environment->GetIntValue("ViewCells.PostProcessing.minPvs", mMinPvs);
36        environment->GetIntValue("ViewCells.PostProcessing.maxPvs", mMaxPvs);
37}
38
39ViewCellsManager::~ViewCellsManager()
40{
41        DEL_PTR(mRenderSimulator);
42}
43
44void ViewCellsManager::InitRenderSimulator()
45{
46        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
47
48        environment->GetFloatValue("Simulation.objRenderCost",objRenderCost);
49        environment->GetFloatValue("Simulation.vcOverhead", vcOverhead);
50        environment->GetFloatValue("Simulation.moveSpeed", moveSpeed);
51
52        mRenderSimulator->SetObjectRenderCost(objRenderCost);
53        mRenderSimulator->SetVcOverhead(vcOverhead);
54        mRenderSimulator->SetMoveSpeed(moveSpeed);
55}
56
57bool ViewCellsManager::LoadViewCells(const string filename)
58{
59        X3dParser parser;
60       
61        environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
62       
63        bool success = parser.ParseFile(filename, *this);
64        Debug << (int)mViewCells.size() << " view cells loaded" << endl;
65
66        return success;
67}
68
69void ViewCellsManager::ComputeSampleContributions(const RayContainer &rays,
70                                                                                                  const bool castRays,
71                                                                                                  int &sampleContributions,
72                                                                                                  int &contributingSamples)
73{
74        // view cells not yet constructed
75        if (!ViewCellsConstructed())
76                return;
77
78        RayContainer::const_iterator it, it_end = rays.end();
79
80    for (it = rays.begin(); it != it_end; ++ it)
81        {
82                sampleContributions += ComputeSampleContributions(*(*it), castRays);
83                contributingSamples += sampleContributions > 0;
84        }
85}
86
87void ViewCellsManager::AddViewCell(ViewCell *viewCell)
88{
89        mViewCells.push_back(viewCell);
90}
91
92void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects,
93                                                                           ViewCellContainer &viewCells,
94                                                                           const int maxViewCells) const
95{
96        // maximal max viewcells
97        int limit = maxViewCells > 0 ?
98                Min((int)objects.size(), maxViewCells) : (int)objects.size();
99
100        for (int i = 0; i < limit; ++ i)
101        {
102                Intersectable *object = objects[i];
103               
104                // extract the mesh instances
105                if (object->Type() == Intersectable::MESH_INSTANCE)
106                {
107                        MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
108
109                        ViewCell *viewCell = GenerateViewCell(inst->GetMesh());
110                        viewCells.push_back(viewCell);
111                }
112                //TODO: transformed meshes
113        }
114}
115
116ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri,
117                                                                                        const float height) const
118{
119        // one mesh per view cell
120        Mesh *mesh = new Mesh();
121       
122        //-- construct prism
123
124        // bottom
125        mesh->mFaces.push_back(new Face(2,1,0));
126        // top
127    mesh->mFaces.push_back(new Face(3,4,5));
128        // sides
129        mesh->mFaces.push_back(new Face(1, 4, 3, 0));
130        mesh->mFaces.push_back(new Face(2, 5, 4, 1));
131        mesh->mFaces.push_back(new Face(3, 5, 2, 0));
132
133        //--- extrude new vertices for top of prism
134        Vector3 triNorm = baseTri.GetNormal();
135
136        Triangle3 topTri;       
137
138        // add base vertices and calculate top vertices
139        for (int i = 0; i < 3; ++ i)
140                mesh->mVertices.push_back(baseTri.mVertices[i]);
141       
142        // add top vertices     
143        for (int i = 0; i < 3; ++ i)
144                mesh->mVertices.push_back(baseTri.mVertices[i] + height * triNorm);
145       
146        mesh->Preprocess();
147
148        return GenerateViewCell(mesh);
149}
150
151ViewCell *ViewCellsManager::MergeViewCells(ViewCell &front, ViewCell &back) const
152{
153        ViewCell *vc = GenerateViewCell();
154        // merge pvs
155        vc->GetPvs().Merge(front.GetPvs(), back.GetPvs());
156
157        // merge ray sets
158        stable_sort(front.mPiercingRays.begin(), front.mPiercingRays.end());
159        stable_sort(back.mPiercingRays.begin(), back.mPiercingRays.end());
160
161        std::merge(front.mPiercingRays.begin(), front.mPiercingRays.end(),
162                           back.mPiercingRays.begin(), back.mPiercingRays.end(),
163                           vc->mPiercingRays.begin());
164
165        return vc;
166}
167
168SimulationStatistics ViewCellsManager::SimulateRendering() const
169{
170        if (!ViewCellsConstructed())
171                return SimulationStatistics();
172
173        return mRenderSimulator->SimulateRendering();
174}
175
176ViewCell *ViewCellsManager::GenerateViewCell(Mesh *mesh) const
177{
178        return new ViewCell(mesh);
179}
180
181
182void ViewCellsManager::SetVisualizationSamples(const int visSamples)
183{
184        mVisualizationSamples = visSamples;
185}
186
187void ViewCellsManager::SetConstructionSamples(const int constructionSamples)
188{
189        mConstructionSamples = constructionSamples;
190}
191
192void ViewCellsManager::SetPostProcessSamples(const int postProcessSamples)
193{
194        mPostProcessSamples = postProcessSamples;
195}
196
197int ViewCellsManager::GetVisualizationSamples() const
198{
199        return mVisualizationSamples;
200}
201
202int ViewCellsManager::GetConstructionSamples() const
203{
204        return mConstructionSamples;
205}
206
207int ViewCellsManager::GetPostProcessSamples() const
208{
209        return mPostProcessSamples;
210}
211
212/**********************************************************************/
213/*                   BspViewCellsManager implementation               */
214/**********************************************************************/
215
216BspViewCellsManager::BspViewCellsManager(BspTree *bspTree, int constructionSamples):
217ViewCellsManager(constructionSamples),
218mBspTree(bspTree)
219{
220   mRenderSimulator = new BspRenderSimulator(bspTree);
221   InitRenderSimulator();
222}
223
224bool BspViewCellsManager::ViewCellsConstructed() const
225{
226        return mBspTree->GetRoot() != NULL;
227}
228
229ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const
230{
231        return new BspViewCell(mesh);
232}
233
234int BspViewCellsManager::Construct(const ObjectContainer &objects,
235                                                                   const VssRayContainer &rays,
236                                                                   AxisAlignedBox3 *sceneBbox)
237{
238        // if view cells were already constructed
239        if (ViewCellsConstructed())
240                return 0;
241
242        Debug << "Constructing bsp view cells" << endl;
243
244        int sampleContributions = 0;
245       
246        RayContainer sampleRays;
247
248        int limit = min (mConstructionSamples, (int)rays.size());
249
250    for (int i = 0; i < limit; ++ i)
251                sampleRays.push_back(new Ray(*rays[i]));
252
253        if (mViewCells.empty()) // no view cells loaded
254                mBspTree->Construct(objects, sampleRays);
255        else
256                mBspTree->Construct(mViewCells);
257
258        Debug << mBspTree->GetStatistics() << endl;
259       
260        return sampleContributions;
261}
262
263int BspViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
264{
265        // view cells not yet constructed
266        if (!ViewCellsConstructed())
267                return 0;
268
269        int contributingSamples = 0;
270
271        if (castRay)
272                mBspTree->CastRay(ray);
273       
274        //if (mBspTree->bspIntersections.empty()) return 0;
275
276        Intersectable *tObject =
277                !ray.intersections.empty() ? ray.intersections[0].mObject : NULL;
278
279        Intersectable *sObject = ray.sourceObject.mObject;
280
281        if (sObject || tObject)
282        {
283                // object can be seen from the view cell => add to view cell pvs
284                for (int j = 0; j < (int)ray.bspIntersections.size(); ++ j)
285                {       
286                        BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
287               
288                        // if ray not outside of view space
289                        if (leaf->GetViewCell() != mBspTree->GetRootCell())
290                        {
291                                if (sObject)
292                                {
293                                        contributingSamples +=
294                                                leaf->GetViewCell()->GetPvs().AddSample(sObject);
295                                }
296
297                                if (tObject)
298                                {
299                                        contributingSamples +=
300                                                leaf->GetViewCell()->GetPvs().AddSample(tObject);
301                                }
302                        }
303                }
304        }
305
306        // rays passing through this viewcell
307        if (0)
308                for (int j = 1; j < ((int)ray.bspIntersections.size() - 1); ++ j)
309                {
310                        BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
311
312                        if (leaf->GetViewCell() != mBspTree->GetRootCell())
313                                leaf->GetViewCell()->
314                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
315                }
316
317        return contributingSamples;
318}
319
320int BspViewCellsManager::PostProcess(const ObjectContainer &objects,
321                                                                         const RayContainer &rays)
322{
323        if (!ViewCellsConstructed())
324        {
325                Debug << "view cells not constructed" << endl;
326                return 0;
327        }
328
329
330        //-- post processing of bsp view cells
331    int vcSize = 0;
332        int pvsSize = 0;
333
334        BspViewCellsStatistics stat;
335        mBspTree->EvaluateViewCellsStats(stat);
336        Debug << "original view cell partition:\n" << stat << endl;
337               
338        if (1) // export view cells
339        {
340                cout << "exporting initial view cells (=leaves) ... ";
341                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
342       
343                if (exporter)
344                {
345                        exporter->SetWireframe();
346                        exporter->ExportBspLeaves(*mBspTree, stat.maxPvs);
347                        //exporter->ExportBspViewCellPartition(*mBspTree, 0);
348                               
349                        if (0)
350                        {
351                                Material m;//= RandomMaterial();
352                                m.mDiffuseColor = RgbColor(0, 1, 0);
353                                exporter->SetForcedMaterial(m);
354                                exporter->SetWireframe();
355
356                                exporter->ExportGeometry(objects);
357                        }
358
359                        delete exporter;
360                }
361                cout << "finished" << endl;
362        }
363
364        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
365               
366        long startTime = GetTime();
367
368
369        //-- merge or subdivide view cells
370        int merged = 0;
371
372        RayContainer::const_iterator rit, rit_end = rays.end();
373        vector<Ray::BspIntersection>::const_iterator iit;
374
375        int limit = min((int)rays.size(), mPostProcessSamples);
376
377        for (int i = 0; i < limit; ++ i)
378        { 
379                Ray *ray = rays[i];
380
381                // traverse leaves stored in the rays and compare and merge consecutive
382                // leaves (i.e., the neighbors in the tree)
383                if (ray->bspIntersections.size() < 2)
384                        continue;
385
386                iit = ray->bspIntersections.begin();
387
388                BspLeaf *previousLeaf = (*iit).mLeaf;
389                ++ iit;
390               
391                for (; iit != ray->bspIntersections.end(); ++ iit)
392                {
393                        BspLeaf *leaf = (*iit).mLeaf;
394
395                        if (ShouldMerge(leaf, previousLeaf))
396                        {                       
397                                MergeBspLeafViewCells(leaf, previousLeaf);
398
399                                ++ merged;
400                        }
401               
402                        previousLeaf = leaf;
403                }
404        }
405
406        //-- stats and visualizations
407        cout << "finished" << endl;
408        cout << "merged " << merged << " view cells in "
409                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
410
411        return merged;
412}
413
414int BspViewCellsManager::GetType() const
415{
416        return BSP;
417}
418
419
420void BspViewCellsManager::Visualize(const ObjectContainer &objects,
421                                                                        const RayContainer &sampleRays)
422{
423        if (!ViewCellsConstructed())
424                return;
425
426        //-- recount pvs
427        BspViewCellsStatistics vcStats;
428        mBspTree->EvaluateViewCellsStats(vcStats);
429
430        if (1) // export view cells
431        {
432                cout << "exporting view cells after merge ... ";
433                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
434
435                if (exporter)
436                {
437                        exporter->ExportBspViewCellPartition(*mBspTree, vcStats.maxPvs);
438                        //exporter->ExportBspViewCellPartition(*mBspTree, 0);
439                        delete exporter;
440                }
441
442                cout << "finished" << endl;
443        }       
444
445        //-- visualization of the BSP splits
446        bool exportSplits = false;
447                environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
448       
449        if (exportSplits)
450        {
451                cout << "exporting splits ... ";
452                ExportSplits(objects, sampleRays);
453                cout << "finished" << endl;
454        }
455
456        ExportBspPvs(objects, sampleRays);
457}
458
459
460inline bool vc_gt(ViewCell *a, ViewCell *b)
461{
462        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
463}
464
465void BspViewCellsManager::ExportSplits(const ObjectContainer &objects,
466                                                                           const RayContainer &sampleRays)
467{
468        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
469
470        if (exporter)
471        {       
472                Material m;
473                m.mDiffuseColor = RgbColor(1, 0, 0);
474                exporter->SetForcedMaterial(m);
475                exporter->SetWireframe();
476                exporter->ExportBspSplits(*mBspTree, true);
477
478                // take forced material, else big scenes cannot be viewed
479                m.mDiffuseColor = RgbColor(0, 1, 0);
480                exporter->SetForcedMaterial(m);
481                exporter->SetFilled();
482
483                exporter->ResetForcedMaterial();
484               
485                // export rays
486                if (0)
487                {
488                        RayContainer outRays;
489               
490                        int raysSize = min((int)sampleRays.size(), mVisualizationSamples);
491
492                        for (int i = 0; i < raysSize; ++ i)
493                        {
494                                // only rays piercing geometry
495                                if (!sampleRays[i]->intersections.empty())
496                                        outRays.push_back(sampleRays[i]);
497                        }
498                       
499                        // export rays
500                        exporter->ExportRays(outRays, 1000, RgbColor(1, 1, 0));
501                }
502
503                if (0)
504                        exporter->ExportGeometry(objects);
505
506                delete exporter;
507        }
508}
509
510void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
511                                                                           const RayContainer &sampleRays)
512{
513        const int leafOut = 10;
514       
515        ViewCell::NewMail();
516
517        //-- some rays for output
518        const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
519        Debug << "visualization using " << raysOut << " samples" << endl;
520       
521
522        if (1)
523        {
524                //-- some random view cells and rays for output
525                vector<BspLeaf *> bspLeaves;
526
527                for (int i = 0; i < leafOut; ++ i)
528                        bspLeaves.push_back(mBspTree->GetRandomLeaf());
529               
530                for (int i = 0; i < bspLeaves.size(); ++ i)
531                {
532                        BspLeaf *leaf = bspLeaves[i];
533
534                        RayContainer vcRays;
535               
536                        cout << "creating output for view cell " << i << " ... ";
537
538                        // check whether we can add the current ray to the output rays
539                        for (int k = 0; k < raysOut; ++ k)
540                        {
541                                Ray *ray = sampleRays[k];
542
543                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
544                                {
545                                        BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
546
547                                        if (leaf->GetViewCell() == leaf2->GetViewCell())
548                                        {
549                                                vcRays.push_back(ray);
550                                        }
551                                }
552                        }
553
554            Intersectable::NewMail();
555
556                        BspViewCell *vc = dynamic_cast<BspViewCell *>(leaf->GetViewCell());
557
558                        //bspLeaves[j]->Mail();
559                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
560
561                        Exporter *exporter = Exporter::GetExporter(s);
562                        exporter->SetFilled();
563
564                        exporter->SetWireframe();
565                        //exporter->SetFilled();
566
567                        Material m;//= RandomMaterial();
568                        m.mDiffuseColor = RgbColor(1, 1, 0);
569                        exporter->SetForcedMaterial(m);
570
571                        if (vc->GetMesh())
572                                exporter->ExportViewCell(vc);
573                        else
574                        {
575                                PolygonContainer vcGeom;
576                                // export view cell geometry
577                                mBspTree->ConstructGeometry(vc, vcGeom);
578                                exporter->ExportPolygons(vcGeom);
579                                CLEAR_CONTAINER(vcGeom);
580                        }
581
582                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
583                                  << ", piercing rays=" << (int)vcRays.size() << endl;
584
585                        // export rays piercing this view cell
586                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0)); 
587                       
588                        m.mDiffuseColor = RgbColor(1, 0, 0);
589                        exporter->SetForcedMaterial(m);
590
591                        // exporter->SetWireframe();
592                        exporter->SetFilled();
593
594                        ViewCellPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
595                        // output PVS of view cell
596                        for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
597                        {
598                                Intersectable *intersect = (*it).first;
599                                if (!intersect->Mailed())
600                                {
601                                        exporter->ExportIntersectable(intersect);
602                                        intersect->Mail();
603                                }                       
604                        }
605
606                        DEL_PTR(exporter);
607                        cout << "finished" << endl;
608                }
609        }
610        else
611        {
612                ViewCellContainer viewCells;
613                RayContainer vcRays;
614
615                mBspTree->CollectViewCells(viewCells);
616                stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
617
618                int limit = min(leafOut, (int)viewCells.size());
619               
620                for (int i = 0; i < limit; ++ i)
621                {
622                        cout << "creating output for view cell " << i << " ... ";
623                       
624            Intersectable::NewMail();
625                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
626
627                        cout << "creating output for view cell " << i << " ... ";
628                        // check whether we can add the current ray to the output rays
629                        for (int k = 0; k < raysOut; ++ k)
630                        {
631                                Ray *ray = sampleRays[k];
632
633                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
634                                {
635                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
636
637                                        if (vc == leaf->GetViewCell())
638                                        {
639                                                vcRays.push_back(ray);
640                                        }
641                                }
642                        }
643
644                        //bspLeaves[j]->Mail();
645                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
646
647                        Exporter *exporter = Exporter::GetExporter(s);
648                       
649                        exporter->SetWireframe();
650
651                        Material m;//= RandomMaterial();
652                        m.mDiffuseColor = RgbColor(0, 1, 0);
653                        exporter->SetForcedMaterial(m);
654
655                        if (vc->GetMesh())
656                                exporter->ExportViewCell(vc);
657                        else
658                        {
659                                PolygonContainer cell;
660                                // export view cell
661                                mBspTree->ConstructGeometry(vc, cell);
662                                exporter->ExportPolygons(cell);
663                                CLEAR_CONTAINER(cell);
664                        }
665
666                       
667                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
668                                  << ", piercing rays=" << (int)vcRays.size() << endl;
669
670                       
671                        // export rays piercing this view cell
672                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
673       
674                        m.mDiffuseColor = RgbColor(1, 0, 0);
675                        exporter->SetForcedMaterial(m);
676
677                        ViewCellPvsMap::const_iterator it,
678                                it_end = vc->GetPvs().mEntries.end();
679
680                        // output PVS of view cell
681                        for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
682                        {
683                                Intersectable *intersect = (*it).first;
684                                if (!intersect->Mailed())
685                                {
686                                        Material m = RandomMaterial();
687                       
688                                        exporter->SetForcedMaterial(m);
689
690                                        exporter->ExportIntersectable(intersect);
691                                        intersect->Mail();
692                                }                       
693                        }
694                               
695                        DEL_PTR(exporter);
696                        cout << "finished" << endl;
697                }
698        }
699}
700
701
702bool BspViewCellsManager::MergeBspLeafViewCells(BspLeaf *front, BspLeaf *back) const
703{
704        BspViewCell *viewCell =
705                dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(), *back->GetViewCell()));
706       
707        if (!viewCell)
708                return false;
709
710        // change view cells of all leaves associated with the
711        // previous view cells
712
713        BspViewCell *fVc = front->GetViewCell();
714        BspViewCell *bVc = back->GetViewCell();
715
716        vector<BspLeaf *> fLeaves = fVc->mBspLeaves;
717        vector<BspLeaf *> bLeaves = bVc->mBspLeaves;
718
719        vector<BspLeaf *>::const_iterator it;
720       
721        for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
722        {
723                (*it)->SetViewCell(viewCell);
724                viewCell->mBspLeaves.push_back(*it);
725        }
726        for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
727        {
728                (*it)->SetViewCell(viewCell);
729                viewCell->mBspLeaves.push_back(*it);
730        }
731       
732        DEL_PTR(fVc);
733        DEL_PTR(bVc);
734
735        return true;
736}
737
738bool BspViewCellsManager::ShouldMerge(BspLeaf *front, BspLeaf *back) const
739{
740        ViewCell *fvc = front->GetViewCell();
741        ViewCell *bvc = back->GetViewCell();
742
743        if ((fvc == mBspTree->GetRootCell()) || (bvc == mBspTree->GetRootCell()) || (fvc == bvc))
744                return false;
745
746        int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
747
748        if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
749        {
750                if ((fvc->GetPvs().GetSize() < mMinPvs) ||     
751                        (bvc->GetPvs().GetSize() < mMinPvs) ||
752                        ((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
753                {
754                        return true;
755                }
756        }
757       
758        return false;
759}
760
761
762
763/**********************************************************************/
764/*                   KdViewCellsManager implementation               */
765/**********************************************************************/
766
767KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
768ViewCellsManager(),
769mKdTree(kdTree),
770mKdPvsDepth(100)
771{
772   mRenderSimulator = new KdRenderSimulator(mKdTree);
773   InitRenderSimulator();
774}
775
776int KdViewCellsManager::Construct(const ObjectContainer &objects,
777                                                                  const VssRayContainer &rays,
778                                                                  AxisAlignedBox3 *sceneBbox)
779{
780        // if view cells already constructed
781        if (ViewCellsConstructed())
782                return 0;
783
784        Debug << "Constructing bsp view cells" << endl;
785       
786        mKdTree->Construct();
787
788        return 0;
789}
790
791bool KdViewCellsManager::ViewCellsConstructed() const
792{
793        return mKdTree->GetRoot() != NULL;
794}
795
796int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
797                                                                        const RayContainer &rays)
798{
799        return 0;
800}
801
802void KdViewCellsManager::Visualize(const ObjectContainer &objects,
803                                                                   const RayContainer &sampleRays)
804{
805        if (!ViewCellsConstructed())
806                return;
807
808        const int pvsOut = min((int)objects.size(), 10);
809
810        int limit = min(mVisualizationSamples, (int)sampleRays.size());
811
812        RayContainer *rays = new RayContainer[pvsOut];
813
814        for  (int i = 0; i < limit; ++ i)
815        {
816                Ray *ray = sampleRays[i];
817
818                if (!ray->intersections.empty())
819                {
820                        // check whether we can add this to the rays
821                        for (int j = 0; j < pvsOut; j++)
822                        {
823                                if (objects[j] == ray->intersections[0].mObject)
824                                {
825                                        rays[j].push_back(ray);
826                                }
827                        }
828                }
829        }
830
831        bool exportRays = false;
832        if (exportRays) {
833                Exporter *exporter = NULL;
834                exporter = Exporter::GetExporter("sample-rays.x3d");
835                exporter->SetWireframe();
836                exporter->ExportKdTree(*mKdTree);
837               
838                for (i=0; i < pvsOut; i++)
839                        exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
840                exporter->SetFilled();
841               
842                delete exporter;
843        }
844
845        for (int k=0; k < pvsOut; k++)
846        {
847                Intersectable *object = objects[k];
848                char s[64];     
849                sprintf(s, "sample-pvs%04d.x3d", k);
850
851                Exporter *exporter = Exporter::GetExporter(s);
852                exporter->SetWireframe();
853         
854        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
855                Intersectable::NewMail();
856                       
857                // avoid adding the object to the list
858                object->Mail();
859                ObjectContainer visibleObjects;
860           
861                for (; i != object->mKdPvs.mEntries.end(); i++)
862                {
863                         KdNode *node = (*i).first;
864                         exporter->ExportBox(mKdTree->GetBox(node));
865                         mKdTree->CollectObjects(node, visibleObjects);
866                }
867
868                exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
869                exporter->SetFilled();
870                 
871                for (int j = 0; j < visibleObjects.size(); j++)
872                        exporter->ExportIntersectable(visibleObjects[j]);
873                 
874                Material m;
875                m.mDiffuseColor = RgbColor(1, 0, 0);
876                exporter->SetForcedMaterial(m);
877                exporter->ExportIntersectable(object);
878         
879                delete exporter;
880        }
881        DEL_PTR(rays);
882}
883
884int KdViewCellsManager::GetType() const
885{
886        return ViewCellsManager::KD;
887}
888
889int KdViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
890{
891        // view cells not yet constructed
892        if (!ViewCellsConstructed())
893                return 0;
894
895        if (castRay)
896                mKdTree->CastRay(ray);
897
898        if (ray.kdLeaves.empty())
899                return 0;
900
901        Intersectable *tObject =
902                !ray.intersections.empty() ? ray.intersections[0].mObject : NULL;
903
904        Intersectable *sObject =
905                ray.sourceObject.mObject;
906
907        int contributingSamples = 0;
908       
909        int objects = 0;
910
911        if (sObject)
912                objects++;
913        if (tObject)
914                objects++;
915
916        for (int j = 1; j < ((int)ray.kdLeaves.size() - 1); ++ j)
917        {
918                ray.kdLeaves[j]->AddPassingRay2(ray, objects,
919                                                                                (int)ray.kdLeaves.size());
920        }
921
922        if (!objects)
923                return 0;
924       
925        for (int j=0; j < ray.kdLeaves.size(); j++)
926        {
927                KdNode *node = GetNodeForPvs(ray.kdLeaves[j]);
928
929                if (sObject)
930                        contributingSamples += sObject->mKdPvs.AddSample(node);
931                if (tObject)
932                        contributingSamples += tObject->mKdPvs.AddSample(node);
933        }
934
935        return contributingSamples;
936}
937
938
939KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)
940{
941        KdNode *node = leaf;
942
943        while (node->mParent && node->mDepth > mKdPvsDepth)
944                node = node->mParent;
945        return node;
946}
947
948
949
950/**********************************************************************/
951/*                   VspKdViewCellsManager implementation             */
952/**********************************************************************/
953
954VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree, int constructionSamples):
955ViewCellsManager(constructionSamples),
956mVspKdTree(vspKdTree)
957{
958   mRenderSimulator = NULL; // TODO: new VspKdRenderSimulator(vspKdTree);
959   InitRenderSimulator();
960}
961
962int VspKdViewCellsManager::Construct(const ObjectContainer &objects,
963                                                                         const VssRayContainer &rays,
964                                                                         AxisAlignedBox3 *sceneBbox)
965{
966        // if view cells already constructed
967        if (ViewCellsConstructed())
968                return 0;
969
970        mVspKdTree->Construct(rays, sceneBbox);
971        return 0;
972}
973
974bool VspKdViewCellsManager::ViewCellsConstructed() const
975{
976        return mVspKdTree->GetRoot() != NULL;
977}
978
979int VspKdViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
980{
981        // view cells not yet constructed
982        if (!ViewCellsConstructed())
983                return 0;
984
985        //if (castRay) // TODO
986
987        int sampleContributions = 0;
988
989/*
990    for (int i = 0; i < (int)rays.size(); ++ i)
991        {
992                Ray *ray = rays[i];
993
994                mBspTree->CastRay(*ray);
995                       
996                Intersectable *term =
997                        !ray->intersections.empty() ? ray->intersections[0].mObject : NULL
998                        ;
999                sampleContributions +=
1000                        AddSampleContributions(*ray, ray->sourceObject.mObject, term);
1001                       
1002        }
1003*/
1004        return sampleContributions;
1005}
1006
1007int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
1008                                                                           const RayContainer &rays)
1009{
1010        if (!ViewCellsConstructed())
1011                return 0;
1012
1013        return 0;
1014}
1015
1016void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
1017                                                                          const RayContainer &sampleRays)
1018{
1019        if (!ViewCellsConstructed())
1020                return;
1021
1022        if (1)
1023        {
1024                Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
1025                //exporter->SetWireframe();
1026                exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
1027
1028                Debug << "average PVS size: " << mVspKdTree->GetAvgPvsSize() << endl;
1029
1030                if (0)
1031                        exporter->ExportGeometry(objects);
1032
1033                bool exportRays = true;
1034
1035                if (exportRays)
1036                {
1037                        int raysSize = 2000;
1038                        float prob = raysSize / (float)sampleRays.size();
1039               
1040                        exporter->SetWireframe();
1041                       
1042                        RayContainer rays;
1043               
1044                        for (int i = 0; i < sampleRays.size(); ++ i)
1045                        {
1046                                if (RandomValue(0,1) < prob)
1047                                        rays.push_back(sampleRays[i]);
1048                        }
1049
1050                        exporter->ExportRays(rays, 1000, RgbColor(1, 0, 0));
1051                }
1052
1053                delete exporter;
1054        }
1055
1056        if (1)
1057        {
1058                vector<VspKdTreeLeaf *> leafContainer;
1059
1060                mVspKdTree->CollectLeaves(leafContainer);
1061
1062                for (int i = 0; i < 10; ++ i)
1063                {
1064                        char s[64];
1065                        sprintf(s, "vsp_leaves%04d.x3d", i);
1066                        Exporter *exporter = Exporter::GetExporter(s);
1067
1068                        // export geometry
1069                        VspKdTreeLeaf *leaf = leafContainer[Random((int)leafContainer.size())];
1070                        AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
1071
1072                        Material m;
1073                        m.mDiffuseColor = RgbColor(0, 1, 1);
1074                        exporter->SetForcedMaterial(m);
1075                        exporter->SetWireframe();
1076                        exporter->ExportBox(box);
1077
1078                        //-- export stored rays
1079                        VssRayContainer vssRays;
1080                        leaf->GetRays(vssRays);
1081
1082                        VssRayContainer rays;
1083                        VssRayContainer::const_iterator it, it_end = vssRays.end();
1084
1085                        for (it = vssRays.begin(); it != it_end; ++ it)
1086                        {
1087                                //if (!(*it)->mOriginObject && !(*it)->mTerminationObject)
1088                                        rays.push_back(*it);
1089
1090                                //if (!(*it)->mOriginObject && !(*it)->mTerminationObject)
1091                                //      Debug << "ERR: " << (*it)->mOrigin << " " << (*it)->mTermination << endl;
1092                        }
1093
1094                        exporter->ExportRays(rays, RgbColor(1, 0, 0));
1095
1096                        //-- export stored PVS
1097                       
1098                        ObjectContainer pvsObj;
1099                        leaf->ExtractPvs(pvsObj);
1100                               
1101                        exporter->ExportGeometry(pvsObj);
1102
1103                        delete exporter;
1104                }                       
1105        }
1106}
1107
1108int VspKdViewCellsManager::GetType() const
1109{
1110        return VSP_KD;
1111}
1112
1113
1114/**********************************************************************/
1115/*                 VspBspViewCellsManager implementation              */
1116/**********************************************************************/
1117
1118VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree,
1119                                                                                           int constructionSamples):
1120ViewCellsManager(constructionSamples),
1121mVspBspTree(vspBspTree)
1122{
1123   mRenderSimulator = NULL;// TODO new VspBspRenderSimulator(bspTree);
1124   //InitRenderSimulator();
1125}
1126
1127bool VspBspViewCellsManager::ViewCellsConstructed() const
1128{
1129        return mVspBspTree->GetRoot() != NULL;
1130}
1131
1132ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const
1133{
1134        return new BspViewCell(mesh);
1135}
1136
1137int VspBspViewCellsManager::Construct(const ObjectContainer &objects,
1138                                                                          const VssRayContainer &rays,
1139                                                                          AxisAlignedBox3 *sceneBbox)
1140{
1141        // if view cells were already constructed
1142        if (ViewCellsConstructed())
1143                return 0;
1144
1145        Debug << "Constructing bsp view cells" << endl;
1146
1147        int sampleContributions = 0;
1148       
1149        VssRayContainer sampleRays;
1150
1151        int limit = min (mConstructionSamples, (int)rays.size());
1152
1153    for (int i = 0; i < limit; ++ i)
1154                sampleRays.push_back(rays[i]);
1155
1156        mVspBspTree->Construct(sampleRays);
1157       
1158        Debug << mVspBspTree->GetStatistics() << endl;
1159
1160        return sampleContributions;
1161}
1162
1163int VspBspViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
1164{
1165        // view cells not yet constructed
1166        if (!ViewCellsConstructed())
1167                return 0;
1168
1169        int contributingSamples = 0;
1170
1171        if (castRay)
1172                mVspBspTree->CastRay(ray);
1173
1174        Intersectable *tObject =
1175                !ray.intersections.empty() ? ray.intersections[0].mObject : NULL;
1176
1177        Intersectable *sObject = ray.sourceObject.mObject;
1178
1179        if (sObject || tObject)
1180        {
1181                // object can be seen from the view cell => add to view cell pvs
1182                for (int j = 0; j < (int)ray.bspIntersections.size(); ++ j)
1183                {       
1184                        VspBspLeaf *leaf = NULL;  //TODO ray.bspIntersections[j].mLeaf;
1185               
1186                        // if ray not in unbounded space
1187                        if (leaf->GetViewCell() != mVspBspTree->GetRootCell())
1188                        {
1189                                if (sObject)
1190                                {
1191                                        contributingSamples +=
1192                                                leaf->GetViewCell()->GetPvs().AddSample(sObject);
1193                                }
1194
1195                                if (tObject)
1196                                {
1197                                        contributingSamples +=
1198                                                leaf->GetViewCell()->GetPvs().AddSample(tObject);
1199                                }
1200                        }
1201                }
1202        }
1203
1204        // rays passing through this viewcell
1205        if (0)
1206                for (int j = 1; j < ((int)ray.bspIntersections.size() - 1); ++ j)
1207                {
1208                        VspBspLeaf *leaf = NULL;// TODO = ray.bspIntersections[j].mLeaf;
1209
1210                        if (leaf->GetViewCell() != mVspBspTree->GetRootCell())
1211                                leaf->GetViewCell()->
1212                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
1213                }
1214
1215        return contributingSamples;
1216}
1217
1218int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
1219                                                                                const RayContainer &rays)
1220{
1221        return 0;// TODO
1222        if (!ViewCellsConstructed())
1223        {
1224                Debug << "view cells not constructed" << endl;
1225                return 0;
1226        }
1227
1228
1229        //-- post processing of bsp view cells
1230    int vcSize = 0;
1231        int pvsSize = 0;
1232
1233        VspBspViewCellsStatistics vcStats;
1234        mVspBspTree->EvaluateViewCellsStats(vcStats);
1235        Debug << "original view cell partition:\n" << vcStats << endl;
1236               
1237        if (1) // export view cells
1238        {
1239                cout << "exporting initial view cells (=leaves) ... ";
1240                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
1241       
1242                if (exporter)
1243                {
1244                        exporter->SetWireframe();
1245                        //exporter->ExportBspLeaves(*mVspBspTree, stat.maxPvs);
1246                               
1247                        if (0)
1248                        {
1249                                Material m;
1250                                m.mDiffuseColor = RgbColor(0, 1, 0);
1251                                exporter->SetForcedMaterial(m);
1252                                exporter->SetWireframe();
1253
1254                                exporter->ExportGeometry(objects);
1255                        }
1256
1257                        delete exporter;
1258                }
1259                cout << "finished" << endl;
1260        }
1261
1262        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
1263               
1264        long startTime = GetTime();
1265
1266
1267        //-- merge or subdivide view cells
1268        int merged = 0;
1269
1270        RayContainer::const_iterator rit, rit_end = rays.end();
1271        vector<Ray::BspIntersection>::const_iterator iit;
1272
1273        int limit = min((int)rays.size(), mPostProcessSamples);
1274
1275        for (int i = 0; i < limit; ++ i)
1276        { 
1277                Ray *ray = rays[i];
1278
1279                // traverse leaves stored in the rays and compare and merge consecutive
1280                // leaves (i.e., the neighbors in the tree)
1281                if (ray->bspIntersections.size() < 2)
1282                        continue;
1283
1284                iit = ray->bspIntersections.begin();
1285
1286                VspBspLeaf *previousLeaf = NULL;//TODO(*iit).mLeaf;
1287                ++ iit;
1288               
1289                for (; iit != ray->bspIntersections.end(); ++ iit)
1290                {
1291                        VspBspLeaf *leaf = NULL;//TODO(*iit).mLeaf;
1292
1293                        if (ShouldMerge(leaf, previousLeaf))
1294                        {                       
1295                                MergeVspBspLeafViewCells(leaf, previousLeaf);
1296
1297                                ++ merged;
1298                        }
1299               
1300                        previousLeaf = leaf;
1301                }
1302        }
1303
1304        //-- stats and visualizations
1305        cout << "finished" << endl;
1306        cout << "merged " << merged << " view cells in "
1307                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
1308
1309        return merged;
1310}
1311
1312int VspBspViewCellsManager::GetType() const
1313{
1314        return VSP_BSP;
1315}
1316
1317
1318void VspBspViewCellsManager::Visualize(const ObjectContainer &objects,
1319                                                                           const RayContainer &sampleRays)
1320{
1321        return; // TODO
1322        if (!ViewCellsConstructed())
1323                return;
1324
1325        //-- recount pvs
1326        VspBspViewCellsStatistics vcStats;
1327        mVspBspTree->EvaluateViewCellsStats(vcStats);
1328
1329        if (1) // export view cells
1330        {
1331                cout << "exporting view cells after merge ... ";
1332                /*Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
1333
1334                if (exporter)
1335                {
1336                        exporter->ExportBspViewCellPartition(*mVspBspTree, vcStats.maxPvs);
1337                        delete exporter;
1338                }
1339                */
1340                cout << "finished" << endl;
1341        }       
1342
1343        //-- visualization of the BSP splits
1344        bool exportSplits = false;
1345                environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
1346       
1347        if (exportSplits)
1348        {
1349                cout << "exporting splits ... ";
1350                ExportSplits(objects, sampleRays);
1351                cout << "finished" << endl;
1352        }
1353
1354//TODO  ExportVspBspPvs(objects, sampleRays);
1355}
1356
1357
1358void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
1359                                                                                  const RayContainer &sampleRays)
1360{
1361        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
1362
1363        if (exporter)
1364        {       
1365                Material m;
1366                m.mDiffuseColor = RgbColor(1, 0, 0);
1367                exporter->SetForcedMaterial(m);
1368                exporter->SetWireframe();
1369                // TODO
1370                //exporter->ExportBspSplits(*mVspBspTree, true);
1371
1372                // take forced material, else big scenes cannot be viewed
1373                m.mDiffuseColor = RgbColor(0, 1, 0);
1374                exporter->SetForcedMaterial(m);
1375                exporter->SetFilled();
1376
1377                exporter->ResetForcedMaterial();
1378               
1379                // export rays
1380                if (0)
1381                {
1382                        RayContainer outRays;
1383               
1384                        int raysSize = min((int)sampleRays.size(), mVisualizationSamples);
1385
1386                        for (int i = 0; i < raysSize; ++ i)
1387                        {
1388                                // only rays piercing geometry
1389                                if (!sampleRays[i]->intersections.empty())
1390                                        outRays.push_back(sampleRays[i]);
1391                        }
1392                       
1393                        // export rays
1394                        exporter->ExportRays(outRays, 1000, RgbColor(1, 1, 0));
1395                }
1396
1397                if (0)
1398                        exporter->ExportGeometry(objects);
1399
1400                delete exporter;
1401        }
1402}
1403
1404void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
1405                                                                                  const RayContainer &sampleRays)
1406{
1407        const int leafOut = 10;
1408       
1409        ViewCell::NewMail();
1410
1411        //-- some rays for output
1412        const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
1413        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
1414        vector<Ray *> vcRays[leafOut];
1415
1416        if (0)
1417        {
1418                //-- some random view cells and rays for output
1419                vector<VspBspLeaf *> vspBspLeaves;
1420
1421                for (int i = 0; i < leafOut; ++ i)
1422                        vspBspLeaves.push_back(mVspBspTree->GetRandomLeaf());   
1423               
1424                for (int i = 0; i < (int)vspBspLeaves.size(); ++ i)
1425                {
1426                        cout << "creating output for view cell " << i << " ... ";
1427                        // check whether we can add the current ray to the output rays
1428                        for (int k = 0; k < raysOut; ++ k)
1429                        {
1430                                Ray *ray = sampleRays[k];
1431
1432                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1433                                {
1434                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
1435
1436                                        if (vspBspLeaves[i]->GetViewCell() == leaf->GetViewCell())
1437                                        {
1438                                                vcRays[i].push_back(ray);
1439                                        }
1440                                }
1441                        }
1442
1443                        Intersectable::NewMail();
1444
1445                        BspViewCell *vc = dynamic_cast<BspViewCell *>
1446                                (vspBspLeaves[i]->GetViewCell());
1447
1448                        //bspLeaves[j]->Mail();
1449                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
1450
1451                        Exporter *exporter = Exporter::GetExporter(s);
1452                        exporter->SetFilled();
1453
1454                        ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
1455
1456                        exporter->SetWireframe();
1457                        //exporter->SetFilled();
1458
1459                        Material m;//= RandomMaterial();
1460                        m.mDiffuseColor = RgbColor(0, 1, 0);
1461                        exporter->SetForcedMaterial(m);
1462
1463                        if (vc->GetMesh())
1464                                exporter->ExportViewCell(vc);
1465                        else
1466                        {
1467                                PolygonContainer vcGeom;
1468
1469                                // export view cell geometry
1470                                mVspBspTree->ConstructGeometry(vc, vcGeom);
1471                                exporter->ExportPolygons(vcGeom);
1472                                CLEAR_CONTAINER(vcGeom);
1473                        }
1474
1475                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1476                                        << ", piercing rays=" << (int)vcRays[i].size() << endl;
1477
1478                        // export rays piercing this view cell
1479                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
1480
1481                        m.mDiffuseColor = RgbColor(1, 0, 0);
1482                        exporter->SetForcedMaterial(m);
1483
1484                        // exporter->SetWireframe();
1485                        exporter->SetFilled();
1486
1487                        // output PVS of view cell
1488                        for (; it != vc->GetPvs().mEntries.end(); ++ it)
1489                        {
1490                                Intersectable *intersect = (*it).first;
1491                                if (!intersect->Mailed())
1492                                {
1493                                        exporter->ExportIntersectable(intersect);
1494                                        intersect->Mail();
1495                                }                       
1496                        }
1497                               
1498                        // output rest of the objects
1499                        if (0)
1500                        {
1501                                Material m;//= RandomMaterial();
1502                                m.mDiffuseColor = RgbColor(0, 0, 1);
1503                                exporter->SetForcedMaterial(m);
1504
1505                                for (int j = 0; j < objects.size(); ++ j)
1506                                        if (!objects[j]->Mailed())
1507                                        {
1508                                                exporter->SetForcedMaterial(m);
1509                                                exporter->ExportIntersectable(objects[j]);
1510                                                objects[j]->Mail();
1511                                        }
1512                        }
1513                        DEL_PTR(exporter);
1514                        cout << "finished" << endl;
1515                }
1516        }
1517        else
1518        {
1519                ViewCellContainer viewCells;
1520
1521                mVspBspTree->CollectViewCells(viewCells);
1522                stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
1523
1524                int limit = min(leafOut, (int)viewCells.size());
1525               
1526                for (int i = 0; i < limit; ++ i)
1527                {
1528                        cout << "creating output for view cell " << i << " ... ";
1529                       
1530            Intersectable::NewMail();
1531                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
1532
1533                        cout << "creating output for view cell " << i << " ... ";
1534                        // check whether we can add the current ray to the output rays
1535                        for (int k = 0; k < raysOut; ++ k)
1536                        {
1537                                Ray *ray = sampleRays[k];
1538
1539                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1540                                {
1541                                        VspBspLeaf *leaf = NULL; // TODO = ray->bspIntersections[j].mLeaf;
1542
1543                                        if (vc == leaf->GetViewCell())
1544                                        {
1545                                                vcRays[i].push_back(ray);
1546                                        }
1547                                }
1548                        }
1549
1550                        //bspLeaves[j]->Mail();
1551                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
1552
1553                        Exporter *exporter = Exporter::GetExporter(s);
1554                       
1555                        exporter->SetWireframe();
1556
1557                        Material m;//= RandomMaterial();
1558                        m.mDiffuseColor = RgbColor(0, 1, 0);
1559                        exporter->SetForcedMaterial(m);
1560
1561                        if (vc->GetMesh())
1562                                exporter->ExportViewCell(vc);
1563                        else
1564                        {
1565                                PolygonContainer vcGeom;
1566                                // export view cell
1567                                mVspBspTree->ConstructGeometry(vc, vcGeom);
1568                                exporter->ExportPolygons(vcGeom);
1569                                CLEAR_CONTAINER(vcGeom);
1570                        }
1571
1572                       
1573                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1574                                        << ", piercing rays=" << (int)vcRays[i].size() << endl;
1575
1576                       
1577                        // export rays piercing this view cell
1578                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
1579       
1580                        m.mDiffuseColor = RgbColor(1, 0, 0);
1581                        exporter->SetForcedMaterial(m);
1582
1583                        ViewCellPvsMap::const_iterator it,
1584                                it_end = vc->GetPvs().mEntries.end();
1585
1586                        // output PVS of view cell
1587                        for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
1588                        {
1589                                Intersectable *intersect = (*it).first;
1590
1591                                if (!intersect->Mailed())
1592                                {
1593                                        Material m = RandomMaterial();
1594                       
1595                                        exporter->SetForcedMaterial(m);
1596
1597                                        exporter->ExportIntersectable(intersect);
1598                                        intersect->Mail();
1599                                }                       
1600                        }
1601                               
1602                        DEL_PTR(exporter);
1603                        cout << "finished" << endl;
1604                }
1605        }
1606}
1607
1608
1609bool VspBspViewCellsManager::MergeVspBspLeafViewCells(VspBspLeaf *front,
1610                                                                                                          VspBspLeaf *back) const
1611{
1612        BspViewCell *viewCell =
1613                dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(),
1614                                                                                                   *back->GetViewCell()));
1615       
1616        if (!viewCell)
1617                return false;
1618
1619        // change view cells of all leaves associated with the
1620        // previous view cells
1621
1622        BspViewCell *fVc = front->GetViewCell();
1623        BspViewCell *bVc = back->GetViewCell();
1624
1625        // TODO
1626        /*vector<VspBspLeaf *> fLeaves = fVc->mBspLeaves;
1627        vector<VspBspLeaf *> bLeaves = bVc->mBspLeaves;
1628
1629        vector<VspBspLeaf *>::const_iterator it;
1630       
1631        for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
1632        {
1633                (*it)->SetViewCell(viewCell);
1634                viewCell->mBspLeaves.push_back(*it);
1635        }
1636        for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
1637        {
1638                (*it)->SetViewCell(viewCell);
1639                viewCell->mBspLeaves.push_back(*it);
1640        }
1641       
1642        DEL_PTR(fVc);
1643        DEL_PTR(bVc);
1644*/
1645        return true;
1646}
1647
1648bool VspBspViewCellsManager::ShouldMerge(VspBspLeaf *front, VspBspLeaf *back) const
1649{
1650        ViewCell *fvc = front->GetViewCell();
1651        ViewCell *bvc = back->GetViewCell();
1652
1653        if ((fvc == mVspBspTree->GetRootCell()) ||
1654                (bvc == mVspBspTree->GetRootCell()) ||
1655                (fvc == bvc))
1656                return false;
1657
1658        int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
1659
1660        if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
1661        {
1662                if ((fvc->GetPvs().GetSize() < mMinPvs) ||     
1663                        (bvc->GetPvs().GetSize() < mMinPvs) ||
1664                        ((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
1665                {
1666                        return true;
1667                }
1668        }
1669       
1670        return false;
1671}
1672
Note: See TracBrowser for help on using the repository browser.