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

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