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

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