Added Paging TerraPage loader and osgTXP library.

This commit is contained in:
Don BURNS
2002-11-24 21:36:05 +00:00
parent 89b2575ffe
commit 12e922bc3c
55 changed files with 2578 additions and 175 deletions

18
src/Demos/osgtxp/Makefile Normal file
View File

@@ -0,0 +1,18 @@
TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgtxp.cpp\
LIBS += $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
LIBS += -losgTXP
INSTFILES = \
$(CXXFILES)\
Makefile.inst=Makefile
EXEC = osgtxp
include $(TOPDIR)/Make/makerules

170
src/Demos/osgtxp/osgtxp.cpp Normal file
View File

@@ -0,0 +1,170 @@
#include <osg/GL>
#include <osgGLUT/glut>
#include <osgGLUT/Viewer>
#include <osg/Node>
#include <osg/Notify>
#include <osgUtil/Optimizer>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgTXP/TrPageArchive.h>
#include <osgTXP/TrPageViewer.h>
void write_usage(std::ostream& out,const std::string& name)
{
out << std::endl;
out <<"usage:"<< std::endl;
out <<" "<<name<<" [options] infile1 [infile2 ...]"<< std::endl;
out << std::endl;
out <<"options:"<< std::endl;
out <<" -l libraryName - load plugin of name libraryName"<< std::endl;
out <<" i.e. -l osgdb_pfb"<< std::endl;
out <<" Useful for loading reader/writers which can load"<< std::endl;
out <<" other file formats in addition to its extension."<< std::endl;
out <<" -e extensionName - load reader/wrter plugin for file extension"<< std::endl;
out <<" i.e. -e pfb"<< std::endl;
out <<" Useful short hand for specifying full library name as"<< std::endl;
out <<" done with -l above, as it automatically expands to"<< std::endl;
out <<" the full library name appropriate for each platform."<< std::endl;
out <<std::endl;
out <<" -stereo - switch on stereo rendering, using the default of,"<< std::endl;
out <<" ANAGLYPHIC or the value set in the OSG_STEREO_MODE "<< std::endl;
out <<" environmental variable. See doc/stereo.html for "<< std::endl;
out <<" further details on setting up accurate stereo "<< std::endl;
out <<" for your system. "<< std::endl;
out <<" -stereo ANAGLYPHIC - switch on anaglyphic(red/cyan) stereo rendering."<< std::endl;
out <<" -stereo QUAD_BUFFER - switch on quad buffered stereo rendering."<< std::endl;
out <<std::endl;
out <<" -stencil - use a visual with stencil buffer enabled, this "<< std::endl;
out <<" also allows the depth complexity statistics mode"<< std::endl;
out <<" to be used (press 'p' three times to cycle to it)."<< std::endl;
out <<" -f - start with a full screen, borderless window." << std::endl;
out << std::endl;
}
using namespace txp;
int main( int argc, char **argv )
{
// initialize the GLUT
glutInit( &argc, argv );
if (argc<2)
{
write_usage(std::cout,argv[0]);
return 0;
}
// create the commandline args.
std::vector<std::string> commandLine;
for(int i=1;i<argc;++i) commandLine.push_back(argv[i]);
// initialize the viewer.
PagingViewer *viewer = new PagingViewer();
viewer->setWindowTitle(argv[0]);
// configure the viewer from the commandline arguments, and eat any
// parameters that have been matched.
viewer->readCommandLine(commandLine);
// configure the plugin registry from the commandline arguments, and
// eat any parameters that have been matched.
osgDB::readCommandLine(commandLine);
// Initialize the TXP database
bool loadAll = false;
bool threadIt = false;
std::string fileName;
for(std::vector<std::string>::iterator itr=commandLine.begin();
itr!=commandLine.end();
++itr)
{
if ((*itr)[0]!='-')
{
fileName = (*itr);
} else {
// Look for switches we want
if (!strcasecmp((*itr).c_str(),"-loadall")) {
loadAll = true;
continue;
}
if (!strcasecmp((*itr).c_str(),"-thread")) {
threadIt = true;
continue;
}
}
}
if (fileName.empty()) {
fprintf(stderr,"No TerraPage file specified on command line.\n");
return 1;
}
// Open the TXP database
TrPageArchive *txpArchive = new TrPageArchive();
if (!txpArchive->OpenFile(fileName.c_str())) {
fprintf(stderr,"Couldn't load TerraPage archive %s.\n",fileName.c_str());
return 1;
}
// Note: Should be checking the return values
txpArchive->LoadMaterials();
// txpArchive->LoadModels();
// Might need a page manager if we're paging
OSGPageManager *pageManager = new OSGPageManager(txpArchive);
osg::Group *rootNode=NULL;
if (loadAll) {
// Load the whole scenegraph
rootNode = txpArchive->LoadAllTiles();
if (!rootNode) {
fprintf(stderr,"Couldn't load whole TerraPage archive %s.\n",fileName.c_str());
return 1;
}
// add a viewport to the viewer and attach the scene graph.
viewer->addViewport( rootNode );
} else {
viewer->Init(pageManager,(threadIt ? txp::OSGPageManager::ThreadFree : txp::OSGPageManager::ThreadNone));
rootNode = new osg::Group();
viewer->addViewport(rootNode);
}
// run optimization over the scene graph
// osgUtil::Optimizer optimzer;
// optimzer.optimize(rootnode);
// register trackball, flight and drive.
viewer->registerCameraManipulator(new osgGA::TrackballManipulator);
viewer->registerCameraManipulator(new osgGA::FlightManipulator);
viewer->registerCameraManipulator(new osgGA::DriveManipulator);
// Recenter the camera to the middle of the database
osg::Vec3 center;
txpArchive->GetCenter(center); center[2] += 200;
osgUtil::SceneView *sceneView = viewer->getViewportSceneView(0);
osg::Camera *camera = sceneView->getCamera();
osg::Vec3 eyePt = center;
eyePt[0] -= 1000;
osg::Vec3 upVec( 0, 0, 1 );
camera->setLookAt(eyePt,center,upVec);
// open the viewer window.
viewer->open();
// fire up the event loop.
viewer->run();
// Close things down
delete pageManager;
delete txpArchive;
delete viewer;
return 0;
}

View File

@@ -23,15 +23,24 @@ CXXFILES =\
trpage_compat.cpp\
trpage_light.cpp\
trpage_pparse.cpp\
trpage_print.cpp
trpage_print.cpp\
trpage_managers.cpp\
trPagePageManager.cpp\
trpage_print_parse.cpp\
trpage_util.cpp\
TrPageViewer.cpp\
INC += -I$(THISDIR)
INC += -I$(THISDIR)
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
TARGET_BASENAME = txp
PLUGIN_TARGET_BASENAME = txp
include $(TOPDIR)/Make/cygwin_plugin_def
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
PLUGIN = $(PLUGIN_PREFIX)$(PLUGIN_TARGET_BASENAME).$(PLUGIN_EXT)
LIB_TARGET_BASENAME=osgTXP
LIB = $(LIB_PREFIX)$(LIB_TARGET_BASENAME).$(LIB_EXT)
include $(TOPDIR)/Make/makerules

View File

@@ -1,5 +1,5 @@
#include "ReaderWriterTXP.h"
#include "TrPageArchive.h"
#include <osgTXP/TrPageArchive.h>
#include <osg/Group>
#include <osg/Object>

View File

@@ -26,7 +26,7 @@
#ifndef READER_WRITER_TXP_H
#define READER_WRITER_TXP_H
#include "trpage_sys.h"
#include <osgTXP/trpage_sys.h>
#include <osg/Object>
#include <osg/Node>

View File

@@ -1,5 +1,9 @@
#include "TrPageArchive.h"
#include "TrPageParser.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <osgTXP/TrPageArchive.h>
#include <osgTXP/TrPageParser.h>
#include <osg/AlphaFunc>
#include <osg/Group>
@@ -19,14 +23,12 @@
#include <osgDB/WriteFile>
#include <osgDB/FileNameUtils>
#include "trpage_geom.h"
#include "trpage_read.h"
#include "trpage_write.h"
#include "trpage_scene.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
#include <osgTXP/trpage_write.h>
#include <osgTXP/trpage_scene.h>
#include <osgTXP/trpage_managers.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace txp;
using namespace osg;
@@ -39,7 +41,8 @@ using namespace osg;
TrPageArchive::TrPageArchive()
: trpgr_Archive()
, parse(new TrPageParser(this))
, parse(new TrPageParser(this))
, buf(GetEndian())
{
}
@@ -85,6 +88,29 @@ bool TrPageArchive::OpenFile(const char* file)
return true;
}
/* Calculate the center of the database (including Z)
*/
void TrPageArchive::GetCenter(Vec3 &center)
{
trpg2dPoint sw,ne;
const trpgHeader *head = GetHeader();
const trpgTileTable *tileTable = GetTileTable();
head->GetExtents(sw,ne);
trpg2dPoint tileSize;
head->GetTileSize(0,tileSize);
center[0] = (ne.x+sw.x)/2.0;
center[1] = (ne.y+sw.y)/2.0;
trpg2iPoint loc;
loc.x = int((center[0]-sw.x)/tileSize.x);
loc.y = int((center[1]-sw.y)/tileSize.y);
trpgwAppAddress foo;
float zmin,zmax;
tileTable->GetTile(loc.x, loc.y,0,foo,zmin,zmax);
center[2] = (zmin+zmax)/2.0;
}
// load textures and materials
// TODO : multitexturing
void TrPageArchive::LoadMaterials()
@@ -174,6 +200,8 @@ void TrPageArchive::LoadMaterials()
// TODO : multitextuting
// also note that multitexturing in terrapage can came from two sides
// - multiple textures per material, and multiple materials per geometry
// Note: Only in theory. The only type you'll encounter is multiple
// materials per polygon.
if( numMatTex )
{
Material *osg_material = new Material;
@@ -337,6 +365,7 @@ bool TrPageArchive::LoadModels()
return true;
}
// Group* TrPageArchive::LoadTile(int x,int y,int lod,int &parentID,vector<GroupIDInfo> **groupList)
Group* TrPageArchive::LoadTile(int x,int y,int lod,int &parentID)
{
trpgMemReadBuffer buf(GetEndian());
@@ -352,10 +381,71 @@ Group* TrPageArchive::LoadTile(int x,int y,int lod,int &parentID)
// This is where you would page in textures and models
}
// Also return the list of IDs and their groups we read in for this tile
// *groupList = parse->GetGroupList();
// That's it
return tile;
}
// Group* TrPageArchive::LoadTile(Group *rootNode,trpgPageManager *pageManage,trpgManagedTile *tile,vector<)
Group* TrPageArchive::LoadTile(Group *rootNode,
trpgPageManager * /*pageManage*/,
trpgManagedTile *tile,osg::Group **parentNode)
{
int x,y,lod;
tile->GetTileLoc(x,y,lod);
std::vector<osg::Group *> *groupList = parse->GetGroupList();
// Fetch the tile data (but don't parse it)
if (!ReadTile(x,y,lod,buf))
return NULL;
// Now parse it
Group *gTile = parse->ParseScene(buf, m_gstates, m_models);
if (gTile && rootNode) {
// Hook it into its parent
int parentID = parse->GetParentID();
if (parentID >= 0) {
(*groupList)[parentID]->addChild(gTile);
} else
rootNode->addChild(gTile);
// Note: Need to page in the textures
// They're being forced in during the parse right now
}
if (parentNode) {
int parentID = parse->GetParentID();
if (parentID >= 0)
*parentNode = (*groupList)[parentID];
else
*parentNode = rootNode;
}
// Add the tile to the local data in the managed tile
tile->SetLocalData(gTile);
return gTile;
}
bool TrPageArchive::UnLoadTile(trpgPageManager * /*pageManage*/,
trpgManagedTile *tile)
{
// The local tile data will have the group we need
Group *gTile = (Group *)tile->GetLocalData();
if (gTile) {
// Remove it from the parent list
// We're only expecting on parent
const Group::ParentList &pList = gTile->getParents();
if (pList.size() != 1)
return false;
pList[0]->removeChild(gTile);
} else
return false;
return true;
}
//----------------------------------------------------------------------------
Group* TrPageArchive::LoadAllTiles()
{
@@ -372,6 +462,7 @@ Group* TrPageArchive::LoadAllTiles()
trpg2iPoint tileSize;
// The group list is used to map parent IDs to pfGroup nodes
//std::vector<Group *> groupList;
std::vector<Group *> *groupList = parse->GetGroupList();
for (int nl=0;nl<numLod;nl++)
@@ -401,7 +492,7 @@ Group* TrPageArchive::LoadAllTiles()
else
{
// Added below some other node
(*groupList)[parentID]->addChild(tile);
(*groupList)[parentID]->addChild(tile);
}
}
}

View File

@@ -1,87 +0,0 @@
/* **************************************************************************
* OpenSceneGraph loader for Terrapage format database
* by Boris Bralo 2002
*
* based on/modifed sgl (Scene Graph Library) loader by Bryan Walsh
*
* This loader is based on/modified from Terrain Experts Performer Loader,
* and was ported to SGL by Bryan Walsh / bryanw at earthlink dot net
*
* That loader is redistributed under the terms listed on Terrain Experts
* website (www.terrex.com/www/pages/technology/technologypage.htm)
*
* "TerraPage is provided as an Open Source format for use by anyone...
* We supply the TerraPage C++ source code free of charge. Anyone
* can use it and redistribute it as needed (including our competitors).
* We do, however, ask that you keep the TERREX copyrights intact."
*
* Copyright Terrain Experts Inc. 1999.
* All Rights Reserved.
*
*****************************************************************************/
#ifndef _TRPAGEARCHIVE_H_
#define _TRPAGEARCHIVE_H_
#include "trpage_sys.h"
#include "trpage_read.h"
#include "TrPageParser.h"
#include <string>
#include <vector>
#include <memory> // for auto_ptr
namespace txp
{
/// main class for loading terrapage archives
class TrPageArchive : public trpgr_Archive
{
public:
TrPageArchive();
~TrPageArchive();
// open archive file
virtual bool OpenFile(const char* file);
/// Load and create textures and materials
void LoadMaterials();
// Load and create models, usualy OpenFlight models
bool LoadModels();
/** Load a TXP tile and
@param x Tile location input - x dimension.
@param y Tile location input - y dimension.
@param lod Tile LOD level input.
@return The parent ID of this tile to let you hook it into the scene
graph.
x, y dimensions are not coordinates, they are tile numbers. For example,
for combination 10, 1 and lod number 2 terrapage opens file tile_10_1_2.tpt
in directory of the archive. This is THE method which shoud be used once
paging is implemented.
*/
osg::Group *LoadTile(int x,int y,int lod,int &parent);
/** Load all the tiles . No paging.
@return The parent of the complete scene graph.
*/
osg::Group *LoadAllTiles();
protected:
/// This class does most of the actual parsing.
std::auto_ptr<TrPageParser> parse;
// Texture, material, and model lists.
std::vector< osg::ref_ptr<osg::Texture2D> > m_textures;
std::vector< osg::ref_ptr<osg::StateSet> > m_gstates;
std::vector< osg::ref_ptr<osg::Node> > m_models;
std::string m_alternate_path;
};
}; // end namespace
#endif

View File

@@ -19,7 +19,7 @@
* All Rights Reserved.
*
*****************************************************************************/
#include "trpage_sys.h"
#include <osgTXP/trpage_sys.h>
#include <osg/AlphaFunc>
#include <osg/Group>
#include <osg/Material>
@@ -35,8 +35,8 @@
#include <osg/Notify>
#include "TrPageParser.h"
#include "TrPageArchive.h"
#include <osgTXP/TrPageParser.h>
#include <osgTXP/TrPageArchive.h>
/*
#include <stdlib.h>
#include <stdio.h>
@@ -121,6 +121,7 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria
if(gltype!=(GLenum)-1)
{
osg_texture = new Texture2D();
osg_texture->setInternalFormatMode(internalFormat);
Image* image = new Image;
@@ -132,7 +133,7 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria
{
int32 size = s.x*s.y*depth;
// int32 size = const_cast<trpgTexture*>(tex)->MipLevelSize(1) ;
data = (char*)::malloc(size);
data = (char *)::malloc(size);
if(locmat)
image_helper.GetImageForLocalMat(locmat,data,size);
@@ -148,7 +149,7 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria
int32 size = tex->CalcTotalSize();
trpgTexture* tmp_tex = const_cast<trpgTexture*>(tex);
data = (char*)::malloc(size);
data = (char *)::malloc(size);
if(locmat)
image_helper.GetImageForLocalMat(locmat,data,size);
@@ -172,6 +173,8 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria
image->setMipmapData(mipmaps);
}
// delete [] data;
// image->unref();
// AAAARRRGH! TOOK ME 2 DAYS TO FIGURE IT OUT
// EVERY IMAGE HAS TO HAVE UNIQUE NAME FOR OPTIMIZER NOT TO OPTIMIZE IT OFF
//
@@ -216,7 +219,7 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
Vec3Array* vertices = new Vec3Array(numVert);
// Get vertices
geom.GetVertices(&(vertices->front()));
geom.GetVertices((float *)&(vertices->front()));
// Turn the trpgGeometry into something Performer can understand
Geometry *geometry = 0L;
@@ -431,6 +434,7 @@ void* billboardRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
Group* osg_Group = new Group;
int type;
bill.GetType(type);
// Note: Must deal with the billboard type here
if( type == trpgBillboard::Group )
{
// Create a new Performer group
@@ -489,7 +493,8 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
Vec3 osg_Center;
osg_Center[0] = center.x; osg_Center[1] = center.y; osg_Center[2] = center.z;
osg_Lod->setCenter(osg_Center);
osg_Lod->setRange(0,minRange,maxRange);
osg_Lod->setRange(0,0.0, minRange);
osg_Lod->setRange(1,minRange, maxRange );
// Our LODs are binary so we need to add a group under this LOD and attach stuff
// to that instead of the LOD
@@ -535,7 +540,12 @@ void *modelRefRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
);
// Note: Array check before you do this
Node *osg_Model = (*parse->GetModels())[modelID].get();
Node *osg_Model = NULL;
std::vector<osg::ref_ptr<osg::Node> >*modelList = parse->GetModels();
if( modelList->size() > size_t(modelID) )
{
//(*parse->GetModels())[modelID].get();
osg_Model = (*modelList)[modelID].get();
// Create the SCS and position the model
if (osg_Model) {
MatrixTransform *scs = new MatrixTransform();
@@ -546,6 +556,7 @@ void *modelRefRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
if (top)
top->addChild(scs);
}
}
return (void *) 1;
}

View File

@@ -1,162 +0,0 @@
/* **************************************************************************
* OpenSceneGraph loader for Terrapage format database
* by Boris Bralo 2002
*
* based on/modifed sgl (Scene Graph Library) loader by Bryan Walsh
*
* This loader is based on/modified from Terrain Experts Performer Loader,
* and was ported to SGL by Bryan Walsh / bryanw at earthlink dot net
*
* That loader is redistributed under the terms listed on Terrain Experts
* website (www.terrex.com/www/pages/technology/technologypage.htm)
*
* "TerraPage is provided as an Open Source format for use by anyone...
* We supply the TerraPage C++ source code free of charge. Anyone
* can use it and redistribute it as needed (including our competitors).
* We do, however, ask that you keep the TERREX copyrights intact."
*
* Copyright Terrain Experts Inc. 1999.
* All Rights Reserved.
*
*****************************************************************************/
#ifndef _TRPAGEPARSER_H_
#define _TRPAGEPARSER_H_
#include <osg/Vec3>
#include <osg/Vec2>
#include <osg/StateSet>
#include <osg/ref_ptr>
#include <osg/Texture2D>
#include <osg/Group>
#include <osg/StateSet>
#include <vector>
#include "trpage_read.h"
namespace txp
{
class TrPageArchive;
class TrPageParser : public trpgSceneParser
{
public:
TrPageParser(TrPageArchive* parent);
~TrPageParser();
osg::Group *ParseScene(trpgReadBuffer & buf,
std::vector<osg::ref_ptr<osg::StateSet> > & materials_,
std::vector<osg::ref_ptr<osg::Node> > & node );
// Return the parent of a recently parsed tile
int GetParentID() { return parentID; }
void SetParentID(int id) { parentID = id; }
// Return a reference to the tile header (after a tile has been read)
trpgTileHeader *GetTileHeaderRef();
// Return the current top node (used during parsing)
osg::Group *GetCurrTop();
// Return the current material list (passed in to ParseScene())
std::vector<osg::ref_ptr<osg::StateSet> >* GetMaterials() { return materials; }
// new to TerraPage 2.0 - local materials
std::vector<osg::ref_ptr<osg::StateSet> >* GetLocalMaterials() { return &local_materials; }
std::vector<osg::ref_ptr<osg::Node> >* GetModels() { return models; }
// Add the Group to the group list
bool AddToGroupList(int id,osg::Group *);
// Return the group list
std::vector< osg::Group* > *GetGroupList() { return &groupList; }
// Set the maximum number of groups (once per archive)
void SetMaxGroupID(int);
/// TXP 2.0 - local materials
void LoadLocalMaterials();
protected:
bool StartChildren(void *);
bool EndChildren(void *);
protected:
TrPageArchive* parent_;
osg::Group *currTop; // Current parent group
osg::Group *top; // Top group
trpgTileHeader tileHead; // Dump tile header here
// If there was an attach node, this is
// the tile's parent ID. -1 otherwise
int parentID;
std::vector<osg::ref_ptr<osg::StateSet> >* materials;
std::vector<osg::ref_ptr<osg::StateSet> > local_materials;
std::vector<osg::Group *> groupList;
std::vector<osg::ref_ptr<osg::Node> >* models;
};
osg::Texture2D* GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMaterial* locmat, const trpgTexture* tex);
//! callback functions for various scene graph elements
class geomRead : public trpgr_Callback {
public:
geomRead(TrPageParser *in_parse);
~geomRead();
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser *parse;
};
//----------------------------------------------------------------------------
class groupRead : public trpgr_Callback {
public:
groupRead(TrPageParser *in_parse);
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser *parse;
};
//----------------------------------------------------------------------------
class attachRead : public trpgr_Callback {
public:
attachRead(TrPageParser*in_parse);
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser*parse;
};
//----------------------------------------------------------------------------
class billboardRead : public trpgr_Callback {
public:
billboardRead(TrPageParser*in_parse);
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser*parse;
};
//----------------------------------------------------------------------------
class lodRead : public trpgr_Callback {
public:
lodRead(TrPageParser*in_parse);
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser*parse;
};
//----------------------------------------------------------------------------
class modelRefRead : public trpgr_Callback {
public:
modelRefRead(TrPageParser*in_parse);
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser*parse;
};
//----------------------------------------------------------------------------
class tileHeaderRead : public trpgr_Callback {
public:
tileHeaderRead(TrPageParser*in_parse);
void *Parse(trpgToken tok,trpgReadBuffer &buf);
protected:
TrPageParser*parse;
};
}; // namespace txp
#endif

View File

@@ -0,0 +1,188 @@
#if defined(_MSC_VER)
#pragma warning( disable : 4786 )
#endif
#include <osg/GL>
#include <osgGLUT/glut>
#include <stdlib.h>
#if (!defined(WIN32) && !defined(macintosh)) || defined(__CYGWIN__)
#include <unistd.h>
#include <sys/time.h>
#endif
#include <stdio.h>
#include <osg/Math>
#include <osg/Statistics>
#include <string>
#include <osgGLUT/Viewer>
#include <osgGLUT/GLUTEventAdapter>
#include <osg/Switch>
#include <osg/Billboard>
#include <osg/LOD>
#include <osg/Light>
#include <osg/LightSource>
#include <osg/Geode>
#include <osg/Group>
#include <osg/NodeVisitor>
#include <osg/LineSegment>
#include <osg/PolygonMode>
#include <osg/Texture2D>
#include <osg/LightModel>
#include <osg/ShadeModel>
#include <osg/Notify>
#include <osg/CollectOccludersVisitor>
#include <osg/Fog>
#include <osgDB/WriteFile>
#include <osgUtil/IntersectVisitor>
#include <osgUtil/DisplayListVisitor>
#include <osgUtil/SmoothingVisitor>
#include <osgUtil/TriStripVisitor>
#include <osgUtil/DisplayRequirementsVisitor>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osg/Version>
#include <osgUtil/Version>
#ifdef WIN32
#define USE_FLTK
#define USE_GLUT
#endif
#include <osgTXP/TrPageArchive.h>
#include <osgTXP/TrPageViewer.h>
/*
#if defined(WIN32) && !defined(__CYGWIN__)
#include <sys/timeb.h>
#else
#endif
*/
using namespace osg;
using namespace osgUtil;
using namespace osgGLUT;
using namespace osgGA;
using namespace std;
using namespace txp;
PagingViewer::PagingViewer() : Viewer()
{
pageManage = NULL;
}
bool PagingViewer::Init(OSGPageManager *in_manage,OSGPageManager::ThreadMode threadMode)
{
pageManage = in_manage;
// Start up the thread if needed
if (threadMode != OSGPageManager::ThreadNone) {
ThreadID newThread;
pageManage->StartThread(threadMode,newThread);
}
return true;
}
/* App call
This replaces the app() call for the base viewer.
In this one, we ask the page manager to load stuff in.
*/
float PagingViewer::app(unsigned int viewport)
{
osg::Timer_t beforeApp = _timer.tick();
// update the camera manipulator.
osg::ref_ptr<GLUTEventAdapter> ea = osgNew GLUTEventAdapter;
ea->adaptFrame(_frameStamp->getReferenceTime());
#if 0 // This is the old way...
if (_viewportList[viewport]._eventHandler.valid() && _viewportList[viewport]._eventHandler->handle(*ea,*this))
{
// event handler handle this call.
}
else if (_viewportList[viewport]._cameraManipulator->handle(*ea,*this))
{
// osg::notify(osg::INFO) << "Handled update frame"<< std::endl;
}
#else // this is the new way
bool handled = false;
for (EventHandlerList::iterator eh = _viewportList[viewport]._eventHandlerList.begin(); eh != _viewportList[viewport]._eventHandlerList.end();
eh++ )
{
if ( eh->valid() )
{
if ( (*eh)->handle(*ea,*this) )
{
handled = true;
break;
}
}
}
// if ( !handled ) {
_viewportList[viewport]._cameraManipulator->handle(*ea,*this);
// }
#endif
// Update the paging
if (pageManage) {
int numTile = 1;
osgUtil::SceneView *sceneView = getViewportSceneView(viewport);
osg::Camera *camera = sceneView->getCamera();
const Vec3 &eyePt = camera->getEyePoint();
double eyeX = eyePt[0];
double eyeY = eyePt[1];
/* If we're in ThreadFree mode, merge in whatever may be ready.
If we're in non-thread mode, load in the given number of tiles (maximum).
*/
if (pageManage->GetThreadMode() == OSGPageManager::ThreadFree) {
pageManage->MergeUpdateThread((osg::Group *)sceneView->getSceneData());
pageManage->UpdatePositionThread(eyeX,eyeY);
} else {
pageManage->UpdateNoThread((osg::Group *)sceneView->getSceneData(),eyeX,eyeY,numTile);
}
}
// do app traversal.
getViewportSceneView(viewport)->setFrameStamp(_frameStamp.get());
getViewportSceneView(viewport)->app();
osg::Timer_t beforeCull = _timer.tick();
#if 0
// We're going for 66ms per frame
float targetFrameTime = 30;
static osg::Timer_t lastCull = 0;
if (lastCull > 0) {
float deltaT = _timer.delta_m(lastCull,beforeCull);
int extraTime = targetFrameTime - deltaT;
if (extraTime > 0)
Sleep(extraTime);
}
lastCull = beforeCull;
#endif
return _timer.delta_m(beforeApp,beforeCull);
}
bool PagingViewer::run()
{
updateFrameTick();
return Window::run();
}

View File

@@ -0,0 +1,413 @@
#include <stdlib.h>
#include <stdio.h>
#if defined(_WIN32)
#include <windows.h>
#include <conio.h>
#else
#include <unistd.h>
#include <pthread.h>
#endif
#include <osgTXP/TrPageArchive.h>
#include <osgTXP/trPagePageManager.h>
#include <osgTXP/trpage_print.h>
#include <osg/Group>
#include <osg/Object>
#include <osg/Node>
#include <osg/Notify>
#include <osgDB/Registry>
#include <osgDB/FileUtils>
#include <iostream>
using namespace txp;
using namespace osg;
OSGPageManager::OSGPageManager(TrPageArchive *in_arch,trpgPageManager *in_pageManage)
{
archive = in_arch;
pageManage = in_pageManage;
if (!in_arch)
throw 1;
if (pageManage)
pageManageOurs = false;
else {
pageManage = new trpgPageManager();
pageManage->SetPageDistFactor(1.2);
pageManage->Init(archive);
pageManageOurs = true;
}
// Location info we'll need later
const trpgHeader *head = archive->GetHeader();
trpg2dPoint sw,ne;
head->GetExtents(sw,ne);
originX = sw.x;
originY = sw.y;
threadMode = ThreadNone;
}
OSGPageManager::~OSGPageManager()
{
if (threadMode != ThreadNone)
EndThread();
if (pageManageOurs)
delete pageManage;
pageManage = NULL;
}
/* Update
Bring the paging up to date based on the given location.
The location is in TerraPage's coordinate system, but must
still be adjusted to the SW corner.
*/
bool OSGPageManager::UpdateNoThread(osg::Group *rootNode,double locX,double locY,int numTile)
{
// Adjust to TerraPage coordinates
double lx = locX-originX;
double ly = locY-originY;
/* Do that paging thing:
- Tell the manager the new location
- Iterate over the unloads
- Iterate over the loads
*/
trpg2dPoint loc;
loc.x = lx;
loc.y = ly;
if (pageManage->SetLocation(loc)) {
// printf("Location (%f,%f) resulted in changes.",loc.x,loc.y);
// trpgFilePrintBuffer printBuf(stdout);
// pageManage->Print(printBuf);
}
// Do the unloads
trpgManagedTile *tile=NULL;
while ((tile = pageManage->GetNextUnload())) {
archive->UnLoadTile(pageManage,tile);
pageManage->AckUnload();
};
// Decide how many loads to do per frame
int loadCount=0;
// Do the loads
while ((tile = pageManage->GetNextLoad())) {
archive->LoadTile(rootNode,pageManage,tile);
pageManage->AckLoad();
loadCount++;
if (numTile > 0 && loadCount >= numTile)
break;
};
return true;
}
// Mutex lock function
// --- Either thread ---
void osgLockMutex(ThreadMutex &mtx)
{
#if defined (_WIN32)
WaitForSingleObject( mtx, INFINITE);
#else
pthread_mutex_lock( &mtx );
#endif
}
// Mutex unlock function
// --- Either thread ---
void osgUnLockMutex(ThreadMutex &mtx)
{
#if defined (_WIN32)
ReleaseMutex(mtx);
#else
pthread_mutex_unlock( &mtx );
#endif
}
// Wait for Event
// --- Either thread (only used in paging thread) ---
void osgWaitEvent(ThreadEvent &ev)
{
#if defined (_WIN32)
WaitForSingleObject( ev, INFINITE);
#else
ev.wait();
#endif
}
// Set Event (i.e. notify the other thread something's up)
// --- Either thread (only used in main thread) ---
void osgSetEvent(ThreadEvent &ev)
{
#if defined (_WIN32)
SetEvent(ev);
#else
ev.release();
#endif
}
// Windows specific thread function.
// This just fires up our own loop
// --- Paging Thread ---
#if defined (_WIN32)
DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
OSGPageManager *myPager = (OSGPageManager *)lpParam;
myPager->ThreadLoop();
return 0;
}
#else // Pthreads, cause Pthreads is a POSIX standard and is EVERYWHERE else
void *ThreadFunc( void *data )
{
OSGPageManager *myPager = static_cast<OSGPageManager *>(data);
myPager->ThreadLoop();
return 0L;
}
#endif
/* Start Thread
This initialized
--- Main Thread ---
*/
bool OSGPageManager::StartThread(ThreadMode mode,ThreadID &newThread)
{
positionValid = false;
#if defined(_WIN32)
// Create the event we'll use to wake up the pager thread when the location changes
locationChangeEvent = CreateEvent(NULL,false,false,"Location Change Event");
// Create the mutexes we'll need later
changeListMutex = CreateMutex(NULL,false,"Change List Mutex");
locationMutex = CreateMutex(NULL,false,"Location Mutex");
{
// Create the thread
DWORD dwThreadId=0;
LPVOID dwThrdParam = (LPVOID) this;
newThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadFunc, // thread function
dwThrdParam, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
}
// Note: Should be optional
// Set the priority low so this is only called when the other thread is idle
// if (!SetThreadPriority(newThread,THREAD_PRIORITY_IDLE))
// fprintf(stderr,"Couldn't set paging thread priority.\n");
// Was successfull
if (newThread != NULL)
threadMode = mode;
#endif
//locationChangeEvent is self-initialized.
pthread_mutex_init( &changeListMutex, 0L );
pthread_mutex_init( &locationMutex, 0L );
if( pthread_create( &newThread, 0L, ThreadFunc, (void *)this ) == 0 )
threadMode = mode;
return threadMode != ThreadNone;
}
/* End Thread
Note: Do this
*/
bool OSGPageManager::EndThread()
{
#ifdef WIN32
#else
// Need a handle to the thread ID here.
//pthread_cancel( ?newThread? );
#endif
return true;
}
/* Thread Loop
This method is the main loop for the pager when it's
working in its own thread.
--- Paging Thread ---
*/
bool OSGPageManager::ThreadLoop()
{
// Note: Only works for free running thread
if (threadMode != ThreadFree)
throw 1;
bool done = false;
bool pagingActive = false;
while (!done) {
/* Here's how we do it:
Wait for position change
Update manager w/ position
Form delete list
Load tile (if needed)
Add tile to merge list
*/
// Position has already changed or we'll wait for it to do so
osgWaitEvent(locationChangeEvent);
double myLocX,myLocY;
{
osgLockMutex(locationMutex);
myLocX = locX;
myLocY = locY;
osgUnLockMutex(locationMutex);
}
// Pass the new location on to page manager
trpg2dPoint loc;
loc.x = myLocX;
loc.y = myLocY;
if (pageManage->SetLocation(loc) || pagingActive) {
// If there were changes, process them
// Form the delete list first
trpgManagedTile *tile=NULL;
std::vector<osg::Group *> unhook;
while (tile = pageManage->GetNextUnload()) {
unhook.push_back((Group *)tile->GetLocalData());
pageManage->AckUnload();
}
// Tell the main thread to unhook tiles
// and get the groups to delete as well.
std::vector <osg::Group *> nextDelete;
{
osgLockMutex(changeListMutex);
// Add to the unhook list
for (unsigned int ti=0;ti<unhook.size();ti++)
toUnhook.push_back(unhook[ti]);
// Also get the list of deletions while we're here
nextDelete = toDelete;
toDelete.clear();
osgUnLockMutex(changeListMutex);
}
// Unreference whatever we're supposed to delete
for (unsigned int gi=0;gi<nextDelete.size();gi++)
nextDelete[gi]->unref();
// Now do a single load
tile = pageManage->GetNextLoad();
osg::Group *tileGroup=NULL;
pagingActive = false;
if (tile) {
osg::Group *parentNode = NULL;
tileGroup = archive->LoadTile(NULL,pageManage,tile,&parentNode);
pageManage->AckLoad();
if (tileGroup) {
// Make an extra reference to it because we want it back for deletion
tileGroup->ref();
} else {
int x,y,lod;
tile->GetTileLoc(x,y,lod);
fprintf(stderr,"Failed to load tile (%d,%d,%d)\n",x,y,lod);
}
// Now add this tile to the merge list
if (tileGroup) {
osgLockMutex(changeListMutex);
toMerge.push_back(tileGroup);
toMergeParent.push_back(parentNode);
osgUnLockMutex(changeListMutex);
}
// We're not necessarily done paging, we're just handing control back
// It's likely we'll be back here
pagingActive = true;
}
}
}
return true;
}
/* Update Position Thread
This method updates the location for the paging thread to use.
--- Main Thread ---
*/
void OSGPageManager::UpdatePositionThread(double inLocX,double inLocY)
{
// Update the position
{
// Get the location mutex
osgLockMutex(locationMutex);
positionValid = true;
locX = inLocX-originX;
locY = inLocY-originY;
osgUnLockMutex(locationMutex);
}
// Notify the paging thread there's been a position update
osgSetEvent(locationChangeEvent);
}
/* Merge Updates
Merge in the new tiles and unhook the ones we'll be deleting.
Actually, we'll hand these back to the paging thread for deletion.
--- Main Thread ---
*/
bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode)
{
std::vector<osg::Group *> mergeList;
std::vector<osg::Group *> mergeParentList;
std::vector<osg::Group *> unhookList;
// Make local copies of the merge and unhook lists
{
osgLockMutex(changeListMutex);
mergeList = toMerge;
mergeParentList = toMergeParent;
unhookList = toUnhook;
toMerge.clear();
toMergeParent.clear();
toUnhook.clear();
osgUnLockMutex(changeListMutex);
}
// Do the unhooking first
for (unsigned int ui=0;ui<unhookList.size();ui++) {
osg::Group *unhookMe = unhookList[ui];
// Look for its parent(s)
// Only expecting one, but it doesn't matter
const osg::Node::ParentList &parents = unhookMe->getParents();
for (unsigned int pi=0;pi<parents.size();pi++) {
osg::Group *parent = parents[pi];
parent->removeChild(unhookMe);
}
}
// Put the unhooked things on the list to delete
{
osgLockMutex(changeListMutex);
for (unsigned int di=0;di<unhookList.size();di++)
toDelete.push_back(unhookList[di]);
osgUnLockMutex(changeListMutex);
}
// Do the merging last
{
for (unsigned int mi=0;mi<mergeList.size();mi++) {
osg::Group *mergeMe = mergeList[mi];
osg::Group *parent = mergeParentList[mi];
if (parent)
parent->addChild(mergeMe);
else
rootNode->addChild(mergeMe);
}
}
return true;
}

View File

@@ -1,125 +0,0 @@
/* ************************
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
************************
*/
/* trdll.h
Windows Only
This header file defines the declaration macros for DLLs.
*/
// Export/import declaration for classes and functions
// Use EXDECL class CPPDECL ... for a class
// Use CPPDECL foo *bar(bletch) for a stand-alone C++ function
// Use CDECL foo *bar(bletch) for a C function
// __COMP_DLL must be defined explicitly in Build->Settings->Code Generation
// __CURR_DLL must be defined in each header in a DLL
#ifdef TX_CLDECL
#undef TX_CLDECL
#undef TX_EXDECL
#undef TX_CDECL
#undef TX_CPPDECL
#undef TX_DODECL
#endif
// Work through cases
// If we're not compiling a DLL, or compiling the wrong DLL do import
// declarations (0), otherwise do export declarations (1)
#if !defined (__COMP_DLL)
// {secret}
#define TX_DODECL 0
#else
#if __COMP_DLL == __CURR_DLL
#define TX_DODECL 1
#else
#define TX_DODECL 0
#endif
#endif
// #if !defined (__CURR_DLL) || __COMP_DLL != __CURR_DLL
#if TX_DODECL == 0
// Modified by Paul J. Metzger (pjm@rbd.com) to support static link libraries.
// Here's the original code:
// #define TX_CLDECL __declspec( dllimport )
// #define TX_EXDECL
// #ifdef __cplusplus
// #define TX_CDECL extern "C" __declspec(dllimport)
// #else
// #define TX_CDECL extern __declspec(dllimport)
// #endif
// #define TX_CPPDECL extern __declspec(dllimport)
#ifndef TX_CLDECL
// Class declaration. Goes after "class" to handle DLL export in windows.
#define TX_CLDECL
// Goes before "class" to handle DLL export in windows
#define TX_EXDECL /* no-op */
// Exports a C++ function properly in a windows DLL
#define TX_CPPDECL /* no-op */
// Exports a C function properly in a windows DLL
#define TX_CDECL /* no-op */
// {secret}
#ifndef TXDUMMY_DLL_MAIN
#define TXDUMMY_DLL_MAIN /* no-op */
#endif
#endif
#else
#define TX_CLDECL __declspec( dllexport )
#define TX_EXDECL
#define TX_CPPDECL extern __declspec(dllexport)
#ifdef __cplusplus
#define TX_CDECL extern "C" __declspec(dllexport)
#else
#define TX_CDECL extern __declspec(dllexport)
#endif
// The following is a DLL Main function for DLLs that wouldn't otherwise
// have one. It's needed to initialize the run time library.
// This should appear once within every DLL
// commented out by Boris Bralo for osg
/*
#ifndef TXDUMMY_DLL_MAIN
#define TXDUMMY_DLL_MAIN \
extern "C" { \
BOOL WINAPI _CRT_INIT (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved); \
BOOL APIENTRY DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) \
{ \
switch (dwReason) \
{ \
case DLL_PROCESS_ATTACH: \
{ \
if (!_CRT_INIT (hDLL, dwReason, lpReserved)) \
return FALSE; \
break; \
} \
\
case DLL_PROCESS_DETACH: \
{ \
break; \
} \
} \
return TRUE; \
} \
}
#endif
*/
#endif
#ifndef txdll_h_
// {secret}
#define txdll_h_
#endif

View File

@@ -20,7 +20,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "trpage_io.h"
#include <osgTXP/trpage_io.h>
/* Checkable
This is just a class that checks validity.

View File

@@ -24,9 +24,9 @@
*/
#include "trpage_geom.h"
#include "trpage_read.h"
#include "trpage_compat.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
#include <osgTXP/trpage_compat.h>
/* Old short Material definition from 1.0.
{secret}

View File

@@ -1,96 +0,0 @@
/* ************************
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_compat_h_
#define _trpage_compat_h_
/* trpage_compat.h
This file and the accompanying trpage_compat.cpp contain objects and procedures
used to maintain compatibility between versions of TerraPage. In particular, the
ability to read older versions of TerraPage and newer applications.
*/
/* Material Table 1.0.
This class is used to read old 1.0 material tables and convert them
into the 2.0 material table we're inheriting from. Users should
never directly interact with this class.
{secret}
*/
class trpgMatTable1_0 : public trpgMatTable {
public:
trpgMatTable1_0() { };
trpgMatTable1_0(const trpgMatTable &);
/* This read method overrides the one from trpgMatTable and knows
how to read the old school material tables.
*/
bool Read(trpgReadBuffer &);
/* This write method can write a 2.0 material table as 1.0
style for backward compatibility.
*/
bool Write(trpgWriteBuffer &);
protected:
};
/* Texture Table 1.0.
This class is used to read old 1.0 texture tables and convert them
into 2.0 texture tables. Users should never directly interact with
this class.
{secret}
*/
class trpgTexTable1_0 : public trpgTexTable {
public:
trpgTexTable1_0() { };
trpgTexTable1_0(const trpgTexTable &);
/* This read method overrides the one from trpgTexTable and
knows how to read the old style texture table.
*/
bool Read(trpgReadBuffer &);
/* The write method can write a 2.0 texture table as 1.0
style for backward compatibility.
*/
bool Write(trpgWriteBuffer &);
protected:
};
/* Texture 1.0.
Knows how to read an old style texture.
{secret}
*/
class trpgTexture1_0 : public trpgTexture {
public:
// Assignment operator from a regular trpgTexture
trpgTexture1_0 operator = (const trpgTexture &);
// Knows how to read old style textures
bool Read(trpgReadBuffer &);
// Can write old style textures
bool Write(trpgWriteBuffer &);
protected:
};
/* Tile Table 1.0
Knows how to write an old style tile table.
{secret}
*/
class trpgTileTable1_0 : public trpgTileTable {
public:
trpgTileTable1_0(const trpgTileTable &);
// Can write old style tile table
bool Write(trpgWriteBuffer &);
};
#endif

View File

@@ -24,8 +24,8 @@
#include <stdio.h>
#include <string.h>
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
#include <osg/Vec3>

File diff suppressed because it is too large Load Diff

View File

@@ -23,8 +23,8 @@
to the header definition.
*/
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
/* Write Header class
Fill it in and write it out.

View File

@@ -1,615 +0,0 @@
/* ************************
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_io_h_
#define _trpage_io_h_
/* trpage_io.h
Token definitions and basic classes.
*/
#include "trpage_sys.h"
// Macros we may need
#ifndef MIN
// {secret}
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
// {secret}
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
// File header Magic Number
#define TRPG_MAGIC 9480372
// Current TerraPage major version
#define TRPG_VERSION_MAJOR 2
// Current TerraPage minor version
#define TRPG_VERSION_MINOR 0
// Non-existent token
// {secret}
#define TRPG_NOTOKEN 0
// 16 bit token definition value. These are values such as TRPGTEXTABLE or TRPG_ATTACH, etc...
typedef short trpgToken;
// Tokens for paging data structures
// Update the MINTOKEN and MAXTOKEN when you add tokens
// {secret}
#define TRPG_MINTOKEN 100
// {secret}
#define TRPG_PUSH 100
// {secret}
#define TRPG_POP 101
// {secret}
#define TRPGHEADER 200
// {secret}
#define TRPGHEAD_LODINFO 201
// {secret}
#define TRPGMATTABLE 300
// Added 11/14/98 - New material table
// {secret}
#define TRPGMATTABLE2 301
// Added 11/14/98
// {secret}
#define TRPGSHORTMATTABLE 302
// {secret}
#define TRPGMATERIAL 400
// {secret}
#define TRPGMAT_BASIC 401
// {secret}
#define TRPGMAT_SHADE 402
// {secret}
// {secret}
#define TRPGMAT_SIZES 403
// {secret}
#define TRPGMAT_CULL 404
// {secret}
#define TRPGMAT_ALPHA 405
// {secret}
#define TRPGMAT_NORMAL 406
// {secret}
#define TRPGMAT_TEXTURE 407
// {secret}
#define TRPGMAT_BUMP 408
// {secret}
#define TRPGMAT_TEXENV 500
// {secret}
#define TRPGMAT_TXENV_MODE 501
// {secret}
#define TRPGMAT_TXENV_FILTER 502
// {secret}
#define TRPGMAT_TXENV_WRAP 503
// {secret}
#define TRPGMAT_TXENV_BORDER 504
// {secret}
#define TRPGTEXTABLE 600
// {secret}
#define TRPGTEXTABLE2 601
// {secret}
#define TRPGTEXTURE 650
// {secret}
#define TRPGMODELREF 700
// {secret}
#define TRPGMODELTABLE 800
// {secret}
#define TRPGTILETABLE 900
// {secret}
#define TRPG_TILE_ENTRY 901
// {secret}
#define TRPGTILETABLE2 902
// {secret}
#define TRPGTILEHEADER 1000
// {secret}
#define TRPG_TILE_MATLIST 1001
// {secret}
#define TRPG_TILE_MODELLIST 1002
// {secret}
#define TRPG_TILE_DATE 1003
// {secret}
#define TRPGLOCALMATERIAL 1004
// {secret}
#define TRPG_TILE_LOCMATLIST 1005
// Lights support added by Nick
// {secret}
#define TRPGLIGHTTABLE 1100
// {secret}
#define TRPGLIGHTATTR 1150
// {secret}
#define TRPGLIGHTATTR_BASIC 1151
// {secret}
#define TRPGLIGHTATTR_RASCAL 1152
// {secret}
#define TRPGLIGHTATTR_CALLIGRAPHIC 1153
// {secret}
#define TRPGLIGHTATTR_PERFORMER 1154
// {secret}
#define TRPGLIGHTATTR_ANIMATION 1155
// {secret}
#define TRPGLIGHT 1160
#define TRPG_LIGHT 1160
// {secret}
#define TRPGRANGETABLE 1200
// {secret}
#define TRPG_RANGE 1201
// {secret}
#define TRPG_GROUP 2001
// {secret}
#define TRPG_BILLBOARD 2002
// {secret}
#define TRPG_LOD 2003
// {secret}
#define TRPG_TRANSFORM 2004
// {secret}
#define TRPG_MODELREF 2005
// {secret}
#define TRPG_LAYER 2006
// {secret}
#define TRPG_GEOMETRY 3000
// {secret}
#define TRPG_GEOM_PRIM 3001
// {secret}
#define TRPG_GEOM_MATERIAL 3002
// {secret}
#define TRPG_GEOM_VERT32 3003
// {secret}
#define TRPG_GEOM_VERT64 3004
// {secret}
#define TRPG_GEOM_NORM32 3005
// {secret}
#define TRPG_GEOM_NORM64 3006
// {secret}
#define TRPG_GEOM_COLOR 3007
// {secret}
#define TRPG_GEOM_TEX32 3008
// {secret}
#define TRPG_GEOM_TEX64 3009
// {secret}
#define TRPG_GEOM_EFLAG 3010
// {secret}
#define TRPG_ATTACH 4000
// {secret}
#define TRPG_MAXTOKEN 4000
// Basic data types
/* 64 bit disk reference value. */
typedef trpgllong trpgDiskRef;
// {secret}
typedef int trpgMatRef;
/* Double precision 2 dimensional point. */
TX_EXDECL class TX_CLDECL trpg2dPoint {
public:
double x, y;
trpg2dPoint (void) { };
trpg2dPoint (double in_x,double in_y) { x = in_x; y = in_y; };
};
/* Integer 2 dimensional point. This is used primarily as a 2D index value. */
TX_EXDECL class TX_CLDECL trpg2iPoint {
public:
int x,y;
trpg2iPoint (void) { };
trpg2iPoint (int in_x,int in_y) {x = in_x; y = in_y;};
};
/* Double precision 3 dimensional point. */
TX_EXDECL class TX_CLDECL trpg3dPoint {
public:
double x,y,z;
trpg3dPoint(void) { };
trpg3dPoint(double in_x,double in_y,double in_z) {x = in_x; y = in_y; z = in_z;}
bool operator==(const trpg3dPoint& pt ) {
if ( x != pt.x ) return false;
if ( y != pt.y ) return false;
if ( z != pt.z ) return false;
return true;
};
bool operator!=(const trpg3dPoint& pt ) { return !operator==(pt); };
};
/* Simple red, green, blue color definition */
TX_EXDECL class TX_CLDECL trpgColor {
public:
trpgColor(float64 r,float64 g,float64 b) {red = r; green = g; blue = b;}
trpgColor(void) { };
bool operator==(const trpgColor& color) {
if ( color.red != red ) return false;
if ( color.green != green ) return false;
if ( color.blue != blue ) return false;
return true;
};
bool operator!=(const trpgColor& color) { return !operator==(color); };
float64 red,green,blue;
};
// Used to specify machine endianess
typedef enum {LittleEndian,BigEndian} trpgEndian;
/* This is a base class for an abstract buffer type.
It contains the virtual methods for writing
data to an abstract device. The device implementation is up
to the subclass. trpgReadBuffer performs the similar function
for reading.
{group:Low Level I/O}
*/
TX_EXDECL class TX_CLDECL trpgWriteBuffer {
public:
virtual ~trpgWriteBuffer(void) { };
/* The add functions must be filled in by the child class
They add data of the appropriate type to the current buffer. */
virtual void Add(int32) = 0;
virtual void Add(int64) = 0;
virtual void Add(const char *) = 0;
virtual void Add(float32) = 0;
virtual void Add(float64) = 0;
#if (bool != int32)
virtual void Add(bool) = 0;
#endif
virtual void Add(uint8) = 0;
#if (trpgDiskRef != int64)
virtual void Add(trpgDiskRef) = 0;
#endif
virtual void Add(trpgToken) = 0;
/* Child class method. Returns the buffer to an original state. */
virtual void Reset(void) = 0;
// See trpgMemWriteBuffer for details
virtual void Begin(trpgToken) = 0;
// See trpgMemWriteBuffer for details
virtual void End(void) = 0;
// See trpgMemWriteBuffer for details
virtual void Push(void) = 0;
// See trpgMemWriteBuffer for details
virtual void Pop(void) = 0;
// Some add functions are helpers for composite values that call the basic add functions
virtual void Add(const trpg2iPoint &);
virtual void Add(const trpg2dPoint &);
virtual void Add(const trpg3dPoint &);
virtual void Add(const trpgColor &);
/* Endianness is something the child class buffer type must set and use.
This function returns the endiannes of the current buffer. */
virtual trpgEndian GetEndian(void) { return ness; }
protected:
// Target endianness of the buffer. This should be set by the subclass on creation.
trpgEndian ness;
// Endianness of the machine we're running on.
trpgEndian cpuNess;
};
/* The Memory Write Buffer is an implementation of the Write Buffer that
uses chunks of memory. It contains implementations of the all the virtual
methods straight to memory. This is used primarily in writing archives and
tiles.
{group:Low Level I/O}
*/
TX_EXDECL class TX_CLDECL trpgMemWriteBuffer : public trpgWriteBuffer {
public:
/* The constructor takes an endianness for this buffer.
Data will automatically be converted to that as it goes in. */
trpgMemWriteBuffer(trpgEndian);
virtual ~trpgMemWriteBuffer(void);
// Return the current length of buffer
virtual int length(void) const;
// Return the raw data (if you want to write to disk, for example)
virtual const char *getData(void) const;
// Allocate the given amount of space for the buffer
virtual void setLength(unsigned int);
// Add a 32 bit integer to the buffer
virtual void Add(int32);
// Add a 64 bit integer to the buffer
virtual void Add(int64);
/* Add an arbitrary length string to the buffer.
This writes both the length and the string itself.
*/
virtual void Add(const char *);
// Add a 32 bit float to the buffer
virtual void Add(float32);
// Add a 64 bit float to the buffer
virtual void Add(float64);
#if (bool != int32)
// Add a boolean value to the buffer. It will become at least one byte.
virtual void Add(bool);
#endif
// Add an unsigned character to the buffer
virtual void Add(uint8);
#if (trpgDiskRef != int64)
// Add a 64 bit disk reference to the buffer
virtual void Add(trpgDiskRef);
#endif
// Add a token (16 bit) to the buffer
virtual void Add(trpgToken);
// Reset this buffer. This will set the current length to zero, but will not deallocate memory
virtual void Reset(void);
/* Start defining an tokenized object. The token is put into the buffer stream
and the position of a size value following it is kept. When End() is called
the buffer will rewind to that value and save the size. This method ensures
that token data can be skipped if necessary. */
virtual void Begin(trpgToken);
/* This method is called at the end of a tokenized object. See Begin for details. */
virtual void End(void);
/* Adds the TRPG_PUSH token to the current buffer. This is done by objects
that have children as they're being written. See Pop as well. */
virtual void Push(void);
/* Adds the TRPG_POP token to the current buffer. This is done by objects
that have defined children. See Push. */
virtual void Pop(void);
protected:
virtual void append(unsigned int,const char *);
virtual void set(unsigned int pos,unsigned int len,const char *);
int curLen;
int totLen;
char *data;
std::vector<int> lengths;
};
/* This is a virtual base class for reading data from a device.
The device implementation is left as an excercise to the sub class.
This class contains methods for getting data that must be filled in
as well as helper methods that call those.
{group:Low Level I/O}
*/
TX_EXDECL class TX_CLDECL trpgReadBuffer {
public:
virtual ~trpgReadBuffer(void) { };
/* The Get methods are utility routines that all call the GetData method.
Only that method need be filled in by a subclass. */
virtual bool Get(int32 &);
virtual bool Get(int64 &);
virtual bool Get(char *,int);
virtual bool Get(float32 &);
virtual bool Get(float64 &);
#if (bool != int32)
virtual bool Get(bool &);
#endif
virtual bool Get(uint8 &);
#if (trpgDiskRef != int64)
virtual bool Get(trpgDiskRef &);
#endif
virtual bool Get(trpgToken &);
/* These methods return references to arrays of data of the given types.
These are all utility routines and depend upon GetDataRef. */
virtual bool GetArray(int,float32 **);
virtual bool GetArray(int,float64 **);
virtual bool GetArray(int,int32 **);
virtual bool GetArray(int,trpgColor **);
virtual bool GetArray(int,char **);
virtual bool Get(trpg2iPoint &);
virtual bool Get(trpg2dPoint &);
virtual bool Get(trpg3dPoint &);
virtual bool Get(trpgColor &);
virtual bool GetToken(trpgToken &,int32 &);
/* Force the buffer to only allow the next N bytes to be read.
The limits are stack based. That is, this limit is the current one
until it's popped off the stack. Then it reverts to the previous one.
Any bytes read in the mean time count against all limits. */
virtual void PushLimit(int);
/* Revert to the limit before this one. Typically this would happen when
a tokenized object has been read. */
virtual void PopLimit(void);
/* Skip to the end of the current limit. This is done by a parser when
reading a tokenized object from the buffer to make sure that the next
object can be safely read even if the current one wasn't. */
virtual bool SkipToLimit(void);
// Buffer is empty
virtual bool isEmpty(void) = 0;
protected:
trpgEndian ness; // Endianness of the source we're reading
trpgEndian cpuNess; // Endiannees of the CPU
/* Virtual raw data retrieval function that must be implemented by a subclass.
It must return a given number of bytes in the array passed in. */
virtual bool GetData(char *,int)=0;
/* Virtual raw data reference retrieval function. The difference between
this method and GetData is that this is supposed to return a pointer
to a given amount of bytes. This assumes some sort of memory caching
mechanism in the subclass. */
virtual bool GetDataRef(char **,int)=0;
/* This virtual method must be filled in by the subclass so that SkipToLimit
will work correctly. */
virtual bool Skip(int) = 0;
/* A utility function for subclasses to use to see if they would exceed an
outside imposed limit by reading the given number of bytes. */
virtual bool TestLimit(int);
/* Utility function that must be called after a successfull read to update
the outside imposed read limits. */
virtual void UpdateLimits(int);
std::vector<int> limits;
};
/* This class implements a read buffer that uses a chunk of memory.
Typically, raw data will be dumped into this class, then it will be
passed to a parser for object based reading.
{group:Low Level I/O}
*/
TX_EXDECL class TX_CLDECL trpgMemReadBuffer : public trpgReadBuffer {
public:
// Memory read buffers must be initialized with an endianness
trpgMemReadBuffer(trpgEndian);
~trpgMemReadBuffer(void);
// Return true if we're out of data
bool isEmpty(void);
// Sets the size of this read buffer.
void SetLength(int);
/* Return a pointer to the raw data cache for this object. Data will
be dumped straight into here (from disk, for example) and then parsed
by something that takes a trpgReadBuffer as input. */
char *GetDataPtr(void);
protected:
bool GetData(char *,int); // Retrieve the given amount of data
bool GetDataRef(char **,int); // Retrieve a pointer to the given array
bool Skip(int); // Skip over the given amount
int len; // Data Length
int totLen; // Total allocated length
int pos; // Current position
char *data;
};
/* A Checkable is purely a base class used by other classes that
need validity checks associated with them. By default, the
checkable will return false for isValid unless the valid flag is set.
*/
TX_EXDECL class TX_CLDECL trpgCheckable {
public:
trpgCheckable(void);
virtual ~trpgCheckable(void);
// Returns the state of the valid flag, or can be overriden by a subclass to do a more complex check.
bool isValid(void) const;
protected:
/* Set this flag to true if your checkable structure doesn't have a complex
check it needs to do. */
bool valid;
};
class trpgPrintBuffer;
/* The Read/Writeable is a class that knows how to read itself from a trpgReadBuffer
and write itself to a trpgWriteBuffer. This includes all the node and header
data in TerraPage. These classes are intended as marshalling points for reading
and writing data, not as data containers in and of themselves. If you find
yourself keeping a lot of classes derived from trpgReadWriteable around, you're
probably misusing them.
The classes derived from this one will have a lot of methods that begin with
"Set", "Get", and "Add". These will almost always return a bool value. This
is used to indicate whether the given call succeeded. In the case of "Set" and "Add" calls
this should always work if it possibly can. An out of range index might make it
fail, for example. "Get" calls will always fail if the object you're getting from
is not valid. Be sure to do an isValid check as soon as you've read or filled out
one of these objects.
{group:Read/Write Classes}
*/
TX_EXDECL class TX_CLDECL trpgReadWriteable : public trpgCheckable {
public:
/* The Write method is a virtual that must be filled in by the subclass.
It takes a trpgWriteBuffer and should return true on success. */
virtual bool Write(trpgWriteBuffer &) = 0;
/* The Read method should be overriden by a subclass. It should read
the contents of the given trpgReadBuffer up to the current limit
into itself. It must return true on success. */
virtual bool Read(trpgReadBuffer &) { return false;};
/* Every read/writeable must be able to reset itself to a pristine state
so that, for example, multiple objects of the same type can be read into
it, one after the other. */
virtual void Reset(void) = 0;
/* The print method is optional. If it's not there, it won't do anything.
*/
virtual bool Print(trpgPrintBuffer &) const { return true; }
protected:
};
/* Pointer into a trpgwAppFile. The full name of the file
is based on the context (e.g. texture vs. tile)
{group:Archive Writing}
*/
TX_EXDECL class TX_CLDECL trpgwAppAddress {
public:
// Which file
int32 file;
// Offset within the file
// Note: This is not a 64 bit value
int32 offset;
};
/* Archive File.
This class represents an appendable file archive used for
consolidating tiles and textures.
{group:Archive Writing}
*/
TX_EXDECL class TX_CLDECL trpgwAppFile {
public:
trpgwAppFile(trpgEndian,const char *);
virtual ~trpgwAppFile(void);
virtual bool Append(const trpgMemWriteBuffer *,const trpgMemWriteBuffer *);
virtual bool Append(const char *,int size);
virtual int64 Pos(void) const;
virtual int GetLengthWritten();
bool isValid(void) const;
protected:
bool valid;
trpgEndian ness,cpuNess;
FILE *fp;
int lengthSoFar;
};
/* Archive File - Read version.
This class represents an appendable file archive from the
read perspective. This is the same type of file written by
trpgwAppFile.
*/
TX_EXDECL class TX_CLDECL trpgrAppFile {
public:
trpgrAppFile(trpgEndian,const char *);
virtual ~trpgrAppFile(void);
virtual bool Read(trpgMemReadBuffer *,int32 offset);
virtual bool Read(char *data,int32 offset,uint32 dataSize);
bool isValid(void) const;
protected:
bool valid;
trpgEndian ness,cpuNess;
FILE *fp;
};
/* Archive File Cache.
This class keeps
*/
TX_EXDECL class TX_CLDECL trpgrAppFileCache {
public:
trpgrAppFileCache(const char *prefix,const char *ext,int noFiles=32);
~trpgrAppFileCache(void);
trpgrAppFile *GetFile(trpgEndian ness,int id);
protected:
// Prefix name and extension
char baseName[1024],ext[20];
class OpenFile {
public:
OpenFile(void);
int id; // ID of open file
trpgrAppFile *afile;
int lastUsed; // When the file was last accessed
};
std::vector<OpenFile> files;
int timeCount; // Incremented for every access
};
#endif

View File

@@ -24,8 +24,8 @@
#include <stdio.h>
#include <string.h>
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
#if defined(_WIN32)
#define ALIGNMENT_WORKAROUND false

View File

@@ -26,6 +26,6 @@
#include <stdlib.h>
#include <stdio.h>
#include "trdll.h"
#include <osgTXP/trdll.h>
TXDUMMY_DLL_MAIN

View File

@@ -0,0 +1,810 @@
/* ************************
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
************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <osgTXP/trpage_sys.h>
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
#include <osgTXP/trpage_print.h>
#include <osgTXP/trpage_managers.h>
/* Managed Tile class.
Check the header file for details.
*/
trpgManagedTile::trpgManagedTile()
{
isLoaded = false;
x = y = -1;
lod = -1;
localData = NULL;
}
void trpgManagedTile::Reset()
{
// Null out the local material data
for (int i=0;i<int(localMatData.size());i++)
localMatData[i] = NULL;
groupIDs.resize(0);
isLoaded = false;
x = y = -1;
lod = -1;
localData = NULL;
}
bool trpgManagedTile::ParseTileHeader(trpgReadBuffer &buf)
{
isLoaded = false;
if (!tileHead.Read(buf))
return false;
int numLoc;
tileHead.GetNumLocalMaterial(numLoc);
localMatData.resize(numLoc);
// The tile considers itself loaded with just
// the header. This isn't true as far as the paging
// manager is concerned.
isLoaded = true;
return true;
}
bool trpgManagedTile::IsLoaded()
{
return isLoaded;
}
bool trpgManagedTile::SetTileLoc(int inX,int inY,int inLod)
{
x = inX; y = inY;
if (inLod < 0)
return false;
lod = inLod;
return true;
}
bool trpgManagedTile::GetTileLoc(int &retx,int &rety,int &retLod)
{
retx = x; rety = y; retLod = lod;
return true;
}
const trpgTileHeader *trpgManagedTile::GetTileHead()
{
return &tileHead;
}
const std::vector<trpgLocalMaterial> *trpgManagedTile::GetLocMatList() const
{
return tileHead.GetLocalMaterialList();
}
const trpgLocalMaterial *trpgManagedTile::GetLocMaterial(int id) const
{
const std::vector<trpgLocalMaterial> *matList;
matList = tileHead.GetLocalMaterialList();
if (id <0 || id >= int(matList->size()))
return NULL;
return &(*matList)[id];
}
void trpgManagedTile::SetLocalData(void *inData)
{
localData = inData;
}
void *trpgManagedTile::GetLocalData() const
{
return localData;
}
bool trpgManagedTile::SetMatData(int id,void *info)
{
if (id < 0 || id >= int(localMatData.size()))
return false;
localMatData[id] = info;
return true;
}
void *trpgManagedTile::GetMatData(int id) const
{
if (id < 0 || id >= int(localMatData.size()))
return NULL;
return localMatData[id];
}
void trpgManagedTile::AddGroupID(int id)
{
groupIDs.push_back(id);
}
const std::vector<int> *trpgManagedTile::GetGroupIDs() const
{
return &groupIDs;
}
void trpgManagedTile::Print(trpgPrintBuffer &buf)
{
char line[1024];
sprintf(line,"x = %d, y = %d, lod = %d",x,y,lod); buf.prnLine(line);
// Note: Should print the rest too, probably.
}
/* Page Manager LOD Page Info class.
Used by the page manager to keep track of paging information
for a single terrain LOD. See the header file for details.
*/
trpgPageManager::LodPageInfo::LodPageInfo()
{
valid = false;
pageDist = 0.0;
cell.x = cell.y = -100;
}
trpgPageManager::LodPageInfo::~LodPageInfo()
{
Clean();
}
void trpgPageManager::LodPageInfo::Clean()
{
// Clean up managed tile structures
int i;
for (i=0;i<int(load.size());i++)
if (load[i])
delete load[i];
load.resize(0);
for (i=0;i<int(unload.size());i++)
if (unload[i])
delete unload[i];
unload.resize(0);
for (i=0;i<int(current.size());i++)
if (current[i])
delete current[i];
current.resize(0);
for (i=0;i<int(freeList.size());i++)
delete freeList[i];
freeList.resize(0);
activeLoad = false;
activeUnload = false;
}
bool trpgPageManager::LodPageInfo::Init(trpgr_Archive *archive, int myLod, double scale)
{
Clean();
lod = myLod;
// In theory we could have a negative scale, but I don't
// really want to deal with that.
if (scale < 0) scale = 0.0;
// Need some size and shape info about our terrain LOD
const trpgHeader *head = archive->GetHeader();
head->GetTileSize(lod,cellSize);
head->GetLodRange(lod,pageDist);
head->GetLodSize(lod,lodSize);
pageDist *= scale;
// Area of interest size (in cells)
aoiSize.x = (int)(pageDist/cellSize.x);
aoiSize.y = (int)(pageDist/cellSize.y);
/* Make a guess as to how many tiles we might have loaded
in at any given time. Give ourselves 15% extra room.
From the area of interest in cells, we can guess the max
number of tiles (aka cells) we'll have loaded in at once.
Note that the AOI size is only ahead, so it must be doubled.
*/
maxNumTiles = (int)(1.15*(2*aoiSize.x+1)*(2*aoiSize.y+1));
// Allocate 'em
for (int i=0;i<maxNumTiles;i++) {
trpgManagedTile *tile = new trpgManagedTile();
freeList.push_back(tile);
}
// We still don't have a position yet
valid = true;
return true;
}
bool trpgPageManager::LodPageInfo::SetLocation(trpg2dPoint &loc)
{
// Calculate the cell this falls into
trpg2iPoint newCell;
newCell.x = (int)(loc.x/cellSize.x);
newCell.y = (int)(loc.y/cellSize.y);
// Snap to the database border
if (newCell.x < 0) newCell.x = 0;
if (newCell.y < 0) newCell.y = 0;
if (newCell.x >= lodSize.x) newCell.x = lodSize.x-1;
if (newCell.y >= lodSize.y) newCell.y = lodSize.y-1;
// Nothing to page. Done.
if (newCell.x == cell.x && newCell.y == cell.y)
return false;
// Cell has changed. Update.
cell = newCell;
Update();
return true;
}
trpgManagedTile *trpgPageManager::LodPageInfo::GetNextLoad()
{
// Can only load one tile at a time
if (activeLoad)
return NULL;
// Clear any NULLs at the beginning
while (load.size() && !load[0])
load.pop_front();
if (load.size() > 0) {
activeLoad = true;
return load[0];
}
return NULL;
}
void trpgPageManager::LodPageInfo::AckLoad()
{
if (activeLoad) {
current.push_back(load[0]);
load.pop_front();
}
activeLoad = false;
}
trpgManagedTile *trpgPageManager::LodPageInfo::GetNextUnload()
{
// Can only unload one tile at a time
if (activeUnload)
return NULL;
// Clear any NULLs at the beginning
while (unload.size() && !unload[0])
unload.pop_front();
if (unload.size() > 0) {
activeUnload = true;
return unload[0];
}
return NULL;
}
void trpgPageManager::LodPageInfo::AckUnload()
{
if (activeUnload) {
trpgManagedTile *tile = unload[0];
tile->Reset();
freeList.push_back(tile);
unload.pop_front();
}
activeUnload = false;
}
bool trpgPageManager::LodPageInfo::isWithin(trpgManagedTile *tile,trpg2iPoint &sw,trpg2iPoint &ne)
{
int tileX,tileY,tileLod;
tile->GetTileLoc(tileX,tileY,tileLod);
if (tileX >= sw.x && tileX <= ne.x &&
tileY >= sw.y && tileY <= ne.y)
return true;
return false;
}
bool trpgPageManager::LodPageInfo::Stop()
{
// Empty the load list
int i;
for (i=0;i<int(load.size());i++)
freeList.push_back(load[i]);
load.resize(0);
// Move the current tiles to the unload list
for (i=0;i<int(current.size());i++)
if (current[i])
unload.push_back(current[i]);
current.resize(0);
return (unload.size() > 0);
}
/* Update does the major work of figuring out what to load and
what to unload.
*/
void trpgPageManager::LodPageInfo::Update()
{
trpg2iPoint sw,ne;
// Figure out the lower left and upper right corners
// in cell coordinates
sw.x = cell.x - aoiSize.x; sw.y = cell.y - aoiSize.y;
ne.x = cell.x + aoiSize.x; ne.y = cell.y + aoiSize.y;
sw.x = MAX(0,sw.x); sw.y = MAX(0,sw.y);
ne.x = MIN(lodSize.x-1,ne.x); ne.y = MIN(lodSize.y-1,ne.y);
/* Load list -
Some of the tiles we're supposed to load may now be
out of range. Take them off the load list.
*/
int i;
for (i=0;i<int(load.size());i++) {
if (load[i] && !isWithin(load[i],sw,ne)) {
freeList.push_back(load[i]);
load[i] = NULL;
}
}
/* Unload list -
Some of the tiles we were planning on unloading may now
be in view again. Move them back to current.
*/
for (i=0;i<int(unload.size());i++) {
if (unload[i] && isWithin(unload[i],sw,ne)) {
current.push_back(unload[i]);
unload[i] = NULL;
}
}
/* Current list -
We need to figure out a few things here.
1) What's in the current list that should be paged out.
2) What's already paged, sorted into tmpCurrent.
3) What's missing from tmpCurrent and should be paged in.
*/
// Look for tiles to page out
// Move them to the unload list
for (i=0;i<int(current.size());i++) {
if (current[i] && !isWithin(current[i],sw,ne)) {
unload.push_back(current[i]);
current[i] = NULL;
}
}
// Clean the NULLs out of the current list
int curPos = 0;
for (i=0;i<int(current.size());i++) {
if (current[i]) {
current[curPos] = current[i];
curPos++;
}
}
current.resize(curPos);
// Sort the currently loaded stuff into a spatial array
// so we can figure out what needs to be loaded in addition.
int dx,dy;
dx = ne.x - sw.x+1; dy = ne.y - sw.y+1;
tmpCurrent.resize(dx*dy);
for (i=0;i<int(tmpCurrent.size());i++) tmpCurrent[i] = false;
for (i=0;i<int(current.size());i++) {
trpgManagedTile *tile = current[i];
if (tile) {
int tileX,tileY,tileLod;
tile->GetTileLoc(tileX,tileY,tileLod);
tmpCurrent[(tileY-sw.y)*dx + (tileX-sw.x)] = true;
}
}
// Now figure out which ones are missing and add them
// to the load list
for (int x=0;x<dx;x++) {
for (int y=0;y<dy;y++) {
if (!tmpCurrent[y*dx + x]) {
// Allocate a new tile
trpgManagedTile *tile = NULL;
if (freeList.size() > 0) {
tile = freeList[0];
freeList.pop_front();
} else
tile = new trpgManagedTile();
tile->SetTileLoc(x+sw.x,y+sw.y,lod);
load.push_back(tile);
}
}
}
// That's it. All the rest is handled by the caller
// iterating through the tiles to load and unload.
}
void trpgPageManager::LodPageInfo::Print(trpgPrintBuffer &buf)
{
char line[1024];
int i;
sprintf(line,"lod = %d, valid = %s",lod,(valid ? "yes" : "no")); buf.prnLine(line);
sprintf(line,"pageDist = %f, maxNumTiles = %d",pageDist,maxNumTiles); buf.prnLine(line);
sprintf(line,"cellSize = (%f,%f)",cellSize.x,cellSize.y); buf.prnLine(line);
sprintf(line,"cell = (%d,%d), aoiSize = (%d,%d), lodSize = (%d,%d)",cell.x,cell.y,aoiSize.x,aoiSize.y,lodSize.x,lodSize.y); buf.prnLine(line);
sprintf(line,"Loads: (activeLoad = %s)",(activeLoad ? "yes" : "no")); buf.prnLine(line);
buf.IncreaseIndent();
for (i=0;i<int(load.size());i++)
if (load[i])
load[i]->Print(buf);
buf.DecreaseIndent();
sprintf(line,"Unloads: (activeUnload = %s)",(activeUnload ? "yes" : "no")); buf.prnLine(line);
buf.IncreaseIndent();
for (i=0;i<int(unload.size());i++)
if (unload[i])
unload[i]->Print(buf);
buf.DecreaseIndent();
buf.prnLine("Currently loaded:");
buf.IncreaseIndent();
for (i=0;i<int(current.size());i++)
if (current[i])
current[i]->Print(buf);
buf.DecreaseIndent();
sprintf(line,"Free list size = %d",freeList.size()); buf.prnLine(line);
}
/* Page Manager methods
These are methods of the main trpgPageManager. Check the header
file for more detailed information.
*/
trpgPageManager::trpgPageManager()
{
scale = 1.0;
valid = false;
// This should be sufficiently unlikely
pagePt.x = -1e20; pagePt.y = -1e20;
}
trpgPageManager::~trpgPageManager()
{
}
void trpgPageManager::Init(trpgr_Archive *inArch)
{
archive = inArch;
// We're resetting everything. In general, Init should only
// be called once, but it'll work fine if you call it more than once.
lastLoad = None;
lastTile = NULL;
lastLod = -1;
// Need to know the number of terrain LODs
const trpgHeader *head = archive->GetHeader();
int numLod;
head->GetNumLods(numLod);
// Reset the terrain LOD paging classes.
valid = true;
pageInfo.resize(numLod);
for (int i=0;i<numLod;i++) {
pageInfo[i].Init(archive,i,scale);
}
}
bool trpgPageManager::SetPageDistFactor(double inFact)
{
// A scaling factor less than 1 will break the archive display.
if (inFact <= 1.0)
return false;
scale = inFact;
return true;
}
bool trpgPageManager::SetLocation(trpg2dPoint &pt)
{
// Do a basic sanity check
if (!valid || (pagePt.x == pt.x && pagePt.y == pt.y))
return false;
pagePt = pt;
// Call each terrain LOD and let if figure out if something
// has changed.
bool change = false;
for (int i=0;i<int(pageInfo.size());i++) {
if (pageInfo[i].SetLocation(pt))
change = true;
}
return change;
}
trpgManagedTile *trpgPageManager::GetNextLoad()
{
// If we're already doing something, let them know about it
if (lastLoad != None)
throw 1;
// Look for anything that needs loaded
// Start with lowest LOD, work up to highest
trpgManagedTile *tile = NULL;
for (int i=0;i<int(pageInfo.size());i++) {
LodPageInfo &info = pageInfo[i];
if ((tile = info.GetNextLoad()))
break;
}
// Found one. Now the user has to load it.
if (tile) {
lastLoad = Load;
lastTile = tile;
lastLod = tile->lod;
}
return tile;
}
void trpgPageManager::AckLoad()
{
// If we're not in the middle of a load, register our displeasure
if (lastLoad != Load)
throw 1;
LodPageInfo &info = pageInfo[lastLod];
info.AckLoad();
lastLoad = None;
lastTile = NULL;
}
void trpgPageManager::AddGroupID(trpgManagedTile *tile,int groupID,void *data)
{
groupMap[groupID] = data;
tile->AddGroupID(groupID);
}
void *trpgPageManager::GetGroupData(int groupID)
{
ManageGroupMap::const_iterator p = groupMap.find(groupID);
if (p != groupMap.end())
return (*p).second;
return NULL;
}
trpgManagedTile *trpgPageManager::GetNextUnload()
{
// If we're already doing something, let them know about it
if (lastLoad != None)
throw 1;
// Look for anything that needs unloaded
// Start with highest LOD, work down to lowest
trpgManagedTile *tile = NULL;
for (int i=pageInfo.size()-1;i>=0;i--) {
LodPageInfo &info = pageInfo[i];
if ((tile = info.GetNextUnload()))
break;
}
// Found one. Now the user has to unload it.
if (tile) {
lastLoad = Unload;
lastTile = tile;
lastLod = tile->lod;
}
return tile;
}
void trpgPageManager::AckUnload()
{
// If we're not in the middle of an unload, let 'em know.
if (lastLoad != Unload)
throw 1;
// Remove this tile's group IDs from the map
const std::vector<int> *groupIDs = lastTile->GetGroupIDs();
int i;
for (i=0;i<int(groupIDs->size());i++) {
ManageGroupMap::iterator p = groupMap.find((*groupIDs)[i]);
if (p != groupMap.end())
groupMap.erase(p);
}
LodPageInfo &info = pageInfo[lastLod];
info.AckUnload();
lastLoad = None;
lastTile = NULL;
}
bool trpgPageManager::Stop()
{
bool res=false;
int i;
for (i=0;i<int(pageInfo.size());i++)
res |= pageInfo[i].Stop();
lastLoad = None;
return res;
}
void trpgPageManager::Print(trpgPrintBuffer &buf)
{
char line[1024];
sprintf(line,"Paging pos = (%f,%f), scale = %f",pagePt.x,pagePt.y,scale); buf.prnLine(line);
buf.prnLine("Terrain LODs:");
int i;
for (i=0;i<int(pageInfo.size());i++) {
sprintf(line,"----Terrain lod %d---",i); buf.prnLine(line);
buf.IncreaseIndent();
pageInfo[i].Print(buf);
buf.DecreaseIndent();
}
}
/* Page Manager Tester
These methods are used to test the Paging Manager.
*/
trpgPageManageTester::trpgPageManageTester()
{
manager = NULL;
archive = NULL;
}
trpgPageManageTester::~trpgPageManageTester()
{
}
void trpgPageManageTester::Init(trpgPrintBuffer *pBuf,trpgPageManager *pMan,trpgr_Archive *inArch)
{
archive = inArch;
manager = pMan;
printBuf = pBuf;
if (!archive->isValid())
throw 1;
// Start up the paging manager
manager->Init(archive);
}
void trpgPageManageTester::RandomTest(int num,int seed)
{
if (!manager || !archive || !printBuf)
throw 1;
// Seed the random number generator so we can replicate runs
if (seed != -1)
srand(seed);
// Need the extents
trpg2dPoint ll,ur,lod0Size;
const trpgHeader *head = archive->GetHeader();
head->GetExtents(ll,ur);
head->GetTileSize(0,lod0Size);
// Give ourselves some space around the extents
ll.x -= lod0Size.x/2.0; ll.y -= lod0Size.y/2.0;
ur.x += lod0Size.x/2.0; ur.y += lod0Size.y/2.0;
// Jump around
int i;
char line[1024];
for (i=0;i<num;i++) {
// Generate a point
double randNum1 = rand()/(double)RAND_MAX;
double randNum2 = rand()/(double)RAND_MAX;
trpg2dPoint pt;
pt.x = (ur.x - ll.x)*randNum1;
pt.y = (ur.y - ll.y)*randNum2;
// Jump to the point
bool changes = manager->SetLocation(pt);
sprintf(line,"Jumped to (%f,%f). Tiles to load/unload = %s",pt.x,pt.y,
(changes ? "yes" : "no")); printBuf->prnLine(line);
// Process the results
ProcessChanges();
}
// Ask the page manager for its final status
manager->Print(*printBuf);
manager->Stop();
}
void trpgPageManageTester::Fly_LL_to_UR(double dist)
{
char line[1024];
if (!manager || !archive || !printBuf)
throw 1;
// Need the extents
trpg2dPoint ll,ur,lod0Size;
const trpgHeader *head = archive->GetHeader();
head->GetExtents(ll,ur);
head->GetTileSize(0,lod0Size);
// Give ourselves some space around the extents
ll.x -= lod0Size.x/2.0; ll.y -= lod0Size.y/2.0;
ur.x += lod0Size.x/2.0; ur.y += lod0Size.y/2.0;
// Fly the path
trpg2dPoint loc; loc = ll;
do {
loc.x += dist; loc.y += dist;
// Jump to next point
bool changes = manager->SetLocation(loc);
sprintf(line,"Moved to (%f,%f). Tiles to load/unload = %s",loc.x,loc.y,
(changes ? "yes" : "no")); printBuf->prnLine(line);
// Process new location
ProcessChanges();
} while (loc.x < ur.x && loc.y < ur.y);
// Ask the page manager for its final status
manager->Print(*printBuf);
manager->Stop();
}
void trpgPageManageTester::ProcessChanges()
{
char line[1024];
int x,y,lod;
// Look for unloads to process
trpgManagedTile *unloadTile;
printBuf->prnLine("Tiles to unload:");
printBuf->IncreaseIndent();
while ((unloadTile = manager->GetNextUnload())) {
unloadTile->GetTileLoc(x,y,lod);
sprintf(line,"x = %d, y = %d, lod = %d",x,y,lod); printBuf->prnLine(line);
manager->AckUnload();
}
printBuf->DecreaseIndent();
// Look for loads to process
trpgManagedTile *loadTile;
printBuf->prnLine("Tiles to load:");
printBuf->IncreaseIndent();
while ((loadTile = manager->GetNextLoad())) {
loadTile->GetTileLoc(x,y,lod);
sprintf(line,"x = %d, y = %d, lod = %d",x,y,lod); printBuf->prnLine(line);
manager->AckLoad();
}
printBuf->DecreaseIndent();
}

View File

@@ -23,8 +23,8 @@
You should only modify this code if you want to add data to these classes.
*/
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
/* Write Material Table class
Keeps track of the materials that have been added.

View File

@@ -22,8 +22,8 @@
You should only modify this code if you want to add data to these classes.
*/
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
/* Write Model class
Represents a model reference.

View File

@@ -24,8 +24,8 @@
of these classes.
*/
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
/* Write Group
Basic group.

View File

@@ -30,7 +30,7 @@
for the rest of the tokens that you want.
*/
#include "trpage_read.h"
#include <osgTXP/trpage_read.h>
/* ***************************
Paging token callback structure

View File

@@ -22,8 +22,8 @@
archive for the purpose of printing it out.
*/
#include "trpage_print.h"
#include "trpage_scene.h"
#include <osgTXP/trpage_print.h>
#include <osgTXP/trpage_scene.h>
/* Set up the callbacks for the scene graph parser.
In our case this is just one read helper with

View File

@@ -23,7 +23,7 @@
within a TerraPage archive.
*/
#include "trpage_print.h"
#include <osgTXP/trpage_print.h>
/* ******************************************
Print Buffer implementation

View File

@@ -1,106 +0,0 @@
/* ************************
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_print_h_
#define trpage_print_h_
#include "trpage_read.h"
/* Print Buffer for TerraPage. Subclasses of this object
are used to print out to stdout or disk (or whatever).
You won't create one of these directly, instead you'll create
something which inherits from it.
*/
TX_EXDECL class TX_CLDECL trpgPrintBuffer {
public:
trpgPrintBuffer(void);
virtual ~trpgPrintBuffer(void) { };
// Check if print buffer is valid
virtual bool isValid(void) { return true; }
// The main print function. Subclasses must fill this in.
virtual bool prnLine(char *str=NULL)=0;
// This increases the current indentation by the amount given (defaults to one)
virtual void IncreaseIndent(int amount=1);
// Decreases the current indentation by the amount given (defaults to one)
virtual void DecreaseIndent(int amount=1);
protected:
void updateIndent(void);
int curIndent;
char indentStr[200];
};
/* File print buffer for TerraPage. The file print buffer writes
debugging output to a file.
*/
TX_EXDECL class TX_CLDECL trpgFilePrintBuffer : public trpgPrintBuffer {
public:
// This class can be constructed with either a FILE pointer or a file name
trpgFilePrintBuffer(FILE *);
trpgFilePrintBuffer(char *);
~trpgFilePrintBuffer(void);
// Check if file print buffer is valid (i.e. if file was opened)
bool isValid(void) { return valid; };
// For a file printer buffer, this writes a string out to a file
bool prnLine(char *str = NULL);
protected:
bool valid;
bool isMine;
FILE *fp;
};
/* The Print Graph Parser is a scene graph parser that
prints out the scene graph as it goes. It's simpler
than the scene example in trpage_scene.cpp since it
isn't trying to build up a working scene graph.
*/
TX_EXDECL class TX_CLDECL trpgPrintGraphParser : public trpgSceneParser {
public:
trpgPrintGraphParser(trpgPrintBuffer *);
virtual ~trpgPrintGraphParser(void) { };
/* The read helper class is the callback for all the various
token (node) types. Normally we would use a number of
these, probably one per token. However, since we're just
printing we can use a switch statement instead.
*/
class ReadHelper : public trpgr_Callback {
public:
ReadHelper(trpgPrintBuffer *inBuf) {pBuf = inBuf;};
void *Parse(trpgToken,trpgReadBuffer &buf);
protected:
trpgPrintBuffer *pBuf;
};
protected:
bool StartChildren(void *);
bool EndChildren(void *);
trpgPrintBuffer *printBuf;
};
// Print utitility for while archive
#define TRPGPRN_ALL -1
#define TRPGPRN_HEADER (1<<0)
#define TRPGPRN_BODY (1<<1)
TX_CPPDECL bool trpgPrintArchive(char *filename,trpgPrintBuffer &pBuf,int flags=TRPGPRN_ALL);
TX_CPPDECL bool trpgPrintArchive(trpgr_Archive *,trpgPrintBuffer &pBuf,int flags=TRPGPRN_ALL);
#endif

View File

@@ -22,8 +22,8 @@
#include <stdio.h>
#include <string.h>
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
/* *******************
Range Methods

View File

@@ -22,8 +22,8 @@
The Read Archive is used to read a paging archive from disk.
*/
#include "trpage_read.h"
#include "trpage_compat.h"
#include <osgTXP/trpage_read.h>
#include <osgTXP/trpage_compat.h>
// Constructor
trpgr_Archive::trpgr_Archive()

View File

@@ -1,218 +0,0 @@
/* ************************
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_read_h_
// {secret}
#define _txpage_read_h_
/* txpage_read.h
Classes used to represent read objects for paging files.
*/
#include "trpage_sys.h"
#include "trpage_geom.h"
/* Callback base class
Called when a given token is found.
{group:Archive Reading}
*/
TX_EXDECL class TX_CLDECL trpgr_Callback {
public:
virtual ~trpgr_Callback(void) { };
virtual void *Parse(trpgToken,trpgReadBuffer &) { return (void *)1; };
};
/* Paging Token
Stores callback info associated with a given token.
{group:Archive Reading}
*/
TX_EXDECL class TX_CLDECL trpgr_Token {
public:
trpgr_Token(void);
trpgr_Token(int,trpgr_Callback *,bool destroy=true);
~trpgr_Token(void);
void init(int,trpgr_Callback *,bool destroy=true);
int Token; // Constant token value
trpgr_Callback *cb; // Callback when we hit this token
bool destroy; // Should we call delete on the callback or not
void Destruct(void); // Not quite like delete
};
/* Parse class for paging data structures.
This executes callbacks
{group:Archive Reading}
*/
TX_EXDECL class TX_CLDECL trpgr_Parser {
public:
trpgr_Parser(void);
virtual ~trpgr_Parser(void);
bool isValid(void) const;
// Add and remove token callbacks
virtual void AddCallback(trpgToken,trpgr_Callback *,bool destroy = true);
virtual void AddCallback(trpgToken,trpgReadWriteable *);
virtual void RemoveCallback(trpgToken);
virtual void SetDefaultCallback(trpgr_Callback *,bool destroy = true);
// Parse a read buffer
virtual bool Parse(trpgReadBuffer &);
virtual bool TokenIsValid(trpgToken); // Check token validity
protected:
void *lastObject;
private:
// Note: Just how slow is a map<> anyway?
// This usage is self-contained and could be replaced with an array
#if defined(_WIN32)
typedef std::map<trpgToken,trpgr_Token> tok_map;
#else
typedef std::map<trpgToken,trpgr_Token,std::less<trpgToken> > tok_map;
#endif
tok_map tokenMap;
trpgr_Token defCb; // Call this when no others are called
};
/* Image Read Helper.
Used to help read Local and Tile Local textures into
memory (in OpenGL format). You're on your own for External
textures.
If you want to add additional ways to read textures, feel free
to subclass this object.
*/
TX_EXDECL class TX_CLDECL trpgrImageHelper {
public:
trpgrImageHelper(trpgEndian ness,char *dir,const trpgMatTable &,const trpgTexTable &);
virtual ~trpgrImageHelper(void);
/* Fetch the bytes for the given texture.
This is only valid for Local textures.
*/
virtual bool GetLocalGL(const trpgTexture *,char *data,int32 dataSize);
/* Fetch the bytes for the given mip level of a given texture.
This is only valid for Local textures.
*/
virtual bool GetMipLevelLocalGL(int miplevel, const trpgTexture *,char *data,int32 dataSize);
/* Do the lookups to figure out the correct material
and Template (or Local) texture for a given Local Material.
You'll need this for sizes (among other things).
This routine also calculates the total size, including mipmaps if they're there.
*/
virtual bool GetImageInfoForLocalMat(const trpgLocalMaterial *locMat,
const trpgMaterial **retMat,const trpgTexture **retTex,
int &totSize);
/* Fetch the bytes for the given Local Material (and
associated texture). This is for Tile Local and
Global textures.
Data is a pre-allocated buffer for the data and
dataSize is the size of that buffer.
*/
virtual bool GetImageForLocalMat(const trpgLocalMaterial *locMat,char *data,int dataSize);
/* Same as the one above, just fetch single mip levels
*/
virtual bool GetMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat,char *data,int dataSize);
/* Determine the full path of the image in the given
trpgTexture class.
Only useful for External images.
*/
virtual bool GetImagePath(const trpgTexture *,char *,int len);
protected:
char dir[1024];
trpgEndian ness;
const trpgMatTable *matTable;
const trpgTexTable *texTable;
trpgrAppFileCache *texCache;
};
/* Paging Archive (read version)
This just reads the first bits of the file (and the header)
and lets you parse from there.
{group:Archive Reading}
*/
TX_EXDECL class TX_CLDECL trpgr_Archive : public trpgCheckable {
public:
trpgr_Archive(void);
virtual ~trpgr_Archive(void);
virtual void SetDirectory(const char *);
virtual bool OpenFile(const char *); // Open File
virtual void CloseFile(void);
virtual bool ReadHeader(void); // Read header (materials, tile table. etc..)
virtual bool ReadTile(uint32 x, uint32 y, uint32 lod,trpgMemReadBuffer &);
// Get access to header info
virtual const trpgHeader *GetHeader(void) const;
virtual const trpgMatTable *GetMaterialTable(void) const;
virtual const trpgTexTable *GetTexTable(void) const;
virtual const trpgModelTable *GetModelTable(void) const;
virtual const trpgTileTable *GetTileTable(void) const;
virtual const trpgLightTable *GetLightTable(void) const;
virtual const trpgRangeTable *GetRangeTable(void) const;
// Utility routine to calculate the MBR of a given tile
virtual bool trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,
trpg3dPoint &ll,trpg3dPoint &ur) const;
trpgEndian GetEndian(void) const;
char* getDir(void){return dir;};
protected:
bool headerRead;
trpgEndian ness;
FILE *fp;
int fid;
// Header info
char dir[1024];
trpgHeader header;
trpgMatTable materialTable;
trpgTexTable texTable;
trpgModelTable modelTable;
trpgTileTable tileTable;
trpgLightTable lightTable;
trpgRangeTable rangeTable;
trpgrAppFileCache *tileCache;
};
class trpgSceneHelperPush;
class trpgSceneHelperPop;
class trpgSceneHelperDefault;
/* Scene Parser
This class assists in parsing a scene graph structure (tiles and models).
To use it, do an archive ReadTile and pass the resulting Read Buffer to this
parser.
{group:Archive Reading}
*/
TX_EXDECL class TX_CLDECL trpgSceneParser : public trpgr_Parser {
friend class trpgSceneHelperPush;
friend class trpgSceneHelperPop;
friend class trpgSceneHelperDefault;
public:
trpgSceneParser(void);
virtual ~trpgSceneParser(void);
protected:
// Start defining children for the given object
virtual bool StartChildren(void *) { return true;};
virtual bool EndChildren(void *) { return true;};
// List of objects whose children we're working on
std::vector<void *> parents;
};
#endif

View File

@@ -28,8 +28,8 @@
implement a trpgDiskReadBuffer as a subclass of trpgReadBuffer.
*/
#include "trpage_io.h"
#include "trpage_swap.h"
#include <osgTXP/trpage_io.h>
#include <osgTXP/trpage_swap.h>
/* **********************
Read buffer base class functions

View File

@@ -34,8 +34,8 @@
to read into a scene graph. You'll need to replace the helpers, primarily.
*/
#include "trpage_read.h"
#include "trpage_scene.h"
#include <osgTXP/trpage_read.h>
#include <osgTXP/trpage_scene.h>
/* ****************
MBR Calculation and handling

View File

@@ -1,238 +0,0 @@
/* ************************
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_scene_h_
// {secret}
#define _txpage_scene_h_
/* trpage_scene.h
Scene Graph definition.
This is a small scene graph we use for testing.
It's not intended to replace the scene graph you may already be using.
You do not need to translate from this scene graph structure to your own,
at run-time. Instead, use this file and trpage_scene.cpp as a guideline
for how to read TerraPage format into your own scene graph.
*/
#include "trpage_geom.h"
/*
{group:Demonstration Scene Graph}
*/
TX_EXDECL class TX_CLDECL trpgMBR {
public:
trpgMBR(void);
~trpgMBR(void) { };
bool isValid(void) const;
void Reset(void);
void AddPoint(const trpg3dPoint &);
void AddPoint(double,double,double);
void GetMBR(trpg3dPoint &ll,trpg3dPoint &ur) const;
trpg3dPoint GetLL(void) const;
trpg3dPoint GetUR(void) const;
void Union(const trpgMBR &);
// bool Overlap(const trpgMBR &) const;
bool Overlap(const trpg2dPoint &ll, const trpg2dPoint &ur) const;
// bool Within(const trpg3dPoint &) const
bool Within(const trpg2dPoint &) const;
protected:
inline bool inRange(double minv,double maxv,double val) const { return (val >= minv && val <= maxv); }
bool valid;
trpg3dPoint ll,ur;
};
// Read Node
// Simple Scenegraph node used for read testing
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadNode {
public:
virtual ~trpgReadNode(void) { };
virtual bool isGroupType(void) = 0;
virtual int GetType(void) { return type; }
virtual trpgMBR GetMBR(void) const { return trpgMBR(); }
protected:
int type;
};
// Read Group Base
// Base class for all group nodes
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadGroupBase : public trpgReadNode {
public:
virtual ~trpgReadGroupBase(void);
void AddChild(trpgReadNode *);
bool isGroupType(void) { return true; }
int GetNumChildren(void) { return children.size(); }
trpgReadNode *GetChild(int i) { return children[i]; }
trpgMBR GetMBR(void) const;
void unRefChild(int i);
void unRefChildren(void);
protected:
trpgMBR mbr;
void DeleteChildren(void);
std::vector<trpgReadNode *> children;
};
// Read Geometry
// The leaf for this scene graph
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadGeometry : public trpgReadNode {
public:
trpgReadGeometry(void) { type = TRPG_GEOMETRY; }
~trpgReadGeometry(void) { };
bool isGroupType(void) { return false; }
trpgGeometry *GetData(void) { return &data; }
trpgMBR GetMBR(void) const;
protected:
trpgMBR mbr;
trpgGeometry data;
};
// Read Tile Header
// One per tile. Info about what materials and models are used
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadTileHeader : public trpgReadNode {
public:
trpgReadTileHeader(void) { type = TRPGTILEHEADER; }
~trpgReadTileHeader(void) { };
bool isGroupType(void) { return false; }
trpgTileHeader *GetData(void) { return &data; }
trpgMBR GetMBR(void) const { trpgMBR mbr; return mbr; };
protected:
trpgTileHeader data;
};
// Read Group
// Simple group structure
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadGroup : public trpgReadGroupBase {
public:
trpgReadGroup(void) { type = TRPG_GROUP; }
~trpgReadGroup(void) { };
trpgGroup *GetData(void) { return &data; }
protected:
trpgGroup data;
};
// Read Attach
// Should be the top of a higher LOD tile
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadAttach : public trpgReadGroupBase {
public:
trpgReadAttach(void) { type = TRPG_ATTACH; }
~trpgReadAttach(void) { };
trpgAttach *GetData(void) { return &data; }
protected:
trpgAttach data;
};
// Read billboard
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadBillboard : public trpgReadGroupBase {
public:
trpgReadBillboard(void) { type = TRPG_BILLBOARD; }
~trpgReadBillboard(void) { };
trpgBillboard *GetData(void) { return &data; }
protected:
trpgBillboard data;
};
// Read LOD
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadLod : public trpgReadGroupBase {
public:
trpgReadLod(void) { type = TRPG_LOD; }
~trpgReadLod(void) { };
trpgLod *GetData(void) { return &data; }
protected:
trpgLod data;
};
// Read Layer
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadLayer : public trpgReadGroupBase {
public:
trpgReadLayer(void) { type = TRPG_LAYER; }
~trpgReadLayer(void) { };
trpgLayer *GetData(void) { return &data; }
protected:
trpgLayer data;
};
// Read Transform
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadTransform : public trpgReadGroupBase {
public:
trpgReadTransform(void) { type = TRPG_TRANSFORM; }
~trpgReadTransform(void) { };
trpgTransform *GetData(void) { return &data; }
protected:
trpgTransform data;
};
// Read Model Reference
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadModelRef : public trpgReadGroupBase {
public:
trpgReadModelRef(void) { type = TRPG_MODELREF; }
~trpgReadModelRef(void) { };
trpgModelRef *GetData(void) { return &data; }
protected:
trpgModelRef data;
};
/* Scene Graph Parser
Parses a read buffer and returns a full scenegraph.
You don't want to use this if you're reading into your own scenegraph.
Instead, you'll want to sublcass trpgSceneParser, which is a helper
class to keep track of pushes and pops and implement the same functionality
that trpgSceneGraphParser has for your own scene graph.
*/
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgSceneGraphParser : public trpgSceneParser {
public:
#if defined(_WIN32)
typedef std::map<int,trpgReadGroupBase *> GroupMap;
#else
typedef std::map<int,trpgReadGroupBase *,std::less<int> > GroupMap;
#endif
trpgSceneGraphParser(void);
virtual ~trpgSceneGraphParser(void) { };
// Call this instead of Parse()
// Deleting it is your responsibility
trpgReadNode *ParseScene(trpgReadBuffer &,GroupMap &);
trpgReadGroupBase *GetCurrTop(void); // Get the current parent object
trpgReadTileHeader *GetTileHeaderRef(void);
// For use by the helpers only
GroupMap *GetGroupMap(void);
protected:
bool StartChildren(void *);
bool EndChildren(void *);
trpgReadNode *currTop; // Current parent group
trpgReadNode *top; // Top of everything
GroupMap *gmap;
trpgReadTileHeader tileHead; // Tile header gets read into here
};
/* Test Archive
Utility function that loads and tests all tiles.
The only reason you'd want to call this is to test a TerraPage archive
you'd written.
*/
// {group:Demonstration Scene Graph}
TX_CPPDECL bool trpgTestArchive(trpgr_Archive &);
#endif

View File

@@ -20,7 +20,7 @@
Byte swapping utility functions.
*/
#include "trpage_swap.h"
#include <osgTXP/trpage_swap.h>
/*
** func: swap_two( in, out )

View File

@@ -1,68 +0,0 @@
/* ************************
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_swap_h_
#define trpage_swap_h_
/* trpage_swap.h
Byte swapping utility functions.
*/
#include "trpage_sys.h"
#include "trpage_io.h"
// Byte swap and return a short
// {group:Byte Ordering Utilities}
short trpg_byteswap_short( short number );
// Byte swap and return an integer
// {group:Byte Ordering Utilities}
int trpg_byteswap_int( int number );
// Byte swap and return a long
// {group:Byte Ordering Utilities}
long trpg_byteswap_long( long number );
// Byte swap and return a 64 bit long
// {group:Byte Ordering Utilities}
trpgllong trpg_byteswap_llong ( trpgllong number );
// Byte swap a float value into 4 characters. We do it this way to avoid floating point exceptions.
// {group:Byte Ordering Utilities}
void trpg_byteswap_float_to_4bytes( float number, char result[4] );
// Byte swap a double value into 8 characters. We do it this way to avoid floating point exceptions.
// {group:Byte Ordering Utilities}
void trpg_byteswap_double_to_8bytes( double number, char result[8] );
// Swap 4 bytes into a float and return it
// {group:Byte Ordering Utilities}
float trpg_byteswap_4bytes_to_float( const char result[4] );
// Swap 8 bytes into a double and return it
// {group:Byte Ordering Utilities}
double trpg_byteswap_8bytes_to_double( const char result[8] );
// Determine the current CPU's byte ordering
// {group:Byte Ordering Utilities}
trpgEndian trpg_cpu_byte_order(void);
// Swap two chars
// {group:Byte Ordering Utilities}
void trpg_swap_two ( const char *in, char *out );
// Swap 4 chars
// {group:Byte Ordering Utilities}
void trpg_swap_four ( const char *in, char *out );
// Swap 8 chars
// {group:Byte Ordering Utilities}
void trpg_swap_eight ( const char *in, char *out );
// Swap sixteen chars
// {group:Byte Ordering Utilities}
void trpg_swap_sixteen ( const char *in, char *out );
#endif

View File

@@ -1,107 +0,0 @@
/* ************************
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
************************
*/
/* trpage_sys.h
System specific declarations.
*/
#ifndef trpage_sys_h_
#define trpage_sys_h_
#ifndef PATHSEPARATOR
#ifdef macintosh
#define PATHSEPARATOR ":"
#else
#define PATHSEPARATOR "/"
#endif
#endif
#if defined(_WIN32)
/* *********************
System Specific Section.
This is currently set up for win32.
*********************
*/
#include <windows.h>
#include <stdio.h>
// Microsoft Developer warnings that annoy me
#pragma warning ( disable : 4251)
#pragma warning ( disable : 4275)
#pragma warning ( disable : 4786)
// Somewhat system independent file deletion macro
#define TRPGDELETEFILE(file) DeleteFile((file))
#ifndef int64
// 64 bit long value. Need this for really big files.
typedef __int64 int64;
#endif
#else // Unix
#include <stdio.h>
// Delete a file
#define TRPGDELETEFILE(file) remove((file))
#ifndef int64
typedef long long int64;
#endif
#endif
// Basic data types
#ifndef uint8
typedef unsigned char uint8;
#endif
#ifndef int32
typedef int int32;
#endif
#ifndef uint32
typedef unsigned int uint32;
#endif
#ifndef float32
typedef float float32;
#endif
#ifndef float64
typedef double float64;
#endif
// Note: replace this with your own STL implementation
// You can use the Microsoft provided one by deleting the first #include
#ifdef USEROGUE
#include <txRogueWave.h>
#endif
#include <vector>
#include <map>
#if defined(_WIN32) // PJM
// Had to take this out because of an iostream conflict
// Now referencing everything by std::
// using namespace std;
#endif
// We use long longs for addresses within a paging file
typedef int64 trpgllong;
// These are used to export classes from a DLL
// Definitely Windows specific
#include "trpage_ident.h"
#include "trdll.h"
#endif

View File

@@ -23,8 +23,8 @@
the front of an archive) or the Tile Header (at the beginning of each tile).
*/
#include "trpage_geom.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_read.h>
/* Write Tile Table
Keeps track of tiles written to disk.

View File

@@ -13,8 +13,15 @@
************************
*/
#ifdef __CURR_DLL
#undef __CURR_DLL
#endif
// {secret}
#define __CURR_DLL 7931
#include <osgTXP/trpage_util.h>
/* trpage_util.cpp
This source file implements various utility routines for paging archive
*/
/* The merge routine used to be in here.
However, merge isn't actually general enough to be part of the library.
Only portable code should be in the TerraPage API.
Instead, there's a Windows specific program that merges TerraPage archives in
the merge/ directory of this distribution.
*/

View File

@@ -28,10 +28,10 @@
again, subclass and override if you need to change them.
*/
#include "trpage_geom.h"
#include "trpage_write.h"
#include "trpage_compat.h"
#include "trpage_read.h"
#include <osgTXP/trpage_geom.h>
#include <osgTXP/trpage_write.h>
#include <osgTXP/trpage_compat.h>
#include <osgTXP/trpage_read.h>
// Constructor
trpgwArchive::trpgwArchive(trpgEndian inNess,TileMode inTileMode,int inVersion)

View File

@@ -1,301 +0,0 @@
/* ************************
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 "trpage_sys.h"
#include "trpage_io.h"
#include "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

View File

@@ -29,8 +29,8 @@
is required.
*/
#include "trpage_io.h"
#include "trpage_swap.h"
#include <osgTXP/trpage_io.h>
#include <osgTXP/trpage_swap.h>
/* **********************
Memory Write Buffer functions