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

Revision 1551, 29.1 KB checked in by mattausch, 18 years ago (diff)

updated view cells loading. probably no optimal for performance

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