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

Revision 2130, 18.4 KB checked in by mattausch, 17 years ago (diff)

runs also under debug mode now

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