source: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h @ 1109

Revision 1109, 41.7 KB checked in by mattausch, 18 years ago (diff)

erronous version using kd viewcell pvss

Line 
1#ifndef _VspOspTree_H__
2#define _VspOspTree_H__
3
4#include <stack>
5
6#include "Mesh.h"
7#include "Containers.h"
8#include "Statistics.h"
9#include "VssRay.h"
10#include "RayInfo.h"
11#include "gzstream.h"
12#include "FlexibleHeap.h"
13
14
15namespace GtpVisibilityPreprocessor {
16
17class ViewCellLeaf;
18//class VspViewCell;
19class Plane3;
20class AxisAlignedBox3;
21class Ray;
22class ViewCellsStatistics;
23class ViewCellsManager;
24class MergeCandidate;
25class Beam;
26class ViewCellsTree;
27class Environment;
28class VspInterior;
29class VspLeaf;
30class VspNode;
31class KdNode;
32class KdInterior;
33class KdLeaf;
34
35class KdTreeStatistics;
36
37template <typename T> class GtPriority
38{
39public:
40        bool operator() (const T c1, const T c2) const
41        {
42                //return false;
43                return c1->GetPriority() < c2->GetPriority();
44        }
45};
46
47
48/** Candidate for a view space / object space split.
49*/
50class SplitCandidate: public Heapable
51
52public:
53
54        enum {OBJECT_SPACE, VIEW_SPACE};
55
56        /// the current split plane
57        AxisAlignedPlane mSplitPlane;
58        /// split axis of this plane (0, 1, 2, or 3 if non-axis-aligned)
59        int mSplitAxis;
60        /// the number of misses of max cost ratio until this split
61        int mMaxCostMisses;
62
63        /// priority of this split
64        //float mPriority;
65       
66        SplitCandidate()
67        {};
68
69        SplitCandidate(const AxisAlignedPlane &plane): mSplitPlane(plane)
70        {}
71
72        virtual void EvalPriority() = 0;
73        virtual int Type() const = 0;
74        virtual bool GlobalTerminationCriteriaMet() const = 0;
75};
76
77
78/** View space partition statistics.
79*/
80class VspTreeStatistics: public StatisticsBase
81{
82public:
83        // total number of nodes
84        int nodes;
85        // number of splits
86        int splits[3];
87       
88        // totals number of rays
89        int rays;
90        // maximal reached depth
91        int maxDepth;
92        // minimal depth
93        int minDepth;
94       
95        // max depth nodes
96        int maxDepthNodes;
97        // minimum depth nodes
98        int minDepthNodes;
99        // max depth nodes
100        int minPvsNodes;
101        // nodes with minimum PVS
102        int minRaysNodes;
103        // max ray contribution nodes
104        int maxRayContribNodes;
105        // minimum area nodes
106        int minProbabilityNodes;
107        /// nodes termination because of max cost ratio;
108        int maxCostNodes;
109        // max number of rays per node
110        int maxObjectRefs;
111        /// samples contributing to pvs
112        int contributingSamples;
113        /// sample contributions to pvs
114        int sampleContributions;
115        /// largest pvs
116        int maxPvs;
117        /// number of invalid leaves
118        int invalidLeaves;
119        /// accumulated number of rays refs
120        int accumRays;
121        int pvs;
122        // accumulated depth (used to compute average)
123        int accumDepth;
124
125        // Constructor
126        VspTreeStatistics()
127        {
128                Reset();
129        }
130
131        int Nodes() const {return nodes;}
132        int Interior() const { return nodes / 2; }
133        int Leaves() const { return (nodes / 2) + 1; }
134       
135        // TODO: computation wrong
136        double AvgDepth() const { return accumDepth / (double)Leaves();};
137        double AvgRays() const { return accumRays / (double)Leaves();};
138
139        void Reset()
140        {
141                nodes = 0;
142                for (int i = 0; i < 3; ++ i)
143                        splits[i] = 0;
144               
145                maxDepth = 0;
146                minDepth = 99999;
147                accumDepth = 0;
148        pvs = 0;
149                maxDepthNodes = 0;
150                minPvsNodes = 0;
151                minRaysNodes = 0;
152                maxRayContribNodes = 0;
153                minProbabilityNodes = 0;
154                maxCostNodes = 0;
155
156                contributingSamples = 0;
157                sampleContributions = 0;
158
159                maxPvs = 0;
160                invalidLeaves = 0;
161                accumRays = 0;
162        }
163
164        void Print(ostream &app) const;
165
166        friend ostream &operator<<(ostream &s, const VspTreeStatistics &stat)
167        {
168                stat.Print(s);
169                return s;
170        }
171};
172
173
174/** View space partition statistics.
175*/
176class OspTreeStatistics: public StatisticsBase
177{
178public:
179        // total number of nodes
180        int nodes;
181        // number of splits
182        int splits[3];
183       
184        // maximal reached depth
185        int maxDepth;
186        // minimal depth
187        int minDepth;
188       
189        // max depth nodes
190        int maxDepthNodes;
191        // minimum depth nodes
192        int minDepthNodes;
193        // max depth nodes
194        int minPvsNodes;
195        // minimum area nodes
196        int minProbabilityNodes;
197        /// nodes termination because of max cost ratio;
198        int maxCostNodes;
199        // max number of objects per node
200        int maxObjectRefs;
201        int objectRefs;
202        /// samples contributing to pvs
203        int contributingSamples;
204        /// sample contributions to pvs
205        int sampleContributions;
206        /// largest pvs
207        int maxPvs;
208        /// number of invalid leaves
209        int invalidLeaves;
210        /// accumulated number of rays refs
211        int accumRays;
212        /// potentially visible objects from this leaf
213        int pvs;
214
215        // accumulated depth (used to compute average)
216        int accumDepth;
217
218        // Constructor
219        OspTreeStatistics()
220        {
221                Reset();
222        }
223
224        int Nodes() const {return nodes;}
225        int Interior() const { return nodes / 2; }
226        int Leaves() const { return (nodes / 2) + 1; }
227       
228        // TODO: computation wrong
229        double AvgDepth() const { return accumDepth / (double)Leaves();};
230       
231
232        void Reset()
233        {
234                nodes = 0;
235                for (int i = 0; i < 3; ++ i)
236                        splits[i] = 0;
237               
238                maxDepth = 0;
239                minDepth = 99999;
240                accumDepth = 0;
241        pvs = 0;
242                maxDepthNodes = 0;
243                minPvsNodes = 0;
244       
245                minProbabilityNodes = 0;
246                maxCostNodes = 0;
247
248                contributingSamples = 0;
249                sampleContributions = 0;
250
251                maxPvs = 0;
252                invalidLeaves = 0;
253                objectRefs = 0;
254        }
255
256
257        void Print(ostream &app) const;
258
259        friend ostream &operator<<(ostream &s, const OspTreeStatistics &stat)
260        {
261                stat.Print(s);
262                return s;
263        }
264};
265
266
267/**
268    VspNode abstract class serving for interior and leaf node implementation
269*/
270class VspNode
271{
272public:
273       
274        // types of vsp nodes
275        enum {Interior, Leaf};
276
277        VspNode();
278        virtual ~VspNode(){};
279        VspNode(VspInterior *parent);
280
281        /** Determines whether this node is a leaf or not
282                @return true if leaf
283        */
284        virtual bool IsLeaf() const = 0;
285
286        virtual int Type() const = 0;
287
288        /** Determines whether this node is a root
289                @return true if root
290        */
291        virtual bool IsRoot() const;
292
293        /** Returns parent node.
294        */
295        VspInterior *GetParent();
296
297        /** Sets parent node.
298        */
299        void SetParent(VspInterior *parent);
300
301        /** Returns true if this node is a sibling of node n.
302        */
303        bool IsSibling(VspNode *n) const;
304
305        /** returns depth of the node.
306        */
307        int GetDepth() const;
308
309        /** returns true if the whole subtree is valid
310        */
311        bool TreeValid() const;
312
313        void SetTreeValid(const bool v);
314
315        //-- mailing options
316
317        void Mail() { mMailbox = sMailId; }
318        static void NewMail() { ++ sMailId; }
319        bool Mailed() const { return mMailbox == sMailId; }
320
321        static int sMailId;
322        int mMailbox;
323
324        int mTimeStamp;
325
326protected:
327
328        /// if this sub tree is a completely valid view space region
329        bool mTreeValid;
330        /// parent of this node
331        VspInterior *mParent;
332};
333
334
335/** BSP interior node implementation
336*/
337class VspInterior: public VspNode
338{
339public:
340        /** Standard contructor taking split plane as argument.
341        */
342        VspInterior(const AxisAlignedPlane &plane);
343
344        ~VspInterior();
345        /** @return false since it is an interior node
346        */
347        bool IsLeaf() const;
348
349        int Type() const;
350
351        VspNode *GetBack();
352        VspNode *GetFront();
353
354        /** Returns split plane.
355        */
356        AxisAlignedPlane GetPlane() const;
357
358        /** Returns position of split plane.
359        */
360        float GetPosition() const;
361
362        /** Returns split axis.
363        */
364        int GetAxis() const;
365
366        /** Replace front or back child with new child.
367        */
368        void ReplaceChildLink(VspNode *oldChild, VspNode *newChild);
369
370        /** Replace front and back child.
371        */
372        void SetupChildLinks(VspNode *front, VspNode *back);
373
374        friend ostream &operator<<(ostream &s, const VspInterior &A)
375        {
376                return s << A.mPlane.mAxis << " " << A.mPlane.mPosition;
377        }
378
379        AxisAlignedBox3 GetBoundingBox() const;
380        void SetBoundingBox(const AxisAlignedBox3 &box);
381
382        /** Computes intersection of this plane with the ray segment.
383        */
384        int ComputeRayIntersection(const RayInfo &rayData, float &t) const
385        {
386                return rayData.ComputeRayIntersection(mPlane.mAxis, mPlane.mPosition, t);
387        }
388
389
390protected:
391
392        AxisAlignedBox3 mBoundingBox;
393
394        /// Splitting plane corresponding to this node
395        AxisAlignedPlane mPlane;
396
397        /// back node
398        VspNode *mBack;
399        /// front node
400        VspNode *mFront;
401};
402
403
404/** BSP leaf node implementation.
405*/
406class VspLeaf: public VspNode
407{
408
409public:
410        VspLeaf();
411        VspLeaf(ViewCellLeaf *viewCell);
412        VspLeaf(VspInterior *parent);
413        VspLeaf(VspInterior *parent, ViewCellLeaf *viewCell);
414
415        ~VspLeaf();
416
417        /** @return true since it is an interior node
418        */
419        bool IsLeaf() const;
420       
421        int Type() const;
422
423        /** Returns pointer of view cell.
424        */
425        ViewCellLeaf *GetViewCell() const;
426
427        /** Sets pointer to view cell.
428        */
429        void SetViewCell(ViewCellLeaf *viewCell);
430
431        /// Rays piercing this leaf.
432        VssRayContainer mVssRays;
433       
434        /// leaf pvs
435        ObjectPvs *mPvs;
436
437        /// Probability that the view point lies in this leaf
438        float mProbability;
439
440protected:
441       
442        /// if NULL this does not correspond to feasible viewcell
443        ViewCellLeaf *mViewCell;
444};
445
446
447#if 0
448typedef std::priority_queue<SplitCandidate *,
449                                                        std::vector<SplitCandidate *>,
450                                                        GtPriority<std::vector<SplitCandidate *>::value_type> > SplitQueue;
451#endif
452
453typedef FlexibleHeap<SplitCandidate *> SplitQueue;
454
455/** View Space Partitioning tree.
456*/
457class VspTree
458{
459        friend class ViewCellsParseHandlers;
460        friend class HierarchyManager;
461
462public:
463       
464        /** Additional data which is passed down the BSP tree during traversal.
465        */
466        class VspTraversalData
467        { 
468        public:
469                /// the current node
470                VspLeaf *mNode;
471                /// current depth
472                int mDepth;
473                /// rays piercing this node
474                RayInfoContainer *mRays;
475                /// the probability that this node contains view point
476                float mProbability;
477                /// the bounding box of the node
478                AxisAlignedBox3 mBoundingBox;
479                /// pvs size
480                int mPvs;
481                /// how often this branch has missed the max-cost ratio
482                int mMaxCostMisses;
483                // current priority
484                float mPriority;
485
486               
487                /** Returns average ray contribution.
488                */
489                float GetAvgRayContribution() const
490                {
491                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
492                }
493
494
495                VspTraversalData():
496                mNode(NULL),
497                mDepth(0),
498                mRays(NULL),
499                mPvs(0),
500                mProbability(0.0),
501                mMaxCostMisses(0),
502                mPriority(0)
503                {}
504               
505                VspTraversalData(VspLeaf *node,
506                                                 const int depth,
507                                                 RayInfoContainer *rays,
508                                                 const int pvs,
509                                                 const float p,
510                                                 const AxisAlignedBox3 &box):
511                mNode(node),
512                mDepth(depth),
513                mRays(rays),
514                mPvs(pvs),
515                mProbability(p),
516                mBoundingBox(box),
517                mMaxCostMisses(0),
518                mPriority(0)
519                {}
520
521                VspTraversalData(const int depth,
522                                                 RayInfoContainer *rays,
523                                                 const AxisAlignedBox3 &box):
524                mNode(NULL),
525                mDepth(depth),
526                mRays(rays),
527                mPvs(0),
528                mProbability(0),
529                mMaxCostMisses(0),
530                mBoundingBox(box)
531                {}
532
533                /** Returns cost of the traversal data.
534                */
535                float GetCost() const
536                {
537                        //cout << mPriority << endl;
538                        return mPriority;
539                }
540
541                // deletes contents and sets them to NULL
542                void Clear()
543                {
544                        DEL_PTR(mRays);
545                }
546
547                friend bool operator<(const VspTraversalData &a, const VspTraversalData &b)
548                {
549                        return a.GetCost() < b.GetCost();
550                }
551    };
552
553        /** Candidate for a view space split.
554        */
555        class VspSplitCandidate: public SplitCandidate
556        { 
557        public:
558
559                static VspTree* sVspTree;
560
561                /// parent node traversal data
562                VspTraversalData mParentData;
563               
564                VspSplitCandidate(const VspTraversalData &tData): mParentData(tData)
565                {};
566
567                int Type() const { return VIEW_SPACE; }
568
569                void EvalPriority()
570                {
571                        sVspTree->EvalSplitCandidate(*this);   
572                }
573
574                bool GlobalTerminationCriteriaMet() const
575                {
576                        return sVspTree->GlobalTerminationCriteriaMet(mParentData);
577                }
578
579                VspSplitCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData):
580                SplitCandidate(plane), mParentData(tData)
581                {}
582        };
583
584        /** Struct for traversing line segment.
585        */
586        struct LineTraversalData
587        {
588                VspNode *mNode;
589                Vector3 mExitPoint;
590               
591                float mMaxT;
592   
593                LineTraversalData () {}
594                LineTraversalData (VspNode *n, const Vector3 &p, const float maxt):
595                mNode(n), mExitPoint(p), mMaxT(maxt) {}
596        };
597
598        //typedef std::priority_queue<VspTraversalData> VspOspTraversalQueue;
599
600        /** Default constructor creating an empty tree.
601        */
602        VspTree();
603
604        /** Default destructor.
605        */
606        ~VspTree();
607
608        /** Returns BSP Tree statistics.
609        */
610        const VspTreeStatistics &GetStatistics() const;
611 
612        /** Returns bounding box of the specified node.
613        */
614        AxisAlignedBox3 GetBBox(VspNode *node) const;
615
616        /** Returns list of BSP leaves with pvs smaller than
617                a certain threshold.
618                @param onlyUnmailed if only the unmailed leaves should be considered
619                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
620        */
621        void CollectLeaves(vector<VspLeaf *> &leaves,
622                                           const bool onlyUnmailed = false,
623                                           const int maxPvs = -1) const;
624
625        /** Returns box which bounds the whole tree.
626        */
627        AxisAlignedBox3 GetBoundingBox() const;
628
629        /** Returns root of the view space partitioning tree.
630        */
631        VspNode *GetRoot() const;
632
633        /** Collects the leaf view cells of the tree
634                @param viewCells returns the view cells
635        */
636        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
637
638        /** A ray is cast possible intersecting the tree.
639                @param the ray that is cast.
640                @returns the number of intersections with objects stored in the tree.
641        */
642        int CastRay(Ray &ray);
643
644
645        /** finds neighbouring leaves of this tree node.
646        */
647        int FindNeighbors(VspLeaf *n,
648                                          vector<VspLeaf *> &neighbors,
649                                          const bool onlyUnmailed) const;
650
651        /** Returns random leaf of BSP tree.
652                @param halfspace defines the halfspace from which the leaf is taken.
653        */
654        VspLeaf *GetRandomLeaf(const Plane3 &halfspace);
655
656        /** Returns random leaf of BSP tree.
657                @param onlyUnmailed if only unmailed leaves should be returned.
658        */
659        VspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
660
661        /** Returns epsilon of this tree.
662        */
663        float GetEpsilon() const;
664
665        /** Casts line segment into the tree.
666                @param origin the origin of the line segment
667                @param termination the end point of the line segment
668                @returns view cells intersecting the line segment.
669        */
670    int CastLineSegment(const Vector3 &origin,
671                                                const Vector3 &termination,
672                                                ViewCellContainer &viewcells);
673
674               
675        /** Sets pointer to view cells manager.
676        */
677        void SetViewCellsManager(ViewCellsManager *vcm);
678
679        /** Returns view cell the current point is located in.
680                @param point the current view point
681                @param active if currently active view cells should be returned or
682                elementary view cell
683        */
684        ViewCell *GetViewCell(const Vector3 &point, const bool active = false);
685
686
687        /** Returns true if this view point is in a valid view space,
688                false otherwise.
689        */
690        bool ViewPointValid(const Vector3 &viewPoint) const;
691
692        /** Returns view cell corresponding to
693                the invalid view space.
694        */
695        VspViewCell *GetOutOfBoundsCell();
696
697        /** Writes tree to output stream
698        */
699#if ZIPPED_VIEWCELLS
700        bool Export(ogzstream &stream);
701#else
702        bool Export(ofstream &stream);
703#endif
704
705        /** Casts beam, i.e. a 5D frustum of rays, into tree.
706                Tests conservative using the bounding box of the nodes.
707                @returns number of view cells it intersected
708        */
709        int CastBeam(Beam &beam);
710
711
712        /** Checks if tree validity-flags are right
713                with respect to view cell valitiy.
714                If not, marks subtree as invalid.
715        */
716        void ValidateTree();
717
718        /** Invalid view cells are added to the unbounded space
719        */
720        void CollapseViewCells();
721
722        /** Collects rays stored in the leaves.
723        */
724        void CollectRays(VssRayContainer &rays);
725
726        /** Intersects box with the tree and returns the number of intersected boxes.
727                @returns number of view cells found
728        */
729        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
730                                                                ViewCellContainer &viewCells) const;
731
732        /// pointer to the hierarchy of view cells
733        ViewCellsTree *mViewCellsTree;
734
735        /** Remove the references of the parent view cell from the kd nodes associated with
736                the objects.
737        */
738        void RemoveParentViewCellReferences(ViewCell *parent);
739        /** Adds references to the view cell to the kd nodes associated with the objects.
740        */
741        void AddViewCellReferences(ViewCell *vc) const;
742
743
744protected:
745
746        // --------------------------------------------------------------
747        // For sorting objects
748        // --------------------------------------------------------------
749        struct SortableEntry
750        {
751                enum EType
752                {
753                        ERayMin,
754                        ERayMax
755                };
756
757                int type;
758                float value;
759                VssRay *ray;
760 
761                SortableEntry() {}
762                SortableEntry(const int t, const float v, VssRay *r):
763                type(t), value(v), ray(r)
764                {
765                }
766               
767                friend bool operator<(const SortableEntry &a, const SortableEntry &b)
768                {
769                        return a.value < b.value;
770                }
771        };
772
773        /** faster evaluation of split plane cost for kd axis aligned cells.
774        */
775        float EvalLocalSplitCost(const VspTraversalData &data,
776                                                         const AxisAlignedBox3 &box,
777                                                         const int axis,
778                                                         const float &position,
779                                                         float &pFront,
780                                                         float &pBack) const;
781
782        void PrepareConstruction(const VssRayContainer &sampleRays,
783                                                         AxisAlignedBox3 *forcedBoundingBox);
784
785        /** Evaluates candidate for splitting.
786        */
787        void EvalSplitCandidate(VspSplitCandidate &splitData);
788
789        /** Evaluates render cost decrease of next split.
790        */
791        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
792                                                                 const VspTraversalData &data) const;
793
794        /** Collects view cells in the subtree under root.
795        */
796        void CollectViewCells(VspNode *root,
797                                                  bool onlyValid,
798                                                  ViewCellContainer &viewCells,
799                                                  bool onlyUnmailed = false) const;
800
801        /** Returns view cell corresponding to
802                the invalid view space. If it does not exist, it is created.
803        */
804        VspViewCell *GetOrCreateOutOfBoundsCell();
805
806        /** Collapses the tree with respect to the view cell partition,
807                i.e. leaves having the same view cell are collapsed.
808                @param node the root of the subtree to be collapsed
809                @param collapsed returns the number of collapsed nodes
810                @returns node of type leaf if the node could be collapsed,
811                this node otherwise
812        */
813        VspNode *CollapseTree(VspNode *node, int &collapsed);
814
815        /** Helper function revalidating the view cell leaf list after merge.
816        */
817        void RepairViewCellsLeafLists();
818
819        /** Evaluates tree stats in the BSP tree leafs.
820        */
821        void EvaluateLeafStats(const VspTraversalData &data);
822
823        /** Subdivides node using a best split priority queue.
824            @param tQueue the best split priority queue
825                @param splitCandidate the candidate for the next split
826                @param globalCriteriaMet if the global termination criteria were already met
827                @returns new root of the subtree
828        */
829        VspNode *Subdivide(SplitQueue &tQueue,
830                                           VspSplitCandidate &splitCandidate,
831                                           const bool globalCriteriaMet);
832
833        /** Adds stats to subdivision log file.
834        */
835        void AddSubdivisionStats(const int viewCells,
836                                                         const float renderCostDecr,
837                                                         const float splitCandidateCost,
838                                                         const float totalRenderCost,
839                                                         const float avgRenderCost);
840       
841        /** Subdivides leaf.
842                       
843                @param tData data object holding, e.g., a pointer to the leaf
844                @param frontData returns the data (e.g.,  pointer to the leaf) in front of the split plane
845                @param backData returns the data (e.g.,  pointer to the leaf) in the back of the split plane
846               
847                @param rays the polygons to be filtered
848                @param frontRays returns the polygons in front of the split plane
849       
850                @returns the root of the subdivision
851        */
852        VspInterior *SubdivideNode(const AxisAlignedPlane &splitPlane,
853                                                           VspTraversalData &tData,
854                                                           VspTraversalData &frontData,
855                               VspTraversalData &backData);
856
857        /** Selects an axis aligned for the next split.
858                @returns cost for this split
859        */
860        float SelectSplitPlane(const VspTraversalData &tData,
861                                                   AxisAlignedPlane &plane,
862                                                   float &pFront,
863                                                   float &pBack);
864
865        /** Sorts split candidates along the specified axis.
866                The split candidates are generated on possible visibility
867                events (i.e., where ray segments intersect the ray boundaries).
868                The sorted candidates are needed to compute the heuristics.
869
870                @param polys the input for choosing split candidates
871                @param axis the current split axis
872                @param splitCandidates returns sorted list of split candidates
873        */
874        void SortSplitCandidates(const RayInfoContainer &rays,
875                                                         const int axis,
876                                                         float minBand,
877                                                         float maxBand);
878
879        /** Computes pvs increase with respect to the previous pvs for heuristics.
880        */
881        int GetPvsIncr(Intersectable *object, const KdPvsMap &activeNodes);
882
883        /** Returns absolute pvs contribution of this object.
884        */
885        int GetPvsContribution(Intersectable *object) const;
886
887        /** Computes best cost for axis aligned planes.
888        */
889        float EvalLocalCostHeuristics(const RayInfoContainer &rays,
890                                                                  const AxisAlignedBox3 &box,
891                                                                  int pvsSize,
892                                                                  const int axis,
893                                                                  float &position);
894
895        /** Evaluates the influence on the pvs of the visibility event ve.
896                @param ve the visibility event
897                @param pvsLeft updates the left pvs
898                @param rightPvs updates the right pvs
899        */
900        void EvalPvsIncr(const SortableEntry &ve,
901                                          int &pvsLeft,
902                                          int &pvsRight) const;
903
904        void RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const;
905        void AddContriToPvs(KdLeaf *leaf, int &pvs) const;
906
907        /** Prepares objects for the heuristics.
908                @returns pvs size of the ray container
909        */
910        int PrepareHeuristics(const RayInfoContainer &rays);
911
912        int PrepareHeuristics(Intersectable *object);
913
914        /** Subdivides the rays into front and back rays according to the split plane.
915               
916                @param plane the split plane
917                @param rays contains the rays to be split. The rays are
918                           distributed into front and back rays.
919                @param frontRays returns rays on the front side of the plane
920                @param backRays returns rays on the back side of the plane
921               
922                @returns the number of splits
923        */
924        int SplitRays(const AxisAlignedPlane &plane,
925                                  RayInfoContainer &rays,
926                              RayInfoContainer &frontRays,
927                                  RayInfoContainer &backRays) const;
928
929        /** Adds the object to the pvs of the front and back leaf with a given classification.
930
931                @param obj the object to be added
932                @param cf the ray classification regarding the split plane
933                @param frontPvs returns the PVS of the front partition
934                @param backPvs returns the PVS of the back partition
935       
936        */
937        void AddObjToPvs(Intersectable *obj,
938                                         const int cf,
939                                         float &frontPvs,
940                                         float &backPvs,
941                                         float &totalPvs) const;
942       
943        /** Computes PVS size induced by the rays.
944        */
945        int ComputePvsSize(const RayInfoContainer &rays) const;
946       
947        /** Collects pvs from rays.
948        */
949        void CollectPvs(const RayInfoContainer &rays,
950                                        ObjectContainer &objects) const;
951
952        /** Returns true if tree can be terminated.
953        */
954        inline bool LocalTerminationCriteriaMet(const VspTraversalData &data) const;
955
956        /** Returns true if global tree can be terminated.
957        */
958        inline bool GlobalTerminationCriteriaMet(const VspTraversalData &data) const;
959
960        /** Adds ray sample contributions to the PVS.
961                @param sampleContributions the number contributions of the samples
962                @param contributingSampels the number of contributing rays
963               
964        */
965        void AddToPvs(VspLeaf *leaf,
966                                  const RayInfoContainer &rays,
967                                  float &sampleContributions,
968                                  int &contributingSamples);
969
970        /** Propagates valid flag up the tree.
971        */
972        void PropagateUpValidity(VspNode *node);
973
974        /** Writes the node to disk
975                @note: should be implemented as visitor.
976        */
977#if ZIPPED_VIEWCELLS
978        void ExportNode(VspNode *node, ogzstream &stream);
979#else
980        void ExportNode(VspNode *node, ofstream &stream);
981#endif
982
983        /** Returns estimated memory usage of tree.
984        */
985        float GetMemUsage() const;
986
987        void ProcessViewCellObjects(ViewCell *parent, ViewCell *front, ViewCell *back) const;
988
989        void CreateViewCell(VspTraversalData &tData);
990
991protected:
992
993        int mPvsCountMethod;
994        enum {PER_OBJECT, PER_KDLEAF};
995
996        ViewCellsManager *mViewCellsManager;
997        vector<SortableEntry> *mSplitCandidates;
998
999        /// Pointer to the root of the tree
1000        VspNode *mRoot;
1001               
1002        VspTreeStatistics mVspStats;
1003       
1004        /// View cell corresponding to the space outside the valid view space
1005        VspViewCell *mOutOfBoundsCell;
1006
1007        /// box around the whole view domain
1008        AxisAlignedBox3 mBoundingBox;
1009
1010
1011
1012        //-- local termination
1013
1014        /// minimal number of rays before subdivision termination
1015        int mTermMinRays;
1016        /// maximal possible depth
1017        int mTermMaxDepth;
1018        /// mininum probability
1019        float mTermMinProbability;
1020        /// mininum PVS
1021        int mTermMinPvs;
1022        /// maximal contribution per ray
1023        float mTermMaxRayContribution;
1024        /// maximal acceptable cost ratio
1025        float mTermMaxCostRatio;
1026        /// tolerance value indicating how often the max cost ratio can be failed
1027        int mTermMissTolerance;
1028
1029
1030        //-- global criteria
1031        float mTermMinGlobalCostRatio;
1032        int mTermGlobalCostMissTolerance;
1033        int mGlobalCostMisses;
1034
1035        /// maximal number of view cells
1036        int mMaxViewCells;
1037        /// maximal tree memory
1038        float mMaxMemory;
1039        /// the tree is out of memory
1040        bool mOutOfMemory;
1041
1042
1043
1044        //-- split heuristics based parameters
1045       
1046        bool mUseCostHeuristics;
1047        /// balancing factor for PVS criterium
1048        float mCtDivCi;
1049        /// if only driving axis should be used for split
1050        bool mOnlyDrivingAxis;
1051        /// if random split axis should be used
1052        bool mUseRandomAxis;
1053        /// if vsp bsp tree should simulate octree
1054        bool mCirculatingAxis;
1055        /// minimal relative position where the split axis can be placed
1056        float mMinBand;
1057        /// maximal relative position where the split axis can be placed
1058        float mMaxBand;
1059
1060
1061        /// current time stamp (used for keeping split history)
1062        int mTimeStamp;
1063        // if rays should be stored in leaves
1064        bool mStoreRays;
1065
1066        /// epsilon for geometric comparisons
1067        float mEpsilon;
1068
1069
1070        /// subdivision stats output file
1071        ofstream  mSubdivisionStats;
1072        /// keeps track of cost during subdivision
1073        float mTotalCost;
1074        /// keeps track of overall pvs size during subdivision
1075        int mTotalPvsSize;
1076        /// number of currenly generated view cells
1077        int mCreatedViewCells;
1078};
1079
1080
1081/** View Space Partitioning tree.
1082*/
1083class OspTree
1084{
1085        friend class ViewCellsParseHandlers;
1086        friend class HierarchyManager;
1087
1088public:
1089       
1090        /** Additional data which is passed down the BSP tree during traversal.
1091        */
1092        class OspTraversalData
1093        { 
1094        public:
1095                /// the current node
1096                KdLeaf *mNode;
1097                /// current depth
1098                int mDepth;
1099                /// rays piercing this node
1100                //RayInfoContainer *mRays;
1101                /// the probability that this node contains view point
1102                float mProbability;
1103                /// the bounding box of the node
1104                AxisAlignedBox3 mBoundingBox;
1105                /// pvs size
1106                int mPvs;
1107                /// how often this branch has missed the max-cost ratio
1108                int mMaxCostMisses;
1109                // current axis
1110                int mAxis;
1111                // current priority
1112                float mPriority;
1113
1114
1115                OspTraversalData():
1116                mNode(NULL),
1117                mDepth(0),
1118                mPvs(0),
1119                mProbability(0.0),
1120                mMaxCostMisses(0),
1121                mPriority(0),
1122                mAxis(0)
1123                {}
1124               
1125                OspTraversalData(KdLeaf *node,
1126                                                 const int depth,
1127                                                 const int pvs,
1128                                                 const float p,
1129                                                 const AxisAlignedBox3 &box):
1130                mNode(node),
1131                mDepth(depth),
1132                mPvs(pvs),
1133                mProbability(p),
1134                mBoundingBox(box),
1135                mMaxCostMisses(0),
1136                mPriority(0),
1137                mAxis(0)
1138                {}
1139
1140                OspTraversalData(const int depth,
1141                                                 const AxisAlignedBox3 &box):
1142                mNode(NULL),
1143                mDepth(depth),
1144                mPvs(0),
1145                mProbability(0),
1146                mMaxCostMisses(0),
1147                mAxis(0),
1148                mBoundingBox(box)
1149                {}
1150
1151                /** Returns cost of the traversal data.
1152                */
1153                float GetCost() const
1154                {
1155                        //cout << mPriority << endl;
1156                        return mPriority;
1157                }
1158
1159                // deletes contents and sets them to NULL
1160                void Clear()
1161                {
1162                }
1163
1164                friend bool operator<(const OspTraversalData &a, const OspTraversalData &b)
1165                {
1166                        return a.GetCost() < b.GetCost();
1167                }
1168    };
1169
1170        /** Candidate for a view space split.
1171        */
1172        class OspSplitCandidate: public SplitCandidate
1173        { 
1174        public:
1175                static OspTree* sOspTree;
1176
1177                /// parent data
1178                OspTraversalData mParentData;
1179               
1180                OspSplitCandidate(const OspTraversalData &tData): mParentData(tData)
1181                {};
1182
1183                int Type() const { return OBJECT_SPACE; }
1184       
1185                void EvalPriority()
1186                {
1187                        sOspTree->EvalSplitCandidate(*this);   
1188                }
1189
1190                bool GlobalTerminationCriteriaMet() const
1191                {
1192                        return sOspTree->GlobalTerminationCriteriaMet(mParentData);
1193                }
1194
1195
1196                OspSplitCandidate(const AxisAlignedPlane &plane, const OspTraversalData &tData):
1197                SplitCandidate(plane), mParentData(tData)
1198                {}
1199        };
1200
1201        /** Struct for traversing line segment.
1202        */
1203        struct LineTraversalData
1204        {
1205                KdNode *mNode;
1206                Vector3 mExitPoint;
1207               
1208                float mMaxT;
1209   
1210                LineTraversalData () {}
1211                LineTraversalData (KdNode *n, const Vector3 &p, const float maxt):
1212                mNode(n), mExitPoint(p), mMaxT(maxt) {}
1213        };
1214
1215        //typedef std::priority_queue<VspTraversalData> VspOspTraversalQueue;
1216
1217        /** Default constructor creating an empty tree.
1218        */
1219        OspTree();
1220
1221        /** Default destructor.
1222        */
1223        ~OspTree();
1224
1225        /** Returns BSP Tree statistics.
1226        */
1227        const KdTreeStatistics &GetStatistics() const;
1228 
1229        /** Returns bounding box of the specified node.
1230        */
1231        AxisAlignedBox3 GetBBox(KdNode *node) const;
1232
1233        /** Returns list of leaves with pvs smaller than
1234                a certain threshold.
1235                @param onlyUnmailed if only the unmailed leaves should be considered
1236                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
1237        */
1238       
1239        void CollectLeaves(vector<KdLeaf *> &leaves) const;
1240
1241
1242        /** Returns bounding box of the whole tree (= bbox of root node)
1243        */
1244        AxisAlignedBox3 GetBoundingBox()const;
1245
1246        /** Returns root of the view space partitioning tree.
1247        */
1248        KdNode *GetRoot() const;
1249
1250        /** Collects the leaf view cells of the tree
1251                @param viewCells returns the view cells
1252        */
1253        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
1254
1255        /** A ray is cast possible intersecting the tree.
1256                @param the ray that is cast.
1257                @returns the number of intersections with objects stored in the tree.
1258        */
1259        int CastRay(Ray &ray);
1260
1261        /** finds neighbouring leaves of this tree node.
1262        */
1263        int FindNeighbors(KdLeaf *n,
1264                                          vector<VspLeaf *> &neighbors,
1265                                          const bool onlyUnmailed) const;
1266
1267        /** Returns random leaf of BSP tree.
1268                @param halfspace defines the halfspace from which the leaf is taken.
1269        */
1270        KdLeaf *GetRandomLeaf(const Plane3 &halfspace);
1271
1272        /** Returns random leaf of BSP tree.
1273                @param onlyUnmailed if only unmailed leaves should be returned.
1274        */
1275        KdLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
1276
1277        /** Returns epsilon of this tree.
1278        */
1279        float GetEpsilon() const;
1280
1281        /** Casts line segment into the tree.
1282                @param origin the origin of the line segment
1283                @param termination the end point of the line segment
1284                @returns view cells intersecting the line segment.
1285        */
1286    int CastLineSegment(const Vector3 &origin,
1287                                                const Vector3 &termination,
1288                                                ViewCellContainer &viewcells);
1289               
1290        /** Sets pointer to view cells manager.
1291        */
1292        void SetViewCellsManager(ViewCellsManager *vcm);
1293
1294        /** Writes tree to output stream
1295        */
1296#if ZIPPED_VIEWCELLS
1297        bool Export(ogzstream &stream);
1298#else
1299        bool Export(ofstream &stream);
1300#endif
1301
1302        /** Collects rays stored in the leaves.
1303        */
1304        void CollectRays(VssRayContainer &rays);
1305
1306        /** Intersects box with the tree and returns the number of intersected boxes.
1307                @returns number of view cells found
1308        */
1309        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
1310                                                                ViewCellContainer &viewCells) const;
1311
1312
1313        /// pointer to the hierarchy of view cells
1314        ViewCellsTree *mViewCellsTree;
1315
1316
1317protected:
1318
1319        // --------------------------------------------------------------
1320        // For sorting objects
1321        // --------------------------------------------------------------
1322        struct  SortableEntry
1323        {
1324                enum
1325                {
1326                        BOX_MIN,
1327                        BOX_MAX
1328                };
1329
1330                int type;
1331                float value;
1332                Intersectable *mObject;
1333
1334                SortableEntry() {}
1335
1336                SortableEntry(const int t, const float v, Intersectable *obj):
1337                type(t), value(v), mObject(obj)
1338                {}
1339
1340                bool operator<(const SortableEntry &b) const
1341                {
1342                        return value < b.value;
1343                }
1344        };
1345
1346 
1347        /** faster evaluation of split plane cost for kd axis aligned cells.
1348        */
1349        float EvalLocalSplitCost(const OspTraversalData &data,
1350                                                         const AxisAlignedBox3 &box,
1351                                                         const int axis,
1352                                                         const float &position,
1353                                                         float &pFront,
1354                                                         float &pBack) const;
1355
1356        /** Evaluates candidate for splitting.
1357        */
1358        void EvalSplitCandidate(OspSplitCandidate &splitData);
1359
1360        /** Computes priority of the traversal data and stores it in tData.
1361        */
1362        void EvalPriority(OspTraversalData &tData) const;
1363
1364        /** Evaluates render cost decrease of next split.
1365        */
1366        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
1367                                                                 const OspTraversalData &data) const;
1368
1369        float EvalViewCellPvsIncr(Intersectable *object) const;
1370
1371
1372        /** Collects view cells in the subtree under root.
1373        */
1374        void CollectViewCells(KdNode *root,
1375                                                  bool onlyValid,
1376                                                  ViewCellContainer &viewCells,
1377                                                  bool onlyUnmailed = false) const;
1378
1379        /** Evaluates tree stats in the BSP tree leafs.
1380        */
1381        void EvaluateLeafStats(const OspTraversalData &data);
1382
1383        /** Subdivides node using a best split priority queue.
1384            @param tQueue the best split priority queue
1385                @param splitCandidate the candidate for the next split
1386                @param globalCriteriaMet if the global termination criteria were already met
1387                @returns new root of the subtree
1388        */
1389        KdNode *Subdivide(SplitQueue &tQueue,
1390                                          OspSplitCandidate &splitCandidate,
1391                                          const bool globalCriteriaMet);
1392       
1393        /** Subdivides leaf.
1394                @param leaf the leaf to be subdivided
1395               
1396                @param polys the polygons to be split
1397                @param frontPolys returns the polygons in front of the split plane
1398                @param backPolys returns the polygons in the back of the split plane
1399               
1400                @param rays the polygons to be filtered
1401                @param frontRays returns the polygons in front of the split plane
1402                @param backRays returns the polygons in the back of the split plane
1403
1404                @returns the root of the subdivision
1405        */
1406        KdInterior *SubdivideNode(
1407                const AxisAlignedPlane &splitPlane,
1408                const OspTraversalData &tData,
1409                OspTraversalData &frontData,
1410                OspTraversalData &backData);
1411
1412        void SplitObjects(const AxisAlignedPlane & splitPlane,
1413                                          const ObjectContainer &objects,
1414                                          ObjectContainer &front,
1415                                          ObjectContainer &back);
1416
1417        void ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const;
1418
1419        /** Selects an axis aligned for the next split.
1420                @returns cost for this split
1421        */
1422        float SelectPlane(const OspTraversalData &tData,
1423                                          AxisAlignedPlane &plane,
1424                                          float &pFront,
1425                                          float &pBack);
1426
1427        /** Sorts split candidates for cost heuristics using axis aligned splits.
1428                @param node the current node
1429                @param axis the current split axis
1430        */
1431        void SortSplitCandidates(KdLeaf *node, const int axis);
1432
1433        /** Computes best cost for axis aligned planes.
1434        */
1435        float EvalLocalCostHeuristics(KdLeaf *node,
1436                const AxisAlignedBox3 &box,
1437                const int axis,
1438                float &position,
1439                int &objectsFront,
1440                int &objectsBack);
1441
1442        /** Subdivides the rays into front and back rays according to the split plane.
1443               
1444                @param plane the split plane
1445                @param rays contains the rays to be split. The rays are
1446                           distributed into front and back rays.
1447                @param frontRays returns rays on the front side of the plane
1448                @param backRays returns rays on the back side of the plane
1449               
1450                @returns the number of splits
1451        */
1452        int SplitRays(const AxisAlignedPlane &plane,
1453                                  RayInfoContainer &rays,
1454                              RayInfoContainer &frontRays,
1455                                  RayInfoContainer &backRays) const;
1456
1457        /** Adds the object to the pvs of the front and back leaf with a given classification.
1458
1459                @param obj the object to be added
1460                @param cf the ray classification regarding the split plane
1461                @param frontPvs returns the PVS of the front partition
1462                @param backPvs returns the PVS of the back partition
1463       
1464        */
1465        void AddObjToPvs(Intersectable *obj,
1466                                         const int cf,
1467                                         float &frontPvs,
1468                                         float &backPvs,
1469                                         float &totalPvs) const;
1470       
1471        /** Computes PVS size induced by the rays.
1472        */
1473        int ComputePvsSize(const RayInfoContainer &rays) const;
1474
1475        /** Returns true if tree can be terminated.
1476        */
1477        inline bool LocalTerminationCriteriaMet(const OspTraversalData &data) const;
1478
1479        /** Returns true if global tree can be terminated.
1480        */
1481        inline bool GlobalTerminationCriteriaMet(const OspTraversalData &data) const;
1482
1483        float SelectSplitPlane(const OspTraversalData &tData,
1484                AxisAlignedPlane &plane,
1485                float &pFront,
1486                float &pBack);
1487        /** Adds ray sample contributions to the PVS.
1488                @param sampleContributions the number contributions of the samples
1489                @param contributingSampels the number of contributing rays
1490               
1491        */
1492        void AddToPvs(VspLeaf *leaf,
1493                                  const RayInfoContainer &rays,
1494                                  float &sampleContributions,
1495                                  int &contributingSamples);
1496
1497        /** Propagates valid flag up the tree.
1498        */
1499        void PropagateUpValidity(KdNode *node);
1500
1501        /** Writes the node to disk
1502                @note: should be implemented as visitor.
1503        */
1504#if ZIPPED_VIEWCELLS
1505        void ExportNode(KdNode *node, ogzstream &stream);
1506#else
1507        void ExportNode(KdNode *node, ofstream &stream);
1508#endif
1509
1510        /** Returns estimated memory usage of tree.
1511        */
1512        float GetMemUsage() const;
1513
1514        /** Evaluates the influence on the pvs of the visibility event ve.
1515                @param ve the visibility event
1516                @param pvsLeft updates the left pvs
1517                @param rightPvs updates the right pvs
1518        */
1519        void EvalPvsIncr(const SortableEntry &ve,
1520                                          int &pvsLeft,
1521                                          int &pvsRight) const;
1522
1523        void RemoveContriFromPvs(Intersectable *object, int &pvs) const;
1524        void AddContriToPvs(Intersectable *object, int &pvs) const;
1525
1526        /** Prepares objects for the cost heuristics.
1527                @returns pvs size of the node
1528        */
1529        int PrepareHeuristics(const ObjectContainer &objects);
1530
1531        int PrepareHeuristics(Intersectable *object);
1532
1533        void PrepareConstruction(const ObjectContainer &objects,
1534                AxisAlignedBox3 *forcedBoundingBox);
1535
1536
1537protected:
1538
1539        ViewCellsManager *mViewCellsManager;
1540        vector<SortableEntry> *mSplitCandidates;
1541
1542        /// Pointer to the root of the tree
1543        KdNode *mRoot;
1544               
1545        OspTreeStatistics mOspStats;
1546       
1547        /// box around the whole view domain
1548        AxisAlignedBox3 mBoundingBox;
1549
1550
1551        //-- local termination
1552
1553        /// maximal possible depth
1554        int mTermMaxDepth;
1555        /// mininum probability
1556        float mTermMinProbability;
1557        /// minimal number of objects
1558        int mTermMinObjects;
1559        /// maximal contribution per ray
1560        float mTermMaxRayContribution;
1561        /// maximal acceptable cost ratio
1562        float mTermMaxCostRatio;
1563        /// tolerance value indicating how often the max cost ratio can be failed
1564        int mTermMissTolerance;
1565
1566
1567
1568        //-- global criteria
1569        float mTermMinGlobalCostRatio;
1570        int mTermGlobalCostMissTolerance;
1571        int mGlobalCostMisses;
1572
1573        /// maximal number of view cells
1574        int mTermMaxLeaves;
1575        /// maximal tree memory
1576        float mMaxMemory;
1577        /// the tree is out of memory
1578        bool mOutOfMemory;
1579
1580
1581
1582        //-- split heuristics based parameters
1583       
1584        bool mUseCostHeuristics;
1585        /// balancing factor for PVS criterium
1586        float mCtDivCi;
1587        /// if only driving axis should be used for split
1588        bool mOnlyDrivingAxis;
1589       
1590        /// current time stamp (used for keeping split history)
1591        int mTimeStamp;
1592        // if rays should be stored in leaves
1593        bool mStoreRays;
1594
1595        /// epsilon for geometric comparisons
1596        float mEpsilon;
1597
1598
1599        /// subdivision stats output file
1600        ofstream  mSubdivisionStats;
1601        /// keeps track of cost during subdivision
1602        float mTotalCost;
1603        /// keeps track of overall pvs size during subdivision
1604        int mTotalPvsSize;
1605        /// number of currenly generated view cells
1606        int mCreatedLeaves;
1607
1608        /// represents min and max band for sweep
1609        float mSplitBorder;
1610};
1611
1612
1613/** This class implements a structure holding two different hierarchies,
1614        one for object space partitioning and one for view space partitioning.
1615
1616        The object space and the view space are subdivided using a cost heuristics.
1617        If an object space split or a view space split is chosen is also evaluated
1618        based on the heuristics.
1619       
1620        The view space heuristics is evaluated by weighting and adding the pvss of the back and
1621        front node of each specific split. unlike for the standalone method vspbsp tree,
1622        the pvs of an object would not be the pvs of single object but that of all objects
1623        which are contained in the same leaf of the object subdivision. This could be done
1624        by storing the pointer to the object space partition parent, which would allow access to all children.
1625        Another possibility is to include traced kd-cells in the ray casing process.
1626
1627        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
1628        the contribution to an object to the pvs is the number of view cells it can be seen from.
1629
1630        @note
1631        There is a potential efficiency problem involved in a sense that once a certain type
1632        of split is chosen for view space / object space, the candidates for the next split of
1633        object space / view space must be reevaluated.
1634       
1635*/
1636class HierarchyManager
1637{
1638public:
1639        /** Constructor taking an object space partition and a view space partition tree.
1640        */
1641        HierarchyManager(VspTree &vspTree, OspTree &ospTree);
1642
1643        /** Constructs the view space and object space subdivision from a given set of rays
1644                and a set of objects.
1645                @param sampleRays the set of sample rays the construction is based on
1646                @param objects the set of objects
1647        */
1648        void Construct(const VssRayContainer &sampleRays,
1649                                   const ObjectContainer &objects,
1650                                   AxisAlignedBox3 *forcedViewSpace);
1651
1652        /** Constructs first view cells, then object space partition.
1653        */
1654        void Construct2(const VssRayContainer &sampleRays,
1655                                        const ObjectContainer &objects,
1656                                        AxisAlignedBox3 *forcedViewSpace);
1657public:
1658        VspTree &mVspTree;
1659        OspTree &mOspTree;
1660
1661protected:
1662
1663        bool GlobalTerminationCriteriaMet(SplitCandidate *candidate) const;
1664
1665        void PrepareConstruction(const VssRayContainer &sampleRays,
1666                                                         const ObjectContainer &objects,
1667                                                         AxisAlignedBox3 *forcedViewSpace,
1668                                                         RayInfoContainer &rays);
1669
1670        bool FinishedConstruction();
1671        SplitCandidate *NextSplitCandidate();
1672
1673        void RepairQueue(const vector<SplitCandidate *> &dirtyList);
1674
1675        AxisAlignedBox3 mBoundingBox;
1676
1677        SplitQueue mTQueue;
1678
1679        //-- global criteria
1680        float mTermMinGlobalCostRatio;
1681        int mTermGlobalCostMissTolerance;
1682        int mGlobalCostMisses;
1683
1684        /// keeps track of cost during subdivision
1685        float mTotalCost;
1686};
1687
1688}
1689
1690#endif
Note: See TracBrowser for help on using the repository browser.