BVH.h

Go to the documentation of this file.
00001 /* $Id: BVH.h,v 1.12 2002/11/20 15:22:15 cvs Exp $ */
00002 
00003 #ifndef __BOUNDING_VOLUME_HIERARCHY_H
00004 #define __BOUNDING_VOLUME_HIERARCHY_H
00005 
00006 #include <esg/SceneGraphObject.h>
00007 #include <esg/spacesorting/SDS.h>
00008 #include <esg/spacesorting/DistRot.h>
00009 #include <esg/geometry/Geometry.h>
00010 #include <esg/geometry/BVList.h>
00011 #include <esg/SceneGraphObject.h>
00012 //#include <esg/metric/Metric.h>
00013 
00014 namespace esg {
00015 
00037 class OGSCENE_EXPORT BVH : public SDS {
00038         friend class IteratorBVH;
00039         friend class InspectorBVH;
00040         friend class BVDistance;
00041         friend class BVExplorer;
00042   
00043 public:
00044         struct Node {
00045                 Geometry*  bv;         
00046                 BVList*    list;       
00047                 Node*      leftChild;  
00048                 Node*      rightChild; 
00049                 Node*      parent;     
00050                 Node*      sibling;    
00051                 bool       leaf;       
00052                 
00053                 Node() {
00054                     leftChild = (rightChild = (parent = (sibling = NULL)));
00055                     bv   = NULL;
00056                     list = NULL;
00057                 }
00058         };
00059 
00060 protected:
00061         struct DRInfo {
00062                 double      minD;     
00063                 BVH::Node * pLeafA;   
00064                 BVH::Node * pLeafB;
00065                 Vector3   * pDir;     
00066                 DistRot   * pDistRot; 
00067 
00068                 unsigned    myMaxDepth;
00069                 unsigned    hisMaxDepth;
00070                 unsigned    maxDepth; 
00071         
00072         /* In the case we reached a leaf of the tree we can use only the leaf
00073          * and don't pass any argument for it. Following fields are used only
00074          * in this case: */
00075                 bool        leafInMe; 
00076                 BVH::Node * pLeaf;    
00077                 enum Strategy {
00078                     POINT_COLLISION,
00079                     SEPARATION,
00080                     DISTANCE
00081                 }           strategy;
00082         } _drInfo;
00083 
00084 protected:        
00085         bool      _append       (SceneGraphObject*,Geometry*, Node*, unsigned);
00086         void      _remove_leaf  (Node*);
00087         void      _build_tree   (Node*, unsigned);
00088         void      _destroy_tree (Node*);
00089         void      _rebuild_tree (Node*);
00090         Geometry* _create_bv    (BVList&);
00091         void      _collision    (Node*, Geometry&, List<SceneGraphObject>*);
00092         void      _dump         (const Node*, const char*, const char*);
00093     
00094         virtual DistRot* _create_dist_rot (BVH::Node*);
00095         virtual void     _dr_init         (const Matrix4*,const Matrix4*,BVH*);
00096         virtual void     _dr_primitives   (DRInfo&, Node*, Vector3*);
00097         virtual void     _dr_leaf         (DRInfo&, Node*, unsigned);
00098         virtual void     _dr_inner        (DRInfo&, Node*, Node*, unsigned);
00099     
00100         virtual bool      _enlarge_bv  (Geometry**, Geometry&)   = 0;
00101         virtual Geometry* _create_bv   (List<SceneGraphObject>&) = 0;
00102         virtual Geometry* _create_bv   (Geometry&, Geometry&)    = 0;
00103         virtual Geometry* _create_bv   (SceneGraphObject&)       = 0;
00104         virtual BVList*   _create_list ()                        = 0;
00105  
00106         virtual void _duplicate_attributes (const SDS&);
00107 
00108         //void _bv_distance (Node*, Metric&) const;
00109     
00110         BVH () {
00111             _root       = (_leftLeaf = NULL);
00112             _leafLimit  = 1;
00113             _depthLimit = 0;
00114             _scaleRatio = 1.0;
00115         }
00116 
00117 protected:
00118         Node*     _root;
00119         Node*     _leftLeaf;
00120         unsigned  _leafLimit;
00121         unsigned  _depthLimit;
00122         unsigned  _treeDepth;
00123         
00124         Matrix4 _myTrMat;
00125         Matrix4 _coordMat;   
00126         double  _scaleRatio; 
00127         BVH   * _pPartner;   
00128 
00129         BVList::SplitStrategy _splitStrategy;
00130         
00131 public:
00132         BVH (unsigned              /* leaf limit                 */,
00133              unsigned              /* depth limit                */,
00134              bool                  /* delay creation             */,
00135              BVList::SplitStrategy /* strategy of space division */);
00136     
00137     virtual ~BVH();
00138     
00139     virtual SDS*          clone           () const = 0;
00140     virtual Iterator*     createIterator  ();
00141     virtual InspectorSDS* createInspector (unsigned);
00142 
00143     // Add new object to tree. When tree is full, that is the
00144     // leaf limit and depth limit are over, then ignore leaf limit.
00145     virtual int               append (SceneGraphObject*);
00146     virtual SceneGraphObject* detach (SceneGraphObject::OID);
00147 
00148     // Update inner structure. Typically when some stored object
00149     // has been moved.
00150     virtual bool update (void);
00151 
00152     // Build inner structure. Some space sub-division structures
00153     // may prefer its real creation until they know most of storing objects.
00154     // This method must be called after all objects are appended when
00155     // delayBuild is set to true in constructor
00156     virtual bool build (void);
00157 
00158     unsigned leafLimit  (void) const { return _leafLimit;  }
00159     unsigned depthLimit (void) const { return _depthLimit; }
00160 
00161     /*
00162      * Find such two nodes, my and partner's, that are closest to each
00163      * other, put them into *ppMinA and *ppMinB and return their distance.
00164      * Returned distance is distance of bouding volumes, not stored
00165      * objects themselves!
00166      *
00167      * Parameters ppMinA and ppMinB should be either NULL or they should
00168      * points to closest leaves from previous pass.
00169      * In the second case, better optimization is used.
00170      *
00171      * Acually the only supported transformations are those don't
00172      * deforming objects, i.e. rotation, translation and single value scale.
00173      *
00174      * d1 and d2 are maximal depths for collision detection traversal.
00175      * If they are reached sooner then leaves then detection ends
00176      * (hierarchies behave like having depth d1 and d2 respectively).
00177      */
00178     virtual double distance (Matrix4* /* my tr. matrix                     */,
00179                              BVH&     /* tested hierarchy                  */,
00180                              Matrix4* /* its tr. matrix                    */,
00181                              Node**   /* my best leaf from prev. pass      */,
00182                              Node**   /* partner's  -"-                    */,
00183                              Vector3* pDir=NULL/* approx. dir. of distance */,
00184                              unsigned d1  =UINT_MAX /* my max. depth       */,
00185                              unsigned d2  =UINT_MAX /* partner's max depth */);
00186 
00187     /*
00188      * Output separation diraction is valid only for objects that are
00189      * penetrated and represents the approximately shortest way to
00190      * get the colliding leaves separated. Therefore this is not the
00191      * shortest way to get separated the whole complex object stored
00192      * in the hierarchy!
00193      *
00194      * d1 and d2 are maximal depths for collision detection traversal.
00195      * If they are reached sooner then leaves then detection ends
00196      * (hierarchies behave like having depth d1 and d2 respectively).
00197      */
00198     virtual bool separation (Matrix4* /* my tr. matrix                     */,
00199                              BVH&     /* tested hierarchy                  */,
00200                              Matrix4* /* its tr. matrix                    */,
00201                              Vector3* pDir=NULL/* approx. dir. of distance */,
00202                              unsigned d1  =UINT_MAX /* my max. depth       */,
00203                              unsigned d2  =UINT_MAX /* partner's max depth */);
00204 
00205     /*
00206      * Collision detection with 3D point.
00207      * It returns geometries of all leaf objects penetrating
00208      * a sphere that surrounds given point.
00209      */
00210     virtual Geometry** collision (Matrix4*            /* my tr.. matrix */,
00211                                   float, float, float /* 3D point */,
00212                                   float               /* rasius */,
00213                                   int*                /* # of returned obj.*/);
00214 
00215 //    virtual void acceptMetric (Metric& metric) { metric.visitBVH(this); }
00216 
00217     // Dump the tree structure into (opened) file
00218     virtual void dump (const char* /* intent */, const char* /* tab */);
00219 
00220     
00221 
00222     
00223     // For debugging purposes only:
00224     virtual void __debug (void);
00225     virtual void __debug (Node* n, int d);
00226 
00227     // rot == 0 => zadna rotace
00228     // rot == 1 => rotace pomoci pMyTr
00229     // rot == 2 => rotace pomoci _pCoordMat
00230     void   __get_edges(Matrix4 *,Node*,unsigned,unsigned,int,float*,unsigned&);
00231     float* __getEdges (Matrix4 * pMyTr,unsigned level,int rot,unsigned& size);
00232 
00233     void  __get_meshes(Matrix4 *,Node*,unsigned,unsigned,int,Mesh**,unsigned&);
00234     Mesh**__getMeshes (Matrix4 * pMyTr,unsigned level,int rot,unsigned& size);
00235 };
00236 
00237 }; // namespace
00238 
00239 #endif // __BOUNDING_VOLUME_HIERARCHY_H

Generated on Wed Jun 28 12:24:28 2006 for esg by  doxygen 1.4.6