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

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