root/OpenSceneGraph/trunk/src/osgPlugins/txp/trpage_managers.h @ 13041

Revision 13041, 17.2 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
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
28class trpgPageManager;
29
30// Grid and file location of a tile
31struct 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 */
43TX_EXDECL class TX_CLDECL trpgManagedTile
44{
45    friend class trpgPageManager;
46public:
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
148protected:
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*/
179TX_EXDECL class TX_CLDECL trpgPageManager
180{
181public:
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
265protected:
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.
460TX_EXDECL class TX_CLDECL trpgr_ChildRefCB : public trpgr_Callback
461{
462public:
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();
472protected:
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*/
486TX_EXDECL class TX_CLDECL trpgPageManageTester
487{
488public:
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
508protected:
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.