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

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

implemented several accelleration svhemes for the gradient method

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