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

Revision 1379, 21.5 KB checked in by mattausch, 18 years ago (diff)

fixed sah for objeect partition
loader for single triangles also for x3d

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