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_geom_h_
17 #define _trpage_geom_h_
18 
19 /* trpage_geom.h
20    Geometry and node definitions.
21    These are the objects that get read from and written to archives.
22 */
23 
24 #include <trpage_sys.h>
25 
26 #include <trpage_io.h>
27 #include <trpage_swap.h>
28 
29 
30 
31 // Forward declarations
32 
33 class trpgMaterial;
34 class trpgTextureEnv;
35 class trpgMatTable;
36 
37 #define ISMASTER 1
38 #define ISLOCAL 2
39 
40 /* This is the archive header structure.  There is one per TerraPage archive.
41    You don't write it directly, but instead fill it out and pass it to
42    a trpgwArchive (if you're writing), or get it back from a trpgr_Archive
43    (if you're reading).
44    If you're putting together a reader, just use the default methods for
45    reading this class.  Since it's only read once, the overhead is low.
46    {group:Read/Write Classes}
47 */
48 TX_EXDECL class TX_CLDECL trpgHeader : public trpgReadWriteable
49 {
50 public:
51     trpgHeader(void);
52     ~trpgHeader(void);
53 
54     // Set the TerraPage version info.
55     void    SetVersion(int major,int minor);
56     // Set the database version info.
57     void    SetDbVersion(int major,int minor);
58     /* Set the tile size for the given LOD.  See GetTileSize for more info.
59        Each LOD must have its size set, otherwise the trpgHeader won't be valid.
60        You must set the number of LODs with SetNumLods first.
61        You should use the AddLod method if you can, which handles all of this.
62     */
63     void    SetTileSize(int lod,const trpg2dPoint &size);
64     // Origin defaults to 0,0,0
65     void    SetOrigin(const trpg3dPoint &);
66     // 2D archive extents.  Must be set.
67     void    SetExtents(const trpg2dPoint &sw,const trpg2dPoint &ne);
68 
69     typedef enum {DatabaseLocal,Absolute,TileLocal} trpgTileType;
70     // How the coordinates are treated with respect to real world values.
71     void    SetTileOriginType(trpgTileType);
72 
73     /* Number of terrain LODs.  If you use this method when building a database
74        you have to use the SetLodRange and SetLodSize methods on each LOD as well.
75        It's better to use AddLod instead of calling these three methods.
76     */
77     void    SetNumLods(int);
78     /* Number of tiles (x,y) for each LOD.
79        The single argument version assumes lod = 0, num lods = 1.
80     */
81     void    SetLodSize(int lod,const trpg2iPoint &);
82     void    SetLodSize(const trpg2iPoint *);
83     /* Set the range for the given terrain LOD.
84        The single argument version assumes lod = 0, num lods = 1.
85     */
86     void    SetLodRange(int,float64);
87     void    SetLodRange(const float64 *);
88     // Increase the number of terrain LODs, adding a new one with the given size and range
89     void    AddLod(const trpg2iPoint &size,const trpg2dPoint &ext,float64 range);
90 
91     // Set details for an LOD, resizing if necessary
92     void    SetLod(const trpg2iPoint &size,const trpg2dPoint &ext,float64 range,unsigned int lod);
93 
94     // Keep track of the maximum assigned group IDs (for tile paging)
95     void    SetMaxGroupID(int);
96     /* Instead of keeping a count of all the group IDs you added and then
97        calling SetMaxGroupID, you can call this function and it will return
98        the next valid groupID to you.  It will also keep track of the maximum.
99     */
100     int            AddGroupID(void);
101 
102     // Validity check
103     bool        isValid(void) const;
104     // Resets the contents back to empty
105     void    Reset(void);
106 
107     // TerraVista version information is two integers.
108     bool    GetVersion(int &,int &) const;
109     // Database version information is user defined.  Put whatever you want here.
110     bool    GetDbVersion(int &,int &) const;
111     /* This is the extents, in X/Y of a
112        single tile.  All tiles within an LOD should be the same size (although this is not
113        enforced).  It's also assumed that a given tile lives entirely within
114        its own extents (as calculated with this value), although that's not
115        enforced either. */
116     bool    GetTileSize(int,trpg2dPoint &) const;
117     /* The meaning of the database origin varies depending on the value returned
118        by GetTileOriginType.  If the database is Absolute, then this value
119        will be the lower left corner.  If the database is DatabaseLocal or
120        TileLocal you can use this value to determine the real world coordinates.
121        Just add origin + coordinate.
122     */
123     bool    GetOrigin(trpg3dPoint &) const;
124     /* These are the 2D extents that the database covers.  You can use this
125        information to determine where the middle is, for example.
126     */
127     bool    GetExtents(trpg2dPoint &sw,trpg2dPoint &ne) const;
128     /* The tile origin type tells you the coordinate system of each database
129        tile.  There are three type:
130        * Absolute - All coordinate values are absolute.  No translation is required.
131        * DatabaseLocal - All coordinate values are local to the database.  That is
132        if you want to determine the real world value do: coord + origin.
133        * TileLocal - Each tile has its own coordinate system starting from the lower left
134        corner.  We do this to get around floating point accuracy problems (although we
135        can do Double coordinates if necessary, as well).  To determine the
136        real world coordinate value do: tileID*tileSize + coord.
137     */
138     bool    GetTileOriginType(trpgTileType &) const;
139     /* Group IDs are used by TerraPage to hook level of detail structures together.
140        A TerraPage database can have an arbitrary number of terrain LODs, each stored
141        separately.  To hook them together we use trpgAttach nodes and number each group &
142        LOD node.  This returns the maximum group ID in the file, which is important
143        to know if you're keeping an array of them. */
144     bool    GetMaxGroupID(int &) const;
145 
146     /* A TerraPage archive can contain any number of terrain LODs (a typical number is 4).
147        Each of these terrain LODs is accessed separately (as are the tiles within them).
148        This returns the number of terrain LODs in the file.  It will be at least 1.
149        See trpgAttach for instructions on how to hook the terrain LODs together.
150 
151        For version 2.1 and over, this number represent the depest lod that was found
152        in the gaming area. With variable lod, tiles will not ncessarily fill out all of
153        the gaming area for all of the lods. trpgAttach node are no longer used, instead
154        see trpgChildRef
155     */
156     bool    GetNumLods(int32 &) const;
157     /* A terrain LOD conceptually covers the entire database and is broken up
158        into some X x Y set of tiles.  We make no assumptions about the number
159        of tiles in each terrain LOD.  That's entirely up to the writer.  This
160        returns the number of tiles in 2D for a given terrain LOD. */
161     bool    GetLodSize(int32,trpg2iPoint &) const;
162     /* It's up to the TerraPage archive writer to make their terrain LOD structure
163        work by using trpgAttach nodes.  The scheme they're using may be quad-tree
164        or replacement LOD or something where the highest LOD isn't even terrain.
165        It really doesn't matter.  However, the reader does need a hint as to
166        when tiles for a given LOD must be pulled in.  This returns that range
167        in database coordinates (usually meters).
168     */
169     bool    GetLodRange(int32,float64 &) const;
170 
171     // Read/Write functions
172 
173     // Writes this class to a write buffer
174     bool    Write(trpgWriteBuffer &);
175     // Reads this class from a read buffer
176     bool    Read(trpgReadBuffer &);
177     // Prints this class to a print buffer
178     bool    Print(trpgPrintBuffer &) const;
179     // {secret}
180     bool    ReadLodInfo(trpgReadBuffer &);
181 
SetMaster(bool isMaster)182     void    SetMaster(bool isMaster)
183     {
184         if((verMajor >= TRPG_NOMERGE_VERSION_MAJOR) && (verMinor >=TRPG_NOMERGE_VERSION_MINOR))
185         {
186             if(isMaster)
187                 flags |= ISMASTER;//set the master flag
188             else
189                 flags &= ~ISMASTER;//clear the master flag
190         }
191     }
GetIsMaster()192     bool    GetIsMaster() const
193     {
194         return ((flags & ISMASTER)==ISMASTER);
195     }
SetLocal(bool isLocal)196     void    SetLocal(bool isLocal)
197     {
198         if((verMajor >= TRPG_NOMERGE_VERSION_MAJOR) && (verMinor >=TRPG_NOMERGE_VERSION_MINOR))
199         {
200             if(isLocal)
201                 flags |= ISLOCAL;//set the local flag
202             else
203                 flags &= ~ISLOCAL;//clear the local flag
204         }
205     }
GetIsLocal()206     bool    GetIsLocal() const
207     {
208         return ((flags & ISLOCAL)==ISLOCAL);
209     }
SetBlocks(int r,int c)210     void    SetBlocks(int r,int c)
211     {
212         rows = r;
213         cols = c;
214     }
GetBlocks(int & r,int & c)215     void    GetBlocks(int &r,int &c)
216     {
217         r = rows;
218         c = cols;
219     }
220 protected:
221     int verMinor,verMajor;
222     int dbVerMinor,dbVerMajor;
223     int maxGroupID;
224     trpg2dPoint sw,ne;
225     trpg3dPoint origin;
226     trpgTileType tileType;
227 
228     int numLods;
229     std::vector<trpg2dPoint> tileSize;
230     std::vector<trpg2iPoint> lodSizes;
231     std::vector<float64>   lodRanges;
232     int32   flags;
233     int32    rows;
234     int32    cols;
235 };
236 
237 /* The Texture Environment is used by the trpgMaterial to define texture
238    related parameters.  A trpgTextureEnv is associated with each texture
239    used in a trpgMaterial.  So, for example, if there are 2 textures in
240    a material, there will be two texture environments.
241    Most of these parameters come straight from the OpenGL specification.  It's
242    best to consult that for an exact meaning.
243 
244    If you doing a TerraPage reader, expect to get a trpgTextureEnv when
245    dealing with trpgMaterial definitions.  If you're doing a writer, you'll
246    need to build these in the course of building a trpgMaterial.
247    {group:Read/Write Classes}
248 */
249 TX_EXDECL class TX_CLDECL trpgTextureEnv : public trpgReadWriteable
250 {
251     friend class trpgMatTable;
252 public:
253     trpgTextureEnv(void);
254     ~trpgTextureEnv(void);
255 
256     // Environment mode values
257     enum {Alpha,Blend,Decal,Modulate,AddDetail,ModulateDetail};
258     // Set the application mode for the texture.
259     void    SetEnvMode(int);
260     // Values used by SetMinFilter and SetMagFilter
261     enum {Point, Linear, MipmapPoint, MipmapLinear,
262       MipmapBilinear, MipmapTrilinear, Nearest};
263     // Set the Minification filter for a texture
264     void    SetMinFilter(int);
265     // Set the Magnification filter for a texture
266     void    SetMagFilter(int);
267 
268     // Values used by SetWrap
269     enum {Clamp,Repeat};
270     // Set the texture wrapping for S and T, respectively
271     void    SetWrap(int,int);
272     // Set the texture border color
273     void    SetBorderColor(const trpgColor &);
274 
275     /* The environment mode controls how the texture is applied.
276        It can take the following values:
277        Alpha - Used to change the alpha values on a polygon.
278        Blend - Blended with the polygon color
279        Decal - Doesn't take polygon color into account.
280        Modulate - See openGL spec for definition.
281        AddDetail - See openGL spec for definition.
282        ModulateDetail - See openGL spec for definition.
283     */
284     bool    GetEnvMode(int32 &) const;
285     /* The Minification and Magnification filters control how texture
286        mipmap levels are used.  We support the values: Point, Linear,
287        MipmapPoint, MipmapLinear,
288        MipmapBilinear, MipmapTrilinear, Nearest
289     */
290     bool    GetMinFilter(int32 &) const;
291     // Get the magnification filter
292     bool    GetMagFilter(int32 &) const;
293     /* Wrapping controls how textures are used near the edges.
294        There are two valid values: Clamp, Repeat.
295     */
296     bool    GetWrap(int &,int &) const;
297     /* This maps straight into the OpenGL definition of border color. */
298     bool    GetBorderColor(trpgColor &) const;
299 
300     // Validity check
301     bool        isValid(void) const;
302     // Resets the contents back to empty
303     void    Reset(void);
304     // Writes this class to a write buffer
305     bool        Write(trpgWriteBuffer &);
306     // Reads this class from a read buffer
307     bool    Read(trpgReadBuffer &);
308     // Prints this class to a print buffer
309     bool    Print(trpgPrintBuffer &) const;
310 
311 protected:
312     int envMode;
313     int minFilter;
314     int magFilter;
315     int wrapS,wrapT;
316     trpgColor borderCol;
317 };
318 
319 /* The material definition for TerraPage encompasses those things that have to
320    do with visual display that can be indexed and disassociated from the
321    polygons themselves.  This covers things like color, texture, alpha
322    and a few more obscure ones.
323    Materials are indexed centrally in a trpgMatTable.
324 
325    This material definition borrows heavily from the OpenGL specification.
326    Please refer to that for a good definition of all the fields.
327 
328    If you're doing a TerraPage reader you'll need to deal with these in two places.
329    First, is when you read the archive header and get a trpgMatTable back.  You'll
330    want to translate them into your own internal representation and keep track of
331    the mapping.  Later, when parsing trpgGeometry nodes, you'll run into them
332    again.  This time they will be material indices into a trpgMatTable.  At that
333    point you'll want to map these indices into your own material definition table.
334 
335    If you're doing a TerraPage writer you'll need to create one of these for every
336    unique material-like object you have.  Since trpgMaterial objects are indexed
337    centrally in a TerraPage archive, you should take advantage of that and use
338    as few as possible.  After defining one, you'll want to add it to a trpgMatTable
339    and keep track of the material index that returns.  This will be the mapping from
340    your own internal material table (or whatever you've got) into the archive's
341    material table.  A trpgMaterial sets up defaults that work pretty well, so just
342    fill in what you need to use.
343    {group:Read/Write Classes}
344 */
345 TX_EXDECL class TX_CLDECL trpgMaterial : public trpgReadWriteable
346 {
347     friend class trpgMatTable;
348 public:
349     trpgMaterial(void);
350     ~trpgMaterial(void);
351     // Set base material color
352     void    SetColor(const trpgColor &);
353     // Ambient color
354     void    SetAmbient(const trpgColor &);
355     // Diffuse color (the most commonly used)
356     void    SetDiffuse(const trpgColor &);
357     // Specular color used in lighting
358     void    SetSpecular(const trpgColor &);
359     // Emissive color used in lighting
360     void    SetEmission(const trpgColor &);
361     // Shininess used in lighting
362     void    SetShininess(float64);
363 
364     enum {Smooth,Flat};
365     // Shading model
366     void    SetShadeModel(int);
367     // Point size
368     void    SetPointSize(float64);
369     // Line width
370     void    SetLineWidth(float64);
371     enum {Front,Back,FrontAndBack};
372     // Cull mode.  See GetCullMode
373     void    SetCullMode(int);
374 #ifdef Always
375     // None and Always appear to be defined on the SGI
376     //  in such a way as to interfere with a local enum
377     //  declaration within a class
378     enum {trNone,trAlways,Equal,GreaterThanOrEqual,GreaterThan,
379       LessThanOrEqual,LessThan,Never,NotEqual};
380 #else
381     enum {None,Always,Equal,GreaterThanOrEqual,GreaterThan,
382       LessThanOrEqual,LessThan,Never,NotEqual};
383 #endif
384     // Alpha Function.  See GetAlphaFunc
385     void    SetAlphaFunc(int);
386     // Alpha Ref value.  See GetAlphaRef
387     void    SetAlphaRef(float64);
388     // Alpha value for any polygon using this material
389     void    SetAlpha(float64);
390     // Generate normals automatically from geometry
391     void    SetAutoNormal(bool);
392 
393     /* Set the total number of textures used by this trpgMaterial.
394        This works with SetTexture.  We recommend that you used
395        AddTexture instead of these two methods. */
396     void    SetNumTexture(int);
397     /* Works with SetNumTexture.
398        This method sets the texture ID and texture environment for the given
399        texture instance in this material.  Use AddTexture instead, if you can.
400     */
401     void    SetTexture(int no,int id,const trpgTextureEnv &);
402     /* This method takes a texture ID that refers to a trpgTexTable and a
403        trpgTextureEnv which specifies the application information relating
404        to this texture instance.  It returns the reference number (i.e. the
405        3rd texture in this material, etc...)
406     */
407     int        AddTexture(int,const trpgTextureEnv &);
408 
409     // Number of tiles this material is used in
410     void    SetNumTiles(int);
411     // Adds a count to the number of tiles this material is used in and returns that number
412     int        AddTile(void);
413 
414     // Sets bump map status (color etc... isn't important)
415     void    SetIsBumpMap(bool);
416 
417     // Set an attribute (e.g. fid/smc)
418     enum {TR_FID,TR_SMC,TR_STP,TR_SWC};
419     void    SetAttr(int attrCode,int val);
420 
421     // Return the current color
422     bool    GetColor(trpgColor &) const;
423     // Returns the ambient color
424     bool    GetAmbient(trpgColor &) const;
425     // Returns the diffuse color (the most commonly used color)
426     bool    GetDiffuse(trpgColor &) const;
427     // Specular color used for lighting
428     bool    GetSpecular(trpgColor &) const;
429     // Emissive color used for lighting
430     bool    GetEmission(trpgColor &) const;
431     // Shininess used for lighting
432     bool    GetShininess(float64 &) const;
433 
434     // The shading model can be either Smooth or Flat
435     bool    GetShadeModel(int &) const;
436     // Point size
437     bool    GetPointSize(float64 &) const;
438     // Line width
439     bool    GetLineWidth(float64 &) const;
440     /* Cull mode determines whether geometry will be rejected if it's Front facing, Back
441        facing, or neither (FrontAndBack)
442     */
443     bool    GetCullMode(int &) const;
444     /* This controls what alpha values in a texture mean.  It can take the values:
445        None,Always,Equal,GreaterThanOrEqual,GreaterThan,
446        LessThanOrEqual,LessThan,Never,NotEqual
447     */
448     bool    GetAlphaFunc(int &) const;
449     /* The Alpha Ref is a value used in some of the Alpha Functions */
450     bool    GetAlphaRef(float64 &) const;
451     // Whether or not to generate normals from geometry
452     bool    GetAutoNormal(bool &) const;
453     // A single Alpha value that applies to any polygons using this material
454     bool    GetAlpha(float64 &) const;
455     /* One of the useful things about TerraPage is that it contains enough information
456        to page textures & materials as well as terrain.  This is part of that.
457        It returns the number of tiles this material is used in.  The trpgTexture has
458        its own which is used for paging textures.  You only want to pay attention to
459        this if you have some costly material definition in your hardware and so have
460        to swap them in and out.
461     */
462     bool    GetNumTile(int &) const;
463 
464     /* There can be multiple textures per material.  This returns the number.
465        The first is the base texture, so just use that if you can only do 1 texture per poly.
466     */
467     bool    GetNumTexture(int &) const;
468     /* TerraPage supports multiple textures per polygon.  Some hardware can do this,
469        some can't.  If you can support it, here's how this works.
470        This method returns the texture definition for the Nth texture used in this material.
471        That consists of a texture ID which points into a trpgTexTable and a trpgTextureEnv
472        which contains the texture application information.
473        Multiple materials can also appear per trpgGeometry, so be aware that there are
474        two ways to have multiple textures per polygon.
475     */
476     bool    GetTexture(int no,int &id,trpgTextureEnv &) const;
477 
478     // Return whether or not this material is a bump map
479     bool    GetIsBumpMap(bool &) const;
480 
481     // Get an attribute (e.g. fid/smc)
482     bool    GetAttr(int attrCode,int &val) const;
483 
484     // Validity check
485     bool    isValid(void) const;
486     // Resets the contents back to empty
487     void    Reset(void);
488     // Writes this class to a write buffer
489     bool    Write(trpgWriteBuffer &);
490     // Reads this class from a read buffer
491     bool    Read(trpgReadBuffer &);
492     // Prints this class to a print buffer
493     bool    Print(trpgPrintBuffer &) const;
494 
495     // Note: Need to do equality operator
496 
497 protected:
498     bool isBump;
499     trpgColor color;
500     trpgColor ambient;
501     trpgColor diffuse;
502     trpgColor specular;
503     trpgColor emission;
504     float64 shininess;
505     int shadeModel;
506     float64 pointSize;
507     float64 lineWidth;
508     int cullMode;
509     int alphaFunc;
510     float64 alpha;
511     float64 alphaRef;
512     bool autoNormal;
513     int numTex;
514     int32 numTile;
515     struct _attrSet
516     {
517         int fid;
518         int smc;
519         int stp;
520         int swc;
521     } attrSet;
522     std::vector<int> texids;
523     std::vector<trpgTextureEnv> texEnvs;
524 };
525 
526 /* Light attributes are used by the trpgLight objects.
527    They control all aspects of how lights are constructed and
528    displayed.  Lights are very complicated and often system specific.
529    It's best to consult the Get methods to figure out what options
530    are available.
531 */
532 TX_EXDECL class TX_CLDECL trpgLightAttr : public trpgReadWriteable
533 {
534 public:
535     // Default constructor
536     trpgLightAttr(void);
537     // Copy constructor
538     trpgLightAttr(const trpgLightAttr &);
539     // Destructor
540     ~trpgLightAttr(void);
541 
542     // Light Flags
543     enum LightFlags
544     {
545         // Light flags
546         trpg_Day =        0x0001,
547         trpg_Dusk =        0x0002,
548         trpg_Night =        0x0004,
549         trpg_Directional =    0x0008,
550         trpg_BackColor =    0x0010,
551         trpg_Reflective =    0x0020,
552 
553         // Animation flags
554         trpg_Flashing =        0x0100,
555         trpg_Rotating =        0x0200,
556         trpg_ClockWise =    0x0400,
557         trpg_AnimationMask =    0x0f00,
558 
559         // Performer light flags
560         trpg_Perspective =    0x1000,
561         trpg_Fade =        0x2000,
562         trpg_ZBuffer =        0x4000,
563         trpg_FogPunch =        0x8000,
564         trpg_PerformerMask =    0xf000
565     };
566 
567     // Light Type
568     enum LightType
569     {
570         trpg_Raster,
571         trpg_Calligraphic,
572         trpg_RASCAL
573     };
574 
575     // Light Directionality
576     enum LightDirectionality
577     {
578         trpg_Omnidirectional,
579         trpg_Bidirectional,
580         trpg_Unidirectional
581     } ;
582 
583     // Light Quality
584     enum LightQuality
585     {
586         trpg_Off,
587         trpg_Low,
588         trpg_Medium,
589         trpg_High,
590         trpg_Undefined
591     };
592 
593     // Struct for Performer Lights
594     struct PerformerAttr
595     {
PerformerAttrPerformerAttr596         PerformerAttr() : flags(0),minPixelSize(0),maxPixelSize(0),actualSize(0),
597             transparentPixelSize(0),transparentFallofExp(0),transparentScale(0),
598             transparentClamp(0),fogScale(0) {};
599         int32                    flags;
600         float64                    minPixelSize;
601         float64                    maxPixelSize;
602         float64                    actualSize;
603         float64                    transparentPixelSize;
604         float64                    transparentFallofExp;
605         float64                    transparentScale;
606         float64                    transparentClamp;
607         float64                    fogScale;
608     };
609 
610     // Struct for Animated Lights
611     struct AnimationAttr
612     {
AnimationAttrAnimationAttr613         AnimationAttr() : period(0),phaseDelay(0),timeOn(0),vector(trpg3dPoint(0,0,0)),flags(0) {};
614         float64                    period;
615         float64                    phaseDelay;
616         float64                    timeOn;
617         trpg3dPoint                vector;
618         int32                    flags;
619     };
620 
621     // Struct for Calligraphic Lights
622     struct CalligraphicAttr
623     {
CalligraphicAttrCalligraphicAttr624         CalligraphicAttr() : drawOrder(0),minDefocus(0),maxDefocus(0) {} ;
625         int32                    drawOrder;
626         float64                    minDefocus;
627         float64                    maxDefocus;
628     };
629 
630     // Setters
631     // Set Type
632     void SetType( trpgLightAttr::LightType );
633 
634     // Set Directionality
635     void SetDirectionality( trpgLightAttr::LightDirectionality );
636 
637     // Set Front Color
638     void SetFrontColor( trpgColor );
639 
640     // Set Front Intensity
641     void SetFrontIntensity( float64 );
642 
643     // Set Back Color
644     void SetBackColor( trpgColor );
645 
646     // Set Back Intensity
647     void SetBackIntensity( float64 );
648 
649     // Set Normal
650     void SetNormal( trpg3dPoint );
651 
652     // Set SMC
653     void SetSMC( int32 );
654 
655     // Set FID
656     void SetFID( int32 );
657 
658     // Set Flags
659     void SetFlags( int32 );
660 
661     // Set Horizontal Lobe Angle
662     void SetHLobeAngle( float64 );
663 
664     // Set Vertical Lobe Angle
665     void SetVLobeAngle( float64 );
666 
667     // Set Lobe Roll Angle
668     void SetLobeRollAngle( float64 );
669 
670     // Set Lobe Falloff
671     void SetLobeFalloff( float64 );
672 
673     // Set Ambient Intensity
674     void SetAmbient( float64 );
675 
676     // Set Quality
677     void SetQuality( trpgLightAttr::LightQuality );
678 
679     // Set RASCAL Significance
680     void SetRascalSignificance( float64 );
681 
682     // Set Random Intensity
683     void SetRandomIntensity( trpgLightAttr::LightQuality );
684 
685     // Set the attributes for Calligraphics Lights
686     void SetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& );
687 
688     // Set Calligraphic Draw Order
689     void SetCalligraphicDrawOrder( int32 );
690 
691     // Set Calligraphic Minimum Defocus
692     void SetCalligraphicMinDefocus( float64 );
693 
694     // Set Calligraphic Maximum Defocus
695     void SetCalligraphicMaxDefocus( float64 );
696 
697     // Set the attributes for Performer Lights
698     void SetPerformerAttr( trpgLightAttr::PerformerAttr& );
699 
700     // Set the flags for Perfromer Lights
701     void SetPerformerFlags( int32 );
702 
703     // Set the minimum pixel size for Performer Lights
704     void SetPerformerMinPixelSize( float64 );
705 
706     // Set the maximum pixel size for Performer Lights
707     void SetPerformerMaxPixelSize( float64 );
708 
709     // Set the actual size for Performer Lights
710     void SetPerformerActualSize( float64 );
711 
712     // Set the transparent pixel size for Performer Lights
713     void SetPerformerTpPixelSize( float64 );
714 
715     // Set the transparent Falloff exponent for Performer Lights
716     void SetPerformerTpFalloffExp( float64 );
717 
718     // Set the transparent scale for Performer Lights
719     void SetPerformerTpScale( float64 );
720 
721     // Set the transparent clamp for Performer Lights
722     void SetPerformerTpClamp( float64 );
723 
724     // Set the fog scale for Performer Lights
725     void SetPerformerFogScale( float64 );
726 
727     // Set the attributes for animated lights
728     void SetAnimationAttr( trpgLightAttr::AnimationAttr& );
729 
730     // Set the animation period for animated lights
731     void SetAnimationPeriod( float64 );
732 
733     // Set the animation phase delay for animated lights
734     void SetAnimationPhaseDelay( float64 );
735 
736     // Set the time on for animated lights
737     void SetAnimationTimeOn( float64 );
738 
739     // Set the animation vector for animated lights
740     void SetAnimationVector( trpg3dPoint );
741 
742     // Set the flags for animated lights
743     void SetAnimationFlags( int32 );
744 
745     // Set the comment for this light point type
746     void SetComment(const char *);
747 
748     // Getters
749     // See the comments for the Setters
750     void GetType( trpgLightAttr::LightType& );
751     void GetDirectionality( trpgLightAttr::LightDirectionality& );
752     void GetFrontColor( trpgColor& );
753     void GetFrontIntensity( float64& );
754     void GetBackColor( trpgColor& );
755     void GetBackIntensity( float64& );
756     void GetNormal( trpg3dPoint& );
757     void GetSMC( int32& );
758     void GetFID( int32& );
759     void GetFlags( int32& );
760     void GetHLobeAngle( float64& );
761     void GetVLobeAngle( float64& );
762     void GetLobeRollAngle( float64& );
763     void GetLobeFalloff( float64& );
764     void GetAmbient( float64& );
765     void GetQuality( trpgLightAttr::LightQuality& );
766     void GetRascalSignificance( float64& );
767     void GetRandomIntensity( trpgLightAttr::LightQuality& );
768     void GetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& );
769     void GetCalligraphicDrawOrder( int32& );
770     void GetCalligraphicMinDefocus( float64& );
771     void GetCalligraphicMaxDefocus( float64& );
772     void GetPerformerAttr( trpgLightAttr::PerformerAttr& );
773     void GetPerformerFlags( int32& );
774     void GetPerformerMinPixelSize( float64& );
775     void GetPerformerMaxPixelSize( float64& );
776     void GetPerformerActualSize( float64& );
777     void GetPerformerTpPixelSize( float64& );
778     void GetPerformerTpFalloffExp( float64& );
779     void GetPerformerTpScale( float64& );
780     void GetPerformerTpClamp( float64& );
781     void GetPerformerFogScale( float64& );
782     void GetAnimationAttr( trpgLightAttr::AnimationAttr& );
783     void GetAnimationPeriod( float64& );
784     void GetAnimationPhaseDelay( float64& );
785     void GetAnimationTimeOn( float64& );
786     void GetAnimationVector( trpg3dPoint& );
787     void GetAnimationFlags( int32& );
788     const char *GetComment();
789 
790     // operators
791     trpgLightAttr& operator = (const trpgLightAttr&);
792     bool operator == (const trpgLightAttr&);
793     bool operator != (const trpgLightAttr&);
794 
795     // Writes this class to a write buffer
796     bool Write(trpgWriteBuffer &);
797 
798     // Reads this class from a read buffer
799     bool Read(trpgReadBuffer &);
800 
801     // Prints this class to a print buffer
802     bool Print(trpgPrintBuffer &) const;
803 
804     // Validity check
805     bool isValid(void) const;
806 
807     // Resets the contents back to empty
808     void Reset(void);
809 
810 
811 protected:
812     struct DataSet
813     {
814         LightType        type;
815         LightDirectionality    directionality;
816         trpgColor        frontColor;
817         float64            frontIntensity;
818         trpgColor        backColor;
819         float64            backIntensity;
820         trpg3dPoint        normal;
821         int32            smc;
822         int32            fid;
823         int32            flags;
824         float64            horizontalLobeAngle;
825         float64            verticalLobeAngle;
826         float64            lobeRollAngle;
827         float64            lobeFalloff;
828         float64            ambientIntensity;
829         LightQuality        quality;
830         LightQuality        randomIntensity;
831         float64            rascalSignificance;
832         CalligraphicAttr    calligraphicAttr;
833         PerformerAttr        performerAttr;
834         AnimationAttr        animationAttr;
835         char            *commentStr;
836     } data;
837 };
838 
839 /* Lights in TerraPage are called out as separate objects.  The trpgLight
840    object will appear in the scenegraph as an individual light structure.
841    These may consist of single lights or light strings.
842    The trpgLight points into the trpgLightTable for its attributes.
843 */
844 TX_EXDECL class TX_CLDECL trpgLight : public trpgReadWriteable
845 {
846 public:
847     // Default constructor
848     trpgLight(void);
849     // Copy constructor
850     trpgLight(const trpgLight &);
851     // Destructor
852     ~trpgLight(void);
853 
854     // Set the index pointing into the Light Table
855     void SetAttrIndex(int);
856 
857     // Add a new location this light is located at
858     void AddVertex(trpg3dPoint);
859 
860     // Returns the number of locations, this light is located at
861     void GetNumVertices(uint32 &) const;
862 
863     // Returns the location at a given index
864     bool GetVertex(uint32, trpg3dPoint &) const;
865 
866     // Returns the whole list of vertices
867     bool GetVertices(trpg3dPoint *) const;
868     bool GetVertices(float64 *) const;
869     bool GetVertices(float32 *) const;
870 
871 
872     // Returns the index of the Light Attributes in the Light Table
873     void GetAttrIndex(int &) const;
874 
875     // Validity check
876     bool isValid(void) const;
877 
878     // Resets the contents back to empty
879     void Reset(void);
880 
881     // Writes this class to a write buffer
882     bool Write(trpgWriteBuffer &);
883 
884     // Reads this class from a read buffer
885     bool Read(trpgReadBuffer &);
886 
887     // Prints this class to a print buffer
888     bool Print(trpgPrintBuffer &) const;
889 
890     // operator
891     trpgLight& operator = (const trpgLight &);
892 
893 protected:
894     // Here we store the light locations
895     std::vector<trpg3dPoint>    lightPoints;
896     int                index;
897 };
898 
899 /* The Light Table is stored in the TerraPage header and consolidates
900    the attributes for all light points.  trpgLight structures will index
901    into this table to define their appearance.
902 */
903 TX_EXDECL class TX_CLDECL trpgLightTable : public trpgReadWriteable
904 {
905 public:
906     // Default constructor
907     trpgLightTable(void);
908 
909     // Copy constructor
910     trpgLightTable(const trpgLightTable &);
911 
912     // Destructor
913     ~trpgLightTable(void);
914 
915     // Adds the given light attrib to the table and increments the total light attrib count.
916     int AddLightAttr(const trpgLightAttr&);
917 
918     /* This is the same as AddLightAttr except that it searches for a matching light attrib
919        first.  This is convenient for writers who aren't keeping track of their
920        own light attrib internally.
921     */
922     int    FindAddLightAttr(const trpgLightAttr&);
923 
924     // Returns the number of light attrib in this table
925     bool GetNumLightAttrs(int &) const;
926 
927     // Returns a pointer to a light attrib from a given index
928     const trpgLightAttr* GetLightAttrRef(int) const;
929 
930     // Validity check
931     bool isValid(void) const;
932 
933     // Resets the contents back to empty
934     void Reset(void);
935 
936     // Writes this class to a write buffer
937     bool Write(trpgWriteBuffer &);
938 
939     // Reads this class from a read buffer
940     bool Read(trpgReadBuffer &);
941 
942     // Prints this class to a print buffer
943     bool Print(trpgPrintBuffer &) const;
944 
945     // operator
946     trpgLightTable & operator = (const trpgLightTable &);
947 
948     typedef std::map<int,trpgLightAttr> LightMapType;
getLightMap()949     LightMapType *getLightMap() { return &lightMap; }
950 protected:
951     // Here we store the light attributes
952     //std::vector<trpgLightAttr> lightList;
953     LightMapType lightMap;
954 
955 };
956 
957 /* Range Info
958    These classes live within the trpgRangeTable.  They encapsulate range
959    information that ties trpgLod nodes together.  Their purpose is to provide
960    data to the run-time system about the relative priorities of classes of
961    features.  See the trpgRangeTable for a complete explanation.
962 */
963 TX_EXDECL class TX_CLDECL trpgRange : public trpgReadWriteable
964 {
965 public:
966     trpgRange(void);
967     ~trpgRange(void);
968 
969     // Copy constructor
970     trpgRange(const trpgRange &);
971 
972     // Set the name and subName (can be NULL)
973     void    SetCategory(const char *cat,const char *subCat);
974 
975     /* Get the name and subName
976        Name should be the major category (e.g. "trees")
977        SubName should be the minor category (e.g. "big trees")
978     */
979     void    GetCategory(char *cat,int maxCatLen,char *subCat,int maxSubCatLen) const;
980 
981     // Set the lod info
982     void    SetLodInfo(double in,double out);
983 
984     // Get the lod info (this will be duplicated in the trpgLod node)
985     // However, you may want to change these values yourself during a run
986     void    GetLodInfo(double &in,double &out) const;
987 
988     // Set the priority
989     void    SetPriority(int);
990 
991     /* Get the priority.
992        Priority is a hint to the run-time system as to the relative importance
993        of range limited features.  Features with lower priorities should be
994        sacrified before those with higher priorities.
995     */
996     void    GetPriority(int &) const;
997 
998     // Writes this class to a write buffer
999     bool    Write(trpgWriteBuffer &);
1000 
1001     // Reads this class from a read buffer
1002     bool    Read(trpgReadBuffer &);
1003 
1004     // Prints this class to a print buffer
1005     bool    Print(trpgPrintBuffer &) const;
1006 
1007     // Reset back to a clean state
1008     void Reset(void);
1009 
1010     // Equality operator
1011     bool operator == (const trpgRange &) const;
1012 
1013     // Assignment operator
1014     trpgRange & operator = (const trpgRange &);
1015 
1016 protected:
1017     double inLod,outLod;
1018     char *category;
1019     char *subCategory;
1020     int priority;
1021 };
1022 
1023 /* The Range Table is new to 2.0.  The goal is to provide information about
1024    certain classes of features within a TerraPage database.  It's intended
1025    to solve the following problem.
1026 
1027    Let's say that you have an Image Generator that must draw a given TerraPage
1028    database at 60Hz.  However, it's only hitting 30Hz reliably.  Often, some
1029    feature set (e.g. bushes) must be sacrified in order to reach the target frame rate.
1030    Determining which features can be throttled back can often be very difficult.
1031    Scaling all of the LODs will often work, but it's not very elegant.  It's
1032    not selective (you may lose important features as well as unimportant ones)
1033    and it doesn't easily let turn whole feature sets off.
1034 
1035    If you do want to selectively turn features on and off or throttle them
1036    back, you can do so based on node names within the LODs.  This can work, however
1037    you've got the additional overhead of traversing the tree looking for LODs
1038    and trying to figure out what the names mean.  The range table is intended
1039    to make this task easier.
1040 
1041    Each trpgLod can (but isn't required to) have an index into the Range Table.
1042    That index will point to a trpgRange that contains global information
1043    about that class of LODs.  This includes the in/out information already contained
1044    within the LOD as well as global info.  The global information includes a category
1045    and sub-category as well as an integer priority.  The category data is there to
1046    allow run-time systems to tell users what they're dropping (or allow them to pick).
1047    The priority is there to tell systems what to get rid of first (according to the
1048    user who build the TerraPage archive).
1049 
1050    Priorities are relative to each other within the Range Table.  There can be
1051    duplicates and there may be holes in the numbering.
1052 
1053    {group:Read/Write Classes}
1054 */
1055 TX_EXDECL class TX_CLDECL trpgRangeTable : public trpgReadWriteable
1056 {
1057 public:
1058     trpgRangeTable(void);
1059     ~trpgRangeTable(void);
1060 
1061     // Get the given range info
1062     bool    GetRange(int id,trpgRange &) const;
1063 
1064     // Get the number of entries in the table
GetNumRanges()1065     int        GetNumRanges() {return int(rangeMap.size());}
1066     // Set the range info for the given ID
1067     bool    SetRange(int id,trpgRange &);
1068 
1069     // Add a new range and return the ID
1070     int        AddRange(trpgRange &);
1071 
1072     // Find a matching range and return it or add a new one if needed
1073     int        FindAddRange(trpgRange &);
1074 
1075     // Writes this class to a write buffer
1076     bool    Write(trpgWriteBuffer &);
1077 
1078     // Reads this class from a read buffer
1079     bool    Read(trpgReadBuffer &);
1080 
1081     // Prints this class to a print buffer
1082     bool    Print(trpgPrintBuffer &) const;
1083 
1084     // Resets the contents back to empty
1085     void    Reset(void);
1086 
1087     // Assignment operator
1088     trpgRangeTable & operator = (const trpgRangeTable &);
1089 
1090 protected:
1091     typedef std::map<int,trpgRange> RangeMapType;
1092     RangeMapType rangeMap;
1093     //std::vector<trpgRange> rangeList;
1094 };
1095 
1096 /* All materials are centrally indexed in TerraPage.  There is one material
1097    table per archive.  All trpgGeometry nodes point to that material table (with indices)
1098    for their trpgMaterial definitions.
1099 
1100    The material table has one wrinkle.  It is divided up into sub-tables or channels.
1101    Each sub-table has the same number of materials, so there will be NxM trpgMaterial
1102    structures in a trpgMatTable.  The sub-tables are intended for use in simple sensor
1103    simulations.  For example, the base table (0) is the purely visual, out the window
1104    representation.  The next table (1) might the Infra-Red version.  It's up to the run-time
1105    system to switch between these two.  TerraPage simply provides the means for keeping
1106    track of it.
1107 
1108    If you're doing a TerraPage reader you'll get a trpgMatTable from the trpgr_Archive.
1109    This is your central index for materials.  If you can handle the multiple channels/sub-tables
1110    then you can access those as you need.  If you can't, just use 0 for the sub-table index where appropriate.
1111 
1112    If you're doing a TerraPage writer you'll need to build up a trpgMatTable to pass to
1113    trpgwArchive.  If you're only doing a single sub-table (i.e. visible materials only)
1114    just use AddMaterial and add them as you go.  The trpgMaterial object you build up
1115    for a given material are copied when you call the add function.  So you can have a single
1116    trpgMaterial, modify just a few fields and call AddMaterial repeatedly.
1117    {group:Read/Write Classes}
1118 */
1119 TX_EXDECL class TX_CLDECL trpgMatTable : public trpgReadWriteable
1120 {
1121 public:
1122     trpgMatTable(void);
1123     ~trpgMatTable(void);
1124     /* If you intend to have more than one material sub-table you'll
1125        need to set this first before doing anything else.
1126     */
1127     void    SetNumTable(int);
1128     /* This sets the total number of materials.  Each sub-table will
1129        have this many of its own materials.  If you call this function
1130        you can't use AddMaterial.
1131     */
1132     void    SetNumMaterial(int);
1133     /* Sets a material definition for the given sub-table material ID
1134        combination.  If you only have one sub-table you can use
1135        AddMaterial instead.
1136        The two argument version assumes subTable = 0
1137     */
1138     //void    SetMaterial(int subTable,int mat,const trpgMaterial &);
1139     void    SetMaterial(int,const trpgMaterial &);
1140 
1141     /* This function should be used if you only have a single material sub-table.
1142        It searches for a matching material and then adds a new one if it doesn't
1143        find a match.  The new (or old) ID is returned.
1144     */
1145     int        AddMaterial(const trpgMaterial &,bool lookForExisting=true);
1146 
1147 
1148     // The following method is unused currently
1149     /* This function should be used when adding materials to multiple sub-tables.
1150        It searches for a matching material and then adds a new one if it doesn't
1151        find a match.  The new (or old) ID is returned.
1152     */
1153     //int    AddMaterialInSubtable(const trpgMaterial &,int table,bool lookForExisting=true);
1154 
1155     /* Return the number of sub-tables.  This will, most commonly, be 1.
1156        Any value more than 1 means the archive has alternate material definitions
1157        (think IR or Radar versions).
1158     */
1159     bool    GetNumTable(int &) const;
1160     /* The number of materials per sub-table.  Each sub-table has the same number
1161        of materials.  So there will be N x M number of materials total, but you'll
1162        only see M of them at any given time.
1163     */
1164     bool    GetNumMaterial(int &) const;
1165 
1166     /* Returns the material definition for the given subTable and the given material
1167        ID.  The most common subTable will be 0 (visual).  The material ID comes
1168        from the value(s) in trpgGeometry.
1169     */
1170     bool    GetMaterial(int subTable,int matID,trpgMaterial &) const;
1171 
1172     /* This is a convenience method for getting a reference to a trpgMaterial object.
1173        The reason you might want to do this is if you don't want to create a full
1174        trpgMaterial object to pass to GetMaterial.
1175        The returned value is only valid until the next GetMaterialRef call.
1176     */
1177     const trpgMaterial *GetMaterialRef(int,int) const;
1178 
1179     // Validity check
1180     bool    isValid(void) const;
1181     // Resets the contents back to empty
1182     void    Reset(void);
1183 
1184     // Writes this class to a write buffer
1185     bool    Write(trpgWriteBuffer &);
1186     // Reads this class from a read buffer
1187     bool    Read(trpgReadBuffer &);
1188     // Prints this class to a print buffer
1189     bool    Print(trpgPrintBuffer &) const;
1190 
1191 
1192 protected:
1193     int numTable;
1194     int numMat;
1195     typedef std::map<int,trpgMaterial> MaterialMapType;
1196     MaterialMapType materialMap;
1197 };
1198 
1199 /* This class holds the texture definition TerraPage uses.  Textures are a little
1200    different than other TerraPage objects for the following reason: they aren't
1201    stored in the archive.  Instead they're stored individually on disk in your
1202    favorite image format.  We don't constrain what that format is, although SGI
1203    format (.rgb) is always the safest in this industry.
1204 
1205    Texture objects are really just references to these on-disk textures.  As such,
1206    they're pretty simple.  They just consist of a filename.  These trpgTexture
1207    objects will be indexed in a trpgTexTable.  The indices you get from trpgMaterial
1208    objects point to trpgTexture objects through that table.  trpgMaterial objects
1209    should be the only things that have texture indices.
1210 
1211    If you're doing a TerraPage reader textures are pretty simple to read in.  There
1212    are two ways to do it.  First, if you're not doing texture paging, simply read
1213    them all in, using the trpgTexTable to figure out where they all are.  If you
1214    are doing texture paging (highly recommended) then you'll need to call GetNumTile
1215    to figure out how many tiles a texture is used in.  If it's 1, then this is probably
1216    a geospecific textures and ought to be paged.  If it's more than 1, then it's a
1217    geotypical texture (i.e. a tree or road) and should be loaded in at the beginning.
1218 
1219    If you're doing a TerraPage writer you'll need to be creating trpgTexture objects
1220    as you go and adding them to your central trpgTexTable.  If you want to support
1221    texture paging set the numTile count to 1 for the geospecific textures and more
1222    than 1 for everything else.  There are utility functions for keeping track of all
1223    of this.  It's best to use those.
1224    {group:Read/Write Classes}
1225 */
1226 TX_EXDECL class TX_CLDECL trpgTexture : public trpgReadWriteable
1227 {
1228 public:
1229     trpgTexture(void);
1230     trpgTexture(const trpgTexture &);
1231     ~trpgTexture(void);
1232 
1233     /* This enum is used to determine where the image is.
1234        External - Stored in an external file, just like TerraPage 1.x.
1235        Local - Stored in one of the archive files.  The type and size will be here.
1236        Use trpgrImageHelper to fetch the image, either initially or later.
1237        Global - This image is really large and parts of it will be referenced
1238        later within individual tiles.  Use the trpgrImageHelper class
1239        to reference the various parts of the image.  Don't load it yourself.
1240        Template - This isn't an image at all.  It's here to represent a class of
1241        images with a certain size and type.  You'll encounter inline materials
1242        (for pageable textures) in the tiles which make use of this template.
1243        If you use trpgrImageHelper to fetch those textures, you don't need to
1244        do anything with this texture.
1245     */
1246     typedef enum {External,Local,Global,Template} ImageMode;
1247 
1248     /* These are the types of images TerraPage can support for Local and Template
1249        image modes (see ImageMode).  If the image is External or Global, anything
1250        is fair game, but these are the only types TerraPage can store itself.
1251     */
1252     typedef enum
1253     {
1254         trpg_RGB8,
1255         trpg_RGBA8,
1256         trpg_INT8,
1257         trpg_INTA8,
1258         trpg_FXT1,
1259         trpg_Filler,  // This is not a texture format.  It's here to keep the numbering consistent
1260         trpg_RGBX, // MCM no longer
1261         trpg_Unknown,
1262         trpg_DDS,
1263         trpg_DXT1,
1264         trpg_DXT3,
1265         trpg_DXT5,
1266         // This is a bit ugly, but we can't change the size of the texture record without
1267         // breaking existing readers.  So there will be multiple MCM types to indicate the number
1268         // of bands and the nature of the extra channels, if any
1269         trpg_MCM5,
1270         trpg_MCM6R,
1271         trpg_MCM6A,
1272         trpg_MCM7RA,
1273         trpg_MCM7AR
1274     } ImageType;
1275 
1276     // Set the texture name.
1277     void    SetName(const char *);
1278     /* This is the texture name.  You pass in a string of a pre-defined length
1279        and it returns the texture name in that. */
1280     bool    GetName(char *retStr,int strLen) const;
1281 
1282     /* Sets the number of tiles this texture is used in.  This hint is used by
1283        readers to determine texture pageability. */
1284     void    SetNumTile(int);
1285     /* Instead of calling SetNumTile after you've built a database, you can call
1286        AddTile as you encounter each texture reference (per tile). */
1287     void    AddTile(void);
1288 
1289     /* This tells you the number of tiles this texture is used in.  You can
1290        use this to do texture paging (if you can support it).  It's a pretty
1291        general meachanism and will work for large scale geospecific terrain textures
1292        as well as things like specific building pictures.
1293        When GetImageMode returns Global, expect this value to always be 1.  For
1294        Template texture, it will be set to the total number of uses of the template
1295        (which should be fairly large).
1296     */
1297     bool    GetNumTile(int &) const;
1298 
1299     // Retrieve the image mode for this texture.  See ImageMode for details.
1300     bool    GetImageMode(ImageMode &) const;
1301 
1302     // Retrieve the image type for this texture.  See ImageType for details.
1303     // This method is only used if ImageMode is Local or Template
1304     bool    GetImageType(ImageType &) const;
1305 
1306     // Retrieve the size of this image. Valid only for Local and Template textures.
1307     bool    GetImageSize(trpg2iPoint &) const;
1308 
1309     // Get the location of a Local image
1310     bool    GetImageAddr(trpgwAppAddress &) const;
1311 
1312     // Figure out the image depth from the type
1313     bool    GetImageDepth(int32 &depth) const;
1314 
1315     // Determine whether this image (must be Local or Template) has all its mipmaps
1316     bool    GetIsMipmap(bool &) const;
1317 
1318     // Set the image mode of this texture.  Used by writers only.
1319     void    SetImageMode(ImageMode);
1320 
1321     // Set the image type of this texture.  See GetImageType for details.
1322     void    SetImageType(ImageType);
1323 
1324     // Set the image size of this texture.  See GetImageSize for details
1325     void    SetImageSize(const trpg2iPoint &);
1326 
1327     // Set the image location (For Local images only)
1328     void    SetImageAddr(const trpgwAppAddress &);
1329 
1330     // Set whether or not this is a full set of mipmaps
1331     void    SetIsMipmap(bool);
1332 
1333     // Set the storage sizes for all mipmap levels
1334     //    void    SetStorageSizes(vector<int> &);
1335 
1336     // Get the storage sizes for all mipmap levels.
1337     //    bool    GetStorageSizes(const vector<int> *) const;
1338 
1339     // Set the number of mipmap levels
1340     void    SetNumMipmap(int);
1341 
1342     // Set the number of layers used in an RGBX image
1343     void    SetNumLayer(int);
1344 
1345     // Get the number of layers used in an RGBX image.  RGBX images are typically for
1346     //  sensors and contain arbitrary data which is not visual.
1347     bool    GetNumLayer(int &) const;
1348 
1349     /* Utility to figure out the number of mipmap levels this image would have.
1350        Only really necessary for Local or Template images.
1351     */
1352     int32    CalcNumMipmaps() const;
1353 
1354     // Calculate the total size of this texture
1355     int32    CalcTotalSize() const;
1356 
1357     // Returns the size of a given mip level
1358     int32    MipLevelSize(int miplevel);
1359 
1360     // Returns the offset of the mip level in the whole texture data buffer
1361     int32    MipLevelOffset(int miplevel);
1362 
1363     // Validity check
1364     bool    isValid(void) const;
1365     // Resets the contents back to empty
1366     void    Reset(void);
1367 
1368     // Writes this class to a write buffer
1369     bool    Write(trpgWriteBuffer &);
1370     // Reads this class from a read buffer
1371     bool    Read(trpgReadBuffer &);
1372     // Prints this class to a print buffer
1373     bool    Print(trpgPrintBuffer &) const;
1374 
1375     trpgTexture & operator = (const trpgTexture &);
1376     int operator == (const trpgTexture &) const;
1377 protected:
1378     // Mode for this texture.  See ImageMode for details
1379     ImageMode mode;
1380 
1381     // Type of texture (only valid if ImageMode is Local or Template)
1382     ImageType type;
1383 
1384     // The name really only has meaning for External or Global textures
1385     char *name;
1386     int useCount;
1387 
1388     // The size values are used only if this is a Local or Template image
1389     int sizeX,sizeY;
1390 
1391     // Whether or not there are mipmap levels
1392     bool isMipmap;
1393 
1394     // Number of mipmap levels, 0 if not present
1395     int numMipMap;
1396 
1397     // Number of layers (for RGBX)
1398     int numLayer;
1399 
1400     // Sizes of each level.  This is important for compressed textures in particular,
1401     //  which may have random sizes.  Used only for Local textures.
1402     std::vector<int> storageSize;
1403 
1404     // Offset of each level
1405     std::vector<int> levelOffset;
1406 
1407     // Address is used only for Local textures
1408     trpgwAppAddress addr;
1409 
1410     // calculate the mip level sizes
1411     void CalcMipLevelSizes();
1412 };
1413 
1414 /* The texture table keeps track of all the textures in a TerraPage archive.
1415    All textures are indexed centrally here.  The indices in trpgMaterial objects
1416    point into a trpgTexTable.  Although the trpgMatTable potentially has several
1417    sub-tables for different representations (visual, IR, etc..), the trpgTexTable
1418    is not affected by that.  All textures, no matter what their use, are indexed
1419    together here.
1420 
1421    If you're doing a TerraPage reader you'll get a trpgTexTable back from your
1422    trpgr_Archive.  You'll then want to iterate over the trpgTexture objects and
1423    load in the ones used in more than one tile.  If you can do texture paging
1424    you should leave the ones only used in 1 tile alone initially.  You may also
1425    want to set up a mapping from texture indices here into whatever your own texture
1426    repository is.  The texture indices in trpgMaterial objects refer to the listing
1427    here.
1428 
1429    If you're doing a TerraPage writer you'll want to create one of these and add
1430    textures as you go.  Textures are copied in when you call AddTexture or SetTexture
1431    so you can reused the trpgTexture object you put together to pass in.  The texture
1432    index returned by AddTexture should be used in the trpgMaterial you'll need to build.
1433    Textures don't live in isolation and must be applied to geometry through a trpgMaterial.
1434    After the trpgTexTable is built it will get passed to a trpgwArchive for writing.  That
1435    can be done right before you close the archive.
1436    {group:Read/Write Classes}
1437 */
1438 TX_EXDECL class TX_CLDECL trpgTexTable : public trpgReadWriteable
1439 {
1440 public:
1441     trpgTexTable(void);
1442     trpgTexTable(const trpgTexTable &);
1443     ~trpgTexTable(void);
1444 
1445     /* Sets the total number of textures in this table.  This is used in
1446        combination with SetTexture.  If you can, you should use AddTexture
1447        and FindAddTexture instead.
1448     */
1449     void    SetNumTextures(int);
1450     /* Adds the given texture to the table and increments the total texture
1451        count.  If you use this, you should not use SetNumTextures and SetTexture.
1452     */
1453     int        AddTexture(const trpgTexture &);
1454     /* This is the same as AddTexture except that it searches for a matching texture
1455        first.  This is convenient for writers who aren't keeping track of their
1456        own textures internally.
1457     */
1458     int        FindAddTexture(const trpgTexture &);
1459     /* This sets the given texture ID to be the trpgTexture passed in.  It's used
1460        in combination with SetNumTextures.  Use AddTexture or FindAddTexture instead
1461        if you can.
1462     */
1463     void    SetTexture(int texID,const trpgTexture &);
1464 
1465     // Returns the number of textures in this table
1466     bool    GetNumTextures(int &) const;
1467     // This returns the trpgTexture corresponding to the given ID (from a trpgMaterial)
1468     bool    GetTexture(int texID,trpgTexture &) const;
1469     /* Does the same thing as GetTexture only it returns a pointer instead.
1470        You would use this if you don't want a new trpgTexture created for you.
1471        Assume the value it returns is only good until the next GetTextureRef call.
1472     */
1473     const trpgTexture *GetTextureRef(int) const;
1474 
1475     // Validity check
1476     bool    isValid(void) const;
1477     // Resets the contents back to empty
1478     void    Reset(void);
1479 
1480     // Writes this class to a write buffer
1481     bool    Write(trpgWriteBuffer &);
1482     // Reads this class from a read buffer
1483     bool    Read(trpgReadBuffer &);
1484     // Prints this class to a print buffer
1485     bool    Print(trpgPrintBuffer &) const;
1486 
1487 
1488     trpgTexTable & operator = (const trpgTexTable &);
1489     const trpgTexture *FindByName(const char *name, int &texid) const;
SetCurrentBlock(int row,int col)1490     void    SetCurrentBlock(int row, int col)
1491     {
1492         currentRow = row;
1493         currentCol = col;
1494     }
1495 
1496     //bool dumpGeoTypicalTextures(trpgwImageHelper *ihelper);
1497     typedef std::map<int,trpgTexture> TextureMapType;
getTextureMap()1498     TextureMapType *getTextureMap()
1499     {
1500         return &textureMap;
1501     }
1502 protected:
1503 
1504     TextureMapType textureMap;
1505     //These are used to initialize the row/col values for
1506     //multi-archive archives
1507     int currentRow;
1508     int currentCol;
1509 
1510 };
1511 
1512 /* Models are basically just references in TerraPage.  This class just points
1513    to a model from somewhere else.  There are two places it can point.  (1) It
1514    can point externally to a model in some arbitrary format (OpenFlight(tm) is
1515    a popular one).  (2) It can also point to a model within the TerraPage archive.
1516    The first case is much like trpgTexture objects are treated.  That is, the actual
1517    thing itself is on disk somewhere corresponding to a file name.  The second case is
1518    more like tile terrain geometry.  In that case there is scene node type data (LODs,
1519    groups, geometry, etc...) associated with it.
1520 
1521    trpgModel objects live within a trpgModelTable.  They are indexed there and referred
1522    to by trpgModelRef objects.  Those model references are the only things that explicitly
1523    use trpgModel objects.
1524 
1525    If you're doing a TerraPage reader you'll need to take into account whether the
1526    model is external or internal.  If it's external you'll need to read the given file
1527    and convert it to your own representation.  If it's internal you've probably already
1528    got the code for dealing with terrain tiles, which is essentially the same thing.
1529    Models can be paged, if you're so inclined.  They have tile reference counts just
1530    like trpgTexture objects.  If numTile == 1 then page it, if > 1 then don't.
1531 
1532    If you're doing a TerraPage writer you'll want to build up a trpgModelTable of these
1533    as you encounter them.  If your models are external in some other format then setting
1534    up a trpgModel is pretty easy.  If you want to do internal models, the support is not
1535    quite there yet.
1536    {group:Read/Write Classes}
1537 */
1538 TX_EXDECL class TX_CLDECL trpgModel : public trpgReadWriteable
1539 {
1540 public:
1541     trpgModel(void);
1542     trpgModel(const trpgModel &);
1543     ~trpgModel(void);
1544     enum {Local,External};
1545     // Sets the name of the external model file and sets this model to External type.
1546     // 5.28.04 - It will not set the model to be as of external type. Use the method
1547     // from below to set the type of the model
1548     void    SetName(const char *);
1549     // Sets the on-disk reference to an internal model and sets this model to Internal type.
1550     // 5.28.04 - It will not set the model to be as of internal type. Use the method
1551     // from below to set the type of the model
1552     void    SetReference(trpgDiskRef);
1553     // Sets the model type
1554     void    SetType(int);
1555     /* Models are reference counted (per-tile).  It's up to the writer to set this
1556        value.  */
1557     void    SetNumTiles(int);
1558     /* TerraPage writers can use AddTile (starts at 0) every time they use this model
1559        in a tile.  Note that this is not for every instance within a tile.  So if
1560        you use a model 40 times within a tile, you call AddTile once.
1561        This is used instead of SetNumTiles. */
1562     void    AddTile(void);
1563 
1564     /* Returns the type (Local or External) of this model */
1565     bool    GetType(int &);
1566     /* If the model is external, this returns the file name of that model.
1567        You pass in a string and a length and it copies the filename into that. */
1568     bool    GetName(char *ret,int strLen) const;
1569     /* If the model is internal, this returns the disk reference to it.
1570        At some future data you'll be able to simply read these out of an archive. */
1571     bool    GetReference(trpgDiskRef &) const;
1572     /* Models are reference counted, like trpgTexture objects.  You can  use this
1573        value to determine whether or not you should page models.
1574     */
1575     bool    GetNumTiles(int &) const;
1576 
1577     // Validity check
1578     bool    isValid(void) const;
1579     // Resets the contents back to empty
1580     void    Reset(void);
1581 
1582     // Writes this class to a write buffer
1583     bool    Write(trpgWriteBuffer &);
1584     // Reads this class from a read buffer
1585     bool    Read(trpgReadBuffer &, bool);
1586     // Prints this class to a print buffer
1587     bool    Print(trpgPrintBuffer &) const;
1588 
1589 
1590     trpgModel & operator =  (const trpgModel &);
1591     int operator == (const trpgModel &) const;
1592 
1593 
1594 protected:
1595     int type;
1596     char *name;
1597     trpgDiskRef diskRef;
1598     int useCount;
1599 };
1600 
1601 /* Models (trpgModel) are indexed together in a model table.  There is one
1602    model table per TerraPage archive.  It holds the canonical list of models
1603    for the entire database.  It's pretty simple.  Just a list of models, really.
1604    the trpgModel object holds the real information.
1605 
1606    If you're doing a TerraPage reader you'll get one of these from a trpgr_Archive.
1607    You'll want to iterate over the models in it and figure out which ones to page,
1608    if you're doing model paging.  If not, then you can just read them all in
1609    at initialization time and index them as need per-tile.
1610 
1611    If you're doing a TerraPage writer you'll build one of these up for the entire
1612    database as you go.  Just call AddModel every time you finish a model definition.
1613    The finished table will be passed to trpgwArchive at the end.
1614    {group:Read/Write Classes}
1615 */
1616 TX_EXDECL class TX_CLDECL trpgModelTable : public trpgReadWriteable
1617 {
1618 public:
1619     trpgModelTable(void);
1620     ~trpgModelTable(void);
1621 
1622     /* Set the total number of models in the table.  Use this in conjunction
1623        with SetModel.  If you can, use AddModel isntead of either of these.
1624     */
1625     void    SetNumModels(int);
1626     /* Add the given model to the table.  Makes a copy of the model you pass in
1627        and returns the new model ID which you'll need to reference in trpgModelRef.
1628     */
1629     int        AddModel(trpgModel &);
1630     /* Look for a given model.  If it's not there, add it. */
1631     int        FindAddModel(trpgModel &);
1632     /* Sets the model definition corresponding to the given ID.  Use this in conjunction
1633        with SetNumModels. */
1634     void    SetModel(int,const trpgModel &);
1635 
1636     // Returns the number of models in this table
1637     bool    GetNumModels(int &) const;
1638     /* Returns the Nth model.  trpgModelRef objects point into this table
1639        and that is where the model ID comes from. */
1640     bool    GetModel(int modID,trpgModel &) const;
1641 
1642     /* The same as GetModel only it returns a pointer to the trpgModel instead.
1643        Use this if you don't want to create a copy of the model.
1644        The result is only good until the next GetModelRef call.
1645     */
1646     trpgModel *GetModelRef(int);
1647 
1648     // Validity check
1649     bool    isValid(void) const;
1650     // Resets the contents back to empty
1651     void    Reset(void);
1652 
1653     // Writes this class to a write buffer
1654     bool    Write(trpgWriteBuffer &);
1655     // Reads this class from a read buffer
1656     bool    Read(trpgReadBuffer &);
1657     // Prints this class to a print buffer
1658     bool    Print(trpgPrintBuffer &) const;
1659 
1660     bool FindByName(const char *name, unsigned int &mId);
1661     typedef std::map<int,trpgModel> ModelMapType;
GetModelMap()1662     ModelMapType *GetModelMap()
1663     {
1664         return &modelsMap;
1665     }
1666 protected:
1667 
1668     ModelMapType modelsMap;
1669 };
1670 
1671 /* The tile table keeps track of tile locations within a TerraPage archive.
1672    Tiles can be stored either externally (as individual files) or locally
1673    (grouped together into bigger files).  The details are hidden from the
1674    reader completely and the writer in most cases.
1675    In version 2.1 the tile table only contains the location of lod 0 tiles.
1676    All other tiles location are stored in the parent tile as trpgChildRef
1677    nodes, so you need to parse the parent tile to get at them.
1678    {group:Read/Write Classes}
1679 */
1680 TX_EXDECL class TX_CLDECL trpgTileTable : public trpgReadWriteable
1681 {
1682 public:
1683     // Tiles can be stored individually (External and ExternalSaved) or in grouped files (Local).
1684     // ExternalSaved still have an entry in the table. In this case the address data is not valid.
1685 
1686     enum TileMode {Local,External, ExternalSaved};
1687 
1688     trpgTileTable();
1689     ~trpgTileTable(void);
1690 
1691     // Set the tile storage mode: external or local
1692     void    SetMode(TileMode);
1693     // Set the total number of LODs
1694     // For version 2.1 only lod 0 is stored in the table
1695     void    SetNumLod(int numLod);
1696     // Set the number of tiles in each dimenion for each terrain LOD
1697     // This must agree with trpgHeader
1698     void    SetNumTiles(int numX,int numY,int lod);
1699     // Set the external address of a given tile as well as its Z value
1700     void    SetTile(int x,int y,int lod,trpgwAppAddress &,float32 min,float32 max);
1701 
1702     // Local or external tiles
1703     bool    GetMode(TileMode &) const;
1704     // Get the disk reference (local)
1705     bool    GetTile(int x,int y,int lod,trpgwAppAddress &,float32 &min,float32 &max) const;
1706 
1707     // Validity check
1708     bool    isValid(void) const;
1709     // Reads this class from a read buffer
1710     void    Reset(void);
1711 
1712     // Writes this class to a write buffer
1713     bool    Write(trpgWriteBuffer &);
1714     // Reads this class from a read buffer
1715     bool    Read(trpgReadBuffer &);
1716     // Prints this class to a print buffer
1717     bool    Print(trpgPrintBuffer &) const;
1718     /**
1719      * SetCurrentBlock is used in two cases:
1720      * 1. When building a block specific tile archive (MMB and non-MMB). (local is TRUE)
1721      * 2. When merging several blocks into memory for visualization. (local is FALSE)
1722      **/
SetCurrentBlock(int row,int col,bool local)1723     void    SetCurrentBlock(int row, int col, bool local)
1724     {
1725         currentRow = row;
1726         currentCol = col;
1727         localBlock = local;
1728     }
1729 protected:
1730     TileMode mode;
1731 
1732     class LodInfo
1733     {
1734     public:
1735         int numX,numY;
1736         // Tile addresses into external Appendable files
1737         std::vector<trpgwAppAddress> addr;
1738         // Elevation of the midpoint of each tile
1739         // This is used for calculating bounding boxes
1740         std::vector<float> elev_min;
1741         std::vector<float> elev_max;
1742     };
1743     std::vector <LodInfo> lodInfo;
1744     //These are used to initialize the row/col values for
1745     //multi-archive archives
1746     int currentRow;
1747     int currentCol;
1748     bool localBlock; // if true, this tile table should only contain entries for one block.
1749 };
1750 
1751 
1752 /* Local materials are new to TerraPage 2.0.
1753    The idea is that for pageable one-time textures it makes more sense
1754    to define them in the tiles.  This keeps the size of Texture and
1755    Material tables down in the header.  It also lets us make use of
1756    Global textures by grabbing subimages.
1757    You'll encounter these in a tile right after the tile header.  They'll
1758    be referenced by ID in trpgGeometry nodes within that tile.  They
1759    can represent a sub-image of a Global texture or a whole Local texture.
1760    In either case, you can pass this class to trpgrTextureHelper and let
1761    it get the image data for you.
1762 */
1763 TX_EXDECL class TX_CLDECL trpgLocalMaterial : public trpgReadWriteable
1764 {
1765 public:
1766     trpgLocalMaterial(void);
1767     ~trpgLocalMaterial(void);
1768 
1769     // Set the base material for this local material
1770     void    SetBaseMaterial(int32 matSubTable,int32 matID);
1771 
1772     /* Get the base material for this local material.  Base materials
1773        define the colors, specularity, texture environments, and in
1774        general everything not having to do with the texture image itself.
1775        In effect you're using the base material as your material definition and
1776        the local material is just telling you what part of the image to use.
1777        By convention, there should only be one global image used in any given
1778        trpgMaterial and it should be at texture index 0 (within that trpgMaterial).
1779        If you want to use multiple pageable textures per polygon, you can do
1780        that with multiple materials per trpgGeometry node.  Doing it any
1781        other way makes my head hurt (actually the thought of multiple, pageable
1782        textures per polygon makes my head hurt in general).
1783        // 2003-06-17.  Your prophecy (my headache) has come true.  MD
1784        */
1785     bool    GetBaseMaterial(int32 &matSubTable,int32 &matID) const;
1786 
1787     class SubImageInfo
1788     {
1789     public:
1790         int32 sx,sy;  // Source (sx,sy) in pixels
1791         int32 ex,ey;  // Source (ex,ey) in pixels
1792         int32 destWidth,destHeight;  // Size of destination image (in pixels)
1793     };
1794 
1795     // Set the sub image info (only for writers)
1796     void    SetSubImageInfo(const SubImageInfo &);
1797 
1798     /* Get the sub image info.  This is valid only for Global images
1799        (you can check what a given Local Material is by looking at the
1800        base material's texture).
1801     */
1802     bool    GetSubImageInfo(SubImageInfo &) const;
1803 
1804     // Set the address info (only for writers)
1805     void    SetAddr(const trpgwAppAddress &);
1806 
1807     // Set address info for one of multiple local textures
1808     void    SetNthAddr(unsigned int subtable, const trpgwAppAddress &);
1809 
1810     /* Get the address (location in an archive) for an image.
1811        This is valid for Local images only.  You can determine what
1812        a Local Material refers to by looking in its base material's texture.
1813     */
1814     bool    GetAddr(trpgwAppAddress &) const;
1815 
1816     // Get address info for one of multiple local textures
1817     bool    GetNthAddr(unsigned int subtable, trpgwAppAddress &) const;
1818 
1819     // Get the number of local images associated with this local material
1820     // Tile Local Images only
1821     bool    GetNumLocals(int &) const;
1822 
1823     // Set the storage sizes for all mipmap levels
1824     //    bool    SetStorageSizes(vector<int> &);
1825 
1826     // Get the storage sizes for all mipmap levels.
1827     //    bool    GetStorageSizes(const vector<int> *) const;
1828 
1829     // Validity check
1830     bool    isValid(void) const;
1831     // Reads this class from a read buffer
1832     void    Reset(void);
1833 
1834     // Writes this class to a write buffer
1835     bool    Write(trpgWriteBuffer &);
1836     // Reads this class from a read buffer
1837     bool    Read(trpgReadBuffer &);
1838     // Prints this class to a print buffer
1839     bool    Print(trpgPrintBuffer &) const;
1840 
1841 protected:
1842     int32 baseMatTable,baseMat;
1843     // These are valid for Global images
1844     int32 sx,sy,ex,ey,destWidth,destHeight;
1845     // Storage sizes for each mipmap level.  Important for compressed textures.
1846     //    vector<int> storageSize;
1847     // This is valid only for Tile Local images
1848     std::vector<trpgwAppAddress> addr;
1849 };
1850 
1851 /* The tile header is one of the more interesting parts of TerraPage.  Basically,
1852    it's a list of all the materials, local material  and models used in a tile.
1853    Tile headers are stuck at the beginning of terrain tiles to give you this
1854    information.  They can be read separately, in theory, although no one is doing
1855    that at present.
1856 
1857    If you're doing a TerraPage reader you will encounter one of these first thing
1858    when you parse a terrain tile.  These are here to aid texture and model paging.
1859    Texture paging is the most common and there are now two ways of doing it.  The
1860    simpler one (supported in version 1.0) is as follows.  Textures are indexed at
1861    the beginning of a TerraPage archive (in a trpgTexTable) and when listed in the
1862    trpgTileHeader for a tile must be loaded in for use.  You can tell the pageable
1863    textures from the non-pageable ones by looking at the tile reference count in
1864    the trpgTexture object.
1865 
1866    The second way of doing texture paging (in version 2.0) is more complex, but
1867    much more powerful.  One of the big problems we encountered with v1.0 was the
1868    enormous proliferation of texture files.  In addition, much information was
1869    duplicated between the different terrain resolutions.  Lastly, we (TERREX) have
1870    had a lot of success with wavelet compressed image pyramids for solving quite a
1871    few interesting problems.  This second approach to texture paging makes use of
1872    what we've learned from all of this.  The idea is that instead of having lots of
1873    little textures, we have a small number of very large images which can support
1874    extraction at any resolution.  In this way we re-use information between terrain
1875    levels of detail and we cut down on our disk usage, both in terms of number of
1876    files as well as data size.
1877 
1878    To implement this scheme we added the trpgLocalMaterial object.  trpgTexture
1879    objects tell you if they are global images (e.g. parts are pageable).  If they
1880    are, then they can be used in a trpgLocalMaterial.  These objects define the
1881    sub-image (extents and a resolution) for a texture/material that can be used
1882    within this tile (and only within this tile).  The trpgLocalMaterial objects
1883    reside within the trpgTileHeader and should be filled out (e.g. the sub-images
1884    paged) as soon as the trpgTileHeader is parsed because you'll be needing them
1885    in trpgGeometry nodes to follow.
1886 
1887    If you want to page models, you can do so by looking at the list of model IDs
1888    used in a tile.
1889 
1890    If you're doing a TerraPage writer you will need to construct one of these for
1891    each tile that you build (remember that tiles are per-terrain LOD).  You'll want
1892    to call AddMaterial for every material that you use in a tile and AddModel
1893    for every model.  You can call these methods multiple times and it will keep track
1894    of whether you've already added a model or material.  The tile header will then
1895    be passed to trpgwArchive along with the tile geometry and written to disk.
1896    {group:Read/Write Classes}
1897 */
1898 TX_EXDECL class TX_CLDECL trpgTileHeader : public trpgReadWriteable
1899 {
1900 public:
1901     trpgTileHeader(void);
1902     ~trpgTileHeader(void);
1903     /* Add the given material reference to this tile if it's not already there.
1904        The ID passed in refers to a trpgMatTable. */
1905     void    AddMaterial(int);
1906     /* Add the given model reference to this tile if it's not already there.
1907        The ID passed in refers to a trpgModelTable. */
1908     void    AddModel(int);
1909     /* Add the given local material to the list of local materials in this tile.
1910        Local materials are used to page sub-pieces of very large images and
1911        are referenced by trpgGeometry nodes (in their material indices) within
1912        a given tile.  Local materials can't be referenced across tiles.
1913     */
1914     void    AddLocalMaterial(trpgLocalMaterial &);
1915     // {secret}
1916     void    SetDate(int32);
1917     /* Set the given material reference to the given value.
1918        It's easier to use AddMaterial(), if possible.
1919     */
1920     void    SetMaterial(int no,int id);
1921     /* Set the given model reference (in this tile) to the given value
1922        It's easier to use AddModel(), if possible.
1923     */
1924     void    SetModel(int no,int id);
1925 
1926     // Returns the number of materials used in this tile
1927     bool    GetNumMaterial(int32 &) const;
1928     /* Return the material ID of the Nth material reference.
1929        The ID returned points into a trpgMatTable. */
1930     bool    GetMaterial(int32 nth,int32 &matID) const;
1931     // This is the number of models used in this tile
1932     bool    GetNumModel(int32 &) const;
1933     /* Gets the model ID of the Nth model reference.
1934        The ID returned points into a trpgModelTable. */
1935     bool    GetModel(int32 nth,int32 &modID) const;
1936     // Returns the number of local materials in this tile
1937     bool    GetNumLocalMaterial(int32 &) const;
1938     /* Return the given local material.  Local materials are used
1939        to page sub-pieces of extremely large images.  The Local Material
1940        list within a tile is distinct from the list of materials used within
1941        a tile.  Local materials will be referenced by trpgGeometry nodes within
1942        a given tile.
1943     */
1944     bool    GetLocalMaterial(int32 nth,trpgLocalMaterial &locMat) const;
1945     /* Return a pointer to the list of locally defined materials.
1946        See GetLocalMaterial for an explanation of local materials.
1947     */
1948     const std::vector<trpgLocalMaterial> *GetLocalMaterialList(void) const;
1949     // {secret}
1950     bool    GetDate(int32 &) const;
1951 
1952     // Validity check
1953     bool    isValid(void) const;
1954     // Resets the contents back to empty
1955     void    Reset(void);
1956 
1957     // Writes this class to a write buffer
1958     bool    Write(trpgWriteBuffer &);
1959     // Reads this class from a read buffer
1960     bool    Read(trpgReadBuffer &);
1961     // Prints this class to a print buffer
1962     bool    Print(trpgPrintBuffer &) const;
SetBlockNo(int r,int c)1963     void    SetBlockNo(int r, int c)
1964     {
1965         row = r;
1966         col = c;
1967     }
GetBlockNo(int & r,int & c)1968     void    GetBlockNo(int &r, int &c)
1969     {
1970         r = row;
1971         c = col;
1972     }
1973 protected:
1974     std::vector<int> matList;
1975     std::vector<int> modelList;
1976     std::vector<trpgLocalMaterial> locMats;
1977     // {secret}
1978     int date;
1979     //These are used to find them in the block archive.
1980     int row;
1981     int col;
1982 };
1983 
1984 /* The color info structure is used by the trpgGeometry class to store
1985    per vertex (or per primitive) color information.  It can be read directly
1986    by the user (all its data is public).  This structure is returned by
1987    trpgGeometry::GetColorSet().
1988    {group:Read/Write Classes}
1989 */
1990 TX_EXDECL class TX_CLDECL trpgColorInfo
1991 {
1992 public:
1993     trpgColorInfo(void);
1994     ~trpgColorInfo(void);
1995 
1996     /* This is a trpgGeometry::ColorType
1997      */
1998     int type;
1999     /* This refers to how the colors in the data array are used.
2000        It can take the values "Overall", "PerPrim" or "PerVertex".
2001     */
2002     int bind;
2003     /* The list of colors.  There will be one total (bind=Overall), one per
2004        primitive (bind=PerPrim), or one per vertex (bind=PerVertex).
2005     */
2006     std::vector<trpgColor> data;
2007     /* Resets the structure to a default state.
2008      */
2009     void Reset(void);
2010 
2011     // Print out debugging info
2012     bool Print(trpgPrintBuffer &) const;
2013 };
2014 
2015 /*  This class represents a group of texture coordinates applied to a trpgGeometry
2016     class.  It is returned by trpgGeometry::GetTexCoordSet.  TerraPage supports
2017     multiple materials per polygon.  The way we implement this is as multiple
2018     materials on a trpgGeometry node.  The first material with be the "primary"
2019     and additional ones will be secondary and so on.
2020     To support this, we need multiple sets of texture coordinates.  That's what
2021     this structure is used for.
2022     {group:Read/Write Classes}
2023 */
2024 TX_EXDECL class TX_CLDECL trpgTexData
2025 {
2026 public:
2027     trpgTexData(void);
2028     ~trpgTexData(void);
2029     // This should always be set to PerVertex
2030     int bind;
2031     /* List of texture coordinates in 32 bit floating point.
2032        There should be one per vertex.  Either this or doubleData will be
2033        set, but never both.
2034     */
2035     std::vector<float32> floatData;
2036     /* List of texture coordinates in 64 bit floating point.
2037        There should be one per vertex.  Either this or floatData will be
2038        set, but never both.
2039     */
2040     std::vector<float64> doubleData;
2041     /* Initialize the texture coordinate data set with floating point or double values.
2042        num should correspond to the correct bind. */
2043     void set(int num,int bind,const float32 *);
2044     void set(int num,int bind,const float64 *);
2045     /* Resets the structure to a default state.
2046      */
2047     void Reset(void);
2048 
2049     // Print out debugging info
2050     bool Print(trpgPrintBuffer &) const;
2051 };
2052 
2053 /*  The trpgGeometry class represents a low level geometry node within the
2054     TerraPage "scene graph".  This is where the triangles (or quads, polygons, etc...)
2055     are actually kept.  If you're writing a TerraPage reader, you'll encounter a
2056     lot of these nodes.  If you're doing a writer, you'll need to construct them.
2057     You can use a trpgwGeomHelper to aid you in this process.
2058     We use data arrays to store lists of vertices, colors, texture coordinates, and
2059     normals.  These data arrays correspond pretty  closely to the respective OpenGL
2060     equivalents.
2061 
2062     In general, you'll want to do a GetPrimType() to figure out what primitive
2063     type (PrimType) a given node is holding.  It will typically be TriStrips,
2064     TriFans, or Triangles, but all the other types are valid as well.
2065     The next step is to get the vertices via a GetVertices() call and then get
2066     the normals and texture coordinates (via GetNormals() and GetTexCoordSet() calls).
2067     To get the material information call GetNumMaterial() (if you can support more
2068     than one texture per polygon) and then GetMaterial() for each material.  If you
2069     only support one material/texture per polygon then just do one GetMaterial() all.
2070     There's always guaranteed to be at least one material.
2071 
2072     It's a good idea to review the OpenGL specification for triangle arrays and
2073     such before diving into this structure.
2074     {group:Read/Write Classes}
2075 */
2076 TX_EXDECL class TX_CLDECL trpgGeometry : public trpgReadWriteable
2077 {
2078 public:
2079     trpgGeometry(void);
2080     ~trpgGeometry(void);
2081     typedef enum {Points,LineStrips,LineLoops,Lines,Polygons,TriStrips,
2082           TriFans,Triangles,QuadStrips,Quads} PrimType;
2083     // Set the primitive type for the geometry node
2084     void    SetPrimType(PrimType type);
2085     /* Some primitive types require lengths.  These include TriStrips and
2086        TriFans, but not Triangles, for example. */
2087     void    SetPrimLengths(int,const int *);
2088     /* Add a primitive length on to the end of the current primLength array.
2089        Use this if you're adding geometry one vertex at a time.
2090     */
2091     void    AddPrimLength(int);
2092     /* This just increments the number of primitives in the structure.  Use this
2093        if you're adding geometry one vertex at a time for a Triangle array, for example.
2094     */
2095     void    AddPrim(void);
2096     /* Set the total number of primitives.  You would use this only when the PrimType
2097        does not require primitive lengths (e.g. Triangles, but not TriStrips).  Use
2098        SetPrimLengths() or AddPrimLength() in that case.
2099     */
2100     void    SetNumPrims(int);  // Only when there are no primitive lengths
2101     /* This function sets the total number of materials applied to this group
2102        of geometry.  If you're only using one material, trpgGeometry defaults to
2103        1, so you can just do a SetMaterial() and ignore this.
2104     */
2105     void    SetNumMaterial(int);
2106     /* Set the given material instance (in this trpgGeometry node) to the given
2107        material ID.  The material ID is an index into a trpgMatTable.  You would
2108        need to do a SetNumMaterial() call first, before any number of SetMaterial()
2109        calls if there is more than one material.  If there is only one material,
2110        you can do a single SetMaterial(0,MatID) call.
2111        Negative materials IDs denote local material definitions (e.g. parts of
2112        a larger, paged image).  They will always be returned as positive by
2113        GetMaterial, however you must set them as negative so that GetMaterial
2114        can set its isLocal bit on return.
2115     */
2116     void    SetMaterial(int which,int matID,bool isLocal=false);
2117     /* This is the same as repeated SetMaterial() calls.
2118      */
2119     void    SetMaterials(int32 numMat,const int32 *matIDs);
2120     /* This adds the given material ID to the end of the material list.
2121        You can use this instead of SetNumMaterial() and SetMaterial().
2122     */
2123     int        AddMaterial(int matID);
2124 
2125     // These are primitive types used within the trpgGeometry structure.
2126     enum {VertexFloat,VertexDouble,NormalFloat,NormalDouble,
2127       Color,TextureFloat,TextureDouble,EdgeFlag};
2128 
2129     /* Used to tell some of the trpgGeometry methods what kind of
2130        data they're getting */
2131     typedef enum {FloatData,DoubleData} DataType;
2132 
2133     /* The SetVertices() methods will set either 32 or 64 bit floating
2134        point vertex arrays within the trpgGeometry structure.
2135        The num passed in is the number of vertices, not the number of individual
2136        floats or doubles (as with GetNumVertex).
2137     */
2138     void    SetVertices(int num,const float32 *);
2139     void    SetVertices(int num,const float64 *);
2140     /* This method will add a vertex to the end of the appropriate data array
2141        (either float or double, but never both).  You would use this method
2142        if you were building up a trpgGeometry structure vertex by vertex.
2143     */
2144     void    AddVertex(DataType type,trpg3dPoint &);
2145     /* Binding type used by colors, normals, and textures (just PerPrim).
2146      */
2147     typedef enum {Overall,PerPrim,PerVertex} BindType;
2148     /* The SetNormals() methods will set either the 32 or 64 bit floating
2149        point normal arrays within the trpgGeometry structure.
2150        The num of normals is determined by the bind type.  You should
2151        either set the 32 or 64 bit floating point arrays, but not both.
2152        num is the number of individual normals, not float values, unlike
2153        the GetNumNormal() call.
2154     */
2155     void    SetNormals(int num,BindType bind,const float32 *);
2156     void    SetNormals(int num,BindType bind,const float64 *);
2157     /* This method is used to add normals one by one of the given type.
2158        You would use this if you were adding geometry one vertex at a time
2159        in conjuntion with AddVertex().
2160     */
2161     void    AddNormal(DataType type,trpg3dPoint &);
2162     /* This constant is used to select the type of a color array
2163        passed to SetColors().
2164     */
2165     typedef enum {Ambient,Diffuse,Specular,Emission} ColorType;
2166     /* This method sets an array of color structures for a trpgGeometry node.
2167        The num should correspond to the bind type.  You can set as many of
2168        these color arrays as you like, they're simply stored in an array for
2169        later use.
2170     */
2171     void    SetColors(int num,ColorType type,BindType bind,const trpgColor *);
2172     /* The SetTexCoords() methods set a list of texture coordinates.  This
2173        essentially builds a trpgTexData class and pushes it onto the current
2174        list of texture coordinate sets.  Choose the appropriate method based
2175        on 32 or 64 bit floating point values.  num should be the number of
2176        texture coordinates, not the number of floats passed in.
2177 
2178        bind should be PerPrim in all cases.
2179     */
2180     void    SetTexCoords(int num,BindType bind,const float32 *);
2181     void    SetTexCoords(int num,BindType bind,const float64 *);
2182     /* This is the same as SetTexCoords(0,bind,NULL) */
2183     void    AddTexCoords(BindType bind);
2184     /* This method adds a texture coordinate to array n.  You would use
2185        this if you were adding vertices one at a time.
2186     */
2187     void    AddTexCoord(DataType type,trpg2dPoint &,int n=0);
2188     /* This method adds a texture coordinate to each trpgTexData.  You would use
2189        this if you were adding vertices one at a time with multiple materials.
2190     */
2191     void    AddTexCoord(DataType type,std::vector<trpg2dPoint> &pts);
2192     /* Edge flags are used by some primitives in OpenGL.  We don't typically
2193        use them, but they can be read and written with TerraPage.
2194     */
2195     void    SetEdgeFlags(int num,const char *);
2196 
2197     /* Returns the primitive type for this trpgGeometry structure.
2198      */
2199     bool    GetPrimType(PrimType &type) const;
2200     /* Number of primitives in this structure.  Primitives are things
2201        like a single triangle, a triangle strip or fan.  Some primitives
2202        require a primitive length array.
2203     */
2204     bool    GetNumPrims(int &num) const;
2205     /* This returns the primitive length array.  Some primitive types, like
2206        TriStrips or TriFans (but not Triangles) require a primitive length
2207        array to tell you how to break up the vertex/normal/texture/color
2208        arrays into individual primitives.  The array you pass in must be
2209        of a certain length (returned by GetNumPrims()) and will only be
2210        valid for some primitive types.
2211     */
2212     bool    GetPrimLengths(int *lenArray) const;
2213     /* TerraPage supports multiple materials per geometry set.  This method
2214        tells you how many are applied to this structure.  There will always
2215        be at least one.
2216     */
2217     bool    GetNumMaterial(int &num) const;
2218     /* Returns the material ID for a material instance.  num is the
2219        nth material instance.  matId is an index into a trpgMatTable.
2220        isLocal is true if the given material is local to this tile.
2221        Local materials are only used to page small pieces of a larger image.
2222     */
2223     bool    GetMaterial(int num,int32 &matID,bool &isLocal) const;
2224     /* This returns num_vertex.  The function returns the length
2225        of the vertex array dived by 3, which is the total number of
2226        vertices.
2227     */
2228     bool    GetNumVertex(int &num) const;
2229     /* The GetVertices() methods return a list of vertices in the given
2230        form (32 or 64 bit floating point).  These functions will convert to
2231        the appropriate format, just ask for the one you need.
2232        The length of the vertex array is determined by GetNumVertex(), which
2233        returns 3* the number of vertices.
2234     */
2235     bool    GetVertices(float32 *) const;
2236     bool    GetVertices(float64 *) const;
2237     /* This method lets you get an individual vertex.  The number of vertices
2238        can be determined by GetNumVertex()/3.
2239     */
2240     bool    GetVertex(int id,trpg3dPoint &) const;
2241     /* GetNumNormal() returns the number of normals.  See GetNumVertex()
2242        for an explanation of why.
2243     */
2244     bool    GetNumNormal(int &num) const;
2245     /* Much, like GetVertices(), these methods will copy the contents of
2246        the normal array into the array passed in.  They will convert the
2247        contents to the appropriate format (32 or 64 bit floating point).
2248        The length of the input array can be determined by GetNumNormal().
2249     */
2250     bool    GetNormals(float32 *) const;
2251     bool    GetNormals(float64 *) const;
2252     /* This returns the number of color sets in the trpgGeometry structure.
2253        There can be one color set per ColorType.  Color sets are either
2254        per vertex, per primitive, or per geometry unit (i.e. only one)
2255        arrays of color data.
2256     */
2257     bool    GetNumColorSets(int &num) const;
2258     /* This method fills out the trpgColorInfo class that you pass in.
2259        The number of color sets is determined by GetNumColorSets and
2260        the structure you passed can be reused (to save memory).
2261     */
2262     bool    GetColorSet(int id,trpgColorInfo *) const;
2263     /* Returns the number of texture coordinate sets.  There could (and
2264        should) be one texture coordinate set per material applied to this
2265        geometry.  Tex Coord sets can be retrieved with GetTexCoordSet.
2266     */
2267     bool    GetNumTexCoordSets(int &) const;
2268     /* This method returns the texture coordinate set specified by the given
2269        index.  GetNumTexCoordSets determines the total number of texture
2270        coordinate sets.
2271     */
2272     bool    GetTexCoordSet(int id,trpgTexData *) const;
2273     /* This method returns this trpgGeometry's texture coordinate set specified by the given
2274        index.  GetNumTexCoordSets determines the total number of texture
2275        coordinate sets.
2276     */
2277     const trpgTexData *GetTexCoordSet(int id) const;
2278     /* Returns the number of edge flags in this geometry node.
2279        Edge flags are used on certain primitive types, but are rather rare.
2280     */
2281     bool    GetNumEdgeFlag(int &num) const;
2282     /* This returns the edge flags for the current set of primitives.
2283      */
2284     bool    GetEdgeFlags(char *) const;
2285 
2286     // Returns true if the trpgGeometry structure is valid
2287     bool    isValid(void) const;
2288     // Resets the contents back to empty
2289     void    Reset(void);
2290 
2291     // Write self to a buffer
2292     bool    Write(trpgWriteBuffer &);
2293     // Read self from a buffer.  Check isValid() afterwards
2294     bool    Read(trpgReadBuffer &);
2295     // Prints this class to a print buffer
2296     bool    Print(trpgPrintBuffer &) const;
2297 
2298 protected:
2299     int primType;
2300     int numPrim;
2301     std::vector<int> primLength;
2302     std::vector<int> materials;
2303     std::vector<float> vertDataFloat;
2304     std::vector<double> vertDataDouble;
2305     int normBind;
2306     std::vector<float> normDataFloat;
2307     std::vector<double> normDataDouble;
2308     std::vector<trpgColorInfo> colors;
2309     std::vector<trpgTexData> texData;
2310     std::vector<char> edgeFlags;
2311 };
2312 
2313 /* This is a standard Group that you might see in any reasonable
2314    scene graph.  It holds a number of children.  TerraPage isn't
2315    actually a scene graph, it just represents one.  That means that there
2316    are no pointers to children here.  Instead you'll encounter this group
2317    while reading a terrain tile or model.  That tells you to create a group
2318    (or whatever you call it) in your own system and get read to dump child
2319    trees into it.  A push will follow this object, then the children (however
2320    deep they may be) then a pop.
2321 
2322    All groups have IDs.  These IDs are unique among groups and group-like things
2323    (i.e. LODs) and are used to hook trpgAttach geometry into a scene graph hierarchy
2324    as you page in higher terrain levels of detail.
2325 
2326    If you're doing a TerraPage reader, the group tells you to put together
2327    your generic container in a scene graph and get read for the push/children/pop.
2328    The NumChild field should tell you how many children will follow, but a writer
2329    can easily forget to put it, so be wary.  You'll also want to look at the group
2330    ID and build a mapping from that ID (look at the max group ID in trpgHeader) to
2331    your own group structure.  A trpgAttach is allowed to page itself into any group.
2332 
2333    If you're doing a TerraPage writer you'll create one of these, fill out the
2334    numChild hint, the group ID and then write it.  You'll then write a Push, then
2335    the children hierarchies (which can be anything) followed by a Pop.  You'll want
2336    to keep track of the group ID you assigned in case one of the children is a
2337    pageable chunk of terrain hierarchy.
2338    {group:Read/Write Classes}
2339 */
2340 TX_EXDECL class TX_CLDECL trpgGroup : public trpgReadWriteable
2341 {
2342 public:
2343     trpgGroup(void);
2344     virtual        ~trpgGroup(void);
2345     // Resets the contents back to empty
2346     virtual void    Reset(void);
2347 
2348     /* Set the total number of children this group will have */
2349     virtual void    SetNumChild(int);
2350     // Starting from 0, increments the number of children
2351     virtual int        AddChild(void);
2352     /* The writer is supposed to set this value to the number of
2353        children. */
2354     virtual bool    GetNumChild(int &) const;
2355 
2356     /* Set the group ID */
2357     virtual void    SetID(int);
2358     // Returns the group ID
2359     virtual bool    GetID(int &) const;
2360 
2361     /* Set the group name */
2362     void    SetName(const char* );
2363     // Returns the group name
2364     const char*        GetName(void) const;
2365 
2366     // Validity check
2367     virtual bool    isValid(void) const;
2368     // Writes this class to a write buffer
2369     virtual bool    Write(trpgWriteBuffer &);
2370     // Reads this class from a read buffer
2371     bool        Read(trpgReadBuffer &);
2372     // Prints this class to a print buffer
2373     bool        Print(trpgPrintBuffer &) const;
2374 
2375 protected:
2376     int id;
2377     int numChild;
2378     char* name;
2379 };
2380 
2381 /* Structurally, an attach is just like a trpgGroup.  It does everything a group
2382    does, plus a little bit more.  The attach node is how TerraPage does terrain
2383    database paging across LODs.
2384 
2385    In TerraPage we don't enfoced a terrain LOD structure.  Let's say you built
2386    your database as a quad-tree.  That is, there is one root tile per block,
2387    4 children, each of which has 4 of its own children etc...  That would imply
2388    a certain structure (4 children per tile until you reach the bottom).  That would
2389    also lock you into a database scheme (quad-tree).  However, let's assume that
2390    someone else wanted to do replacement LOD for their terrain.  That scheme works
2391    by having one child per tile.  If you want to support both of these then you're
2392    asking the reader to do a lot of thinking and you can pretty much assume that the
2393    one you don't test won't work.  We decided to avoid all that by coming up with a
2394    generic scene graph paging scheme.  It's a little more painfull, but once you deal
2395    with it you get whatever weird scheme the writer is using for free without having to
2396    think about it.
2397 
2398    Here's how it works.  Each trpgGroup and group-like structure (trpgLod for example)
2399    has a unique group ID.  You can have one trpgAttach at the start of a given terrain
2400    tile.  That trpgAttach can point to any group within the scene graph (with a group ID).
2401    Level of detail for the terrain is controlled by trpgLod nodes as if everything was
2402    loaded in all the time.  That is, you'll see the same thing no matter whether every node
2403    is loaded into memory or just the nearby ones.  The theoretical scene graph structure
2404    is the same no matter what.  It's the ranges in your trpgHeader that tell you when
2405    things ought to be loaded in, but the actual display logic is contained within the trpgLod
2406    objects.  It sounds complicated and it is... for the writer.  But for the reader it's
2407    really simple.
2408 
2409    If you're doing a TerraPage reader all you'll need to do is keep a mapping from group
2410    ID's to your own internal scene graph node representation.  Then when a trpgAttach shows
2411    up you can turn it into your own group-like thing and stuff it and its children into
2412    the scene graph.  When it wanders out of range (the trpgHeader tells you that for a given
2413    terrain LOD) you simply delete it.  If you out-run your paging you've got two options:
2414    (1) Display holes.  That's what will happen when the LOD above a given tile trpgAttach
2415    turns on without the children in memory; or (2) Don't switch LODs that don't have all
2416    their children loaded in yet.  Be aware that a trpgAttach inherits from trpgGroup and
2417    so can have trpgAttach children.  So don't absorb the trpgAttach even though it's extra
2418    hierarchy.  Also, don't make any assumptions that there is really terrain in a given
2419    tile.  The writer may have chosen to page buildings or trees.  You never know and there's
2420    no reason to assume.
2421 
2422    If you're doing a TerraPage writer this is slightly more complex than writing a normal
2423    format, depending on the structure of your internal scene graph.  If you don't want
2424    to write more than one pageable terrain LOD you can just ignore trpgAttach nodes.  This
2425    doesn't mean you can only have one terrain LOD, it only means they won't be pageable.
2426    If you do want to fully support it, what you'll need to
2427    do is give all your groups (or whatever will become groups) unique IDs, keeping in mind
2428    to update the trpgHeader max group ID as you go.  Start at the lowest terrain lod.  This
2429    one doesn't need to have a trpgAttach node since it's at the top.  Traverse toward
2430    the higher lods.  When you hit one, spit out a trpgAttach, giving it the group ID of
2431    the trpgGroup directly above it.  Then treat the node you just created as a trpgGroup
2432    (i.e. do its children as normal).  You will also need to keep the trpgTileHeader for
2433    each tile around.  It's best to index these by (x,y,lod) index.  You'll need to build
2434    that tile header up *just for this tile geometry*.  That means you have to stop adding
2435    material/model references when you start defining the next tile.  Depending on how you
2436    write out your scene graph it may make sense to keep a stack of trpgTileHeader and
2437    trpgMemWriteBuffer objects around indexed by tile (x,y,lod).
2438 
2439    {group:Read/Write Classes}
2440 */
2441 TX_EXDECL class TX_CLDECL trpgAttach : public trpgGroup
2442 {
2443 public:
2444     trpgAttach(void);
2445     ~trpgAttach(void);
2446     // Resets the contents back to empty
2447     void    Reset(void);
2448 
2449     // Set the parent of the group/LOD/whatever to attach to when loaded in
2450     void    SetParentID(int);
2451     // Retrieve the parent ID we'll need to attach this thing into the scene graph
2452     bool    GetParentID(int &) const;
2453 
2454     /* The writer is supposed to set this value to a unique position with relation
2455        to its parent group. */
2456     void    SetChildPos(int);
2457     /* The child position is a hint as to which child this is in its parent group.
2458        That is, if there are 3 children, of which this is one, then it could be
2459        at child position 0, 1, or 3 in its parent.  You can safely ignore this if
2460        you want to just this node to its parent's list of children. */
2461     bool    GetChildPos(int &) const;
2462 
2463     // Validity check
2464     bool    isValid(void) const;
2465     // Writes this class to a write buffer
2466     bool    Write(trpgWriteBuffer &);
2467     // Reads this class from a read buffer
2468     bool    Read(trpgReadBuffer &);
2469     // Prints this class to a print buffer
2470     bool    Print(trpgPrintBuffer &) const;
2471 
2472 protected:
2473     int parentID,childPos;
2474 };
2475 
2476 TX_EXDECL class TX_CLDECL trpgChildRef : public trpgReadWriteable
2477 {
2478 public:
2479     trpgChildRef();
2480     ~trpgChildRef();
2481     // Resets the contents back to empty
2482     void    Reset();
2483 
2484     // Set the tile grid location
2485     void SetTileLoc(int gx,int gy,int glod);
2486 
2487     // Get the tile grid location
2488     bool GetTileLoc(int &gx,int &gy,int &glod) const;
2489 
2490 
2491     void SetTileAddress(const trpgwAppAddress& gAddr);
2492     void SetTileAddress(int32 file, int32 offset);
2493     void SetTileZValue( float gZmin, float gZmax);
2494     bool GetTileAddress(int32& file, int32& offset) const;
2495     bool GetTileAddress(trpgwAppAddress& gAddr) const;
2496     bool GetTileZValue( float& gZmin, float& gZmax) const;
2497 
2498 
2499     // Validity check
2500     bool    isValid(void) const;
2501     // Writes this class to a write buffer
2502     bool    Write(trpgWriteBuffer &);
2503     // Reads this class from a read buffer
2504     bool    Read(trpgReadBuffer &);
2505     // Prints this class to a print buffer
2506     bool    Print(trpgPrintBuffer &) const;
2507 
2508 protected:
2509     // Grid Location
2510     int x,y,lod;
2511     // File Location
2512     trpgwAppAddress addr;
2513 
2514     float zmin, zmax;
2515 
2516 };
2517 
2518 /* The billboard inherits from the standard trpgGroup.  It tells the reader that
2519    everything underneath this node is supposed to be treated like a stamp or billboard
2520    (depending on your terminology).  That means it's supposed to be rotated towards
2521    the eye point in some way.  There are no restrictions on the number, depth, or type
2522    of children.  In theory you could have another billboard as a child, although we have
2523    no idea what that should look like.
2524 
2525    If you're doing a TerraPage reader treat everything underneath this group as rotatable.
2526    Pay attention to the Type in particular.  There's a shorthand for rotating a bunch
2527    of objects that is a little confusing.
2528 
2529    If you're doing a TerraPage write this is pretty simple.  For the standard tree example
2530    use one of these with one or more trpgGeometry children.
2531    {group:Read/Write Classes}
2532 */
2533 TX_EXDECL class TX_CLDECL trpgBillboard : public trpgGroup
2534 {
2535 public:
2536     trpgBillboard(void);
2537     ~trpgBillboard(void);
2538     enum {Individual,Group};
2539     // Set the type.  See GetType for details.
2540     void    SetType(int);
2541     // Set the center.
2542     void    SetCenter(const trpg3dPoint &);
2543     enum {Axial,World,Eye};
2544     // Set the rotation mode.
2545     void    SetMode(int);
2546     // Set the rotation axis if mode == Axial
2547     void    SetAxis(const trpg3dPoint &);
2548 
2549     /* The type controls how the billboard node relates to its children.  There
2550        are two modes: (1) Group - This is the obvious one.  Everything below
2551        this node rotates around the center in the way specified by GetMode.  (2) Individual - This
2552        is a little weirder.  Basically, it's here for trees.  It's assumed that
2553        there will be one or more trpgGeometry nodes below this node.  Each single
2554        primitive is supposed to rotate "separately".  That is, you must take into
2555        account the unique center of each one and rotate it around that.  If you have
2556        some optimization scheme where you can deal with groups of billboards (ala Performer)
2557        it is valid to do so in the Individual case. */
2558     bool    GetType(int &) const;
2559     /* Center of the thing to be rotated.  For Group this does the obvious thing.
2560        For Individual it should be the center of the group of things you want to rotate.
2561        This has no use if you're going to rotate each primitive separately, but if you've
2562        got some sort of optimized scheme for doing so (ala Performer) this information is useful.
2563     */
2564     bool    GetCenter(trpg3dPoint &) const;
2565     /* The mode will be one of: (1) Axial - rotate around the Axis.  This is the normal
2566        one for tree. (2) Eye - Always rotate toward the eye point.  (3) world.
2567     */
2568     bool    GetMode(int &) const;
2569     /* The axis used when GetMode returns Axial. */
2570     bool    GetAxis(trpg3dPoint &) const;
2571 
2572     // Resets the contents back to empty
2573     void    Reset(void);
2574 
2575     // Writes this class to a write buffer
2576     bool    Write(trpgWriteBuffer &);
2577     // Reads this class from a read buffer
2578     bool    Read(trpgReadBuffer &);
2579     // Prints this class to a print buffer
2580     bool    Print(trpgPrintBuffer &) const;
2581 protected:
2582     int type;
2583     int mode;
2584     trpg3dPoint center;
2585     trpg3dPoint axis;
2586 };
2587 
2588 /* TerraPage level of detail nodes are pretty simple.  Even though they don't inherit from trpgGroup,
2589    they have many of the same calls and act, structurally at least, in much the same way.  These
2590    act as a switch.  When the user's eye point is within a distance then the children of this
2591    node should be turned on for display.  Otherwise, the children will be invisible.
2592 
2593    A simple on/off test for a TerraPage lod might look like this:
2594    If ( in < dist < out || out < dist < in) then
2595    Turn children on
2596    else
2597    Turn children off.
2598 
2599    There is also a transition width can be used to fade LODs in and out around
2600    the transition zones.  Keep in mind that these LODs are binary.  Children
2601    are either on or off (in the process of being turned off).  The position of
2602    a child doesn't have any special meaning with respect to range.
2603 
2604    If you're doing a TerraPage reader you'll need to turn this into your own LOD
2605    structure.  Keep in mind that trpgAttach nodes can and do attach to trpgLod
2606    nodes.  If you have a general purpose LOD in your scene graph this should be
2607    pretty easy.  However, you must have implemented the concept of LOD center and
2608    you definitely should *not* recalculate the LOD center yourself based on the
2609    center of child geometry.  They may not be the same.  In fact, many terrain
2610    LOD schemes depend on them not being the same.
2611 
2612    If you're doing a TerraPage writer you'll need to use these both for geometry
2613    that you want to disappear at certain distances (e.g. trees, houses, etc..), but
2614    also terrain.  Any terrain LOD scheme you implement must use these to drop out
2615    polygons in the distance.  You'll need to set the center and in/out/width info.
2616    Otherwise it's like a group.
2617 
2618    In TerraPage 2.0 we added the Range Index field.  This field is here to help
2619    run-time systems gracefully degrade visual fidelity.  The trpgLod node still acts
2620    like a normal LOD and you can safely ignore the range index field.  If, however,
2621    you want to use it, please read the documentation on the trpgRangeTable for further
2622    information.
2623 
2624    {group:Read/Write Classes}
2625 */
2626 TX_EXDECL class TX_CLDECL trpgLod : public trpgReadWriteable
2627 {
2628 public:
2629     trpgLod(void);
2630     ~trpgLod(void);
2631     // Set the calculated center
2632     void    SetCenter(const trpg3dPoint &);
2633     // Set the number of children hint
2634     void    SetNumChild(int);
2635     // Set the LOD information
2636     void    SetLOD(double in,double out,double width);
2637 
2638     // Center of this LOD.  Distance from the viewer is calculated from this.
2639     bool    GetCenter(trpg3dPoint &) const;
2640     // Number of children hint.
2641     bool    GetNumChild(int &) const;
2642     // LOD specific information.  in and out can be switched.  width is
2643     // the transition range for doing fading.
2644     bool    GetLOD(double &in,double &out,double &width) const;
2645 
2646     // Set the group ID
2647     void    SetID(int);
2648 
2649     // Group IDs are used here the same way as in trpgGroup
2650     bool    GetID(int &) const;
2651 
2652     /* Set the lod name */
2653     void    SetName(const char* );
2654     // Returns the lod name
2655     const char* GetName(void) const;
2656 
2657     // Set the range Index
2658     void    SetRangeIndex(int ri);
2659     // Get the range index
2660     bool    GetRangeIndex(int &ri) const;
2661 
2662     // Resets the contents back to empty
2663     void    Reset(void);
2664 
2665     // Writes this class to a write buffer
2666     bool    Write(trpgWriteBuffer &);
2667     // Reads this class from a read buffer
2668     bool    Read(trpgReadBuffer &);
2669     // Prints this class to a print buffer
2670     bool    Print(trpgPrintBuffer &) const;
2671 
2672 protected:
2673     int numRange;
2674     double switchIn,switchOut,width;
2675     trpg3dPoint center;
2676     int id;
2677     char* name;
2678     int rangeIndex;
2679 };
2680 
2681 /* Layers are used to draw subface geometry.  That is, geometry that is
2682    coplanar.  This object should be treated just like a group otherwise.
2683    Its existence implies the layering effect.  There is no other associated
2684    information.
2685 
2686    If you're doing a TerraPage reader you should assume that each child,
2687    starting at 0 should be draw one after the other using whatever subfacing
2688    scheme you support.  There are no restrictions on what the children may
2689    be, but we strongly recommend that writers keep this simple.  Keep in
2690    mind that trpgAttach nodes can legally appear as children.  If you can pull
2691    it off this has a rather nice effect (think strips on runways).  If not,
2692    don't sweat it.
2693 
2694    If you're doing a TerraPage writer, this is fairly simple.  Obey the ordering
2695    constraints and try to keep this simple.  Ideally that would mean just a few
2696    trpgGeometry nodes below this node.  Also keep in mind that layering works
2697    very poorly on most OpenGL systems.
2698    {group:Read/Write Classes}
2699 */
2700 TX_EXDECL class TX_CLDECL trpgLayer : public trpgGroup
2701 {
2702 public:
2703     trpgLayer(void);
2704     ~trpgLayer(void);
2705     // Writes this class to a write buffer
2706     bool    Write(trpgWriteBuffer &);
2707     // Reads this class from a read buffer
2708     bool    Read(trpgReadBuffer &);
2709     // Prints this class to a print buffer
2710     bool    Print(trpgPrintBuffer &) const;
2711 
2712     // Resets the contents back to empty
2713     void    Reset(void);
2714 protected:
2715 };
2716 
2717 /* This is pretty much a standard 4x4 static transform.  It has a matrix
2718    which controls where its children wind up in 3D.  Otherwise it acts just
2719    like a trpgGroup.
2720    {group:Read/Write Classes}
2721 */
2722 TX_EXDECL class TX_CLDECL trpgTransform : public trpgGroup
2723 {
2724 public:
2725     trpgTransform(void);
2726     ~trpgTransform(void);
2727 
2728     // Set the 4x4 matrix
2729     void    SetMatrix(const float64 *);
2730 
2731     // Get the 4x4 matrix
2732     bool    GetMatrix(float64 *) const;
2733 
2734     // Writes this class to a write buffer
2735     bool    Write(trpgWriteBuffer &);
2736     // Reads this class from a read buffer
2737     bool    Read(trpgReadBuffer &);
2738     // Prints this class to a print buffer
2739     bool    Print(trpgPrintBuffer &) const;
2740 
2741     // Resets the contents back to empty
2742     void    Reset(void);
2743 protected:
2744     float64 m[4][4];
2745 };
2746 
2747 /* TerraPage treats model references pretty much like instances.  Models
2748    are organized centrally in a trpgModelTable.  This class simply points
2749    into there with a model ID.  There is also a 4x4 matrix (ala trpgTransform)
2750    which moves the model to its final location.
2751 
2752    If you're doing a TerraPage reader you should already have dealt with the
2753    trpgModelTable by this point.  Presumably you've got a mapping from model IDs
2754    to small scene graphs in your own representation.  This can be treated just like
2755    an instance into one of those.
2756 
2757    If you're doing a TerraPage writer this is pretty simple.  When you encounter
2758    a model (external reference) add it to your trpgModelTable and stuff the resulting
2759    model ID into one of these.  Stick that trpgModelRef into your tile data stream.
2760    You'll need to fill out the matrix to scale/translate/rotate it as well.
2761    The model is assumed to be spatially within the tile it's written into.  That isn't
2762    enforced, though.
2763 
2764    {group:Read/Write Classes}
2765 */
2766 TX_EXDECL class TX_CLDECL trpgModelRef : public trpgReadWriteable
2767 {
2768 public:
2769     trpgModelRef(void);
2770     ~trpgModelRef(void);
2771     // Set the model ID.  Must come from a trpgModelTable
2772     void    SetModel(int);
2773     // Set the 4x4 rotate/translate/scale matrix
2774     void    SetMatrix(const float64 *);
2775 
2776     // Model ID pointing into a trpgModelTable
2777     bool    GetModel(int32 &) const;
2778     // Positional matrix.  Works just like a trpgTransform.
2779     bool    GetMatrix(float64 *) const;
2780 
2781     // Writes this class to a write buffer
2782     bool    Write(trpgWriteBuffer &);
2783     // Reads this class from a read buffer
2784     bool    Read(trpgReadBuffer &);
2785     // Prints this class to a print buffer
2786     bool    Print(trpgPrintBuffer &) const;
2787 
2788     // Resets the contents back to empty
2789     void    Reset(void);
2790 protected:
2791     int modelRef;
2792     float64 m[4][4];
2793 };
2794 
2795 /* The Text Styles are used to consolidate attributes related to labels.
2796    It would be inefficient to store the font, for instance, for every
2797    single label, so we do it in the Text Style table.
2798    For the most part, text styles are very simple, consisting of
2799    very basic font and material information.
2800 */
2801 TX_EXDECL class TX_CLDECL trpgTextStyle : public trpgReadWriteable
2802 {
2803 public:
2804     trpgTextStyle(void);
2805     ~trpgTextStyle(void);
2806 
2807     bool operator == (const trpgTextStyle&) const;
2808 
2809     // Set the material ID.  Should point into trpgMatTable
2810     void    SetMaterial(int);
2811     // Get the material ID.  Points into trpgMatTable
2812     int        GetMaterial(void) const;
2813 
2814     // Set the font description
2815     void    SetFont(std::string &);
2816     // Get the font description
2817     const std::string *GetFont(void) const;
2818 
2819     // Set bold to on/off
2820     void    SetBold(bool);
2821     // Return value of bold status
2822     bool    GetBold(void) const;
2823 
2824     // Set italic on/off
2825     void    SetItalic(bool);
2826     // Return value of italic status
2827     bool    GetItalic(void) const;
2828 
2829     // Set underline on/off
2830     void    SetUnderline(bool);
2831     // Return value of underline status
2832     bool    GetUnderline(void) const;
2833 
2834     // Set character size: MUST BE IN METER
2835     void    SetCharacterSize(float32);
2836     // Get character (e.g. font) size
2837     float32    GetCharacterSize(void) const;
2838 
2839     // Write this class to a write buffer
2840     bool    Write(trpgWriteBuffer &);
2841     // Reads this class from a read buffer
2842     bool    Read(trpgReadBuffer &);
2843     // Prints this class to a print buffer
2844     bool    Print(trpgPrintBuffer &) const;
2845 
2846     // Reset the contents back to empty
2847     void    Reset(void);
2848 
2849     // Return object validity
2850     bool isValid(void) const;
2851 protected:
2852     std::string font;
2853     bool bold,italic,underline;
2854     float32 characterSize;
2855     int matId;
2856 };
2857 
2858 /* The text style table is just a collection of trpgTextStyle obejcts for the
2859    whole archive.  Individual text styles will be indexed by trpgLabelProperty
2860    objects.  It is from these that you decide how to display a given label.
2861 */
2862 TX_EXDECL class TX_CLDECL trpgTextStyleTable : public trpgReadWriteable
2863 {
2864 public:
2865     trpgTextStyleTable(void);
2866     ~trpgTextStyleTable(void);
2867 
2868     // Add a single text style
2869     int        AddStyle(const trpgTextStyle &);
2870 
2871     int        FindAddStyle(const trpgTextStyle &);
2872 
2873     // Figure out how many text styles there are
2874     int        GetNumStyle(void) const;
2875 
2876     // Return a reference to the given style
2877     const trpgTextStyle *GetStyleRef(int) const;
2878 
2879     // Validity check
2880     bool    isValid(void) const;
2881     // Reset the contents back to empty
2882     void    Reset(void);
2883 
2884     // Write this class to a write buffer
2885     bool    Write(trpgWriteBuffer &);
2886     // Read this class from a read buffer
2887     bool    Read(trpgReadBuffer &);
2888     // Print this class to a print buffer
2889     bool    Print(trpgPrintBuffer &) const;
2890     typedef std::map<int,trpgTextStyle> StyleMapType;
getStyleMap()2891     const StyleMapType *getStyleMap()const  { return &styleMap; }
2892 protected:
2893     //std::vector<trpgTextStyle> styles;
2894 
2895     StyleMapType styleMap;
2896 };
2897 
2898 
2899 
2900 /* The Support Styles are used to consolidate attributes related to labels.
2901    For the most part, support styles are very simple, consisting of
2902    very basic description of object to use for drawing support.
2903 */
2904 TX_EXDECL class TX_CLDECL trpgSupportStyle : public trpgReadWriteable
2905 {
2906 public:
2907     trpgSupportStyle(void);
2908     ~trpgSupportStyle(void);
2909 
2910     bool operator == (const trpgSupportStyle&) const;
2911 
2912     typedef enum {Line,Cylinder,MaxSupportType} SupportType;
2913 
2914     // Set the support type.  Get GetSupportType() for more information
2915     void    SetType(SupportType);
2916     /* Return the support types.  Supports are geometry that run from the
2917        bottom middle of the label object to some point in space.
2918        Most likely that point is somewhere on the ground, but not
2919        necessarily.  How the support is drawn is controlled both by
2920        the support type and the material ID for the support.
2921     */
2922     SupportType    GetType(void) const;
2923 
2924     // Set the material ID.  Should point into trpgMatTable
2925     void    SetMaterial(int);
2926     // Get the material ID.  Points into trpgMatTable
2927     int        GetMaterial(void) const;
2928 
2929 
2930     // Write this class to a write buffer
2931     bool    Write(trpgWriteBuffer &);
2932     // Reads this class from a read buffer
2933     bool    Read(trpgReadBuffer &);
2934     // Prints this class to a print buffer
2935     bool    Print(trpgPrintBuffer &) const;
2936 
2937     // Reset the contents back to empty
2938     void    Reset(void);
2939 
2940     // Return object validity
2941     bool        isValid(void) const;
2942 protected:
2943     SupportType type;
2944     int matId;
2945 };
2946 
2947 /* The support style table is just a collection of trpgSupportStyle obejcts for the
2948    whole archive.  Individual support styles will be indexed by trpgLabelProperty
2949    objects.  It is from these that you decide how to display a given support.
2950 */
2951 TX_EXDECL class TX_CLDECL trpgSupportStyleTable : public trpgReadWriteable
2952 {
2953 public:
2954     trpgSupportStyleTable(void);
2955     ~trpgSupportStyleTable(void);
2956 
2957     // Add a single text style
2958     int        AddStyle(const trpgSupportStyle &);
2959 
2960     int        FindAddStyle(const trpgSupportStyle &);
2961 
2962     // Figure out how many text styles there are
2963     int        GetNumStyle(void) const;
2964 
2965     // Return a reference to the given style
2966     const trpgSupportStyle *GetStyleRef(int) const;
2967 
2968     // Validity check
2969     bool    isValid(void) const;
2970     // Reset the contents back to empty
2971     void    Reset(void);
2972 
2973     // Write this class to a write buffer
2974     bool    Write(trpgWriteBuffer &);
2975     // Read this class from a read buffer
2976     bool    Read(trpgReadBuffer &);
2977     // Print this class to a print buffer
2978     bool    Print(trpgPrintBuffer &) const;
2979 
2980 protected:
2981     //std::vector<trpgSupportStyle> styles;
2982     typedef std::map<int,trpgSupportStyle> SupportStyleMapType;
2983     SupportStyleMapType supportStyleMap;
2984 };
2985 
2986 
2987 
2988 /* The Label property are used to consolidate attributes related to labels.
2989    Label properties are very simple, consisting of
2990    basic font style and support properties.
2991 */
2992 TX_EXDECL class TX_CLDECL trpgLabelProperty : public trpgReadWriteable
2993 {
2994 public:
2995     trpgLabelProperty(void);
2996     ~trpgLabelProperty(void);
2997 
2998     typedef enum {VertBillboard,Billboard,Panel,Cube,MaxLabelType} LabelType;
2999 
3000     bool operator == (const trpgLabelProperty&) const;
3001 
3002     // Set the label type.  See GetType() for more information.
3003     void    SetType(LabelType);
3004     /* Return the label type.  This controls the geometry for the label.
3005        Panel labels are simple polygons.  Cube labels should display
3006        the text on every side with single sided polygons.
3007        Billboard labels rotate toward the user with no particular axes.
3008        That is, they will always be pointed directly toward the user.
3009        Vertical billboards rotate toward the user, but have an axis along +Z.
3010     */
3011     LabelType    GetType(void) const;
3012 
3013     // Set the font style ID.  Should point into trpgTextStyleTable
3014     void    SetFontStyle(int);
3015     // Get the font style ID.  Points into trpgTextStyleTable
3016     int        GetFontStyle(void) const;
3017 
3018     // Set the support style ID.  Should point into trpgSupportTable
3019     void    SetSupport(int);
3020     // Get the font style ID.  Points into trpgSupportTable
3021     int        GetSupport(void) const;
3022 
3023     // Write this class to a write buffer
3024     bool    Write(trpgWriteBuffer &);
3025     // Reads this class from a read buffer
3026     bool    Read(trpgReadBuffer &);
3027     // Prints this class to a print buffer
3028     bool    Print(trpgPrintBuffer &) const;
3029 
3030     // Reset the contents back to empty
3031     void    Reset(void);
3032 
3033     // Return object validity
3034     bool isValid(void) const;
3035 protected:
3036     int fontId;
3037     int supportId;
3038     LabelType type;
3039 };
3040 
3041 /* The label property table is just a collection of trpgLabelProperty obejcts for the
3042    whole archive.  Individual label property will be indexed by trpgLable
3043    objects.
3044 */
3045 TX_EXDECL class TX_CLDECL trpgLabelPropertyTable : public trpgReadWriteable
3046 {
3047 public:
3048     trpgLabelPropertyTable(void);
3049     ~trpgLabelPropertyTable(void);
3050 
3051     // Add a single label property
3052     int        AddProperty(const trpgLabelProperty &);
3053 
3054     // Find or Add a single label property
3055     int FindAddProperty(const trpgLabelProperty& property);
3056 
3057     // Figure out how many properties there are
3058     int        GetNumProperty(void) const;
3059 
3060     // Return a reference to the given property
3061     const trpgLabelProperty *GetPropertyRef(int) const;
3062 
3063     // Validity check
3064     bool    isValid(void) const;
3065     // Reset the contents back to empty
3066     void    Reset(void);
3067 
3068     // Write this class to a write buffer
3069     bool    Write(trpgWriteBuffer &);
3070     // Read this class from a read buffer
3071     bool    Read(trpgReadBuffer &);
3072     // Print this class to a print buffer
3073     bool    Print(trpgPrintBuffer &) const;
3074 
3075 protected:
3076     //std::vector<trpgLabelProperty> properties;
3077     typedef std::map<int,trpgLabelProperty> LabelPropertyMapType;
3078     LabelPropertyMapType labelPropertyMap;
3079 };
3080 
3081 /* Labels are objects that float above the terrain (usually) and display
3082    some text message to the user.  They're primarily used in 3D map sort of
3083    application.  In other words, they're not intended to be real world objects.
3084    You would use one if you want to float a message such as "Natural History Museum"
3085    over a specific building in a visual database.
3086 */
3087 TX_EXDECL class TX_CLDECL trpgLabel : public trpgReadWriteable {
3088 public:
3089     trpgLabel(void);
3090     ~trpgLabel(void);
3091 
3092     bool isValid(void) const;
3093 
3094 
3095     typedef enum {Left,Center,Right,MaxAlignmentType} AlignmentType;
3096 
3097     // Set the label property ID. This is an index into a tprgLabelPropertyTable
3098     void    SetProperty(int);
3099     int        GetProperty() const;
3100 
3101 
3102 
3103     // Set the text for this label.  See GetText() for more information
3104     void    SetText(const std::string &);
3105     /* Return the text for this label.  The text may contain basic formatting
3106        such as newlines and tabs.  Expect to see those as \n and \t respectively.
3107        Eventually, this text might contain HTML formatting, but we do not use
3108        that at present.
3109        Should not be empty.
3110     */
3111     const std::string *GetText(void) const;
3112 
3113     // Set the text alignment.  See GetAlignmentType() for more information.
3114     void    SetAlignment(AlignmentType);
3115     /* Return the alignment type.  This controls the alignment of the text
3116        with respect to the label geometry.
3117     */
3118     AlignmentType    GetAlignment(void) const;
3119 
3120     // Set the number of spaces between tabs
3121     void    SetTab(int);
3122     // Get the number of spaces between tabs
3123     int        GetTab(void) const;
3124 
3125     // Set the text scaling value: font size * scale = real world text size in meter
3126     void        SetScale(float32);
3127     float32     GetScale() const;
3128 
3129     // Set the text thickness: use to draw 3D text. if thickness = 0, we have
3130     // 2D text only.
3131     void        SetThickness(float32);
3132     float32     GetThickness() const;
3133 
3134     // Set the description for this label.  Set GetDesc() for more information
3135     void    SetDesc(const std::string &);
3136     /* Return the description for this label.  Descriptions should contain no
3137        formatting.  They are a description of what the label represents and may
3138        appear if a user interacts with the label, but should not be drawn in 3D.
3139        May be empty.
3140     */
3141     const std::string *GetDesc(void) const;
3142 
3143     // Set the URL for this label.  See GetURL() for more information.
3144     void    SetURL(const std::string &);
3145     /* Return the URL for this label.  The URL would invoke some sort of
3146        web browser if the user of the 3D application clicks on the label.
3147        May be empty.
3148     */
3149     const std::string *GetURL(void) const;
3150 
3151     // Set the number of spaces between tabs
3152     void    SetTabSize(int);
3153     // Get the number of spaces between tabs
3154     int        GetTabSize(void) const;
3155 
3156     // Set the location of the label.
3157     void SetLocation(const trpg3dPoint &);
3158     const trpg3dPoint& GetLocation() const;
3159 
3160     // Add a support.  See GetSupports() for more information
3161     void    AddSupport(const trpg3dPoint &);
3162     /* Return the support array.  Supports are linear features that run from
3163        the middle bottom of the label to some set of points in the database.
3164        These will often be on the ground, but need not be.  Support display
3165        is controlled by the SupportType and by the Support Material ID.
3166     */
3167     const std::vector<trpg3dPoint> *GetSupports(void) const;
3168 
3169     // Writes this class to a write buffer
3170     bool    Write(trpgWriteBuffer &);
3171     // Reads this class from a read buffer
3172     bool    Read(trpgReadBuffer &);
3173     // Prints this class to a print buffer
3174     bool    Print(trpgPrintBuffer &) const;
3175 
3176     // Resets the contents back to empty
3177     void    Reset(void);
3178 
3179 protected:
3180     int propertyId;
3181     std::string text;  // Actual label text.  May contain formatting
3182     AlignmentType alignment;
3183     int tabSize;
3184     float32 scale;
3185     float32 thickness;
3186     std::string desc;
3187     std::string url;
3188     trpg3dPoint location;
3189     std::vector<trpg3dPoint> supports;
3190 };
3191 
3192 #endif
3193