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

Revision 1889, 17.6 KB checked in by mattausch, 18 years ago (diff)
Line 
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"
12#include "SubdivisionCandidate.h"
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;
41class BvHierarchy;
42class Exporter;
43class ViewCellsParseHandlers;
44
45
46#define COUNT_ORIGIN_OBJECTS 1
47
48/** View space / object space hierarchy statistics.
49*/
50class HierarchyStatistics: public StatisticsBase
51{
52public:
53        /// total number of entries in the pvs
54        int mPvsEntries;
55        /// storage cost in MB
56        float mMemory;
57        /// total number of nodes
58        int mNodes;
59        /// maximal reached depth
60        int mMaxDepth;
61        /// accumulated depth
62        int mAccumDepth;
63        /// time spent for queue repair
64        float mRepairTime;
65
66        // global cost ratio violations
67        int mGlobalCostMisses;
68        /// total cost of subdivision
69        float mTotalCost;
70        /// render cost decrease of subdivision
71        float mRenderCostDecrease;
72
73        // Constructor
74        HierarchyStatistics()
75        {
76                Reset();
77        }
78
79        int Nodes() const {return mNodes;}
80        int Interior() const { return mNodes / 2 - 1; }
81        int Leaves() const { return (mNodes / 2) + 1; }
82       
83        // TODO: computation wrong
84        double AvgDepth() const { return mAccumDepth / (double)Leaves();}
85
86        void Reset()
87        {
88                mGlobalCostMisses = 0;
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;
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
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        float mPriority;
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;
148                mPriority = 0;
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
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:
187        /** Constructor with the view space partition tree and
188                the object space hierarchy type as argument.
189        */
190        HierarchyManager(const int objectSpaceHierarchyType);
191        /** Hack: OspTree will copy the content from this kd tree.
192                Only view space hierarchy will be constructed.
193        */
194        HierarchyManager(KdTree *kdTree);
195
196        /** Deletes space partition and view space partition.
197        */
198        ~HierarchyManager();
199
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        */
205        void Construct(
206                const VssRayContainer &sampleRays,
207                const ObjectContainer &objects,
208                AxisAlignedBox3 *forcedViewSpace);
209
210        enum
211        {
212                NO_OBJ_SUBDIV,
213                KD_BASED_OBJ_SUBDIV,
214                BV_BASED_OBJ_SUBDIV
215        };
216
217        enum
218        {
219                NO_VIEWSPACE_SUBDIV,
220                KD_BASED_VIEWSPACE_SUBDIV
221        };
222
223        /** The type of object space subdivison
224        */
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        */             
231        void SetViewCellsManager(ViewCellsManager *vcm);
232        /** Sets a pointer to the view cells tree.
233        */
234        void SetViewCellsTree(ViewCellsTree *vcTree);
235        /** Exports the object hierarchy to disc.
236        */
237        void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
238       
239        /** Print out statistics.
240        */
241        void PrintHierarchyStatistics(ostream &stream) const;
242
243        /** Returns the view space partition tree.
244        */
245        VspTree *GetVspTree();
246
247        /** Returns view space bounding box.
248        */
249        //AxisAlignedBox3 GetViewSpaceBox() const;
250
251        /** Returns object space bounding box.
252        */
253        AxisAlignedBox3 GetObjectSpaceBox() const;
254
255        /** Exports object space hierarchy for visualization.
256        */
257        void ExportObjectSpaceHierarchy(Exporter *exporter,
258                                                                        const ObjectContainer &objects,
259                                                                        AxisAlignedBox3 *bbox,
260                                                                        const bool exportBounds = true) const;
261
262        /** Returns intersectable pierced by this ray.
263        */
264        Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
265 
266        Intersectable *GetIntersectable(Intersectable *obj, const Vector3 &point) const;
267 
268        float AvgRayContribution(const float pvs, const float rays) const;
269
270        /** Export object space partition bounding boxes.
271        */
272        void ExportBoundingBoxes(OUT_STREAM &stream, const ObjectContainer &objects);
273
274        friend ostream &operator<<(ostream &s, const HierarchyManager &hm)
275        {
276                hm.PrintHierarchyStatistics(s);
277                return s;
278        }
279
280        HierarchyStatistics &GetHierarchyStats() { return mHierarchyStats; };
281
282        inline bool ConsiderMemory() const { return mConsiderMemory; }
283       
284        void EvaluateSubdivision(const VssRayContainer &sampleRays,                                                                                     
285                                                         const ObjectContainer &objects,
286                                                         const string &filename);
287
288        void EvaluateSubdivision2(ofstream &splitsStats,
289                                                          const int splitsStepSize,
290                                                          const bool useFilter);
291
292
293        void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
294
295        int CompressObjectSpace();
296        void CreateUniqueObjectIds();
297
298
299        float mInitialRenderCost;
300
301
302protected:
303
304        /** Returns true if the global termination criteria were met.
305        */
306        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
307
308        /** Prepare construction of the hierarchies, set parameters, compute
309                first split candidates.
310        */
311        void PrepareObjectSpaceSubdivision(SplitQueue &tQueue,
312                                                                           const VssRayContainer &sampleRays,
313                                                                           const ObjectContainer &objects);
314
315
316        /** Create bounding box and root.
317        */
318        void InitialiseObjectSpaceSubdivision(const ObjectContainer &objects);
319
320        /** Returns memory usage of object space hierarchy.
321        */
322        float GetObjectSpaceMemUsage() const;
323
324
325        //////////////////////////////
326        // the main loop
327
328        /** This is for interleaved construction / sequential construction.
329        */
330        void RunConstruction(const bool repairQueue,
331                                                 const VssRayContainer &sampleRays,
332                                                 const ObjectContainer &objects,
333                                                 AxisAlignedBox3 *forcedViewSpace);
334       
335        /** This is for interleaved construction using some objects
336                and some view space splits.
337        */
338        int RunConstruction(SplitQueue &splitQueue,
339                                                SubdivisionCandidateContainer &chosenCandidates,
340                                                //const float minRenderCostDecr,
341                                                SubdivisionCandidate *oldCandidate,
342                                                const int minSteps,
343                                                const int maxSteps);
344
345        /** Default subdivision method.
346        */
347        void RunConstruction(const bool repairQueue);
348               
349        ////////////////////////////////////////////////
350
351        /** Evaluates the subdivision candidate and executes the split.
352        */
353        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
354                                                                   SplitQueue &splitQueue,
355                                                                   const bool repairQueue);
356
357        /** Tests if hierarchy construction is finished.
358        */
359        bool FinishedConstruction() const;
360
361        /** Returns next subdivision candidate from the split queue.
362        */
363        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
364
365        /** Repairs the dirty entries of the subdivision candidate queue. The
366                list of entries is given in the dirty list.
367
368                @returns number of repaired candidates
369        */
370        int RepairQueue(const SubdivisionCandidateContainer &dirtyList,
371                                        SplitQueue &splitQueue,
372                                        const bool recomputeSplitPlaneOnRepair);
373
374        /** Collect subdivision candidates which were affected by the splits from the
375                chosenCandidates list.
376        */
377        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
378                                                                SubdivisionCandidateContainer &dirtyList);
379
380        /** Evaluate subdivision stats for log.
381        */
382        void EvalSubdivisionStats();
383
384        void AddSubdivisionStats(const int splits,
385                                                         const float renderCostDecr,
386                                                         const float totalRenderCost,
387                                                         const int totalPvsEntries,
388                                                         const float memory,
389                                                         const float renderCostPerStorage,
390                                                         const float vspOspRatio);
391
392        /** Collect affected view space candidates.
393        */
394        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
395                                                                   SubdivisionCandidateContainer &dirtyList);
396
397        /** Collect affected object space candidates.
398        */
399        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
400                                                                         SubdivisionCandidateContainer &dirtyList);
401               
402        /** Export object space partition tree.
403        */
404        void ExportOspTree(Exporter *exporter,
405                                           const ObjectContainer &objects) const;
406
407        /** Parse the environment variables.
408        */
409        void ParseEnvironment();
410
411        bool StartObjectSpaceSubdivision() const;
412        bool StartViewSpaceSubdivision() const;
413
414
415        ////////////////////////////
416        // Helper function for preparation of subdivision
417
418        /** Prepare bv hierarchy for subdivision
419        */
420        void PrepareBvHierarchy(SplitQueue &tQueue,
421                                                        const VssRayContainer &sampleRays,
422                                                        const ObjectContainer &objects);
423
424        /** Prepare object space kd tree for subdivision.
425        */
426        void PrepareOspTree(SplitQueue &tQueue,
427                                                const VssRayContainer &sampleRays,
428                                                const ObjectContainer &objects);
429
430        /** Prepare view space subdivision and add candidate to queue.
431        */
432        void PrepareViewSpaceSubdivision(SplitQueue &tQueue,
433                                                                         const VssRayContainer &sampleRays,
434                                                                         const ObjectContainer &objects);
435
436        /** Was object space subdivision already constructed?
437        */
438        bool ObjectSpaceSubdivisionConstructed() const;
439       
440        /** Was view space subdivision already constructed?
441        */
442        bool ViewSpaceSubdivisionConstructed() const;
443
444        /** Reset the split queue, i.e., reevaluate the split candidates.
445        */
446    void ResetQueue(SplitQueue &splitQueue, const bool recomputeSplitPlane);
447
448        /** After the suddivision has ended, do some final tasks.
449        */
450        void FinishObjectSpaceSubdivision(const ObjectContainer &objects,
451                                                                          const bool removeRayRefs = true) const;
452
453        /** Returns depth of object space subdivision.
454        */
455        int GetObjectSpaceSubdivisionDepth() const;
456
457        /** Returns number of leaves in object space subdivision.
458        */
459        int GetObjectSpaceSubdivisionLeaves() const;
460        int GetObjectSpaceSubdivisionNodes() const;
461
462        /** Construct object space partition interleaved with view space partition.
463                Each time the best object or view space candidate is selected
464                for the next split.
465        */
466        void ConstructInterleaved(const VssRayContainer &sampleRays,
467                                                          const ObjectContainer &objects,
468                                                          AxisAlignedBox3 *forcedViewSpace);
469
470        /** Construct object space partition interleaved with view space partition.
471                The method chooses a number candidates of each type for subdivision.
472                The number is determined by the "gradient", i.e., the render cost decrease.
473                Once this render cost decrease is lower than the render cost decrease
474                for the splits of previous type, the method will stop current subdivision and
475                evaluate if view space or object space would be the beneficial for the
476                next number of split.
477        */
478        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
479                                                                                  const ObjectContainer &objects,
480                                                                                  AxisAlignedBox3 *forcedViewSpace);
481
482        /** Use iteration to construct the object space hierarchy.
483        */
484        void ConstructMultiLevel(const VssRayContainer &sampleRays,
485                                                         const ObjectContainer &objects,
486                                                         AxisAlignedBox3 *forcedViewSpace);
487
488        /** Based on a given subdivision, we try to optimize using an
489                multiple iteration over view and object space.
490        */
491        void OptimizeMultiLevel(const VssRayContainer &sampleRays,                                                                                       
492                                                        const ObjectContainer &objects,
493                                                        AxisAlignedBox3 *forcedViewSpace);
494
495        /** Reset the object space subdivision.
496                E.g., deletes hierarchy and resets stats.
497                so construction can be restarted.
498        */
499        void ResetObjectSpaceSubdivision(SplitQueue &tQueue,
500                                                                         const VssRayContainer &rays,
501                                                                         const ObjectContainer &objects);
502
503        void ResetViewSpaceSubdivision(SplitQueue &tQueue,
504                                                                   const VssRayContainer &rays,
505                                                                   const ObjectContainer &objects,
506                                                                   AxisAlignedBox3 *forcedViewSpace);
507
508
509        ///////////////////////////
510
511        void ExportStats(ofstream &stats,
512                                         SplitQueue &tQueue,
513                                         const ObjectContainer &objects);
514
515        void CollectBestSet(const int maxSplits,
516                                                const float maxMemoryCost,
517                                                ViewCellContainer &viewCells,
518                                                vector<BvhNode *> &bvhNodes);
519
520        int ExtractStatistics(const int maxSplits,
521                                                  const float maxMemoryCost,
522                                                  float &renderCost,
523                                                  float &memory,
524                                                  int &pvsEntries,
525                                                  int &viewSpaceSplits,
526                                                  int &objectSpaceSplits,
527                                                  const bool useFilter);
528
529        void ComputePvs(const ObjectPvs &pvs, float &rc, int &pvsEntries);
530        void GetPvsIncrementially(ViewCell *vc, ObjectPvs &pvs) const;
531        void PullUpPvsIncrementally(ViewCell *viewCell) const;
532        void GetPvsRecursive(ViewCell *vc, ObjectPvs &pvs) const;
533        void GetPvsEfficiently(ViewCell *vc, ObjectPvs &pvs) const;
534
535        float EvalFullMem() const;
536
537
538
539protected:
540
541        /** construction types
542                sequential: construct first view space, then object space
543                interleaved: construct view space and object space fully interleaved
544                gradient: construct view space / object space until a threshold is reached
545                multilevel: iterate until subdivisions converge to the optimum.
546        */
547        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
548
549        /// type of hierarchy construction
550        int mConstructionType;
551
552        /// Type of object space partition
553        int mObjectSpaceSubdivisionType;
554        /// Type of view space partition
555    int mViewSpaceSubdivisionType;
556
557        /// the traversal queue
558        SplitQueue mTQueue;
559       
560        ////////////
561        //-- helper variables
562       
563        // the original osp type
564        int mSavedObjectSpaceSubdivisionType;
565        // the original vsp type
566        int mSavedViewSpaceSubdivisionType;
567        /// the current subdivision candidate
568        //SubdivisionCandidate *mCurrentCandidate;
569
570
571        ///////////////////
572        // Hierarchies
573
574        /// view space hierarchy
575        VspTree *mVspTree;
576        /// object space partition kd tree
577        OspTree *mOspTree;
578
579        public:
580        /// bounding volume hierarchy
581        BvHierarchy *mBvHierarchy;
582       
583protected:
584
585
586        //////////
587        //-- global termination criteria
588
589        /// the mininal acceptable cost ratio for a split
590        float mTermMinGlobalCostRatio;
591        /// the threshold for global cost miss tolerance
592        int mTermGlobalCostMissTolerance;
593        /// maximum number of leaves
594        int mTermMaxLeaves;
595        /// Maximal allowed memory consumption.
596        float mTermMaxMemory;
597
598
599        ////////////////////
600
601        /// number of minimal steps of the same type
602        int mMinStepsOfSameType;
603        int mMaxStepsOfSameType;
604
605        /// statistics about the hierarchy
606        HierarchyStatistics mHierarchyStats;
607
608        int mMinDepthForObjectSpaceSubdivion;
609        int mMinDepthForViewSpaceSubdivion;
610       
611        //int mMinRenderCostDecrease;
612
613        ofstream mSubdivisionStats;
614
615        /// if the queue should be repaired after a subdivision steps
616        bool mRepairQueue;
617
618        bool mStartWithObjectSpace;
619        /** if multi level construction method should be used
620                where we iterate over both hierarchies until we
621                converge to the optimum.
622        */
623        bool mUseMultiLevelConstruction;
624
625        /// number of iteration steps for multilevel approach   
626        int mNumMultiLevels;
627
628        /** if split plane should be recomputed for the repair.
629                Otherwise only the priority is recomputed, the
630                split plane itself stays the same
631        */
632        bool mRecomputeSplitPlaneOnRepair;
633
634        /** If memory should be considered during choosing
635                of the next split type during gradient method.
636        */
637        bool mConsiderMemory;
638
639        int mMaxRepairs;
640
641        int mTimeStamp;
642        friend VspTree;
643        friend OspTree;
644        friend BvHierarchy;
645
646        float mPriority;
647
648        friend ViewCellsParseHandlers;
649
650        ViewCellContainer mOldViewCells;
651
652        ObjectPvs mOldPvs;
653};
654
655}
656
657#endif
Note: See TracBrowser for help on using the repository browser.