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

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