source: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h @ 610

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