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

Revision 1006, 28.8 KB checked in by mattausch, 18 years ago (diff)

started viewspace-objectspace subdivision
removed memory leaks

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