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

Revision 1845, 17.6 KB checked in by mattausch, 18 years ago (diff)

improved object pvs

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