source: GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h @ 2753

Revision 2753, 13.7 KB checked in by mattausch, 16 years ago (diff)
Line 
1// This file has been written by Jiri Bittner, October 2006
2
3#ifndef __BVH_H
4#define __BVH_H
5
6#include "Geometry.h"
7//#include "FlexibleHeap.h"
8
9
10namespace CHCDemo
11{
12
13////////
14// Forward declarations
15
16class SceneGeometry;
17class Camera;
18
19
20/** A node in the bv hierarchy.
21*/
22class BvhNode
23{
24        friend class Bvh;
25
26public:
27
28        /** visibility related options
29        */
30        struct VisibilityInfo
31        {
32                VisibilityInfo() { Reset(); }           
33                /** Reset the visibility info.
34                */
35                void Reset();
36
37                /// if the node is visible
38                bool mIsVisible;
39                /// #frames this node is assumed to stay visible
40                int mAssumedVisibleFrames;
41                /// the frame when this node was last touched during traversal
42                int mLastVisitedFrame;
43                /// #times this node was invisible (only valid if the node actually is invisible)
44                int mTimesInvisible;
45                /// if the node is view frustum culled
46                bool mIsFrustumCulled;
47                /// if the node is newly processed with no prior history available
48                bool mIsNew;
49        };
50
51        /** Constructor taking the parent node.
52        */
53        BvhNode(BvhNode *parent);
54       
55        /** Returns true if this node is a leaf.
56        */
57        //virtual bool IsPseudoLeaf() = 0;
58        /** Virtual destructor doing nothing.
59        */
60        virtual ~BvhNode();
61        /** Returns unique id for this node.
62        */
63        //inline int GetId() {return mId;}
64        /** Depth of this node in the tree.
65        */
66        inline int GetDepth() const {return mDepth;}
67        /** Returns parent of this bvh node, NULL if it is root.
68        */
69        inline BvhNode *GetParent() {return mParent;}
70        /** Number of leaves in the subtree induced by this node.
71        */
72        inline int GetNumLeaves() const {return mNumLeaves;}
73        /** Reset the status of this node.
74        */
75        virtual void ResetVisibility();
76
77        virtual int GetType() = 0; //{ return BVH_NODE; }
78
79
80        /////////////////////
81        //-- visibility culling related functions
82
83        inline int GetLastVisitedFrame() const;
84
85        inline void SetLastVisitedFrame(const int lastVisited);
86        /** If this node is considered visible.
87        */
88        inline bool IsVisible() const;
89        /** Set visibility flag of the node.
90        */
91        inline void SetVisible(const bool visible);
92        /** The assumed visible time span of this node.
93        */
94        inline void SetAssumedVisibleFrames(const int t);
95        /** See set.
96        */
97        inline int GetAssumedVisibleFrames() const;
98        /** The time span this node remains visible.
99        */
100        inline void SetRemainingVisibleFrames(const int t);
101        /** Decrease the time this node is considered visible.
102        */
103        inline void DecAssumedVisibleFrames();
104        /** Increases the #times this node was
105                successfully tested invisible.
106        */
107        inline void IncTimesInvisible();
108       
109        inline int GetTimesInvisible() const;
110        inline void SetTimesInvisible(const int t);
111       
112        inline int GetTurnedVisibleFrame() const;
113        inline void SetTurnedVisibleFrame(const int turnedVisibleFrame);
114
115        inline int GetLastTestedFrame();
116        inline void SetLastTestedFrame(const int lastTested);
117       
118        inline bool IsViewFrustumCulled() const;
119        inline void SetViewFrustumCulled(const bool frustumCulled);
120
121        inline bool IsNew() const;
122        inline void SetIsNew(const bool isNew);
123
124
125        //////////
126        //-- rendering
127       
128        /** Returns the frame in which this node was last rendered.
129        */
130        inline int GetLastRenderedFrame() const;
131        /** See get.
132        */
133        inline void SetLastRenderedFrame(int lastRenderedFrame);
134        /** Does this node contain renderable geometry?
135        */
136        inline bool Empty() const;
137        /** Counts #geometry stored in the subtree.
138        */
139        inline int CountPrimitives() const;
140
141
142protected:
143
144        /////////////
145       
146        /// some flags
147        int mFlags;
148        /// the depth of this node
149        unsigned char mDepth;
150        /// the split axis
151        char mAxis;
152        /// the parent node
153        BvhNode *mParent;
154        /// stores the visibility related parameters
155        VisibilityInfo mVisibility;
156
157        /////////
158        // used for view frustum culling
159
160        int mPlaneMask;
161        int mPreferredPlane;
162
163
164        ////////////
165        //-- rendering related options
166       
167        /// when the node was last rendered
168        int mLastRenderedFrame;
169        /// #leaves under this node
170        int mNumLeaves;
171       
172        // Indices to first and last triangle in the triangle array
173        // assumes the triangle are placed in continuous chunk of memory
174        // however this need not be a global array!
175       
176        /// the index of the first triangle
177        int mFirst;
178        /// the index of the last triangle
179        int mLast;
180
181        /// these nodes can be tested instead of the current node
182        int mTestNodesIdx;
183        int mNumTestNodes;
184        int mIndicesPtr;
185        /// Area of this node
186        float mArea;
187};
188
189
190/////////////////
191//-- public inline functions
192
193int BvhNode::GetLastVisitedFrame() const
194{
195        return mVisibility.mLastVisitedFrame;
196}
197
198
199void BvhNode::SetLastVisitedFrame(const int lastVisited)
200{
201        mVisibility.mLastVisitedFrame = lastVisited;
202}
203
204
205bool BvhNode::IsVisible() const
206{
207        return mVisibility.mIsVisible;
208}
209
210
211void BvhNode::SetVisible(const bool visible)
212{
213        mVisibility.mIsVisible = visible;
214}
215
216
217void BvhNode::IncTimesInvisible()
218{
219        ++ mVisibility.mTimesInvisible;
220}
221
222
223int BvhNode::GetTimesInvisible() const
224{
225        return mVisibility.mTimesInvisible;
226}
227
228
229void BvhNode::SetTimesInvisible(const int t)
230{
231        mVisibility.mTimesInvisible = t;
232}
233
234
235bool BvhNode::IsViewFrustumCulled() const
236{
237        return mVisibility.mIsFrustumCulled;
238}
239
240
241void BvhNode::SetViewFrustumCulled(const bool frustumCulled)
242{
243        mVisibility.mIsFrustumCulled = frustumCulled;
244}
245
246
247bool BvhNode::IsNew() const
248{
249        return mVisibility.mIsNew;
250}
251
252
253void BvhNode::SetIsNew(const bool isNew)
254{
255        mVisibility.mIsNew = isNew;
256}
257
258
259int BvhNode::GetLastRenderedFrame() const
260{
261        return mLastRenderedFrame;
262}
263       
264
265void BvhNode::SetLastRenderedFrame(int lastRenderedFrame)
266{
267        mLastRenderedFrame = lastRenderedFrame;
268}
269       
270       
271bool BvhNode::Empty() const
272{
273        return mFirst == -1;
274}
275
276
277int BvhNode::CountPrimitives() const
278{
279        return mLast - mFirst + 1;
280}
281
282
283void BvhNode::SetAssumedVisibleFrames(const int t)
284{
285        mVisibility.mAssumedVisibleFrames = t;
286}
287
288
289int BvhNode::GetAssumedVisibleFrames() const
290{
291        return mVisibility.mAssumedVisibleFrames;
292}
293
294void BvhNode::DecAssumedVisibleFrames()
295{
296        -- mVisibility.mAssumedVisibleFrames;
297}
298
299
300/** Internal node of the bv hierarchy.
301*/
302class BvhInterior: public BvhNode
303{
304friend class Bvh;
305
306public:
307        BvhInterior(BvhNode *parent): mBack(NULL), mFront(NULL), BvhNode(parent)
308        {}
309        virtual bool IsLeaf() {return false;}
310        /** Back child.
311        */
312        inline BvhNode *GetBack() { return mBack;}
313        /** Front child.
314        */
315        inline BvhNode *GetFront() { return mFront;}
316        /** recursivly delete tree.
317        */
318        virtual ~BvhInterior() { if (mBack) delete mBack; if (mFront) delete mFront;}
319        /** Returns split axis of this interior node.
320        */
321        inline int GetAxis() {return (int)mAxis;}
322        /** Returns position of the split axis.
323        */
324        inline float GetPosition() {return (float)mPosition;}
325
326
327protected:
328
329        /// the position of the split plane
330        float mPosition;
331       
332        BvhNode *mBack;
333        BvhNode *mFront;
334};
335
336
337class BvhLeaf: public BvhNode
338{
339friend class Bvh;
340
341public:
342
343        BvhLeaf(BvhNode *parent): BvhNode(parent)
344        {}
345
346        ~BvhLeaf();
347
348        virtual bool IsLeaf() { return true; }
349};
350
351
352/** Class representing a bounding volume hierarchy.
353*/
354class Bvh
355{
356        /** Bvh properties
357        */
358        struct BvhStats
359        {
360                BvhStats():
361                mInteriorSA(0),
362                mLeafSA(0),
363                mInteriorVol(0),
364                mLeafVol(0),
365                mBoundsInteriorSA(0),
366                mBoundsLeafSA(0),
367                mBoundsInteriorVol(0),
368                mBoundsLeafVol(0),
369                mBoundsLeavesCount(0),
370                mTriangles(0),
371                mTriangleRatio(0),
372                mGeometryRatio(0),
373                mMaxGeometry(0),
374                mMaxTriangles(0)
375                {}
376               
377                float mInteriorSA;
378                float mLeafSA;
379                float mInteriorVol;
380                float mLeafVol;
381                float mBoundsInteriorSA;
382                float mBoundsLeafSA;
383                float mBoundsInteriorVol;
384                float mBoundsLeafVol;
385                int mBoundsLeavesCount;
386                int mTriangles;
387
388                float mTriangleRatio;
389                float mGeometryRatio;
390
391                int mMaxGeometry;
392                int mMaxTriangles;
393        };
394
395public:
396
397        /** Returns number of bvh nodes.
398        */
399        inline int GetNumNodes() const {return mNumNodes;}
400        /** Returns number of bvh leaves.
401        */
402        inline int GetNumLeaves() const {return mNumNodes / 2 + 1;}
403        /** Constructs the bounding volume hierarchy.
404        */
405        void Construct();
406        /** Returns root node of the bvh.
407        */
408        BvhNode *GetRoot() {return mRoot;}
409        /** Counts the triangle in this leaf.
410        */
411        int CountTriangles(BvhLeaf *leaf) const;
412
413
414        //////////////////////
415
416        /** Returns geometry by reference (faster).
417        */
418        SceneGeometry **GetGeometry(BvhNode *node, int &size);
419
420
421        /////////////
422        //-- Rendering related options
423
424        /** Renders the bounding box of this node (Or the tigher bounding boxes of some subnodes).
425        */
426        void RenderBoundingBox(BvhNode *node);
427        /** Renders bounding boxes of the collection of nodes.
428                @returns #rendered boxes
429        */
430        int RenderBoundingBoxes(const BvhNodeContainer &nodes);
431
432
433
434        //////////////
435        //-- Traversal related options
436
437        /** Pulls up visible classification.
438        */
439        void MakeParentsVisible(BvhNode *node);
440        /** Does the view frustum culling for this node with respect to the previous culls
441                @returns: 0 if completely outside, 1 if completely inside, -1 if intersecting (partly inside),
442        */
443        int     IsWithinViewFrustum(BvhNode *node);
444        /** sets frame dependent values.
445        */
446        void InitFrame(Camera *camera, const int currentFrameId);
447        /** this gives the orthogonal distance from the viewpoint to the nearest bounding box vertex
448                note that negative values can appear because culling is done only afterwards
449        */
450        float CalcDistance(BvhNode *node) const;
451        /** Sets maximal depth for taking the bounding boxes to test the
452                visibility of a node. The deeper the more the box fits to the geometry.
453        */
454        void SetMaxDepthForTestingChildren(const int maxDepth);
455        /** Pulls up the fully visible classification in the bvh.
456        */
457        void UpdateFullVisibility(BvhNode *node) const;
458        /** Pulls up the last visited classification in the bvh.
459        */
460        void PullUpLastVisited(BvhNode *node, const int frameId) const;
461        /** Resets the node classifications in the tree.
462        */
463        void ResetNodeClassifications();
464        /** Helper function that renders the bounding boxes of the leaves as
465                wireframes for visualization purpose.
466        */
467        void RenderBoundingBoxesForViz(const int mode);
468        /** Returns squared min distance to the view point.
469        */
470        float GetSquareDistance(BvhNode *node) const;
471        /** Count triangles the node contains.
472        */
473        int CountTriangles(BvhNode *node) const;
474        /** Returns area of the geometry contained in the node.
475        */
476        float GetGeometryArea(BvhNode *node) const;
477
478
479        ////////////
480        //-- functions that change the boundaries of the nodes
481
482        void SetUseTighterBoundsForTests(bool tighterBoundsForTests);
483
484        void SetAreaRatioThresholdForTestingChildren(const float ratio);
485
486
487        const BvhStats &GetBvhStats() const {return mBvhStats;}
488
489        void SetCollectTighterBoundsWithMaxLevel(bool t);
490
491
492        //////////////
493
494        static unsigned int sCurrentVboId;
495       
496
497protected:
498
499        /** Small struct representing a frustum.
500        */
501        struct Frustum
502        {
503                /// the 6 clip planes
504                float mClipPlane[6][4];
505        };
506       
507
508
509        ////////////////////
510
511        /** Constructor loading the bvh from disc
512        */
513        Bvh(const std::string &filename);
514        /** protected constructor: do nothing.
515        */
516        //Bvh(): mCamera(NULL), mFrameId(-1), mVertices(NULL), mRenderer(NULL) {}
517        /** Destructor.
518        */
519        ~Bvh();
520
521
522        /////////////
523
524        void ComputeBvhStats();
525        void PrintBvhStats() const;
526
527
528        //////////
529        //-- Helper methods for bounding box rendering in immediate and vbo mode.
530       
531        void PrepareVertices();
532
533        int PrepareBoundingBoxesWithDrawArrays(const BvhNodeContainer &nodes);
534        void RenderBoundingBoxesWithDrawArrays(int numNodes);
535
536        int RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes);
537        /** Renders a bounding box in immediate mode using index restart
538                and restarts the strip only if wished.
539        */
540        void RenderBoundingBoxImmediate(const AxisAlignedBox3 &box, bool restartStrip);
541        /** Create the indices that each node needs to use vbo rendering.
542        */
543        void CreateIndices();
544        /** Create the list of nodes whose bounding boxes are tested instead of the
545                bounding box of the node itself.
546        */
547        bool CreateNodeRenderList(BvhNode *node);
548        /** Recursivly updates indices so we can
549                render also interior nodes without traversing hierarchy
550        */
551        void UpdateInteriors(BvhNode *node);
552        /** Recomputes the boundaries of the nodes. This function is always called if
553                some boundary options are changed.
554        */
555        void RecomputeBounds();
556        /** Does some postprocessing on the leaves.
557                @returns #leaves that were chosen for tighter bounds.
558        */
559        int PostProcessLeaves(BvhLeafContainer &leaves);
560
561
562        int     IsWithinViewFrustumLocal(BvhNode *node);
563
564        int     IsWithinViewFrustum(const AxisAlignedBox3 &box, int planeMask, int preferredPlane);
565       
566        float GetMinSquareDistance(const AxisAlignedBox3 &box) const;
567       
568       
569        ////////////////////////
570
571        /// the root of the hierarchy
572        BvhNode *mRoot;
573        /// pointers to the geometry associated with this node
574        SceneGeometry **mGeometry;
575        /// #of entities
576        size_t mGeometrySize;
577
578
579        ////////////////
580
581
582        /// these values are valid for all nodes
583        char mClipPlaneAABBVertexIndices[6][2];
584        /// the current view frustum
585        Frustum mFrustum;
586        /// the current camera
587        Camera *mCamera;
588        // current frame id
589        int mFrameId;
590        /// a vertex array used if working with indexed arrays (without vbo)
591        //Point3f *mVertices;
592        /// indices used for draw array rendering
593        unsigned int *mIndices;
594
595        /** maximal depth from which children are fetched for
596                testing instead of the current node
597        */
598        int mMaxDepthForTestingChildren;
599
600        float mAreaRatioThreshold;
601        float mVolRatioThreshold;
602
603        BvhStats mBvhStats;
604
605        //HierarchyNodeContainer mTestNodes;
606       
607        unsigned int *mTestIndices;
608        /// a pointer to the end of the indices array
609        int mCurrentIndicesPtr;
610
611        float mScale;
612
613        Vector3 mNearPlane;
614        float mNearPlaneD;
615        int mNumNodes;
616};
617
618}
619
620#endif // __BVH_H
Note: See TracBrowser for help on using the repository browser.