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

Revision 2332, 18.6 KB checked in by mattausch, 17 years ago (diff)

implemented part of rendering estimation of wimmer et al. for view space / object space subdivision.
warning: not working with undersampling estimation + local visibility based subdivision.

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       
324protected:
325
326        void PrintTimings(const bool osp);
327
328        /** Returns true if the global termination criteria were met.
329        */
330        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
331
332        /** Prepare construction of the hierarchies, set parameters, compute
333                first split candidates.
334        */
335        void PrepareObjectSpaceSubdivision(SplitQueue &tQueue,
336                                                                           const VssRayContainer &sampleRays,
337                                                                           const ObjectContainer &objects);
338
339
340        /** Create bounding box and root.
341        */
342        void InitialiseObjectSpaceSubdivision(const ObjectContainer &objects);
343
344        /** Returns memory usage of object space hierarchy.
345        */
346        float GetObjectSpaceMemUsage() const;
347
348
349        //////////////////////////////
350        // the main loop
351
352        /** This is for interleaved construction / sequential construction.
353        */
354        void RunConstruction(const bool repairQueue,
355                                                 const VssRayContainer &sampleRays,
356                                                 const ObjectContainer &objects,
357                                                 AxisAlignedBox3 *forcedViewSpace);
358       
359        /** This is for interleaved construction using some objects
360                and some view space splits.
361        */
362        int RunConstruction(SplitQueue &splitQueue,
363                                                SubdivisionCandidateContainer &chosenCandidates,
364                                                //const float minRenderCostDecr,
365                                                SubdivisionCandidate *oldCandidate,
366                                                const int minSteps,
367                                                const int maxSteps);
368
369        /** Default subdivision method.
370        */
371        void RunConstruction(const bool repairQueue);
372       
373       
374        ////////////////////////////////////////////////
375
376        /** Evaluates the subdivision candidate and executes the split.
377        */
378        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
379                                                                   SplitQueue &splitQueue,
380                                                                   //const bool repairQueue,
381                                                                   std::vector<SubdivisionCandidate *> &dirtyList
382                                                                   );
383
384        /** Tests if hierarchy construction is finished.
385        */
386        bool FinishedConstruction() const;
387
388        /** Returns next subdivision candidate from the split queue.
389        */
390        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
391
392        /** Repairs the dirty entries of the subdivision candidate queue. The
393                list of entries is given in the dirty list.
394
395                @returns number of repaired candidates
396        */
397        int RepairQueue(const SubdivisionCandidateContainer &dirtyList,
398                                        SplitQueue &splitQueue,
399                                        const bool recomputeSplitPlaneOnRepair);
400
401        /** Collect subdivision candidates which were affected by the splits from the
402                chosenCandidates list.
403        */
404        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
405                                                                SubdivisionCandidateContainer &dirtyList);
406
407        /** Print subdivision stats for log.
408        */
409        void PrintSubdivisionStats();
410
411        void AddSubdivisionStats(const int splits,
412                                                         const float renderCostDecr,
413                                                         const float totalRenderCost,
414                                                         const int totalPvsEntries,
415                                                         const float memory,
416                                                         const float renderCostPerStorage,
417                                                         const float vspOspRatio);
418
419        /** Collect affected view space candidates.
420        */
421        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
422                                                                   SubdivisionCandidateContainer &dirtyList);
423
424        /** Collect affected object space candidates.
425        */
426        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
427                                                                         SubdivisionCandidateContainer &dirtyList);
428               
429        /** Export object space partition tree.
430        */
431        void ExportOspTree(Exporter *exporter,
432                                           const ObjectContainer &objects) const;
433
434        /** Parse the environment variables.
435        */
436        void ParseEnvironment();
437
438        bool StartObjectSpaceSubdivision() const;
439        bool StartViewSpaceSubdivision() const;
440
441
442        ////////////////////////////
443        // Helper function for preparation of subdivision
444
445        /** Prepare bv hierarchy for subdivision
446        */
447        void PrepareBvHierarchy(SplitQueue &tQueue,
448                                                        const VssRayContainer &sampleRays,
449                                                        const ObjectContainer &objects);
450
451        /** Prepare object space kd tree for subdivision.
452        */
453        void PrepareOspTree(SplitQueue &tQueue,
454                                                const VssRayContainer &sampleRays,
455                                                const ObjectContainer &objects);
456
457        /** Prepare view space subdivision and add candidate to queue.
458        */
459        void PrepareViewSpaceSubdivision(SplitQueue &tQueue,
460                                                                         const VssRayContainer &sampleRays,
461                                                                         const ObjectContainer &objects);
462
463        /** Was object space subdivision already constructed?
464        */
465        bool ObjectSpaceSubdivisionConstructed() const;
466       
467        /** Was view space subdivision already constructed?
468        */
469        bool ViewSpaceSubdivisionConstructed() const;
470
471        /** Reset the split queue, i.e., reevaluate the split candidates.
472        */
473    void ResetQueue(SplitQueue &splitQueue, const bool recomputeSplitPlane);
474
475        /** After the suddivision has ended, do some final tasks.
476        */
477        void FinishObjectSpaceSubdivision(const ObjectContainer &objects,
478                                                                          const bool removeRayRefs = true) const;
479
480        /** Returns depth of object space subdivision.
481        */
482        int GetObjectSpaceSubdivisionDepth() const;
483
484        /** Returns number of leaves in object space subdivision.
485        */
486        int GetObjectSpaceSubdivisionLeaves() const;
487        int GetObjectSpaceSubdivisionNodes() const;
488
489        /** Construct object space partition interleaved with view space partition.
490                Each time the best object or view space candidate is selected
491                for the next split.
492        */
493        void ConstructInterleaved(const VssRayContainer &sampleRays,
494                                                          const ObjectContainer &objects,
495                                                          AxisAlignedBox3 *forcedViewSpace);
496
497        /** Construct object space partition interleaved with view space partition.
498                The method chooses a number candidates of each type for subdivision.
499                The number is determined by the "gradient", i.e., the render cost decrease.
500                Once this render cost decrease is lower than the render cost decrease
501                for the splits of previous type, the method will stop current subdivision and
502                evaluate if view space or object space would be the beneficial for the
503                next number of split.
504        */
505        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
506                                                                                  const ObjectContainer &objects,
507                                                                                  AxisAlignedBox3 *forcedViewSpace);
508
509        /** Use iteration to construct the object space hierarchy.
510        */
511        void ConstructMultiLevel(const VssRayContainer &sampleRays,
512                                                         const ObjectContainer &objects,
513                                                         AxisAlignedBox3 *forcedViewSpace);
514
515        /** Based on a given subdivision, we try to optimize using an
516                multiple iteration over view and object space.
517        */
518        void OptimizeMultiLevel(const VssRayContainer &sampleRays,                                                                                       
519                                                        const ObjectContainer &objects,
520                                                        AxisAlignedBox3 *forcedViewSpace);
521
522        /** Reset the object space subdivision.
523                E.g., deletes hierarchy and resets stats.
524                so construction can be restarted.
525        */
526        void ResetObjectSpaceSubdivision(SplitQueue &tQueue,
527                                                                         const VssRayContainer &rays,
528                                                                         const ObjectContainer &objects);
529
530        void ResetViewSpaceSubdivision(SplitQueue &tQueue,
531                                                                   const VssRayContainer &rays,
532                                                                   const ObjectContainer &objects,
533                                                                   AxisAlignedBox3 *forcedViewSpace);
534
535        void CreateTraversalTree();
536
537        ///////////////////////////
538
539        void ExportStats(std::ofstream &stats,
540                                         SplitQueue &tQueue,
541                                         const ObjectContainer &objects);
542
543        void CollectBestSet(const int maxSplits,
544                                                const float maxMemoryCost,
545                                                ViewCellContainer &viewCells,
546                                                vector<BvhNode *> &bvhNodes);
547
548        int ExtractStatistics(const int maxSplits,
549                                                  const float maxMemoryCost,
550                                                  float &renderCost,
551                                                  float &memory,
552                                                  int &pvsEntries,
553                                                  int &viewSpaceSplits,
554                                                  int &objectSpaceSplits,
555                                                  const bool useFilter,
556                                                  const bool useHisto,
557                                                  const int histoMem,
558                                                  const int pass,
559                                                  bool &histoUsed);
560
561        void ComputePvs(const ObjectPvs &pvs, float &triangles, int &pvsEntries);
562        void GetPvsIncrementially(ViewCell *vc, ObjectPvs &pvs) const;
563        void PullUpPvsIncrementally(ViewCell *viewCell) const;
564        void GetPvsRecursive(ViewCell *vc, ObjectPvs &pvs) const;
565        void GetPvsEfficiently(ViewCell *vc, ObjectPvs &pvs) const;
566
567        float EvalFullMem() const;
568
569        ViewCellsManager *GetViewCellsManager();
570
571protected:
572
573        /** construction types
574                sequential: construct first view space, then object space
575                interleaved: construct view space and object space fully interleaved
576                gradient: construct view space / object space until a threshold is reached
577                multilevel: iterate until subdivisions converge to the optimum.
578        */
579        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
580
581        /// type of hierarchy construction
582        int mConstructionType;
583
584        /// Type of object space partition
585        int mObjectSpaceSubdivisionType;
586        /// Type of view space partition
587    int mViewSpaceSubdivisionType;
588
589        /// the traversal queue
590        SplitQueue mTQueue;
591       
592        ////////////
593        //-- helper variables
594       
595        // the original osp type
596        int mSavedObjectSpaceSubdivisionType;
597        // the original vsp type
598        int mSavedViewSpaceSubdivisionType;
599       
600
601        ///////////////////
602        // Hierarchies
603
604        /// view space hierarchy
605        VspTree *mVspTree;
606        /// object space partition kd tree
607        OspTree *mOspTree;
608
609        float mInitialRenderCost;
610       
611        //float mMaxAvgRayContri;
612        //float mMinAvgRayContri;
613
614        float mMaxAvgRaysPerObject;
615        float mMinAvgRaysPerObject;
616
617        // quick hack:
618public:
619        /// bounding volume hierarchy
620        BvHierarchy *mBvHierarchy;
621       
622        bool mUseTraversalTree;
623
624        float mMinRenderCost;
625
626protected:
627
628
629        //////////
630        //-- global termination criteria
631
632        /// the mininal acceptable cost ratio for a split
633        float mTermMinGlobalCostRatio;
634        /// the threshold for global cost miss tolerance
635        int mTermGlobalCostMissTolerance;
636        /// maximum number of leaves
637        int mTermMaxLeaves;
638        /// Maximal allowed memory consumption.
639        float mTermMaxMemory;
640
641
642        ////////////////////
643
644        /// number of minimal steps of the same type
645        int mMinStepsOfSameType;
646        int mMaxStepsOfSameType;
647
648        /// statistics about the hierarchy
649        HierarchyStatistics mHierarchyStats;
650
651        int mMinDepthForObjectSpaceSubdivion;
652        int mMinDepthForViewSpaceSubdivion;
653       
654        //int mMinRenderCostDecrease;
655
656        std::ofstream mSubdivisionStats;
657
658        /// if the queue should be repaired after a subdivision steps
659        bool mRepairQueue;
660
661        bool mStartWithObjectSpace;
662        /** if multi level construction method should be used
663                where we iterate over both hierarchies until we
664                converge to the optimum.
665        */
666        bool mUseMultiLevelConstruction;
667
668        /// number of iteration steps for multilevel approach   
669        int mNumMultiLevels;
670
671        /** if split plane should be recomputed for the repair.
672                Otherwise only the priority is recomputed, the
673                split plane itself stays the same
674        */
675        bool mRecomputeSplitPlaneOnRepair;
676
677        /** If memory should be considered during choosing
678                of the next split type during gradient method.
679        */
680        bool mConsiderMemory;
681
682        TraversalTree *mTraversalTree;
683
684        int mMaxRepairs;
685
686        int mTimeStamp;
687        friend VspTree;
688        friend OspTree;
689        friend BvHierarchy;
690
691        float mPriority;
692
693        friend ViewCellsParseHandlers;
694
695        ViewCellContainer mOldViewCells;
696};
697
698}
699
700#endif
Note: See TracBrowser for help on using the repository browser.