Added Paging TerraPage loader and osgTXP library.
This commit is contained in:
18
src/Demos/osgtxp/Makefile
Normal file
18
src/Demos/osgtxp/Makefile
Normal 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
170
src/Demos/osgtxp/osgtxp.cpp
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "ReaderWriterTXP.h"
|
||||
#include "TrPageArchive.h"
|
||||
#include <osgTXP/TrPageArchive.h>
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/Object>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 ¢er)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
188
src/osgPlugins/txp/TrPageViewer.cpp
Normal file
188
src/osgPlugins/txp/TrPageViewer.cpp
Normal 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();
|
||||
}
|
||||
413
src/osgPlugins/txp/trPagePageManager.cpp
Normal file
413
src/osgPlugins/txp/trPagePageManager.cpp
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "trdll.h"
|
||||
#include <osgTXP/trdll.h>
|
||||
|
||||
TXDUMMY_DLL_MAIN
|
||||
|
||||
810
src/osgPlugins/txp/trpage_managers.cpp
Normal file
810
src/osgPlugins/txp/trpage_managers.cpp
Normal 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();
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
within a TerraPage archive.
|
||||
*/
|
||||
|
||||
#include "trpage_print.h"
|
||||
#include <osgTXP/trpage_print.h>
|
||||
|
||||
/* ******************************************
|
||||
Print Buffer implementation
|
||||
|
||||
@@ -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
|
||||
0
src/osgPlugins/txp/trpage_print_parse.cpp
Normal file
0
src/osgPlugins/txp/trpage_print_parse.cpp
Normal 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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -20,7 +20,7 @@
|
||||
Byte swapping utility functions.
|
||||
*/
|
||||
|
||||
#include "trpage_swap.h"
|
||||
#include <osgTXP/trpage_swap.h>
|
||||
|
||||
/*
|
||||
** func: swap_two( in, out )
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user