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

Revision 2539, 32.1 KB checked in by mattausch, 17 years ago (diff)

fixed obj loading error

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