source: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h @ 1779

Revision 1779, 25.6 KB checked in by mattausch, 18 years ago (diff)

warning: this version contains bugs!!

Line 
1#ifndef _BvHierarchy_H__
2#define _BvHierarchy_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 "AxisAlignedBox3.h"
14#include "IntersectableWrapper.h"
15#include "HierarchyManager.h"
16
17
18namespace GtpVisibilityPreprocessor {
19
20
21class ViewCellLeaf;
22class Plane3;
23class AxisAlignedBox3;
24class Ray;
25class ViewCellsStatistics;
26class ViewCellsManager;
27class MergeCandidate;
28class Beam;
29class ViewCellsTree;
30class Environment;
31class BvhInterior;
32class BvhLeaf;
33class BvhNode;
34class BvhTree;
35class VspTree;
36class ViewCellsContainer;
37class HierarchyManager;
38
39
40/** View space partition statistics.
41*/
42class BvhStatistics: public StatisticsBase
43{
44public:
45       
46        /// Constructor
47        BvhStatistics()
48        {
49                Reset();
50        }
51
52        int Nodes() const {return nodes;}
53        int Interior() const { return nodes / 2; }
54        int Leaves() const { return (nodes / 2) + 1; }
55       
56        double AvgDepth() const
57        { return accumDepth / (double)Leaves(); }
58
59        double AvgObjectRefs() const
60        { return objectRefs / (double)Leaves(); }
61
62        double AvgRayRefs() const
63        { return rayRefs / (double)Leaves(); }
64
65       
66        void Reset()
67        {
68                nodes = 0;
69                splits = 0;
70                maxDepth = 0;
71
72                minDepth = 99999;
73                accumDepth = 0;
74        maxDepthNodes = 0;
75                minProbabilityNodes = 0;
76                maxCostNodes = 0;
77                ///////////////////
78                minObjectsNodes = 0;
79                maxObjectRefs = 0;
80                minObjectRefs = 999999999;
81                objectRefs = 0;
82                emptyNodes = 0;
83
84                ///////////////////
85                minRaysNodes = 0;
86                maxRayRefs = 0;
87                minRayRefs = 999999999;
88                rayRefs = 0;
89                maxRayContriNodes = 0;
90                mGlobalCostMisses = 0;
91        }
92
93
94public:
95
96        // total number of nodes
97        int nodes;
98        // number of splits
99        int splits;
100        // maximal reached depth
101        int maxDepth;
102        // minimal depth
103        int minDepth;
104        // max depth nodes
105        int maxDepthNodes;
106        // accumulated depth (used to compute average)
107        int accumDepth;
108        // minimum area nodes
109        int minProbabilityNodes;
110        /// nodes termination because of max cost ratio;
111        int maxCostNodes;
112        // global cost ratio violations
113        int mGlobalCostMisses;
114
115        //////////////////
116        // nodes with minimum objects
117        int minObjectsNodes;
118        // max number of rays per node
119        int maxObjectRefs;
120        // min number of rays per node
121        int minObjectRefs;
122        /// object references
123        int objectRefs;
124        // leaves with no objects
125        int emptyNodes;
126
127        //////////////////////////
128        // nodes with minimum rays
129        int minRaysNodes;
130        // max number of rays per node
131        int maxRayRefs;
132        // min number of rays per node
133        int minRayRefs;
134        /// object references
135        int rayRefs;
136        /// nodes with max ray contribution
137        int maxRayContriNodes;
138
139        void Print(ostream &app) const;
140
141        friend ostream &operator<<(ostream &s, const BvhStatistics &stat)
142        {
143                stat.Print(s);
144                return s;
145        }
146};
147
148
149/**
150    VspNode abstract class serving for interior and leaf node implementation
151*/
152class BvhNode: public Intersectable
153{
154public:
155       
156        // types of vsp nodes
157        enum {Interior, Leaf};
158
159        BvhNode();
160        BvhNode(const AxisAlignedBox3 &bbox);
161        BvhNode(const AxisAlignedBox3 &bbox, BvhInterior *parent);
162
163        virtual ~BvhNode(){};
164
165        /** Determines whether this node is a leaf or not
166                @return true if leaf
167        */
168        virtual bool IsLeaf() const = 0;
169
170        /** Determines whether this node is a root
171                @return true if root
172        */
173        virtual bool IsRoot() const;
174
175        /** Returns parent node.
176        */
177        BvhInterior *GetParent();
178
179        /** Sets parent node.
180        */
181        void SetParent(BvhInterior *parent);
182
183        /** collects all objects under this node.
184        */
185        virtual void CollectObjects(ObjectContainer &objects) = 0;
186
187        /** The bounding box specifies the node extent.
188        */
189        inline
190        AxisAlignedBox3 GetBoundingBox() const
191        { return mBoundingBox; }
192
193        /** Sets bouding box of this node.
194        */
195        inline
196        void SetBoundingBox(const AxisAlignedBox3 &boundingBox)
197        { mBoundingBox = boundingBox; }
198
199        /** Cost of mergin this node.
200        */
201        float GetMergeCost() {return (float)-mTimeStamp; }
202
203        virtual int GetRandomEdgePoint(Vector3 &point,
204                                                                 Vector3 &normal);
205
206        inline int GetTimeStamp() const { return mTimeStamp; }
207        inline void SetTimeStamp(const int timeStamp) { mTimeStamp = timeStamp; };
208
209        /////////////////////////////////////
210        //-- mailing options
211       
212//      static void NewMail(const int reserve = 1) {
213//              sMailId += sReservedMailboxes;
214//              sReservedMailboxes = reserve;
215//      }
216       
217//      void Mail() { mMailbox = sMailId; }
218//      bool Mailed() const { return mMailbox == sMailId; }
219
220//      void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
221//      bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
222
223//      int IncMail() { return ++ mMailbox - sMailId; }
224
225//      static int sMailId;
226//      //int mMailbox;
227//      static int sReservedMailboxes;
228
229
230
231        /////////////////////////////////////////////
232        //-- inherited functions from Intersectable
233
234        AxisAlignedBox3 GetBox() const { return mBoundingBox; }
235       
236        int CastRay(Ray &ray) { return 0; }
237       
238        bool IsConvex() const { return true; }
239        bool IsWatertight() const { return true; }
240        float IntersectionComplexity() { return 1; }
241 
242        int NumberOfFaces() const { return 6; };
243       
244        int GetRandomSurfacePoint(GtpVisibilityPreprocessor::Vector3 &point,
245                                                          GtpVisibilityPreprocessor::Vector3 &normal)
246        {
247                // TODO
248                return 0;
249        }
250
251        int GetRandomVisibleSurfacePoint(GtpVisibilityPreprocessor::Vector3 &point,
252                                                                         GtpVisibilityPreprocessor::Vector3 &normal,
253                                                                         const GtpVisibilityPreprocessor::Vector3 &viewpoint,
254                                                                         const int maxTries)
255        {
256                // TODO
257                return 0;
258        }
259 
260        int Type() const
261        {
262                return Intersectable::BVH_INTERSECTABLE;
263        }
264
265        ostream &Describe(ostream &s) { return s; }
266
267        ///////////////////////////////////
268
269protected:
270       
271        /// the bounding box of the node
272        AxisAlignedBox3 mBoundingBox;
273        /// parent of this node
274        BvhInterior *mParent;
275        int mTimeStamp;
276};
277
278
279/** BSP interior node implementation
280*/
281class BvhInterior: public BvhNode
282{
283public:
284        /** Standard contructor taking a bounding box as argument.
285        */
286        BvhInterior(const AxisAlignedBox3 &bbox);
287        BvhInterior(const AxisAlignedBox3 &bbox, BvhInterior *parent);
288
289        ~BvhInterior();
290        /** @return false since it is an interior node
291        */
292        bool IsLeaf() const;
293       
294        BvhNode *GetBack() { return mBack; }
295        BvhNode *GetFront() { return mFront; }
296
297        /** Replace front or back child with new child.
298        */
299        void ReplaceChildLink(BvhNode *oldChild, BvhNode *newChild);
300
301        /** Replace front and back child.
302        */
303        void SetupChildLinks(BvhNode *front, BvhNode *back);
304
305        friend ostream &operator<<(ostream &s, const BvhInterior &A)
306        {
307                return s << A.mBoundingBox;
308        }
309
310        virtual void CollectObjects(ObjectContainer &objects);
311
312protected:
313
314        /// back node
315        BvhNode *mBack;
316        /// front node
317        BvhNode *mFront;
318};
319
320
321/** BSP leaf node implementation.
322*/
323class BvhLeaf: public BvhNode
324{
325public:
326        /** Standard contructor taking a bounding box as argument.
327        */
328        BvhLeaf(const AxisAlignedBox3 &bbox);
329        BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent);
330        BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent, const int numObjects);
331
332        ~BvhLeaf();
333
334        /** @return true since it is an interior node
335        */
336        bool IsLeaf() const;
337       
338        SubdivisionCandidate *GetSubdivisionCandidate()// const
339        {
340                return mSubdivisionCandidate;
341        }
342
343        void SetSubdivisionCandidate(SubdivisionCandidate *candidate)
344        {
345                mSubdivisionCandidate = candidate;
346        }
347       
348        virtual void CollectObjects(ObjectContainer &objects);
349
350        /** Returns level of the hierarchy that is "active" right now.
351        */
352        BvhNode *GetActiveNode()
353        {
354                return mActiveNode;
355        }
356
357        /** Returns level of the hierarchy that is "active" right now.
358        */
359        void SetActiveNode(BvhNode *node)
360        {
361                mActiveNode = node;
362        }
363
364public:
365
366        /// objects
367        ObjectContainer mObjects;
368
369protected:
370
371        /// pointer to a split plane candidate splitting this leaf
372        SubdivisionCandidate *mSubdivisionCandidate;
373
374        /// the active node which will be accounted for in the pvs
375        BvhNode *mActiveNode;
376};
377
378
379/** View Space Partitioning tree.
380*/
381class BvHierarchy
382{
383        friend class ViewCellsParseHandlers;
384        friend class HierarchyManager;
385
386protected:
387        struct SortableEntry;
388        typedef vector<SortableEntry> SortableEntryContainer;
389
390public:
391       
392        /** Additional data which is passed down the BSP tree during traversal.
393        */
394        class BvhTraversalData
395        { 
396        public:
397               
398                BvhTraversalData():
399                mNode(NULL),
400                mDepth(0),
401                mProbability(0.0),
402                mMaxCostMisses(0),
403                mAxis(0),
404                mNumRays(0)
405                {
406                        for (int i = 0; i < 4; ++ i)
407                                mSortedObjects[i] = NULL;
408                }
409               
410                BvhTraversalData(BvhLeaf *node,
411                                                 const int depth,
412                                                 const float v,
413                                                 const int numRays):
414                mNode(node),
415                mDepth(depth),
416                //mBoundingBox(box),
417                mProbability(v),
418                mMaxCostMisses(0),
419                mAxis(0),
420                mNumRays(numRays)
421                {
422                        for (int i = 0; i < 4; ++ i)
423                                mSortedObjects[i] = NULL;
424                }
425
426                /** Deletes contents and sets them to NULL.
427                */
428                void Clear()
429                {
430                        DEL_PTR(mNode);
431                        for (int i = 0; i < 4; ++ i)
432                                DEL_PTR(mSortedObjects[i]);
433                }
434
435                /// the current node
436                BvhLeaf *mNode;
437                /// current depth
438                int mDepth;
439                /// the probability that this node is seen
440                float mProbability;
441                /// the bounding box of the node
442                //AxisAlignedBox3 mBoundingBox;
443                /// how often this branch has missed the max-cost ratio
444                int mMaxCostMisses;
445                /// current axis
446                int mAxis;
447                /// number of rays
448                int mNumRays;
449                /// the sorted objects for the three dimensions
450                ObjectContainer *mSortedObjects[4];             
451    };
452
453
454        /** Candidate for a object space split.
455        */
456        class BvhSubdivisionCandidate: public SubdivisionCandidate
457        { 
458        public:
459
460        BvhSubdivisionCandidate(const BvhTraversalData &tData): mParentData(tData)
461                {};
462
463                ~BvhSubdivisionCandidate()
464                {
465                        mParentData.Clear();
466                }
467
468                int Type() const { return OBJECT_SPACE; }
469       
470                void EvalCandidate(bool computeSplitplane = true)
471                {
472            mDirty = false;
473                        sBvHierarchy->EvalSubdivisionCandidate(*this, computeSplitplane);
474                }
475
476                bool Apply(SplitQueue &splitQueue, bool terminationCriteriaMet)
477                {
478                        BvhNode *n = sBvHierarchy->Subdivide(splitQueue, this, terminationCriteriaMet);
479
480                        // local or global termination criteria failed
481                        return !n->IsLeaf();           
482                }
483
484                void CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList,
485                                                                        const bool onlyUnmailed)
486                {
487                        sBvHierarchy->CollectDirtyCandidates(this, dirtyList, onlyUnmailed);
488                }
489
490                bool GlobalTerminationCriteriaMet() const
491                {
492                        return sBvHierarchy->GlobalTerminationCriteriaMet(mParentData);
493                }
494
495                BvhSubdivisionCandidate(const ObjectContainer &frontObjects,
496                                                                const ObjectContainer &backObjects,
497                                                                const BvhTraversalData &tData):
498                mFrontObjects(frontObjects), mBackObjects(backObjects), mParentData(tData)
499                {}
500
501                float GetPriority() const
502                {
503                        return mPriority;
504                }
505
506                /// pointer to parent tree.
507                static BvHierarchy *sBvHierarchy;
508
509                /// parent data
510                BvhTraversalData mParentData;
511                /// the objects on the front of the potential split
512                ObjectContainer mFrontObjects;
513                /// the objects on the back of the potential split
514                ObjectContainer mBackObjects;
515        };
516
517        /** Struct for traversing line segment.
518        */
519        struct LineTraversalData
520        {
521                BvhNode *mNode;
522                Vector3 mExitPoint;
523               
524                float mMaxT;
525   
526                LineTraversalData () {}
527                LineTraversalData (BvhNode *n, const Vector3 &p, const float maxt):
528                mNode(n), mExitPoint(p), mMaxT(maxt) {}
529        };
530
531
532        /** Default constructor creating an empty tree.
533        */
534        BvHierarchy();
535
536        /** Default destructor.
537        */
538        ~BvHierarchy();
539
540        /** Returns tree statistics.
541        */
542        const BvhStatistics &GetStatistics() const;
543 
544        /** Returns bounding box of the specified node.
545        */
546        AxisAlignedBox3 GetBoundingBox(BvhNode *node) const;
547
548        /** Reads parameters from environment singleton.
549        */
550        void ReadEnvironment();
551
552        /** Evaluates candidate for splitting.
553        */
554        void EvalSubdivisionCandidate(BvhSubdivisionCandidate &splitData,
555                                                                  bool computeSplitPlane = true);
556
557        /** Returns vector of leaves.
558        */
559        void CollectLeaves(BvhNode *root, vector<BvhLeaf *> &leaves) const;
560
561        /** Returns bounding box of the whole tree (= bbox of root node)
562        */
563        AxisAlignedBox3 GetBoundingBox()const;
564
565        /** Returns root of the view space partitioning tree.
566        */
567        BvhNode *GetRoot() const;
568
569        /** finds neighbouring leaves of this tree node.
570        */
571        int FindNeighbors(BvhLeaf *n,
572                                          vector<BvhLeaf *> &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        BvhLeaf *GetRandomLeaf(const Plane3 &halfspace);
579
580        /** Returns random leaf of BSP tree.
581                @param onlyUnmailed if only unmailed leaves should be returned.
582        */
583        BvhLeaf *GetRandomLeaf(const bool onlyUnmailed = false);
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               
594        /** Sets pointer to view cells manager.
595        */
596        void SetViewCellsManager(ViewCellsManager *vcm);
597
598        /** Writes tree to output stream
599        */
600        bool Export(OUT_STREAM &stream);
601
602        /** Collects rays associated with the objects.
603        */
604        void CollectRays(const ObjectContainer &objects, VssRayContainer &rays) const;
605
606        /** Intersects box with the tree and returns the number of intersected boxes.
607                @returns number of view cells found
608        */
609        int ComputeBoxIntersections(const AxisAlignedBox3 &box,
610                                                                ViewCellContainer &viewCells) const;
611
612        /** Returns leaf the point pt lies in, starting from root.
613        */
614        BvhLeaf *GetLeaf(Intersectable *obj, BvhNode *root = NULL) const;
615
616        /** Sets a pointer to the view cells tree.
617        */
618        ViewCellsTree *GetViewCellsTree() const { return mViewCellsTree; }
619       
620        /** See Get
621        */
622        void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
623
624        /** Returns estimated memory usage of tree.
625        */
626        float GetMemUsage() const;
627
628        /** Sets this node to be an active node.
629        */
630        void SetActive(BvhNode *node) const;
631
632
633        ///////////////////////////
634        // hacks in order to provide interleaved heurisitcs
635
636        BvhNode *SubdivideAndCopy(SplitQueue &tQueue, SubdivisionCandidate *splitCandidate);
637
638        /////////////////////////////////
639
640        static float EvalAbsCost(const ObjectContainer &objects);
641
642        void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
643
644protected:
645
646        /** Returns true if tree can be terminated.
647        */
648        bool LocalTerminationCriteriaMet(const BvhTraversalData &data) const;
649
650        /** Returns true if global tree can be terminated.
651        */
652        bool GlobalTerminationCriteriaMet(const BvhTraversalData &data) const;
653
654        /** For sorting the objects during the heuristics
655        */
656        struct SortableEntry
657        {
658                Intersectable *mObject;
659                float mPos;
660
661                SortableEntry() {}
662
663                SortableEntry(Intersectable *obj, const float pos):
664                mObject(obj), mPos(pos)
665                {}
666
667                bool operator<(const SortableEntry &b) const
668                {
669                        return mPos < b.mPos;
670                }
671        };
672
673        /** Evaluate balanced object partition.
674        */
675        float EvalLocalObjectPartition(const BvhTraversalData &tData,
676                                                                   const int axis,
677                                                                   ObjectContainer &objectsFront,
678                                                                   ObjectContainer &objectsBack);
679
680        /** Evaluate surface area heuristic for the node.
681        */
682        float EvalSah(const BvhTraversalData &tData,
683                                  const int axis,
684                                  ObjectContainer &objectsFront,
685                                  ObjectContainer &objectsBack);
686
687
688        /** Evaluates render cost of the bv induced by these objects
689        */
690        float EvalRenderCost(const ObjectContainer &objects) const;
691
692        /** Evaluates tree stats in the BSP tree leafs.
693        */
694        void EvaluateLeafStats(const BvhTraversalData &data);
695
696        /** Subdivides node using a best split priority queue.
697            @param tQueue the best split priority queue
698                @param splitCandidate the candidate for the next split
699                @param globalCriteriaMet if the global termination criteria were already met
700                @returns new root of the subtree
701        */
702        BvhNode *Subdivide(SplitQueue &tQueue,
703                                           SubdivisionCandidate *splitCandidate,
704                                           const bool globalCriteriaMet);
705       
706        /** Subdivides leaf.
707                @param sc the subdivisionCandidate holding all necessary data for subdivision           
708               
709                @param frontData returns the traversal data for the front node
710                @param backData returns the traversal data for the back node
711
712                @returns the new interior node = the of the subdivision
713        */
714        BvhInterior *SubdivideNode(const BvhSubdivisionCandidate &sc,
715                                                           BvhTraversalData &frontData,
716                                                           BvhTraversalData &backData);
717
718        /** Splits the objects for the next subdivision.
719                @returns cost for this split
720        */
721        float SelectObjectPartition(const BvhTraversalData &tData,
722                                                                ObjectContainer &frontObjects,
723                                                                ObjectContainer &backObjects,
724                                                                bool useVisibilityBasedHeuristics);
725       
726        /** Writes the node to disk
727                @note: should be implemented as visitor.
728        */
729        void ExportNode(BvhNode *node, OUT_STREAM &stream);
730
731        /** Exports objects associated with this leaf.
732        */
733        void ExportObjects(BvhLeaf *leaf, OUT_STREAM &stream);
734
735        /** Associates the objects with their bvh leaves.
736        */
737        static void AssociateObjectsWithLeaf(BvhLeaf *leaf);
738
739
740        /////////////////////////////
741        // Helper functions for local cost heuristics
742       
743        /** Prepare split candidates for cost heuristics using axis aligned splits.
744                @param node the current node
745                @param axis the current split axis
746        */
747        void PrepareLocalSubdivisionCandidates(const BvhTraversalData &tData,
748                                                                                   const int axis);
749
750        static void CreateLocalSubdivisionCandidates(const ObjectContainer &objects,
751                                                                                                 SortableEntryContainer **subdivisionCandidates,
752                                                                                                 const bool sort,
753                                                                                                 const int axis);
754
755        float EvalPriority(const BvhSubdivisionCandidate &splitCandidate,
756                                           const float renderCostDecr,
757                                           const float oldRenderCost) const;
758
759        /** Computes object partition with the best cost according to the heurisics.
760                @param tData the traversal data
761                @param axis the split axis
762                @param objectsFront the objects in the front child bv
763                @param objectsBack the objects in the back child bv
764                @param backObjectsStart the iterator marking the position where the back objects begin
765
766                @returns relative cost (relative to parent cost)
767        */
768        float EvalLocalCostHeuristics(const BvhTraversalData &tData,
769                                                                  const int axis,
770                                                                  ObjectContainer &objectsFront,
771                                                                  ObjectContainer &objectsBack);
772
773        /** Evaluates the contribution to the front and back volume
774                when this object is changing sides in the bvs.
775
776                @param object the object
777                @param volLeft updates the left pvs
778                @param volPvs updates the right pvs
779        */
780        void EvalHeuristicsContribution(Intersectable *obj,
781                                                                        float &volLeft,
782                                                                        float &volRight);
783
784        /** Prepares objects for the cost heuristics.
785                @returns sum of volume of associated view cells
786        */
787        float PrepareHeuristics(const BvhTraversalData &tData, const int axis);
788       
789        /** Evaluates cost for a leaf given the surface area heuristics.
790        */
791        float EvalSahCost(BvhLeaf *leaf) const;
792
793        ////////////////////////////////////////////////
794
795
796        /** Prepares construction for vsp and osp trees.
797        */
798        AxisAlignedBox3 EvalBoundingBox(const ObjectContainer &objects,
799                                                                        const AxisAlignedBox3 *parentBox = NULL) const;
800
801        /** Collects list of invalid candidates. Candidates
802                are invalidated by a view space subdivision step
803                that affects this candidate.
804        */
805        void CollectDirtyCandidates(BvhSubdivisionCandidate *sc,
806                                                                vector<SubdivisionCandidate *> &dirtyList,
807                                                                const bool onlyUnmailed);
808
809        /** Collect view cells which see this bvh leaf.
810        */
811        int CollectViewCells(const ObjectContainer &objects,
812                                                 ViewCellContainer &viewCells,
813                                                 const bool setCounter,
814                                                 const bool onlyUnmailedRays) const;
815
816        /** Counts the view cells of this object. note: only
817                counts unmailed objects.
818        */
819        int CountViewCells(Intersectable *obj) const;
820
821        /** Counts the view cells seen by this bvh leaf
822        */
823        int CountViewCells(const ObjectContainer &objects) const;
824
825        /** Collects view cells which see an object.
826        */
827        int CollectViewCells(Intersectable *object,
828                                                 ViewCellContainer &viewCells,
829                                                 const bool useMailBoxing,
830                                                 const bool setCounter,
831                                                 const bool onlyUnmailedRays) const;
832
833        /** Evaluates increase in pvs size.
834        */
835        int EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate) const;
836
837        /** Rays will be clipped to the bounding box.
838        */
839        void PreprocessRays(BvhLeaf *root,
840                                                const VssRayContainer &sampleRays,
841                                                RayInfoContainer &rays);
842
843        /** Print the subdivision stats in the subdivison log.
844        */
845        void PrintSubdivisionStats(const SubdivisionCandidate &tData);
846
847        /** Prints out the stats for this subdivision.
848        */
849        void AddSubdivisionStats(const int viewCells,
850                                                         const float renderCostDecr,
851                                                         const float totalRenderCost);
852
853        /** Stores rays with objects that see the rays.
854        */
855        int AssociateObjectsWithRays(const VssRayContainer &rays) const;
856
857        /** Tests if object is in this leaf.
858                @note: assumes that objects are sorted by their id.
859        */
860        bool IsObjectInLeaf(BvhLeaf *, Intersectable *object) const;
861
862        /** Prepares the construction of the bv hierarchy and returns
863                the first subdivision candidate.
864        */
865        void PrepareConstruction(SplitQueue &tQueue,
866                                                         const VssRayContainer &sampleRays,
867                                                         const ObjectContainer &objects);
868
869        /** Resets bv hierarchy. E.g. deletes root and resets stats.
870        */
871        void Reset(SplitQueue &tQueue,
872                           const VssRayContainer &rays,
873                           const ObjectContainer &objects);
874
875        /** Evaluates volume of view cells that see the objects.
876        */
877        float EvalViewCellsVolume(const ObjectContainer &objects) const;
878
879        /** Assigns or newly creates initial list of sorted objects.
880        */
881        void AssignInitialSortedObjectList(BvhTraversalData &tData,
882                                                                           const ObjectContainer &objects);
883
884        /** Assigns sorted objects to front and back data.
885        */
886        void AssignSortedObjects(const BvhSubdivisionCandidate &sc,
887                                                         BvhTraversalData &frontData,
888                                                         BvhTraversalData &backData);
889       
890        /** Creates new root of hierarchy and computes bounding box.
891                Has to be called before the preparation of the subdivision.
892        */
893        void Initialise(const ObjectContainer &objects);
894
895
896        ////////////////////
897        // initial subdivision
898
899        /** Makes an initial parititon of the object space based on
900                some criteria (size, shader)
901        */
902        void ApplyInitialSubdivision(SubdivisionCandidate *firstCandidate,
903                                                                 SplitQueue &tQueue);
904
905        void ApplyInititialSplit(const BvhTraversalData &tData,
906                                                         ObjectContainer &frontObjects,
907                                                         ObjectContainer &backObjects);
908
909        bool InitialTerminationCriteriaMet(const BvhTraversalData &tData) const;
910
911        float mMinInitialSurfaceArea;
912        int mInititialObjectsSize;
913
914protected:
915       
916        /// pre-sorted subdivision candidtes for all three directions.
917        vector<SortableEntry> *mGlobalSubdivisionCandidates[3];
918        /// pointer to the hierarchy of view cells
919        ViewCellsTree *mViewCellsTree;
920        /// The view cells manager
921        ViewCellsManager *mViewCellsManager;
922        /// candidates for placing split planes during cost heuristics
923        vector<SortableEntry> *mSubdivisionCandidates;
924        /// Pointer to the root of the tree
925        BvhNode *mRoot;
926        /// Statistics for the object space partition
927        BvhStatistics mBvhStats;       
928        /// box around the whole view domain
929        AxisAlignedBox3 mBoundingBox;
930        /// the hierarchy manager
931        HierarchyManager *mHierarchyManager;
932
933
934        ////////////////////
935        //-- local termination criteria
936
937        /// maximal possible depth
938        int mTermMaxDepth;
939        /// mininum probability
940        float mTermMinProbability;
941        /// minimal number of objects
942        int mTermMinObjects;
943        /// maximal acceptable cost ratio
944        float mTermMaxCostRatio;
945        /// tolerance value indicating how often the max cost ratio can be failed
946        int mTermMissTolerance;
947        /// minimum number of rays
948        int mTermMinRays;
949
950
951        ////////////////////
952        //-- global termination criteria
953
954        /// the minimal accepted global cost ratio
955        float mTermMinGlobalCostRatio;
956        //// number of accepted misses of the global cost ratio
957        int mTermGlobalCostMissTolerance;
958        /// maximal number of view cells
959        int mTermMaxLeaves;
960        /// maximal tree memory
961        float mMaxMemory;
962        /// the tree is out of memory
963        bool mOutOfMemory;
964
965
966        ////////////////////////////////////////
967        //-- split heuristics based parameters
968       
969        /// if a heuristics should be used for finding a split plane
970    bool mUseCostHeuristics;
971        /// if sah heuristcs should be used for finding a split plane
972        bool mUseSah;
973    /// balancing factor for PVS criterium
974        float mCtDivCi;
975        /// if only driving axis should be used for split
976        bool mOnlyDrivingAxis;
977        /// current time stamp (used for keeping split history)
978        int mTimeStamp;
979        // if rays should be stored in leaves
980        bool mStoreRays;
981        // subdivision stats output file
982        ofstream  mSubdivisionStats;
983        /// keeps track of cost during subdivision
984        float mTotalCost;
985        int mPvsEntries;
986        /// keeps track of overall pvs size during subdivision
987        int mTotalPvsSize;
988        /// number of currenly generated view cells
989        int mCreatedLeaves;
990        /// represents min and max band for sweep
991        float mSplitBorder;
992        /// weight between render cost decrease and node render cost
993        float mRenderCostDecreaseWeight;
994
995        /// if the objects should be sorted in one global step
996        bool mUseGlobalSorting;
997
998        bool mUseBboxAreaForSah;
999
1000        //SortableEntryContainer *mSortedObjects[4];
1001
1002        int mMinRaysForVisibility;
1003
1004        /// constant value for driving the heuristics
1005        float mMemoryConst;
1006
1007        bool mIsInitialSubdivision;
1008
1009        bool mApplyInitialPartition;
1010
1011        int mMaxTests;
1012};
1013
1014}
1015
1016#endif
Note: See TracBrowser for help on using the repository browser.