2536 lines
104 KiB
C++
2536 lines
104 KiB
C++
/* ************************
|
|
Copyright Terrain Experts Inc.
|
|
Terrain Experts Inc (TERREX) reserves all rights to this source code
|
|
unless otherwise specified in writing by the President of TERREX.
|
|
This copyright may be updated in the future, in which case that version
|
|
supercedes this one.
|
|
-------------------
|
|
Terrex Experts Inc.
|
|
4400 East Broadway #314
|
|
Tucson, AZ 85711
|
|
info@terrex.com
|
|
Tel: (520) 323-7990
|
|
************************
|
|
*/
|
|
|
|
#ifndef _trpage_geom_h_
|
|
#define _trpage_geom_h_
|
|
|
|
/* trpage_geom.h
|
|
Geometry and node definitions.
|
|
These are the objects that get read from and written to archives.
|
|
*/
|
|
|
|
#include <osgTXP/trpage_sys.h>
|
|
|
|
#include <osgTXP/trpage_io.h>
|
|
#include <osgTXP/trpage_swap.h>
|
|
|
|
// Forward declarations
|
|
|
|
class trpgMaterial;
|
|
class trpgTextureEnv;
|
|
class trpgMatTable;
|
|
|
|
namespace osg
|
|
{
|
|
class Vec3;
|
|
}
|
|
|
|
/* This is the archive header structure. There is one per TerraPage archive.
|
|
You don't write it directly, but instead fill it out and pass it to
|
|
a trpgwArchive (if you're writing), or get it back from a trpgr_Archive
|
|
(if you're reading).
|
|
If you're putting together a reader, just use the default methods for
|
|
reading this class. Since it's only read once, the overhead is low.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgHeader : public trpgReadWriteable {
|
|
public:
|
|
trpgHeader(void);
|
|
~trpgHeader(void);
|
|
|
|
// Set the TerraPage version info.
|
|
void SetVersion(int major,int minor);
|
|
// Set the database version info.
|
|
void SetDbVersion(int major,int minor);
|
|
/* Set the tile size for the given LOD. See GetTileSize for more info.
|
|
Each LOD must have its size set, otherwise the trpgHeader won't be valid.
|
|
You must set the number of LODs with SetNumLods first.
|
|
You should use the AddLod method if you can, which handles all of this.
|
|
*/
|
|
void SetTileSize(int lod,const trpg2dPoint &size);
|
|
// Origin defaults to 0,0,0
|
|
void SetOrigin(const trpg3dPoint &);
|
|
// 2D archive extents. Must be set.
|
|
void SetExtents(const trpg2dPoint &sw,const trpg2dPoint &ne);
|
|
|
|
typedef enum {DatabaseLocal,Absolute,TileLocal} trpgTileType;
|
|
// How the coordinates are treated with respect to real world values.
|
|
void SetTileOriginType(trpgTileType);
|
|
|
|
/* Number of terrain LODs. If you use this method when building a database
|
|
you have to use the SetLodRange and SetLodSize methods on each LOD as well.
|
|
It's better to use AddLod instead of calling these three methods.
|
|
*/
|
|
void SetNumLods(int);
|
|
/* Number of tiles (x,y) for each LOD.
|
|
The single argument version assumes lod = 0, num lods = 1.
|
|
*/
|
|
void SetLodSize(int lod,const trpg2iPoint &);
|
|
void SetLodSize(const trpg2iPoint *);
|
|
/* Set the range for the given terrain LOD.
|
|
The single argument version assumes lod = 0, num lods = 1.
|
|
*/
|
|
void SetLodRange(int,float64);
|
|
void SetLodRange(const float64 *);
|
|
// Increase the number of terrain LODs, adding a new one with the given size and range
|
|
void AddLod(const trpg2iPoint &size,const trpg2dPoint &ext,float64 range);
|
|
|
|
// Keep track of the maximum assigned group IDs (for tile paging)
|
|
void SetMaxGroupID(int);
|
|
/* Instead of keeping a count of all the group IDs you added and then
|
|
calling SetMaxGroupID, you can call this function and it will return
|
|
the next valid groupID to you. It will also keep track of the maximum.
|
|
*/
|
|
int AddGroupID(void);
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// TerraVista version information is two integers.
|
|
bool GetVersion(int &,int &) const;
|
|
// Database version information is user defined. Put whatever you want here.
|
|
bool GetDbVersion(int &,int &) const;
|
|
/* This is the extents, in X/Y of a
|
|
single tile. All tiles within an LOD should be the same size (although this is not
|
|
enforced). It's also assumed that a given tile lives entirely within
|
|
its own extents (as calculated with this value), although that's not
|
|
enforced either. */
|
|
bool GetTileSize(int,trpg2dPoint &) const;
|
|
/* The meaning of the database origin varies depending on the value returned
|
|
by GetTileOriginType. If the database is Absolute, then this value
|
|
will be the lower left corner. If the database is DatabaseLocal or
|
|
TileLocal you can use this value to determine the real world coordinates.
|
|
Just add origin + coordinate.
|
|
*/
|
|
bool GetOrigin(trpg3dPoint &) const;
|
|
/* These are the 2D extents that the database covers. You can use this
|
|
information to determine where the middle is, for example.
|
|
*/
|
|
bool GetExtents(trpg2dPoint &sw,trpg2dPoint &ne) const;
|
|
/* The tile origin type tells you the coordinate system of each database
|
|
tile. There are three type:
|
|
* Absolute - All coordinate values are absolute. No translation is required.
|
|
* DatabaseLocal - All coordinate values are local to the database. That is
|
|
if you want to determine the real world value do: coord + origin.
|
|
* TileLocal - Each tile has its own coordinate system starting from the lower left
|
|
corner. We do this to get around floating point accuracy problems (although we
|
|
can do Double coordinates if necessary, as well). To determine the
|
|
real world coordinate value do: tileID*tileSize + coord.
|
|
*/
|
|
bool GetTileOriginType(trpgTileType &) const;
|
|
/* Group IDs are used by TerraPage to hook level of detail structures together.
|
|
A TerraPage database can have an arbitrary number of terrain LODs, each stored
|
|
seperately. To hook them together we use trpgAttach nodes and number each group &
|
|
LOD node. This returns the maximum group ID in the file, which is important
|
|
to know if you're keeping an array of them. */
|
|
bool GetMaxGroupID(int &) const;
|
|
|
|
/* A TerraPage archive can contain any number of terrain LODs (a typical number is 4).
|
|
Each of these terrain LODs is accessed seperately (as are the tiles within them).
|
|
This returns the number of terrain LODs in the file. It will be at least 1.
|
|
See trpgAttach for instructions on how to hook the terrain LODs together.
|
|
*/
|
|
bool GetNumLods(int32 &) const;
|
|
/* A terrain LOD conceptually covers the entire database and is broken up
|
|
into some X x Y set of tiles. We make no assumptions about the number
|
|
of tiles in each terrain LOD. That's entirely up to the writer. This
|
|
returns the number of tiles in 2D for a given terrain LOD. */
|
|
bool GetLodSize(int32,trpg2iPoint &) const;
|
|
/* It's up to the TerraPage archive writer to make their terrain LOD structure
|
|
work by using trpgAttach nodes. The scheme they're using may be quad-tree
|
|
or replacement LOD or something where the highest LOD isn't even terrain.
|
|
It really doesn't matter. However, the reader does need a hint as to
|
|
when tiles for a given LOD must be pulled in. This returns that range
|
|
in database coordinates (usually meters).
|
|
*/
|
|
bool GetLodRange(int32,float64 &) const;
|
|
|
|
// Read/Write functions
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
// {secret}
|
|
bool ReadLodInfo(trpgReadBuffer &);
|
|
|
|
protected:
|
|
int verMinor,verMajor;
|
|
int dbVerMinor,dbVerMajor;
|
|
int maxGroupID;
|
|
trpg2dPoint sw,ne;
|
|
trpg3dPoint origin;
|
|
trpgTileType tileType;
|
|
|
|
int numLods;
|
|
std::vector<trpg2dPoint> tileSize;
|
|
std::vector<trpg2iPoint> lodSizes;
|
|
std::vector<float64> lodRanges;
|
|
};
|
|
|
|
/* The Texture Environment is used by the trpgMaterial to define texture
|
|
related parameters. A trpgTextureEnv is associated with each texture
|
|
used in a trpgMaterial. So, for example, if there are 2 textures in
|
|
a material, there will be two texture environments.
|
|
Most of these parameters come straight from the OpenGL specification. It's
|
|
best to consult that for an exact meaning.
|
|
|
|
If you doing a TerraPage reader, expect to get a trpgTextureEnv when
|
|
dealing with trpgMaterial definitions. If you're doing a writer, you'll
|
|
need to build these in the course of building a trpgMaterial.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTextureEnv : public trpgReadWriteable {
|
|
friend class trpgMatTable;
|
|
public:
|
|
trpgTextureEnv(void);
|
|
~trpgTextureEnv(void);
|
|
|
|
// Environment mode values
|
|
enum {Alpha,Blend,Decal,Modulate,AddDetail,ModulateDetail};
|
|
// Set the application mode for the texture.
|
|
void SetEnvMode(int);
|
|
// Values used by SetMinFilter and SetMagFilter
|
|
enum {Point, Linear, MipmapPoint, MipmapLinear,
|
|
MipmapBilinear, MipmapTrilinear, Nearest};
|
|
// Set the Minification filter for a texture
|
|
void SetMinFilter(int);
|
|
// Set the Magnification filter for a texture
|
|
void SetMagFilter(int);
|
|
|
|
// Values used by SetWrap
|
|
enum {Clamp,Repeat};
|
|
// Set the texture wrapping for S and T, respectively
|
|
void SetWrap(int,int);
|
|
// Set the texture border color
|
|
void SetBorderColor(const trpgColor &);
|
|
|
|
/* The environment mode controls how the texture is applied.
|
|
It can take the following values:
|
|
Alpha - Used to change the alpha values on a polygon.
|
|
Blend - Blended with the polygont color
|
|
Decal - Doesn't take polygon color into account.
|
|
Modulate - See openGL spec for definition.
|
|
*/
|
|
bool GetEnvMode(int32 &) const;
|
|
/* The Minification and Magnification filters control how texture
|
|
mipmap levels are used. We support the values: Point, Linear,
|
|
MipmapPoint, MipmapLinear,
|
|
MipmapBilinear, MipmapTrilinear, Nearest
|
|
*/
|
|
bool GetMinFilter(int32 &) const;
|
|
// Get the magnification filter
|
|
bool GetMagFilter(int32 &) const;
|
|
/* Wrapping controls how textures are used near the edges.
|
|
There are two valid values: Clamp, Repeat.
|
|
*/
|
|
bool GetWrap(int &,int &) const;
|
|
/* This maps straight into the OpenGL definition of border color. */
|
|
bool GetBorderColor(trpgColor &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
int envMode;
|
|
int minFilter;
|
|
int magFilter;
|
|
int wrapS,wrapT;
|
|
trpgColor borderCol;
|
|
};
|
|
|
|
/* The material definition for TerraPage encompasses those things that have to
|
|
do with visual display that can be indexed and disassociated from the
|
|
polygons themselves. This covers things like color, texture, alpha
|
|
and a few more obscure ones.
|
|
Materials are indexed centrally in a trpgMatTable.
|
|
|
|
This material definition borrows heavily from the OpenGL specification.
|
|
Please refer to that for a good definition of all the fields.
|
|
|
|
If you're doing a TerraPage reader you'll need to deal with these in two places.
|
|
First, is when you read the archive header and get a trpgMatTable back. You'll
|
|
want to translate them into your own internal representation and keep track of
|
|
the mapping. Later, when parsing trpgGeometry nodes, you'll run into them
|
|
again. This time they will be material indices into a trpgMatTable. At that
|
|
point you'll want to map these indices into your own material definition table.
|
|
|
|
If you're doing a TerraPage writer you'll need to create one of these for every
|
|
unique material-like object you have. Since trpgMaterial objects are indexed
|
|
centrally in a TerraPage archive, you should take advantage of that and use
|
|
as few as possible. After defining one, you'll want to add it to a trpgMatTable
|
|
and keep track of the material index that returns. This will be the mapping from
|
|
your own internal material table (or whatever you've got) into the archive's
|
|
material table. A trpgMaterial sets up defaults that work pretty well, so just
|
|
fill in what you need to use.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgMaterial : public trpgReadWriteable {
|
|
friend class trpgMatTable;
|
|
public:
|
|
trpgMaterial(void);
|
|
~trpgMaterial(void);
|
|
// Set base material color
|
|
void SetColor(const trpgColor &);
|
|
// Ambient color
|
|
void SetAmbient(const trpgColor &);
|
|
// Diffuse color (the most commonly used)
|
|
void SetDiffuse(const trpgColor &);
|
|
// Specular color used in lighting
|
|
void SetSpecular(const trpgColor &);
|
|
// Emissive color used in lighting
|
|
void SetEmission(const trpgColor &);
|
|
// Shininess used in lighting
|
|
void SetShininess(float64);
|
|
|
|
enum {Smooth,Flat};
|
|
// Shading model
|
|
void SetShadeModel(int);
|
|
// Point size
|
|
void SetPointSize(float64);
|
|
// Line width
|
|
void SetLineWidth(float64);
|
|
enum {Front,Back,FrontAndBack};
|
|
// Cull mode. See GetCullMode
|
|
void SetCullMode(int);
|
|
#ifdef Always
|
|
// None and Always appear to be defined on the SGI
|
|
// in such a way as to interfere with a local enum
|
|
// declaration within a class
|
|
enum {trNone,trAlways,Equal,GreaterThanOrEqual,GreaterThan,
|
|
LessThanOrEqual,LessThan,Never,NotEqual};
|
|
#else
|
|
enum {None,Always,Equal,GreaterThanOrEqual,GreaterThan,
|
|
LessThanOrEqual,LessThan,Never,NotEqual};
|
|
#endif
|
|
// Alpha Function. See GetAlphaFunc
|
|
void SetAlphaFunc(int);
|
|
// Alpha Ref value. See GetAlphaRef
|
|
void SetAlphaRef(float64);
|
|
// Alpha value for any polygon using this material
|
|
void SetAlpha(float64);
|
|
// Generate normals automatically from geometry
|
|
void SetAutoNormal(bool);
|
|
|
|
/* Set the total number of textures used by this trpgMaterial.
|
|
This works with SetTexture. We recommend that you used
|
|
AddTexture instead of these two methods. */
|
|
void SetNumTexture(int);
|
|
/* Works with SetNumTexture.
|
|
This method sets the texture ID and texture environment for the given
|
|
texture instance in this material. Use AddTexture instead, if you can.
|
|
*/
|
|
void SetTexture(int no,int id,const trpgTextureEnv &);
|
|
/* This method takes a texture ID that refers to a trpgTexTable and a
|
|
trpgTextureEnv which specifies the application information relating
|
|
to this texture instance. It returns the reference number (i.e. the
|
|
3rd texture in this material, etc...)
|
|
*/
|
|
int AddTexture(int,const trpgTextureEnv &);
|
|
|
|
// Number of tiles this material is used in
|
|
void SetNumTiles(int);
|
|
// Adds a count to the number of tiles this material is used in and returns that number
|
|
int AddTile(void);
|
|
|
|
// Sets bump map status (color etc... isn't important)
|
|
void SetIsBumpMap(bool);
|
|
|
|
// Return the current color
|
|
bool GetColor(trpgColor &) const;
|
|
// Returns the ambient color
|
|
bool GetAmbient(trpgColor &) const;
|
|
// Returns the diffuse color (the most commonly used color)
|
|
bool GetDiffuse(trpgColor &) const;
|
|
// Specular color used for lighting
|
|
bool GetSpecular(trpgColor &) const;
|
|
// Emissive color used for lighting
|
|
bool GetEmission(trpgColor &) const;
|
|
// Shininess used for lighting
|
|
bool GetShininess(float64 &) const;
|
|
|
|
// The shading model can be either Smooth or Flat
|
|
bool GetShadeModel(int &) const;
|
|
// Point size
|
|
bool GetPointSize(float64 &) const;
|
|
// Line width
|
|
bool GetLineWidth(float64 &) const;
|
|
/* Cull mode determines whether geometry will be rejected if it's Front facing, Back
|
|
facing, or neither (FrontAndBack)
|
|
*/
|
|
bool GetCullMode(int &) const;
|
|
/* This controls what alpha values in a texture mean. It can take the values:
|
|
None,Always,Equal,GreaterThanOrEqual,GreaterThan,
|
|
LessThanOrEqual,LessThan,Never,NotEqual
|
|
*/
|
|
bool GetAlphaFunc(int &) const;
|
|
/* The Alpha Ref is a value used in some of the Alpha Functions */
|
|
bool GetAlphaRef(float64 &) const;
|
|
// Whether or not to generate normals from geometry
|
|
bool GetAutoNormal(bool &) const;
|
|
// A single Alpha value that applies to any polygons using this material
|
|
bool GetAlpha(float64 &) const;
|
|
/* One of the useful things about TerraPage is that it contains enough information
|
|
to page textures & materials as well as terrain. This is part of that.
|
|
It returns the number of tiles this material is used in. The trpgTexture has
|
|
its own which is used for paging textures. You only want to pay attention to
|
|
this if you have some costly material definition in your hardware and so have
|
|
to swap them in and out.
|
|
*/
|
|
bool GetNumTile(int &) const;
|
|
|
|
/* There can be multiple textures per material. This returns the number.
|
|
The first is the base texture, so just use that if you can only do 1 texture per poly.
|
|
*/
|
|
bool GetNumTexture(int &) const;
|
|
/* TerraPage supports multiple textures per polygon. Some hardware can do this,
|
|
some can't. If you can support it, here's how this works.
|
|
This method returns the texture definition for the Nth texture used in this material.
|
|
That consists of a texture ID which points into a trpgTexTable and a trpgTextureEnv
|
|
which contains the texture application information.
|
|
Multiple materials can also appear per trpgGeometry, so be aware that there are
|
|
two ways to have multiple textures per polygon.
|
|
*/
|
|
bool GetTexture(int no,int &id,trpgTextureEnv &) const;
|
|
|
|
// Return whether or not this material is a bump map
|
|
bool GetIsBumpMap(bool &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Note: Need to do equality operator
|
|
|
|
protected:
|
|
bool isBump;
|
|
trpgColor color;
|
|
trpgColor ambient;
|
|
trpgColor diffuse;
|
|
trpgColor specular;
|
|
trpgColor emission;
|
|
float64 shininess;
|
|
int shadeModel;
|
|
float64 pointSize;
|
|
float64 lineWidth;
|
|
int cullMode;
|
|
int alphaFunc;
|
|
float64 alpha;
|
|
float64 alphaRef;
|
|
bool autoNormal;
|
|
int numTex;
|
|
int32 numTile;
|
|
std::vector<int> texids;
|
|
std::vector<trpgTextureEnv> texEnvs;
|
|
};
|
|
|
|
/* The lights in TerraPage
|
|
*/
|
|
|
|
TX_EXDECL class TX_CLDECL trpgLightAttr : public trpgReadWriteable {
|
|
public:
|
|
// Default constructor
|
|
trpgLightAttr(void);
|
|
// Copy constructor
|
|
trpgLightAttr(const trpgLightAttr &);
|
|
// Destructor
|
|
~trpgLightAttr(void);
|
|
|
|
// Light Flags
|
|
enum {
|
|
// Light flags
|
|
trpg_Day = 0x0001,
|
|
trpg_Dusk = 0x0002,
|
|
trpg_Night = 0x0004,
|
|
trpg_Directional = 0x0008,
|
|
trpg_BackColor = 0x0010,
|
|
trpg_Reflective = 0x0020,
|
|
|
|
// Animation flags
|
|
trpg_Flashing = 0x0100,
|
|
trpg_Rotating = 0x0200,
|
|
trpg_ClockWise = 0x0400,
|
|
trpg_AnimationMask =0x0f00,
|
|
|
|
// Performer light flags
|
|
trpg_Perspective = 0x1000,
|
|
trpg_Fade = 0x2000,
|
|
trpg_ZBuffer = 0x4000,
|
|
trpg_FogPunch = 0x8000,
|
|
trpg_PerformerMask =0xf000
|
|
} LightFlags;
|
|
|
|
// Light Type
|
|
typedef enum {
|
|
trpg_Raster,
|
|
trpg_Calligraphic,
|
|
trpg_RASCAL
|
|
} LightType;
|
|
|
|
// Light Directionality
|
|
typedef enum {
|
|
trpg_Omnidirectional,
|
|
trpg_Bidirectional,
|
|
trpg_Unidirectional
|
|
} LightDirectionality;
|
|
|
|
// Light Quality
|
|
typedef enum {
|
|
trpg_Off,
|
|
trpg_Low,
|
|
trpg_Medium,
|
|
trpg_High,
|
|
trpg_Undefined
|
|
} LightQuality;
|
|
|
|
// Struct for Performer Lights
|
|
struct PerformerAttr {
|
|
PerformerAttr() : flags(0),minPixelSize(0),maxPixelSize(0),actualSize(0),
|
|
transparentPixelSize(0),transparentFallofExp(0),transparentScale(0),
|
|
transparentClamp(0),fogScale(0) {};
|
|
int32 flags;
|
|
float64 minPixelSize;
|
|
float64 maxPixelSize;
|
|
float64 actualSize;
|
|
float64 transparentPixelSize;
|
|
float64 transparentFallofExp;
|
|
float64 transparentScale;
|
|
float64 transparentClamp;
|
|
float64 fogScale;
|
|
};
|
|
|
|
// Struct for Animated Lights
|
|
struct AnimationAttr {
|
|
AnimationAttr() : period(0),phaseDelay(0),timeOn(0),vector(trpg3dPoint(0,0,0)),flags(0) {};
|
|
float64 period;
|
|
float64 phaseDelay;
|
|
float64 timeOn;
|
|
trpg3dPoint vector;
|
|
int32 flags;
|
|
};
|
|
|
|
// Struct for Calligraphic Lights
|
|
struct CalligraphicAttr {
|
|
CalligraphicAttr() : drawOrder(0),minDefocus(0),maxDefocus(0) {} ;
|
|
int32 drawOrder;
|
|
float64 minDefocus;
|
|
float64 maxDefocus;
|
|
};
|
|
|
|
// Setters
|
|
// Set Type
|
|
void SetType( trpgLightAttr::LightType );
|
|
|
|
// Set Directionality
|
|
void SetDirectionality( trpgLightAttr::LightDirectionality );
|
|
|
|
// Set Front Color
|
|
void SetFrontColor( trpgColor );
|
|
|
|
// Set Front Intensity
|
|
void SetFrontIntensity( float64 );
|
|
|
|
// Set Back Color
|
|
void SetBackColor( trpgColor );
|
|
|
|
// Set Back Intensity
|
|
void SetBackIntensity( float64 );
|
|
|
|
// Set Normal
|
|
void SetNormal( trpg3dPoint );
|
|
|
|
// Set SMC
|
|
void SetSMC( int32 );
|
|
|
|
// Set FID
|
|
void SetFID( int32 );
|
|
|
|
// Set Flags
|
|
void SetFlags( int32 );
|
|
|
|
// Set Horizontal Lobe Angle
|
|
void SetHLobeAngle( float64 );
|
|
|
|
// Set Vertical Lobe Angle
|
|
void SetVLobeAngle( float64 );
|
|
|
|
// Set Lobe Roll Angle
|
|
void SetLobeRollAngle( float64 );
|
|
|
|
// Set Lobe Falloff
|
|
void SetLobeFalloff( float64 );
|
|
|
|
// Set Ambient Intensity
|
|
void SetAmbient( float64 );
|
|
|
|
// Set Quality
|
|
void SetQuality( trpgLightAttr::LightQuality );
|
|
|
|
// Set RASCAL Significance
|
|
void SetRascalSignificance( float64 );
|
|
|
|
// Set Random Intensity
|
|
void SetRandomIntensity( trpgLightAttr::LightQuality );
|
|
|
|
// Set the attributes for Calligraphics Lights
|
|
void SetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& );
|
|
|
|
// Set Calligraphic Draw Order
|
|
void SetCalligraphicDrawOrder( int32 );
|
|
|
|
// Set Calligraphic Minimum Defocus
|
|
void SetCalligraphicMinDefocus( float64 );
|
|
|
|
// Set Calligraphic Maximum Defocus
|
|
void SetCalligraphicMaxDefocus( float64 );
|
|
|
|
// Set the attributes for Performer Lights
|
|
void SetPerformerAttr( trpgLightAttr::PerformerAttr& );
|
|
|
|
// Set the flags for Perfromer Lights
|
|
void SetPerformerFlags( int32 );
|
|
|
|
// Set the minimum pixel size for Performer Lights
|
|
void SetPerformerMinPixelSize( float64 );
|
|
|
|
// Set the maximum pixel size for Performer Lights
|
|
void SetPerformerMaxPixelSize( float64 );
|
|
|
|
// Set the actual size for Performer Lights
|
|
void SetPerformerActualSize( float64 );
|
|
|
|
// Set the transparent pixel size for Performer Lights
|
|
void SetPerformerTpPixelSize( float64 );
|
|
|
|
// Set the transparent Falloff exponent for Performer Lights
|
|
void SetPerformerTpFalloffExp( float64 );
|
|
|
|
// Set the transparent scale for Performer Lights
|
|
void SetPerformerTpScale( float64 );
|
|
|
|
// Set the transparent clamp for Performer Lights
|
|
void SetPerformerTpClamp( float64 );
|
|
|
|
// Set the fog scale for Performer Lights
|
|
void SetPerformerFogScale( float64 );
|
|
|
|
// Set the attributes for animated lights
|
|
void SetAnimationAttr( trpgLightAttr::AnimationAttr& );
|
|
|
|
// Set the animation period for animated lights
|
|
void SetAnimationPeriod( float64 );
|
|
|
|
// Set the animation phase delay for animated lights
|
|
void SetAnimationPhaseDelay( float64 );
|
|
|
|
// Set the time on for animated lights
|
|
void SetAnimationTimeOn( float64 );
|
|
|
|
// Set the animation vector for animated lights
|
|
void SetAnimationVector( trpg3dPoint );
|
|
|
|
// Set the flags for animated lights
|
|
void SetAnimationFlags( int32 );
|
|
|
|
// Getters
|
|
// See the comments for the Setters
|
|
void GetType( trpgLightAttr::LightType& );
|
|
void GetDirectionality( trpgLightAttr::LightDirectionality& );
|
|
void GetFrontColor( trpgColor& );
|
|
void GetFrontIntensity( float64& );
|
|
void GetBackColor( trpgColor& );
|
|
void GetBackIntensity( float64& );
|
|
void GetNormal( trpg3dPoint& );
|
|
void GetSMC( int32& );
|
|
void GetFID( int32& );
|
|
void GetFlags( int32& );
|
|
void GetHLobeAngle( float64& );
|
|
void GetVLobeAngle( float64& );
|
|
void GetLobeRollAngle( float64& );
|
|
void GetLobeFalloff( float64& );
|
|
void GetAmbient( float64& );
|
|
void GetQuality( trpgLightAttr::LightQuality& );
|
|
void GetRascalSignificance( float64& );
|
|
void GetRandomIntensity( trpgLightAttr::LightQuality& );
|
|
void GetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& );
|
|
void GetCalligraphicDrawOrder( int32& );
|
|
void GetCalligraphicMinDefocus( float64& );
|
|
void GetCalligraphicMaxDefocus( float64& );
|
|
void GetPerformerAttr( trpgLightAttr::PerformerAttr& );
|
|
void GetPerformerFlags( int32& );
|
|
void GetPerformerMinPixelSize( float64& );
|
|
void GetPerformerMaxPixelSize( float64& );
|
|
void GetPerformerActualSize( float64& );
|
|
void GetPerformerTpPixelSize( float64& );
|
|
void GetPerformerTpFalloffExp( float64& );
|
|
void GetPerformerTpScale( float64& );
|
|
void GetPerformerTpClamp( float64& );
|
|
void GetPerformerFogScale( float64& );
|
|
void GetAnimationAttr( trpgLightAttr::AnimationAttr& );
|
|
void GetAnimationPeriod( float64& );
|
|
void GetAnimationPhaseDelay( float64& );
|
|
void GetAnimationTimeOn( float64& );
|
|
void GetAnimationVector( trpg3dPoint& );
|
|
void GetAnimationFlags( int32& );
|
|
|
|
// operators
|
|
trpgLightAttr& operator = (const trpgLightAttr&);
|
|
bool operator == (const trpgLightAttr&);
|
|
bool operator != (const trpgLightAttr&);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
protected:
|
|
struct DataSet {
|
|
LightType type;
|
|
LightDirectionality directionality;
|
|
trpgColor frontColor;
|
|
float64 frontIntensity;
|
|
trpgColor backColor;
|
|
float64 backIntensity;
|
|
trpg3dPoint normal;
|
|
int32 smc;
|
|
int32 fid;
|
|
int32 flags;
|
|
float64 horizontalLobeAngle;
|
|
float64 verticalLobeAngle;
|
|
float64 lobeRollAngle;
|
|
float64 lobeFalloff;
|
|
float64 ambientIntensity;
|
|
LightQuality quality;
|
|
LightQuality randomIntensity;
|
|
float64 rascalSignificance;
|
|
CalligraphicAttr calligraphicAttr;
|
|
PerformerAttr performerAttr;
|
|
AnimationAttr animationAttr;
|
|
} data;
|
|
};
|
|
|
|
TX_EXDECL class TX_CLDECL trpgLight : public trpgReadWriteable {
|
|
public:
|
|
// Default constructor
|
|
trpgLight(void);
|
|
// Copy constructor
|
|
trpgLight(const trpgLight &);
|
|
// Destructor
|
|
~trpgLight(void);
|
|
|
|
// Set the index pointing into the Light Table
|
|
void SetAttrIndex(int);
|
|
|
|
// Add a new location this light is located at
|
|
void AddVertex(trpg3dPoint);
|
|
|
|
// Returns the number of locations, this light is located at
|
|
void GetNumVertices(uint32 &) const;
|
|
|
|
// Returns the location at a given index
|
|
bool GetVertex(uint32, trpg3dPoint &) const;
|
|
|
|
// Returns the whole list of vertices
|
|
bool GetVertices(trpg3dPoint *) const;
|
|
bool GetVertices(float64 *) const;
|
|
bool GetVertices(float32 *) const;
|
|
|
|
// Returns the index of the Light Attributes in the Light Table
|
|
void GetAttrIndex(int &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// operator
|
|
trpgLight& operator = (const trpgLight &);
|
|
|
|
protected:
|
|
// Here we store the light locations
|
|
std::vector<trpg3dPoint> lightPoints;
|
|
int index;
|
|
};
|
|
|
|
TX_EXDECL class TX_CLDECL trpgLightTable : public trpgReadWriteable {
|
|
public:
|
|
// Default constructor
|
|
trpgLightTable(void);
|
|
|
|
// Copy constructor
|
|
trpgLightTable(const trpgLightTable &);
|
|
|
|
// Destructor
|
|
~trpgLightTable(void);
|
|
|
|
// Adds the given light attrib to the table and increments the total light attrib count.
|
|
int AddLightAttr(const trpgLightAttr&);
|
|
|
|
/* This is the same as AddLightAttr except that it searches for a matching light attrib
|
|
first. This is convenient for writers who aren't keeping track of their
|
|
own light attrib internally.
|
|
*/
|
|
int FindAddLightAttr(const trpgLightAttr&);
|
|
|
|
// Returns the number of light attrib in this table
|
|
bool GetNumLightAttrs(int &) const;
|
|
|
|
// Returns a pointer to a light attrib from a given index
|
|
const trpgLightAttr* GetLightAttrRef(int) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// operator
|
|
trpgLightTable & operator = (const trpgLightTable &);
|
|
|
|
protected:
|
|
// Here we store the light attributes
|
|
std::vector<trpgLightAttr> lightList;
|
|
|
|
};
|
|
|
|
/* Range Info
|
|
These classes live within the trpgRangeTable. They encapsulate range
|
|
information that ties trpgLod nodes together. Their purpose is to provide
|
|
data to the run-time system about the relative priorities of classes of
|
|
features. See the trpgRangeTable for a complete explanation.
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgRange : public trpgReadWriteable {
|
|
public:
|
|
trpgRange(void);
|
|
~trpgRange(void);
|
|
|
|
// Copy constructor
|
|
trpgRange(const trpgRange &);
|
|
|
|
// Set the name and subName (can be NULL)
|
|
void SetCategory(char *cat,char *subCat);
|
|
|
|
/* Get the name and subName
|
|
Name should be the major category (e.g. "trees")
|
|
SubName should be the minor category (e.g. "big trees")
|
|
*/
|
|
void GetCategory(char *cat,int maxCatLen,char *subCat,int maxSubCatLen) const;
|
|
|
|
// Set the lod info
|
|
void SetLodInfo(double in,double out);
|
|
|
|
// Get the lod info (this will be duplicated in the trpgLod node)
|
|
// However, you may want to change these values yourself during a run
|
|
void GetLodInfo(double &in,double &out) const;
|
|
|
|
// Set the priority
|
|
void SetPriority(int);
|
|
|
|
/* Get the priority.
|
|
Priority is a hint to the run-time system as to the relative importance
|
|
of range limited features. Features with lower priorities should be
|
|
sacrified before those with higher priorities.
|
|
*/
|
|
void GetPriority(int &) const;
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Reset back to a clean state
|
|
void Reset(void);
|
|
|
|
// Equality operator
|
|
bool operator == (const trpgRange &) const;
|
|
|
|
// Assignment operator
|
|
trpgRange & operator = (const trpgRange &);
|
|
|
|
protected:
|
|
double inLod,outLod;
|
|
char *category;
|
|
char *subCategory;
|
|
int priority;
|
|
};
|
|
|
|
/* The Range Table is new to 2.0. The goal is to provide information about
|
|
certain classes of features within a TerraPage database. It's intended
|
|
to solve the following problem.
|
|
|
|
Let's say that you have an Image Generator that must draw a given TerraPage
|
|
database at 60Hz. However, it's only hitting 30Hz reliably. Often, some
|
|
feature set (e.g. bushes) must be sacrified in order to reach the target frame rate.
|
|
Determining which features can be throttled back can often be very difficult.
|
|
Scaling all of the LODs will often work, but it's not very elegant. It's
|
|
not selective (you may lose important features as well as unimportant ones)
|
|
and it doesn't easily let turn whole feature sets off.
|
|
|
|
If you do want to selectively turn features on and off or throttle them
|
|
back, you can do so based on node names within the LODs. This can work, however
|
|
you've got the additional overhead of traversing the tree looking for LODs
|
|
and trying to figure out what the names mean. The range table is intended
|
|
to make this task easier.
|
|
|
|
Each trpgLod can (but isn't required to) have an index into the Range Table.
|
|
That index will point to a trpgRange that contains global information
|
|
about that class of LODs. This includes the in/out information already contained
|
|
within the LOD as well as global info. The global information includes a category
|
|
and sub-category as well as an integer priority. The category data is there to
|
|
allow run-time systems to tell users what they're dropping (or allow them to pick).
|
|
The priority is there to tell systems what to get rid of first (according to the
|
|
user who build the TerraPage archive).
|
|
|
|
Priorities are relative to each other within the Range Table. There can be
|
|
duplicates and there may be holes in the numbering.
|
|
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgRangeTable : public trpgReadWriteable {
|
|
public:
|
|
trpgRangeTable(void);
|
|
~trpgRangeTable(void);
|
|
|
|
// Get the given range info
|
|
bool GetRange(int id,trpgRange &) const;
|
|
|
|
// Set the range info for the given ID
|
|
bool SetRange(int id,trpgRange &);
|
|
|
|
// Add a new range and return the ID
|
|
int AddRange(trpgRange &);
|
|
|
|
// Find a matching range and return it or add a new one if needed
|
|
int FindAddRange(trpgRange &);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Assignment operator
|
|
trpgRangeTable & operator = (const trpgRangeTable &);
|
|
|
|
protected:
|
|
std::vector<trpgRange> rangeList;
|
|
};
|
|
|
|
/* All materials are centrally indexed in TerraPage. There is one material
|
|
table per archive. All trpgGeometry nodes point to that material table (with indices)
|
|
for their trpgMaterial definitions.
|
|
|
|
The material table has one wrinkle. It is divided up into sub-tables or channels.
|
|
Each sub-table has the same number of materials, so there will be NxM trpgMaterial
|
|
structures in a trpgMatTable. The sub-tables are intended for use in simple sensor
|
|
simulations. For example, the base table (0) is the purely visual, out the window
|
|
representation. The next table (1) might the Infra-Red version. It's up to the run-time
|
|
system to switch between these two. TerraPage simply provides the means for keeping
|
|
track of it.
|
|
|
|
If you're doing a TerraPage reader you'll get a trpgMatTable from the trpgr_Archive.
|
|
This is your central index for materials. If you can handle the multiple channels/sub-tables
|
|
then you can access those as you need. If you can't, just use 0 for the sub-table index where appropriate.
|
|
|
|
If you're doing a TerraPage writer you'll need to build up a trpgMatTable to pass to
|
|
trpgwArchive. If you're only doing a single sub-table (i.e. visible materials only)
|
|
just use AddMaterial and add them as you go. The trpgMaterial object you build up
|
|
for a given material are copied when you call the add function. So you can have a single
|
|
trpgMaterial, modify just a few fields and call AddMaterial repeatedly.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgMatTable : public trpgReadWriteable {
|
|
public:
|
|
trpgMatTable(void);
|
|
~trpgMatTable(void);
|
|
/* If you intend to have more than one material sub-table you'll
|
|
need to set this first before doing anything else.
|
|
*/
|
|
void SetNumTable(int);
|
|
/* This sets the total number of materials. Each sub-table will
|
|
have this many of its own materials. If you call this function
|
|
you can't use AddMaterial.
|
|
*/
|
|
void SetNumMaterial(int);
|
|
/* Sets a material definition for the given sub-table material ID
|
|
combination. If you only have one sub-table you can use
|
|
AddMaterial instead.
|
|
The two argument version assumes subTable = 0
|
|
*/
|
|
void SetMaterial(int subTable,int mat,const trpgMaterial &);
|
|
void SetMaterial(int,const trpgMaterial &);
|
|
|
|
/* This function should be used if you only have a single material sub-table.
|
|
It searches for a matching material and then adds a new one if it doesn't
|
|
find a match. The new (or old) ID is returned.
|
|
*/
|
|
int AddMaterial(const trpgMaterial &);
|
|
|
|
/* Return the number of sub-tables. This will, most commonly, be 1.
|
|
Any value more than 1 means the archive has alternate material definitions
|
|
(think IR or Radar versions).
|
|
*/
|
|
bool GetNumTable(int &) const;
|
|
/* The number of materials per sub-table. Each sub-table has the same number
|
|
of materials. So there will be N x M number of materials total, but you'll
|
|
only see M of them at any given time.
|
|
*/
|
|
bool GetNumMaterial(int &) const;
|
|
|
|
/* Returns the material definition for the given subTable and the given material
|
|
ID. The most common subTable will be 0 (visual). The material ID comes
|
|
from the value(s) in trpgGeometry.
|
|
*/
|
|
bool GetMaterial(int subTable,int matID,trpgMaterial &) const;
|
|
|
|
/* This is a convenience method for getting a reference to a trpgMaterial object.
|
|
The reason you might want to do this is if you don't want to create a full
|
|
trpgMaterial object to pass to GetMaterial.
|
|
The returned value is only valid until the next GetMaterialRef call.
|
|
*/
|
|
const trpgMaterial *GetMaterialRef(int,int) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
|
|
protected:
|
|
int numTable;
|
|
int numMat;
|
|
std::vector<trpgMaterial> matTables;
|
|
};
|
|
|
|
/* This class holds the texture definition TerraPage uses. Textures are a little
|
|
different than other TerraPage objects for the following reason: they aren't
|
|
stored in the archive. Instead they're stored individually on disk in your
|
|
favorite image format. We don't constrain what that format is, although SGI
|
|
format (.rgb) is always the safest in this industry.
|
|
|
|
Texture objects are really just references to these on-disk textures. As such,
|
|
they're pretty simple. They just consist of a filename. These trpgTexture
|
|
objects will be indexed in a trpgTexTable. The indices you get from trpgMaterial
|
|
objects point to trpgTexture objects through that table. trpgMaterial objects
|
|
should be the only things that have texture indices.
|
|
|
|
If you're doing a TerraPage reader textures are pretty simple to read in. There
|
|
are two ways to do it. First, if you're not doing texture paging, simply read
|
|
them all in, using the trpgTexTable to figure out where they all are. If you
|
|
are doing texture paging (highly recommended) then you'll need to call GetNumTile
|
|
to figure out how many tiles a texture is used in. If it's 1, then this is probably
|
|
a geospecific textures and ought to be paged. If it's more than 1, then it's a
|
|
geotypical texture (i.e. a tree or road) and should be loaded in at the beginning.
|
|
|
|
If you're doing a TerraPage writer you'll need to be creating trpgTexture objects
|
|
as you go and adding them to your central trpgTexTable. If you want to support
|
|
texture paging set the numTile count to 1 for the geospecific textures and more
|
|
than 1 for everything else. There are utility functions for keeping track of all
|
|
of this. It's best to use those.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTexture : public trpgReadWriteable {
|
|
public:
|
|
trpgTexture(void);
|
|
trpgTexture(const trpgTexture &);
|
|
~trpgTexture(void);
|
|
|
|
/* This enum is used to determine where the image is.
|
|
External - Stored in an external file, just like TerraPage 1.x.
|
|
Local - Stored in one of the archive files. The type and size will be here.
|
|
Use trpgrImageHelper to fetch the image, either initially or later.
|
|
Global - This image is really large and parts of it will be referenced
|
|
later within individual tiles. Use the trpgrImageHelper class
|
|
to reference the various parts of the image. Don't load it yourself.
|
|
Template - This isn't an image at all. It's here to represent a class of
|
|
images with a certain size and type. You'll encounter inline materials
|
|
(for pageable textures) in the tiles which make use of this template.
|
|
If you use trpgrImageHelper to fetch those textures, you don't need to
|
|
do anything with this texture.
|
|
*/
|
|
typedef enum {External,Local,Global,Template} ImageMode;
|
|
|
|
/* These are the types of images TerraPage can support for Local and Template
|
|
image modes (see ImageMode). If the image is External or Global, anything
|
|
is fair game, but these are the only types TerraPage can store itself.
|
|
*/
|
|
typedef enum {
|
|
trpg_RGB8,
|
|
trpg_RGBA8,
|
|
trpg_INT8,
|
|
trpg_INTA8,
|
|
trpg_FXT1,
|
|
trpg_Filler, // This is not a texture format. It's here to keep the numbering consistent
|
|
trpg_RGBX, // MCM
|
|
trpg_Unknown,
|
|
trpg_DDS,
|
|
trpg_DXT1,
|
|
trpg_DXT3,
|
|
trpg_DXT5
|
|
} ImageType;
|
|
|
|
// How the image bit planes are organized
|
|
typedef enum {} ImageOrg;
|
|
|
|
// Set the texture name.
|
|
void SetName(const char *);
|
|
/* This is the texture name. You pass in a string of a pre-defined length
|
|
and it returns the texture name in that. */
|
|
bool GetName(char *retStr,int strLen) const;
|
|
|
|
/* Sets the number of tiles this texture is used in. This hint is used by
|
|
readers to determine texture pageability. */
|
|
void SetNumTile(int);
|
|
/* Instead of calling SetNumTile after you've built a database, you can call
|
|
AddTile as you encounter each texture reference (per tile). */
|
|
void AddTile(void);
|
|
|
|
/* This tells you the number of tiles this texture is used in. You can
|
|
use this to do texture paging (if you can support it). It's a pretty
|
|
general meachanism and will work for large scale geospecific terrain textures
|
|
as well as things like specific building pictures.
|
|
When GetImageMode returns Global, expect this value to always be 1. For
|
|
Template texture, it will be set to the total number of uses of the template
|
|
(which should be fairly large).
|
|
*/
|
|
bool GetNumTile(int &) const;
|
|
|
|
// Retrieve the image mode for this texture. See ImageMode for details.
|
|
bool GetImageMode(ImageMode &) const;
|
|
|
|
// Retrieve the image type for this texture. See ImageType for details.
|
|
// This method is only used if ImageMode is Local or Template
|
|
bool GetImageType(ImageType &) const;
|
|
|
|
// Find out how the bit planes are organized. Only important for some types
|
|
// of images
|
|
bool GetImageOrganization(ImageOrg &) const;
|
|
|
|
// Retrieve the size of this image. Valid only for Local and Template textures.
|
|
bool GetImageSize(trpg2iPoint &) const;
|
|
|
|
// Get the location of a Local image
|
|
bool GetImageAddr(trpgwAppAddress &) const;
|
|
|
|
// Figure out the image depth from the type
|
|
bool GetImageDepth(int32 &depth) const;
|
|
|
|
// Determine whether this image (must be Local or Template) has all its mipmaps
|
|
bool GetIsMipmap(bool &) const;
|
|
|
|
// Set the image mode of this texture. Used by writers only.
|
|
void SetImageMode(ImageMode);
|
|
|
|
// Set the image type of this texture. See GetImageType for details.
|
|
void SetImageType(ImageType);
|
|
|
|
// Sets a constant the dictates bit plane organization. Not used for all image
|
|
// types
|
|
void SetImageOrganization(ImageOrg);
|
|
|
|
// Set the image size of this texture. See GetImageSize for details
|
|
void SetImageSize(const trpg2iPoint &);
|
|
|
|
// Set the image location (For Local images only)
|
|
void SetImageAddr(const trpgwAppAddress &);
|
|
|
|
// Set whether or not this is a full set of mipmaps
|
|
void SetIsMipmap(bool);
|
|
|
|
// Set the storage sizes for all mipmap levels
|
|
// void SetStorageSizes(vector<int> &);
|
|
|
|
// Get the storage sizes for all mipmap levels.
|
|
// bool GetStorageSizes(const vector<int> *) const;
|
|
|
|
// Set the number of mipmap levels
|
|
void SetNumMipmap(int);
|
|
|
|
// Set the number of layers used in an RGBX image
|
|
void SetNumLayer(int);
|
|
|
|
// Get the number of layers used in an RGBX image. RGBX images are typically for
|
|
// sensors and contain arbitrary data which is not visual.
|
|
bool GetNumLayer(int &) const;
|
|
|
|
/* Utility to figure out the number of mipmap levels this image would have.
|
|
Only really necessary for Local or Template images.
|
|
*/
|
|
int32 CalcNumMipmaps() const;
|
|
|
|
// Calculate the total size of this texture
|
|
int32 CalcTotalSize() const;
|
|
|
|
// Returns the size of a given mip level
|
|
int32 MipLevelSize(int miplevel);
|
|
|
|
// Returns the offset of the mip level in the whole texture data buffer
|
|
int32 MipLevelOffset(int miplevel);
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
trpgTexture & operator = (const trpgTexture &);
|
|
int operator == (const trpgTexture &) const;
|
|
protected:
|
|
// Mode for this texture. See ImageMode for details
|
|
ImageMode mode;
|
|
|
|
// Type of texture (only valid if ImageMode is Local or Template)
|
|
ImageType type;
|
|
|
|
// Organize of image bit planes
|
|
ImageOrg org;
|
|
|
|
// The name really only has meaning for External or Global textures
|
|
char *name;
|
|
int useCount;
|
|
|
|
// The size values are used only if this is a Local or Template image
|
|
int sizeX,sizeY;
|
|
|
|
// Whether or not there are mipmap levels
|
|
bool isMipmap;
|
|
|
|
// Number of mipmap levels, 0 if not present
|
|
int numMipMap;
|
|
|
|
// Number of layers (for RGBX)
|
|
int numLayer;
|
|
|
|
// Sizes of each level. This is important for compressed textures in particular,
|
|
// which may have random sizes. Used only for Local textures.
|
|
std::vector<int> storageSize;
|
|
|
|
// Offset of each level
|
|
std::vector<int> levelOffset;
|
|
|
|
// Address is used only for Local textures
|
|
trpgwAppAddress addr;
|
|
|
|
// calculate the mip level sizes
|
|
void CalcMipLevelSizes();
|
|
};
|
|
|
|
/* The texture table keeps track of all the textures in a TerraPage archive.
|
|
All textures are indexed centrally here. The indices in trpgMaterial objects
|
|
point into a trpgTexTable. Although the trpgMatTable potentially has several
|
|
sub-tables for different representations (visual, IR, etc..), the trpgTexTable
|
|
is not affected by that. All textures, no matter what their use, are indexed
|
|
together here.
|
|
|
|
If you're doing a TerraPage reader you'll get a trpgTexTable back from your
|
|
trpgr_Archive. You'll then want to iterate over the trpgTexture objects and
|
|
load in the ones used in more than one tile. If you can do texture paging
|
|
you should leave the ones only used in 1 tile alone initially. You may also
|
|
want to set up a mapping from texture indices here into whatever your own texture
|
|
repository is. The texture indices in trpgMaterial objects refer to the listing
|
|
here.
|
|
|
|
If you're doing a TerraPage writer you'll want to create one of these and add
|
|
textures as you go. Textures are copied in when you call AddTexture or SetTexture
|
|
so you can reused the trpgTexture object you put together to pass in. The texture
|
|
index returned by AddTexture should be used in the trpgMaterial you'll need to build.
|
|
Textures don't live in isolation and must be applied to geometry through a trpgMaterial.
|
|
After the trpgTexTable is built it will get passed to a trpgwArchive for writing. That
|
|
can be done right before you close the archive.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTexTable : public trpgReadWriteable {
|
|
public:
|
|
trpgTexTable(void);
|
|
trpgTexTable(const trpgTexTable &);
|
|
~trpgTexTable(void);
|
|
|
|
/* Sets the total number of textures in this table. This is used in
|
|
combination with SetTexture. If you can, you should use AddTexture
|
|
and FindAddTexture instead.
|
|
*/
|
|
void SetNumTextures(int);
|
|
/* Adds the given texture to the table and increments the total texture
|
|
count. If you use this, you should not use SetNumTextures and SetTexture.
|
|
*/
|
|
int AddTexture(const trpgTexture &);
|
|
/* This is the same as AddTexture except that it searches for a matching texture
|
|
first. This is convenient for writers who aren't keeping track of their
|
|
own textures internally.
|
|
*/
|
|
int FindAddTexture(const trpgTexture &);
|
|
/* This sets the given texture ID to be the trpgTexture passed in. It's used
|
|
in combination with SetNumTextures. Use AddTexture or FindAddTexture instead
|
|
if you can.
|
|
*/
|
|
void SetTexture(int texID,const trpgTexture &);
|
|
|
|
// Returns the number of textures in this table
|
|
bool GetNumTextures(int &) const;
|
|
// This returns the trpgTexture corresponding to the given ID (from a trpgMaterial)
|
|
bool GetTexture(int texID,trpgTexture &) const;
|
|
/* Does the same thing as GetTexture only it returns a pointer instead.
|
|
You would use this if you don't want a new trpgTexture created for you.
|
|
Assume the value it returns is only good until the next GetTextureRef call.
|
|
*/
|
|
const trpgTexture *GetTextureRef(int) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
|
|
trpgTexTable & operator = (const trpgTexTable &);
|
|
protected:
|
|
std::vector<trpgTexture> texList;
|
|
};
|
|
|
|
/* Models are basically just references in TerraPage. This class just points
|
|
to a model from somewhere else. There are two places it can point. (1) It
|
|
can point externally to a model in some arbitrary format (OpenFlight(tm) is
|
|
a popular one). (2) It can also point to a model within the TerraPage archive.
|
|
The first case is much like trpgTexture objects are treated. That is, the actual
|
|
thing itself is on disk somewhere corresponding to a file name. The second case is
|
|
more like tile terrain geometry. In that case there is scene node type data (LODs,
|
|
groups, geometry, etc...) associated with it.
|
|
|
|
trpgModel objects live within a trpgModelTable. They are indexed there and refered
|
|
to by trpgModelRef objects. Those model references are the only things that explicitly
|
|
use trpgModel objects.
|
|
|
|
If you're doing a TerraPage reader you'll need to take into account whether the
|
|
model is external or internal. If it's external you'll need to read the given file
|
|
and convert it to your own representation. If it's internal you've probably already
|
|
got the code for dealing with terrain tiles, which is essentially the same thing.
|
|
Models can be paged, if you're so inclined. They have tile reference counts just
|
|
like trpgTexture objects. If numTile == 1 then page it, if > 1 then don't.
|
|
|
|
If you're doing a TerraPage writer you'll want to build up a trpgModelTable of these
|
|
as you encounter them. If your models are external in some other format then setting
|
|
up a trpgModel is pretty easy. If you want to do internal models, the support is not
|
|
quite there yet.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgModel : public trpgReadWriteable {
|
|
public:
|
|
trpgModel(void);
|
|
trpgModel(const trpgModel &);
|
|
~trpgModel(void);
|
|
enum {Local,External};
|
|
// Sets the name of the external model file and sets this model to External type.
|
|
void SetName(const char *);
|
|
// Sets the on-disk reference to an internal model and sets this model to Internal type.
|
|
void SetReference(trpgDiskRef);
|
|
/* Models are reference counted (per-tile). It's up to the writer to set this
|
|
value. */
|
|
void SetNumTiles(int);
|
|
/* TerraPage writers can use AddTile (starts at 0) every time they use this model
|
|
in a tile. Note that this is not for every instance within a tile. So if
|
|
you use a model 40 times within a tile, you call AddTile once.
|
|
This is used instead of SetNumTiles. */
|
|
void AddTile(void);
|
|
|
|
/* Returns the type (Local or External) of this model */
|
|
bool GetType(int &);
|
|
/* If the model is external, this returns the file name of that model.
|
|
You pass in a string and a length and it copies the filename into that. */
|
|
bool GetName(char *ret,int strLen) const;
|
|
/* If the model is internal, this returns the disk reference to it.
|
|
At some future data you'll be able to simply read these out of an archive. */
|
|
bool GetReference(trpgDiskRef &) const;
|
|
/* Models are reference counted, like trpgTexture objects. You can use this
|
|
value to determine whether or not you should page models.
|
|
*/
|
|
bool GetNumTiles(int &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
|
|
trpgModel & operator = (const trpgModel &);
|
|
int operator == (const trpgModel &) const;
|
|
protected:
|
|
int type;
|
|
char *name;
|
|
trpgDiskRef diskRef;
|
|
int useCount;
|
|
};
|
|
|
|
/* Models (trpgModel) are indexed together in a model table. There is one
|
|
model table per TerraPage archive. It holds the canonical list of models
|
|
for the entire database. It's pretty simple. Just a list of models, really.
|
|
the trpgModel object holds the real information.
|
|
|
|
If you're doing a TerraPage reader you'll get one of these from a trpgr_Archive.
|
|
You'll want to iterate over the models in it and figure out which ones to page,
|
|
if you're doing model paging. If not, then you can just read them all in
|
|
at initialization time and index them as need per-tile.
|
|
|
|
If you're doing a TerraPage writer you'll build one of these up for the entire
|
|
database as you go. Just call AddModel every time you finish a model definition.
|
|
The finished table will be passed to trpgwArchive at the end.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgModelTable : public trpgReadWriteable {
|
|
public:
|
|
trpgModelTable(void);
|
|
~trpgModelTable(void);
|
|
|
|
/* Set the total number of models in the table. Use this in conjunction
|
|
with SetModel. If you can, use AddModel isntead of either of these.
|
|
*/
|
|
void SetNumModels(int);
|
|
/* Add the given model to the table. Makes a copy of the model you pass in
|
|
and returns the new model ID which you'll need to reference in trpgModelRef.
|
|
*/
|
|
int AddModel(const trpgModel &);
|
|
/* Look for a given model. If it's not there, add it. */
|
|
int FindAddModel(const trpgModel &);
|
|
/* Sets the model definition corresponding to the given ID. Use this in conjunction
|
|
with SetNumModels. */
|
|
void SetModel(int,const trpgModel &);
|
|
|
|
// Returns the number of models in this table
|
|
bool GetNumModels(int &) const;
|
|
/* Returns the Nth model. trpgModelRef objects point into this table
|
|
and that is where the model ID comes from. */
|
|
bool GetModel(int modID,trpgModel &) const;
|
|
|
|
/* The same as GetModel only it returns a pointer to the trpgModel instead.
|
|
Use this if you don't want to create a copy of the model.
|
|
The result is only good until the next GetModelRef call.
|
|
*/
|
|
trpgModel *GetModelRef(int);
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
std::vector<trpgModel> models;
|
|
};
|
|
|
|
/* The tile table keeps track of tile locations within a TerraPage archive.
|
|
Tiles can be stored either externally (as individual files) or locally
|
|
(grouped together into bigger files). The details are hidden from the
|
|
reader completely and the writer in most cases.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTileTable : public trpgReadWriteable {
|
|
public:
|
|
// Tiles can be stored individually (External) or in grouped files (Local)
|
|
typedef enum {Local,External} TileMode;
|
|
|
|
trpgTileTable(void);
|
|
~trpgTileTable(void);
|
|
// Set the tile storage mode: external or local
|
|
void SetMode(TileMode);
|
|
// Set the total number of LODs
|
|
void SetNumLod(int numLod);
|
|
// Set the number of tiles in each dimenion for each terrain LOD
|
|
// This must agree with trpgHeader
|
|
void SetNumTiles(int numX,int numY,int lod);
|
|
// Set the external address of a given tile as well as its Z value
|
|
void SetTile(int x,int y,int lod,trpgwAppAddress &,float32 min,float32 max);
|
|
|
|
// Local or external tiles
|
|
bool GetMode(TileMode &) const;
|
|
// Get the disk reference (local)
|
|
bool GetTile(int x,int y,int lod,trpgwAppAddress &,float32 &min,float32 &max) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Reads this class from a read buffer
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
TileMode mode;
|
|
|
|
class LodInfo {
|
|
public:
|
|
int numX,numY;
|
|
// Tile addresses into external Appendable files
|
|
std::vector<trpgwAppAddress> addr;
|
|
// Elevation of the midpoint of each tile
|
|
// This is used for calculating bounding boxes
|
|
std::vector<float> elev_min;
|
|
std::vector<float> elev_max;
|
|
};
|
|
std::vector <LodInfo> lodInfo;
|
|
};
|
|
|
|
/* Local materials are new to TerraPage 2.0.
|
|
The idea is that for pageable one-time textures it makes more sense
|
|
to define them in the tiles. This keeps the size of Texture and
|
|
Material tables down in the header. It also lets us make use of
|
|
Global textures by grabbing subimages.
|
|
You'll encounter these in a tile right after the tile header. They'll
|
|
be referenced by ID in trpgGeometry nodes within that tile. They
|
|
can represent a sub-image of a Global texture or a whole Local texture.
|
|
In either case, you can pass this class to trpgrTextureHelper and let
|
|
it get the image data for you.
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgLocalMaterial : public trpgReadWriteable {
|
|
public:
|
|
trpgLocalMaterial(void);
|
|
~trpgLocalMaterial(void);
|
|
|
|
// Set the base material for this local material
|
|
void SetBaseMaterial(int32 matSubTable,int32 matID);
|
|
|
|
/* Get the base material for this local material. Base materials
|
|
define the colors, specularity, texture environments, and in
|
|
general everything not having to do with the texture image itself.
|
|
In effect you're using the base material as your material definition and
|
|
the local material is just telling you what part of the image to use.
|
|
By convention, there should only be one global image used in any given
|
|
trpgMaterial and it should be at texture index 0 (within that trpgMaterial).
|
|
If you want to use multiple pageable textures per polygon, you can do
|
|
that with multiple materials per trpgGeometry node. Doing it any
|
|
other way makes my head hurt (actually the thought of multiple, pageable
|
|
textures per polygon makes my head hurt in general).
|
|
*/
|
|
bool GetBaseMaterial(int32 &matSubTable,int32 &matID) const;
|
|
|
|
class SubImageInfo {
|
|
public:
|
|
int32 sx,sy; // Source (sx,sy) in pixels
|
|
int32 ex,ey; // Source (ex,ey) in pixels
|
|
int32 destWidth,destHeight; // Size of destination image (in pixels)
|
|
};
|
|
|
|
// Set the sub image info (only for writers)
|
|
void SetSubImageInfo(const SubImageInfo &);
|
|
|
|
/* Get the sub image info. This is valid only for Global images
|
|
(you can check what a given Local Material is by looking at the
|
|
base material's texture).
|
|
*/
|
|
bool GetSubImageInfo(SubImageInfo &) const;
|
|
|
|
// Set the address info (only for writers)
|
|
void SetAddr(const trpgwAppAddress &);
|
|
|
|
/* Get the address (location in an archive) for an image.
|
|
This is valid for Local images only. You can determine what
|
|
a Local Material refers to by looking in its base material's texture.
|
|
*/
|
|
bool GetAddr(trpgwAppAddress &) const;
|
|
|
|
// Set the storage sizes for all mipmap levels
|
|
// bool SetStorageSizes(vector<int> &);
|
|
|
|
// Get the storage sizes for all mipmap levels.
|
|
// bool GetStorageSizes(const vector<int> *) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Reads this class from a read buffer
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
int32 baseMatTable,baseMat;
|
|
// These are valid for Global images
|
|
int32 sx,sy,ex,ey,destWidth,destHeight;
|
|
// Storage sizes for each mipmap level. Important for compressed textures.
|
|
// vector<int> storageSize;
|
|
// This is valid only for Tile Local images
|
|
trpgwAppAddress addr;
|
|
};
|
|
|
|
/* The tile header is one of the more interesting parts of TerraPage. Basically,
|
|
it's a list of all the materials, local material and models used in a tile. Tile headers are
|
|
stuck at the beginning of terrain tiles to give you this information. They
|
|
can be read separately, in theory, although no one is doing that at present.
|
|
|
|
If you're doing a TerraPage reader you will encounter one of these first thing
|
|
when you parse a terrain tile. These are here to aid texture and model paging.
|
|
Texture paging is the most common and there are now two ways of doing it. The
|
|
simpler one (supported in version 1.0) is as follows. Textures are indexed at
|
|
the beginning of a TerraPage archive (in a trpgTexTable) and when listed in the
|
|
trpgTileHeader for a tile must be loaded in for use. You can tell the pageable
|
|
textures from the non-pageable ones by looking at the tile reference count in
|
|
the trpgTexture object.
|
|
|
|
The second way of doing texture paging (in version 2.0) is more complex, but
|
|
much more powerful. One of the big problems we encountered with v1.0 was the
|
|
enormous proliferation of texture files. In addition, much information was
|
|
duplicated between the different terrain resolutions. Lastly, we (TERREX) have
|
|
had a lot of success with wavelet compressed image pyramids for solving quite a
|
|
few interesting problems. This second approach to texture paging makes use of
|
|
what we've learned from all of this. The idea is that instead of having lots of
|
|
little textures, we have a small number of very large images which can support
|
|
extraction at any resolution. In this way we re-use information between terrain
|
|
levels of detail and we cut down on our disk usage, both in terms of number of
|
|
files as well as data size.
|
|
|
|
To implement this scheme we added the trpgLocalMaterial object. trpgTexture
|
|
objects tell you if they are global images (e.g. parts are pageable). If they
|
|
are, then they can be used in a trpgLocalMaterial. These objects define the
|
|
sub-image (extents and a resolution) for a texture/material that can be used
|
|
within this tile (and only within this tile). The trpgLocalMaterial objects
|
|
reside within the trpgTileHeader and should be filled out (e.g. the sub-images
|
|
paged) as soon as the trpgTileHeader is parsed because you'll be needing them
|
|
in trpgGeometry nodes to follow.
|
|
|
|
If you want to page models, you can do so by looking at the list of model IDs
|
|
used in a tile.
|
|
|
|
If you're doing a TerraPage writer you will need to construct one of these for
|
|
each tile that you build (remember that tiles are per-terrain LOD). You'll want
|
|
to call AddMaterial for every material that you use in a tile and AddModel
|
|
for every model. You can call these methods multiple times and it will keep track
|
|
of whether you've already added a model or material. The tile header will then
|
|
be passed to trpgwArchive along with the tile geometry and written to disk.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTileHeader : public trpgReadWriteable {
|
|
public:
|
|
trpgTileHeader(void);
|
|
~trpgTileHeader(void);
|
|
/* Add the given material reference to this tile if it's not already there.
|
|
The ID passed in refers to a trpgMatTable. */
|
|
void AddMaterial(int);
|
|
/* Add the given model reference to this tile if it's not already there.
|
|
The ID passed in refers to a trpgModelTable. */
|
|
void AddModel(int);
|
|
/* Add the given local material to the list of local materials in this tile.
|
|
Local materials are used to page sub-pieces of very large images and
|
|
are referenced by trpgGeometry nodes (in their material indices) within
|
|
a given tile. Local materials can't be referenced across tiles.
|
|
*/
|
|
void AddLocalMaterial(trpgLocalMaterial &);
|
|
// {secret}
|
|
void SetDate(int32);
|
|
/* Set the given material reference to the given value.
|
|
It's easier to use AddMaterial(), if possible.
|
|
*/
|
|
void SetMaterial(int no,int id);
|
|
/* Set the given model reference (in this tile) to the given value
|
|
It's easier to use AddModel(), if possible.
|
|
*/
|
|
void SetModel(int no,int id);
|
|
|
|
// Returns the number of materials used in this tile
|
|
bool GetNumMaterial(int32 &) const;
|
|
/* Return the material ID of the Nth material reference.
|
|
The ID returned points into a trpgMatTable. */
|
|
bool GetMaterial(int32 nth,int32 &matID) const;
|
|
// This is the number of models used in this tile
|
|
bool GetNumModel(int32 &) const;
|
|
/* Gets the model ID of the Nth model reference.
|
|
The ID returned points into a trpgModelTable. */
|
|
bool GetModel(int32 nth,int32 &modID) const;
|
|
// Returns the number of local materials in this tile
|
|
bool GetNumLocalMaterial(int32 &) const;
|
|
/* Return the given local material. Local materials are used
|
|
to page sub-pieces of extremely large images. The Local Material
|
|
list within a tile is distinct from the list of materials used within
|
|
a tile. Local materials will be referenced by trpgGeometry nodes within
|
|
a given tile.
|
|
*/
|
|
bool GetLocalMaterial(int32 nth,trpgLocalMaterial &locMat) const;
|
|
/* Return a pointer to the list of locally defined materials.
|
|
See GetLocalMaterial for an explantion of local materials.
|
|
*/
|
|
const std::vector<trpgLocalMaterial> *GetLocalMaterialList(void) const;
|
|
// {secret}
|
|
bool GetDate(int32 &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
std::vector<int> matList;
|
|
std::vector<int> modelList;
|
|
std::vector<trpgLocalMaterial> locMats;
|
|
// {secret}
|
|
int date;
|
|
};
|
|
|
|
/* The color info structure is used by the trpgGeometry class to store
|
|
per vertex (or per primitive) color information. It can be read directly
|
|
by the user (all its data is public). This structure is returned by
|
|
trpgGeometry::GetColorSet().
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgColorInfo {
|
|
public:
|
|
trpgColorInfo(void);
|
|
~trpgColorInfo(void);
|
|
|
|
/* This is a trpgGeometry::ColorType
|
|
*/
|
|
int type;
|
|
/* This refers to how the colors in the data array are used.
|
|
It can take the values "Overall", "PerPrim" or "PerVertex".
|
|
*/
|
|
int bind;
|
|
/* The list of colors. There will be one total (bind=Overall), one per
|
|
primitive (bind=PerPrim), or one per vertex (bind=PerVertex).
|
|
*/
|
|
std::vector<trpgColor> data;
|
|
/* Resets the structure to a default state.
|
|
*/
|
|
void Reset(void);
|
|
|
|
// Print out debugging info
|
|
bool Print(trpgPrintBuffer &) const;
|
|
};
|
|
|
|
/* This class represents a group of texture coordinates applied to a trpgGeometry
|
|
class. It is returned by trpgGeometry::GetTexCoordSet. TerraPage supports
|
|
multiple materials per polygon. The way we implement this is as multiple
|
|
materials on a trpgGeometry node. The first material with be the "primary"
|
|
and additional ones will be secondary and so on.
|
|
To support this, we need multiple sets of texture coordinates. That's what
|
|
this structure is used for.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTexData {
|
|
public:
|
|
trpgTexData(void);
|
|
~trpgTexData(void);
|
|
// This should always be set to PerVertex
|
|
int bind;
|
|
/* List of texture coordinates in 32 bit floating point.
|
|
There should be one per vertex. Either this or doubleData will be
|
|
set, but never both.
|
|
*/
|
|
std::vector<float32> floatData;
|
|
/* List of texture coordinates in 64 bit floating point.
|
|
There should be one per vertex. Either this or floatData will be
|
|
set, but never both.
|
|
*/
|
|
std::vector<float64> doubleData;
|
|
/* Initialize the texture coordinate data set with floating point or double values.
|
|
num should correspond to the correct bind. */
|
|
void set(int num,int bind,const float32 *);
|
|
void set(int num,int bind,const float64 *);
|
|
/* Resets the structure to a default state.
|
|
*/
|
|
void Reset(void);
|
|
|
|
// Print out debugging info
|
|
bool Print(trpgPrintBuffer &) const;
|
|
};
|
|
|
|
/* The trpgGeometry class represents a low level geometry node within the
|
|
TerraPage "scene graph". This is where the triangles (or quads, polygons, etc...)
|
|
are actually kept. If you're writing a TerraPage reader, you'll encounter a
|
|
lot of these nodes. If you're doing a writer, you'll need to construct them.
|
|
You can use a trpgwGeomHelper to aid you in this process.
|
|
We use data arrays to store lists of vertices, colors, texture coordinates, and
|
|
normals. These data arrays correspond pretty closely to the respective OpenGL
|
|
equivalents.
|
|
|
|
In general, you'll want to do a GetPrimType() to figure out what primitive
|
|
type (PrimType) a given node is holding. It will typically be TriStrips,
|
|
TriFans, or Triangles, but all the other types are valid as well.
|
|
The next step is to get the vertices via a GetVertices() call and then get
|
|
the normals and texture coordinates (via GetNormals() and GetTexCoordSet() calls).
|
|
To get the material information call GetNumMaterial() (if you can support more
|
|
than one texture per polygon) and then GetMaterial() for each material. If you
|
|
only support one material/texture per polygon then just do one GetMaterial() all.
|
|
There's always guaranteed to be at least one material.
|
|
|
|
It's a good idea to review the OpenGL specification for triangle arrays and
|
|
such before diving into this structure.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgGeometry : public trpgReadWriteable {
|
|
public:
|
|
trpgGeometry(void);
|
|
~trpgGeometry(void);
|
|
typedef enum {Points,LineStrips,LineLoops,Lines,Polygons,TriStrips,
|
|
TriFans,Triangles,QuadStrips,Quads} PrimType;
|
|
// Set the primitive type for the geometry node
|
|
void SetPrimType(PrimType type);
|
|
/* Some primitive types require lengths. These include TriStrips and
|
|
TriFans, but not Triangles, for example. */
|
|
void SetPrimLengths(int,const int *);
|
|
/* Add a primitive length on to the end of the current primLength array.
|
|
Use this if you're adding geometry one vertex at a time.
|
|
*/
|
|
void AddPrimLength(int);
|
|
/* This just increments the number of primitives in the structure. Use this
|
|
if you're adding geometry one vertex at a time for a Triangle array, for example.
|
|
*/
|
|
void AddPrim(void);
|
|
/* Set the total number of primitives. You would use this only when the PrimType
|
|
does not require primitive lengths (e.g. Triangles, but not TriStrips). Use
|
|
SetPrimLengths() or AddPrimLength() in that case.
|
|
*/
|
|
void SetNumPrims(int); // Only when there are no primitive lengths
|
|
/* This function sets the total number of materials applied to this group
|
|
of geometry. If you're only using one material, trpgGeometry defaults to
|
|
1, so you can just do a SetMaterial() and ignore this.
|
|
*/
|
|
void SetNumMaterial(int);
|
|
/* Set the given material instance (in this trpgGeometry node) to the given
|
|
material ID. The material ID is an index into a trpgMatTable. You would
|
|
need to do a SetNumMaterial() call first, before any number of SetMaterial()
|
|
calls if there is more than one material. If there is only one material,
|
|
you can do a single SetMaterial(0,MatID) call.
|
|
Negative materials IDs denote local material definitions (e.g. parts of
|
|
a larger, paged image). They will always be returned as positive by
|
|
GetMaterial, however you must set them as negative so that GetMaterial
|
|
can set its isLocal bit on return.
|
|
*/
|
|
void SetMaterial(int which,int matID,bool isLocal=false);
|
|
/* This is the same as repeated SetMaterial() calls.
|
|
*/
|
|
void SetMaterials(int32 numMat,const int32 *matIDs);
|
|
/* This adds the given material ID to the end of the material list.
|
|
You can use this instead of SetNumMaterial() and SetMaterial().
|
|
*/
|
|
int AddMaterial(int matID);
|
|
|
|
// These are primitive types used within the trpgGeometry structure.
|
|
enum {VertexFloat,VertexDouble,NormalFloat,NormalDouble,
|
|
Color,TextureFloat,TextureDouble,EdgeFlag};
|
|
|
|
/* Used to tell some of the trpgGeometry methods what kind of
|
|
data they're getting */
|
|
typedef enum {FloatData,DoubleData} DataType;
|
|
|
|
/* The SetVertices() methods will set either 32 or 64 bit floating
|
|
point vertex arrays within the trpgGeometry structure.
|
|
The num passed in is the number of vertices, not the number of individual
|
|
floats or doubles (as with GetNumVertex).
|
|
*/
|
|
void SetVertices(int num,const float32 *);
|
|
void SetVertices(int num,const float64 *);
|
|
/* This method will add a vertex to the end of the appropriate data array
|
|
(either float or double, but never both). You would use this method
|
|
if you were building up a trpgGeometry structure vertex by vertex.
|
|
*/
|
|
void AddVertex(DataType type,trpg3dPoint &);
|
|
/* Binding type used by colors, normals, and textures (just PerPrim).
|
|
*/
|
|
typedef enum {Overall,PerPrim,PerVertex} BindType;
|
|
/* The SetNormals() methods will set either the 32 or 64 bit floating
|
|
point normal arrays within the trpgGeometry structure.
|
|
The num of normals is determined by the bind type. You should
|
|
either set the 32 or 64 bit floating point arrays, but not both.
|
|
num is the number of individual normals, not float values, unlike
|
|
the GetNumNormal() call.
|
|
*/
|
|
void SetNormals(int num,BindType bind,const float32 *);
|
|
void SetNormals(int num,BindType bind,const float64 *);
|
|
/* This method is used to add normals one by one of the given type.
|
|
You would use this if you were adding geometry one vertex at a time
|
|
in conjuntion with AddVertex().
|
|
*/
|
|
void AddNormal(DataType type,trpg3dPoint &);
|
|
/* This constant is used to select the type of a color array
|
|
passed to SetColors().
|
|
*/
|
|
typedef enum {Ambient,Diffuse,Specular,Emission} ColorType;
|
|
/* This method sets an array of color structures for a trpgGeometry node.
|
|
The num should correspond to the bind type. You can set as many of
|
|
these color arrays as you like, they're simply stored in an array for
|
|
later use.
|
|
*/
|
|
void SetColors(int num,ColorType type,BindType bind,const trpgColor *);
|
|
/* The SetTexCoords() methods set a list of texture coordinates. This
|
|
essentially builds a trpgTexData class and pushes it onto the current
|
|
list of texture coordinate sets. Choose the appropriate method based
|
|
on 32 or 64 bit floating point values. num should be the number of
|
|
texture coordinates, not the number of floats passed in.
|
|
|
|
bind should be PerPrim in all cases.
|
|
*/
|
|
void SetTexCoords(int num,BindType bind,const float32 *);
|
|
void SetTexCoords(int num,BindType bind,const float64 *);
|
|
/* This is the same as SetTexCoords(0,bind,NULL) */
|
|
void AddTexCoords(BindType bind);
|
|
/* This method adds a texture coordinate to array 0. You would use
|
|
this if you were adding vertices one at a time.
|
|
*/
|
|
void AddTexCoord(DataType type,trpg2dPoint &);
|
|
/* Edge flags are used by some primitives in OpenGL. We don't typically
|
|
use them, but they can be read and written with TerraPage.
|
|
*/
|
|
void SetEdgeFlags(int num,const char *);
|
|
|
|
/* Returns the primitive type for this trpgGeometry structure.
|
|
*/
|
|
bool GetPrimType(PrimType &type) const;
|
|
/* Number of primitives in this structure. Primitives are things
|
|
like a single triangle, a triangle strip or fan. Some primitives
|
|
require a primitive length array.
|
|
*/
|
|
bool GetNumPrims(int &num) const;
|
|
/* This returns the primitive length array. Some primitive types, like
|
|
TriStrips or TriFans (but not Triangles) require a primitive length
|
|
array to tell you how to break up the vertex/normal/texture/color
|
|
arrays into individual primitives. The array you pass in must be
|
|
of a certain length (returned by GetNumPrims()) and will only be
|
|
valid for some primitive types.
|
|
*/
|
|
bool GetPrimLengths(int *lenArray) const;
|
|
/* TerraPage supports multiple materials per geometry set. This method
|
|
tells you how many are applied to this structure. There will always
|
|
be at least one.
|
|
*/
|
|
bool GetNumMaterial(int &num) const;
|
|
/* Returns the material ID for a material instance. num is the
|
|
nth material instance. matId is an index into a trpgMatTable.
|
|
isLocal is true if the given material is local to this tile.
|
|
Local materials are only used to page small pieces of a larger image.
|
|
*/
|
|
bool GetMaterial(int num,int32 &matID,bool &isLocal) const;
|
|
/* This returns num_vertex. The function returns the length
|
|
of the vertex array dived by 3, which is the total number of
|
|
vertices.
|
|
*/
|
|
bool GetNumVertex(int &num) const;
|
|
/* The GetVertices() methods return a list of vertices in the given
|
|
form (32 or 64 bit floating point). These functions will convert to
|
|
the appropriate format, just ask for the one you need.
|
|
The length of the vertex array is determined by GetNumVertex(), which
|
|
returns 3* the number of vertices.
|
|
*/
|
|
bool GetVertices(float32 *) const;
|
|
bool GetVertices(float64 *) const;
|
|
|
|
bool GetVertices(osg::Vec3*) const;
|
|
/* This method lets you get an individual vertex. The number of vertices
|
|
can be determined by GetNumVertex()/3.
|
|
*/
|
|
bool GetVertex(int id,trpg3dPoint &) const;
|
|
/* GetNumNormal() returns the number of normals. See GetNumVertex()
|
|
for an explanation of why.
|
|
*/
|
|
bool GetNumNormal(int &num) const;
|
|
/* Much, like GetVertices(), these methods will copy the contents of
|
|
the normal array into the array passed in. They will convert the
|
|
contents to the appropriate format (32 or 64 bit floating point).
|
|
The length of the input array can be determined by GetNumNormal().
|
|
*/
|
|
bool GetNormals(float32 *) const;
|
|
bool GetNormals(float64 *) const;
|
|
bool GetNormals(osg::Vec3*) const;
|
|
/* This returns the number of color sets in the trpgGeometry structure.
|
|
There can be one color set per ColorType. Color sets are either
|
|
per vertex, per primitive, or per geometry unit (i.e. only one)
|
|
arrays of color data.
|
|
*/
|
|
bool GetNumColorSets(int &num) const;
|
|
/* This method fills out the trpgColorInfo class that you pass in.
|
|
The number of color sets is determined by GetNumColorSets and
|
|
the structure you passed can be reused (to save memory).
|
|
*/
|
|
bool GetColorSet(int id,trpgColorInfo *) const;
|
|
/* Returns the number of texture coordinate sets. There could (and
|
|
should) be one texture coordinate set per material applied to this
|
|
geometry. Tex Coord sets can be retrieved with GetTexCoordSet.
|
|
*/
|
|
bool GetNumTexCoordSets(int &) const;
|
|
/* This method returns the texture coordinate set specified by the given
|
|
index. GetNumTexCoordSets determines the total number of texture
|
|
coordinate sets.
|
|
*/
|
|
bool GetTexCoordSet(int id,trpgTexData *) const;
|
|
/* Returns the number of edge flags in this geometry node.
|
|
Edge flags are used on certain primitive types, but are rather rare.
|
|
*/
|
|
bool GetNumEdgeFlag(int &num) const;
|
|
/* This returns the edge flags for the current set of primitives.
|
|
*/
|
|
bool GetEdgeFlags(char *) const;
|
|
|
|
// Returns true if the trpgGeometry structure is valid
|
|
bool isValid(void) const;
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Write self to a buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Read self from a buffer. Check isValid() afterwards
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
int primType;
|
|
int numPrim;
|
|
std::vector<int> primLength;
|
|
std::vector<int> materials;
|
|
std::vector<float> vertDataFloat;
|
|
std::vector<double> vertDataDouble;
|
|
int normBind;
|
|
std::vector<float> normDataFloat;
|
|
std::vector<double> normDataDouble;
|
|
std::vector<trpgColorInfo> colors;
|
|
std::vector<trpgTexData> texData;
|
|
std::vector<char> edgeFlags;
|
|
};
|
|
|
|
/* This is a standard Group that you might see in any reasonable
|
|
scene graph. It holds a number of children. TerraPage isn't
|
|
actually a scene graph, it just represents one. That means that there
|
|
are no pointers to children here. Instead you'll encounter this group
|
|
while reading a terrain tile or model. That tells you to create a group
|
|
(or whatever you call it) in your own system and get read to dump child
|
|
trees into it. A push will follow this object, then the children (however
|
|
deep they may be) then a pop.
|
|
|
|
All groups have IDs. These IDs are unique among groups and group-like things
|
|
(i.e. LODs) and are used to hook trpgAttach geometry into a scene graph hierachy
|
|
as you page in higher terrain levels of detail.
|
|
|
|
If you're doing a TerraPage reader, the group tells you to put together
|
|
your generic container in a scene graph and get read for the push/children/pop.
|
|
The NumChild field should tell you how many children will follow, but a writer
|
|
can easily forget to put it, so be wary. You'll also want to look at the group
|
|
ID and build a mapping from that ID (look at the max group ID in trpgHeader) to
|
|
your own group structure. A trpgAttach is allowed to page itself into any group.
|
|
|
|
If you're doing a TerraPage writer you'll create one of these, fill out the
|
|
numChild hint, the group ID and then write it. You'll then write a Push, then
|
|
the children hierarchies (which can be anything) followed by a Pop. You'll want
|
|
to keep track of the group ID you assigned in case one of the children is a
|
|
pageable chunk of terrain hierarchy.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgGroup : public trpgReadWriteable {
|
|
public:
|
|
trpgGroup(void);
|
|
virtual ~trpgGroup(void);
|
|
// Resets the contents back to empty
|
|
virtual void Reset(void);
|
|
|
|
/* Set the total number of children this group will have */
|
|
virtual void SetNumChild(int);
|
|
// Starting from 0, increments the number of children
|
|
virtual int AddChild(void);
|
|
/* The writer is supposed to set this value to the number of
|
|
children. */
|
|
virtual bool GetNumChild(int &) const;
|
|
|
|
/* Set the group ID */
|
|
virtual void SetID(int);
|
|
// Returns the group ID
|
|
virtual bool GetID(int &) const;
|
|
|
|
/* Set the group name */
|
|
void SetName(const char* );
|
|
// Returns the group name
|
|
const char* GetName(void) const;
|
|
|
|
// Validity check
|
|
virtual bool isValid(void) const;
|
|
// Writes this class to a write buffer
|
|
virtual bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
int id;
|
|
int numChild;
|
|
char* name;
|
|
};
|
|
|
|
/* Structurally, an attach is just like a trpgGroup. It does everything a group
|
|
does, plus a little bit more. The attach node is how TerraPage does terrain
|
|
database paging across LODs.
|
|
|
|
In TerraPage we don't enfoced a terrain LOD structure. Let's say you built
|
|
your database as a quad-tree. That is, there is one root tile per block,
|
|
4 children, each of which has 4 of its own children etc... That would imply
|
|
a certain structure (4 children per tile until you reach the bottom). That would
|
|
also lock you into a database scheme (quad-tree). However, let's assume that
|
|
someone else wanted to do replacement LOD for their terrain. That scheme works
|
|
by having one child per tile. If you want to support both of these then you're
|
|
asking the reader to do a lot of thinking and you can pretty much assume that the
|
|
one you don't test won't work. We decided to avoid all that by coming up with a
|
|
generic scene graph paging scheme. It's a little more painfull, but once you deal
|
|
with it you get whatever weird scheme the writer is using for free without having to
|
|
think about it.
|
|
|
|
Here's how it works. Each trpgGroup and group-like structure (trpgLod for example)
|
|
has a unique group ID. You can have one trpgAttach at the start of a given terrain
|
|
tile. That trpgAttach can point to any group within the scene graph (with a group ID).
|
|
Level of detail for the terrain is controlled by trpgLod nodes as if everything was
|
|
loaded in all the time. That is, you'll see the same thing no matter whether every node
|
|
is loaded into memory or just the nearby ones. The theoretical scene graph structure
|
|
is the same no matter what. It's the ranges in your trpgHeader that tell you when
|
|
things ought to be loaded in, but the actual display logic is contained within the trpgLod
|
|
objects. It sounds complicated and it is... for the writer. But for the reader it's
|
|
really simple.
|
|
|
|
If you're doing a TerraPage reader all you'll need to do is keep a mapping from group
|
|
ID's to your own internal scene graph node representation. Then when a trpgAttach shows
|
|
up you can turn it into your own group-like thing and stuff it and its children into
|
|
the scene graph. When it wanders out of range (the trpgHeader tells you that for a given
|
|
terrain LOD) you simply delete it. If you out-run your paging you've got two options:
|
|
(1) Display holes. That's what will happen when the LOD above a given tile trpgAttach
|
|
turns on without the children in memory; or (2) Don't switch LODs that don't have all
|
|
their children loaded in yet. Be aware that a trpgAttach inherits from trpgGroup and
|
|
so can have trpgAttach children. So don't absorb the trpgAttach even though it's extra
|
|
hierarchy. Also, don't make any assumptions that there is really terrain in a given
|
|
tile. The writer may have chosen to page buildings or trees. You never know and there's
|
|
no reason to assume.
|
|
|
|
If you're doing a TerraPage writer this is slightly more complex than writing a normal
|
|
format, depending on the structure of your internal scene graph. If you don't want
|
|
to write more than one pageable terrain LOD you can just ignore trpgAttach nodes. This
|
|
doesn't mean you can only have one terrain LOD, it only means they won't be pageable.
|
|
If you do want to fully support it, what you'll need to
|
|
do is give all your groups (or whatever will become groups) unique IDs, keeping in mind
|
|
to update the trpgHeader max group ID as you go. Start at the lowest terrain lod. This
|
|
one doesn't need to have a trpgAttach node since it's at the top. Traverse toward
|
|
the higher lods. When you hit one, spit out a trpgAttach, giving it the group ID of
|
|
the trpgGroup directly above it. Then treat the node you just created as a trpgGroup
|
|
(i.e. do its children as normal). You will also need to keep the trpgTileHeader for
|
|
each tile around. It's best to index these by (x,y,lod) index. You'll need to build
|
|
that tile header up *just for this tile geometry*. That means you have to stop adding
|
|
material/model references when you start defining the next tile. Depending on how you
|
|
write out your scene graph it may make sense to keep a stack of trpgTileHeader and
|
|
trpgMemWriteBuffer objects around indexed by tile (x,y,lod).
|
|
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgAttach : public trpgGroup {
|
|
public:
|
|
trpgAttach(void);
|
|
~trpgAttach(void);
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Set the parent of the group/LOD/whatever to attach to when loaded in
|
|
void SetParentID(int);
|
|
// Retrieve the parent ID we'll need to attach this thing into the scene graph
|
|
bool GetParentID(int &) const;
|
|
|
|
/* The writer is supposed to set this value to a unique position with relation
|
|
to its parent group. */
|
|
void SetChildPos(int);
|
|
/* The child position is a hint as to which child this is in its parent group.
|
|
That is, if there are 3 children, of which this is one, then it could be
|
|
at child position 0, 1, or 3 in its parent. You can safely ignore this if
|
|
you want to just this node to its parent's list of children. */
|
|
bool GetChildPos(int &) const;
|
|
|
|
// Validity check
|
|
bool isValid(void) const;
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
int parentID,childPos;
|
|
};
|
|
|
|
/* The billboard inherits from the standard trpgGroup. It tells the reader that
|
|
everything underneath this node is supposed to be treated like a stamp or billboard
|
|
(depending on your terminology). That means it's supposed to be rotated towards
|
|
the eye point in some way. There are no restrictions on the number, depth, or type
|
|
of children. In theory you could have another billboard as a child, although we have
|
|
no idea what that should look like.
|
|
|
|
If you're doing a TerraPage reader treat everything underneath this group as rotatable.
|
|
Pay attention to the Type in particular. There's a shorthand for rotating a bunch
|
|
of objects that is a little confusing.
|
|
|
|
If you're doing a TerraPage write this is pretty simple. For the standard tree example
|
|
use one of these with one or more trpgGeometry children.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgBillboard : public trpgGroup {
|
|
public:
|
|
trpgBillboard(void);
|
|
~trpgBillboard(void);
|
|
enum {Individual,Group};
|
|
// Set the type. See GetType for details.
|
|
void SetType(int);
|
|
// Set the center.
|
|
void SetCenter(const trpg3dPoint &);
|
|
enum {Axial,World,Eye};
|
|
// Set the rotation mode.
|
|
void SetMode(int);
|
|
// Set the rotation axis if mode == Axial
|
|
void SetAxis(const trpg3dPoint &);
|
|
|
|
/* The type controls how the billboard node relates to its children. There
|
|
are two modes: (1) Group - This is the obvious one. Everything below
|
|
this node rotates around the center in the way specified by GetMode. (2) Individual - This
|
|
is a little weirder. Basically, it's here for trees. It's assumed that
|
|
there will be one or more trpgGeometry nodes below this node. Each single
|
|
primitive is supposed to rotate "seperately". That is, you must take into
|
|
account the unique center of each one and rotate it around that. If you have
|
|
some optimization scheme where you can deal with groups of billboards (ala Performer)
|
|
it is valid to do so in the Individual case. */
|
|
bool GetType(int &) const;
|
|
/* Center of the thing to be rotated. For Group this does the obvious thing.
|
|
For Individual it should be the center of the group of things you want to rotate.
|
|
This has no use if you're going to rotate each primitive seperately, but if you've
|
|
got some sort of optimized scheme for doing so (ala Performer) this information is useful.
|
|
*/
|
|
bool GetCenter(trpg3dPoint &) const;
|
|
/* The mode will be one of: (1) Axial - rotate around the Axis. This is the normal
|
|
one for tree. (2) Eye - Always rotate toward the eye point. (3) world.
|
|
*/
|
|
bool GetMode(int &) const;
|
|
/* The axis used when GetMode returns Axial. */
|
|
bool GetAxis(trpg3dPoint &) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
protected:
|
|
int type;
|
|
int mode;
|
|
trpg3dPoint center;
|
|
trpg3dPoint axis;
|
|
};
|
|
|
|
/* TerraPage level of detail nodes are pretty simple. Even though they don't inherit from trpgGroup,
|
|
they have many of the same calls and act, structurally at least, in much the same way. These
|
|
act as a switch. When the user's eye point is within a distance then the children of this
|
|
node should be turned on for display. Otherwise, the children will be invisible.
|
|
|
|
A simple on/off test for a TerraPage lod might look like this:
|
|
If ( in < dist < out || out < dist < in) then
|
|
Turn children on
|
|
else
|
|
Turn children off.
|
|
|
|
There is also a transition width can be used to fade LODs in and out around
|
|
the transition zones. Keep in mind that these LODs are binary. Children
|
|
are either on or off (in the process of being turned off). The position of
|
|
a child doesn't have any special meaning with respect to range.
|
|
|
|
If you're doing a TerraPage reader you'll need to turn this into your own LOD
|
|
structure. Keep in mind that trpgAttach nodes can and do attach to trpgLod
|
|
nodes. If you have a general purpose LOD in your scene graph this should be
|
|
pretty easy. However, you must have implemented the concept of LOD center and
|
|
you definitely should *not* recalculate the LOD center yourself based on the
|
|
center of child geometry. They may not be the same. In fact, many terrain
|
|
LOD schemes depend on them not being the same.
|
|
|
|
If you're doing a TerraPage writer you'll need to use these both for geometry
|
|
that you want to disappear at certain distances (e.g. trees, houses, etc..), but
|
|
also terrain. Any terrain LOD scheme you implement must use these to drop out
|
|
polygons in the distance. You'll need to set the center and in/out/width info.
|
|
Otherwise it's like a group.
|
|
|
|
In TerraPage 2.0 we added the Range Index field. This field is here to help
|
|
run-time systems gracefully degrade visual fidelity. The trpgLod node still acts
|
|
like a normal LOD and you can safely ignore the range index field. If, however,
|
|
you want to use it, please read the documention on the trpgRangeTable for further
|
|
information.
|
|
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgLod : public trpgReadWriteable {
|
|
public:
|
|
trpgLod(void);
|
|
~trpgLod(void);
|
|
// Set the calculated center
|
|
void SetCenter(const trpg3dPoint &);
|
|
// Set the number of children hint
|
|
void SetNumChild(int);
|
|
// Set the LOD information
|
|
void SetLOD(double in,double out,double width);
|
|
|
|
// Center of this LOD. Distance from the viewer is calculated from this.
|
|
bool GetCenter(trpg3dPoint &) const;
|
|
// Number of children hint.
|
|
bool GetNumChild(int &) const;
|
|
// LOD specific information. in and out can be switched. width is
|
|
// the transition range for doing fading.
|
|
bool GetLOD(double &in,double &out,double &width) const;
|
|
|
|
// Set the group ID
|
|
void SetID(int);
|
|
|
|
// Group IDs are used here the same way as in trpgGroup
|
|
bool GetID(int &) const;
|
|
|
|
/* Set the lod name */
|
|
void SetName(const char* );
|
|
// Returns the lod name
|
|
const char* GetName(void) const;
|
|
|
|
// Set the range Index
|
|
void SetRangeIndex(int ri);
|
|
// Get the range index
|
|
bool GetRangeIndex(int &ri) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
protected:
|
|
int numRange;
|
|
double switchIn,switchOut,width;
|
|
trpg3dPoint center;
|
|
int id;
|
|
char* name;
|
|
int rangeIndex;
|
|
};
|
|
|
|
/* Layers are used to draw subface geometry. That is, geometry that is
|
|
coplanar. This object should be treated just like a group otherwise.
|
|
Its existence implies the layering effect. There is no other associated
|
|
information.
|
|
|
|
If you're doing a TerraPage reader you should assume that each child,
|
|
starting at 0 should be draw one after the other using whatever subfacing
|
|
scheme you support. There are no restrictions on what the children may
|
|
be, but we strongly recommend that writers keep this simple. Keep in
|
|
mind that trpgAttach nodes can legally appear as children. If you can pull
|
|
it off this has a rather nice effect (think strips on runways). If not,
|
|
don't sweat it.
|
|
|
|
If you're doing a TerraPage writer, this is fairly simple. Obey the ordering
|
|
contraints and try to keep this simple. Ideally that would mean just a few
|
|
trpgGeometry nodes below this node. Also keep in mind that layering works
|
|
very poorly on most OpenGL systems.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgLayer : public trpgGroup {
|
|
public:
|
|
trpgLayer(void);
|
|
~trpgLayer(void);
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
protected:
|
|
};
|
|
|
|
/* This is pretty much a standard 4x4 static transform. It has a matrix
|
|
which controls where its children wind up in 3D. Otherwise it acts just
|
|
like a trpgGroup.
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgTransform : public trpgGroup {
|
|
public:
|
|
trpgTransform(void);
|
|
~trpgTransform(void);
|
|
|
|
// Set the 4x4 matrix
|
|
void SetMatrix(const float64 *);
|
|
|
|
// Get the 4x4 matrix
|
|
bool GetMatrix(float64 *) const;
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
protected:
|
|
float64 m[4][4];
|
|
};
|
|
|
|
/* TerraPage treats model references pretty much like instances. Models
|
|
are organized centrally in a trpgModelTable. This class simply points
|
|
into there with a model ID. There is also a 4x4 matrix (ala trpgTransform)
|
|
which moves the model to its final location.
|
|
|
|
If you're doing a TerraPage reader you should already have dealt with the
|
|
trpgModelTable by this point. Presumably you've got a mapping from model IDs
|
|
to small scene graphs in your own representation. This can be treated just like
|
|
an instance into one of those.
|
|
|
|
If you're doing a TerraPage writer this is pretty simple. When you encounter
|
|
a model (external reference) add it to your trpgModelTable and stuff the resulting
|
|
model ID into one of these. Stick that trpgModelRef into your tile data stream.
|
|
You'll need to fill out the matrix to scale/translate/rotate it as well.
|
|
The model is assumed to be spatially within the tile it's written into. That isn't
|
|
enforced, though.
|
|
|
|
{group:Read/Write Classes}
|
|
*/
|
|
TX_EXDECL class TX_CLDECL trpgModelRef : public trpgReadWriteable {
|
|
public:
|
|
trpgModelRef(void);
|
|
~trpgModelRef(void);
|
|
// Set the model ID. Must come from a trpgModelTable
|
|
void SetModel(int);
|
|
// Set the 4x4 rotate/translate/scale matrix
|
|
void SetMatrix(const float64 *);
|
|
|
|
// Model ID pointing into a trpgModelTable
|
|
bool GetModel(int32 &) const;
|
|
// Positional matrix. Works just like a trpgTransform.
|
|
bool GetMatrix(float64 *) const;
|
|
|
|
// Writes this class to a write buffer
|
|
bool Write(trpgWriteBuffer &);
|
|
// Reads this class from a read buffer
|
|
bool Read(trpgReadBuffer &);
|
|
// Prints this class to a print buffer
|
|
bool Print(trpgPrintBuffer &) const;
|
|
|
|
// Resets the contents back to empty
|
|
void Reset(void);
|
|
protected:
|
|
int modelRef;
|
|
float64 m[4][4];
|
|
};
|
|
|
|
#endif
|