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

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

added new active view cell concept

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/** BSP interior node implementation
326*/
327class BspInterior: public BspNode
328{
329        friend class BspTree;
330public:
331        /** Standard contructor taking split plane as argument.
332        */
333        BspInterior(const Plane3 &plane);
334        ~BspInterior();
335        /** @return false since it is an interior node
336        */
337        bool IsLeaf() const;
338
339        BspNode *GetBack();
340        BspNode *GetFront();
341
342        /** Returns split plane.
343        */
344        Plane3 GetPlane() const;
345
346        /** Replace front or back child with new child.
347        */
348        void ReplaceChildLink(BspNode *oldChild, BspNode *newChild);
349        /** Replace front and back child.
350        */
351        void SetupChildLinks(BspNode *b, BspNode *f);
352
353        friend ostream &operator<<(ostream &s, const BspInterior &A)
354        {
355                return s << A.mPlane;
356        }
357
358protected:
359
360        /// Splitting plane corresponding to this node
361        Plane3 mPlane;
362
363        /// back node
364        BspNode *mBack;
365        /// front node
366        BspNode *mFront;
367};
368
369/** BSP leaf node implementation.
370*/
371class BspLeaf: public BspNode
372{
373        friend class BspTree;
374
375public:
376        BspLeaf();
377        BspLeaf(ViewCellLeaf *viewCell);
378        BspLeaf(BspInterior *parent);
379        BspLeaf(BspInterior *parent, ViewCellLeaf *viewCell);
380
381        ~BspLeaf();
382
383        /** @return true since it is an interior node
384        */
385        bool IsLeaf() const;
386       
387        /** Returns pointer of view cell.
388        */
389        ViewCellLeaf *GetViewCell() const;
390
391        /** Sets pointer to view cell.
392        */
393        void SetViewCell(ViewCellLeaf *viewCell);
394
395        /// Rays piercing this leaf.
396        VssRayContainer mVssRays;
397       
398        /// leaf pvs
399        ObjectPvs *mPvs;
400
401        /// Probability that the view point lies in this leaf
402        float mProbability;
403
404protected:
405       
406        /// if NULL this does not correspond to feasible viewcell
407        ViewCellLeaf *mViewCell;
408};
409
410/** Implementation of the view cell BSP tree.
411*/
412class BspTree
413{
414        friend class ViewCellsParseHandlers;
415
416public:
417       
418        /** Additional data which is passed down the BSP tree during traversal.
419        */
420        struct BspTraversalData
421        { 
422                /// the current node
423                BspNode *mNode;
424                /// polygonal data for splitting
425                PolygonContainer *mPolygons;
426                /// current depth
427                int mDepth;
428                /// the view cell associated with this subdivsion
429                ViewCellLeaf *mViewCell;
430                /// rays piercing this node
431                BoundedRayContainer *mRays;
432                /// probability of current node
433                float mProbability;
434                /// geometry of node as induced by planes
435                BspNodeGeometry *mGeometry;
436               
437                /// pvs size
438                int mPvs;
439               
440                /** Returns average ray contribution.
441                */
442                float GetAvgRayContribution() const
443                {
444                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
445                }
446
447
448                BspTraversalData():
449                mNode(NULL),
450                mPolygons(NULL),
451                mDepth(0),
452                mViewCell(NULL),
453                mRays(NULL),
454                mPvs(0),
455                mProbability(0.0),
456                mGeometry(NULL)
457                {}
458               
459                BspTraversalData(BspNode *node,
460                                                 PolygonContainer *polys,
461                                                 const int depth,
462                                                 ViewCellLeaf *viewCell,
463                                                 BoundedRayContainer *rays,
464                                                 int pvs,
465                                                 float p,
466                                                 BspNodeGeometry *cell):
467                mNode(node),
468                mPolygons(polys),
469                mDepth(depth),
470                mViewCell(viewCell),
471                mRays(rays),
472                mPvs(pvs),
473                mProbability(p),
474                mGeometry(cell)
475                {}
476
477
478                float GetCost() const
479                {
480#if 0
481                        return mPvs * mProbability;
482#endif
483#if 0
484                        return (float) (-mDepth); // for regular grid
485#endif
486#if 1
487                        return (float) mDepth; // depth first
488#endif
489#if 0
490                        return mProbability;
491#endif
492#if 0
493                        return (float)mPvs;
494#endif
495#if 0
496                        return (float)mRays->size();
497#endif
498                }
499               
500                friend bool operator<(const BspTraversalData &a, const BspTraversalData &b)
501                {
502                        return a.GetCost() < b.GetCost();
503                }
504    };
505       
506        //typedef std::stack<BspTraversalData> BspTraversalStack;
507        typedef std::priority_queue<BspTraversalData> BspTraversalStack;
508
509        /** Default constructor reading the environment file and
510                creating an empty tree.
511        */
512        BspTree();
513        /** Destroys tree and nodes.
514        */
515        ~BspTree();
516
517        /** Returns detailed statistics of the BSP tree.
518        */
519        const BspTreeStatistics &GetStatistics() const;
520 
521        /** Constructs tree using the given list of view cells.
522            For this type of construction we filter all view cells down the
523                tree. If there is no polygon left, the last split plane
524            decides inside or outside of the viewcell. A pointer to the
525                appropriate view cell is stored within each leaf.
526                Many leafs can point to the same viewcell.
527        */
528        void Construct(const ViewCellContainer &viewCells);
529
530        /** Constructs tree using the given list of objects.
531            @note the objects are not taken as view cells, but the view cells are
532                constructed from the subdivision: Each leaf is taken as one viewcell.
533                @param objects list of objects
534        */
535        void Construct(const ObjectContainer &objects);
536
537        void Construct(const ObjectContainer &objects,
538                                   const RayContainer &sampleRays,
539                                   AxisAlignedBox3 *forcedBoundingBox);
540
541        /** Constructs the tree from a given set of rays.
542                @param sampleRays the set of sample rays the construction is based on
543                @param viewCells if not NULL, new view cells are
544                created in the leafs and stored in the conatainer
545        */
546        void Construct(const RayContainer &sampleRays,
547                                   AxisAlignedBox3 *forcedBoundingBox);
548
549        /** Returns list of BSP leaves.
550        */
551        void CollectLeaves(vector<BspLeaf *> &leaves) const;
552
553        /** Returns box which bounds the whole tree.
554        */
555        AxisAlignedBox3 GetBoundingBox()const;
556
557        /** Returns root of BSP tree.
558        */
559        BspNode *GetRoot() const;
560
561       
562        //bool Export(const string filename);
563
564        /** Collects the leaf view cells of the tree
565                @param viewCells returns the view cells
566        */
567        void CollectViewCells(ViewCellContainer &viewCells) const;
568
569        /** A ray is cast possible intersecting the tree.
570                @param the ray that is cast.
571                @returns the number of intersections with objects stored in the tree.
572        */
573        int     _CastRay(Ray &ray);
574
575
576        int     CastLineSegment(const Vector3 &origin,
577                                                const Vector3 &termination,
578                                                ViewCellContainer &viewcells
579                                                );
580
581        ViewCell *GetViewCell(const Vector3 &point);
582 
583        /// bsp tree construction types
584        enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
585
586        /** Returns statistics.
587        */
588        BspTreeStatistics &GetStat();
589
590        /** finds neighbouring leaves of this tree node.
591        */
592        int FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
593                                          const bool onlyUnmailed) const;
594
595        /** Constructs geometry of view cell returning a BSP node geometry type.
596        */
597        void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
598       
599        /** Construct geometry of view cell.
600        */
601        void ConstructGeometry(ViewCell* vc, BspNodeGeometry &geom) const;
602
603                       
604        /** Sets pointer to view cells manager.
605        */
606        void SetViewCellsManager(ViewCellsManager *vcm);
607
608        /** Returns random leaf of BSP tree.
609                @param halfspace defines the halfspace from which the leaf is taken.
610        */
611        BspLeaf *GetRandomLeaf(const Plane3 &halfspace);
612
613        /** Returns random leaf of BSP tree.
614                @param onlyUnmailed if only unmailed leaves should be returned.
615        */
616        BspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
617
618
619        /** Returns epsilon of this tree.
620        */
621        float GetEpsilon() const;
622
623        int CollectMergeCandidates(const vector<BspLeaf *> leaves,
624                                                           vector<MergeCandidate> &candidates);
625
626        int CollectMergeCandidates(const VssRayContainer &rays,
627                                                   vector<MergeCandidate> &candidates);
628
629        /** Exports Bsp tree to file.
630        */
631        bool Export(ofstream &stream);
632
633
634        /** Returns view cell corresponding to
635                the invalid view space. If it does not exist, it is created.
636        */
637        BspViewCell *GetOutOfBoundsCell();
638
639        ViewCellsTree *mViewCellsTree;
640       
641protected:
642
643        // --------------------------------------------------------------
644        // For sorting objects
645        // --------------------------------------------------------------
646        struct SortableEntry
647        {
648                enum {POLY_MIN, POLY_MAX};
649   
650                int type;
651                float value;
652                Polygon3 *poly;
653                SortableEntry() {}
654                SortableEntry(const int t, const float v, Polygon3 *poly):
655                type(t), value(v), poly(poly) {}
656               
657                bool operator<(const SortableEntry &b) const
658                {
659                        return value < b.value;
660                } 
661        };
662
663        void ExportNode(BspNode *node, ofstream &stream);
664
665        /** Evaluates tree stats in the BSP tree leafs.
666        */
667        void EvaluateLeafStats(const BspTraversalData &data);
668
669        /** Subdivides node with respect to the traversal data.
670            @param tStack current traversal stack
671                @param tData traversal data also holding node to be subdivided
672                @returns new root of the subtree
673        */
674        BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData);
675
676        /** Constructs the tree from the given list of polygons and rays.
677                @param polys stores set of polygons on which subdivision may be based
678                @param rays storesset of rays on which subdivision may be based
679        */
680        void Construct(PolygonContainer *polys, BoundedRayContainer *rays);
681
682        /** Selects the best possible splitting plane.
683                @param leaf the leaf to be split
684                @param polys the polygon list on which the split decition is based
685                @param rays ray container on which selection may be based
686                @note the polygons can be reordered in the process
687                @returns the split plane
688        */
689        Plane3 SelectPlane(BspLeaf *leaf,
690                                           BspTraversalData &data);
691
692        /** Evaluates the contribution of the candidate split plane.
693               
694                @param candidatePlane the candidate split plane
695                @param polys the polygons the split can be based on
696                @param rays the rays the split can be based on
697
698                @returns the cost of the candidate split plane
699        */
700        float SplitPlaneCost(const Plane3 &candidatePlane,
701                                                 BspTraversalData &data) const;
702
703        /** Strategies where the effect of the split plane is tested
704            on all input rays.
705                @returns the cost of the candidate split plane
706        */
707        float SplitPlaneCost(const Plane3 &candidatePlane,
708                                                 const PolygonContainer &polys) const;
709
710        /** Strategies where the effect of the split plane is tested
711            on all input rays.
712
713                @returns the cost of the candidate split plane
714        */
715        float SplitPlaneCost(const Plane3 &candidatePlane,
716                                                 const BoundedRayContainer &rays,
717                                                 const int pvs,
718                                                 const float probability,
719                                                 const BspNodeGeometry &cell) const;
720
721        /** Filters next view cell down the tree and inserts it into the appropriate leaves
722                (i.e., possibly more than one leaf).
723        */
724        void InsertViewCell(ViewCellLeaf *viewCell);
725        /** Inserts polygons down the tree. The polygons are filtered until a leaf is reached,
726                then further subdivided.
727        */
728        void InsertPolygons(PolygonContainer *polys);
729
730        /** Subdivide leaf.
731                @param leaf the leaf to be subdivided
732               
733                @param polys the polygons to be split
734                @param frontPolys returns the polygons in front of the split plane
735                @param backPolys returns the polygons in the back of the split plane
736               
737                @param rays the polygons to be filtered
738                @param frontRays returns the polygons in front of the split plane
739                @param backRays returns the polygons in the back of the split plane
740
741                @returns the root of the subdivision
742        */
743
744        BspInterior *SubdivideNode(BspTraversalData &tData,
745                                                           BspTraversalData &frontData,
746                                                           BspTraversalData &backData,
747                                                           PolygonContainer &coincident);
748
749        /** Filters polygons down the tree.
750                @param node the current BSP node
751                @param polys the polygons to be filtered
752                @param frontPolys returns the polygons in front of the split plane
753                @param backPolys returns the polygons in the back of the split plane
754        */
755        void FilterPolygons(BspInterior *node,
756                                                PolygonContainer *polys,
757                                                PolygonContainer *frontPolys,
758                                                PolygonContainer *backPolys);
759
760        /** Take 3 ray endpoints, where two are minimum and one a maximum
761                point or the other way round.
762        */
763        Plane3 ChooseCandidatePlane(const BoundedRayContainer &rays) const;
764
765        /** Take plane normal as plane normal and the midpoint of the ray.
766                PROBLEM: does not resemble any point where visibility is likely to change
767        */
768        Plane3 ChooseCandidatePlane2(const BoundedRayContainer &rays) const;
769
770        /** Fit the plane between the two lines so that the plane has equal shortest
771                distance to both lines.
772        */
773        Plane3 ChooseCandidatePlane3(const BoundedRayContainer &rays) const;
774
775        /** Selects the split plane in order to construct a tree with
776                certain characteristics (e.g., balanced tree, least splits,
777                2.5d aligned)
778                @param polygons container of polygons
779                @param rays bundle of rays on which the split can be based
780        */
781        Plane3 SelectPlaneHeuristics(BspLeaf *leaf,
782                                                                 BspTraversalData &data);
783
784        /** Extracts the meshes of the objects and adds them to polygons.
785                Adds object aabb to the aabb of the tree.
786                @param maxPolys the maximal number of objects to be stored as polygons
787                @returns the number of polygons
788        */
789        int AddToPolygonSoup(const ObjectContainer &objects,
790                                                 PolygonContainer &polys,
791                                                 int maxObjects = 0,
792                                                 bool addToBbox = true);
793
794        /** Extracts the meshes of the view cells and and adds them to polygons.
795                Adds view cell aabb to the aabb of the tree.
796                @param maxPolys the maximal number of objects to be stored as polygons
797                @returns the number of polygons
798        */
799        int AddToPolygonSoup(const ViewCellContainer &viewCells,
800                                                 PolygonContainer &polys,
801                                                 int maxObjects = 0);
802
803        /** Extract polygons of this mesh and add to polygon container.
804                @param mesh the mesh that drives the polygon construction
805                @param parent the parent intersectable this polygon is constructed from
806                @returns number of polygons
807        */
808        int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
809
810        /** Helper function which extracts a view cell on the front and the back
811                of the split plane.
812                @param backViewCell returns view cell on the back of the split plane
813                @param frontViewCell returns a view cell on the front of the split plane
814                @param coincident container of polygons coincident to the split plane
815                @param splitPlane the split plane which decides about back and front
816                @param extractBack if a back view cell is extracted
817                @param extractFront if a front view cell is extracted
818        */
819        void ExtractViewCells(BspTraversalData &frontData,
820                                                  BspTraversalData &backData,
821                                                  const PolygonContainer &coincident,
822                                                  const Plane3 &splitPlane) const;
823       
824        /** Computes best cost ratio for the suface area heuristics for axis aligned
825                splits. This heuristics minimizes the cost for ray traversal.
826                @param polys the polygons guiding the ratio computation
827                @param box the bounding box of the leaf
828                @param axis the current split axis
829                @param position returns the split position
830                @param objectsBack the number of objects in the back of the split plane
831                @param objectsFront the number of objects in the front of the split plane
832        */
833        float BestCostRatio(const PolygonContainer &polys,
834                                                const AxisAlignedBox3 &box,
835                                                const int axis,
836                                                float &position,
837                                                int &objectsBack,
838                                                int &objectsFront) const;
839       
840        /** Sorts split candidates for surface area heuristics for axis aligned splits.
841                @param polys the input for choosing split candidates
842                @param axis the current split axis
843                @param splitCandidates returns sorted list of split candidates
844        */
845        void SortSplitCandidates(const PolygonContainer &polys,
846                                                         const int axis,
847                                                         vector<SortableEntry> &splitCandidates) const;
848
849        /** Selects an axis aligned split plane.
850                Returns true if split is valied
851        */
852        bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
853
854        /** Subdivides the rays into front and back rays according to the split plane.
855               
856                @param plane the split plane
857                @param rays contains the rays to be split. The rays are
858                           distributed into front and back rays.
859                @param frontRays returns rays on the front side of the plane
860                @param backRays returns rays on the back side of the plane
861               
862                @returns the number of splits
863        */
864        int SplitRays(const Plane3 &plane,
865                                  BoundedRayContainer &rays,
866                              BoundedRayContainer &frontRays,
867                                  BoundedRayContainer &backRays);
868
869
870        /** Extracts the split planes representing the space bounded by node n.
871        */
872        void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
873
874        /** Adds the object to the pvs of the front and back leaf with a given classification.
875
876                @param obj the object to be added
877                @param cf the ray classification regarding the split plane
878                @param frontPvs returns the PVS of the front partition
879                @param backPvs returns the PVS of the back partition
880       
881        */
882        void AddObjToPvs(Intersectable *obj, const int cf, int &frontPvs, int &backPvs) const;
883
884        /** Computes PVS size induced by the rays.
885        */
886        int ComputePvsSize(const BoundedRayContainer &rays) const;
887
888        /** Returns true if tree can be terminated.
889        */
890        inline bool TerminationCriteriaMet(const BspTraversalData &data) const;
891
892        /** Computes accumulated ray lenght of this rays.
893        */
894        float AccumulatedRayLength(BoundedRayContainer &rays) const;
895
896        /** Splits polygons with respect to the split plane.
897                @param polys the polygons to be split. the polygons are consumed and
898                           distributed to the containers frontPolys, backPolys, coincident.
899                @param frontPolys returns the polygons in the front of the split plane
900                @param backPolys returns the polygons in the back of the split plane
901                @param coincident returns the polygons coincident to the split plane
902
903                @returns the number of splits   
904        */
905        int SplitPolygons(const Plane3 &plane,
906                                          PolygonContainer &polys,
907                                          PolygonContainer &frontPolys,
908                                          PolygonContainer &backPolys,
909                                          PolygonContainer &coincident) const;
910
911        /** Adds ray sample contributions to the PVS.
912                @param sampleContributions the number contributions of the samples
913                @param contributingSampels the number of contributing rays
914               
915        */
916        void AddToPvs(BspLeaf *leaf,
917                                  const BoundedRayContainer &rays,
918                                  int &sampleContributions,     
919                                  int &contributingSamples);
920
921        /** Preprocesses polygons and throws out all polygons which
922                are coincident to the view space box faces:
923                These polygons can can be problematic for bsp because they create
924                bad view cells.
925        */
926        void PreprocessPolygons(PolygonContainer &polys);
927
928        /** Returns view cell corresponding to the invalid view space.
929                If it does not exist, it is created.
930        */
931        BspViewCell *GetOrCreateOutOfBoundsCell();
932
933        /// Pointer to the root of the tree.
934        BspNode *mRoot;
935
936        /// Stores statistics during traversal.
937        BspTreeStatistics mStat;
938
939        /// Strategies for choosing next split plane.
940        enum {NO_STRATEGY = 0,
941                  RANDOM_POLYGON = 1,
942                  AXIS_ALIGNED = 2,
943                  LEAST_SPLITS = 4,
944                  BALANCED_POLYS = 8,
945                  BALANCED_VIEW_CELLS = 16,
946                  LARGEST_POLY_AREA = 32,
947                  VERTICAL_AXIS = 64,
948                  BLOCKED_RAYS = 128,
949                  LEAST_RAY_SPLITS = 256,
950                  BALANCED_RAYS = 512,
951                  PVS = 1024
952                };
953
954        /// box around the whole view domain
955        AxisAlignedBox3 mBox;
956
957        /// view cell corresponding to unbounded space
958        BspViewCell *mOutOfBoundsCell;
959
960        /// if view cells should be generated or the given view cells should be used.
961        bool mGenerateViewCells;
962
963        /// maximal number of polygons before subdivision termination
964        int mTermMinPolys;
965        /// maximal number of rays before subdivision termination
966        int mTermMinRays;
967        /// maximal possible depth
968        int mTermMaxDepth;
969        /// mininum area
970        float mTermMinProbability;
971        /// mininum PVS
972        int mTermMinPvs;
973
974        /// minimal number of polygons for axis aligned split
975        int mTermMinPolysForAxisAligned;
976        /// minimal number of rays for axis aligned split
977        int mTermMinRaysForAxisAligned;
978        /// minimal number of objects for axis aligned split
979        int mTermMinObjectsForAxisAligned;
980        /// maximal contribution per ray
981        float mTermMaxRayContribution;
982        /// minimal accumulated ray length
983        float mTermMinAccRayLength;
984
985
986        /// strategy to get the best split plane
987        int mSplitPlaneStrategy;
988        /// number of candidates evaluated for the next split plane
989        int mMaxPolyCandidates;
990        /// number of candidates for split planes evaluated using the rays
991        int mMaxRayCandidates;
992        /// maximum tests for split plane evaluation with a single candidate
993        int mMaxTests;
994
995        float mCtDivCi;
996
997        /// axis aligned split criteria
998        float mAxisAlignedCtDivCi;
999        float mSplitBorder;
1000        float mMaxCostRatio;
1001
1002        // factors guiding the split plane heuristics
1003        float mVerticalSplitsFactor;
1004        float mLargestPolyAreaFactor;
1005        float mBlockedRaysFactor;
1006        float mLeastRaySplitsFactor;
1007        float mBalancedRaysFactor;
1008        float mPvsFactor;
1009        float mLeastSplitsFactor;
1010        float mBalancedPolysFactor;
1011        float mBalancedViewCellsFactor;
1012
1013        /// if area or accumulated ray lenght should be used for PVS heuristics
1014        bool mUseAreaForPvs;
1015
1016        int mMaxViewCells;
1017
1018        /// epsilon where two points are still considered equal
1019        float mEpsilon;
1020
1021        ViewCellsManager *mViewCellsManager;
1022
1023        int mTimeStamp;
1024
1025        float mTotalCost;
1026        int mTotalPvsSize;
1027
1028        //int mSplits;
1029        ofstream  mSubdivisionStats;
1030
1031private:
1032       
1033        /** Evaluates split plane classification with respect to the plane's
1034                contribution for a balanced tree.
1035        */
1036        static const float sLeastPolySplitsTable[4];
1037        /** Evaluates split plane classification with respect to the plane's
1038                contribution for a minimum number splits in the tree.
1039        */
1040        static const float sBalancedPolysTable[4];
1041        /** Evaluates split plane classification with respect to the plane's
1042                contribution for a minimum number of ray splits.
1043        */
1044        static const float sLeastRaySplitsTable[5];
1045        /** Evaluates split plane classification with respect to the plane's
1046                contribution for balanced rays.
1047        */
1048        static const float sBalancedRaysTable[5];
1049
1050        /// Generates unique ids for PVS criterium
1051        static void GenerateUniqueIdsForPvs();
1052
1053        //-- unique ids for PVS criterium
1054        static int sFrontId;
1055        static int sBackId;
1056        static int sFrontAndBackId;
1057};
1058
1059
1060struct BspIntersection
1061{
1062        // the point of intersection
1063        float mT;
1064 
1065        BspLeaf *mLeaf;
1066 
1067        BspIntersection(const float t, BspLeaf *l):
1068        mT(t), mLeaf(l) {}
1069 
1070        BspIntersection() {}
1071 
1072        bool operator<(const BspIntersection &b) const
1073        {
1074                return mT < b.mT;
1075        }
1076};
1077
1078/** struct storing the view cell intersections.
1079*/
1080struct BspRay
1081{
1082        VssRay *vssRay;
1083
1084        std::vector<BspIntersection> intersections;
1085
1086        BspRay(VssRay *ray): vssRay(ray) {}
1087};
1088
1089}
1090
1091#endif
Note: See TracBrowser for help on using the repository browser.