Ignore:
Timestamp:
11/14/05 11:12:38 (19 years ago)
Author:
mattausch
Message:
 
File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h

    r406 r408  
    1 #ifndef _ViewCellKdTree_H__ 
    2 #define _ViewCellKdTree_H__ 
    3  
     1// ================================================================ 
     2// $Id$ 
     3// **************************************************************** 
     4//  
     5// Initial coding by 
     6/** 
     7   @author Jiri Bittner 
     8*/ 
     9 
     10#ifndef __VSPKDTREE_H__ 
     11#define __VSPKDTREE_H__ 
     12 
     13// Standard headers 
     14#include <iomanip> 
     15#include <vector> 
    416#include <functional> 
    5 using namespace std; 
    6  
    7 #include "Containers.h" 
     17#include <stack> 
     18 
     19 
     20// User headers 
     21#include "VssRay.h" 
    822#include "AxisAlignedBox3.h" 
     23 
     24 
     25#define USE_KDNODE_VECTORS 1 
     26#define _RSS_STATISTICS 
     27#define _RSS_TRAVERSAL_STATISTICS 
     28 
     29 
     30#include "Statistics.h" 
    931#include "Ray.h" 
    10 #include "Pvs.h" 
    11  
    12    
    13 class ViewCellKdNode; 
    14 class ViewCellKdLeaf; 
    15 class ViewCellKdInterior; 
    16 class Intersectable; 
    17  
    1832 
    1933// -------------------------------------------------------------- 
    2034// Static statistics for kd-tree search 
    2135// -------------------------------------------------------------- 
    22 class ViewCellKdTreeStatistics  
     36class VspKdStatistics:  public StatisticsBase 
    2337{ 
    2438public:   
     
    2943  // totals number of rays 
    3044  int rays; 
    31   // total number of query domains 
     45        // initial size of the pvs 
     46  int initialPvsSize; 
     47        // total number of query domains 
    3248  int queryDomains; 
    3349  // total number of ray references 
    3450  int rayRefs; 
    35   // refs in non empty leafs 
    36   int rayRefsNonZeroQuery; 
    37   // total number of query references 
    38   int objectRefs; 
    39   // nodes with zero queries 
    40   int zeroQueryNodes; 
    41   // max depth nodes 
     51 
     52        // max depth nodes 
    4253  int maxDepthNodes; 
    4354  // max depth nodes 
    44   int minCostNodes; 
     55  int minPvsNodes; 
     56  int minRaysNodes; 
     57        // max ray contribution nodes 
     58  int maxRayContribNodes; 
     59        // max depth nodes 
     60  int minSizeNodes; 
     61         
    4562  // max number of rays per node 
    46   int maxObjectRefs; 
     63  int maxRayRefs; 
    4764  // number of dynamically added ray refs 
    4865  int addedRayRefs; 
     
    5168   
    5269  // Constructor 
    53   ViewCellKdTreeStatistics() { 
     70  VspKdStatistics() { 
    5471    Reset(); 
    5572  } 
     
    6481      splits[i] = 0; 
    6582    rays = queryDomains = 0; 
    66     rayRefs = rayRefsNonZeroQuery = objectRefs = 0; 
    67     zeroQueryNodes = 0; 
     83    rayRefs = 0; 
    6884    maxDepthNodes = 0; 
    69     minCostNodes = 0; 
    70     maxObjectRefs = 0; 
     85    minPvsNodes = 0; 
     86    minRaysNodes = 0; 
     87    maxRayRefs = 0; 
    7188    addedRayRefs = removedRayRefs = 0; 
    72   } 
    73  
     89                initialPvsSize = 0; 
     90                maxRayContribNodes = 0; 
     91                minSizeNodes = 0; 
     92  } 
     93 
     94   
    7495  void 
    7596  Print(ostream &app) const; 
    7697 
    77   friend ostream &operator<<(ostream &s, const ViewCellKdTreeStatistics &stat) { 
     98  friend ostream &operator<<(ostream &s, const VspKdStatistics &stat) { 
    7899    stat.Print(s); 
    79100    return s; 
     
    82103}; 
    83104 
    84    
    85 class ViewCellKdInterior; 
    86 /** Abstract class for kd-tree node */ 
    87 class ViewCellKdNode { 
     105 
     106// -------------------------------------------------------------- 
     107// For sorting rays 
     108// -------------------------------------------------------------- 
     109struct  SortableEntry 
     110{ 
     111  enum EType { 
     112    ERayMin, 
     113    ERayMax 
     114  }; 
     115 
     116  int type; 
     117  float value; 
     118  void *data; 
     119   
     120  SortableEntry() {} 
     121  SortableEntry(const int t, const float v, void *d):type(t), 
     122                                                                                                                                                                                                                 value(v), 
     123                                                                                                                                                                                                                 data(d) {} 
     124         
     125  friend bool operator<(const SortableEntry &a, const SortableEntry &b) { 
     126    return a.value < b.value; 
     127  } 
     128}; 
     129 
     130 
     131class VspKdTreeInterior; 
     132 
     133 
     134// -------------------------------------------------------------- 
     135// KD-tree node - abstract class 
     136// -------------------------------------------------------------- 
     137class VspKdTreeNode 
     138{ 
     139public: 
     140 
     141#define USE_FIXEDPOINT_T 1 
     142 
     143struct RayInfo 
     144{ 
     145        // pointer to the actual ray 
     146        VssRay *mRay; 
     147         
     148        // endpoints  - do we need them? 
     149#if USE_FIXEDPOINT_T 
     150        short mMinT, mMaxT; 
     151#else 
     152        float mMinT, mMaxT; 
     153#endif 
     154         
     155        RayInfo():mRay(NULL) {} 
     156         
     157        RayInfo(VssRay *r):mRay(r), mMinT(0), 
     158#if USE_FIXEDPOINT_T 
     159#define FIXEDPOINT_ONE 0x7FFE 
     160                                                                                                //                        mMaxT(0xFFFF) 
     161                                                                                                                                                        mMaxT(FIXEDPOINT_ONE) 
     162#else 
     163                mMaxT(1.0f) 
     164#endif 
     165        {} 
     166         
     167        RayInfo(VssRay *r, 
     168                                                                                const float _min, 
     169                                                                                const float _max 
     170                                                                                ):mRay(r) { 
     171                SetMinT(_min); 
     172                SetMaxT(_max); 
     173        } 
     174         
     175        RayInfo(VssRay *r, 
     176                                                                                const short _min, 
     177                                                                                const float _max 
     178                                                                                ):mRay(r), mMinT(_min) { 
     179                SetMaxT(_max); 
     180        } 
     181         
     182        RayInfo(VssRay *r, 
     183                                                                                const float _min, 
     184                                                                                const short _max 
     185                                                                                ):mRay(r), mMaxT(_max) { 
     186                SetMinT(_min); 
     187        } 
     188         
     189        friend bool operator<(const RayInfo &a, const RayInfo &b) { 
     190                return a.mRay < b.mRay; 
     191        } 
     192   
     193         
     194        float ExtrapOrigin(const int axis) const { 
     195                return mRay->GetOrigin(axis) + GetMinT()*mRay->GetDir(axis); 
     196        } 
     197         
     198        float ExtrapTermination(const int axis) const { 
     199                return mRay->GetOrigin(axis) + GetMaxT()*mRay->GetDir(axis); 
     200        } 
     201         
     202#if USE_FIXEDPOINT_T 
     203        float GetMinT () const { return mMinT/(float)(FIXEDPOINT_ONE); } 
     204        float GetMaxT () const { return mMaxT/(float)(FIXEDPOINT_ONE); } 
     205         
     206        void SetMinT (const float t) { 
     207                mMinT = (short) (t*(float)(FIXEDPOINT_ONE)); 
     208        } 
     209         
     210        void SetMaxT (const float t) { 
     211                mMaxT = (short) (t*(float)(FIXEDPOINT_ONE)); 
     212                mMaxT++; 
     213                //      if (mMaxT!=0xFFFF) 
     214                //      mMaxT++; 
     215        } 
     216#else 
     217        float GetMinT () const { return mMinT; } 
     218        float GetMaxT () const { return mMaxT; } 
     219         
     220        void SetMinT (const float t) { mMinT = t; } 
     221        void SetMaxT (const float t) { mMaxT = t; } 
     222#endif  
     223 
     224 
     225  int ComputeRayIntersection(const float axis, 
     226                                                                                                                 const float position, 
     227                                                                                                                 float &t 
     228                                                                                                                 ) const { 
     229                 
     230                // intersect the ray with the plane 
     231    float denom = mRay->GetDir(axis); 
     232     
     233    if (fabs(denom) < 1e-20) 
     234      //if (denom == 0.0f) 
     235      return (mRay->GetOrigin(axis) > position) ? 1 : -1; 
     236     
     237    t = (position - mRay->GetOrigin(axis))/denom; 
     238 
     239    if (t < GetMinT()) 
     240      return (denom > 0) ? 1 : -1; 
     241 
     242    if (t > GetMaxT()) 
     243      return (denom > 0) ? -1 : 1; 
     244 
     245                return 0; 
     246        } 
     247 
     248 
     249}; 
     250 
     251 
     252        typedef vector<RayInfo> RayInfoContainer; 
     253         
     254  enum { EInterior, ELeaf }; 
     255 
     256  ///////////////////////////////// 
     257  // The actual data goes here 
     258   
     259  // link to the parent 
     260  VspKdTreeInterior *parent; 
     261 
     262  enum {SPLIT_X=0, SPLIT_Y, SPLIT_Z, SPLIT_DIRX, SPLIT_DIRY, SPLIT_DIRZ}; 
     263   
     264  // splitting axis 
     265  char axis; 
     266         
     267  // depth 
     268  unsigned char depth; 
     269   
     270  //  short depth; 
     271  // 
     272  ///////////////////////////////// 
     273   
     274  inline VspKdTreeNode(VspKdTreeInterior *p); 
     275 
     276   
     277  virtual ~VspKdTreeNode() {}; 
     278  virtual int Type() const  = 0; 
     279   
     280 
     281  bool IsLeaf() const { return axis == -1; } 
     282   
     283  virtual void Print(ostream &s) const = 0; 
     284 
     285  virtual int GetAccessTime() { 
     286    return 0x7FFFFFF; 
     287  } 
     288 
     289   
     290         
     291}; 
     292 
     293// -------------------------------------------------------------- 
     294// KD-tree node - interior node 
     295// -------------------------------------------------------------- 
     296class VspKdTreeInterior : 
     297  public VspKdTreeNode 
     298{ 
     299public: 
     300  // plane in local modelling coordinates 
     301  float position; 
     302 
     303  // pointers to children 
     304  VspKdTreeNode *back, *front; 
     305 
     306  // the bbox of the node 
     307  AxisAlignedBox3 bbox; 
     308 
     309  // the bbox of the node 
     310  AxisAlignedBox3 dirBBox; 
     311   
     312  // data for caching 
     313  long accesses; 
     314  long lastAccessTime; 
     315   
     316  VspKdTreeInterior(VspKdTreeInterior *p):VspKdTreeNode(p), 
     317                                        back(NULL), 
     318                                        front(NULL), 
     319                                        accesses(0), 
     320                                        lastAccessTime(-1) 
     321  { } 
     322 
     323  virtual int GetAccessTime() { 
     324    return lastAccessTime; 
     325  } 
     326 
     327  void SetupChildLinks(VspKdTreeNode *b, VspKdTreeNode *f) { 
     328    back = b; 
     329    front = f; 
     330    b->parent = f->parent = this; 
     331  } 
     332 
     333  void ReplaceChildLink(VspKdTreeNode *oldChild, VspKdTreeNode *newChild) { 
     334    if (back == oldChild) 
     335      back = newChild; 
     336    else 
     337      front = newChild; 
     338  } 
     339 
     340  virtual int Type() const  { return EInterior; } 
     341   
     342  virtual ~VspKdTreeInterior() { 
     343    if (back) 
     344      delete back; 
     345    if (front) 
     346      delete front; 
     347  } 
     348   
     349  virtual void Print(ostream &s) const { 
     350    if (axis == 0) 
     351      s<<"x "; 
     352    else 
     353      if (axis == 1) 
     354        s<<"y "; 
     355      else 
     356        s<<"z "; 
     357    s<<position<<" "; 
     358    back->Print(s); 
     359    front->Print(s); 
     360  } 
     361 
     362   
     363         
     364  int ComputeRayIntersection(const RayInfo &rayData, 
     365                                                                                                                 float &t 
     366                                                                                                                 ) { 
     367                return rayData.ComputeRayIntersection(axis, position, t); 
     368  } 
     369 
     370}; 
     371 
     372 
     373// -------------------------------------------------------------- 
     374// KD-tree node - leaf node 
     375// -------------------------------------------------------------- 
     376class VspKdTreeLeaf : 
     377  public VspKdTreeNode 
     378{ 
     379private: 
     380        int mPvsSize; 
    88381public: 
    89382  static int mailID; 
    90383  int mailbox; 
    91384   
     385  RayInfoContainer rays; 
     386        bool mValidPvs; 
     387         
     388  VspKdTreeLeaf(VspKdTreeInterior *p, 
     389                                                        const int nRays 
     390                                                        ):VspKdTreeNode(p), rays(), mPvsSize(0), mValidPvs(false) { 
     391    rays.reserve(nRays); 
     392  } 
     393   
     394  virtual ~VspKdTreeLeaf() { } 
     395 
     396  virtual int Type() const  { return ELeaf; } 
     397 
     398  virtual void Print(ostream &s) const { 
     399    s<<endl<<"L: r="<<rays.size()<<endl; 
     400  }; 
     401   
     402  void AddRay(const RayInfo &data) { 
     403                mValidPvs = false; 
     404    rays.push_back(data); 
     405    data.mRay->Ref(); 
     406  } 
     407         
     408        int GetPvsSize() const { 
     409                return mPvsSize; 
     410        } 
     411        void SetPvsSize(const int s) { 
     412                mPvsSize = s; 
     413        } 
     414 
     415        void 
     416        UpdatePvsSize(); 
     417 
    92418  void Mail() { mailbox = mailID; } 
    93419  static void NewMail() { mailID++; } 
    94420  bool Mailed() const { return mailbox == mailID; } 
    95  
    96  
    97   ViewCellKdNode(ViewCellKdInterior *parent); 
    98  
    99   /** Determines whether this node is a leaf or interior node 
    100       @return true if leaf 
    101   */ 
    102   virtual bool IsLeaf() const = 0; 
    103  
    104   /** Determines whether this node is the root of the tree 
    105       @return true if root 
    106   */ 
    107   virtual bool IsRoot() const { 
    108     return mParent == NULL; 
    109   } 
    110  
    111   /** Parent of the node - the parent is a little overhead for maintanance of the tree, 
    112       but allows various optimizations of tree traversal algorithms */ 
    113   ViewCellKdInterior *mParent; 
    114   int mDepth; 
     421   
     422  bool Mailed(const int mail) { 
     423    return mailbox >= mailID + mail; 
     424  } 
     425 
     426        float GetAvgRayContribution() const { 
     427                return GetPvsSize()/((float)rays.size() + Limits::Small); 
     428        } 
     429 
     430        float GetSqrRayContribution() const { 
     431                return sqr(GetPvsSize()/((float)rays.size() + Limits::Small)); 
     432        } 
     433 
    115434}; 
    116435 
    117 /** Implementation of the kd-tree interior node */ 
    118 class ViewCellKdInterior : public ViewCellKdNode { 
    119  
    120 public: 
    121      
    122   ViewCellKdInterior(ViewCellKdInterior *parent):ViewCellKdNode(parent), mBack(NULL), mFront(NULL) {} 
    123  
    124   /** \sa ViewCellKdNode::IsLeaf() */ 
    125   virtual bool IsLeaf() const { return false; } 
    126  
    127   /** splitting axis */ 
    128   int mAxis; 
    129   /** splitting position, absolute position within the bounding box of this node */ 
    130   float mPosition; 
    131   /** bounding box of interior node */ 
    132   AxisAlignedBox3 mBox; 
    133  
    134   /** back node */ 
    135   ViewCellKdNode *mBack; 
    136   /** front node */ 
    137   ViewCellKdNode *mFront; 
    138  
    139   void SetupChildLinks(ViewCellKdNode *b, ViewCellKdNode *f) { 
    140     mBack = b; 
    141     mFront = f; 
    142     b->mParent = f->mParent = this; 
    143   } 
    144    
    145   void ReplaceChildLink(ViewCellKdNode *oldChild, ViewCellKdNode *newChild) { 
    146     if (mBack == oldChild) 
    147       mBack = newChild; 
    148     else 
    149       mFront = newChild; 
    150   } 
    151    
    152    
    153 }; 
    154    
    155    
    156 /** Implementation of the kd-tree leaf node */ 
    157 class ViewCellKdLeaf : public ViewCellKdNode { 
    158 public: 
    159   ViewCellKdLeaf(ViewCellKdInterior *parent, const int objects):ViewCellKdNode(parent) { 
    160     mObjects.reserve(objects); 
    161   } 
    162    
    163   void AddPassingRay(const Ray &ray, 
    164                                                                                  const int contributions) { 
    165     mPassingRays.AddRay(ray, contributions); 
    166                 //              Debug << "adding passing ray" << endl; 
    167   } 
    168  
    169          
    170         void AddPassingRay2(const Ray &ray, 
    171                                                                                         const int objects, 
    172                                                                                         const int viewcells 
    173                                                                                         ) { 
    174     mPassingRays.AddRay2(ray, objects, viewcells); 
    175                 //              Debug << "adding passing ray" << endl; 
    176   } 
    177  
    178   /** \sa ViewCellKdNode::IsLeaf() */ 
    179   virtual bool IsLeaf() const { return true; } 
    180    
    181  
    182    
    183  
    184   /** pointers to occluders contained in this node */ 
    185   ObjectContainer mObjects; 
    186    
    187   /** pointers to viewcells contained in this node */ 
    188   //  ViewCellContainer mViewCells; 
    189  
    190   /** Ray set description of the rays passing through this node */ 
    191   PassingRaySet mPassingRays; 
    192          
    193   /** PVS consisting of visible ViewCellKd nodes */ 
    194   ViewCellKdPvs mKdPvs; 
    195          
    196         /** PVS consisting of visible objects */ 
    197   ViewCellPvs mPvs; 
    198 }; 
    199  
    200    
    201  
    202 /** ViewCellKd for indexing scene entities - occluders/occludees/viewcells */ 
    203 class ViewCellKd { 
    204  
    205 protected: 
     436// Inline functions 
     437inline 
     438VspKdTreeNode::VspKdTreeNode(VspKdTreeInterior *p): 
     439  parent(p), axis(-1), depth(p ? p->depth + 1 : 0) {} 
     440 
     441 
     442 
     443// --------------------------------------------------------------- 
     444// Main LSDS search class 
     445// --------------------------------------------------------------- 
     446class VspKdTree 
     447{ 
    206448  struct TraversalData 
    207449  {   
    208     ViewCellKdNode *mNode; 
    209     AxisAlignedBox3 mBox; 
    210     int mDepth; 
    211     float mPriority; 
     450    VspKdTreeNode *node; 
     451    AxisAlignedBox3 bbox; 
     452    int depth; 
     453    float priority; 
    212454     
    213455    TraversalData() {} 
    214456 
    215     TraversalData(ViewCellKdNode *n, const float p): 
    216       mNode(n), mPriority(p) 
     457    TraversalData(VspKdTreeNode *n, const float p): 
     458      node(n), priority(p) 
    217459    {} 
    218      
    219     TraversalData(ViewCellKdNode *n, 
     460 
     461    TraversalData(VspKdTreeNode *n, 
    220462                   const AxisAlignedBox3 &b, 
    221463                   const int d): 
    222       mNode(n), mBox(b), mDepth(d) {} 
     464      node(n), bbox(b), depth(d) {} 
    223465     
    224  
    225     bool operator<( 
    226                    const TraversalData &b) const { 
    227       ViewCellKdLeaf *leafa = (ViewCellKdLeaf *) mNode; 
    228       ViewCellKdLeaf *leafb = (ViewCellKdLeaf *) b.mNode; 
    229       return  
    230         leafa->mObjects.size()*mBox.SurfaceArea() 
    231         < 
    232         leafb->mObjects.size()*b.mBox.SurfaceArea(); 
    233     } 
    234  
    235  
     466                 
    236467    // comparator for the  
    237468    struct less_priority : public 
    238469    binary_function<const TraversalData, const TraversalData, bool> { 
    239        
     470                         
    240471      bool operator()(const TraversalData a, const TraversalData b) { 
    241                                 return a.mPriority < b.mPriority; 
     472                                return a.priority < b.priority; 
    242473      } 
    243474       
    244475    }; 
    245476 
     477    //    ~TraversalData() {} 
     478    //    TraversalData(const TraversalData &s):node(s.node), bbox(s.bbox), depth(s.depth) {} 
     479     
     480    friend bool operator<(const TraversalData &a, 
     481                                                                                                        const TraversalData &b) { 
     482      //      return a.node->queries.size() < b.node->queries.size(); 
     483      VspKdTreeLeaf *leafa = (VspKdTreeLeaf *) a.node; 
     484      VspKdTreeLeaf *leafb = (VspKdTreeLeaf *) b.node; 
     485#if 0 
     486                        return 
     487                                leafa->rays.size()*a.bbox.GetVolume() 
     488                                < 
     489                                leafb->rays.size()*b.bbox.GetVolume(); 
     490#endif 
     491#if 1 
     492                        return 
     493                                leafa->GetPvsSize()*a.bbox.GetVolume() 
     494                                < 
     495                                leafb->GetPvsSize()*b.bbox.GetVolume(); 
     496#endif 
     497#if 0 
     498                        return 
     499                                leafa->GetPvsSize() 
     500                                < 
     501                                leafb->GetPvsSize(); 
     502#endif 
     503#if 0 
     504                        return 
     505                                leafa->GetPvsSize()/(leafa->rays.size()+1) 
     506                                > 
     507                                leafb->GetPvsSize()/(leafb->rays.size()+1); 
     508#endif 
     509#if 0 
     510                        return 
     511                                leafa->GetPvsSize()*leafa->rays.size() 
     512                                < 
     513                                leafb->GetPvsSize()*leafb->rays.size(); 
     514#endif 
     515    } 
    246516  }; 
    247  
    248    
    249  
    250 public: 
    251  
    252   enum {SPLIT_OBJECT_MEDIAN, 
    253         SPLIT_SPATIAL_MEDIAN, 
    254         SPLIT_SAH}; 
    255    
    256   ViewCellKd(); 
    257    
     517   
     518  // simplified data for ray traversal only... 
     519 
     520  struct RayTraversalData { 
    258521     
    259   /** Insert view cell into the tree */ 
    260   virtual void InsertViewCell(ViewCell *viewCell) { 
    261     //      mRoot->mViewcells.push_back(viewCell); 
    262   } 
    263  
    264   virtual bool Construct(); 
    265  
    266   /** Check whether subdivision criteria are met for the given subtree. 
    267       If not subdivide the leafs of the subtree. The criteria are specified in 
    268       the environment as well as the subdivision method. By default surface area 
    269       heuristics is used. 
    270          
    271       @param subtree root of the subtree 
    272  
    273       @return true if subdivision was performed, false if subdivision criteria 
    274       were already met 
    275   */ 
    276   virtual ViewCellKdNode *Subdivide(const TraversalData &tdata); 
    277  
    278   /** Get the root of the tree */ 
    279   ViewCellKdNode *GetRoot() const { 
    280     return mRoot; 
    281   } 
    282  
    283  
    284   AxisAlignedBox3 GetBox() const { return mBox; } 
    285  
    286   int 
    287   CastRay( 
    288           Ray &ray 
    289           ); 
    290  
    291   const ViewCellKdTreeStatistics &GetStatistics() const { 
    292     return mStat; 
    293   } 
    294  
    295   void 
    296   CollectObjects(ViewCellKdNode *n, ObjectContainer &objects); 
    297          
    298   void 
    299   CollectLeaves(vector<ViewCellKdLeaf *> &leaves); 
    300          
    301   AxisAlignedBox3 GetBox(const ViewCellKdNode *node) const { 
    302     ViewCellKdInterior *parent = node->mParent; 
    303     if (parent == NULL) 
    304       return mBox; 
    305      
    306     if (!node->IsLeaf()) 
    307       return ((ViewCellKdInterior *)node)->mBox; 
    308      
    309     AxisAlignedBox3 box(parent->mBox); 
    310     if (parent->mFront == node) 
    311       box.SetMin(parent->mAxis, parent->mPosition); 
    312     else 
    313       box.SetMax(parent->mAxis, parent->mPosition); 
    314     return box; 
    315   } 
    316          
    317   ViewCellKdNode * 
    318   FindRandomNeighbor(ViewCellKdNode *n, 
    319                                                                                  bool onlyUnmailed 
    320                                                                                  ); 
    321    
    322   ViewCellKdNode * 
    323   ViewCellKd::GetRandomLeaf(const Plane3 &halfspace); 
    324  
    325         ViewCellKdNode * 
    326         GetRandomLeaf(const bool onlyUnmailed = false); 
    327  
    328   int 
    329   FindNeighbors(ViewCellKdNode *n, 
    330                 vector<ViewCellKdNode *> &neighbors, 
    331                 bool onlyUnmailed 
    332                 ); 
    333  
    334   int 
    335   CollectLeafPvs(); 
    336  
    337 protected: 
    338  
    339   struct RayData { 
    340     // pointer to the actual ray 
    341     Ray *ray; 
    342      
    343     // endpoints  - do we need them? 
    344 #if USE_FIXEDPOINT_T 
    345     short tmin, tmax; 
    346 #else 
    347     float tmin, tmax; 
    348 #endif 
    349  
    350     RayData():ray(NULL) {} 
    351     RayData(Ray *r):ray(r), tmin(0), 
    352  
    353 #if USE_FIXEDPOINT_T 
    354 #define FIXEDPOINT_ONE 0x7FFE 
    355                           //                      tmax(0xFFFF) 
    356                           tmax(FIXEDPOINT_ONE) 
    357 #else 
    358       tmax(1.0f) 
    359 #endif 
    360     {} 
    361  
    362     RayData(Ray *r, 
    363             const float _min, 
    364             const float _max 
    365             ):ray(r) { 
    366       SetTMin(_min); 
    367       SetTMax(_max); 
    368     } 
    369  
    370     RayData(Ray *r, 
    371             const short _min, 
    372             const float _max 
    373             ):ray(r), tmin(_min) { 
    374       SetTMax(_max); 
    375     } 
    376  
    377     RayData(Ray *r, 
    378             const float _min, 
    379             const short _max 
    380             ):ray(r), tmax(_max) { 
    381       SetTMin(_min); 
    382     } 
    383  
    384     friend bool operator<(const RayData &a, const RayData &b) { 
    385       return a.ray < b.ray; 
    386     } 
    387      
    388      
    389     float ExtrapOrigin(const int axis) const { 
    390       return ray->GetLoc(axis) + GetTMin()*ray->GetDir(axis); 
    391     } 
    392      
    393     float ExtrapTermination(const int axis) const { 
    394       return ray->GetLoc(axis) + GetTMax()*ray->GetDir(axis); 
    395     } 
    396      
    397 #if USE_FIXEDPOINT_T 
    398     float GetTMin () const { return tmin/(float)(FIXEDPOINT_ONE); } 
    399     float GetTMax () const { return tmax/(float)(FIXEDPOINT_ONE); } 
    400  
    401     void SetTMin (const float t) { 
    402       tmin = (short) (t*(float)(FIXEDPOINT_ONE)); 
    403     } 
    404      
    405     void SetTMax (const float t) { 
    406       tmax = (short) (t*(float)(FIXEDPOINT_ONE)); 
    407       tmax++; 
    408       //      if (tmax!=0xFFFF) 
    409       //        tmax++; 
    410     } 
    411 #else 
    412     float GetTMin () const { return tmin; } 
    413     float GetTMax () const { return tmax; } 
    414  
    415     void SetTMin (const float t) { tmin = t; } 
    416     void SetTMax (const float t) { tmax = t; } 
    417 #endif  
    418   }; 
    419  
    420   struct RayTraversalData { 
    421     ViewCellKdNode *mNode; 
    422     Vector3 mExitPoint; 
    423     float mMaxT; 
     522    VspKdTreeNode::RayInfo rayData; 
     523    VspKdTreeNode *node; 
    424524     
    425525    RayTraversalData() {} 
    426     RayTraversalData(ViewCellKdNode *n, 
    427                      const Vector3 &p, 
    428                      const float maxt): 
    429       mNode(n), mExitPoint(p), mMaxT(maxt) {} 
     526    RayTraversalData(VspKdTreeNode *n, 
     527                                                                                 const VspKdTreeNode::RayInfo &data): 
     528      rayData(data), node(n) {} 
    430529  }; 
    431  
    432   // -------------------------------------------------------------- 
    433   // For sorting objects 
    434   // -------------------------------------------------------------- 
    435   struct  SortableEntry 
    436   { 
    437     enum { 
    438       BOX_MIN, 
    439       BOX_MAX 
    440     }; 
    441      
    442     int type; 
    443     float value; 
    444     Intersectable *intersectable; 
    445      
    446     SortableEntry() {} 
    447     SortableEntry(const int t, const float v, Intersectable *i):type(t), 
    448                                                                 value(v), 
    449                                                                 intersectable(i) {} 
    450      
    451     bool operator<(const SortableEntry &b) const { 
    452       return value < b.value; 
    453     } 
    454      
    455   }; 
     530         
     531public: 
     532  ///////////////////////////// 
     533  // The core pointer 
     534  VspKdTreeNode *root; 
     535   
     536  ///////////////////////////// 
     537  // Basic properties 
     538 
     539  // total number of nodes of the tree 
     540  int nodes; 
     541  // axis aligned bounding box of the scene 
     542  AxisAlignedBox3 bbox; 
     543 
     544  // axis aligned bounding box of directions 
     545  AxisAlignedBox3 dirBBox; 
     546   
     547  ///////////////////////////// 
     548  // Construction parameters 
     549 
     550  // epsilon used for the construction 
     551  float epsilon; 
     552 
     553  // ratio between traversal and intersection costs 
     554  float ct_div_ci; 
     555  // max depth of the tree 
     556  int termMaxDepth; 
     557  // minimal ratio of the volume of the cell and the query volume 
     558  float termMinSize; 
     559 
     560        // minimal pvs per node to still get subdivided 
     561  int termMinPvs; 
     562 
     563        // minimal ray number per node to still get subdivided 
     564  int termMinRays; 
     565         
     566  // maximal cost ration to subdivide a node 
     567  float termMaxCostRatio; 
     568         
     569        // maximal contribution per ray to subdivide the node 
     570        float termMaxRayContribution; 
     571 
     572         
     573  // randomized construction 
     574  bool randomize; 
     575 
     576  // type of the splitting to use fo rthe tree construction 
     577  enum {ESplitRegular, ESplitHeuristic }; 
     578  int splitType; 
     579         
     580  // maximal size of the box on which the refdir splitting can be performed 
     581  // (relative to the scene bbox 
     582  float refDirBoxMaxSize; 
     583   
     584  // maximum alovable memory in MB 
     585  float maxTotalMemory; 
     586 
     587  // maximum alovable memory for static kd tree in MB 
     588  float maxStaticMemory; 
     589 
     590  // this is used during the construction depending 
     591  // on the type of the tree and queries... 
     592  float maxMemory; 
     593 
     594 
     595  // minimal acess time for collapse 
     596  int accessTimeThreshold; 
     597 
     598        // minimal depth at which to perform collapse 
     599  int minCollapseDepth; 
     600 
    456601   
    457602  // reusable array of split candidates 
    458603  vector<SortableEntry> *splitCandidates; 
    459  
    460   float 
    461   BestCostRatio( 
    462                 ViewCellKdLeaf *node, 
    463                 const AxisAlignedBox3 &box, 
    464                 const int axis, 
    465                 float &position, 
    466                 int &objectsBack, 
    467                 int &objectsFront 
    468                 ); 
     604  ///////////////////////////// 
     605 
     606  VspKdStatistics stat; 
     607         
     608   
     609  VspKdTree(); 
     610  virtual ~VspKdTree(); 
     611 
     612  virtual void 
     613  Construct( 
     614                                                VssRayContainer &rays, 
     615                                                AxisAlignedBox3 *forcedBoundingBox = NULL 
     616                                                ); 
     617         
     618  // incemental construction 
     619  virtual void UpdateRays(VssRayContainer &remove, 
     620                                                                                                        VssRayContainer &add 
     621                                                                                                        ); 
     622 
     623        virtual void AddRays( 
     624                                                                                         VssRayContainer &add 
     625                                                                                         ) 
     626        { 
     627                VssRayContainer remove; 
     628                UpdateRays(remove, add); 
     629        } 
     630 
     631   
     632         
     633  VspKdTreeNode * 
     634  Locate(const Vector3 &v); 
     635         
     636  VspKdTreeNode * 
     637  SubdivideNode(VspKdTreeLeaf *leaf, 
     638                                                                const AxisAlignedBox3 &box, 
     639                                                                AxisAlignedBox3 &backBox, 
     640                                                                AxisAlignedBox3 &frontBox 
     641                                                                ); 
     642         
     643  VspKdTreeNode * 
     644  Subdivide(const TraversalData &tdata); 
     645         
     646  int 
     647  SelectPlane(VspKdTreeLeaf *leaf, 
     648                                                        const AxisAlignedBox3 &box, 
     649                                                        float &position, 
     650                                                        int &raysBack, 
     651                                                        int &raysFront, 
     652                                                        int &pvsBack, 
     653                                                        int &pvsFront 
     654                                                        ); 
    469655 
    470656  void 
    471657  SortSplitCandidates( 
    472                       ViewCellKdLeaf *node, 
    473                       const int axis 
    474                       ); 
     658                                                                                        VspKdTreeLeaf *node, 
     659                                                                                        const int axis 
     660                                                                                        ); 
     661         
     662   
     663  // return memory usage in MB 
     664  float GetMemUsage() const { 
     665    return  
     666      (sizeof(VspKdTree) + 
     667       stat.Leaves()*sizeof(VspKdTreeLeaf) + 
     668       stat.Interior()*sizeof(VspKdTreeInterior) + 
     669       stat.rayRefs*sizeof(VspKdTreeNode::RayInfo))/(1024.0f*1024.0f); 
     670  } 
     671         
     672  float GetRayMemUsage() const { 
     673    return  
     674      stat.rays*(sizeof(VssRay))/(1024.0f*1024.0f); 
     675  } 
     676   
     677        float 
     678        BestCostRatioHeuristic( 
     679                                                                                                 VspKdTreeLeaf *node, 
     680                                                                                                 int &axis, 
     681                                                                                                 float &position, 
     682                                                                                                 int &raysBack, 
     683                                                                                                 int &raysFront, 
     684                                                                                                 int &pvsBack, 
     685                                                                                                 int &pvsFront 
     686                                                                                                 ); 
     687 
     688        float 
     689        BestCostRatioRegular( 
     690                                                                                         VspKdTreeLeaf *node, 
     691                                                                                         int &axis, 
     692                                                                                         float &position, 
     693                                                                                         int &raysBack, 
     694                                                                                         int &raysFront, 
     695                                                                                         int &pvsBack, 
     696                                                                                         int &pvsFront 
     697 
     698                                                                                         ); 
     699         
     700        float 
     701        EvalCostRatio( 
     702                                                                VspKdTreeLeaf *node, 
     703                                                                const int axis, 
     704                                                                const float position, 
     705                                                                int &raysBack, 
     706                                                                int &raysFront, 
     707                                                                int &pvsBack, 
     708                                                                int &pvsFront 
     709                                                                ); 
     710 
     711  AxisAlignedBox3 GetBBox(const VspKdTreeNode *node) { 
     712    if (node->parent == NULL) 
     713      return bbox; 
     714 
     715    if (!node->IsLeaf()) 
     716      return ((VspKdTreeInterior *)node)->bbox; 
     717 
     718    if (node->parent->axis >= 3) 
     719      return node->parent->bbox; 
     720       
     721    AxisAlignedBox3 box(node->parent->bbox); 
     722    if (node->parent->front == node) 
     723      box.SetMin(node->parent->axis, node->parent->position); 
     724    else 
     725      box.SetMax(node->parent->axis, node->parent->position); 
     726    return box; 
     727  } 
     728 
     729  AxisAlignedBox3 GetDirBBox(const VspKdTreeNode *node) { 
     730 
     731    if (node->parent == NULL) 
     732      return dirBBox; 
     733     
     734    if (!node->IsLeaf() ) 
     735      return ((VspKdTreeInterior *)node)->dirBBox; 
     736 
     737    if (node->parent->axis < 3) 
     738      return node->parent->dirBBox; 
     739     
     740    AxisAlignedBox3 dBBox(node->parent->dirBBox); 
     741 
     742    if (node->parent->front == node) 
     743      dBBox.SetMin(node->parent->axis - 3, node->parent->position); 
     744    else 
     745      dBBox.SetMax(node->parent->axis - 3, node->parent->position); 
     746    return dBBox; 
     747  } 
     748   
     749  int 
     750  ReleaseMemory(const int time); 
     751 
     752  int 
     753  CollapseSubtree(VspKdTreeNode *node, const int time); 
    475754 
    476755  void 
     756  CountAccess(VspKdTreeInterior *node, const long time) { 
     757    node->accesses++; 
     758    node->lastAccessTime = time; 
     759  } 
     760 
     761  VspKdTreeNode * 
     762  SubdivideLeaf( 
     763                                                                VspKdTreeLeaf *leaf, 
     764                                                                const float SAThreshold 
     765                                                                ); 
     766 
     767  void 
     768  RemoveRay(VssRay *ray, 
     769                                                vector<VspKdTreeLeaf *> *affectedLeaves, 
     770                                                const bool removeAllScheduledRays 
     771                                                ); 
     772 
     773  void 
     774  AddRay(VssRay *ray); 
     775         
     776  void 
     777  TraverseInternalNode( 
     778                                                                                         RayTraversalData &data, 
     779                                                                                         stack<RayTraversalData> &tstack); 
     780 
     781        void 
    477782  EvaluateLeafStats(const TraversalData &data); 
    478783 
    479   ViewCellKdNode * 
    480   SubdivideNode( 
    481                 ViewCellKdLeaf *leaf, 
    482                 const AxisAlignedBox3 &box, 
    483                 AxisAlignedBox3 &backBBox, 
    484                 AxisAlignedBox3 &frontBBox 
    485                 ); 
    486  
    487   bool 
    488   TerminationCriteriaMet(const ViewCellKdLeaf *leaf); 
    489    
    490   int 
    491   SelectPlane(ViewCellKdLeaf *leaf, 
    492               const AxisAlignedBox3 &box, 
    493               float &position 
    494               ); 
    495  
    496  
    497  
    498   float mSplitBorder; 
    499   int mTermMaxDepth; 
    500   int mTermMinCost; 
    501   float mMaxCostRatio; 
    502   float mCt_div_ci; 
    503   int mSplitMethod; 
    504   bool mSahUseFaces; 
    505   /// root of the tree 
    506   ViewCellKdNode *mRoot; 
    507   /// bounding box of the tree root 
    508   AxisAlignedBox3 mBox; 
    509   ViewCellKdTreeStatistics mStat; 
    510    
     784 
     785        int 
     786        GetRootPvsSize() const { 
     787                return GetPvsSize(root, bbox); 
     788        } 
     789         
     790        int 
     791        GetPvsSize(VspKdTreeNode *node, const AxisAlignedBox3 &box) const; 
     792 
     793        void 
     794        GetRayContributionStatistics( 
     795                                                                                                                         float &minRayContribution, 
     796                                                                                                                         float &maxRayContribution, 
     797                                                                                                                         float &avgRayContribution 
     798                                                                                                                         ); 
     799 
     800        int 
     801        GenerateRays(const float ratioPerLeaf, 
     802                                                         SimpleRayContainer &rays); 
     803 
     804        float 
     805        GetAvgPvsSize(); 
     806 
    511807}; 
    512808 
    513 #endif 
     809 
     810#endif // __LSDS_KDTREE_H__ 
     811 
Note: See TracChangeset for help on using the changeset viewer.