root/OpenSceneGraph/trunk/src/osgPlugins/txp/trpage_managers.h
@
13041
| Revision 13041, 17.2 kB (checked in by robert, 14 months ago) | |
|---|---|
|
|
| Line | |
|---|---|
| 1 | /* ************************ |
| 2 | Copyright Terrain Experts Inc. |
| 3 | Terrain Experts Inc (TERREX) reserves all rights to this source code |
| 4 | unless otherwise specified in writing by the President of TERREX. |
| 5 | This copyright may be updated in the future, in which case that version |
| 6 | supercedes this one. |
| 7 | ------------------- |
| 8 | Terrex Experts Inc. |
| 9 | 4400 East Broadway #314 |
| 10 | Tucson, AZ 85711 |
| 11 | info@terrex.com |
| 12 | Tel: (520) 323-7990 |
| 13 | ************************ |
| 14 | */ |
| 15 | |
| 16 | #ifndef _trpage_managers_h_ |
| 17 | #define _trpage_managers_h_ |
| 18 | |
| 19 | #include <deque> |
| 20 | |
| 21 | /* This file contains class definitions for managers |
| 22 | that help you keep track of data related to |
| 23 | paging. For instance, which tiles to load |
| 24 | in at any given time and what textures you need |
| 25 | to read for a given tile. |
| 26 | */ |
| 27 | |
| 28 | class trpgPageManager; |
| 29 | |
| 30 | // Grid and file location of a tile |
| 31 | struct TileLocationInfo |
| 32 | { |
| 33 | TileLocationInfo(): x(-1), y(-1), lod(-1) {} |
| 34 | TileLocationInfo(int gx, int gy, int glod, const trpgwAppAddress& gaddr): x(gx), y(gy), lod(glod), addr(gaddr) {} |
| 35 | int x, y, lod; |
| 36 | trpgwAppAddress addr; |
| 37 | }; |
| 38 | |
| 39 | /* Managed Tiles are used by the trpgPageManager to keep |
| 40 | track of which tiles are loaded and what textures (and |
| 41 | models) they need loaded into memory with them. |
| 42 | */ |
| 43 | TX_EXDECL class TX_CLDECL trpgManagedTile |
| 44 | { |
| 45 | friend class trpgPageManager; |
| 46 | public: |
| 47 | trpgManagedTile(void); |
| 48 | |
| 49 | // Called to clear any info out of this tile |
| 50 | void Reset(void); |
| 51 | |
| 52 | /* Call this when you hit a tile header in your own |
| 53 | Scene parser callback. The managed tile |
| 54 | can then keep track of which textures and models |
| 55 | go with this tile. |
| 56 | */ |
| 57 | bool ParseTileHeader(trpgReadBuffer &); |
| 58 | |
| 59 | // Check if the tile is loaded (e.g. the header read in) |
| 60 | bool IsLoaded(void); |
| 61 | |
| 62 | /* Set the tile location. This resets any internal |
| 63 | state we may be keeping. |
| 64 | */ |
| 65 | bool SetTileLoc(int x,int y,int lod); |
| 66 | // Get the tile location |
| 67 | bool GetTileLoc(int &x,int &y,int &lod) const; |
| 68 | |
| 69 | // In version 2.1 we no longer have the tile table to |
| 70 | // find the tiles, only by traversing the parent can it be |
| 71 | // found. So when we have this info, this is were to save it. |
| 72 | void SetTileAddress(const trpgwAppAddress& gAddr); |
| 73 | void SetTileAddress(int32 file, int32 offset); |
| 74 | const trpgwAppAddress& GetTileAddress() const; |
| 75 | |
| 76 | |
| 77 | |
| 78 | // Return a pointer to the tile header |
| 79 | const trpgTileHeader *GetTileHead(void); |
| 80 | |
| 81 | /* Return a pointer to the list of locally defined |
| 82 | materials. As soon as the tile header is read by |
| 83 | ParseTileHeader (which you call) you'll want to get |
| 84 | this list and load the pageable textures. You can |
| 85 | use SetMatData to keep track of our internal texture |
| 86 | structures. |
| 87 | */ |
| 88 | const std::vector<trpgLocalMaterial> *GetLocMatList(void) const; |
| 89 | |
| 90 | /* Returns a pointer to a single local material, if within |
| 91 | the valid range of local materials for this tile. |
| 92 | */ |
| 93 | const trpgLocalMaterial *GetLocMaterial(int id) const; |
| 94 | |
| 95 | /* Set Local Data for managed tile. The local data would |
| 96 | probably be a pointer to the top of the scene graph you're |
| 97 | using to represent just this tile. |
| 98 | */ |
| 99 | void SetLocalData(void *); |
| 100 | |
| 101 | /* Returns the local data you set with SetLocalData. |
| 102 | */ |
| 103 | void *GetLocalData(void) const; |
| 104 | |
| 105 | /* Associates a void * with one of the materials referenced |
| 106 | within this tile. The idea here is that you'll want |
| 107 | to load the texture for a given local material and then |
| 108 | pass your own internal texture structure into here as |
| 109 | a void *. That way, the trpgPageManager will keep track |
| 110 | of which textures you should unload when this tile goes |
| 111 | out of range. |
| 112 | */ |
| 113 | bool SetMatData(int id,void *); |
| 114 | |
| 115 | /* Gets the void * data you associated with a given local |
| 116 | material index. See SetMatData for more information. |
| 117 | */ |
| 118 | void *GetMatData(int id) const; |
| 119 | |
| 120 | /* Add Group ID to this tile. This is called by the page |
| 121 | manager to keep track of which group IDs belong to this tile. |
| 122 | We use this information to NULL out the appropriate positions |
| 123 | in the group map help by the page manager. |
| 124 | */ |
| 125 | void AddGroupID(int id); |
| 126 | |
| 127 | /* Retrieve the list of group IDs for this tile. |
| 128 | */ |
| 129 | const std::vector<int> *GetGroupIDs(void) const; |
| 130 | |
| 131 | /* Print the current status and information about this managed |
| 132 | Tile. |
| 133 | */ |
| 134 | void Print(trpgPrintBuffer &); |
| 135 | |
| 136 | // Children info, will throw exception if child index is out of bound |
| 137 | unsigned int GetNbChildren() const |
| 138 | { |
| 139 | return (unsigned int)childLocationInfo.size(); |
| 140 | } |
| 141 | bool SetChildLocationInfo(int childIdx, int x, int y, const trpgwAppAddress& addr); |
| 142 | bool SetChildLocationInfo(int childIdx, const TileLocationInfo& info); |
| 143 | const TileLocationInfo& GetChildLocationInfo(int childIdx) const; |
| 144 | bool GetChildTileLoc(int childIdx, int &x,int &y,int &lod) const; |
| 145 | const trpgwAppAddress& GetChildTileAddress(int childIdx) const; |
| 146 | |
| 147 | |
| 148 | protected: |
| 149 | // Set if a tile is currently loaded |
| 150 | bool isLoaded; |
| 151 | // Tile location info |
| 152 | TileLocationInfo location; |
| 153 | |
| 154 | // Tile Header associated with this tile |
| 155 | trpgTileHeader tileHead; |
| 156 | // Data to keep associated with each individual local material index |
| 157 | std::vector<void *> localMatData; |
| 158 | // Used to keep track of group IDs in this tile |
| 159 | std::vector<int> groupIDs; |
| 160 | // Local data (probably the top of the local scene graph) |
| 161 | void *localData; |
| 162 | |
| 163 | // What are the children: this to be used for version 2.1 and up. |
| 164 | // Both vector should have the same size |
| 165 | std::vector<TileLocationInfo> childLocationInfo; |
| 166 | |
| 167 | // Note: Should do models too if anyone wanted them. |
| 168 | }; |
| 169 | |
| 170 | /* The Page Manager is a helper class that can be used |
| 171 | to keep track of: (1) which tiles need to be loaded |
| 172 | into memory for a given viewer position, (2) which tiles |
| 173 | are currently loaded and (3) which tiles need to be unloaded |
| 174 | when the viewer position moves. The tile list this |
| 175 | class generates is guaranteed to be in the right order |
| 176 | for loading. You would use this class if you're implementing |
| 177 | a TerraPage reader for your visual run-time system. |
| 178 | */ |
| 179 | TX_EXDECL class TX_CLDECL trpgPageManager |
| 180 | { |
| 181 | public: |
| 182 | trpgPageManager(void); |
| 183 | virtual ~trpgPageManager(void); |
| 184 | |
| 185 | // Initialize with an archive |
| 186 | virtual void Init(trpgr_Archive *); |
| 187 | virtual void Init(trpgr_Archive *inArch, int maxLod); |
| 188 | |
| 189 | /* Set Paging Distance |
| 190 | This is the extra distance outside the visible range |
| 191 | we want to page. The defaults will be valid. You would |
| 192 | set this if you want to pull tiles in earlier. Be sure |
| 193 | to call it before you call Init(), however. |
| 194 | */ |
| 195 | virtual bool SetPageDistFactor(double); |
| 196 | |
| 197 | /* Updates the current location for paging purposes. |
| 198 | Returns true if any load or unloads need to happen. |
| 199 | */ |
| 200 | virtual bool SetLocation(trpg2dPoint &); |
| 201 | |
| 202 | /* Get next tile to load. |
| 203 | The paging manager is keeping track of which tiles |
| 204 | need to be loaded and in what order. This method |
| 205 | returns a pointer to the next one. The user is |
| 206 | expected to call AckLoad() after the tile is loaded. |
| 207 | */ |
| 208 | virtual trpgManagedTile *GetNextLoad(void); |
| 209 | /* Acknowledge Tile Load. |
| 210 | This method should be called when a tile has been |
| 211 | loaded by the caller. This method is used in conjunction |
| 212 | with GetNextLoad(). |
| 213 | |
| 214 | Version 2.1 and over supports variable lod so that we cannot know |
| 215 | from the tile table if a tile exist or not. So to manage this |
| 216 | the user must parse the loaded tile and extract its list of children |
| 217 | and pass it on to AckLoad() which will add to the appropriate lod list |
| 218 | the children info. If this is not done then only lod 0 will be pageable. |
| 219 | */ |
| 220 | |
| 221 | virtual void AckLoad(std::vector<TileLocationInfo> const& children); |
| 222 | |
| 223 | // Using this call with version 2.1 and over will only page lod 0 tiles |
| 224 | virtual void AckLoad(); |
| 225 | |
| 226 | /* Add Group ID to map. |
| 227 | This should be called when the user encounters a group-like |
| 228 | object while processing the scene graph data from a tile. |
| 229 | The groupId is given by TerraPage and the data should be |
| 230 | the corresponding group object that the user creates in |
| 231 | their own scenegraph toolkit. This information can then |
| 232 | be retrieved later by GetGroupData(). |
| 233 | */ |
| 234 | virtual void AddGroupID(trpgManagedTile *,int groupID,void *data); |
| 235 | |
| 236 | /* Get Group Data fetches the data cached by the user and |
| 237 | associated with the given groupID. This would be used in |
| 238 | conjunction with trpgAttach nodes to implement geometry paging. |
| 239 | */ |
| 240 | virtual void *GetGroupData(int groupID); |
| 241 | |
| 242 | /* Get next tile to unload. |
| 243 | The paging manager keeps track of which tiles need |
| 244 | to be unloaded based on a change of location. It's |
| 245 | best if you unload tiles before loading them, but |
| 246 | that's really up to you. |
| 247 | */ |
| 248 | virtual trpgManagedTile *GetNextUnload(void); |
| 249 | /* Acknowledge a tile unload. |
| 250 | You should call this after you've "unloaded" a tile |
| 251 | and all its associated textures. |
| 252 | */ |
| 253 | virtual void AckUnload(void); |
| 254 | |
| 255 | |
| 256 | /* Stop paging entirely. Call this right before you want to |
| 257 | shut down paging. Everything active will wind up on the |
| 258 | unload lists. Then you can unload those tiles and move on. |
| 259 | */ |
| 260 | virtual bool Stop(void); |
| 261 | |
| 262 | // Print current status and content information |
| 263 | virtual void Print(trpgPrintBuffer &); |
| 264 | |
| 265 | protected: |
| 266 | trpgr_Archive *archive; |
| 267 | |
| 268 | // Center of paging |
| 269 | trpg2dPoint pagePt; |
| 270 | |
| 271 | /* Information associated with each terrain level of |
| 272 | detail as related to paging. |
| 273 | */ |
| 274 | TX_EXDECL class TX_CLDECL LodPageInfo { |
| 275 | friend class trpgPageManager; |
| 276 | public: |
| 277 | LodPageInfo(void); |
| 278 | virtual ~LodPageInfo(void); |
| 279 | |
| 280 | /* Initializes the class with its current LOD. |
| 281 | It figures out all the rest. |
| 282 | */ |
| 283 | virtual bool Init(trpgr_Archive *, int myLod, double scale, int freeListDivider = 1); |
| 284 | |
| 285 | /* Reset the location. This forces a recalculation |
| 286 | of what to load and unload if the cell has changed |
| 287 | or if this is the first SetLocation. |
| 288 | The location passed in must be relative to the southwest |
| 289 | corner of the TerraPage archive. |
| 290 | */ |
| 291 | virtual bool SetLocation(trpg2dPoint &); |
| 292 | |
| 293 | // Return the next tile to load for this terrain lod |
| 294 | virtual trpgManagedTile *GetNextLoad(void); |
| 295 | // Acknowledge the load. Move the active tile to the |
| 296 | // loaded list. |
| 297 | virtual void AckLoad(); |
| 298 | |
| 299 | // Get the lsit of |
| 300 | //bool GetLoadedTile |
| 301 | |
| 302 | // Return the next tile to unload for this terrain lod |
| 303 | virtual trpgManagedTile *GetNextUnload(void); |
| 304 | // Acknowledge the unload. Move the active tile to the |
| 305 | // free list. |
| 306 | virtual void AckUnload(void); |
| 307 | // Called to stop paging. Everything active is dumped on |
| 308 | // the unload list. |
| 309 | virtual bool Stop(void); |
| 310 | // Print current status and content information |
| 311 | virtual void Print(trpgPrintBuffer &); |
| 312 | |
| 313 | const trpg2iPoint& GetLodSize() const |
| 314 | { |
| 315 | return lodSize; |
| 316 | } |
| 317 | |
| 318 | int GetLod() const |
| 319 | { |
| 320 | return lod; |
| 321 | } |
| 322 | |
| 323 | double GetPageDistance() const |
| 324 | { |
| 325 | return pageDist; |
| 326 | } |
| 327 | |
| 328 | const trpg2dPoint& GetCellSize() const |
| 329 | { |
| 330 | return cellSize; |
| 331 | } |
| 332 | |
| 333 | // The unit are cellSize |
| 334 | const trpg2iPoint& GetAreaOfInterest() const |
| 335 | { |
| 336 | return aoiSize; |
| 337 | } |
| 338 | |
| 339 | |
| 340 | // The middle of this cell correspond to our paging |
| 341 | // location |
| 342 | const trpg2iPoint& GetCellPagingLocation() const |
| 343 | { |
| 344 | return cell; |
| 345 | } |
| 346 | |
| 347 | protected: |
| 348 | virtual void Clean(void); |
| 349 | virtual void Update(void); |
| 350 | |
| 351 | // Add to the load list the given tile if it is within the proper |
| 352 | // bound |
| 353 | bool AddToLoadList(int x, int y, const trpgwAppAddress& addr); |
| 354 | |
| 355 | // Add the children of the given parent list |
| 356 | // to the load list if it it not already loaded |
| 357 | // or if it is not already in the list |
| 358 | void AddChildrenToLoadList(std::vector<trpgManagedTile*>& parentList); |
| 359 | |
| 360 | // Check if the given tile is within the area we care about |
| 361 | bool isWithin(trpgManagedTile *,trpg2iPoint &sw,trpg2iPoint &ne); |
| 362 | |
| 363 | // Get the list of currently loaded tiles that fall within |
| 364 | // the region calculated from the given paging distance. |
| 365 | void GetLoadedTileWithin(double pagingDistance, std::vector<trpgManagedTile*>& tileList); |
| 366 | |
| 367 | bool valid; |
| 368 | |
| 369 | // Terrain LOD we're responsible for |
| 370 | int lod; |
| 371 | |
| 372 | /* Adjusted (e.g. paranoid) distance outward from |
| 373 | which to page this terrain LOD. This takes into |
| 374 | account the distance in the header as well as |
| 375 | any factor the user may have added. |
| 376 | */ |
| 377 | double pageDist; |
| 378 | |
| 379 | /* Max tiles we could have loaded in at any given time. |
| 380 | This is just a guess because it's up to the user |
| 381 | to load (and, more importantly) unload. |
| 382 | */ |
| 383 | int maxNumTiles; |
| 384 | |
| 385 | // Size of a single cell. Copied from the archive. |
| 386 | trpg2dPoint cellSize; |
| 387 | |
| 388 | // Number of tiles (cells) in each direction |
| 389 | trpg2iPoint lodSize; |
| 390 | |
| 391 | /* Area of interest size in cells |
| 392 | This is a linear distance "ahead" of the center cell. |
| 393 | */ |
| 394 | trpg2iPoint aoiSize; |
| 395 | |
| 396 | /* Our effective paging location sits at the middle |
| 397 | of this cell. We don't recalculate unless the |
| 398 | cell changes. */ |
| 399 | trpg2iPoint cell; |
| 400 | |
| 401 | // List of tiles to load |
| 402 | std::deque<trpgManagedTile *> load; |
| 403 | // List of tiles to unload |
| 404 | std::deque<trpgManagedTile *> unload; |
| 405 | // List of currently loaded tiles |
| 406 | std::deque<trpgManagedTile *> current; |
| 407 | |
| 408 | // Used by Update. Here because we want to avoid memory allocs, if possible. |
| 409 | std::vector<bool> tmpCurrent; |
| 410 | |
| 411 | // Set if a load is in progress |
| 412 | // Load w/o ACK |
| 413 | bool activeLoad; |
| 414 | // Set if an unload is in progress |
| 415 | // Unload w/o ACK |
| 416 | bool activeUnload; |
| 417 | |
| 418 | // List of tile pointers we can reuse |
| 419 | std::deque<trpgManagedTile *> freeList; |
| 420 | |
| 421 | // TerraPage version |
| 422 | int majorVersion, minorVersion; |
| 423 | |
| 424 | const trpgTileTable *tileTable; |
| 425 | }; |
| 426 | |
| 427 | // Per terrain lod paging information |
| 428 | std::vector<LodPageInfo> pageInfo; |
| 429 | |
| 430 | // Enumerated type for lastLoad |
| 431 | typedef enum {Load,Unload,None} LoadType; |
| 432 | /* Information about what the pending load/unload operation |
| 433 | is. It's up to the user to complete and acknowledge it. |
| 434 | */ |
| 435 | LoadType lastLoad; |
| 436 | // LOD for the pending load/unload requested operation |
| 437 | int lastLod; |
| 438 | // Tile to be loaded/unloaded |
| 439 | trpgManagedTile *lastTile; |
| 440 | |
| 441 | // Optional scaling factor |
| 442 | double scale; |
| 443 | |
| 444 | // Mapping from group IDs to user defined data |
| 445 | typedef std::map<int,void *> ManageGroupMap; |
| 446 | ManageGroupMap groupMap; |
| 447 | |
| 448 | // Terrapge Version |
| 449 | int majorVersion, minorVersion; |
| 450 | |
| 451 | bool valid; |
| 452 | }; |
| 453 | |
| 454 | // For Version 2.1 an over, the tile table only contains |
| 455 | // tiles of lod 0. To get access the other tiles, parent tile |
| 456 | // must be parsed to get at trpgChildRef nodes that will contain |
| 457 | // location info about the children. This callback can be use to |
| 458 | // parse the tile data. After parsing the callback object will contain |
| 459 | // the list of trpgChildRef nodes found. |
| 460 | TX_EXDECL class TX_CLDECL trpgr_ChildRefCB : public trpgr_Callback |
| 461 | { |
| 462 | public: |
| 463 | void *Parse(trpgToken tok, trpgReadBuffer& rbuf); |
| 464 | // After parsing this will return the number of trpgChildRef node found. |
| 465 | unsigned int GetNbChildren() const; |
| 466 | // This will return the trpgChildRef node associated with the index. |
| 467 | // Will throw an exception if the index is out of bound |
| 468 | const trpgChildRef& GetChildRef(unsigned int idx) const; |
| 469 | |
| 470 | // Clear the children list |
| 471 | void Reset(); |
| 472 | protected: |
| 473 | // typedef std::vector<const trpgChildRef> ChildList; |
| 474 | // The const in the template parameter was removed because it causes GCC to |
| 475 | // freak out. I am of the opinion that const doesn't make sense in a template |
| 476 | // parameter for std::vector anyway... const prevents you from changing the |
| 477 | // value, so what exactly is the point? How does one add entries to the vector |
| 478 | // without giving them a value? -ADS |
| 479 | typedef std::vector<trpgChildRef> ChildList; |
| 480 | ChildList childList; |
| 481 | }; |
| 482 | |
| 483 | /* Page Manager Tester. This class tests a given paging manager |
| 484 | by applying likely |
| 485 | */ |
| 486 | TX_EXDECL class TX_CLDECL trpgPageManageTester |
| 487 | { |
| 488 | public: |
| 489 | trpgPageManageTester(); |
| 490 | virtual ~trpgPageManageTester(); |
| 491 | |
| 492 | /* Initialize the tester with a paging manager |
| 493 | and an archive. |
| 494 | */ |
| 495 | void Init(trpgPrintBuffer *,trpgPageManager *,trpgr_Archive *); |
| 496 | |
| 497 | /* Feeds the paging manager coordinates starting from |
| 498 | the lower left to upper right of the database in the |
| 499 | given increment. |
| 500 | */ |
| 501 | void Fly_LL_to_UR(double dist=100.0); |
| 502 | |
| 503 | /* Jumps around randomly within the archive loading and |
| 504 | unloading as needed. |
| 505 | */ |
| 506 | void RandomTest(int no=100,int seed=-1); |
| 507 | |
| 508 | protected: |
| 509 | |
| 510 | // Does the work of "load" and "unloading" |
| 511 | void ProcessChanges(); |
| 512 | |
| 513 | trpgPageManager *manager; |
| 514 | trpgr_Archive *archive; |
| 515 | trpgPrintBuffer *printBuf; |
| 516 | |
| 517 | trpgr_ChildRefCB childRefCB; |
| 518 | trpgr_Parser tileParser; |
| 519 | |
| 520 | // TerraPage version |
| 521 | int majorVersion, minorVersion; |
| 522 | }; |
| 523 | |
| 524 | #endif |
Note: See TracBrowser
for help on using the browser.
