source: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp @ 1416

Revision 1416, 21.9 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include <stack>
2#include <time.h>
3#include <iomanip>
4
5#include "ViewCell.h"
6#include "Plane3.h"
7#include "HierarchyManager.h"
8#include "Mesh.h"
9#include "common.h"
10#include "Environment.h"
11#include "Polygon3.h"
12#include "Ray.h"
13#include "AxisAlignedBox3.h"
14#include "Exporter.h"
15#include "Plane3.h"
16#include "ViewCellsManager.h"
17#include "Beam.h"
18#include "KdTree.h"
19#include "IntersectableWrapper.h"
20#include "VspTree.h"
21#include "OspTree.h"
22#include "BvHierarchy.h"
23
24
25namespace GtpVisibilityPreprocessor {
26
27
28#define USE_FIXEDPOINT_T 0
29
30
31/*******************************************************************/
32/*              class HierarchyManager implementation              */
33/*******************************************************************/
34
35
36HierarchyManager::HierarchyManager(VspTree *vspTree,
37                                                                   const int objectSpaceSubdivisionType):
38mObjectSpaceSubdivisionType(objectSpaceSubdivisionType),
39mVspTree(vspTree),
40mOspTree(NULL),
41mBvHierarchy(NULL)
42{
43        switch(mObjectSpaceSubdivisionType)
44        {
45        case KD_BASED_OBJ_SUBDIV:
46                mOspTree = new OspTree();
47                mOspTree->mVspTree = mVspTree;
48                mOspTree->mHierarchyManager = this;
49                break;
50        case BV_BASED_OBJ_SUBDIV:
51        mBvHierarchy = new BvHierarchy();
52                mBvHierarchy->mHierarchyManager = this;
53                break;
54        default:
55                break;
56        }
57
58        // hierarchy manager links view space partition and object space partition
59        mVspTree->mHierarchyManager = this;
60       
61        ParseEnvironment();
62}
63
64
65HierarchyManager::HierarchyManager(VspTree *vspTree, KdTree *kdTree):
66mObjectSpaceSubdivisionType(KD_BASED_OBJ_SUBDIV),
67mVspTree(vspTree),
68mBvHierarchy(NULL)
69{
70        mOspTree = new OspTree(*kdTree);
71        mOspTree->mVspTree = mVspTree;
72
73        mVspTree->mHierarchyManager = this;
74
75        ParseEnvironment();
76}
77
78
79void HierarchyManager::ParseEnvironment()
80{
81        char subdivisionStatsLog[100];
82        Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats",
83                subdivisionStatsLog);
84        mSubdivisionStats.open(subdivisionStatsLog);
85
86        Environment::GetSingleton()->GetFloatValue(
87                "Hierarchy.Termination.minGlobalCostRatio", mTermMinGlobalCostRatio);
88        Environment::GetSingleton()->GetIntValue(
89                "Hierarchy.Termination.globalCostMissTolerance", mTermGlobalCostMissTolerance);
90
91        Environment::GetSingleton()->GetBoolValue(
92                "Hierarchy.Construction.startWithObjectSpace", mStartWithObjectSpace);
93
94        Environment::GetSingleton()->GetIntValue(
95                "Hierarchy.Termination.maxLeaves", mTermMaxLeaves);
96
97        Environment::GetSingleton()->GetIntValue(
98                "Hierarchy.Construction.type", mConstructionType);
99
100        Environment::GetSingleton()->GetIntValue(
101                "Hierarchy.Construction.minDepthForOsp", mMinDepthForObjectSpaceSubdivion);
102
103        Environment::GetSingleton()->GetIntValue(
104                "Hierarchy.Construction.minDepthForVsp", mMinDepthForViewSpaceSubdivion);
105       
106        Environment::GetSingleton()->GetBoolValue(
107                "Hierarchy.Construction.repairQueue", mRepairQueue);
108
109        Debug << "******** Hierachy Manager Parameters ***********" << endl;
110        Debug << "max leaves: " << mTermMaxLeaves << endl;
111        Debug << "min global cost ratio: " << mTermMinGlobalCostRatio << endl;
112        Debug << "global cost miss tolerance: " << mTermGlobalCostMissTolerance << endl;
113        Debug << "construction type: " << mConstructionType << endl;
114        Debug << "min depth for object space subdivision: " << mMinDepthForObjectSpaceSubdivion << endl;
115        Debug << "repair queue: " << mRepairQueue << endl;
116}
117
118
119HierarchyManager::~HierarchyManager()
120{
121        DEL_PTR(mOspTree);
122        //DEL_PTR(mVspTree);
123        DEL_PTR(mBvHierarchy);
124}
125
126
127int HierarchyManager::GetObjectSpaceSubdivisionType() const
128{
129        return mObjectSpaceSubdivisionType;
130}
131
132
133int HierarchyManager::GetViewSpaceSubdivisionType() const
134{
135        return mViewSpaceSubdivisionType;
136}
137
138
139void HierarchyManager::SetViewCellsManager(ViewCellsManager *vcm)
140{
141        mVspTree->SetViewCellsManager(vcm);
142
143        if (mOspTree)
144                mOspTree->SetViewCellsManager(vcm);
145        else if (mBvHierarchy)
146                mBvHierarchy->SetViewCellsManager(vcm);
147}
148
149
150void HierarchyManager::SetViewCellsTree(ViewCellsTree *vcTree)
151{
152        mVspTree->SetViewCellsTree(vcTree);
153}
154
155
156VspTree *HierarchyManager::GetVspTree()
157{
158        return mVspTree;
159}
160
161
162AxisAlignedBox3 HierarchyManager::GetViewSpaceBox() const
163{
164        return mVspTree->mBoundingBox;
165}
166
167
168AxisAlignedBox3 HierarchyManager::GetObjectSpaceBox() const
169{
170        switch (mObjectSpaceSubdivisionType)
171        {
172        case KD_BASED_OBJ_SUBDIV:
173                return mOspTree->mBoundingBox;
174        case BV_BASED_OBJ_SUBDIV:
175                return mBvHierarchy->mBoundingBox;
176        default:
177                // empty box
178                return AxisAlignedBox3();
179        }
180}
181
182
183SubdivisionCandidate *HierarchyManager::NextSubdivisionCandidate()
184{
185        SubdivisionCandidate *splitCandidate = mTQueue.Top();
186        mTQueue.Pop();
187
188        return splitCandidate;
189}
190
191
192void HierarchyManager::EvalSubdivisionStats(const SubdivisionCandidate &tData)
193{
194        const float costDecr = tData.GetRenderCostDecrease();
195
196        switch (mObjectSpaceSubdivisionType)
197        {
198        case KD_BASED_OBJ_SUBDIV:
199                AddSubdivisionStats(mOspTree->mOspStats.Leaves() + mVspTree->mVspStats.Leaves(),
200                                                        costDecr,
201                                                        mTotalCost
202                                                        );
203                break;
204        case BV_BASED_OBJ_SUBDIV:
205                AddSubdivisionStats(mBvHierarchy->mBvhStats.Leaves() + mVspTree->mVspStats.Leaves(),
206                                                        costDecr,
207                                                        mTotalCost
208                                                        );
209                break;
210        default:
211                AddSubdivisionStats(mVspTree->mVspStats.Leaves(),
212                                                        costDecr,
213                                                        mTotalCost
214                                                        );
215                break;
216        }
217}
218
219
220void HierarchyManager::AddSubdivisionStats(const int splits,
221                                                                                   const float renderCostDecr,
222                                                                                   const float totalRenderCost)
223{
224        mSubdivisionStats
225                        << "#Splits\n" << splits << endl
226                        << "#RenderCostDecrease\n" << renderCostDecr << endl
227                        << "#TotalRenderCost\n" << totalRenderCost << endl;
228                        //<< "#AvgRenderCost\n" << avgRenderCost << endl;
229}
230
231
232bool HierarchyManager::GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const
233{
234        return (0
235                || (mHierarchyStats.Leaves() >= mTermMaxLeaves)
236                //|| (mGlobalCostMisses >= mTermGlobalCostMissTolerance)
237                ||      candidate->GlobalTerminationCriteriaMet()
238                );
239}
240
241
242void HierarchyManager::Construct(const VssRayContainer &sampleRays,
243                                                                 const ObjectContainer &objects,
244                                                                 AxisAlignedBox3 *forcedViewSpace)
245{
246        mHierarchyStats.Reset();
247        mHierarchyStats.Start();
248       
249        mTotalCost = (float)objects.size();
250        Debug << "setting total cost to " << mTotalCost << endl;
251
252        const long startTime = GetTime();
253        cout << "Constructing view space / object space tree ... \n";
254       
255        // compute view space bounding box
256        mVspTree->ComputeBoundingBox(sampleRays, forcedViewSpace);
257
258        // use objects for evaluating vsp tree construction in the first levels
259        // of the subdivision
260        mSavedObjectSpaceSubdivisionType = mObjectSpaceSubdivisionType;
261        mObjectSpaceSubdivisionType = NO_OBJ_SUBDIV;
262
263        mSavedViewSpaceSubdivisionType = mViewSpaceSubdivisionType;
264        mViewSpaceSubdivisionType = NO_VIEWSPACE_SUBDIV;
265
266        // start with view space subdivison: prepare vsp tree for traversal
267        if (StartViewSpaceSubdivision())
268        {
269                mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType;
270                PrepareViewSpaceSubdivision(sampleRays, objects);
271        }
272       
273        // start object space subdivision immediately?
274        if (StartObjectSpaceSubdivision())
275        {
276                mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;
277                PrepareObjectSpaceSubdivision(sampleRays, objects);
278        }
279
280        // process object space candidates
281        RunConstruction(sampleRays, objects, forcedViewSpace);
282       
283        cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
284
285        mHierarchyStats.Stop();
286        mVspTree->mVspStats.Stop();
287        FinishObjectSpaceSubdivision();
288
289        mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;
290        mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType;
291}
292
293
294void HierarchyManager::PrepareViewSpaceSubdivision(const VssRayContainer &sampleRays,
295                                                                                                   const ObjectContainer &objects)
296{
297        cout << "starting view space hierarchy construction ... " << endl;
298
299        RayInfoContainer *viewSpaceRays = new RayInfoContainer();
300        SubdivisionCandidate *vsc =
301                mVspTree->PrepareConstruction(sampleRays, *viewSpaceRays);
302
303        mTQueue.Push(vsc);
304}
305
306
307void HierarchyManager::PrepareObjectSpaceSubdivision(const VssRayContainer &sampleRays,
308                                                                                                         const ObjectContainer &objects)
309{
310        if (mObjectSpaceSubdivisionType == KD_BASED_OBJ_SUBDIV)
311        {
312                PrepareOspTree(sampleRays, objects);
313        }
314        else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV)
315        {
316                PrepareBvHierarchy(sampleRays, objects);
317        }
318}
319
320
321void HierarchyManager::PrepareBvHierarchy(const VssRayContainer &sampleRays,
322                                                                                  const ObjectContainer &objects)
323
324{
325        cout << "starting bv hierarchy construction ... " << endl;
326        mBvHierarchy->CreateRoot(objects);
327
328        // compute first candidate
329        SubdivisionCandidate *sc =
330                mBvHierarchy->PrepareConstruction(sampleRays, objects);
331
332        mTotalCost = mBvHierarchy->mTotalCost;
333        Debug << "\nreseting cost, new total cost: " << mTotalCost << endl;
334
335    mTQueue.Push(sc);
336}
337
338
339void HierarchyManager::PrepareOspTree(const VssRayContainer &sampleRays,
340                                                                          const ObjectContainer &objects)
341{
342        cout << "starting osp tree construction ... " << endl;
343
344        RayInfoContainer *objectSpaceRays = new RayInfoContainer();
345
346        // start with one big kd cell - all objects can be seen from everywhere
347        // note: only true for view space = object space
348
349        // compute first candidate
350        SubdivisionCandidate *osc =
351                mOspTree->PrepareConstruction(sampleRays, objects, *objectSpaceRays);
352
353        mTotalCost = mOspTree->mTotalCost;
354        Debug << "reseting cost, new total cost: " << mTotalCost << endl;
355       
356    mTQueue.Push(osc);
357}
358
359
360bool HierarchyManager::ApplySubdivisionCandidate(SubdivisionCandidate *sc)
361{
362        const bool globalTerminationCriteriaMet = GlobalTerminationCriteriaMet(sc);
363        const bool vspSplit = (sc->Type() == SubdivisionCandidate::VIEW_SPACE);
364
365        if (vspSplit)
366        {
367                VspNode *n = mVspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
368
369                if (n->IsLeaf()) // local or global termination criteria failed
370                        return false;
371        }
372        else
373        {
374                if (mObjectSpaceSubdivisionType == KD_BASED_OBJ_SUBDIV)
375                {
376                        KdNode *n = mOspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
377                        // local or global termination criteria failed
378                        if (n->IsLeaf())
379                                return false;
380                }
381                else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV)
382                {
383                        BvhNode *n = mBvHierarchy->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
384                        // local or global termination criteria failed
385                        if (n->IsLeaf())
386                                return false;
387                }
388        }
389
390        return true;
391}
392
393
394int HierarchyManager::GetObjectSpaceSubdivisionDepth() const
395{
396        int maxDepth = 0;
397
398        if (mObjectSpaceSubdivisionType == KD_BASED_OBJ_SUBDIV)
399        {
400                maxDepth = mOspTree->mOspStats.maxDepth;
401        }
402        else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV)
403        {
404                maxDepth = mBvHierarchy->mBvhStats.maxDepth;
405        }
406
407        return maxDepth;
408}
409
410
411bool HierarchyManager::StartObjectSpaceSubdivision() const
412{
413        // view space construction already started
414        if (ObjectSpaceSubdivisionConstructed())
415                return false;
416
417        // start immediately with object space subdivision?
418        if (mStartWithObjectSpace)
419                return true;
420
421        // is the queue empty again?
422        if (ViewSpaceSubdivisionConstructed() && mTQueue.Empty())
423                return true;
424
425        // has the depth for subdivision been reached?
426        return
427                ((mConstructionType == INTERLEAVED) &&
428                 (mMinDepthForObjectSpaceSubdivion <= mVspTree->mVspStats.maxDepth));
429}
430
431
432bool HierarchyManager::StartViewSpaceSubdivision() const
433{
434        // view space construction already started
435        if (ViewSpaceSubdivisionConstructed())
436                return false;
437
438        // start immediately with view space subdivision?
439        if (!mStartWithObjectSpace)
440                return true;
441
442        // is the queue empty again?
443        if (ObjectSpaceSubdivisionConstructed() && mTQueue.Empty())
444                return true;
445
446        // has the depth for subdivision been reached?
447        return
448                ((mConstructionType == INTERLEAVED) &&
449                 (mMinDepthForViewSpaceSubdivion <= GetObjectSpaceSubdivisionDepth()));
450}
451
452
453void HierarchyManager::RunConstruction(const VssRayContainer &sampleRays,
454                                                                           const ObjectContainer &objects,
455                                                                           AxisAlignedBox3 *forcedViewSpace)
456{
457        mHierarchyStats.nodes = 0;
458        mGlobalCostMisses = 0;
459
460        int i = 0;
461        while (!FinishedConstruction())
462        {
463                mCurrentCandidate = NextSubdivisionCandidate();   
464                mTotalCost -= mCurrentCandidate->GetRenderCostDecrease();
465
466                // cost ratio of cost decrease / totalCost
467                const float costRatio = mCurrentCandidate->GetRenderCostDecrease() / mTotalCost;
468
469                //Debug << "ratio: " << costRatio << " min ratio: " << mTermMinGlobalCostRatio << endl;
470                if (costRatio < mTermMinGlobalCostRatio)
471                {
472                        ++ mGlobalCostMisses;
473                }
474               
475                ///////////////////
476                //-- subdivide leaf node
477
478                if (ApplySubdivisionCandidate(mCurrentCandidate))
479                {
480                        cout << mCurrentCandidate->Type() << " ";
481                        if (0) cout << "subdividing candidate " << ++ i << " of type " << mCurrentCandidate->Type() << endl;
482                        mHierarchyStats.nodes += 2;
483
484                        // subdivision successful
485                        EvalSubdivisionStats(*mCurrentCandidate);
486               
487                        // reevaluate candidates affected by the split for view space splits,
488                        // this would be object space splits and other way round
489                        if (mRepairQueue) RepairQueue();
490                }
491
492                // we use objects for evaluating vsp tree construction until
493                // a certain depth once a certain depth existiert ...
494                if (StartObjectSpaceSubdivision())
495                {
496                        mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;
497
498                        cout << "\nstarting object space subdivision at depth "
499                                 << mVspTree->mVspStats.maxDepth << " ("
500                                 << mMinDepthForObjectSpaceSubdivion << ") " << endl;
501
502                        PrepareObjectSpaceSubdivision(sampleRays, objects);
503
504                        cout << "reseting queue ... ";
505                        ResetQueue();
506                        cout << "finished" << endl;
507                }
508
509                if (StartViewSpaceSubdivision())
510                {
511                        mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType;
512
513                        cout << "\nstarting view space subdivision at depth "
514                                 << GetObjectSpaceSubdivisionDepth() << " ("
515                                 << mMinDepthForViewSpaceSubdivion << ") " << endl;
516
517                        PrepareViewSpaceSubdivision(sampleRays, objects);
518
519                        cout << "reseting queue ... ";
520                        ResetQueue();
521                        cout << "finished" << endl;
522                }
523
524                DEL_PTR(mCurrentCandidate);
525        }
526}
527
528
529bool HierarchyManager::FinishedConstruction() const
530{
531        return mTQueue.Empty();
532}
533
534
535bool HierarchyManager::ObjectSpaceSubdivisionConstructed() const
536{
537        switch (mObjectSpaceSubdivisionType)
538        {
539        case KD_BASED_OBJ_SUBDIV:
540                return mOspTree && mOspTree->GetRoot();
541        case BV_BASED_OBJ_SUBDIV:
542                return mBvHierarchy && mBvHierarchy->GetRoot();
543        default:
544        return false;
545        }
546}
547
548
549bool HierarchyManager::ViewSpaceSubdivisionConstructed() const
550{
551        return mVspTree && mVspTree->GetRoot();
552}
553
554
555void HierarchyManager::CollectObjectSpaceDirtyList(SubdivisionCandidateContainer &dirtyList)
556{
557        switch (mObjectSpaceSubdivisionType)
558        {
559        case KD_BASED_OBJ_SUBDIV:
560                {
561                        OspTree::OspSubdivisionCandidate *sc =
562                                dynamic_cast<OspTree::OspSubdivisionCandidate *>(mCurrentCandidate);
563
564                        mOspTree->CollectDirtyCandidates(sc, dirtyList);
565                        break;
566                }
567        case BV_BASED_OBJ_SUBDIV:
568                {
569                        BvHierarchy::BvhSubdivisionCandidate *sc =
570                                dynamic_cast<BvHierarchy::BvhSubdivisionCandidate *>(mCurrentCandidate);
571
572                        mBvHierarchy->CollectDirtyCandidates(sc, dirtyList);
573                        break;
574                }
575        default:
576                break;
577        }
578}
579
580
581void HierarchyManager::CollectViewSpaceDirtyList(SubdivisionCandidateContainer &dirtyList)
582{
583        VspTree::VspSubdivisionCandidate *sc =
584                dynamic_cast<VspTree::VspSubdivisionCandidate *>(mCurrentCandidate);
585
586        mVspTree->CollectDirtyCandidates(sc, dirtyList);
587}
588
589
590void HierarchyManager::CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList)
591{
592        // we have either a object space or view space split
593        if (mCurrentCandidate->Type() == SubdivisionCandidate::VIEW_SPACE)
594        {
595                CollectViewSpaceDirtyList(dirtyList);
596        }
597        else // object space split
598        {
599                CollectObjectSpaceDirtyList(dirtyList);
600        }
601}
602
603
604void HierarchyManager::RepairQueue()
605{
606        // for each update of the view space partition:
607        // the candidates from object space partition which
608        // have been afected by the view space split (the kd split candidates
609        // which saw the view cell which was split) must be reevaluated
610        // (maybe not locally, just reinsert them into the queue)
611        //
612        // vice versa for the view cells
613        // for each update of the object space partition
614        // reevaluate split candidate for view cells which saw the split kd cell
615        //
616        // the priority queue update can be solved by implementing a binary heap
617        // (explicit data structure, binary tree)
618        // *) inserting and removal is efficient
619        // *) search is not efficient => store queue position with each
620        // split candidate
621
622        // collect list of "dirty" candidates
623        long startTime = GetTime();
624   
625        vector<SubdivisionCandidate *> dirtyList;
626        CollectDirtyCandidates(dirtyList);
627        if (0) cout << "repairing " << (int)dirtyList.size() << " candidates ... ";
628       
629        /////////////////////////////////
630        //-- reevaluate the dirty list
631
632        SubdivisionCandidateContainer::const_iterator sit, sit_end = dirtyList.end();
633       
634        for (sit = dirtyList.begin(); sit != sit_end; ++ sit)
635        {
636                SubdivisionCandidate* sc = *sit;
637                const float rcd = sc->GetRenderCostDecrease();
638               
639                mTQueue.Erase(sc); // erase from queue
640                sc->EvalPriority(); // reevaluate
641               
642                /*
643                Debug << "candidate " << sc << " reevaluated\n"
644                          << "render cost decrease diff " <<  rcd - sc->GetRenderCostDecrease()
645                          << " old: " << rcd << " new " << sc->GetRenderCostDecrease() << endl;*/
646                if (0)
647                {
648                        const float rcDiff =  rcd - sc->GetRenderCostDecrease();
649                        mTotalCost += rcDiff;
650                }
651                mTQueue.Push(sc); // reinsert
652        }
653
654        long endTime = GetTime();
655        Real timeDiff = TimeDiff(startTime, endTime);
656
657        mHierarchyStats.repairTime += timeDiff;
658
659        if (0) cout << "finished in " << timeDiff * 1e-3f << " secs" << endl;
660}
661
662
663void HierarchyManager::ResetQueue()
664{
665        SubdivisionCandidateContainer mCandidateBuffer;
666
667        // remove from queue
668        while (!mTQueue.Empty())
669        {
670                SubdivisionCandidate *candidate = NextSubdivisionCandidate();
671                candidate->EvalPriority(); // reevaluate
672                cout << ".";
673                mCandidateBuffer.push_back(candidate);
674        }
675
676        // put back into queue
677        SubdivisionCandidateContainer::const_iterator sit, sit_end = mCandidateBuffer.end();
678    for (sit = mCandidateBuffer.begin(); sit != sit_end; ++ sit)
679        {cout << ":";
680                mTQueue.Push(*sit);
681        }
682}
683
684
685void HierarchyManager::ExportObjectSpaceHierarchy(OUT_STREAM &stream)
686{
687        // the type of the view cells hierarchy
688        switch (mObjectSpaceSubdivisionType)
689        {
690        case KD_BASED_OBJ_SUBDIV:
691                stream << "<ObjectSpaceHierarchy type=\"osp\">" << endl;
692                mOspTree->Export(stream);
693                stream << endl << "</ObjectSpaceHierarchy>" << endl;
694                break;         
695        case BV_BASED_OBJ_SUBDIV:
696                stream << "<ObjectSpaceHierarchy type=\"bvh\">" << endl;
697                mBvHierarchy->Export(stream);
698                stream << endl << "</ObjectSpaceHierarchy>" << endl;
699                break;
700        }
701}
702
703
704bool HierarchyManager::AddSampleToPvs(Intersectable *obj,
705                                                                          const Vector3 &hitPoint,
706                                                                          ViewCell *vc,
707                                                                          const float pdf,
708                                                                          float &contribution) const
709{
710        if (!obj) return false;
711
712        switch (mObjectSpaceSubdivisionType)
713        {
714        case NO_OBJ_SUBDIV:
715                // potentially visible objects
716                return vc->AddPvsSample(obj, pdf, contribution);
717        case KD_BASED_OBJ_SUBDIV:
718                {
719                        // potentially visible kd cells
720                        KdLeaf *leaf = mOspTree->GetLeaf(hitPoint/*ray->mOriginNode*/);
721                        return mOspTree->AddLeafToPvs(leaf, vc, pdf, contribution);
722                }
723        case BV_BASED_OBJ_SUBDIV:
724                {
725                        BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
726                        BvhIntersectable *bvhObj = mBvHierarchy->GetOrCreateBvhIntersectable(leaf);
727                       
728                        return vc->AddPvsSample(bvhObj, pdf, contribution);
729                }
730        default:
731                return false;
732        }
733}
734
735
736void HierarchyManager::PrintHierarchyStatistics(ofstream &stream) const
737{
738        stream << mHierarchyStats << endl;
739
740        stream << "\nview space:" << endl << endl;
741        stream << mVspTree->GetStatistics() << endl;
742        stream << "\nobject space:" << endl << endl;
743
744        switch (mObjectSpaceSubdivisionType)
745        {
746        case KD_BASED_OBJ_SUBDIV:
747                {
748                        stream << mOspTree->GetStatistics() << endl;
749                        break;
750                }
751        case BV_BASED_OBJ_SUBDIV:
752                {
753                        stream << mBvHierarchy->GetStatistics() << endl;
754                        break;
755                }
756        default:
757                break;
758        }
759}
760
761
762void HierarchyManager::ExportObjectSpaceHierarchy(Exporter *exporter,
763                                                                                                  const ObjectContainer &objects,
764                                                                                                  const AxisAlignedBox3 *bbox) const
765{
766        switch (mObjectSpaceSubdivisionType)
767        {
768        case KD_BASED_OBJ_SUBDIV:
769                {
770                        ExportOspTree(exporter, objects);
771                        break;
772                }
773        case BV_BASED_OBJ_SUBDIV:
774                {
775                        ExportBvHierarchy(exporter, objects, bbox);
776                        break;
777                }
778        default:
779                break;
780        }
781}
782
783
784void HierarchyManager::ExportBvHierarchy(Exporter *exporter,
785                                                                                 const ObjectContainer &objects,
786                                                                                 const AxisAlignedBox3 *bbox) const
787{
788        exporter->SetWireframe();
789        exporter->ExportBvHierarchy(*mBvHierarchy, 0, bbox);
790}
791
792
793void HierarchyManager::ExportOspTree(Exporter *exporter,
794                                                                         const ObjectContainer &objects) const
795{
796        if (0) exporter->ExportGeometry(objects);
797                       
798        exporter->SetWireframe();
799        exporter->ExportOspTree(*mOspTree, 0);
800}
801
802
803void HierarchyStatistics::Print(ostream &app) const
804{
805        app << "=========== Hierarchy statistics ===============\n";
806
807        app << setprecision(4);
808
809        app << "#N_CTIME  ( Construction time [s] )\n" << Time() << " \n";
810       
811        app << "#N_RTIME  ( Repair time [s] )\n" << repairTime * 1e-3f << " \n";
812
813        app << "#N_NODES ( Number of nodes )\n" << nodes << "\n";
814
815        app << "#N_INTERIORS ( Number of interior nodes )\n" << Interior() << "\n";
816
817        app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n";
818
819        app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl;
820       
821        app << "========== END OF Hierarchy statistics ==========\n";
822}
823
824
825void HierarchyManager::FinishObjectSpaceSubdivision() const
826{
827        switch (mObjectSpaceSubdivisionType)
828        {
829        case KD_BASED_OBJ_SUBDIV:
830                {
831                        mOspTree->mOspStats.Stop();
832                        break;
833                }
834        case BV_BASED_OBJ_SUBDIV:
835                {
836                        mBvHierarchy->mBvhStats.Stop();
837                        break;
838                }
839        default:
840                break;
841        }
842}
843
844}
Note: See TracBrowser for help on using the repository browser.