source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h @ 1278

Revision 1278, 29.3 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef _ViewCellBsp_H__
2#define _ViewCellBsp_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Polygon3.h"
7#include <stack>
8#include "Statistics.h"
9#include "VssRay.h"
10#include "ViewCell.h"
11
12namespace GtpVisibilityPreprocessor {
13
14class ViewCellLeaf;
15class Plane3;
16class BspTree; 
17class BspInterior;
18class AxisAlignedBox3;
19class Ray;
20class ViewCellsStatistics;
21class ViewCellsManager;
22class ViewCellsTree;
23class ViewCell;
24class ViewCellLeaf;
25
26class BspNodeGeometry
27{
28public:
29        BspNodeGeometry()
30        {}; 
31
32        /** copy constructor copying the polygon array.
33                The polygons are deeply copied.
34        */
35        BspNodeGeometry(const BspNodeGeometry &rhs);
36        /** This operator uses a deep copy to copy the polygons.
37        */
38        BspNodeGeometry& operator=(const BspNodeGeometry& p);
39
40        /** Builds node geometry using this polygons.
41                @NOTE The polygons are NOT duplicated, only
42                a shallow copy is used.
43        */     
44    BspNodeGeometry(const PolygonContainer &polys);
45
46        ~BspNodeGeometry();
47
48        /** Returns accumulated area of all polygons.
49        */
50        float GetArea() const;
51
52        /** Returns volume of this node geometry.
53        */
54        float GetVolume() const;
55
56        /** Computes new front and back geometry based on the old cell
57                geometry and a new split plane
58                @returns true if the geometry is actually split by this plane
59        */
60        bool SplitGeometry(BspNodeGeometry &front,
61                                           BspNodeGeometry &back,
62                                           const Plane3 &splitPlane,
63                       const AxisAlignedBox3 &box,
64                                           const float epsilon) const;
65
66        /** Computes the intersection of the box with the node geometry.
67        */
68        int ComputeIntersection(const AxisAlignedBox3 &box) const;
69
70        /** Computes bounding box of the geometry.
71        */
72        void GetBoundingBox(AxisAlignedBox3 &box) const;
73
74        /** Returns
75                1 of geometry in front of plane
76                0 if plane intersects geometry,
77                -1 if geometry in back of plane
78        */
79        int Side(const Plane3 &plane, const float eps = 0.0f) const;
80
81        /** Splits the polygon and returns the part of the polygon inside of the node geometry.
82        */
83        Polygon3 *SplitPolygon(Polygon3 *poly, const float epsilon) const;
84
85        /** Computes mass center of bsp node geometry.
86        */
87        Vector3 CenterOfMass() const;
88
89        bool Valid() const;
90
91       
92        friend ostream &operator<<(ostream &s, const BspNodeGeometry &a)
93        {
94                PolygonContainer::const_iterator it, it_end = a.mPolys.end();
95
96                for (it = a.mPolys.begin(); it != it_end; ++ it)
97                        s << *(*it) << endl;
98                return s << endl;
99        }
100
101        int Size() const;
102        const PolygonContainer &GetPolys();
103
104    /** Adds polygon and plane equation to this geometry.
105        */
106        void Add(Polygon3 *p, const Plane3 &plane);
107
108        /** Adds node geometry to mesh.
109                @note the mesh vertices will not be connected
110        */
111        friend void IncludeNodeGeomInMesh(const BspNodeGeometry &geom, Mesh &mesh);
112
113protected:
114        /** The polygons the geometry consists of.
115        */
116        PolygonContainer mPolys;
117
118        /** The corresponding set of planes for the polygons.
119                Need this because of precision issues.
120        */
121        vector<Plane3> mPlanes;
122};
123
124
125/** Data structure used for optimized ray casting.
126*/
127struct BspRayTraversalData
128{
129    BspNode *mNode;
130    Vector3 mExitPoint;
131    float mMaxT;
132   
133    BspRayTraversalData() {}
134
135    BspRayTraversalData(BspNode *n, const Vector3 &extp, const float maxt):
136    mNode(n), mExitPoint(extp), mMaxT(maxt)
137        {}
138
139        BspRayTraversalData(BspNode *n, const Vector3 &extp):
140        mNode(n), mExitPoint(extp)
141        {}
142};
143
144/** Data used for passing ray data down the tree.
145*/
146struct BoundedRay
147{
148        Ray *mRay;
149        float mMinT;
150        float mMaxT;
151               
152        BoundedRay(): mMinT(0), mMaxT(1e6), mRay(NULL)
153        {}
154        BoundedRay(Ray *r, float minT, float maxT):
155        mRay(r), mMinT(minT), mMaxT(maxT)
156        {}
157};
158
159typedef vector<BoundedRay *> BoundedRayContainer;
160
161class BspTreeStatistics: public StatisticsBase
162{
163public:
164        // total number of nodes
165        int nodes;
166        // number of splits
167        int splits[3];
168       
169        // totals number of rays
170        int rays;
171        // maximal reached depth
172        int maxDepth;
173        // minimal depth
174        int minDepth;
175       
176        // max depth nodes
177        int maxDepthNodes;
178        // minimum depth nodes
179        int minDepthNodes;
180        // max depth nodes
181        int minPvsNodes;
182        // nodes with minimum PVS
183        int minRaysNodes;
184        // max ray contribution nodes
185        int maxRayContribNodes;
186        // minimum area nodes
187        int minProbabilityNodes;
188        /// nodes termination because of max cost ratio;
189        int maxCostNodes;
190        // max number of rays per node
191        int maxObjectRefs;
192        // accumulated depth (used to compute average)
193        int accumDepth;
194        // number of initial polygons
195        int polys;
196        /// samples contributing to pvs
197        int contributingSamples;
198        /// sample contributions to pvs
199        int sampleContributions;
200        /// largest pvs
201        int maxPvs;
202        /// number of invalid leaves
203        int invalidLeaves;
204        /// polygon splits
205        int polySplits;
206        /// accumulated number of rays refs
207        int accumRays;
208        int pvs;
209
210        // Constructor
211        BspTreeStatistics()
212        {
213                Reset();
214        }
215
216        int Nodes() const { return nodes; }
217        int Interior() const { return nodes / 2; }
218        int Leaves() const { return (nodes / 2) + 1; }
219       
220        // TODO: computation wrong
221        double AvgDepth() const { return accumDepth / (double)Leaves(); }
222        double AvgRays() const { return accumRays / (double)Leaves(); }
223
224        void Reset()
225        {
226                nodes = 0;
227                for (int i = 0; i < 3; ++ i)
228                        splits[i] = 0;
229               
230                maxDepth = 0;
231                minDepth = 99999;
232                polys = 0;
233                accumDepth = 0;
234        pvs = 0;
235                maxDepthNodes = 0;
236                minPvsNodes = 0;
237                minRaysNodes = 0;
238                maxRayContribNodes = 0;
239                minProbabilityNodes = 0;
240                maxCostNodes = 0;
241
242                contributingSamples = 0;
243                sampleContributions = 0;
244
245                maxPvs = 0;
246                invalidLeaves = 0;
247                polySplits = 0;
248                accumRays = 0;
249        }
250
251        void Print(ostream &app) const;
252
253        friend ostream &operator<<(ostream &s, const BspTreeStatistics &stat)
254        {
255                stat.Print(s);
256                return s;
257        }
258};
259
260
261/**
262    BspNode abstract class serving for interior and leaf node implementation
263*/
264class BspNode
265{
266        friend class BspTree;
267
268public:
269        BspNode();
270        virtual ~BspNode(){};
271        BspNode(BspInterior *parent);
272
273        /** Determines whether this node is a leaf or not
274        @return true if leaf
275        */
276        virtual bool IsLeaf() const = 0;
277
278        /** Determines whether this node is a root
279                @return true if root
280        */
281        virtual bool IsRoot() const
282        {
283                return mParent == NULL;
284        }
285
286        /** Returns parent node.
287        */
288        inline BspInterior *GetParent()
289        {
290                return mParent;
291        }
292
293        /** Sets parent node.
294        */
295        inline void BspNode::SetParent(BspInterior *parent)
296        {
297                mParent = parent;
298        }
299
300
301        /** Returns true if this node is a sibling of node n.
302        */
303        bool IsSibling(BspNode *n) const;
304
305        /** Returns depth of the node.
306        */
307        int GetDepth() const;
308
309        /** Returns true if the whole subtree is valid
310        */
311        bool TreeValid() const;
312
313        /** Sets the valid flag for the subtree with this node as root.
314        */
315        void SetTreeValid(const bool v);
316
317        //-- mailing options
318
319        void Mail() { mMailbox = sMailId; }
320        static void NewMail() { ++ sMailId; }
321        bool Mailed() const { return mMailbox == sMailId; }
322
323        static int sMailId;
324        int mMailbox;
325
326        int mTimeStamp;
327
328protected:
329
330        /// if this sub tree is a completely valid view space region
331        bool mTreeValid;
332        /// parent of this node
333        BspInterior *mParent;
334};
335
336
337/** BSP interior node implementation
338*/
339class BspInterior: public BspNode
340{
341        friend class BspTree;
342public:
343        /** Standard contructor taking split plane as argument.
344        */
345        BspInterior(const Plane3 &plane);
346        ~BspInterior();
347
348        /** @return false since it is an interior node
349        */
350        bool IsLeaf() const
351        {
352                return false;
353        }
354        BspNode *GetBack()
355        {
356                return mBack;
357        }
358
359        BspNode *GetFront()
360        {
361                return mFront;
362        }
363       
364        /** Returns split plane.
365        */
366        Plane3 BspInterior::GetPlane() const
367        {
368                return mPlane;
369        }
370
371        /** Replace front or back child with new child.
372        */
373        inline void ReplaceChildLink(BspNode *oldChild, BspNode *newChild)
374        {
375                if (mBack == oldChild)
376                        mBack = newChild;
377                else
378                        mFront = newChild;
379        }
380
381        /** Replace front and back child.
382        */
383        void SetupChildLinks(BspNode *b, BspNode *f);
384
385        friend ostream &operator<<(ostream &s, const BspInterior &A)
386        {
387                return s << A.mPlane;
388        }
389
390protected:
391
392        /// Splitting plane corresponding to this node
393        Plane3 mPlane;
394
395        /// back node
396        BspNode *mBack;
397        /// front node
398        BspNode *mFront;
399};
400
401
402/** BSP leaf node implementation.
403*/
404class BspLeaf: public BspNode
405{
406        friend class BspTree;
407
408public:
409        BspLeaf();
410        BspLeaf(ViewCellLeaf *viewCell);
411        BspLeaf(BspInterior *parent);
412        BspLeaf(BspInterior *parent, ViewCellLeaf *viewCell);
413
414        ~BspLeaf();
415
416        /** Returns pointer of view cell.
417        */
418        inline ViewCellLeaf *GetViewCell() const
419        {
420                return mViewCell;
421        }
422
423        /** Sets pointer to view cell.
424        */
425        inline void SetViewCell(ViewCellLeaf *viewCell)
426        {
427                mViewCell = viewCell;
428        }
429
430        /** @return true since it is an interior node
431        */
432        bool BspLeaf::IsLeaf() const
433        {
434                return true;
435        }
436       
437
438        /// Rays piercing this leaf.
439        VssRayContainer mVssRays;
440       
441        /// leaf pvs
442        ObjectPvs *mPvs;
443
444        /// Probability that the view point lies in this leaf
445        float mProbability;
446
447
448protected:
449       
450        /// if NULL this does not correspond to feasible viewcell
451        ViewCellLeaf *mViewCell;
452};
453
454
455/** Implementation of the view cell BSP tree.
456*/
457class BspTree
458{
459        friend class ViewCellsParseHandlers;
460
461public:
462       
463        /** Additional data which is passed down the BSP tree during traversal.
464        */
465        struct BspTraversalData
466        { 
467                /// the current node
468                BspNode *mNode;
469                /// polygonal data for splitting
470                PolygonContainer *mPolygons;
471                /// current depth
472                int mDepth;
473                /// the view cell associated with this subdivsion
474                ViewCellLeaf *mViewCell;
475                /// rays piercing this node
476                BoundedRayContainer *mRays;
477                /// probability of current node
478                float mProbability;
479                /// geometry of node as induced by planes
480                BspNodeGeometry *mGeometry;
481               
482                /// pvs size
483                int mPvs;
484               
485                /** Returns average ray contribution.
486                */
487                float GetAvgRayContribution() const
488                {
489                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
490                }
491
492
493                BspTraversalData():
494                mNode(NULL),
495                mPolygons(NULL),
496                mDepth(0),
497                mViewCell(NULL),
498                mRays(NULL),
499                mPvs(0),
500                mProbability(0.0),
501                mGeometry(NULL)
502                {}
503               
504                BspTraversalData(BspNode *node,
505                                                 PolygonContainer *polys,
506                                                 const int depth,
507                                                 ViewCellLeaf *viewCell,
508                                                 BoundedRayContainer *rays,
509                                                 int pvs,
510                                                 float p,
511                                                 BspNodeGeometry *cell):
512                mNode(node),
513                mPolygons(polys),
514                mDepth(depth),
515                mViewCell(viewCell),
516                mRays(rays),
517                mPvs(pvs),
518                mProbability(p),
519                mGeometry(cell)
520                {}
521
522
523                float GetCost() const
524                {
525#if 0
526                        return mPvs * mProbability;
527#endif
528#if 0
529                        return (float) (-mDepth); // for regular grid
530#endif
531#if 1
532                        return (float) mDepth; // depth first
533#endif
534#if 0
535                        return mProbability;
536#endif
537#if 0
538                        return (float)mPvs;
539#endif
540#if 0
541                        return (float)mRays->size();
542#endif
543                }
544               
545                friend bool operator<(const BspTraversalData &a, const BspTraversalData &b)
546                {
547                        return a.GetCost() < b.GetCost();
548                }
549    };
550       
551        //typedef std::stack<BspTraversalData> BspTraversalStack;
552        typedef std::priority_queue<BspTraversalData> BspTraversalStack;
553
554        /** Default constructor reading the environment file and
555                creating an empty tree.
556        */
557        BspTree();
558        /** Destroys tree and nodes.
559        */
560        ~BspTree();
561
562        /** Returns detailed statistics of the BSP tree.
563        */
564        const BspTreeStatistics &GetStatistics() const;
565 
566        /** Constructs tree using the given list of view cells.
567            For this type of construction we filter all view cells down the
568                tree. If there is no polygon left, the last split plane
569            decides inside or outside of the viewcell. A pointer to the
570                appropriate view cell is stored within each leaf.
571                Many leafs can point to the same viewcell.
572        */
573        void Construct(const ViewCellContainer &viewCells);
574
575        /** Constructs tree using the given list of objects.
576            @note the objects are not taken as view cells, but the view cells are
577                constructed from the subdivision: Each leaf is taken as one viewcell.
578                @param objects list of objects
579        */
580        void Construct(const ObjectContainer &objects);
581
582        void Construct(const ObjectContainer &objects,
583                                   const RayContainer &sampleRays,
584                                   AxisAlignedBox3 *forcedBoundingBox);
585
586        /** Constructs the tree from a given set of rays.
587                @param sampleRays the set of sample rays the construction is based on
588                @param viewCells if not NULL, new view cells are
589                created in the leafs and stored in the conatainer
590        */
591        void Construct(const RayContainer &sampleRays,
592                                   AxisAlignedBox3 *forcedBoundingBox);
593
594        /** Returns list of BSP leaves.
595        */
596        void CollectLeaves(vector<BspLeaf *> &leaves) const;
597
598        /** Returns box which bounds the whole tree.
599        */
600        AxisAlignedBox3 GetBoundingBox()const;
601
602        /** Returns root of BSP tree.
603        */
604        BspNode *GetRoot() const;
605
606       
607        //bool Export(const string filename);
608
609        /** Collects the leaf view cells of the tree
610                @param viewCells returns the view cells
611        */
612        void CollectViewCells(ViewCellContainer &viewCells) const;
613
614        /** A ray is cast possible intersecting the tree.
615                @param the ray that is cast.
616                @returns the number of intersections with objects stored in the tree.
617        */
618        int     _CastRay(Ray &ray);
619
620
621        int     CastLineSegment(const Vector3 &origin,
622                                                const Vector3 &termination,
623                                                ViewCellContainer &viewcells
624                                                );
625
626        ViewCell *GetViewCell(const Vector3 &point);
627 
628        /// bsp tree construction types
629        enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
630
631        /** Returns statistics.
632        */
633        BspTreeStatistics &GetStat();
634
635        /** finds neighbouring leaves of this tree node.
636        */
637        int FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
638                                          const bool onlyUnmailed) const;
639
640        /** Constructs geometry of view cell returning a BSP node geometry type.
641        */
642        void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
643       
644        /** Construct geometry of view cell.
645        */
646        void ConstructGeometry(ViewCell* vc, BspNodeGeometry &geom) const;
647
648                       
649        /** Sets pointer to view cells manager.
650        */
651        void SetViewCellsManager(ViewCellsManager *vcm);
652
653        /** Returns random leaf of BSP tree.
654                @param halfspace defines the halfspace from which the leaf is taken.
655        */
656        BspLeaf *GetRandomLeaf(const Plane3 &halfspace);
657
658        /** Returns random leaf of BSP tree.
659                @param onlyUnmailed if only unmailed leaves should be returned.
660        */
661        BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
662
663
664        /** Returns epsilon of this tree.
665        */
666        float GetEpsilon() const;
667
668        int CollectMergeCandidates(const vector<BspLeaf *> leaves,
669                                                           vector<MergeCandidate> &candidates);
670
671        int CollectMergeCandidates(const VssRayContainer &rays,
672                                                   vector<MergeCandidate> &candidates);
673
674        /** Exports Bsp tree to file.
675        */
676        bool Export(ofstream &stream);
677
678
679        /** Returns view cell corresponding to
680                the invalid view space. If it does not exist, it is created.
681        */
682        BspViewCell *GetOutOfBoundsCell();
683
684        ViewCellsTree *mViewCellsTree;
685       
686protected:
687
688        // --------------------------------------------------------------
689        // For sorting objects
690        // --------------------------------------------------------------
691        struct SortableEntry
692        {
693                enum {POLY_MIN, POLY_MAX};
694   
695                int type;
696                float value;
697                Polygon3 *poly;
698                SortableEntry() {}
699                SortableEntry(const int t, const float v, Polygon3 *poly):
700                type(t), value(v), poly(poly) {}
701               
702                bool operator<(const SortableEntry &b) const
703                {
704                        return value < b.value;
705                } 
706        };
707
708        void ExportNode(BspNode *node, ofstream &stream);
709
710        /** Evaluates tree stats in the BSP tree leafs.
711        */
712        void EvaluateLeafStats(const BspTraversalData &data);
713
714        /** Subdivides node with respect to the traversal data.
715            @param tStack current traversal stack
716                @param tData traversal data also holding node to be subdivided
717                @returns new root of the subtree
718        */
719        BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData);
720
721        /** Constructs the tree from the given list of polygons and rays.
722                @param polys stores set of polygons on which subdivision may be based
723                @param rays storesset of rays on which subdivision may be based
724        */
725        void Construct(PolygonContainer *polys, BoundedRayContainer *rays);
726
727        /** Selects the best possible splitting plane.
728                @param leaf the leaf to be split
729                @param polys the polygon list on which the split decition is based
730                @param rays ray container on which selection may be based
731                @note the polygons can be reordered in the process
732                @returns the split plane
733        */
734        Plane3 SelectPlane(BspLeaf *leaf,
735                                           BspTraversalData &data);
736
737        /** Evaluates the contribution of the candidate split plane.
738               
739                @param candidatePlane the candidate split plane
740                @param polys the polygons the split can be based on
741                @param rays the rays the split can be based on
742
743                @returns the cost of the candidate split plane
744        */
745        float SplitPlaneCost(const Plane3 &candidatePlane,
746                                                 BspTraversalData &data) const;
747
748        /** Strategies where the effect of the split plane is tested
749            on all input rays.
750                @returns the cost of the candidate split plane
751        */
752        float SplitPlaneCost(const Plane3 &candidatePlane,
753                                                 const PolygonContainer &polys) const;
754
755        /** Strategies where the effect of the split plane is tested
756            on all input rays.
757
758                @returns the cost of the candidate split plane
759        */
760        float SplitPlaneCost(const Plane3 &candidatePlane,
761                                                 const BoundedRayContainer &rays,
762                                                 const int pvs,
763                                                 const float probability,
764                                                 const BspNodeGeometry &cell) const;
765
766        /** Filters next view cell down the tree and inserts it into the appropriate leaves
767                (i.e., possibly more than one leaf).
768        */
769        void InsertViewCell(ViewCellLeaf *viewCell);
770        /** Inserts polygons down the tree. The polygons are filtered until a leaf is reached,
771                then further subdivided.
772        */
773        void InsertPolygons(PolygonContainer *polys);
774
775        /** Subdivide leaf.
776                @param leaf the leaf to be subdivided
777               
778                @param polys the polygons to be split
779                @param frontPolys returns the polygons in front of the split plane
780                @param backPolys returns the polygons in the back of the split plane
781               
782                @param rays the polygons to be filtered
783                @param frontRays returns the polygons in front of the split plane
784                @param backRays returns the polygons in the back of the split plane
785
786                @returns the root of the subdivision
787        */
788
789        BspInterior *SubdivideNode(BspTraversalData &tData,
790                                                           BspTraversalData &frontData,
791                                                           BspTraversalData &backData,
792                                                           PolygonContainer &coincident);
793
794        /** Filters polygons down the tree.
795                @param node the current BSP node
796                @param polys the polygons to be filtered
797                @param frontPolys returns the polygons in front of the split plane
798                @param backPolys returns the polygons in the back of the split plane
799        */
800        void FilterPolygons(BspInterior *node,
801                                                PolygonContainer *polys,
802                                                PolygonContainer *frontPolys,
803                                                PolygonContainer *backPolys);
804
805        /** Take 3 ray endpoints, where two are minimum and one a maximum
806                point or the other way round.
807        */
808        Plane3 ChooseCandidatePlane(const BoundedRayContainer &rays) const;
809
810        /** Take plane normal as plane normal and the midpoint of the ray.
811                PROBLEM: does not resemble any point where visibility is likely to change
812        */
813        Plane3 ChooseCandidatePlane2(const BoundedRayContainer &rays) const;
814
815        /** Fit the plane between the two lines so that the plane has equal shortest
816                distance to both lines.
817        */
818        Plane3 ChooseCandidatePlane3(const BoundedRayContainer &rays) const;
819
820        /** Selects the split plane in order to construct a tree with
821                certain characteristics (e.g., balanced tree, least splits,
822                2.5d aligned)
823                @param polygons container of polygons
824                @param rays bundle of rays on which the split can be based
825        */
826        Plane3 SelectPlaneHeuristics(BspLeaf *leaf,
827                                                                 BspTraversalData &data);
828
829        /** Extracts the meshes of the objects and adds them to polygons.
830                Adds object aabb to the aabb of the tree.
831                @param maxPolys the maximal number of objects to be stored as polygons
832                @returns the number of polygons
833        */
834        int AddToPolygonSoup(const ObjectContainer &objects,
835                                                 PolygonContainer &polys,
836                                                 int maxObjects = 0,
837                                                 bool addToBbox = true);
838
839        /** Extracts the meshes of the view cells and and adds them to polygons.
840                Adds view cell aabb to the aabb of the tree.
841                @param maxPolys the maximal number of objects to be stored as polygons
842                @returns the number of polygons
843        */
844        int AddToPolygonSoup(const ViewCellContainer &viewCells,
845                                                 PolygonContainer &polys,
846                                                 int maxObjects = 0);
847
848        /** Extract polygons of this mesh and add to polygon container.
849                @param mesh the mesh that drives the polygon construction
850                @param parent the parent intersectable this polygon is constructed from
851                @returns number of polygons
852        */
853        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
854
855        /** Helper function which extracts a view cell on the front and the back
856                of the split plane.
857                @param backViewCell returns view cell on the back of the split plane
858                @param frontViewCell returns a view cell on the front of the split plane
859                @param coincident container of polygons coincident to the split plane
860                @param splitPlane the split plane which decides about back and front
861                @param extractBack if a back view cell is extracted
862                @param extractFront if a front view cell is extracted
863        */
864        void ExtractViewCells(BspTraversalData &frontData,
865                                                  BspTraversalData &backData,
866                                                  const PolygonContainer &coincident,
867                                                  const Plane3 &splitPlane) const;
868       
869        /** Computes best cost ratio for the suface area heuristics for axis aligned
870                splits. This heuristics minimizes the cost for ray traversal.
871                @param polys the polygons guiding the ratio computation
872                @param box the bounding box of the leaf
873                @param axis the current split axis
874                @param position returns the split position
875                @param objectsBack the number of objects in the back of the split plane
876                @param objectsFront the number of objects in the front of the split plane
877        */
878        float BestCostRatio(const PolygonContainer &polys,
879                                                const AxisAlignedBox3 &box,
880                                                const int axis,
881                                                float &position,
882                                                int &objectsBack,
883                                                int &objectsFront) const;
884       
885        /** Sorts split candidates for cost heuristics using axis aligned splits.
886                @param polys the input for choosing split candidates
887                @param axis the current split axis
888                @param splitCandidates returns sorted list of split candidates
889        */
890        void SortSubdivisionCandidates(const PolygonContainer &polys,
891                                                         const int axis,
892                                                         vector<SortableEntry> &splitCandidates) const;
893
894        /** Selects an axis aligned split plane.
895                Returns true if split is valied
896        */
897        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
898
899        /** Subdivides the rays into front and back rays according to the split plane.
900               
901                @param plane the split plane
902                @param rays contains the rays to be split. The rays are
903                           distributed into front and back rays.
904                @param frontRays returns rays on the front side of the plane
905                @param backRays returns rays on the back side of the plane
906               
907                @returns the number of splits
908        */
909        int SplitRays(const Plane3 &plane,
910                                  BoundedRayContainer &rays,
911                              BoundedRayContainer &frontRays,
912                                  BoundedRayContainer &backRays);
913
914
915        /** Extracts the split planes representing the space bounded by node n.
916        */
917        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
918
919        /** Adds the object to the pvs of the front and back leaf with a given classification.
920
921                @param obj the object to be added
922                @param cf the ray classification regarding the split plane
923                @param frontPvs returns the PVS of the front partition
924                @param backPvs returns the PVS of the back partition
925       
926        */
927        void AddObjToPvs(Intersectable *obj, const int cf, int &frontPvs, int &backPvs) const;
928
929        /** Computes PVS size induced by the rays.
930        */
931        int ComputePvsSize(const BoundedRayContainer &rays) const;
932
933        /** Returns true if tree can be terminated.
934        */
935        inline bool TerminationCriteriaMet(const BspTraversalData &data) const;
936
937        /** Computes accumulated ray lenght of this rays.
938        */
939        float AccumulatedRayLength(BoundedRayContainer &rays) const;
940
941        /** Splits polygons with respect to the split plane.
942                @param polys the polygons to be split. the polygons are consumed and
943                           distributed to the containers frontPolys, backPolys, coincident.
944                @param frontPolys returns the polygons in the front of the split plane
945                @param backPolys returns the polygons in the back of the split plane
946                @param coincident returns the polygons coincident to the split plane
947
948                @returns the number of splits   
949        */
950        int SplitPolygons(const Plane3 &plane,
951                                          PolygonContainer &polys,
952                                          PolygonContainer &frontPolys,
953                                          PolygonContainer &backPolys,
954                                          PolygonContainer &coincident) const;
955
956        /** Adds ray sample contributions to the PVS.
957                @param sampleContributions the number contributions of the samples
958                @param contributingSampels the number of contributing rays
959               
960        */
961        void AddToPvs(BspLeaf *leaf,
962                                  const BoundedRayContainer &rays,
963                                  int &sampleContributions,     
964                                  int &contributingSamples);
965
966        /** Preprocesses polygons and throws out all polygons which
967                are coincident to the view space box faces:
968                These polygons can can be problematic for bsp because they create
969                bad view cells.
970        */
971        void PreprocessPolygons(PolygonContainer &polys);
972
973        /** Returns view cell corresponding to the invalid view space.
974                If it does not exist, it is created.
975        */
976        BspViewCell *GetOrCreateOutOfBoundsCell();
977
978        /// Pointer to the root of the tree.
979        BspNode *mRoot;
980
981        /// Stores statistics during traversal.
982        BspTreeStatistics mStat;
983
984        /// Strategies for choosing next split plane.
985        enum {NO_STRATEGY = 0,
986                  RANDOM_POLYGON = 1,
987                  AXIS_ALIGNED = 2,
988                  LEAST_SPLITS = 4,
989                  BALANCED_POLYS = 8,
990                  BALANCED_VIEW_CELLS = 16,
991                  LARGEST_POLY_AREA = 32,
992                  VERTICAL_AXIS = 64,
993                  BLOCKED_RAYS = 128,
994                  LEAST_RAY_SPLITS = 256,
995                  BALANCED_RAYS = 512,
996                  PVS = 1024
997                };
998
999        /// box around the whole view domain
1000        AxisAlignedBox3 mBox;
1001
1002        /// view cell corresponding to unbounded space
1003        BspViewCell *mOutOfBoundsCell;
1004
1005        /// if view cells should be generated or the given view cells should be used.
1006        bool mGenerateViewCells;
1007
1008        /// maximal number of polygons before subdivision termination
1009        int mTermMinPolys;
1010        /// maximal number of rays before subdivision termination
1011        int mTermMinRays;
1012        /// maximal possible depth
1013        int mTermMaxDepth;
1014        /// mininum area
1015        float mTermMinProbability;
1016        /// mininum PVS
1017        int mTermMinPvs;
1018
1019        /// minimal number of polygons for axis aligned split
1020        int mTermMinPolysForAxisAligned;
1021        /// minimal number of rays for axis aligned split
1022        int mTermMinRaysForAxisAligned;
1023        /// minimal number of objects for axis aligned split
1024        int mTermMinObjectsForAxisAligned;
1025        /// maximal contribution per ray
1026        float mTermMaxRayContribution;
1027        /// minimal accumulated ray length
1028        float mTermMinAccRayLength;
1029
1030
1031        /// strategy to get the best split plane
1032        int mSplitPlaneStrategy;
1033        /// number of candidates evaluated for the next split plane
1034        int mMaxPolyCandidates;
1035        /// number of candidates for split planes evaluated using the rays
1036        int mMaxRayCandidates;
1037        /// maximum tests for split plane evaluation with a single candidate
1038        int mMaxTests;
1039
1040        float mCtDivCi;
1041
1042        /// axis aligned split criteria
1043        float mAxisAlignedCtDivCi;
1044        float mSplitBorder;
1045        float mMaxCostRatio;
1046
1047        // factors guiding the split plane heuristics
1048        float mVerticalSplitsFactor;
1049        float mLargestPolyAreaFactor;
1050        float mBlockedRaysFactor;
1051        float mLeastRaySplitsFactor;
1052        float mBalancedRaysFactor;
1053        float mPvsFactor;
1054        float mLeastSplitsFactor;
1055        float mBalancedPolysFactor;
1056        float mBalancedViewCellsFactor;
1057
1058        /// if area or accumulated ray lenght should be used for PVS heuristics
1059        bool mUseAreaForPvs;
1060
1061        int mMaxViewCells;
1062
1063        /// epsilon where two points are still considered equal
1064        float mEpsilon;
1065
1066        ViewCellsManager *mViewCellsManager;
1067
1068        int mTimeStamp;
1069
1070        float mTotalCost;
1071        int mTotalPvsSize;
1072
1073        //int mSplits;
1074        ofstream  mSubdivisionStats;
1075
1076private:
1077       
1078        /** Evaluates split plane classification with respect to the plane's
1079                contribution for a balanced tree.
1080        */
1081        static const float sLeastPolySplitsTable[4];
1082        /** Evaluates split plane classification with respect to the plane's
1083                contribution for a minimum number splits in the tree.
1084        */
1085        static const float sBalancedPolysTable[4];
1086        /** Evaluates split plane classification with respect to the plane's
1087                contribution for a minimum number of ray splits.
1088        */
1089        static const float sLeastRaySplitsTable[5];
1090        /** Evaluates split plane classification with respect to the plane's
1091                contribution for balanced rays.
1092        */
1093        static const float sBalancedRaysTable[5];
1094
1095        /// Generates unique ids for PVS criterium
1096        static void GenerateUniqueIdsForPvs();
1097
1098        //-- unique ids for PVS criterium
1099        static int sFrontId;
1100        static int sBackId;
1101        static int sFrontAndBackId;
1102};
1103
1104
1105struct BspIntersection
1106{
1107        // the point of intersection
1108        float mT;
1109 
1110        BspLeaf *mLeaf;
1111 
1112        BspIntersection(const float t, BspLeaf *l):
1113        mT(t), mLeaf(l) {}
1114 
1115        BspIntersection() {}
1116 
1117        bool operator<(const BspIntersection &b) const
1118        {
1119                return mT < b.mT;
1120        }
1121};
1122
1123/** struct storing the view cell intersections.
1124*/
1125struct BspRay
1126{
1127        VssRay *vssRay;
1128        std::vector<BspIntersection> intersections;
1129        BspRay(VssRay *ray): vssRay(ray) {}
1130};
1131
1132}
1133
1134#endif
Note: See TracBrowser for help on using the repository browser.