00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _SO_LDM_TOPO_OCTREE_
00025 #define _SO_LDM_TOPO_OCTREE_
00026
00027 #include <Inventor/SbLinear.h>
00028 #include <Inventor/SbBox.h>
00029 #include <LDM/SoLDMTileID.h>
00030
00031 class SoLDMOctreeNode;
00032
00033
00034 #ifdef _MSC_VER
00035 #pragma warning( push )
00036 #pragma warning(disable:4251)
00037 #endif
00038
00039
00040 #define LEVEL_MAX 20
00041
00072 class SoLDMTopoOctree
00073 {
00074
00075 public:
00076
00080 SoLDMTopoOctree();
00081
00087 void init( const SbVec3i32& dimension, const int tileDim, const int border=0 );
00088
00092 SbBox3i32 getTilePos( const SoLDMTileID& tileID )const;
00093
00099 SoLDMTileID getTileID( const SbVec3i32& cellPos, const int resolution )const;
00100
00106 int getNumFileIDs()const;
00107
00111 inline int getFileID( const SoLDMTileID& tileID )const;
00112
00116 SoLDMTileID getTileID( const int fileID )const;
00117
00122 inline bool isEmpty() const
00123 { return (m_numFileIDs<=0); }
00124
00129 int getLevelMax()const;
00130
00135 inline int level( const SoLDMTileID& id )const;
00136
00138 SbVec3i32 getTileSize() const
00139 { return m_tileDim; }
00140
00141 private:
00142
00143
00149 enum Location
00150 {
00151 LEFT = 0x01,
00152 RIGHT = 0x02,
00153 BOTTOM = 0x04,
00154 TOP = 0x08,
00155 FRONT = 0x10,
00156 BACK = 0x20
00157 };
00159 int opposite(int locationMask) const;
00160
00186 static const int s_allLocations[26];
00187
00191 ~SoLDMTopoOctree();
00192
00193 SbVec3i32 getTileOrigin( const LDM_TILE_ID_TYPE tileID )const;
00194
00195 LDM_TILE_ID_TYPE parent( const LDM_TILE_ID_TYPE index )const;
00196 inline LDM_TILE_ID_TYPE children( const LDM_TILE_ID_TYPE index )const;
00197
00198
00199 * Returns the resolution level of the given tile Id
00200 * Note: Octree must be initialized.
00201 */
00202 int level( const LDM_TILE_ID_TYPE index )const;
00203
00204 LDM_TILE_ID_TYPE getNumTilesAtDepth( const int level )const;
00205 LDM_TILE_ID_TYPE getSumTilesAtDepth( const int level )const;
00206
00207
00208 inline size_t getNumTileIDs()const;
00209 int getNumFileIDsAtDepth( const int level )const;
00210 int getSumFileIDsAtDepth( const int level )const;
00211 int sizeofTiles( const int numTile )const;
00212
00213 inline bool hasChildren(const SoLDMTileID& tileId) const;
00214
00216 inline const SbVec3i32& getTileDimAtLevel(int l) const;
00217
00219 SbVec3i32 getTileDimAtLevel(const SoLDMTileID& id) const;
00220
00224 inline bool isChildOf(const SoLDMTileID& parent,
00225 const SoLDMTileID& child) const;
00226
00230 inline bool isInFamilyOf(const SoLDMTileID& parent, const SoLDMTileID& child) const;
00231
00232
00234 SbVec3i32 getTileSpacePos( const LDM_TILE_ID_TYPE tileID , const int tileLevel ) const;
00235
00237 SoLDMTileID getTileSpaceID( const SbVec3i32& cellPos, const int level) const;
00238
00244 SoLDMTileID getNeighborTile(const SoLDMTileID& tileID, int locationMask) const;
00245
00246 SoLDMOctreeNode* operator [](const LDM_TILE_ID_TYPE tileID)const;
00247 SoLDMOctreeNode* operator ()(const int fileID)const;
00248
00255 inline static void getOrderedOctant(int octantOrder[8], const SbVec3f & viewVector);
00256
00257
00258 void useThinOptim(bool useThinVolumeOptim);
00259
00265 inline int getMaxNumChildren() const
00266 { return m_maxNumChildren; }
00267
00272 void commonInit( const SbVec3i32& dimension, const int tileDim, const int border=0 );
00273
00274 private:
00276 void fillTileDimAtLevel();
00277
00279 SbVec3i32 getTileOrigin( const LDM_TILE_ID_TYPE tileID, int tileLevel ) const;
00280
00285 int getFileIDReverseTable( const SoLDMTileID& tileID )const;
00286
00292 static float computeLevelMax(unsigned int maxDim, unsigned int tileDim,
00293 unsigned int border);
00294
00295 static const int MAX_OCTREE_DEPTH;
00296
00297
00298 static const uint64_t s_numTilesAtDepth[LEVEL_MAX+1];
00299 static const uint64_t s_sumTilesAtDepth[LEVEL_MAX+2];
00300
00301
00302 SbVec3i32 m_dimension;
00303 SbVec3i32 m_tileDim;
00304 int m_border;
00305 int m_levelMax;
00306 int m_maxNumChildren;
00307 LDM_TILE_ID_TYPE m_numTileIDs;
00308 int m_numFileIDs;
00309 SoLDMOctreeNode *m_tileIDs;
00310 int* m_fileIDs;
00311 int m_numFileIDsAtDepth[LEVEL_MAX+1];
00312 int m_sumFileIDsAtDepth[LEVEL_MAX+1];
00313 bool m_initIsDone;
00315 static const unsigned int TDimension;
00316
00317 std::vector<SbVec3i32> m_tileDimAtLevel;
00318
00319
00320 bool m_useThinVolumeOptim;
00321
00322 };
00323
00324
00325 size_t
00326 SoLDMTopoOctree::getNumTileIDs() const
00327 {
00328 return (size_t)(m_numTileIDs);
00329 }
00330
00331
00332 bool
00333 SoLDMTopoOctree::hasChildren(const SoLDMTileID& tileId) const
00334 {
00335 return children(tileId.getID()) < (LDM_TILE_ID_TYPE)getNumTileIDs() ;
00336 }
00337
00338
00339 int
00340 SoLDMTopoOctree::level(const SoLDMTileID& id) const
00341 {
00342 return level(id.getID());
00343 }
00344
00345
00346 bool
00347 SoLDMTopoOctree::isChildOf(const SoLDMTileID& parent, const SoLDMTileID& child) const
00348 {
00349 if ( child.getID() >= m_numTileIDs )
00350 return false;
00351
00352 LDM_TILE_ID_TYPE firstChild = children(parent.getID());
00353 LDM_TILE_ID_TYPE childId = child.getID();
00354 return childId >= firstChild && childId < firstChild+8;
00355 }
00356
00357
00358 bool
00359 SoLDMTopoOctree::isInFamilyOf(const SoLDMTileID& _parent, const SoLDMTileID& child) const
00360 {
00361 LDM_TILE_ID_TYPE childId = child.getID();
00362 LDM_TILE_ID_TYPE parentId = _parent.getID();
00363 if ( childId >= m_numTileIDs || childId < 0 )
00364 return false;
00365 else if ( childId == parentId)
00366 return true;
00367 else
00368 {
00369 LDM_TILE_ID_TYPE parentChildID = parent(childId);
00370 if ( parentChildID == parentId )
00371 return true;
00372 else
00373 return isInFamilyOf(_parent,parentChildID);
00374 }
00375 return false;
00376 }
00377
00378
00379 int
00380 SoLDMTopoOctree::getFileID( const SoLDMTileID& tileID )const
00381 {
00382 if ( tileID.getID()<0 || tileID.getID()>=m_numTileIDs)
00383 return -1;
00384
00385
00386 if ( m_fileIDs )
00387 return m_fileIDs[tileID.getID()] - 1;
00388
00389 return getFileIDReverseTable(tileID);
00390 }
00391
00392
00393 LDM_TILE_ID_TYPE
00394 SoLDMTopoOctree::children( const LDM_TILE_ID_TYPE index )const
00395 {
00396 return (index << TDimension) + 1;
00397 }
00398
00399
00400 void
00401 SoLDMTopoOctree::getOrderedOctant(int octantOrder[8], const SbVec3f & viewVector)
00402 {
00403 int bitMask = 0;
00404 for ( int i = 0; i < 3; i++ )
00405 bitMask |= (viewVector[i] < 0) << i;
00406 for ( unsigned int i = 0; i < 8; i++ )
00407 octantOrder[i] = i^bitMask;
00408 }
00409
00410 #ifdef _MSC_VER
00411 #pragma warning( pop )
00412 #endif
00413
00414 #endif
00415
00416
00417