source: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h @ 2124

Revision 2124, 18.4 KB checked in by mattausch, 18 years ago (diff)
RevLine 
[1237]1#ifndef _HierarchyManager_H__
2#define _HierarchyManager_H__
3
4#include <stack>
5
6#include "Mesh.h"
7#include "Containers.h"
8#include "Statistics.h"
9#include "VssRay.h"
10#include "RayInfo.h"
11#include "gzstream.h"
[1239]12#include "SubdivisionCandidate.h"
[1237]13
14
15
16namespace GtpVisibilityPreprocessor {
17
18class ViewCellLeaf;
19class OspTree;
20class VspTree;
21class Plane3;
22class AxisAlignedBox3;
23class Ray;
24class ViewCellsStatistics;
25class ViewCellsManager;
26class MergeCandidate;
27class Beam;
28class ViewCellsTree;
29class Environment;
30class VspInterior;
31class VspLeaf;
32class VspNode;
33class KdNode;
34class KdInterior;
35class KdLeaf;
36class OspTree;
37class KdIntersectable;
38class KdTree;
39class VspTree;
40class KdTreeStatistics;
[1259]41class BvHierarchy;
[1287]42class Exporter;
[1667]43class ViewCellsParseHandlers;
[2094]44class TraversalTree;
[2116]45class ObjectPvs;
[1237]46
[1667]47
[1649]48#define COUNT_ORIGIN_OBJECTS 1
[1899]49#define USE_AVGRAYCONTRI 1
[1911]50
51
[1551]52/** View space / object space hierarchy statistics.
[1288]53*/
54class HierarchyStatistics: public StatisticsBase
55{
56public:
[1576]57        /// total number of entries in the pvs
[1624]58        int mPvsEntries;
[1640]59        /// storage cost in MB
60        float mMemory;
[1288]61        /// total number of nodes
[1624]62        int mNodes;
[1288]63        /// maximal reached depth
[1624]64        int mMaxDepth;
[1288]65        /// accumulated depth
[1624]66        int mAccumDepth;
[1449]67        /// time spent for queue repair
[1624]68        float mRepairTime;
69
[1449]70        // global cost ratio violations
71        int mGlobalCostMisses;
[1624]72        /// total cost of subdivision
73        float mTotalCost;
74        /// render cost decrease of subdivision
75        float mRenderCostDecrease;
[1313]76
[1288]77        // Constructor
78        HierarchyStatistics()
79        {
80                Reset();
81        }
82
[1624]83        int Nodes() const {return mNodes;}
[1640]84        int Interior() const { return mNodes / 2 - 1; }
[1624]85        int Leaves() const { return (mNodes / 2) + 1; }
[1288]86       
87        // TODO: computation wrong
[1624]88        double AvgDepth() const { return mAccumDepth / (double)Leaves();}
[1288]89
[1449]90        void Reset()
[1288]91        {
[1449]92                mGlobalCostMisses = 0;
[1624]93                mTotalCost = 0;
94                mRenderCostDecrease = 0;
95
96                mNodes = 0;
97                mMaxDepth = 0;
98                mAccumDepth = 0;
99                mRepairTime = 0;
100                mMemory = 0;
101                mPvsEntries = 0;
[1288]102        }
103
104        void Print(ostream &app) const;
105
106        friend ostream &operator<<(ostream &s, const HierarchyStatistics &stat)
107        {
108                stat.Print(s);
109                return s;
110        }
111};
112
113
[1723]114class HierarchySubdivisionStats
115{
116public:
117           
118        int mNumSplits;
119               
120        float mRenderCostDecrease;
121
122    float mTotalRenderCost;
123   
124        int mEntriesInPvs;
125   
126        float mMemoryCost;
127       
128        float mFullMemory;
129
130        int mViewSpaceSplits;
131
132        int mObjectSpaceSplits;
133
[1744]134        float mPriority;
[1723]135
136        float VspOspRatio() const { return (float)mViewSpaceSplits / (float)mObjectSpaceSplits; }
137
138        float FpsPerMb() const { return 1.0f / (mTotalRenderCost * mMemoryCost); }
139
140        HierarchySubdivisionStats() { Reset(); }
141
142        void Reset()
143        {
144                mNumSplits = 0;
145                mRenderCostDecrease = 0;
146                mTotalRenderCost = 0;
147                mEntriesInPvs = 0;
148                mMemoryCost = 0;
149                mFullMemory = 0;
150                mViewSpaceSplits = 0;
151                mObjectSpaceSplits = 0;
[1744]152                mPriority = 0;
[1723]153        }
154
155
156        void Print(ostream &app) const;
157
158        friend ostream &operator<<(ostream &s, const HierarchySubdivisionStats &stat)
159        {
160                stat.Print(s);
161                return s;
162        }
163};
164
165
[1237]166/** This class implements a structure holding two different hierarchies,
167        one for object space partitioning and one for view space partitioning.
168
169        The object space and the view space are subdivided using a cost heuristics.
170        If an object space split or a view space split is chosen is also evaluated
171        based on the heuristics.
172       
173        The view space heuristics is evaluated by weighting and adding the pvss of the back and
174        front node of each specific split. unlike for the standalone method vspbsp tree,
175        the pvs of an object would not be the pvs of single object but that of all objects
176        which are contained in the same leaf of the object subdivision. This could be done
177        by storing the pointer to the object space partition parent, which would allow access to all children.
178        Another possibility is to include traced kd-cells in the ray casing process.
179
180        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
181        the contribution to an object to the pvs is the number of view cells it can be seen from.
182
183        @note
184        There is a potential efficiency problem involved in a sense that once a certain type
185        of split is chosen for view space / object space, the candidates for the next split of
186        object space / view space must be reevaluated.
187*/
188class HierarchyManager
189{
[2124]190        friend class VspOspViewCellsManager;
191
[1237]192public:
[2124]193       
[1421]194        /** Constructor with the view space partition tree and
195                the object space hierarchy type as argument.
[1237]196        */
[1421]197        HierarchyManager(const int objectSpaceHierarchyType);
[2124]198       
[1279]199        /** Hack: OspTree will copy the content from this kd tree.
200                Only view space hierarchy will be constructed.
201        */
[1421]202        HierarchyManager(KdTree *kdTree);
[1237]203
[1421]204        /** Deletes space partition and view space partition.
205        */
[1286]206        ~HierarchyManager();
207
[1237]208        /** Constructs the view space and object space subdivision from a given set of rays
209                and a set of objects.
210                @param sampleRays the set of sample rays the construction is based on
211                @param objects the set of objects
212        */
[1308]213        void Construct(
[1293]214                const VssRayContainer &sampleRays,
215                const ObjectContainer &objects,
216                AxisAlignedBox3 *forcedViewSpace);
[1237]217
[1259]218        enum
219        {
220                NO_OBJ_SUBDIV,
221                KD_BASED_OBJ_SUBDIV,
222                BV_BASED_OBJ_SUBDIV
223        };
[1237]224
[1370]225        enum
226        {
227                NO_VIEWSPACE_SUBDIV,
228                KD_BASED_VIEWSPACE_SUBDIV
229        };
230
[1259]231        /** The type of object space subdivison
232        */
[1370]233        int GetObjectSpaceSubdivisionType() const;     
[2003]234       
[1370]235        /** The type of view space space subdivison
236        */
237        int GetViewSpaceSubdivisionType() const;
[2003]238       
[1370]239        /** Sets a pointer to the view cells manager.
240        */             
[1279]241        void SetViewCellsManager(ViewCellsManager *vcm);
[2003]242       
[1370]243        /** Sets a pointer to the view cells tree.
244        */
[1279]245        void SetViewCellsTree(ViewCellsTree *vcTree);
[2003]246
[1370]247        /** Exports the object hierarchy to disc.
248        */
[1279]249        void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
[1764]250       
[1421]251        /** Print out statistics.
252        */
253        void PrintHierarchyStatistics(ostream &stream) const;
[1279]254
[1421]255        /** Returns the view space partition tree.
256        */
[1379]257        VspTree *GetVspTree();
[1279]258
[1421]259        /** Returns object space bounding box.
260        */
[1416]261        AxisAlignedBox3 GetObjectSpaceBox() const;
[1379]262
[1421]263        /** Exports object space hierarchy for visualization.
264        */
[1626]265        void ExportObjectSpaceHierarchy(Exporter *exporter,
266                                                                        const ObjectContainer &objects,
[1764]267                                                                        AxisAlignedBox3 *bbox,
[1920]268                                                                        const float maxRenderCost,
[1626]269                                                                        const bool exportBounds = true) const;
[1279]270
[1421]271        /** Returns intersectable pierced by this ray.
272        */
[1626]273        Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
[1743]274 
[1889]275        Intersectable *GetIntersectable(Intersectable *obj, const Vector3 &point) const;
276
[1626]277        /** Export object space partition bounding boxes.
278        */
279        void ExportBoundingBoxes(OUT_STREAM &stream, const ObjectContainer &objects);
280
[1419]281        friend ostream &operator<<(ostream &s, const HierarchyManager &hm)
282        {
[1421]283                hm.PrintHierarchyStatistics(s);
[1419]284                return s;
285        }
286
[1667]287        HierarchyStatistics &GetHierarchyStats() { return mHierarchyStats; };
288
289        inline bool ConsiderMemory() const { return mConsiderMemory; }
[1686]290       
291        void EvaluateSubdivision(const VssRayContainer &sampleRays,                                                                                     
292                                                         const ObjectContainer &objects,
293                                                         const string &filename);
[1676]294
[1710]295        void EvaluateSubdivision2(ofstream &splitsStats,
[1745]296                                                          const int splitsStepSize,
[1919]297                                                          const bool useFilter,
298                                                          const bool useHisto,
299                                                          const int histoMem,
300                                                          const int pass);
[1709]301
302
[1718]303        void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
304
[1845]305        int CompressObjectSpace();
[1843]306        void CreateUniqueObjectIds();
307
[1912]308        float EvalCorrectedPvs(const float pvsFront,
309                                                   const float totalPvs,
310                                                   const float avgRayContri) const;
[1843]311
[1686]312
[2094]313        /** Casts line segment into the view cells tree.
314                @param origin the origin of the line segment
315                @param termination the end point of the line segment
316                @returns view cells intersecting the line segment.
317        */
318    int CastLineSegment(const Vector3 &origin,
319                                                const Vector3 &termination,
320                                                ViewCellContainer &viewcells,
321                                                const bool useMailboxing = true);
322       
[1237]323protected:
324
[1625]325        /** Returns true if the global termination criteria were met.
326        */
[1237]327        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
328
329        /** Prepare construction of the hierarchies, set parameters, compute
330                first split candidates.
331        */
[1779]332        void PrepareObjectSpaceSubdivision(SplitQueue &tQueue,
333                                                                           const VssRayContainer &sampleRays,
334                                                                           const ObjectContainer &objects);
[1237]335
[1625]336
[1640]337        /** Create bounding box and root.
338        */
339        void InitialiseObjectSpaceSubdivision(const ObjectContainer &objects);
340
341        /** Returns memory usage of object space hierarchy.
342        */
343        float GetObjectSpaceMemUsage() const;
344
[1667]345
[1625]346        //////////////////////////////
347        // the main loop
348
349        /** This is for interleaved construction / sequential construction.
350        */
351        void RunConstruction(const bool repairQueue,
352                                                 const VssRayContainer &sampleRays,
353                                                 const ObjectContainer &objects,
[1640]354                                                 AxisAlignedBox3 *forcedViewSpace);
[1449]355       
[1625]356        /** This is for interleaved construction using some objects
357                and some view space splits.
358        */
359        int RunConstruction(SplitQueue &splitQueue,
360                                                SubdivisionCandidateContainer &chosenCandidates,
[1667]361                                                //const float minRenderCostDecr,
362                                                SubdivisionCandidate *oldCandidate,
[1676]363                                                const int minSteps,
364                                                const int maxSteps);
[1625]365
366        /** Default subdivision method.
367        */
[1449]368        void RunConstruction(const bool repairQueue);
[2094]369       
370       
[1625]371        ////////////////////////////////////////////////
372
[1580]373        /** Evaluates the subdivision candidate and executes the split.
374        */
[1625]375        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
376                                                                   SplitQueue &splitQueue,
377                                                                   const bool repairQueue);
[1237]378
[1625]379        /** Tests if hierarchy construction is finished.
380        */
[1237]381        bool FinishedConstruction() const;
382
[1625]383        /** Returns next subdivision candidate from the split queue.
384        */
385        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
[1237]386
[1625]387        /** Repairs the dirty entries of the subdivision candidate queue. The
388                list of entries is given in the dirty list.
[1736]389
390                @returns number of repaired candidates
[1580]391        */
[1736]392        int RepairQueue(const SubdivisionCandidateContainer &dirtyList,
393                                        SplitQueue &splitQueue,
394                                        const bool recomputeSplitPlaneOnRepair);
[1237]395
[1625]396        /** Collect subdivision candidates which were affected by the splits from the
397                chosenCandidates list.
398        */
399        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
400                                                                SubdivisionCandidateContainer &dirtyList);
401
[1580]402        /** Evaluate subdivision stats for log.
403        */
[1624]404        void EvalSubdivisionStats();
[1237]405
[1625]406        void AddSubdivisionStats(const int splits,
407                                                         const float renderCostDecr,
408                                                         const float totalRenderCost,
409                                                         const int totalPvsEntries,
[1640]410                                                         const float memory,
[1654]411                                                         const float renderCostPerStorage,
412                                                         const float vspOspRatio);
[1237]413
[1625]414        /** Collect affected view space candidates.
415        */
416        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
417                                                                   SubdivisionCandidateContainer &dirtyList);
[1259]418
[1625]419        /** Collect affected object space candidates.
420        */
421        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
422                                                                         SubdivisionCandidateContainer &dirtyList);
[1259]423               
[1625]424        /** Export object space partition tree.
425        */
426        void ExportOspTree(Exporter *exporter,
427                                           const ObjectContainer &objects) const;
[1259]428
[1625]429        /** Parse the environment variables.
430        */
[1418]431        void ParseEnvironment();
[1415]432
[1418]433        bool StartObjectSpaceSubdivision() const;
434        bool StartViewSpaceSubdivision() const;
435
[1667]436
[1625]437        ////////////////////////////
438        // Helper function for preparation of subdivision
[1286]439
[1625]440        /** Prepare bv hierarchy for subdivision
441        */
[1779]442        void PrepareBvHierarchy(SplitQueue &tQueue,
443                                                        const VssRayContainer &sampleRays,
444                                                        const ObjectContainer &objects);
[1286]445
[1625]446        /** Prepare object space kd tree for subdivision.
447        */
[1779]448        void PrepareOspTree(SplitQueue &tQueue,
449                                                const VssRayContainer &sampleRays,
450                                                const ObjectContainer &objects);
[1308]451
[1625]452        /** Prepare view space subdivision and add candidate to queue.
453        */
[1779]454        void PrepareViewSpaceSubdivision(SplitQueue &tQueue,
455                                                                         const VssRayContainer &sampleRays,
456                                                                         const ObjectContainer &objects);
[1625]457
458        /** Was object space subdivision already constructed?
459        */
[1313]460        bool ObjectSpaceSubdivisionConstructed() const;
[1625]461       
462        /** Was view space subdivision already constructed?
463        */
[1329]464        bool ViewSpaceSubdivisionConstructed() const;
[1311]465
[1625]466        /** Reset the split queue, i.e., reevaluate the split candidates.
467        */
[1640]468    void ResetQueue(SplitQueue &splitQueue, const bool recomputeSplitPlane);
[1313]469
[1625]470        /** After the suddivision has ended, do some final tasks.
471        */
[1654]472        void FinishObjectSpaceSubdivision(const ObjectContainer &objects,
473                                                                          const bool removeRayRefs = true) const;
[1313]474
[1625]475        /** Returns depth of object space subdivision.
476        */
[1370]477        int GetObjectSpaceSubdivisionDepth() const;
478
[1640]479        /** Returns number of leaves in object space subdivision.
480        */
481        int GetObjectSpaceSubdivisionLeaves() const;
[1663]482        int GetObjectSpaceSubdivisionNodes() const;
[1640]483
[1625]484        /** Construct object space partition interleaved with view space partition.
485                Each time the best object or view space candidate is selected
486                for the next split.
487        */
[1626]488        void ConstructInterleaved(const VssRayContainer &sampleRays,
489                                                          const ObjectContainer &objects,
490                                                          AxisAlignedBox3 *forcedViewSpace);
[1449]491
[1625]492        /** Construct object space partition interleaved with view space partition.
493                The method chooses a number candidates of each type for subdivision.
494                The number is determined by the "gradient", i.e., the render cost decrease.
495                Once this render cost decrease is lower than the render cost decrease
496                for the splits of previous type, the method will stop current subdivision and
497                evaluate if view space or object space would be the beneficial for the
498                next number of split.
499        */
[1626]500        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
501                                                                                  const ObjectContainer &objects,
502                                                                                  AxisAlignedBox3 *forcedViewSpace);
[1624]503
[1548]504        /** Use iteration to construct the object space hierarchy.
505        */
[1626]506        void ConstructMultiLevel(const VssRayContainer &sampleRays,
507                                                         const ObjectContainer &objects,
508                                                         AxisAlignedBox3 *forcedViewSpace);
[1449]509
[1640]510        /** Based on a given subdivision, we try to optimize using an
511                multiple iteration over view and object space.
512        */
513        void OptimizeMultiLevel(const VssRayContainer &sampleRays,                                                                                       
514                                                        const ObjectContainer &objects,
515                                                        AxisAlignedBox3 *forcedViewSpace);
516
[1548]517        /** Reset the object space subdivision.
518                E.g., deletes hierarchy and resets stats.
519                so construction can be restarted.
520        */
[1779]521        void ResetObjectSpaceSubdivision(SplitQueue &tQueue,
522                                                                         const VssRayContainer &rays,
523                                                                         const ObjectContainer &objects);
[1449]524
[1779]525        void ResetViewSpaceSubdivision(SplitQueue &tQueue,
526                                                                   const VssRayContainer &rays,
527                                                                   const ObjectContainer &objects,
528                                                                   AxisAlignedBox3 *forcedViewSpace);
[1557]529
[2073]530        void CreateTraversalTree();
[1614]531
[1686]532        ///////////////////////////
[1680]533
[1779]534        void ExportStats(ofstream &stats,
535                                         SplitQueue &tQueue,
536                                         const ObjectContainer &objects);
[1686]537
[1706]538        void CollectBestSet(const int maxSplits,
539                                                const float maxMemoryCost,
[1707]540                                                ViewCellContainer &viewCells,
[1706]541                                                vector<BvhNode *> &bvhNodes);
542
[1713]543        int ExtractStatistics(const int maxSplits,
544                                                  const float maxMemoryCost,
545                                                  float &renderCost,
546                                                  float &memory,
[1718]547                                                  int &pvsEntries,
548                                                  int &viewSpaceSplits,
[1745]549                                                  int &objectSpaceSplits,
[1919]550                                                  const bool useFilter,
551                                                  const bool useHisto,
552                                                  const int histoMem,
553                                                  const int pass,
554                                                  bool &histoUsed);
[1709]555
[1745]556        void ComputePvs(const ObjectPvs &pvs, float &rc, int &pvsEntries);
[1787]557        void GetPvsIncrementially(ViewCell *vc, ObjectPvs &pvs) const;
[1786]558        void PullUpPvsIncrementally(ViewCell *viewCell) const;
559        void GetPvsRecursive(ViewCell *vc, ObjectPvs &pvs) const;
[1787]560        void GetPvsEfficiently(ViewCell *vc, ObjectPvs &pvs) const;
561
[1830]562        float EvalFullMem() const;
563
[1843]564
[1237]565protected:
566
[1627]567        /** construction types
568                sequential: construct first view space, then object space
569                interleaved: construct view space and object space fully interleaved
570                gradient: construct view space / object space until a threshold is reached
571                multilevel: iterate until subdivisions converge to the optimum.
572        */
573        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
574
[1580]575        /// type of hierarchy construction
576        int mConstructionType;
577
578        /// Type of object space partition
[1308]579        int mObjectSpaceSubdivisionType;
[1580]580        /// Type of view space partition
[1329]581    int mViewSpaceSubdivisionType;
582
[1589]583        /// the traversal queue
584        SplitQueue mTQueue;
585       
[1580]586        ////////////
587        //-- helper variables
588       
589        // the original osp type
[1323]590        int mSavedObjectSpaceSubdivisionType;
[1580]591        // the original vsp type
[1329]592        int mSavedViewSpaceSubdivisionType;
[1911]593       
[1323]594
[1580]595        ///////////////////
596        // Hierarchies
597
598        /// view space hierarchy
[1259]599        VspTree *mVspTree;
[1580]600        /// object space partition kd tree
[1259]601        OspTree *mOspTree;
[1625]602
[1911]603        float mInitialRenderCost;
604       
605        float mMaxAvgRayContri;
606
607        float mMinAvgRayContri;
608
[1895]609        // quick hack:
610public:
[1580]611        /// bounding volume hierarchy
[1259]612        BvHierarchy *mBvHierarchy;
[1580]613       
[1589]614protected:
[1237]615
616
[1580]617        //////////
[1576]618        //-- global termination criteria
619
[1580]620        /// the mininal acceptable cost ratio for a split
[1237]621        float mTermMinGlobalCostRatio;
[1580]622        /// the threshold for global cost miss tolerance
[1237]623        int mTermGlobalCostMissTolerance;
[1580]624        /// maximum number of leaves
625        int mTermMaxLeaves;
[1649]626        /// Maximal allowed memory consumption.
627        float mTermMaxMemory;
[1580]628
[1667]629
[1576]630        ////////////////////
631
[1667]632        /// number of minimal steps of the same type
[1640]633        int mMinStepsOfSameType;
[1684]634        int mMaxStepsOfSameType;
[1640]635
[1580]636        /// statistics about the hierarchy
[1288]637        HierarchyStatistics mHierarchyStats;
638
[1308]639        int mMinDepthForObjectSpaceSubdivion;
[1370]640        int mMinDepthForViewSpaceSubdivion;
[1580]641       
[1625]642        //int mMinRenderCostDecrease;
[1624]643
[1237]644        ofstream mSubdivisionStats;
[1314]645
[1580]646        /// if the queue should be repaired after a subdivision steps
[1314]647        bool mRepairQueue;
[1370]648
649        bool mStartWithObjectSpace;
[1580]650        /** if multi level construction method should be used
651                where we iterate over both hierarchies until we
652                converge to the optimum.
653        */
[1449]654        bool mUseMultiLevelConstruction;
[1640]655
[1580]656        /// number of iteration steps for multilevel approach   
657        int mNumMultiLevels;
[1640]658
[1633]659        /** if split plane should be recomputed for the repair.
660                Otherwise only the priority is recomputed, the
661                split plane itself stays the same
662        */
663        bool mRecomputeSplitPlaneOnRepair;
[1662]664
665        /** If memory should be considered during choosing
666                of the next split type during gradient method.
667        */
668        bool mConsiderMemory;
[1666]669
[2094]670        TraversalTree *mTraversalTree;
671
[1727]672        int mMaxRepairs;
673
[1679]674        int mTimeStamp;
[1667]675        friend VspTree;
676        friend OspTree;
677        friend BvHierarchy;
[1744]678
679        float mPriority;
680
[1667]681        friend ViewCellsParseHandlers;
682
[1750]683        ViewCellContainer mOldViewCells;
[1786]684
[2116]685        //ObjectPvs mOldPvs;
[1237]686};
687
688}
689
690#endif
Note: See TracBrowser for help on using the repository browser.