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

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