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

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