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

Revision 1074, 41.6 KB checked in by mattausch, 18 years ago (diff)

wked on view space object space partition

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