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

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