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

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