source: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h @ 1286

Revision 1286, 19.9 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef _BvHierarchy_H__
2#define _BvHierarchy_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#include "AxisAlignedBox3.h"
14#include "KdIntersectable.h"
15
16
17namespace GtpVisibilityPreprocessor {
18
19
20class ViewCellLeaf;
21class Plane3;
22class AxisAlignedBox3;
23class Ray;
24class ViewCellsStatistics;
25class ViewCellsManager;
26class MergeCandidate;
27class Beam;
28class ViewCellsTree;
29class Environment;
30class BvhInterior;
31class BvhLeaf;
32class BvhNode;
33class BvhIntersectable;
34class BvhTree;
35class VspTree;
36class ViewCellsContainer;
37
38/** View space partition statistics.
39*/
40class BvhStatistics: public StatisticsBase
41{
42public:
43        // total number of nodes
44        int nodes;
45        // number of splits
46        int splits;
47       
48        // maximal reached depth
49        int maxDepth;
50        // minimal depth
51        int minDepth;
52       
53        // max depth nodes
54        int maxDepthNodes;
55        // minimum depth nodes
56        int minDepthNodes;
57        // max depth nodes
58        int minPvsNodes;
59        // nodes with minimum PVS
60        int minRaysNodes;
61        // max ray contribution nodes
62        int maxRayContribNodes;
63        // minimum area nodes
64        int minProbabilityNodes;
65        /// nodes termination because of max cost ratio;
66        int maxCostNodes;
67        // max number of rays per node
68        int maxObjectRefs;
69        /// number of invalid leaves
70        int invalidLeaves;
71        /// accumulated number of rays refs
72        //int accumRays;
73        // accumulated depth (used to compute average)
74        int accumDepth;
75        /// object references
76        int objectRefs;
77
78        // Constructor
79        BvhStatistics()
80        {
81                Reset();
82        }
83
84        int Nodes() const {return nodes;}
85        int Interior() const { return nodes / 2; }
86        int Leaves() const { return (nodes / 2) + 1; }
87       
88        // TODO: computation wrong
89        double AvgDepth() const
90        { return accumDepth / (double)Leaves(); }
91
92        void Reset()
93        {
94                nodes = 0;
95                splits = 0;
96               
97                maxDepth = 0;
98                minDepth = 99999;
99                accumDepth = 0;
100        maxDepthNodes = 0;
101                minPvsNodes = 0;
102                minRaysNodes = 0;
103                maxRayContribNodes = 0;
104                minProbabilityNodes = 0;
105                maxCostNodes = 0;
106                invalidLeaves = 0;
107                maxObjectRefs = 0;
108                objectRefs = 0;
109        }
110
111        void Print(ostream &app) const;
112
113        friend ostream &operator<<(ostream &s, const BvhStatistics &stat)
114        {
115                stat.Print(s);
116                return s;
117        }
118};
119
120
121/**
122    VspNode abstract class serving for interior and leaf node implementation
123*/
124class BvhNode
125{
126public:
127       
128        // types of vsp nodes
129        enum {Interior, Leaf};
130
131        BvhNode::BvhNode();
132        BvhNode(const AxisAlignedBox3 &bbox);
133        BvhNode(const AxisAlignedBox3 &bbox, BvhInterior *parent);
134
135        virtual ~BvhNode(){};
136
137        /** Determines whether this node is a leaf or not
138                @return true if leaf
139        */
140        virtual bool IsLeaf() const = 0;
141
142        //virtual int Type() const = 0;
143
144        /** Determines whether this node is a root
145                @return true if root
146        */
147        virtual bool IsRoot() const;
148
149        /** Returns parent node.
150        */
151        BvhInterior *GetParent();
152
153        /** Sets parent node.
154        */
155        void SetParent(BvhInterior *parent);
156
157        /** The bounding box specifies the node extent.
158        */
159        AxisAlignedBox3 GetBoundingBox() const
160        { return mBoundingBox; }
161
162
163        void SetBoundingBox(const AxisAlignedBox3 &boundingBox)
164        { mBoundingBox = boundingBox; }
165
166
167        //-- mailing options
168
169        void Mail() { mMailbox = sMailId; }
170        static void NewMail() { ++ sMailId; }
171        bool Mailed() const { return mMailbox == sMailId; }
172
173        static int sMailId;
174        int mMailbox;
175
176        ///////////////////////////////////
177
178protected:
179       
180        /// the bounding box of the node
181        AxisAlignedBox3 mBoundingBox;
182
183        /// parent of this node
184        BvhInterior *mParent;
185};
186
187
188/** BSP interior node implementation
189*/
190class BvhInterior: public BvhNode
191{
192public:
193        /** Standard contructor taking a bounding box as argument.
194        */
195        BvhInterior(const AxisAlignedBox3 &bbox);
196        BvhInterior(const AxisAlignedBox3 &bbox, BvhInterior *parent);
197
198        ~BvhInterior();
199        /** @return false since it is an interior node
200        */
201        bool IsLeaf() const;
202        //int Type() const;
203
204        BvhNode *GetBack() { return mBack; }
205        BvhNode *GetFront() { return mFront; }
206
207        /** Replace front or back child with new child.
208        */
209        void ReplaceChildLink(BvhNode *oldChild, BvhNode *newChild);
210
211        /** Replace front and back child.
212        */
213        void SetupChildLinks(BvhNode *front, BvhNode *back);
214
215        friend ostream &operator<<(ostream &s, const BvhInterior &A)
216        {
217                return s << A.mBoundingBox;
218        }
219
220protected:
221
222        /// back node
223        BvhNode *mBack;
224        /// front node
225        BvhNode *mFront;
226};
227
228
229/** BSP leaf node implementation.
230*/
231class BvhLeaf: public BvhNode
232{
233public:
234        /** Standard contructor taking a bounding box as argument.
235        */
236        BvhLeaf(const AxisAlignedBox3 &bbox);
237        BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent);
238        BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent, const int numObjects);
239
240        ~BvhLeaf();
241
242        /** @return true since it is an interior node
243        */
244        bool IsLeaf() const;
245       
246        //int Type() const;
247
248        SubdivisionCandidate *GetSubdivisionCandidate() const
249        {
250                return mSubdivisionCandidate;
251        }
252
253public:
254
255        /// Rays piercing this leaf.
256        VssRayContainer mVssRays;
257       
258        /// objects
259        ObjectContainer mObjects;
260
261        /// universal counter
262        int mCounter;
263protected:
264
265        /// pointer to a split plane candidate splitting this leaf
266        SubdivisionCandidate *mSubdivisionCandidate;
267};
268
269
270typedef map<BvhNode *, BvhIntersectable *> BvhIntersectableMap;
271
272
273/** View Space Partitioning tree.
274*/
275class BvHierarchy
276{
277        friend class ViewCellsParseHandlers;
278        friend class HierarchyManager;
279
280public:
281       
282        /** Additional data which is passed down the BSP tree during traversal.
283        */
284        class BvhTraversalData
285        { 
286        public:
287                /// the current node
288                BvhLeaf *mNode;
289                /// current depth
290                int mDepth;
291                /// rays piercing this node
292                //RayInfoContainer *mRays;
293                /// the volume of this node
294                float mVolume;
295                /// the bounding box of the node
296                AxisAlignedBox3 mBoundingBox;
297                /// how often this branch has missed the max-cost ratio
298                int mMaxCostMisses;
299                /// current axis
300                int mAxis;
301                /// current priority
302                float mPriority;
303
304
305                BvhTraversalData():
306                mNode(NULL),
307                //mRays(NULL),
308                mDepth(0),
309                mVolume(0.0),
310                mMaxCostMisses(0),
311                mPriority(0),
312                mAxis(0)
313                {}
314               
315                BvhTraversalData(BvhLeaf *node,
316                                                 const int depth,
317                         //RayInfoContainer *rays,
318                                                 const float v):
319                mNode(node),
320                mDepth(depth),
321                //mRays(rays),
322                mVolume(v),
323                mMaxCostMisses(0),
324                mPriority(0),
325                mAxis(0)
326                {}
327
328                BvhTraversalData(
329                        const int depth
330                        //,RayInfoContainer *rays
331                        ):
332                mNode(NULL),
333                mDepth(depth),
334                //mRays(rays),
335                mVolume(0),
336                mMaxCostMisses(0),
337                mAxis(0)
338                {}
339
340                /** Returns cost of the traversal data.
341                */
342                float GetCost() const
343                {
344                        //cout << mPriority << endl;
345                        return mPriority;
346                }
347
348                /// deletes contents and sets them to NULL
349                void Clear()
350                {
351                        //DEL_PTR(mRays);
352                }
353
354                friend bool operator<(const BvhTraversalData &a, const BvhTraversalData &b)
355                {
356                        return a.GetCost() < b.GetCost();
357                }
358    };
359
360        /** Candidate for a view space split.
361        */
362        class BvhSubdivisionCandidate: public SubdivisionCandidate
363        { 
364        public:
365                static BvHierarchy *sBvHierarchy;
366
367                /// parent data
368                BvhTraversalData mParentData;
369                ObjectContainer mFrontObjects;
370                ObjectContainer mBackObjects;
371
372                BvhSubdivisionCandidate(const BvhTraversalData &tData): mParentData(tData)
373                {};
374
375                int Type() const { return OBJECT_SPACE; }
376       
377                void EvalPriority()
378                {
379                        sBvHierarchy->EvalSubdivisionCandidate(*this); 
380                }
381
382                bool GlobalTerminationCriteriaMet() const
383                {
384                        return sBvHierarchy->GlobalTerminationCriteriaMet(mParentData);
385                }
386
387
388                BvhSubdivisionCandidate(
389                        const ObjectContainer &frontObjects,
390                        const ObjectContainer &backObjects,
391                        const BvhTraversalData &tData):
392                mFrontObjects(frontObjects), mBackObjects(backObjects), mParentData(tData)
393                {}
394        };
395
396        /** Struct for traversing line segment.
397        */
398        struct LineTraversalData
399        {
400                BvhNode *mNode;
401                Vector3 mExitPoint;
402               
403                float mMaxT;
404   
405                LineTraversalData () {}
406                LineTraversalData (BvhNode *n, const Vector3 &p, const float maxt):
407                mNode(n), mExitPoint(p), mMaxT(maxt) {}
408        };
409
410        //typedef std::priority_queue<VspTraversalData> VspOspTraversalQueue;
411
412        /** Default constructor creating an empty tree.
413        */
414        BvHierarchy();
415
416        /** Default destructor.
417        */
418        ~BvHierarchy();
419
420        /** Returns tree statistics.
421        */
422        const BvhStatistics &GetStatistics() const;
423 
424        /** Returns bounding box of the specified node.
425        */
426        AxisAlignedBox3 GetBoundingBox(BvhNode *node) const;
427
428        /** Reads parameters from environment singleton.
429        */
430        void ReadEnvironment();
431
432        /** Evaluates candidate for splitting.
433        */
434        void EvalSubdivisionCandidate(BvhSubdivisionCandidate &splitData);
435
436        /** Returns list of leaves with pvs smaller than
437                a certain threshold.
438                @param onlyUnmailed if only the unmailed leaves should be considered
439                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
440        */
441        void CollectLeaves(vector<BvhLeaf *> &leaves) const;
442
443        /** Returns bounding box of the whole tree (= bbox of root node)
444        */
445        AxisAlignedBox3 GetBoundingBox()const;
446
447        /** Returns root of the view space partitioning tree.
448        */
449        BvhNode *GetRoot() const;
450
451        /** A ray is cast possible intersecting the tree.
452                @param the ray that is cast.
453                @returns the number of intersections with objects stored in the tree.
454        */
455        //int CastRay(Ray &ray);
456
457        /** finds neighbouring leaves of this tree node.
458        */
459        int FindNeighbors(BvhLeaf *n,
460                                          vector<BvhLeaf *> &neighbors,
461                                          const bool onlyUnmailed) const;
462
463        /** Returns random leaf of BSP tree.
464                @param halfspace defines the halfspace from which the leaf is taken.
465        */
466        BvhLeaf *GetRandomLeaf(const Plane3 &halfspace);
467
468        /** Returns random leaf of BSP tree.
469                @param onlyUnmailed if only unmailed leaves should be returned.
470        */
471        BvhLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
472
473        /** Casts line segment into the tree.
474                @param origin the origin of the line segment
475                @param termination the end point of the line segment
476                @returns view cells intersecting the line segment.
477        */
478    int CastLineSegment(const Vector3 &origin,
479                                                const Vector3 &termination,
480                                                ViewCellContainer &viewcells);
481               
482        /** Sets pointer to view cells manager.
483        */
484        void SetViewCellsManager(ViewCellsManager *vcm);
485
486        /** Writes tree to output stream
487        */
488        bool Export(OUT_STREAM &stream);
489
490        /** Returns or creates a new intersectable for use in a kd based pvs.
491                The OspTree is responsible for destruction of the intersectable.
492        */
493        BvhIntersectable *GetOrCreateBvhIntersectable(BvhNode *node);
494
495        /** Collects rays.
496        */
497        void CollectRays(const ObjectContainer &objects, VssRayContainer &rays) const;
498
499        /** Intersects box with the tree and returns the number of intersected boxes.
500                @returns number of view cells found
501        */
502        int ComputeBoxIntersections(
503                const AxisAlignedBox3 &box,
504                ViewCellContainer &viewCells) const;
505
506
507        /** Returns leaf the point pt lies in, starting from root.
508        */
509        BvhLeaf *GetLeaf(Intersectable *obj, BvhNode *root = NULL) const;
510
511        ViewCellsTree *GetViewCellsTree() const { return mViewCellsTree; }
512       
513        void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
514
515        /** Add the bvh leaf to the pvs of the view cell.
516        */
517        bool AddLeafToPvs(
518                BvhLeaf *leaf,
519                ViewCell *vc,
520                const float pdf,
521                float &contribution);
522
523protected:
524
525        /** Returns true if tree can be terminated.
526        */
527        bool LocalTerminationCriteriaMet(const BvhTraversalData &data) const;
528
529        /** Returns true if global tree can be terminated.
530        */
531        bool GlobalTerminationCriteriaMet(const BvhTraversalData &data) const;
532
533        // --------------------------------------------------------------
534        // For sorting objects
535        // --------------------------------------------------------------
536        struct SortableEntry
537        {
538                /** There is a 3th "event" for rays which intersect a
539                        box in the middle. These "events" don't induce a change in
540                        pvs size, but may induce a change in view cell volume.
541                */
542                enum EType
543                {
544                        OBJECT,
545                        VIEWCELLS
546                };
547
548                int mType;
549                float mPos;
550
551                VssRay *mRay;
552                Intersectable *mObject;
553
554                SortableEntry() {}
555
556                SortableEntry(
557                        const int type,
558                        const float pos,
559                        Intersectable *obj,
560                        VssRay *ray):
561                mType(type), 
562                mPos(pos),
563                mObject(obj),
564                mRay(ray)
565                {}
566
567                bool operator<(const SortableEntry &b) const
568                {
569                        return mPos < b.mPos;
570                }
571        };
572 
573        /** faster evaluation of split plane cost for kd axis aligned cells.
574        */
575        float EvalLocalSplitCost(const BvhTraversalData &data,
576                                                         const AxisAlignedBox3 &box,
577                                                         const int axis,
578                                                         const float &position,
579                                                         float &pFront,
580                                                         float &pBack) const;
581
582        /** Computes priority of the traversal data and stores it in tData.
583        */
584        void EvalPriority(BvhTraversalData &tData) const;
585
586        /** Evaluates render cost decrease of next split.
587        */
588        float EvalRenderCostDecrease(
589                const ObjectContainer &objectsLeft,
590                const ObjectContainer &objectsRight,
591                const BvhTraversalData &tData,
592                float &normalizedOldRenderCost) const;
593
594        /** Evaluates tree stats in the BSP tree leafs.
595        */
596        void EvaluateLeafStats(const BvhTraversalData &data);
597
598        /** Subdivides node using a best split priority queue.
599            @param tQueue the best split priority queue
600                @param splitCandidate the candidate for the next split
601                @param globalCriteriaMet if the global termination criteria were already met
602                @returns new root of the subtree
603        */
604        BvhNode *Subdivide(
605                SplitQueue &tQueue,
606                SubdivisionCandidate *splitCandidate,
607                const bool globalCriteriaMet);
608       
609        /** Subdivides leaf.
610                @param leaf the leaf to be subdivided
611               
612                @param polys the polygons to be split
613                @param frontPolys returns the polygons in front of the split plane
614                @param backPolys returns the polygons in the back of the split plane
615               
616                @param rays the polygons to be filtered
617                @param frontRays returns the polygons in front of the split plane
618                @param backRays returns the polygons in the back of the split plane
619
620                @returns the root of the subdivision
621        */
622        BvhInterior *SubdivideNode(
623                const ObjectContainer &frontObjects,
624                const ObjectContainer &backObjects,
625                const BvhTraversalData &tData,
626                BvhTraversalData &frontData,
627                BvhTraversalData &backData);
628
629        /** Splits the objects for the next subdivision.
630                @returns cost for this split
631        */
632        float SelectObjectPartition(
633                const BvhTraversalData &tData,
634                ObjectContainer &frontObjects,
635                ObjectContainer &backObjects);
636       
637        /** Writes the node to disk
638                @note: should be implemented as visitor.
639        */
640        void ExportNode(BvhNode *node, OUT_STREAM &stream);
641
642        void ExportObjects(BvhLeaf *leaf, OUT_STREAM &stream);
643
644        /** Returns estimated memory usage of tree.
645        */
646        float GetMemUsage() const;
647
648
649
650        /////////////////////////////
651        // Helper functions for local cost heuristics
652
653       
654        /** Sorts split candidates for cost heuristics using axis aligned splits.
655                @param node the current node
656                @param axis the current split axis
657        */
658        void SortSubdivisionCandidates(
659                const BvhTraversalData &data,
660                const int axis,
661                float minBand,
662                float maxBand);
663
664        /** Computes best cost for axis aligned planes.
665        */
666        float EvalLocalCostHeuristics(
667                const BvhTraversalData &tData,
668                const int axis,
669                ObjectContainer &objectsFront,
670                ObjectContainer &objectsFBack);
671
672        /** Evaluate the volume of view cells seeing the left and right child cell.
673        */
674        void EvalRayContribution(const VssRay &ray, float &volLeft, float &volRight);
675
676
677        /** Evaluates the influence on the pvs of the event.
678                @param ve the visibility event
679                @param pvsLeft updates the left pvs
680                @param rightPvs updates the right pvs
681        */
682        void EvalHeuristicsContribution(
683                BvhLeaf *leaf,
684                const SortableEntry &ci,
685                float &volLeft,
686                float &volRight,
687                int &objectsLeft);
688
689        /** Prepares objects for the cost heuristics.
690                @returns sum of volume of associated view cells
691        */
692        float PrepareHeuristics(const BvhTraversalData &tData);
693
694        /** Prepares heuristics for a particular ray.
695        */
696        float PrepareHeuristics(const VssRay &ray);
697
698        void AddViewCellVolumeContri(
699                ViewCell *vc,
700                float &frontVol,
701                float &backVol,
702                float &frontAndBackVol) const;
703
704       
705        ////////////////////////////////////////////////
706
707
708        /** Prepares construction for vsp and osp trees.
709        */
710        AxisAlignedBox3 ComputeBoundingBox(const ObjectContainer &objects);
711
712        void CollectDirtyCandidates(BvhSubdivisionCandidate *sc,
713                vector<SubdivisionCandidate *> &dirtyList);
714
715        /** Collect view cells which see this kd leaf.
716        */
717        void CollectViewCells(BvhLeaf *leaf, ViewCellContainer &viewCells);
718
719        /** Rays will be clipped to the bounding box.
720        */
721        void PreprocessRays(
722                BvhLeaf *root,
723                const VssRayContainer &sampleRays,
724                RayInfoContainer &rays);
725
726
727        void EvalSubdivisionStats(const SubdivisionCandidate &tData);
728
729        void AddSubdivisionStats(
730                const int viewCells,
731                const float renderCostDecr,
732                const float totalRenderCost);
733
734        void AssociateObjectsWithRays(const VssRayContainer &rays);
735
736        //float EvalViewCellsVolume(BvhLeaf *leaf) const;
737       
738/*      int RemoveParentViewCellsPvs(BvhLeaf *leaf, const RayInfoContainer &rays) const;
739        int UpdateViewCellsPvs(BvhLeaf *leaf, const RayInfoContainer &rays) const;
740        bool AddViewCellToObjectPvs(
741                Intersectable *obj,
742                ViewCell *vc,
743                float &contribution,
744                bool onlyMailed) const;
745*/
746
747        bool IsObjectInLeaf(BvhLeaf *, Intersectable *object) const;
748
749        void MailViewCells(
750                const ObjectContainer &objects,
751                const bool isFront,
752                ViewCellContainer &collectedViewCells) const;
753
754        SubdivisionCandidate *PrepareConstruction(const VssRayContainer &sampleRays,
755                                                                                          ObjectContainer &objects,
756                                                                                          AxisAlignedBox3 *forcedObjectSpace
757                                                                                          //, RayInfoContainer &rays
758                                                                                          );
759
760        float EvalViewCellsVolume(BvhLeaf *leaf) const;
761
762
763protected:
764
765       
766        /// pointer to the hierarchy of view cells
767        ViewCellsTree *mViewCellsTree;
768
769        VspTree *mVspTree;
770
771        /// The view cells manager
772        ViewCellsManager *mViewCellsManager;
773
774        /// candidates for placing split planes during cost heuristics
775        vector<SortableEntry> *mSubdivisionCandidates;
776
777        /// Pointer to the root of the tree
778        BvhNode *mRoot;
779               
780        /// Statistics for the object space partition
781        BvhStatistics mBvhStats;
782       
783        /// box around the whole view domain
784        AxisAlignedBox3 mBoundingBox;
785
786
787        //-- local termination
788
789        /// maximal possible depth
790        int mTermMaxDepth;
791        /// mininum probability
792        float mTermMinVolume;
793        /// minimal number of objects
794        int mTermMinObjects;
795        /// maximal contribution per ray
796        float mTermMaxRayContribution;
797        /// maximal acceptable cost ratio
798        float mTermMaxCostRatio;
799        /// tolerance value indicating how often the max cost ratio can be failed
800        int mTermMissTolerance;
801
802
803        //-- global criteria
804
805        float mTermMinGlobalCostRatio;
806        int mTermGlobalCostMissTolerance;
807        int mGlobalCostMisses;
808
809        /// maximal number of view cells
810        int mTermMaxLeaves;
811        /// maximal tree memory
812        float mMaxMemory;
813        /// the tree is out of memory
814        bool mOutOfMemory;
815
816
817        //-- split heuristics based parameters
818       
819        bool mUseCostHeuristics;
820        /// balancing factor for PVS criterium
821        float mCtDivCi;
822        /// if only driving axis should be used for split
823        bool mOnlyDrivingAxis;
824       
825        /// current time stamp (used for keeping split history)
826        int mTimeStamp;
827        // if rays should be stored in leaves
828        bool mStoreRays;
829
830        /// epsilon for geometric comparisons
831        float mEpsilon;
832
833        /// subdivision stats output file
834        ofstream  mSubdivisionStats;
835        /// keeps track of cost during subdivision
836        float mTotalCost;
837        /// keeps track of overall pvs size during subdivision
838        int mTotalPvsSize;
839        /// number of currenly generated view cells
840        int mCreatedLeaves;
841
842        /// represents min and max band for sweep
843        float mSplitBorder;
844
845        /// weight between render cost decrease and node render cost
846        float mRenderCostDecreaseWeight;
847
848        /// stores the kd node intersectables used for pvs
849        BvhIntersectableMap mBvhIntersectables;
850
851};
852
853}
854
855#endif
Note: See TracBrowser for help on using the repository browser.