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

Revision 441, 27.0 KB checked in by mattausch, 19 years ago (diff)

added visibilitymanager
removed area computation from bsp

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
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        int 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        CLEAR_CONTAINER(sampleRays);
260
261        return sampleContributions;
262}
263
264int BspViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
265{
266        // view cells not yet constructed
267        if (!ViewCellsConstructed())
268                return 0;
269
270        int contributingSamples = 0;
271
272        if (castRay)
273                mBspTree->CastRay(ray);
274       
275        //if (mBspTree->bspIntersections.empty()) return 0;
276
277        Intersectable *tObject =
278                !ray.intersections.empty() ? ray.intersections[0].mObject : NULL;
279
280        Intersectable *sObject = ray.sourceObject.mObject;
281
282        if (sObject || tObject)
283        {
284                // object can be seen from the view cell => add to view cell pvs
285                for (int j = 0; j < (int)ray.bspIntersections.size(); ++ j)
286                {       
287                        BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
288               
289                        // if ray not in unbounded space
290                        if (leaf->GetViewCell() != mBspTree->GetRootCell())
291                        {
292                                if (sObject)
293                                {
294                                        contributingSamples +=
295                                                leaf->GetViewCell()->GetPvs().AddSample(sObject);
296                                }
297
298                                if (tObject)
299                                {
300                                        contributingSamples +=
301                                                leaf->GetViewCell()->GetPvs().AddSample(tObject);
302                                }
303                        }
304                }
305        }
306
307        // rays passing through this viewcell
308        if (0)
309                for (int j = 1; j < ((int)ray.bspIntersections.size() - 1); ++ j)
310                {
311                        BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
312
313                        if (leaf->GetViewCell() != mBspTree->GetRootCell())
314                                leaf->GetViewCell()->
315                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
316                }
317
318        return contributingSamples;
319}
320
321int BspViewCellsManager::PostProcess(const ObjectContainer &objects,
322                                                                         const RayContainer &rays)
323{
324        if (!ViewCellsConstructed())
325        {
326                Debug << "view cells not constructed" << endl;
327                return 0;
328        }
329
330
331        //-- post processing of bsp view cells
332    int vcSize = 0;
333        int pvsSize = 0;
334
335        BspViewCellsStatistics stat;
336        mBspTree->EvaluateViewCellsStats(stat);
337        Debug << "original view cell partition:\n" << stat << endl;
338               
339        if (1) // export view cells
340        {
341                cout << "exporting initial view cells (=leaves) ... ";
342                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
343       
344                if (exporter)
345                {
346                        exporter->SetWireframe();
347                        exporter->ExportBspLeaves(*mBspTree, stat.maxPvs);
348                        //exporter->ExportBspViewCellPartition(*mBspTree, 0);
349                               
350                        if (0)
351                        {
352                                Material m;//= RandomMaterial();
353                                m.mDiffuseColor = RgbColor(0, 1, 0);
354                                exporter->SetForcedMaterial(m);
355                                exporter->SetWireframe();
356
357                                exporter->ExportGeometry(objects);
358                        }
359
360                        delete exporter;
361                }
362                cout << "finished" << endl;
363        }
364
365        cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
366               
367        long startTime = GetTime();
368
369
370        //-- merge or subdivide view cells
371        int merged = 0;
372
373        RayContainer::const_iterator rit, rit_end = rays.end();
374        vector<Ray::BspIntersection>::const_iterator iit;
375
376        int limit = min((int)rays.size(), mPostProcessSamples);
377
378        for (int i = 0; i < limit; ++ i)
379        { 
380                Ray *ray = rays[i];
381
382                // traverse leaves stored in the rays and compare and merge consecutive
383                // leaves (i.e., the neighbors in the tree)
384                if (ray->bspIntersections.size() < 2)
385                        continue;
386
387                iit = ray->bspIntersections.begin();
388
389                BspLeaf *previousLeaf = (*iit).mLeaf;
390                ++ iit;
391               
392                for (; iit != ray->bspIntersections.end(); ++ iit)
393                {
394                        BspLeaf *leaf = (*iit).mLeaf;
395
396                        if (ShouldMerge(leaf, previousLeaf))
397                        {                       
398                                MergeBspLeafViewCells(leaf, previousLeaf);
399
400                                ++ merged;
401                        }
402               
403                        previousLeaf = leaf;
404                }
405        }
406
407        //-- stats and visualizations
408        cout << "finished" << endl;
409        cout << "merged " << merged << " view cells in "
410                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
411
412        return merged;
413}
414
415int BspViewCellsManager::GetType() const
416{
417        return BSP;
418}
419
420
421void BspViewCellsManager::Visualize(const ObjectContainer &objects,
422                                                                        const RayContainer &sampleRays)
423{
424        if (!ViewCellsConstructed())
425                return;
426
427        //-- recount pvs
428        BspViewCellsStatistics vcStats;
429        mBspTree->EvaluateViewCellsStats(vcStats);
430
431        if (1) // export view cells
432        {
433                cout << "exporting view cells after merge ... ";
434                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
435
436                if (exporter)
437                {
438                        exporter->ExportBspViewCellPartition(*mBspTree, vcStats.maxPvs);
439                        //exporter->ExportBspViewCellPartition(*mBspTree, 0);
440                        delete exporter;
441                }
442
443                cout << "finished" << endl;
444        }       
445
446        //-- visualization of the BSP splits
447        bool exportSplits = false;
448                environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
449       
450        if (exportSplits)
451        {
452                cout << "exporting splits ... ";
453                ExportSplits(objects, sampleRays);
454                cout << "finished" << endl;
455        }
456
457        ExportBspPvs(objects, sampleRays);
458}
459
460
461inline bool vc_gt(ViewCell *a, ViewCell *b)
462{
463        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
464}
465
466void BspViewCellsManager::ExportSplits(const ObjectContainer &objects,
467                                                                           const RayContainer &sampleRays)
468{
469        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
470
471        if (exporter)
472        {       
473                Material m;
474                m.mDiffuseColor = RgbColor(1, 0, 0);
475                exporter->SetForcedMaterial(m);
476                exporter->SetWireframe();
477                exporter->ExportBspSplits(*mBspTree, true);
478
479                // take forced material, else big scenes cannot be viewed
480                m.mDiffuseColor = RgbColor(0, 1, 0);
481                exporter->SetForcedMaterial(m);
482                exporter->SetFilled();
483
484                exporter->ResetForcedMaterial();
485               
486                // export rays
487                if (0)
488                {
489                        RayContainer outRays;
490               
491                        int raysSize = min((int)sampleRays.size(), mVisualizationSamples);
492
493                        for (int i = 0; i < raysSize; ++ i)
494                        {
495                                // only rays piercing geometry
496                                if (!sampleRays[i]->intersections.empty())
497                                        outRays.push_back(sampleRays[i]);
498                        }
499                       
500                        // export rays
501                        exporter->ExportRays(outRays, 1000, RgbColor(1, 1, 0));
502                }
503
504                if (0)
505                        exporter->ExportGeometry(objects);
506
507                delete exporter;
508        }
509}
510
511void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
512                                                                           const RayContainer &sampleRays)
513{
514        const int leafOut = 10;
515       
516        ViewCell::NewMail();
517
518        //-- some rays for output
519        const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
520        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
521        vector<Ray *> vcRays[leafOut];
522
523        if (0)
524        {
525                //-- some random view cells and rays for output
526                vector<BspLeaf *> bspLeaves;
527
528                for (int i = 0; i < leafOut; ++ i)
529                        bspLeaves.push_back(mBspTree->GetRandomLeaf());
530               
531                for (int i = 0; i < bspLeaves.size(); ++ i)
532                {
533                        cout << "creating output for view cell " << i << " ... ";
534                        // check whether we can add the current ray to the output rays
535                        for (int k = 0; k < raysOut; ++ k)
536                        {
537                                Ray *ray = sampleRays[k];
538
539                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
540                                {
541                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
542
543                                        if (bspLeaves[i]->GetViewCell() == leaf->GetViewCell())
544                                        {
545                                                vcRays[i].push_back(ray);
546                                        }
547                                }
548                        }
549
550                        Intersectable::NewMail();
551
552                        BspViewCell *vc = dynamic_cast<BspViewCell *>(bspLeaves[i]->GetViewCell());
553
554                        //bspLeaves[j]->Mail();
555                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
556
557                        Exporter *exporter = Exporter::GetExporter(s);
558                        exporter->SetFilled();
559
560                        ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
561
562                        exporter->SetWireframe();
563                        //exporter->SetFilled();
564
565                        Material m;//= RandomMaterial();
566                        m.mDiffuseColor = RgbColor(0, 1, 0);
567                        exporter->SetForcedMaterial(m);
568
569                        if (vc->GetMesh())
570                                exporter->ExportViewCell(vc);
571                        else
572                        {
573                                PolygonContainer cell;
574                                // export view cell geometry
575                                mBspTree->ConstructGeometry(vc, cell);
576                                exporter->ExportPolygons(cell);
577                                CLEAR_CONTAINER(cell);
578                        }
579
580                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
581                                        << ", piercing rays=" << (int)vcRays[i].size() << endl;
582
583                        // export rays piercing this view cell
584                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
585
586                        m.mDiffuseColor = RgbColor(1, 0, 0);
587                        exporter->SetForcedMaterial(m);
588
589                        // exporter->SetWireframe();
590                        exporter->SetFilled();
591
592                        // output PVS of view cell
593                        for (; it != vc->GetPvs().mEntries.end(); ++ it)
594                        {
595                                Intersectable *intersect = (*it).first;
596                                if (!intersect->Mailed())
597                                {
598                                        exporter->ExportIntersectable(intersect);
599                                        intersect->Mail();
600                                }                       
601                        }
602                               
603                        // output rest of the objects
604                        if (0)
605                        {
606                                Material m;//= RandomMaterial();
607                                m.mDiffuseColor = RgbColor(0, 0, 1);
608                                exporter->SetForcedMaterial(m);
609
610                                for (int j = 0; j < objects.size(); ++ j)
611                                        if (!objects[j]->Mailed())
612                                        {
613                                                exporter->SetForcedMaterial(m);
614                                                exporter->ExportIntersectable(objects[j]);
615                                                objects[j]->Mail();
616                                        }
617                        }
618                        DEL_PTR(exporter);
619                        cout << "finished" << endl;
620                }
621        }
622        else
623        {
624                ViewCellContainer viewCells;
625
626                mBspTree->CollectViewCells(viewCells);
627                stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
628
629                int limit = min(leafOut, (int)viewCells.size());
630               
631                for (int i = 0; i < limit; ++ i)
632                {
633                        cout << "creating output for view cell " << i << " ... ";
634                       
635            Intersectable::NewMail();
636                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
637
638                        cout << "creating output for view cell " << i << " ... ";
639                        // check whether we can add the current ray to the output rays
640                        for (int k = 0; k < raysOut; ++ k)
641                        {
642                                Ray *ray = sampleRays[k];
643
644                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
645                                {
646                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
647
648                                        if (vc == leaf->GetViewCell())
649                                        {
650                                                vcRays[i].push_back(ray);
651                                        }
652                                }
653                        }
654
655                        //bspLeaves[j]->Mail();
656                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
657
658                        Exporter *exporter = Exporter::GetExporter(s);
659                       
660                        exporter->SetWireframe();
661
662                        Material m;//= RandomMaterial();
663                        m.mDiffuseColor = RgbColor(0, 1, 0);
664                        exporter->SetForcedMaterial(m);
665
666                        if (vc->GetMesh())
667                                exporter->ExportViewCell(vc);
668                        else
669                        {
670                                PolygonContainer cell;
671                                // export view cell
672                                mBspTree->ConstructGeometry(vc, cell);
673                                exporter->ExportPolygons(cell);
674                                CLEAR_CONTAINER(cell);
675                        }
676
677                       
678                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
679                                        << ", piercing rays=" << (int)vcRays[i].size() << endl;
680
681                       
682                        // export rays piercing this view cell
683                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
684       
685                        m.mDiffuseColor = RgbColor(1, 0, 0);
686                        exporter->SetForcedMaterial(m);
687
688                        ViewCellPvsMap::const_iterator it,
689                                it_end = vc->GetPvs().mEntries.end();
690
691                        // output PVS of view cell
692                        for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
693                        {
694                                Intersectable *intersect = (*it).first;
695                                if (!intersect->Mailed())
696                                {
697                                        Material m = RandomMaterial();
698                       
699                                        exporter->SetForcedMaterial(m);
700
701                                        exporter->ExportIntersectable(intersect);
702                                        intersect->Mail();
703                                }                       
704                        }
705                               
706                        DEL_PTR(exporter);
707                        cout << "finished" << endl;
708                }
709        }
710}
711
712
713bool BspViewCellsManager::MergeBspLeafViewCells(BspLeaf *front, BspLeaf *back) const
714{
715        BspViewCell *viewCell =
716                dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(), *back->GetViewCell()));
717       
718        if (!viewCell)
719                return false;
720
721        // change view cells of all leaves associated with the
722        // previous view cells
723
724        BspViewCell *fVc = front->GetViewCell();
725        BspViewCell *bVc = back->GetViewCell();
726
727        vector<BspLeaf *> fLeaves = fVc->mBspLeaves;
728        vector<BspLeaf *> bLeaves = bVc->mBspLeaves;
729
730        vector<BspLeaf *>::const_iterator it;
731       
732        for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
733        {
734                (*it)->SetViewCell(viewCell);
735                viewCell->mBspLeaves.push_back(*it);
736        }
737        for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
738        {
739                (*it)->SetViewCell(viewCell);
740                viewCell->mBspLeaves.push_back(*it);
741        }
742       
743        DEL_PTR(fVc);
744        DEL_PTR(bVc);
745
746        return true;
747}
748
749bool BspViewCellsManager::ShouldMerge(BspLeaf *front, BspLeaf *back) const
750{
751        ViewCell *fvc = front->GetViewCell();
752        ViewCell *bvc = back->GetViewCell();
753
754        if ((fvc == mBspTree->GetRootCell()) || (bvc == mBspTree->GetRootCell()) || (fvc == bvc))
755                return false;
756
757        int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
758
759        if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
760        {
761                if ((fvc->GetPvs().GetSize() < mMinPvs) ||     
762                        (bvc->GetPvs().GetSize() < mMinPvs) ||
763                        ((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
764                {
765                        return true;
766                }
767        }
768       
769        return false;
770}
771
772
773
774/**********************************************************************/
775/*                   KdViewCellsManager implementation               */
776/**********************************************************************/
777
778KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
779ViewCellsManager(),
780mKdTree(kdTree),
781mKdPvsDepth(100)
782{
783   mRenderSimulator = new KdRenderSimulator(mKdTree);
784   InitRenderSimulator();
785}
786
787int KdViewCellsManager::Construct(const ObjectContainer &objects,
788                                                                  const VssRayContainer &rays,
789                                                                  AxisAlignedBox3 *sceneBbox)
790{
791        // if view cells already constructed
792        if (ViewCellsConstructed())
793                return 0;
794
795        Debug << "Constructing bsp view cells" << endl;
796       
797        mKdTree->Construct();
798
799        return 0;
800}
801
802bool KdViewCellsManager::ViewCellsConstructed() const
803{
804        return mKdTree->GetRoot() != NULL;
805}
806
807int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
808                                                                        const RayContainer &rays)
809{
810        return 0;
811}
812
813void KdViewCellsManager::Visualize(const ObjectContainer &objects,
814                                                                   const RayContainer &sampleRays)
815{
816        if (!ViewCellsConstructed())
817                return;
818
819        const int pvsOut = min((int)objects.size(), 10);
820
821        int limit = min(mVisualizationSamples, (int)sampleRays.size());
822
823        RayContainer *rays = new RayContainer[pvsOut];
824
825        for  (int i = 0; i < limit; ++ i)
826        {
827                Ray *ray = sampleRays[i];
828
829                if (!ray->intersections.empty())
830                {
831                        // check whether we can add this to the rays
832                        for (int j = 0; j < pvsOut; j++)
833                        {
834                                if (objects[j] == ray->intersections[0].mObject)
835                                {
836                                        rays[j].push_back(ray);
837                                }
838                        }
839                }
840        }
841
842        bool exportRays = false;
843        if (exportRays) {
844                Exporter *exporter = NULL;
845                exporter = Exporter::GetExporter("sample-rays.x3d");
846                exporter->SetWireframe();
847                exporter->ExportKdTree(*mKdTree);
848               
849                for (i=0; i < pvsOut; i++)
850                        exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
851                exporter->SetFilled();
852               
853                delete exporter;
854        }
855
856        for (int k=0; k < pvsOut; k++)
857        {
858                Intersectable *object = objects[k];
859                char s[64];     
860                sprintf(s, "sample-pvs%04d.x3d", k);
861
862                Exporter *exporter = Exporter::GetExporter(s);
863                exporter->SetWireframe();
864         
865        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
866                Intersectable::NewMail();
867                       
868                // avoid adding the object to the list
869                object->Mail();
870                ObjectContainer visibleObjects;
871           
872                for (; i != object->mKdPvs.mEntries.end(); i++)
873                {
874                         KdNode *node = (*i).first;
875                         exporter->ExportBox(mKdTree->GetBox(node));
876                         mKdTree->CollectObjects(node, visibleObjects);
877                }
878
879                exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
880                exporter->SetFilled();
881                 
882                for (int j = 0; j < visibleObjects.size(); j++)
883                        exporter->ExportIntersectable(visibleObjects[j]);
884                 
885                Material m;
886                m.mDiffuseColor = RgbColor(1, 0, 0);
887                exporter->SetForcedMaterial(m);
888                exporter->ExportIntersectable(object);
889         
890                delete exporter;
891        }
892        DEL_PTR(rays);
893}
894
895int KdViewCellsManager::GetType() const
896{
897        return ViewCellsManager::KD;
898}
899
900int KdViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
901{
902        // view cells not yet constructed
903        if (!ViewCellsConstructed())
904                return 0;
905
906        if (castRay)
907                mKdTree->CastRay(ray);
908
909        if (ray.kdLeaves.empty())
910                return 0;
911
912        Intersectable *tObject =
913                !ray.intersections.empty() ? ray.intersections[0].mObject : NULL;
914
915        Intersectable *sObject =
916                ray.sourceObject.mObject;
917
918        int contributingSamples = 0;
919       
920        int objects = 0;
921
922        if (sObject)
923                objects++;
924        if (tObject)
925                objects++;
926
927        for (int j = 1; j < ((int)ray.kdLeaves.size() - 1); ++ j)
928        {
929                ray.kdLeaves[j]->AddPassingRay2(ray, objects,
930                                                                                (int)ray.kdLeaves.size());
931        }
932
933        if (!objects)
934                return 0;
935       
936        for (int j=0; j < ray.kdLeaves.size(); j++)
937        {
938                KdNode *node = GetNodeForPvs(ray.kdLeaves[j]);
939
940                if (sObject)
941                        contributingSamples += sObject->mKdPvs.AddSample(node);
942                if (tObject)
943                        contributingSamples += tObject->mKdPvs.AddSample(node);
944        }
945
946        return contributingSamples;
947}
948
949
950KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)
951{
952        KdNode *node = leaf;
953
954        while (node->mParent && node->mDepth > mKdPvsDepth)
955                node = node->mParent;
956        return node;
957}
958
959
960
961/**********************************************************************/
962/*                   VspKdViewCellsManager implementation             */
963/**********************************************************************/
964
965VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree, int constructionSamples):
966ViewCellsManager(constructionSamples),
967mVspKdTree(vspKdTree)
968{
969   mRenderSimulator = NULL; // TODO: new VspKdRenderSimulator(vspKdTree);
970   InitRenderSimulator();
971}
972
973int VspKdViewCellsManager::Construct(const ObjectContainer &objects,
974                                                                         const VssRayContainer &rays,
975                                                                         AxisAlignedBox3 *sceneBbox)
976{
977        // if view cells already constructed
978        if (ViewCellsConstructed())
979                return 0;
980
981        mVspKdTree->Construct(rays, sceneBbox);
982        return 0;
983}
984
985bool VspKdViewCellsManager::ViewCellsConstructed() const
986{
987        return mVspKdTree->GetRoot() != NULL;
988}
989
990int VspKdViewCellsManager::ComputeSampleContributions(Ray &ray, const bool castRay)
991{
992        // view cells not yet constructed
993        if (!ViewCellsConstructed())
994                return 0;
995
996        //if (castRay) // TODO
997
998        int sampleContributions = 0;
999
1000/*
1001    for (int i = 0; i < (int)rays.size(); ++ i)
1002        {
1003                Ray *ray = rays[i];
1004
1005                mBspTree->CastRay(*ray);
1006                       
1007                Intersectable *term =
1008                        !ray->intersections.empty() ? ray->intersections[0].mObject : NULL
1009                        ;
1010                sampleContributions +=
1011                        AddSampleContributions(*ray, ray->sourceObject.mObject, term);
1012                       
1013        }
1014*/
1015        return sampleContributions;
1016}
1017
1018int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
1019                                                                           const RayContainer &rays)
1020{
1021        if (!ViewCellsConstructed())
1022                return 0;
1023
1024        return 0;
1025}
1026
1027void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
1028                                                                          const RayContainer &sampleRays)
1029{
1030        if (!ViewCellsConstructed())
1031                return;
1032
1033        if (1)
1034        {
1035                Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
1036                //exporter->SetWireframe();
1037                exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
1038
1039                Debug << "average PVS size: " << mVspKdTree->GetAvgPvsSize() << endl;
1040
1041                if (0)
1042                        exporter->ExportGeometry(objects);
1043
1044                bool exportRays = true;
1045
1046                if (exportRays)
1047                {
1048                        int raysSize = 2000;
1049                        float prob = raysSize / (float)sampleRays.size();
1050               
1051                        exporter->SetWireframe();
1052                       
1053                        RayContainer rays;
1054               
1055                        for (int i = 0; i < sampleRays.size(); ++ i)
1056                        {
1057                                if (RandomValue(0,1) < prob)
1058                                        rays.push_back(sampleRays[i]);
1059                        }
1060
1061                        exporter->ExportRays(rays, 1000, RgbColor(1, 0, 0));
1062                }
1063
1064                delete exporter;
1065        }
1066
1067        if (1)
1068        {
1069                vector<VspKdTreeLeaf *> leafContainer;
1070
1071                mVspKdTree->CollectLeaves(leafContainer);
1072
1073                for (int i = 0; i < 10; ++ i)
1074                {
1075                        char s[64];
1076                        sprintf(s, "vsp_leaves%04d.x3d", i);
1077                        Exporter *exporter = Exporter::GetExporter(s);
1078
1079                        // export geometry
1080                        VspKdTreeLeaf *leaf = leafContainer[Random((int)leafContainer.size())];
1081                        AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
1082
1083                        Material m;
1084                        m.mDiffuseColor = RgbColor(0, 1, 1);
1085                        exporter->SetForcedMaterial(m);
1086                        exporter->SetWireframe();
1087                        exporter->ExportBox(box);
1088
1089                        //-- export stored rays
1090                        VssRayContainer vssRays;
1091                        leaf->GetRays(vssRays);
1092
1093                        VssRayContainer rays;
1094                        VssRayContainer::const_iterator it, it_end = vssRays.end();
1095
1096                        for (it = vssRays.begin(); it != it_end; ++ it)
1097                        {
1098                                //if (!(*it)->mOriginObject && !(*it)->mTerminationObject)
1099                                        rays.push_back(*it);
1100
1101                                //if (!(*it)->mOriginObject && !(*it)->mTerminationObject)
1102                                //      Debug << "ERR: " << (*it)->mOrigin << " " << (*it)->mTermination << endl;
1103                        }
1104
1105                        exporter->ExportRays(rays, RgbColor(1, 0, 0));
1106
1107                        //-- export stored PVS
1108                       
1109                        ObjectContainer pvsObj;
1110                        leaf->ExtractPvs(pvsObj);
1111                               
1112                        exporter->ExportGeometry(pvsObj);
1113
1114                        delete exporter;
1115                }                       
1116        }
1117}
1118
1119int VspKdViewCellsManager::GetType() const
1120{
1121        return VSP_KD;
1122}
Note: See TracBrowser for help on using the repository browser.