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

Revision 1664, 27.6 KB checked in by mattausch, 18 years ago (diff)

changed priority computation:
taking ratio render cost decrease / pvs size increase rather
then render cost decrease alone
this should rather emphasise object space splits, as they
seem to cost less memory.

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