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

Revision 2116, 18.3 KB checked in by mattausch, 17 years ago (diff)

implemented hashpvs

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