source: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h @ 1732

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

resolved coflicts
improved memory constant

Line 
1#ifndef _VspTree_H__
2#define _VspTree_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 "SubdivisionCandidate.h"
13#include "HierarchyManager.h"
14
15
16namespace GtpVisibilityPreprocessor {
17
18class ViewCellLeaf;
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 HierarchyManager;
35class KdIntersectable;
36class KdTree;
37class VspTree;
38class KdTreeStatistics;
39
40
41/** View space partition statistics.
42*/
43class VspTreeStatistics: public StatisticsBase
44{
45public:
46        // total number of nodes
47        int nodes;
48        // number of splits
49        int splits[3];
50       
51        // totals number of rays
52        int rays;
53        // maximal reached depth
54        int maxDepth;
55        // minimal depth
56        int minDepth;
57       
58        // max depth nodes
59        int maxDepthNodes;
60        // minimum depth nodes
61        int minDepthNodes;
62        // max depth nodes
63        int minPvsNodes;
64        // nodes with minimum PVS
65        int minRaysNodes;
66        // max ray contribution nodes
67        int maxRayContribNodes;
68        // minimum area nodes
69        int minProbabilityNodes;
70        /// nodes termination because of max cost ratio;
71        int maxCostNodes;
72        // max number of rays per node
73        int maxObjectRefs;
74        /// samples contributing to pvs
75        int contributingSamples;
76        /// sample contributions to pvs
77        int sampleContributions;
78        /// largest pvs
79        int maxPvs;
80        /// number of invalid leaves
81        int invalidLeaves;
82        /// number of rays refs
83        int rayRefs;
84        /// overall pvs size
85        int pvs;
86        // accumulated depth (used to compute average)
87        int accumDepth;
88        // global cost ratio violations
89        int mGlobalCostMisses;
90
91        // Constructor
92        VspTreeStatistics()
93        {
94                Reset();
95        }
96
97        int Nodes() const {return nodes;}
98        int Interior() const { return nodes / 2; }
99        int Leaves() const { return (nodes / 2) + 1; }
100       
101        // TODO: computation wrong
102        double AvgDepth() const { return accumDepth / (double)Leaves();};
103        double AvgRays() const { return rayRefs / (double)Leaves();};
104
105        void Reset()
106        {
107                nodes = 0;
108                for (int i = 0; i < 3; ++ i)
109                        splits[i] = 0;
110               
111                maxDepth = 0;
112                minDepth = 99999;
113                accumDepth = 0;
114        pvs = 0;
115                maxDepthNodes = 0;
116                minPvsNodes = 0;
117                minRaysNodes = 0;
118                maxRayContribNodes = 0;
119                minProbabilityNodes = 0;
120                maxCostNodes = 0;
121
122                contributingSamples = 0;
123                sampleContributions = 0;
124
125                maxPvs = 0;
126                invalidLeaves = 0;
127                rayRefs = 0;
128                maxObjectRefs = 0;
129                mGlobalCostMisses = 0;
130        }
131
132        void Print(ostream &app) const;
133
134        friend ostream &operator<<(ostream &s, const VspTreeStatistics &stat)
135        {
136                stat.Print(s);
137                return s;
138        }
139};
140
141
142/**
143    VspNode abstract class serving for interior and leaf node implementation
144*/
145class VspNode
146{
147public:
148       
149        /// types of vsp nodes
150        enum {Interior, Leaf};
151
152        VspNode();
153        virtual ~VspNode(){};
154        VspNode(VspInterior *parent);
155
156        /** Determines whether this node is a leaf or not
157                @return true if leaf
158        */
159        virtual bool IsLeaf() const = 0;
160
161        virtual int Type() const = 0;
162
163        /** Determines whether this node is a root
164                @return true if root
165        */
166        virtual bool IsRoot() const;
167       
168        /** Returns parent node.
169        */
170        VspInterior *GetParent();
171       
172        /** Sets parent node.
173        */
174        void SetParent(VspInterior *parent);
175
176        /** Returns true if this node is a sibling of node n.
177        */
178        bool IsSibling(VspNode *n) const;
179       
180        /** returns depth of the node.
181        */
182        int GetDepth() const;
183       
184        /** returns true if the whole subtree is valid
185        */
186        bool TreeValid() const;
187
188        void SetTreeValid(const bool v);
189       
190        /** Cost of mergin this node.
191        */
192        float GetMergeCost() {return (float)-mTimeStamp; }
193
194        int mTimeStamp;
195
196        /////////
197        //-- mailing options
198
199        void Mail() { mMailbox = sMailId; }
200        static void NewMail() { ++ sMailId; }
201        bool Mailed() const { return mMailbox == sMailId; }
202
203
204        static int sMailId;
205        int mMailbox;
206
207        //int mPvsEntriesIncr;
208        //float mMemoryIncr;
209        //float mRenderCostDecr;
210
211protected:
212
213        /// if this sub tree is a completely valid view space region
214        bool mTreeValid;
215       
216        /// parent of this node
217        VspInterior *mParent;
218};
219
220
221/** BSP interior node implementation
222*/
223class VspInterior: public VspNode
224{
225public:
226
227        /** Standard contructor taking split plane as argument.
228        */
229        VspInterior(const AxisAlignedPlane &plane);
230
231        ~VspInterior();
232       
233        /** @return false since it is an interior node
234        */
235        bool IsLeaf() const;
236
237        int Type() const;
238
239        VspNode *GetBack();
240        VspNode *GetFront();
241
242        /** Returns split plane.
243        */
244        AxisAlignedPlane GetPlane() const;
245
246        /** Returns position of split plane.
247        */
248        float GetPosition() const;
249
250        /** Returns split axis.
251        */
252        int GetAxis() const;
253
254        /** Replace front or back child with new child.
255        */
256        void ReplaceChildLink(VspNode *oldChild, VspNode *newChild);
257
258        /** Replace front and back child.
259        */
260        void SetupChildLinks(VspNode *front, VspNode *back);
261
262        friend ostream &operator<<(ostream &s, const VspInterior &A)
263        {
264                return s << A.mPlane.mAxis << " " << A.mPlane.mPosition;
265        }
266
267        AxisAlignedBox3 GetBoundingBox() const;
268        void SetBoundingBox(const AxisAlignedBox3 &box);
269
270        /** Computes intersection of this plane with the ray segment.
271        */
272        int ComputeRayIntersection(const RayInfo &rayData, float &t) const
273        {
274                return rayData.ComputeRayIntersection(mPlane.mAxis, mPlane.mPosition, t);
275        }
276
277
278protected:
279        /// bounding box for this interior node: should we really store this?
280        AxisAlignedBox3 mBoundingBox;
281
282        /// Splitting plane corresponding to this node
283        AxisAlignedPlane mPlane;
284
285        /// back node
286        VspNode *mBack;
287        /// front node
288        VspNode *mFront;
289};
290
291
292/** BSP leaf node implementation.
293*/
294class VspLeaf: public VspNode
295{
296        friend VspTree;
297
298public:
299        VspLeaf();
300        VspLeaf(ViewCellLeaf *viewCell);
301        VspLeaf(VspInterior *parent);
302        VspLeaf(VspInterior *parent, ViewCellLeaf *viewCell);
303
304        ~VspLeaf();
305
306        /** @return true since it is an interior node
307        */
308        bool IsLeaf() const;
309       
310        int Type() const;
311
312        /** Returns pointer of view cell.
313        */
314        ViewCellLeaf *GetViewCell() const;
315        /** Sets pointer to view cell.
316        */
317        void SetViewCell(ViewCellLeaf *viewCell);
318
319        SubdivisionCandidate *GetSubdivisionCandidate()
320        {
321                return mSubdivisionCandidate;
322        }
323
324        void SetSubdivisionCandidate(SubdivisionCandidate *candidate)
325        {
326                mSubdivisionCandidate = candidate;
327        }
328
329
330public:
331
332        /// Rays piercing this leaf.
333        VssRayContainer mVssRays;
334       
335        /// Probability that the view point lies in this leaf
336        float mProbability;
337
338protected:
339
340        /// pointer to a split plane candidate splitting this leaf
341        SubdivisionCandidate *mSubdivisionCandidate;
342       
343        /// if NULL this does not correspond to feasible viewcell
344        ViewCellLeaf *mViewCell;
345};
346
347
348/** View Space Partitioning tree.
349*/
350class VspTree
351{
352        friend class ViewCellsParseHandlers;
353        friend class HierarchyManager;
354
355public:
356       
357        /** Additional data which is passed down the BSP tree during traversal.
358        */
359        class VspTraversalData
360        { 
361        public:
362               
363                /** Returns average ray contribution.
364                */
365                float GetAvgRayContribution() const
366                {
367                        return (float)mPvs / ((float)mRays->size() + Limits::Small);
368                }
369
370
371                VspTraversalData():
372                mNode(NULL),
373                mDepth(0),
374                mRays(NULL),
375                mPvs(0),
376                mProbability(0.0),
377                mMaxCostMisses(0),
378                mPriority(0)
379                {}
380               
381                VspTraversalData(VspLeaf *node,
382                                                 const int depth,
383                                                 RayInfoContainer *rays,
384                                                 const int pvs,
385                                                 const float p,
386                                                 const AxisAlignedBox3 &box):
387                mNode(node),
388                mDepth(depth),
389                mRays(rays),
390                mPvs(pvs),
391                mProbability(p),
392                mBoundingBox(box),
393                mMaxCostMisses(0),
394                mPriority(0)
395                {}
396
397                VspTraversalData(const int depth,
398                                                 RayInfoContainer *rays,
399                                                 const AxisAlignedBox3 &box):
400                mNode(NULL),
401                mDepth(depth),
402                mRays(rays),
403                mPvs(0),
404                mProbability(0),
405                mMaxCostMisses(0),
406                mBoundingBox(box)
407                {}
408
409                /** Returns cost of the traversal data.
410                */
411                float GetCost() const
412                {
413                        return mPriority;
414                }
415
416                /// deletes contents and sets them to NULL
417                void Clear()
418                {
419                        DEL_PTR(mRays);
420
421                        if (mNode)
422                        {
423                                // delete old view cell
424                                delete mNode->GetViewCell();
425                                delete mNode;
426                                mNode = NULL;
427                        }
428                }
429
430                /// the current node
431                VspLeaf *mNode;
432                /// current depth
433                int mDepth;
434                /// rays piercing this node
435                RayInfoContainer *mRays;
436                /// the probability that this node contains view point
437                float mProbability;
438                /// the bounding box of the node
439                AxisAlignedBox3 mBoundingBox;
440                /// pvs size
441                int mPvs;
442                /// how often this branch has missed the max-cost ratio
443                int mMaxCostMisses;
444                // current priority
445                float mPriority;
446
447               
448                friend bool operator<(const VspTraversalData &a, const VspTraversalData &b)
449                {
450                        return a.GetCost() < b.GetCost();
451                }
452    };
453
454        /** Candidate for a view space split.
455        */
456        class VspSubdivisionCandidate: public SubdivisionCandidate
457        { 
458        public:
459
460                static VspTree* sVspTree;
461
462                /// the current split plane
463                AxisAlignedPlane mSplitPlane;
464                /// parent node traversal data
465                VspTraversalData mParentData;
466               
467                VspSubdivisionCandidate(const VspTraversalData &tData): mParentData(tData)
468                {};
469
470                ~VspSubdivisionCandidate()
471                {
472                        mParentData.Clear();
473                }
474
475                int Type() const { return VIEW_SPACE; }
476
477                void EvalCandidate(bool computeSplitplane = true)
478                {
479                        mDirty = false;
480                        sVspTree->EvalSubdivisionCandidate(*this, computeSplitplane);
481                }
482
483                bool GlobalTerminationCriteriaMet() const
484                {
485                        return sVspTree->GlobalTerminationCriteriaMet(mParentData);
486                }
487
488                bool Apply(SplitQueue &splitQueue, bool terminationCriteriaMet)
489                {
490                        VspNode *n = sVspTree->Subdivide(splitQueue, this, terminationCriteriaMet);
491                       
492                        // local or global termination criteria failed
493                        return !n->IsLeaf();           
494                }
495
496                void CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList,
497                                                                        const bool onlyUnmailed)
498                {
499                        sVspTree->CollectDirtyCandidates(this, dirtyList, onlyUnmailed);
500                }
501
502        VspSubdivisionCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData):
503                mSplitPlane(plane), mParentData(tData)
504                {}
505
506                float GetPriority() const
507                {
508                        return mPriority;
509                }
510        };
511
512        /** Struct for traversing line segment.
513        */
514        struct LineTraversalData
515        {
516                VspNode *mNode;
517                Vector3 mExitPoint;
518                float mMaxT;
519   
520                LineTraversalData () {}
521                LineTraversalData (VspNode *n, const Vector3 &p, const float maxt):
522                mNode(n), mExitPoint(p), mMaxT(maxt) {}
523        };
524
525        /** Default constructor creating an empty tree.
526        */
527        VspTree();
528        /** Default destructor.
529        */
530        ~VspTree();
531
532        /** Returns BSP Tree statistics.
533        */
534        const VspTreeStatistics &GetStatistics() const;
535 
536        /** Returns bounding box of the specified node.
537        */
538        AxisAlignedBox3 GetBoundingBox(VspNode *node) const;
539
540        /** Returns list of BSP leaves with pvs smaller than
541                a certain threshold.
542                @param onlyUnmailed if only the unmailed leaves should be considered
543                @param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
544        */
545        void CollectLeaves(vector<VspLeaf *> &leaves,
546                                           const bool onlyUnmailed = false,
547                                           const int maxPvs = -1) const;
548
549        /** Returns box which bounds the whole tree.
550        */
551        AxisAlignedBox3 GetBoundingBox() const;
552
553        /** Returns root of the view space partitioning tree.
554        */
555        VspNode *GetRoot() const;
556
557        /** Collects the leaf view cells of the tree
558                @param viewCells returns the view cells
559        */
560        void CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const;
561
562        /** A ray is cast possible intersecting the tree.
563                @param the ray that is cast.
564                @returns the number of intersections with objects stored in the tree.
565        */
566        int CastRay(Ray &ray);
567
568
569        /** finds neighbouring leaves of this tree node.
570        */
571        int FindNeighbors(VspLeaf *n,
572                                          vector<VspLeaf *> &neighbors,
573                                          const bool onlyUnmailed) const;
574
575        /** Returns random leaf of BSP tree.
576                @param halfspace defines the halfspace from which the leaf is taken.
577        */
578        VspLeaf *GetRandomLeaf(const Plane3 &halfspace);
579
580        /** Returns random leaf of BSP tree.
581                @param onlyUnmailed if only unmailed leaves should be returned.
582        */
583        VspLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
584
585        /** Returns epsilon of this tree.
586        */
587        float GetEpsilon() const;
588
589        /** Casts line segment into the tree.
590                @param origin the origin of the line segment
591                @param termination the end point of the line segment
592                @returns view cells intersecting the line segment.
593        */
594    int CastLineSegment(const Vector3 &origin,
595                                                const Vector3 &termination,
596                                                ViewCellContainer &viewcells,
597                                                const bool useMailboxing = true);
598
599               
600        /** Sets pointer to view cells manager.
601        */
602        void SetViewCellsManager(ViewCellsManager *vcm);
603
604        /** Returns view cell the current point is located in.
605                @param point the current view point
606                @param active if currently active view cells should be returned or
607                elementary view cell
608        */
609        ViewCell *GetViewCell(const Vector3 &point, const bool active = false);
610
611
612        /** Returns true if this view point is in a valid view space,
613                false otherwise.
614        */
615        bool ViewPointValid(const Vector3 &viewPoint) const;
616
617        /** Returns view cell corresponding to
618                the invalid view space.
619        */
620        VspViewCell *GetOutOfBoundsCell();
621
622        /** Writes tree to output stream
623        */
624        bool Export(OUT_STREAM &stream);
625
626        /** Casts beam, i.e. a 5D frustum of rays, into tree.
627                Tests conservative using the bounding box of the nodes.
628                @returns number of view cells it intersected
629        */
630        int CastBeam(Beam &beam);
631
632        /** Checks if tree validity-flags are right
633                with respect to view cell valitiy.
634                If not, marks subtree as invalid.
635        */
636        void ValidateTree();
637
638        /** Invalid view cells are added to the unbounded space
639        */
640        void CollapseViewCells();
641
642        /** Collects rays stored in the leaves.
643        */
644        void CollectRays(VssRayContainer &rays);
645
646        /** Intersects box with the tree and returns the number of intersected boxes.
647                @returns number of view cells found
648        */
649        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
650                                                                ViewCellContainer &viewCells) const;
651
652        /** Returns view cells of this ray, either taking precomputed cells
653                or by recomputation.
654        */
655        void GetViewCells(const VssRay &ray, ViewCellContainer &viewCells);
656
657        /** Returns view cells tree.
658        */
659        ViewCellsTree *GetViewCellsTree() const { return mViewCellsTree; }
660
661        /** Sets the view cells tree.
662        */
663        void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
664
665#if WORK_WITH_VIEWCELLS
666        /** Remove the references of the parent view cell from the kd nodes associated with
667                the objects.
668        */
669        void RemoveParentViewCellReferences(ViewCell *parent) const;
670
671        /** Adds references to the view cell to the kd nodes associated with the objects.
672        */
673        void AddViewCellReferences(ViewCell *vc) const;
674#endif
675
676        VspNode *SubdivideAndCopy(SplitQueue &tQueue, SubdivisionCandidate *splitCandidate);
677
678protected:
679
680        // --------------------------------------------------------------
681        // For sorting objects
682        // --------------------------------------------------------------
683        struct SortableEntry
684        {
685                enum EType
686                {
687                        ERayMin,
688                        ERayMax
689                };
690
691                int type;
692                float value;
693                VssRay *ray;
694 
695                SortableEntry() {}
696                SortableEntry(const int t, const float v, VssRay *r):
697                type(t), value(v), ray(r)
698                {
699                }
700               
701                friend inline bool operator<(const SortableEntry &a, const SortableEntry &b)
702                {       // prefer max event
703                        //if (EpsilonEqual(a.value, b.value, 0.0001f))
704                        //      return (a.type == ERayMax);
705
706                        return (a.value < b.value);
707                }
708        };
709
710        /** faster evaluation of split plane cost for kd axis aligned cells.
711        */
712        float EvalLocalSplitCost(const VspTraversalData &data,
713                                                         const AxisAlignedBox3 &box,
714                                                         const int axis,
715                                                         const float &position,
716                                                         float &pFront,
717                                                         float &pBack) const;
718
719        void ComputeBoundingBox(const VssRayContainer &rays,
720                                                        AxisAlignedBox3 *forcedBoundingBox);
721
722        /** Evaluates candidate for splitting.
723        */
724        void EvalSubdivisionCandidate(VspSubdivisionCandidate &splitData,
725                                                                  bool computeSplitPlane = true);
726
727        /** Evaluates render cost decrease of next split.
728        */
729        float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
730                                                                 const VspTraversalData &data,
731                                                                 float &normalizedOldRenderCost) const;
732
733        /** Collects view cells in the subtree under root.
734        */
735        void CollectViewCells(VspNode *root,
736                                                  bool onlyValid,
737                                                  ViewCellContainer &viewCells,
738                                                  bool onlyUnmailed = false) const;
739
740        /** Returns view cell corresponding to
741                the invalid view space. If it does not exist, it is created.
742        */
743        VspViewCell *GetOrCreateOutOfBoundsCell();
744
745        /** Collapses the tree with respect to the view cell partition,
746                i.e. leaves having the same view cell are collapsed.
747                @param node the root of the subtree to be collapsed
748                @param collapsed returns the number of collapsed nodes
749                @returns node of type leaf if the node could be collapsed,
750                this node otherwise
751        */
752        VspNode *CollapseTree(VspNode *node, int &collapsed);
753
754        /** Helper function revalidating the view cell leaf list after merge.
755        */
756        void RepairViewCellsLeafLists();
757
758        /** Evaluates tree stats in the BSP tree leafs.
759        */
760        void EvaluateLeafStats(const VspTraversalData &data);
761
762        /** Subdivides node using a best split priority queue.
763            @param tQueue the best split priority queue
764                @param splitCandidate the candidate for the next split
765                @param globalCriteriaMet if the global termination criteria were already met
766                @returns new root of the subtree
767        */
768        VspNode *Subdivide(SplitQueue &tQueue,
769                                           SubdivisionCandidate *splitCandidate,
770                                           const bool globalCriteriaMet);
771
772        /** Adds stats to subdivision log file.
773        */
774        void AddSubdivisionStats(const int viewCells,
775                                                         const float renderCostDecr,
776                                                         const float totalRenderCost,
777                                                         const float avgRenderCost);
778       
779        /** Subdivides leaf.
780                       
781                @param tData data object holding, e.g., a pointer to the leaf
782                @param frontData returns the data (e.g.,  pointer to the leaf) in front of the split plane
783                @param backData returns the data (e.g.,  pointer to the leaf) in the back of the split plane
784               
785                @param rays the polygons to be filtered
786                @param frontRays returns the polygons in front of the split plane
787       
788                @returns the root of the subdivision
789        */
790        VspInterior *SubdivideNode(const AxisAlignedPlane &splitPlane,
791                                                           VspTraversalData &tData,
792                                                           VspTraversalData &frontData,
793                               VspTraversalData &backData);
794
795        /** Selects an axis aligned for the next split.
796                @returns cost for this split
797        */
798        float SelectSplitPlane(const VspTraversalData &tData,
799                                                   AxisAlignedPlane &plane,
800                                                   float &pFront,
801                                                   float &pBack);
802
803        /** Sorts split candidates along the specified axis.
804                The split candidates are generated on possible visibility
805                events (i.e., where ray segments intersect the ray boundaries).
806                The sorted candidates are needed to compute the heuristics.
807
808                @param polys the input for choosing split candidates
809                @param axis the current split axis
810                @param splitCandidates returns sorted list of split candidates
811        */
812        void SortSubdivisionCandidates(const RayInfoContainer &rays,
813                                                         const int axis,
814                                                         float minBand,
815                                                         float maxBand);
816
817        /** Evaluate pvs size as induced by the samples.
818        */
819        int EvalPvsSize(const RayInfoContainer &rays) const;
820
821        int EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate) const;
822
823        /** Returns number of effective entries in the pvs.
824        */
825        int EvalPvsEntriesSize(const RayInfoContainer &rays) const;
826        int EvalPvsEntriesContribution(const VssRay &ray, const bool isTermination) const;
827        /** Computes best cost for axis aligned planes.
828        */
829        float EvalLocalCostHeuristics(const VspTraversalData &tData,
830                                                                  const AxisAlignedBox3 &box,
831                                                                  const int axis,
832                                                                  float &position);
833
834
835        //////////////////////////////////////////
836        // Helper function for computing heuristics
837
838        /** Evaluates the contribution to left and right pvs at a visibility event ve.
839                @param ve the visibility event
840                @param pvsLeft updates the left pvs
841                @param rightPvs updates the right pvs
842        */
843        void EvalHeuristics(const SortableEntry &ve, int &pvsLeft, int &pvsRight) const;
844
845        /** Evaluates contribution of min event to pvs
846        */
847        int EvalMinEventContribution(
848                const VssRay &ray, const bool isTermination) const;
849
850        /** Evaluates contribution of max event to pvs
851        */
852        int EvalMaxEventContribution(
853                const VssRay &ray, const bool isTermination) const;
854
855        /** Evaluates contribution of kd leaf when encountering a min event
856        */
857        int EvalMinEventContribution(KdLeaf *leaf) const;
858        /**  Evaluates contribution of kd leaf when encountering a max event
859        */
860        int EvalMaxEventContribution(KdLeaf *leaf) const;
861
862        /** Prepares objects for the heuristics.
863                @returns pvs size as seen by the rays.
864        */
865        int PrepareHeuristics(const RayInfoContainer &rays);
866       
867        /** Prepare a single ray for heuristics.
868        */
869        int PrepareHeuristics(const VssRay &ray, const bool isTermination);
870        /** Prepare a single kd leaf for heuristics.
871        */
872        int PrepareHeuristics(KdLeaf *leaf);
873
874       
875        /////////////////////////////////////////////////////////////////////////////
876
877
878        /** Subdivides the rays into front and back rays according to the split plane.
879               
880                @param plane the split plane
881                @param rays contains the rays to be split. The rays are
882                           distributed into front and back rays.
883                @param frontRays returns rays on the front side of the plane
884                @param backRays returns rays on the back side of the plane
885               
886                @returns the number of splits
887        */
888        int SplitRays(const AxisAlignedPlane &plane,
889                                  RayInfoContainer &rays,
890                              RayInfoContainer &frontRays,
891                                  RayInfoContainer &backRays) const;
892
893        void UpdatePvsEntriesContribution(
894                const VssRay &ray,
895                const bool isTermination,
896                const int cf,
897                float &frontPvs,
898                float &backPvs,
899                float &totalPvs) const;
900
901        /** Classfifies the object with respect to the
902                pvs of the front and back leaf and updates pvs size
903                accordingly.
904
905                @param obj the object to be added
906                @param cf the ray classification regarding the split plane
907                @param frontPvs returns the PVS of the front partition
908                @param backPvs returns the PVS of the back partition
909       
910        */
911        void UpdateContributionsToPvs(
912                const VssRay &ray,
913                const bool isTermination,
914                const int cf,
915                float &frontPvs,
916                float &backPvs,
917                float &totalPvs) const;
918
919        /** Evaluates the contribution for objects.
920        */
921        void UpdateContributionsToPvs(
922                Intersectable *obj,
923                const int cf,
924                float &frontPvs,
925                float &backPvs,
926                float &totalPvs) const;
927
928        /** Evaluates the contribution for bounding volume leaves.
929        */
930        void UpdateContributionsToPvs(
931                BvhLeaf *leaf,
932                const int cf,
933                float &frontPvs,
934                float &backPvs,
935                float &totalPvsm,
936                const bool countEntries = false) const;
937
938        /** Evaluates the contribution for kd leaves.
939        */
940        void UpdateContributionsToPvs(
941                KdLeaf *leaf,
942                const int cf,
943                float &frontPvs,
944                float &backPvs,
945                float &totalPvs) const;
946
947        /** Returns true if tree can be terminated.
948        */
949        bool LocalTerminationCriteriaMet(const VspTraversalData &data) const;
950
951        /** Returns true if global tree can be terminated.
952        */
953        bool GlobalTerminationCriteriaMet(const VspTraversalData &data) const;
954
955        /** Adds ray sample contributions to the PVS.
956                @param sampleContributions the number contributions of the samples
957                @param contributingSampels the number of contributing rays
958               
959        */
960        void AddSamplesToPvs(VspLeaf *leaf,
961                                                 const RayInfoContainer &rays,
962                                                 float &sampleContributions,
963                                                 int &contributingSamples);
964
965        /** Propagates valid flag up the tree.
966        */
967        void PropagateUpValidity(VspNode *node);
968
969        /** Writes the node to disk
970                @note: should be implemented as visitor.
971        */
972        void ExportNode(VspNode *node, OUT_STREAM &stream);
973
974        /** Returns estimated memory usage of tree.
975        */
976        float GetMemUsage() const;
977
978        /** Updates view cell pvs of objects.
979        */
980        void ProcessViewCellObjects(ViewCell *parent,
981                                                                ViewCell *front,
982                                                                ViewCell *back) const;
983
984        void CreateViewCell(VspTraversalData &tData, const bool updatePvs);
985
986        /** Collect split candidates which are affected by the last split
987                and must be reevaluated.
988        */
989        void CollectDirtyCandidates(VspSubdivisionCandidate *sc,
990                                                                vector<SubdivisionCandidate *> &dirtyList,
991                                                                const bool onlyUnmailed);
992
993        void CollectDirtyCandidate(const VssRay &ray,
994                                                           const bool isTermination,
995                                                           vector<SubdivisionCandidate *> &dirtyList,
996                                                           const bool onlyUnmailed) const;
997
998        /** Rays will be clipped to the bounding box.
999        */
1000        void PreprocessRays(const VssRayContainer &sampleRays, RayInfoContainer &rays);
1001
1002        /** Evaluate subdivision statistics.
1003        */
1004        void EvalSubdivisionStats(const SubdivisionCandidate &tData);
1005
1006        SubdivisionCandidate *PrepareConstruction(
1007                const VssRayContainer &sampleRays,
1008                RayInfoContainer &rays);
1009
1010        /** Evaluates pvs contribution of this ray.
1011        */
1012        int EvalContributionToPvs(const VssRay &ray, const bool isTermination) const;
1013
1014        /** Evaluates pvs contribution of a kd node.
1015        */
1016        int EvalContributionToPvs(KdLeaf *leaf) const;
1017
1018        /** Creates new root of hierarchy and computes bounding box.
1019                Has to be called before the preparation of the subdivision.
1020        */
1021        void Initialise(const VssRayContainer &rays,
1022                                        AxisAlignedBox3 *forcedBoundingBox);
1023
1024protected:
1025
1026        /// pointer to the hierarchy of view cells
1027        ViewCellsTree *mViewCellsTree;
1028
1029        HierarchyManager *mHierarchyManager;
1030        //OspTree *mOspTree;
1031        //bool mUseKdPvsForHeuristics;
1032       
1033        ViewCellsManager *mViewCellsManager;
1034       
1035        vector<SortableEntry> *mLocalSubdivisionCandidates;
1036
1037        /// Pointer to the root of the tree
1038        VspNode *mRoot;
1039               
1040        VspTreeStatistics mVspStats;
1041       
1042        /// View cell corresponding to the space outside the valid view space
1043        VspViewCell *mOutOfBoundsCell;
1044
1045        /// box around the whole view domain
1046        AxisAlignedBox3 mBoundingBox;
1047
1048
1049        //-- local termination
1050
1051        /// minimal number of rays before subdivision termination
1052        int mTermMinRays;
1053        /// maximal possible depth
1054        int mTermMaxDepth;
1055        /// mininum probability
1056        float mTermMinProbability;
1057        /// mininum PVS
1058        int mTermMinPvs;
1059        /// maximal contribution per ray
1060        float mTermMaxRayContribution;
1061        /// maximal acceptable cost ratio
1062        float mTermMaxCostRatio;
1063        /// tolerance value indicating how often the max cost ratio can be failed
1064        int mTermMissTolerance;
1065
1066
1067        //-- global criteria
1068        float mTermMinGlobalCostRatio;
1069        int mTermGlobalCostMissTolerance;
1070       
1071
1072        /// maximal number of view cells
1073        int mMaxViewCells;
1074        /// maximal tree memory
1075        float mMaxMemory;
1076        /// the tree is out of memory
1077        bool mOutOfMemory;
1078
1079        ////////////
1080        //-- split heuristics based parameters
1081       
1082        bool mUseCostHeuristics;
1083        /// balancing factor for PVS criterium
1084        float mCtDivCi;
1085        /// if only driving axis should be used for split
1086        bool mOnlyDrivingAxis;
1087        /// if random split axis should be used
1088        bool mUseRandomAxis;
1089        /// if vsp bsp tree should simulate octree
1090        bool mCirculatingAxis;
1091        /// minimal relative position where the split axis can be placed
1092        float mMinBand;
1093        /// maximal relative position where the split axis can be placed
1094        float mMaxBand;
1095
1096
1097        /// current time stamp (used for keeping split history)
1098        int mTimeStamp;
1099        // if rays should be stored in leaves
1100        bool mStoreRays;
1101
1102        /// epsilon for geometric comparisons
1103        float mEpsilon;
1104
1105        /// subdivision stats output file
1106        ofstream  mSubdivisionStats;
1107        /// keeps track of cost during subdivision
1108        float mTotalCost;
1109        int mPvsEntries;
1110        /// keeps track of overall pvs size during subdivision
1111        int mTotalPvsSize;
1112        /// number of currenly generated view cells
1113        int mCreatedViewCells;
1114
1115        /// weight between render cost decrease and node render cost
1116        float mRenderCostDecreaseWeight;
1117
1118        int mMaxTests;
1119
1120        /// constant value for driving the heuristics
1121        float mMemoryConst;
1122};
1123
1124
1125}
1126
1127#endif
Note: See TracBrowser for help on using the repository browser.