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

Revision 2187, 18.5 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
[2176]104        void Print(std::ostream &app) const;
[1288]105
[2176]106        friend std::ostream &operator<<(std::ostream &s, const HierarchyStatistics &stat)
[1288]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
[2176]156        void Print(std::ostream &app) const;
[1723]157
[2176]158        friend std::ostream &operator<<(std::ostream &s, const HierarchySubdivisionStats &stat)
[1723]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        */
[2176]253        void PrintHierarchyStatistics(std::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
[2176]281        friend std::ostream &operator<<(std::ostream &s, const HierarchyManager &hm)
[1419]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,
[2176]293                                                         const std::string &filename);
[1676]294
[2176]295        void EvaluateSubdivision2(std::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
[2187]325        void PrintTimings(const bool osp);
326
[1625]327        /** Returns true if the global termination criteria were met.
328        */
[1237]329        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
330
331        /** Prepare construction of the hierarchies, set parameters, compute
332                first split candidates.
333        */
[1779]334        void PrepareObjectSpaceSubdivision(SplitQueue &tQueue,
335                                                                           const VssRayContainer &sampleRays,
336                                                                           const ObjectContainer &objects);
[1237]337
[1625]338
[1640]339        /** Create bounding box and root.
340        */
341        void InitialiseObjectSpaceSubdivision(const ObjectContainer &objects);
342
343        /** Returns memory usage of object space hierarchy.
344        */
345        float GetObjectSpaceMemUsage() const;
346
[1667]347
[1625]348        //////////////////////////////
349        // the main loop
350
351        /** This is for interleaved construction / sequential construction.
352        */
353        void RunConstruction(const bool repairQueue,
354                                                 const VssRayContainer &sampleRays,
355                                                 const ObjectContainer &objects,
[1640]356                                                 AxisAlignedBox3 *forcedViewSpace);
[1449]357       
[1625]358        /** This is for interleaved construction using some objects
359                and some view space splits.
360        */
361        int RunConstruction(SplitQueue &splitQueue,
362                                                SubdivisionCandidateContainer &chosenCandidates,
[1667]363                                                //const float minRenderCostDecr,
364                                                SubdivisionCandidate *oldCandidate,
[1676]365                                                const int minSteps,
366                                                const int maxSteps);
[1625]367
368        /** Default subdivision method.
369        */
[1449]370        void RunConstruction(const bool repairQueue);
[2094]371       
372       
[1625]373        ////////////////////////////////////////////////
374
[1580]375        /** Evaluates the subdivision candidate and executes the split.
376        */
[1625]377        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
378                                                                   SplitQueue &splitQueue,
379                                                                   const bool repairQueue);
[1237]380
[1625]381        /** Tests if hierarchy construction is finished.
382        */
[1237]383        bool FinishedConstruction() const;
384
[1625]385        /** Returns next subdivision candidate from the split queue.
386        */
387        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
[1237]388
[1625]389        /** Repairs the dirty entries of the subdivision candidate queue. The
390                list of entries is given in the dirty list.
[1736]391
392                @returns number of repaired candidates
[1580]393        */
[1736]394        int RepairQueue(const SubdivisionCandidateContainer &dirtyList,
395                                        SplitQueue &splitQueue,
396                                        const bool recomputeSplitPlaneOnRepair);
[1237]397
[1625]398        /** Collect subdivision candidates which were affected by the splits from the
399                chosenCandidates list.
400        */
401        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
402                                                                SubdivisionCandidateContainer &dirtyList);
403
[1580]404        /** Evaluate subdivision stats for log.
405        */
[1624]406        void EvalSubdivisionStats();
[1237]407
[1625]408        void AddSubdivisionStats(const int splits,
409                                                         const float renderCostDecr,
410                                                         const float totalRenderCost,
411                                                         const int totalPvsEntries,
[1640]412                                                         const float memory,
[1654]413                                                         const float renderCostPerStorage,
414                                                         const float vspOspRatio);
[1237]415
[1625]416        /** Collect affected view space candidates.
417        */
418        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
419                                                                   SubdivisionCandidateContainer &dirtyList);
[1259]420
[1625]421        /** Collect affected object space candidates.
422        */
423        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
424                                                                         SubdivisionCandidateContainer &dirtyList);
[1259]425               
[1625]426        /** Export object space partition tree.
427        */
428        void ExportOspTree(Exporter *exporter,
429                                           const ObjectContainer &objects) const;
[1259]430
[1625]431        /** Parse the environment variables.
432        */
[1418]433        void ParseEnvironment();
[1415]434
[1418]435        bool StartObjectSpaceSubdivision() const;
436        bool StartViewSpaceSubdivision() const;
437
[1667]438
[1625]439        ////////////////////////////
440        // Helper function for preparation of subdivision
[1286]441
[1625]442        /** Prepare bv hierarchy for subdivision
443        */
[1779]444        void PrepareBvHierarchy(SplitQueue &tQueue,
445                                                        const VssRayContainer &sampleRays,
446                                                        const ObjectContainer &objects);
[1286]447
[1625]448        /** Prepare object space kd tree for subdivision.
449        */
[1779]450        void PrepareOspTree(SplitQueue &tQueue,
451                                                const VssRayContainer &sampleRays,
452                                                const ObjectContainer &objects);
[1308]453
[1625]454        /** Prepare view space subdivision and add candidate to queue.
455        */
[1779]456        void PrepareViewSpaceSubdivision(SplitQueue &tQueue,
457                                                                         const VssRayContainer &sampleRays,
458                                                                         const ObjectContainer &objects);
[1625]459
460        /** Was object space subdivision already constructed?
461        */
[1313]462        bool ObjectSpaceSubdivisionConstructed() const;
[1625]463       
464        /** Was view space subdivision already constructed?
465        */
[1329]466        bool ViewSpaceSubdivisionConstructed() const;
[1311]467
[1625]468        /** Reset the split queue, i.e., reevaluate the split candidates.
469        */
[1640]470    void ResetQueue(SplitQueue &splitQueue, const bool recomputeSplitPlane);
[1313]471
[1625]472        /** After the suddivision has ended, do some final tasks.
473        */
[1654]474        void FinishObjectSpaceSubdivision(const ObjectContainer &objects,
475                                                                          const bool removeRayRefs = true) const;
[1313]476
[1625]477        /** Returns depth of object space subdivision.
478        */
[1370]479        int GetObjectSpaceSubdivisionDepth() const;
480
[1640]481        /** Returns number of leaves in object space subdivision.
482        */
483        int GetObjectSpaceSubdivisionLeaves() const;
[1663]484        int GetObjectSpaceSubdivisionNodes() const;
[1640]485
[1625]486        /** Construct object space partition interleaved with view space partition.
487                Each time the best object or view space candidate is selected
488                for the next split.
489        */
[1626]490        void ConstructInterleaved(const VssRayContainer &sampleRays,
491                                                          const ObjectContainer &objects,
492                                                          AxisAlignedBox3 *forcedViewSpace);
[1449]493
[1625]494        /** Construct object space partition interleaved with view space partition.
495                The method chooses a number candidates of each type for subdivision.
496                The number is determined by the "gradient", i.e., the render cost decrease.
497                Once this render cost decrease is lower than the render cost decrease
498                for the splits of previous type, the method will stop current subdivision and
499                evaluate if view space or object space would be the beneficial for the
500                next number of split.
501        */
[1626]502        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
503                                                                                  const ObjectContainer &objects,
504                                                                                  AxisAlignedBox3 *forcedViewSpace);
[1624]505
[1548]506        /** Use iteration to construct the object space hierarchy.
507        */
[1626]508        void ConstructMultiLevel(const VssRayContainer &sampleRays,
509                                                         const ObjectContainer &objects,
510                                                         AxisAlignedBox3 *forcedViewSpace);
[1449]511
[1640]512        /** Based on a given subdivision, we try to optimize using an
513                multiple iteration over view and object space.
514        */
515        void OptimizeMultiLevel(const VssRayContainer &sampleRays,                                                                                       
516                                                        const ObjectContainer &objects,
517                                                        AxisAlignedBox3 *forcedViewSpace);
518
[1548]519        /** Reset the object space subdivision.
520                E.g., deletes hierarchy and resets stats.
521                so construction can be restarted.
522        */
[1779]523        void ResetObjectSpaceSubdivision(SplitQueue &tQueue,
524                                                                         const VssRayContainer &rays,
525                                                                         const ObjectContainer &objects);
[1449]526
[1779]527        void ResetViewSpaceSubdivision(SplitQueue &tQueue,
528                                                                   const VssRayContainer &rays,
529                                                                   const ObjectContainer &objects,
530                                                                   AxisAlignedBox3 *forcedViewSpace);
[1557]531
[2073]532        void CreateTraversalTree();
[1614]533
[1686]534        ///////////////////////////
[1680]535
[2176]536        void ExportStats(std::ofstream &stats,
[1779]537                                         SplitQueue &tQueue,
538                                         const ObjectContainer &objects);
[1686]539
[1706]540        void CollectBestSet(const int maxSplits,
541                                                const float maxMemoryCost,
[1707]542                                                ViewCellContainer &viewCells,
[1706]543                                                vector<BvhNode *> &bvhNodes);
544
[1713]545        int ExtractStatistics(const int maxSplits,
546                                                  const float maxMemoryCost,
547                                                  float &renderCost,
548                                                  float &memory,
[1718]549                                                  int &pvsEntries,
550                                                  int &viewSpaceSplits,
[1745]551                                                  int &objectSpaceSplits,
[1919]552                                                  const bool useFilter,
553                                                  const bool useHisto,
554                                                  const int histoMem,
555                                                  const int pass,
556                                                  bool &histoUsed);
[1709]557
[1745]558        void ComputePvs(const ObjectPvs &pvs, float &rc, int &pvsEntries);
[1787]559        void GetPvsIncrementially(ViewCell *vc, ObjectPvs &pvs) const;
[1786]560        void PullUpPvsIncrementally(ViewCell *viewCell) const;
561        void GetPvsRecursive(ViewCell *vc, ObjectPvs &pvs) const;
[1787]562        void GetPvsEfficiently(ViewCell *vc, ObjectPvs &pvs) const;
563
[1830]564        float EvalFullMem() const;
565
[1843]566
[1237]567protected:
568
[1627]569        /** construction types
570                sequential: construct first view space, then object space
571                interleaved: construct view space and object space fully interleaved
572                gradient: construct view space / object space until a threshold is reached
573                multilevel: iterate until subdivisions converge to the optimum.
574        */
575        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
576
[1580]577        /// type of hierarchy construction
578        int mConstructionType;
579
580        /// Type of object space partition
[1308]581        int mObjectSpaceSubdivisionType;
[1580]582        /// Type of view space partition
[1329]583    int mViewSpaceSubdivisionType;
584
[1589]585        /// the traversal queue
586        SplitQueue mTQueue;
587       
[1580]588        ////////////
589        //-- helper variables
590       
591        // the original osp type
[1323]592        int mSavedObjectSpaceSubdivisionType;
[1580]593        // the original vsp type
[1329]594        int mSavedViewSpaceSubdivisionType;
[1911]595       
[1323]596
[1580]597        ///////////////////
598        // Hierarchies
599
600        /// view space hierarchy
[1259]601        VspTree *mVspTree;
[1580]602        /// object space partition kd tree
[1259]603        OspTree *mOspTree;
[1625]604
[1911]605        float mInitialRenderCost;
606       
607        float mMaxAvgRayContri;
608
609        float mMinAvgRayContri;
610
[1895]611        // quick hack:
612public:
[1580]613        /// bounding volume hierarchy
[1259]614        BvHierarchy *mBvHierarchy;
[1580]615       
[2130]616        bool mUseTraversalTree;
617
[1589]618protected:
[1237]619
620
[1580]621        //////////
[1576]622        //-- global termination criteria
623
[1580]624        /// the mininal acceptable cost ratio for a split
[1237]625        float mTermMinGlobalCostRatio;
[1580]626        /// the threshold for global cost miss tolerance
[1237]627        int mTermGlobalCostMissTolerance;
[1580]628        /// maximum number of leaves
629        int mTermMaxLeaves;
[1649]630        /// Maximal allowed memory consumption.
631        float mTermMaxMemory;
[1580]632
[1667]633
[1576]634        ////////////////////
635
[1667]636        /// number of minimal steps of the same type
[1640]637        int mMinStepsOfSameType;
[1684]638        int mMaxStepsOfSameType;
[1640]639
[1580]640        /// statistics about the hierarchy
[1288]641        HierarchyStatistics mHierarchyStats;
642
[1308]643        int mMinDepthForObjectSpaceSubdivion;
[1370]644        int mMinDepthForViewSpaceSubdivion;
[1580]645       
[1625]646        //int mMinRenderCostDecrease;
[1624]647
[2176]648        std::ofstream mSubdivisionStats;
[1314]649
[1580]650        /// if the queue should be repaired after a subdivision steps
[1314]651        bool mRepairQueue;
[1370]652
653        bool mStartWithObjectSpace;
[1580]654        /** if multi level construction method should be used
655                where we iterate over both hierarchies until we
656                converge to the optimum.
657        */
[1449]658        bool mUseMultiLevelConstruction;
[1640]659
[1580]660        /// number of iteration steps for multilevel approach   
661        int mNumMultiLevels;
[1640]662
[1633]663        /** if split plane should be recomputed for the repair.
664                Otherwise only the priority is recomputed, the
665                split plane itself stays the same
666        */
667        bool mRecomputeSplitPlaneOnRepair;
[1662]668
669        /** If memory should be considered during choosing
670                of the next split type during gradient method.
671        */
672        bool mConsiderMemory;
[1666]673
[2094]674        TraversalTree *mTraversalTree;
675
[1727]676        int mMaxRepairs;
677
[1679]678        int mTimeStamp;
[1667]679        friend VspTree;
680        friend OspTree;
681        friend BvHierarchy;
[1744]682
683        float mPriority;
684
[1667]685        friend ViewCellsParseHandlers;
686
[1750]687        ViewCellContainer mOldViewCells;
[1237]688};
689
690}
691
692#endif
Note: See TracBrowser for help on using the repository browser.