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

Revision 679, 27.8 KB checked in by mattausch, 18 years ago (diff)

debug version: fixing render cost with bsp splits
removed natfx trees

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