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

Revision 1221, 48.6 KB checked in by mattausch, 18 years ago (diff)

added intel ray tracing

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