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

Revision 1764, 17.2 KB checked in by mattausch, 18 years ago (diff)

removed error in sample registration

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