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

Revision 1743, 17.3 KB checked in by bittner, 18 years ago (diff)

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