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

Revision 1635, 14.0 KB checked in by mattausch, 18 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;
43
44
45
46/** View space / object space hierarchy statistics.
47*/
48class HierarchyStatistics: public StatisticsBase
49{
50public:
51        /// total number of entries in the pvs
52        int mPvsEntries;
53        /// storage cost
54        int mMemory;
55        /// total number of nodes
56        int mNodes;
57        /// maximal reached depth
58        int mMaxDepth;
59        /// accumulated depth
60        int mAccumDepth;
61        /// time spent for queue repair
62        float mRepairTime;
63
64        // global cost ratio violations
65        int mGlobalCostMisses;
66        /// total cost of subdivision
67        float mTotalCost;
68        /// render cost decrease of subdivision
69        float mRenderCostDecrease;
70
71        // Constructor
72        HierarchyStatistics()
73        {
74                Reset();
75        }
76
77        int Nodes() const {return mNodes;}
78        int Interior() const { return mNodes / 2; }
79        int Leaves() const { return (mNodes / 2) + 1; }
80       
81        // TODO: computation wrong
82        double AvgDepth() const { return mAccumDepth / (double)Leaves();}
83
84        void Reset()
85        {
86                mGlobalCostMisses = 0;
87                mTotalCost = 0;
88                mRenderCostDecrease = 0;
89
90                mNodes = 0;
91                mMaxDepth = 0;
92                mAccumDepth = 0;
93                mRepairTime = 0;
94                mMemory = 0;
95                mPvsEntries = 0;
96        }
97
98        void Print(ostream &app) const;
99
100        friend ostream &operator<<(ostream &s, const HierarchyStatistics &stat)
101        {
102                stat.Print(s);
103                return s;
104        }
105};
106
107
108/** This class implements a structure holding two different hierarchies,
109        one for object space partitioning and one for view space partitioning.
110
111        The object space and the view space are subdivided using a cost heuristics.
112        If an object space split or a view space split is chosen is also evaluated
113        based on the heuristics.
114       
115        The view space heuristics is evaluated by weighting and adding the pvss of the back and
116        front node of each specific split. unlike for the standalone method vspbsp tree,
117        the pvs of an object would not be the pvs of single object but that of all objects
118        which are contained in the same leaf of the object subdivision. This could be done
119        by storing the pointer to the object space partition parent, which would allow access to all children.
120        Another possibility is to include traced kd-cells in the ray casing process.
121
122        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
123        the contribution to an object to the pvs is the number of view cells it can be seen from.
124
125        @note
126        There is a potential efficiency problem involved in a sense that once a certain type
127        of split is chosen for view space / object space, the candidates for the next split of
128        object space / view space must be reevaluated.
129*/
130class HierarchyManager
131{
132        friend VspTree;
133        friend OspTree;
134        friend BvHierarchy;
135        friend ViewCellsParseHandlers;
136
137public:
138        /** Constructor with the view space partition tree and
139                the object space hierarchy type as argument.
140        */
141        HierarchyManager(const int objectSpaceHierarchyType);
142        /** Hack: OspTree will copy the content from this kd tree.
143                Only view space hierarchy will be constructed.
144        */
145        HierarchyManager(KdTree *kdTree);
146
147        /** Deletes space partition and view space partition.
148        */
149        ~HierarchyManager();
150
151        /** Constructs the view space and object space subdivision from a given set of rays
152                and a set of objects.
153                @param sampleRays the set of sample rays the construction is based on
154                @param objects the set of objects
155        */
156        void Construct(
157                const VssRayContainer &sampleRays,
158                const ObjectContainer &objects,
159                AxisAlignedBox3 *forcedViewSpace);
160
161        enum
162        {
163                NO_OBJ_SUBDIV,
164                KD_BASED_OBJ_SUBDIV,
165                BV_BASED_OBJ_SUBDIV
166        };
167
168        enum
169        {
170                NO_VIEWSPACE_SUBDIV,
171                KD_BASED_VIEWSPACE_SUBDIV
172        };
173
174        /** The type of object space subdivison
175        */
176        int GetObjectSpaceSubdivisionType() const;     
177        /** The type of view space space subdivison
178        */
179        int GetViewSpaceSubdivisionType() const;
180        /** Sets a pointer to the view cells manager.
181        */             
182        void SetViewCellsManager(ViewCellsManager *vcm);
183        /** Sets a pointer to the view cells tree.
184        */
185        void SetViewCellsTree(ViewCellsTree *vcTree);
186        /** Exports the object hierarchy to disc.
187        */
188        void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
189        /** Adds a sample to the pvs of the specified view cell.
190        */
191        bool AddSampleToPvs(
192                Intersectable *obj,
193                const Vector3 &hitPoint,
194                ViewCell *vc,
195                const float pdf,
196                float &contribution) const;
197
198        /** Print out statistics.
199        */
200        void PrintHierarchyStatistics(ostream &stream) const;
201
202        /** Returns the view space partition tree.
203        */
204        VspTree *GetVspTree();
205
206        /** Returns view space bounding box.
207        */
208        //AxisAlignedBox3 GetViewSpaceBox() const;
209
210        /** Returns object space bounding box.
211        */
212        AxisAlignedBox3 GetObjectSpaceBox() const;
213
214        /** Exports object space hierarchy for visualization.
215        */
216        void ExportObjectSpaceHierarchy(Exporter *exporter,
217                                                                        const ObjectContainer &objects,
218                                                                        const AxisAlignedBox3 *bbox,
219                                                                        const bool exportBounds = true) const;
220
221        /** Returns intersectable pierced by this ray.
222        */
223        Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
224
225        /** Export object space partition bounding boxes.
226        */
227        void ExportBoundingBoxes(OUT_STREAM &stream, const ObjectContainer &objects);
228
229        friend ostream &operator<<(ostream &s, const HierarchyManager &hm)
230        {
231                hm.PrintHierarchyStatistics(s);
232                return s;
233        }
234
235protected:
236
237        /** Returns true if the global termination criteria were met.
238        */
239        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
240
241        /** Prepare construction of the hierarchies, set parameters, compute
242                first split candidates.
243        */
244        SubdivisionCandidate *PrepareObjectSpaceSubdivision(const VssRayContainer &sampleRays,
245                                                                                                                const ObjectContainer &objects);
246
247
248        //////////////////////////////
249        // the main loop
250        //////////////////////
251
252        /** This is for interleaved construction / sequential construction.
253        */
254        void RunConstruction(const bool repairQueue,
255                                                 const VssRayContainer &sampleRays,
256                                                 const ObjectContainer &objects,
257                                                 AxisAlignedBox3 *forcedViewSpace,
258                                                 SubdivisionCandidate *firstVsp);
259       
260        /** This is for interleaved construction using some objects
261                and some view space splits.
262        */
263        int RunConstruction(SplitQueue &splitQueue,
264                                                SubdivisionCandidateContainer &chosenCandidates,
265                                                const float minRenderCostDecr,
266                                                const int minSteps);
267
268        /** Default subdivision method.
269        */
270        void RunConstruction(const bool repairQueue);
271               
272        ////////////////////////////////////////////////
273
274        /** Evaluates the subdivision candidate and executes the split.
275        */
276        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
277                                                                   SplitQueue &splitQueue,
278                                                                   const bool repairQueue);
279
280        /** Tests if hierarchy construction is finished.
281        */
282        bool FinishedConstruction() const;
283
284        /** Returns next subdivision candidate from the split queue.
285        */
286        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
287
288        /** Repairs the dirty entries of the subdivision candidate queue. The
289                list of entries is given in the dirty list.
290        */
291        void RepairQueue(const SubdivisionCandidateContainer &dirtyList,
292                                         SplitQueue &splitQueue,
293                                         const bool recomputeSplitPlaneOnRepair);
294
295        /** Collect subdivision candidates which were affected by the splits from the
296                chosenCandidates list.
297        */
298        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
299                                                                SubdivisionCandidateContainer &dirtyList);
300
301        /** Evaluate subdivision stats for log.
302        */
303        void EvalSubdivisionStats();
304
305        void AddSubdivisionStats(const int splits,
306                                                         const float renderCostDecr,
307                                                         const float totalRenderCost,
308                                                         const int totalPvsEntries,
309                                                         const int memory,
310                                                         const float renderCostPerStorage);
311
312        bool AddSampleToPvs(Intersectable *obj,
313                                                const float pdf,
314                                                float &contribution) const;
315
316        /** Collect affected view space candidates.
317        */
318        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
319                                                                   SubdivisionCandidateContainer &dirtyList);
320
321        /** Collect affected object space candidates.
322        */
323        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
324                                                                         SubdivisionCandidateContainer &dirtyList);
325               
326        /** Export object space partition tree.
327        */
328        void ExportOspTree(Exporter *exporter,
329                                           const ObjectContainer &objects) const;
330
331        /** Parse the environment variables.
332        */
333        void ParseEnvironment();
334
335        bool StartObjectSpaceSubdivision() const;
336        bool StartViewSpaceSubdivision() const;
337
338        ////////////////////////////
339        // Helper function for preparation of subdivision
340        ///////
341
342        /** Prepare bv hierarchy for subdivision
343        */
344        SubdivisionCandidate *PrepareBvHierarchy(const VssRayContainer &sampleRays,
345                                                                           const ObjectContainer &objects);
346
347        /** Prepare object space kd tree for subdivision.
348        */
349        SubdivisionCandidate *PrepareOspTree(const VssRayContainer &sampleRays,
350                                                                   const ObjectContainer &objects);
351
352        /** Prepare view space subdivision and add candidate to queue.
353        */
354        SubdivisionCandidate *PrepareViewSpaceSubdivision(const VssRayContainer &sampleRays,
355                                                                                                          const ObjectContainer &objects);
356
357        /** Was object space subdivision already constructed?
358        */
359        bool ObjectSpaceSubdivisionConstructed() const;
360       
361        /** Was view space subdivision already constructed?
362        */
363        bool ViewSpaceSubdivisionConstructed() const;
364
365        /** Reset the split queue, i.e., reevaluate the split candidates.
366        */
367    void ResetQueue();
368
369        /** After the suddivision has ended, do some final tasks.
370        */
371        void FinishObjectSpaceSubdivision(const ObjectContainer &objects) const;
372
373        /** Returns depth of object space subdivision.
374        */
375        int GetObjectSpaceSubdivisionDepth() const;
376
377        /** Construct object space partition interleaved with view space partition.
378                Each time the best object or view space candidate is selected
379                for the next split.
380        */
381        void ConstructInterleaved(const VssRayContainer &sampleRays,
382                                                          const ObjectContainer &objects,
383                                                          AxisAlignedBox3 *forcedViewSpace);
384
385        /** Construct object space partition interleaved with view space partition.
386                The method chooses a number candidates of each type for subdivision.
387                The number is determined by the "gradient", i.e., the render cost decrease.
388                Once this render cost decrease is lower than the render cost decrease
389                for the splits of previous type, the method will stop current subdivision and
390                evaluate if view space or object space would be the beneficial for the
391                next number of split.
392        */
393        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
394                                                                                  const ObjectContainer &objects,
395                                                                                  AxisAlignedBox3 *forcedViewSpace);
396
397        /** Use iteration to construct the object space hierarchy.
398        */
399        void ConstructMultiLevel(const VssRayContainer &sampleRays,
400                                                         const ObjectContainer &objects,
401                                                         AxisAlignedBox3 *forcedViewSpace);
402
403        /** Reset the object space subdivision.
404                E.g., deletes hierarchy and resets stats.
405                so construction can be restarted.
406        */
407        SubdivisionCandidate *ResetObjectSpaceSubdivision(const VssRayContainer &rays,
408                                                                                                          const ObjectContainer &objects);
409
410        SubdivisionCandidate *ResetViewSpaceSubdivision(const VssRayContainer &rays,
411                                                                                                        const ObjectContainer &objects);
412
413
414protected:
415
416        /** construction types
417                sequential: construct first view space, then object space
418                interleaved: construct view space and object space fully interleaved
419                gradient: construct view space / object space until a threshold is reached
420                multilevel: iterate until subdivisions converge to the optimum.
421        */
422        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
423
424        /// type of hierarchy construction
425        int mConstructionType;
426
427        /// Type of object space partition
428        int mObjectSpaceSubdivisionType;
429        /// Type of view space partition
430    int mViewSpaceSubdivisionType;
431
432        /// the traversal queue
433        SplitQueue mTQueue;
434       
435        ////////////
436        //-- helper variables
437       
438        // the original osp type
439        int mSavedObjectSpaceSubdivisionType;
440        // the original vsp type
441        int mSavedViewSpaceSubdivisionType;
442        /// the current subdivision candidate
443        //SubdivisionCandidate *mCurrentCandidate;
444
445
446        ///////////////////
447        // Hierarchies
448
449        /// view space hierarchy
450        VspTree *mVspTree;
451        /// object space partition kd tree
452        OspTree *mOspTree;
453
454        public:
455        /// bounding volume hierarchy
456        BvHierarchy *mBvHierarchy;
457       
458protected:
459
460
461        //////////
462        //-- global termination criteria
463
464        /// the mininal acceptable cost ratio for a split
465        float mTermMinGlobalCostRatio;
466        /// the threshold for global cost miss tolerance
467        int mTermGlobalCostMissTolerance;
468        /// maximum number of leaves
469        int mTermMaxLeaves;
470
471        ////////////////////
472
473        /// statistics about the hierarchy
474        HierarchyStatistics mHierarchyStats;
475
476        int mMinDepthForObjectSpaceSubdivion;
477        int mMinDepthForViewSpaceSubdivion;
478       
479        //int mMinRenderCostDecrease;
480
481        ofstream mSubdivisionStats;
482
483        /// if the queue should be repaired after a subdivision steps
484        bool mRepairQueue;
485
486        bool mStartWithObjectSpace;
487        /** if multi level construction method should be used
488                where we iterate over both hierarchies until we
489                converge to the optimum.
490        */
491        bool mUseMultiLevelConstruction;
492        /// number of iteration steps for multilevel approach   
493        int mNumMultiLevels;
494        /** if split plane should be recomputed for the repair.
495                Otherwise only the priority is recomputed, the
496                split plane itself stays the same
497        */
498        bool mRecomputeSplitPlaneOnRepair;
499};
500
501}
502
503#endif
Note: See TracBrowser for help on using the repository browser.