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

Revision 2353, 18.6 KB checked in by mattausch, 18 years ago (diff)

cleaned up project files

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       
200        /** Hack: OspTree will copy the content from this kd tree.
201                Only view space hierarchy will be constructed.
202        */
203        HierarchyManager(KdTree *kdTree);
204
205        /** Deletes space partition and view space partition.
206        */
207        ~HierarchyManager();
208
209        /** Constructs the view space and object space subdivision from a given set of rays
210                and a set of objects.
211                @param sampleRays the set of sample rays the construction is based on
212                @param objects the set of objects
213        */
214        void Construct(
215                const VssRayContainer &sampleRays,
216                const ObjectContainer &objects,
217                AxisAlignedBox3 *forcedViewSpace);
218
219        enum
220        {
221                NO_OBJ_SUBDIV,
222                KD_BASED_OBJ_SUBDIV,
223                BV_BASED_OBJ_SUBDIV
224        };
225
226        enum
227        {
228                NO_VIEWSPACE_SUBDIV,
229                KD_BASED_VIEWSPACE_SUBDIV
230        };
231
232        /** The type of object space subdivison
233        */
234        int GetObjectSpaceSubdivisionType() const;     
235       
236        /** The type of view space space subdivison
237        */
238        int GetViewSpaceSubdivisionType() const;
239       
240        /** Sets a pointer to the view cells manager.
241        */             
242        void SetViewCellsManager(ViewCellsManager *vcm);
243       
244        /** Sets a pointer to the view cells tree.
245        */
246        void SetViewCellsTree(ViewCellsTree *vcTree);
247
248        /** Exports the object hierarchy to disc.
249        */
250        void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
251       
252        /** Print out statistics.
253        */
254        void PrintHierarchyStatistics(std::ostream &stream) const;
255
256        /** Returns the view space partition tree.
257        */
258        VspTree *GetVspTree();
259
260        /** Returns object space bounding box.
261        */
262        AxisAlignedBox3 GetObjectSpaceBox() const;
263
264        /** Exports object space hierarchy for visualization.
265        */
266        void ExportObjectSpaceHierarchy(Exporter *exporter,
267                                                                        const ObjectContainer &objects,
268                                                                        AxisAlignedBox3 *bbox,
269                                                                        const float maxRenderCost,
270                                                                        const bool exportBounds = true) const;
271
272        /** Returns intersectable pierced by this ray.
273        */
274        Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
275 
276        Intersectable *GetIntersectable(Intersectable *obj, const Vector3 &point) const;
277
278        /** Export object space partition bounding boxes.
279        */
280        void ExportBoundingBoxes(OUT_STREAM &stream, const ObjectContainer &objects);
281
282        friend std::ostream &operator<<(std::ostream &s, const HierarchyManager &hm)
283        {
284                hm.PrintHierarchyStatistics(s);
285                return s;
286        }
287
288        HierarchyStatistics &GetHierarchyStats() { return mHierarchyStats; };
289
290        inline bool ConsiderMemory() const { return mConsiderMemory; }
291       
292        void EvaluateSubdivision(std::ofstream &splitsStats,
293                                                          const int splitsStepSize,
294                                                          const bool useFilter,
295                                                          const bool useHisto,
296                                                          const int histoMem,
297                                                          const int pass);
298
299
300        void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
301
302        int CompressObjectSpace();
303        void CreateUniqueObjectIds();
304
305        float EvalCorrectedPvs(const float pvsFront,
306                                                   const float totalPvs,
307                                                   const float raysPerObjects) const;
308
309
310        /** Casts line segment into the view cells tree.
311                @param origin the origin of the line segment
312                @param termination the end point of the line segment
313                @returns view cells intersecting the line segment.
314        */
315    int CastLineSegment(const Vector3 &origin,
316                                                const Vector3 &termination,
317                                                ViewCellContainer &viewcells,
318                                                const bool useMailboxing = true);
319
320        int CastLineSegment(RayPacket &packet);
321
322
323protected:
324
325        void PrintTimings(const bool osp);
326
327        /** Returns true if the global termination criteria were met.
328        */
329        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
330
331        /** Prepare construction of the hierarchies, set parameters, compute
332                first split candidates.
333        */
334        void PrepareObjectSpaceSubdivision(SplitQueue &tQueue,
335                                                                           const VssRayContainer &sampleRays,
336                                                                           const ObjectContainer &objects);
337
338
339        /** Create bounding box and root.
340        */
341        void InitialiseObjectSpaceSubdivision(const ObjectContainer &objects);
342
343        /** Returns memory usage of object space hierarchy.
344        */
345        float GetObjectSpaceMemUsage() const;
346
347
348        //////////////////////////////
349        // the main loop
350
351        /** This is for interleaved construction / sequential construction.
352        */
353        void RunConstruction(const bool repairQueue,
354                                                 const VssRayContainer &sampleRays,
355                                                 const ObjectContainer &objects,
356                                                 AxisAlignedBox3 *forcedViewSpace);
357       
358        /** This is for interleaved construction using some objects
359                and some view space splits.
360        */
361        int RunConstruction(SplitQueue &splitQueue,
362                                                SubdivisionCandidateContainer &chosenCandidates,
363                                                //const float minRenderCostDecr,
364                                                SubdivisionCandidate *oldCandidate,
365                                                const int minSteps,
366                                                const int maxSteps);
367
368        /** Default subdivision method.
369        */
370        void RunConstruction(const bool repairQueue);
371       
372       
373        ////////////////////////////////////////////////
374
375        /** Evaluates the subdivision candidate and executes the split.
376        */
377        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
378                                                                   SplitQueue &splitQueue,
379                                                                   //const bool repairQueue,
380                                                                   std::vector<SubdivisionCandidate *> &dirtyList
381                                                                   );
382
383        /** Tests if hierarchy construction is finished.
384        */
385        bool FinishedConstruction() const;
386
387        /** Returns next subdivision candidate from the split queue.
388        */
389        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
390
391        /** Repairs the dirty entries of the subdivision candidate queue. The
392                list of entries is given in the dirty list.
393
394                @returns number of repaired candidates
395        */
396        int RepairQueue(const SubdivisionCandidateContainer &dirtyList,
397                                        SplitQueue &splitQueue,
398                                        const bool recomputeSplitPlaneOnRepair);
399
400        /** Collect subdivision candidates which were affected by the splits from the
401                chosenCandidates list.
402        */
403        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
404                                                                SubdivisionCandidateContainer &dirtyList);
405
406        /** Print subdivision stats for log.
407        */
408        void PrintSubdivisionStats();
409
410        void AddSubdivisionStats(const int splits,
411                                                         const float renderCostDecr,
412                                                         const float totalRenderCost,
413                                                         const int totalPvsEntries,
414                                                         const float memory,
415                                                         const float renderCostPerStorage,
416                                                         const float vspOspRatio);
417
418        /** Collect affected view space candidates.
419        */
420        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
421                                                                   SubdivisionCandidateContainer &dirtyList);
422
423        /** Collect affected object space candidates.
424        */
425        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
426                                                                         SubdivisionCandidateContainer &dirtyList);
427               
428        /** Export object space partition tree.
429        */
430        void ExportOspTree(Exporter *exporter,
431                                           const ObjectContainer &objects) const;
432
433        /** Parse the environment variables.
434        */
435        void ParseEnvironment();
436
437        bool StartObjectSpaceSubdivision() const;
438        bool StartViewSpaceSubdivision() const;
439
440
441        ////////////////////////////
442        // Helper function for preparation of subdivision
443
444        /** Prepare bv hierarchy for subdivision
445        */
446        void PrepareBvHierarchy(SplitQueue &tQueue,
447                                                        const VssRayContainer &sampleRays,
448                                                        const ObjectContainer &objects);
449
450        /** Prepare object space kd tree for subdivision.
451        */
452        void PrepareOspTree(SplitQueue &tQueue,
453                                                const VssRayContainer &sampleRays,
454                                                const ObjectContainer &objects);
455
456        /** Prepare view space subdivision and add candidate to queue.
457        */
458        void PrepareViewSpaceSubdivision(SplitQueue &tQueue,
459                                                                         const VssRayContainer &sampleRays,
460                                                                         const ObjectContainer &objects);
461
462        /** Was object space subdivision already constructed?
463        */
464        bool ObjectSpaceSubdivisionConstructed() const;
465       
466        /** Was view space subdivision already constructed?
467        */
468        bool ViewSpaceSubdivisionConstructed() const;
469
470        /** Reset the split queue, i.e., reevaluate the split candidates.
471        */
472    void ResetQueue(SplitQueue &splitQueue, const bool recomputeSplitPlane);
473
474        /** After the suddivision has ended, do some final tasks.
475        */
476        void FinishObjectSpaceSubdivision(const ObjectContainer &objects,
477                                                                          const bool removeRayRefs = true) const;
478
479        /** Returns depth of object space subdivision.
480        */
481        int GetObjectSpaceSubdivisionDepth() const;
482
483        /** Returns number of leaves in object space subdivision.
484        */
485        int GetObjectSpaceSubdivisionLeaves() const;
486        int GetObjectSpaceSubdivisionNodes() const;
487
488        /** Construct object space partition interleaved with view space partition.
489                Each time the best object or view space candidate is selected
490                for the next split.
491        */
492        void ConstructInterleaved(const VssRayContainer &sampleRays,
493                                                          const ObjectContainer &objects,
494                                                          AxisAlignedBox3 *forcedViewSpace);
495
496        /** Construct object space partition interleaved with view space partition.
497                The method chooses a number candidates of each type for subdivision.
498                The number is determined by the "gradient", i.e., the render cost decrease.
499                Once this render cost decrease is lower than the render cost decrease
500                for the splits of previous type, the method will stop current subdivision and
501                evaluate if view space or object space would be the beneficial for the
502                next number of split.
503        */
504        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
505                                                                                  const ObjectContainer &objects,
506                                                                                  AxisAlignedBox3 *forcedViewSpace);
507
508        /** Use iteration to construct the object space hierarchy.
509        */
510        void ConstructMultiLevel(const VssRayContainer &sampleRays,
511                                                         const ObjectContainer &objects,
512                                                         AxisAlignedBox3 *forcedViewSpace);
513
514        /** Based on a given subdivision, we try to optimize using an
515                multiple iteration over view and object space.
516        */
517        void OptimizeMultiLevel(const VssRayContainer &sampleRays,                                                                                       
518                                                        const ObjectContainer &objects,
519                                                        AxisAlignedBox3 *forcedViewSpace);
520
521        /** Reset the object space subdivision.
522                E.g., deletes hierarchy and resets stats.
523                so construction can be restarted.
524        */
525        void ResetObjectSpaceSubdivision(SplitQueue &tQueue,
526                                                                         const VssRayContainer &rays,
527                                                                         const ObjectContainer &objects);
528
529        void ResetViewSpaceSubdivision(SplitQueue &tQueue,
530                                                                   const VssRayContainer &rays,
531                                                                   const ObjectContainer &objects,
532                                                                   AxisAlignedBox3 *forcedViewSpace);
533
534        void CreateTraversalTree();
535
536        ///////////////////////////
537
538        void ExportStats(std::ofstream &stats,
539                                         SplitQueue &tQueue,
540                                         const ObjectContainer &objects);
541
542        void CollectBestSet(const int maxSplits,
543                                                const float maxMemoryCost,
544                                                ViewCellContainer &viewCells,
545                                                vector<BvhNode *> &bvhNodes);
546
547        int ExtractStatistics(const int maxSplits,
548                                                  const float maxMemoryCost,
549                                                  float &renderCost,
550                                                  float &memory,
551                                                  int &pvsEntries,
552                                                  int &viewSpaceSplits,
553                                                  int &objectSpaceSplits,
554                                                  const bool useFilter,
555                                                  const bool useHisto,
556                                                  const int histoMem,
557                                                  const int pass,
558                                                  bool &histoUsed);
559
560        void ComputePvs(const ObjectPvs &pvs, float &triangles, int &pvsEntries);
561        void GetPvsIncrementially(ViewCell *vc, ObjectPvs &pvs) const;
562        void PullUpPvsIncrementally(ViewCell *viewCell) const;
563        void GetPvsRecursive(ViewCell *vc, ObjectPvs &pvs) const;
564        void GetPvsEfficiently(ViewCell *vc, ObjectPvs &pvs) const;
565
566        float EvalFullMem() const;
567
568        ViewCellsManager *GetViewCellsManager();
569
570protected:
571
572        /** construction types
573                sequential: construct first view space, then object space
574                interleaved: construct view space and object space fully interleaved
575                gradient: construct view space / object space until a threshold is reached
576                multilevel: iterate until subdivisions converge to the optimum.
577        */
578        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
579
580        /// type of hierarchy construction
581        int mConstructionType;
582
583        /// Type of object space partition
584        int mObjectSpaceSubdivisionType;
585        /// Type of view space partition
586    int mViewSpaceSubdivisionType;
587
588        /// the traversal queue
589        SplitQueue mTQueue;
590       
591        ////////////
592        //-- helper variables
593       
594        // the original osp type
595        int mSavedObjectSpaceSubdivisionType;
596        // the original vsp type
597        int mSavedViewSpaceSubdivisionType;
598       
599
600        ///////////////////
601        // Hierarchies
602
603        /// view space hierarchy
604        VspTree *mVspTree;
605        /// object space partition kd tree
606        OspTree *mOspTree;
607
608        float mInitialRenderCost;
609       
610        //float mMaxAvgRayContri;
611        //float mMinAvgRayContri;
612
613        float mMaxAvgRaysPerObject;
614        float mMinAvgRaysPerObject;
615
616        // quick hack:
617public:
618        /// bounding volume hierarchy
619        BvHierarchy *mBvHierarchy;
620       
621        bool mUseTraversalTree;
622
623        float mMinRenderCost;
624
625protected:
626
627
628        //////////
629        //-- global termination criteria
630
631        /// the mininal acceptable cost ratio for a split
632        float mTermMinGlobalCostRatio;
633        /// the threshold for global cost miss tolerance
634        int mTermGlobalCostMissTolerance;
635        /// maximum number of leaves
636        int mTermMaxLeaves;
637        /// Maximal allowed memory consumption.
638        float mTermMaxMemory;
639
640
641        ////////////////////
642
643        /// number of minimal steps of the same type
644        int mMinStepsOfSameType;
645        int mMaxStepsOfSameType;
646
647        /// statistics about the hierarchy
648        HierarchyStatistics mHierarchyStats;
649
650        int mMinDepthForObjectSpaceSubdivion;
651        int mMinDepthForViewSpaceSubdivion;
652       
653        //int mMinRenderCostDecrease;
654
655        std::ofstream mSubdivisionStats;
656
657        /// if the queue should be repaired after a subdivision steps
658        bool mRepairQueue;
659
660        bool mStartWithObjectSpace;
661        /** if multi level construction method should be used
662                where we iterate over both hierarchies until we
663                converge to the optimum.
664        */
665        bool mUseMultiLevelConstruction;
666
667        /// number of iteration steps for multilevel approach   
668        int mNumMultiLevels;
669
670        /** if split plane should be recomputed for the repair.
671                Otherwise only the priority is recomputed, the
672                split plane itself stays the same
673        */
674        bool mRecomputeSplitPlaneOnRepair;
675
676        /** If memory should be considered during choosing
677                of the next split type during gradient method.
678        */
679        bool mConsiderMemory;
680
681        TraversalTree *mTraversalTree;
682
683        int mMaxRepairs;
684
685        int mTimeStamp;
686        friend VspTree;
687        friend OspTree;
688        friend BvHierarchy;
689
690        float mPriority;
691
692        friend ViewCellsParseHandlers;
693
694        ViewCellContainer mOldViewCells;
695};
696
697}
698
699#endif
Note: See TracBrowser for help on using the repository browser.