OpenSceneGraph/include/osgTXP/trpage_write.h

302 lines
9.9 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 _txpage_write_h_
// {secret}
#define _txpage_write_h_
/* trpage_write.h
Classes that are used to write paging archives.
*/
#include <osgTXP/trpage_sys.h>
#include <osgTXP/trpage_io.h>
#include <osgTXP/trpage_swap.h>
/* Geometry Stats
Used with a Geometry Helper to keep track of what go built.
{group:Archive Writing}
*/
TX_EXDECL class TX_CLDECL trpgwGeomStats {
public:
trpgwGeomStats(void);
~trpgwGeomStats(void);
int totalTri; // Total # of triangles
int totalQuad; // Total # of quads
// Add up to totalTri
int totalStripTri; // triangles in strips
int totalFanTri; // triangles in fans
int totalBagTri; // loose triangles
int numStrip; // Number of distinct strips
int numFan; // Number of distinct fans
int stripStat[15]; // Strip length stats
int fanStat[15]; // Fan length stats
int stripGeom; // Number of seperate trpgGeometry nodes for strips
int fanGeom; // Same for fans
int bagGeom; // Same for bags
int stateChanges; // Number of distinct material switches
// Helper functions
inline void AddStripStat(int val) { stripStat[MIN(14,val)]++; totalStripTri += val; totalTri += val; numStrip++;}
inline void AddFanStat(int val) { fanStat[MIN(14,val)]++; totalFanTri += val; totalTri += val; numFan++;}
inline void AddBagStat(int val) { totalBagTri += val; totalTri += val;}
inline void AddQuadStat(int val) { totalQuad++; }
};
/* Geometry Helper
Collects up geometry and tries to form triangle strips, fans,
and groups of triangles.
Right now this looks for a very careful ordering. If that ordering
isn't there you won't get useful tristrips or fans. You can, however
use this class as a starting point and build something more akin
to the geometry builder in Performer.
{group:Archive Writing}
*/
TX_EXDECL class TX_CLDECL trpgwGeomHelper {
public:
trpgwGeomHelper(void);
virtual ~trpgwGeomHelper(void);
enum {UseDouble,UseFloat};
trpgwGeomHelper(trpgWriteBuffer *,int dataType=UseDouble);
void init(trpgWriteBuffer *,int dataType=UseDouble);
virtual void SetMode(int); // Takes a trpgGeometry primitive type (triangle by default)
virtual void Reset(void);
// Start/End polygon definition
virtual void StartPolygon(void);
virtual void EndPolygon(void);
virtual void ResetPolygon(void); // If you change your mind about the current poly
// Set the current state
// Note: Currently you *must* set all of these
virtual void SetColor(trpgColor &);
virtual void SetTexCoord(trpg2dPoint &);
virtual void SetNormal(trpg3dPoint &);
virtual void SetMaterial(int32);
// Pull the state info together and add a vertex
virtual void AddVertex(trpg3dPoint &);
// Dump whatever we're doing and move on
virtual void FlushGeom(void);
// Get the Min and Max Z values
virtual void GetZMinMax(double &min,double &max);
// Get statistics for whatever we built
trpgwGeomStats *GetStats(void) { return &stats; }
protected:
int mode;
int dataType;
trpgWriteBuffer *buf;
/* Builds strips and fans from the triangle array.
We (TERREX) are assuming a certain ordering in our vertex array
because we do this optimization elsewhere. This won't work well
for anyone else. What you will need to do if you want good
performance is to implement a more generic form of this method.
All you should have to do is override Optimize(). You've
got the triangle arrays and a guarantee that the triangles
have the same material. All you really need is a decent fan/strip
algorithm.
*/
virtual void Optimize(void);
// Reset Triangle arrays
virtual void ResetTri(void);
// Collections of geometry
trpgGeometry strips,fans,bags;
// Temporary data arrays for triangles/quads
int32 matTri;
std::vector<trpg2dPoint> tex;
std::vector<trpg3dPoint> norm,vert;
// Data arrays for a polygon
int32 matPoly;
std::vector<trpg2dPoint> polyTex;
std::vector<trpg3dPoint> polyNorm,polyVert;
// Single points
trpg2dPoint tmpTex;
trpg3dPoint tmpNorm;
trpgColor tmpCol;
// Geometry status built up as we go
trpgwGeomStats stats;
// Keeps track of min and max z values
double zmin,zmax;
};
/* Image Write Helper.
Used to manage textures being added to a TerraPage archive.
It can write Local and Tile Local textures and also manages
the names of External textures (but you have to write those yourself).
*/
TX_EXDECL class TX_CLDECL trpgwImageHelper {
public:
trpgwImageHelper(trpgEndian ness,char *dir,trpgTexTable &);
virtual ~trpgwImageHelper(void);
// Adds an entry to the texture table for an external texture
virtual bool AddExternal(char *name,int &texID);
/* Adds an entry to the texture table for a local texture and
writes the data for that texture out to one of our texture
archive files.
*/
virtual bool AddLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,bool isMipmap,char *data,int &texID);
/* Write a Tile Local texture out to one of our texture archive files.
Also creates a texture template, if necessary.
Caller is responsible for creating the Tile Local material and
placing it in the appropriate tile.
*/
virtual bool AddTileLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,bool isMipmap,char *data, int &texID,trpgwAppAddress &addr);
/* Sets the maximum advised length for a texture archive file.
Once the length is exceeded, the image write helper will move
on to the next tex file.
*/
virtual void SetMaxTexFileLength(int len);
/* Texture archive files are managed by this class and will
be created as needed. This method will increment to
the next texture file.
Note: This may create more files than we really need.
*/
virtual bool IncrementTextureFile(void);
/* Close the current texture file and go on to one with the
given base name. This is used for regenerate.
*/
virtual bool DesignateTextureFile(int);
protected:
// Write the given texture data into one our local archives
bool WriteToArchive(const trpgTexture &tex,char *data,trpgwAppAddress &addr);
trpgEndian ness;
char dir[1024];
trpgTexTable *texTable;
std::vector<int> texFileIDs;
trpgwAppFile *texFile;
int maxTexFileLen;
};
/* Paging Archive
This is a writeable paging archive.
It organizes where things get written and how.
{group:Archive Writing}
*/
TX_EXDECL class TX_CLDECL trpgwArchive : public trpgCheckable {
public:
// Tiles can be stored as individual files (External) or grouped together (Local)
typedef enum {TileLocal,TileExternal} TileMode;
// Add data to an existing archive
trpgwArchive(char *baseDir,char *name);
// Start an archive from scratch.
trpgwArchive(trpgEndian ness=LittleEndian,TileMode tileMode=TileLocal,int version=2);
virtual ~trpgwArchive(void);
// Set the maximum length for a tile file (if using them)
// This is only a suggestion for when to stop appending
virtual void SetMaxTileFileLength(int len);
// Set functions. Have to fill all these out before writing
virtual bool SetHeader(const trpgHeader &);
virtual bool SetMaterialTable(const trpgMatTable &);
virtual bool SetTextureTable(const trpgTexTable &);
virtual bool SetModelTable(const trpgModelTable &);
virtual bool SetLightTable(const trpgLightTable &);
virtual bool SetRangeTable(const trpgRangeTable &);
// Get functions. If we're doing a regenerate we need to get at these
virtual trpgHeader *GetHeader();
virtual trpgMatTable *GetMatTable();
virtual trpgTexTable *GetTextureTable();
virtual trpgModelTable *GetModelTable();
virtual trpgLightTable *GetLightTable();
virtual trpgRangeTable *GetRangeTable();
virtual bool IncrementTileFile(void);
virtual bool DesignateTileFile(int);
// Write functions.
// For now, the header is written last.
virtual bool OpenFile(const char *,const char *);
virtual void CloseFile(void);
virtual bool WriteHeader(void);
virtual bool WriteTile(unsigned int,unsigned int,unsigned int,float zmin,float zmax,
const trpgMemWriteBuffer *,const trpgMemWriteBuffer *);
// virtual bool WriteModel(unsigned int,trpgMemWriteBuffer &);
bool isValid(void) const;
char* getDir(void){return dir;};
// Used to keep track of which tiles are in which file
class TileFileEntry {
public:
int x,y,lod; // Identifying info for tile
float zmin,zmax;
uint32 offset; // Offset into file
};
protected:
// Set if we're adding to an existing archive
bool isRegenerate;
class TileFile {
public:
int id;
std::vector<TileFileEntry> tiles;
};
trpgEndian ness,cpuNess;
int version;
// Fed in from the outside
char dir[1024]; // Directory where we're doing all this
// These are passed in
trpgHeader header;
trpgMatTable matTable;
trpgTexTable texTable;
trpgModelTable modelTable;
trpgLightTable lightTable;
trpgRangeTable rangeTable;
trpgTileTable tileTable;
int numX,numY,numLod;
TileMode tileMode;
trpgwAppFile *tileFile;
int tileFileCount;
std::vector<TileFile> tileFiles;
int maxTileFileLen;
FILE *fp;
};
#endif