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

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