From Terrex and Andrew Sampsom and Don Tidrow and Robert Osfield,
email comments from Andew Sampson, "I've contacted Terrex, and obtained the 2.2 version of their trpage library. The library included a fork of OSG 0.9.8's txp plugin, modified to load 2.1+ txp DBs. I've done the work of incorporating the changes made to OSG's txp plugin since 0.9.8 into Terrex's fork. The forked version is now up-to-date with the changes made to OSG 0.9.9 and 1.0. Terrex made a lot of changes (especially differences in whitespace), so the diff between the forked version and OSG 1.0's txp plugin is yucky. I did my best, but keep in mind that this is the result of a 4-way merge (kinda... terrex-0.9.8, stock-0.9.8, stock-0.9.9, stock-1.0). I really want to see this forked version merged back into the main OSG branch. The new features offered by this version of the plugin (2.1+ support, variable LOD support, bug fixes) are worth the trouble." -- Don Tidrow then took this code and added his work. -- Robert Osfield then fixed all the warnings that abound in the trpage code base.
This commit is contained in:
parent
240fc9ebee
commit
261f4a3b1c
@ -3,9 +3,12 @@
|
||||
#include <osg/Node>
|
||||
#include <osg/Notify>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/BoundingSphere>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osg/io_utils>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "ReaderWriterTXP.h"
|
||||
#include "TXPNode.h"
|
||||
@ -16,6 +19,13 @@
|
||||
|
||||
#define ReaderWriterTXPERROR(s) osg::notify(osg::NOTICE) << "txp::ReaderWriterTXP::" << (s) << " error: "
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
char gbuf[2048];
|
||||
}
|
||||
|
||||
using namespace txp;
|
||||
|
||||
int ReaderWriterTXP::_archiveId = 0;
|
||||
@ -29,7 +39,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin
|
||||
if (strncmp(name.c_str(),"archive",7)==0)
|
||||
{
|
||||
std::string fileName = osgDB::findDataFile( file, options );
|
||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
if ( fileName.empty() )
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
osg::ref_ptr<TXPNode> txpNode = new TXPNode;
|
||||
txpNode->setArchiveName(fileName);
|
||||
@ -45,7 +56,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin
|
||||
{
|
||||
int id = _archiveId++;
|
||||
archive->setId(id);
|
||||
txpNode->setArchive(getArchive(id,osgDB::getFilePath(fileName)));
|
||||
// txpNode->setArchive(getArchive(id,osgDB::getFilePath(fileName)));
|
||||
getArchive(id,osgDB::getFilePath(fileName));
|
||||
}
|
||||
return txpNode.get();
|
||||
}
|
||||
@ -56,35 +68,92 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin
|
||||
}
|
||||
|
||||
// We load tileLOD_XxY_ID.txp
|
||||
if (strncmp(name.c_str(),"tile",4)==0)
|
||||
else if (strncmp(name.c_str(),"tile",4)==0)
|
||||
{
|
||||
int x,y,lod;
|
||||
unsigned int id;
|
||||
sscanf(name.c_str(),"tile%d_%dx%d_%d",&lod,&x,&y,&id);
|
||||
TXPArchive* archive = getArchive(id,osgDB::getFilePath(file));
|
||||
|
||||
// The way this is done a 'tile' should only be created for lod 0 only,
|
||||
// something is wrong if this is no the case
|
||||
if(lod != 0)
|
||||
{
|
||||
ReaderWriterTXPERROR("ReaderWriterTXP::local_readNode()") << "paged 'tile' should be at lod 0" << std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
trpgEndian endian = archive->GetEndian();
|
||||
archive->ReadSubArchive( 0, 0, endian);
|
||||
archive->ReadSubArchive( y, x, endian);
|
||||
|
||||
// std::cout << "Attempted " << x << " " << y << std::endl;
|
||||
|
||||
TXPArchive::TileInfo info;
|
||||
if (!archive->getTileInfo(x,y,lod,info))
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
|
||||
osg::ref_ptr<osg::Node> tileContent = getTileContent(info,x,y,lod,archive);
|
||||
std::vector<TXPArchive::TileLocationInfo> childrenLoc;
|
||||
osg::ref_ptr<osg::Node> tileContent = getTileContent(info,x,y,lod,archive, childrenLoc);
|
||||
|
||||
tileContent->setName("TileContent");
|
||||
|
||||
bool asChildren = false;
|
||||
std::string childrenInfoStr;
|
||||
|
||||
int numLods = archive->getNumLODs();
|
||||
|
||||
int majorVersion, minorVersion;
|
||||
archive->GetVersion(majorVersion, minorVersion);
|
||||
if(majorVersion ==2 && minorVersion >=1)
|
||||
{
|
||||
// Version 2.1 and over
|
||||
// The tile table only contains lod 0 and the children
|
||||
// info are stored in its parent. SO if we do not want
|
||||
// to be forced to reparse the parent we need to save that
|
||||
// info. For now we just add it to the node name
|
||||
|
||||
if(childrenLoc.size() > 0)
|
||||
{
|
||||
asChildren = true;
|
||||
createChildrenLocationString(childrenLoc, childrenInfoStr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lod < (numLods-1))
|
||||
asChildren = true;
|
||||
}
|
||||
|
||||
if (asChildren)
|
||||
{
|
||||
char pagedLODfile[1024];
|
||||
sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d.txp",
|
||||
archive->getDir(),
|
||||
lod,
|
||||
x,
|
||||
y,
|
||||
archive->getId()
|
||||
);
|
||||
sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d",
|
||||
archive->getDir(),
|
||||
lod,
|
||||
x,
|
||||
y,
|
||||
archive->getId());
|
||||
|
||||
strcat(pagedLODfile, childrenInfoStr.c_str());
|
||||
strcat(pagedLODfile, ".txp");
|
||||
|
||||
|
||||
// there are tile sets which do not maintain the z extents in
|
||||
// the tile table. This attempt to address the issue by using
|
||||
// the geometry bounding sphere. The downside is that this is
|
||||
// not coupled to the generation and may result in runtime cracks
|
||||
if (info.center.z() == 0)
|
||||
{
|
||||
osg::BoundingSphere bSphere = tileContent->getBound();
|
||||
|
||||
info.center.z() = bSphere.center().z();
|
||||
info.radius = bSphere.radius();
|
||||
}
|
||||
|
||||
|
||||
osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;
|
||||
// not use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.
|
||||
// note: use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.
|
||||
pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));
|
||||
pagedLOD->setFileName(1,pagedLODfile);
|
||||
pagedLOD->setRange(1,0,info.minRange);
|
||||
@ -110,111 +179,379 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin
|
||||
return tileContent.get();
|
||||
}
|
||||
|
||||
// We load subtilesLOD_XxY_ID.txp
|
||||
if (strncmp(name.c_str(),"sub",3)==0)
|
||||
|
||||
// For 2.0 and lower we load subtilesLOD_XxY_ID.txp
|
||||
// For 2.1 and over we load subtilesLOD_XxY_ID_NBCHILD_{X_Y_FID_FOFFSET_ZMIN_ZMAX_X_Y_ADDR ....}.txp
|
||||
else if (strncmp(name.c_str(),"sub",3)==0)
|
||||
{
|
||||
int x,y,lod;
|
||||
unsigned int id;
|
||||
sscanf(name.c_str(),"subtiles%d_%dx%d_%d",&lod,&x,&y,&id);
|
||||
TXPArchive* archive = getArchive(id,osgDB::getFilePath(file));
|
||||
|
||||
int majorVersion, minorVersion;
|
||||
archive->GetVersion(majorVersion, minorVersion);
|
||||
|
||||
std::vector<TXPArchive::TileLocationInfo> childrenLoc;
|
||||
|
||||
osg::ref_ptr<osg::Group> subtiles = new osg::Group;
|
||||
|
||||
int numLods = archive->getNumLODs();
|
||||
int sizeX, sizeY;
|
||||
archive->getLODSize(lod+1,sizeX,sizeY);
|
||||
|
||||
const trpgHeader* header = archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
header->GetTileOriginType(tileType);
|
||||
|
||||
TXPArchive::TileInfo parentInfo;
|
||||
archive->getTileInfo(x,y,lod,parentInfo);
|
||||
|
||||
for (int ix = 0; ix < 2; ix++)
|
||||
if(majorVersion == 2 && minorVersion >= 1)
|
||||
{
|
||||
for (int iy = 0; iy < 2; iy++)
|
||||
int nbChild;
|
||||
|
||||
sscanf(name.c_str(),"subtiles%d_%dx%d_%d_%d",&lod,&x,&y,&id, &nbChild);
|
||||
std::vector<TXPArchive::TileLocationInfo> locs;
|
||||
bool status = true;
|
||||
status = extractChildrenLocations(name, lod, locs, nbChild);
|
||||
if(majorVersion >= TRPG_NOMERGE_VERSION_MAJOR && minorVersion >=TRPG_NOMERGE_VERSION_MINOR && archive->GetHeader()->GetIsMaster())
|
||||
{
|
||||
for(int idx=0;idx<nbChild;idx++)
|
||||
{
|
||||
//figure out the block row/col
|
||||
int blockx,blocky;
|
||||
unsigned int denom = (1 << locs[idx].lod); // this should work up to lod 31
|
||||
blockx = locs[idx].x/denom;
|
||||
blocky = locs[idx].y/denom;
|
||||
locs[idx].addr.col = blockx;
|
||||
locs[idx].addr.row = blocky;
|
||||
}
|
||||
}
|
||||
|
||||
if(!status)
|
||||
{
|
||||
int tileX = x*2+ix;
|
||||
int tileY = y*2+iy;
|
||||
int tileLOD = lod+1;
|
||||
ReaderWriterTXPERROR("ReaderWriterTXP::local_readNode()") << "'subtile' filename children parsing failed " << std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
TXPArchive::TileInfo info;
|
||||
if (!archive->getTileInfo(tileX,tileY,tileLOD,info))
|
||||
continue;
|
||||
const trpgHeader* header = archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
header->GetTileOriginType(tileType);
|
||||
|
||||
osg::ref_ptr<osg::Node> tileContent = getTileContent(info,tileX,tileY,tileLOD,archive);
|
||||
TXPArchive::TileLocationInfo plInfo;
|
||||
plInfo.x = x;
|
||||
plInfo.y = y;
|
||||
plInfo.lod = lod;
|
||||
TXPArchive::TileInfo parentInfo;
|
||||
archive->getTileInfo(plInfo,parentInfo);
|
||||
|
||||
tileContent->setName("TileContent");
|
||||
for(int idx = 0; idx < nbChild; ++idx)
|
||||
{
|
||||
std::vector<TXPArchive::TileLocationInfo> childrenChildLoc;
|
||||
|
||||
TXPArchive::TileLocationInfo& loc = locs[idx];
|
||||
|
||||
TXPArchive::TileInfo info;
|
||||
if (!archive->getTileInfo(loc,info))
|
||||
continue;
|
||||
|
||||
if (tileLOD < (numLods-1))
|
||||
{
|
||||
char pagedLODfile[1024];
|
||||
sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d.txp",
|
||||
archive->getDir(),
|
||||
tileLOD,
|
||||
tileX,
|
||||
tileY,
|
||||
archive->getId()
|
||||
);
|
||||
osg::ref_ptr<osg::Node> tileContent = getTileContent(info, loc, archive, childrenChildLoc);
|
||||
|
||||
osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;
|
||||
tileContent->setName("TileContent");
|
||||
|
||||
// not use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.
|
||||
pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));
|
||||
pagedLOD->setFileName(1,pagedLODfile);
|
||||
pagedLOD->setRange(1,0,info.minRange);
|
||||
pagedLOD->setCenter(info.center);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setPriorityOffset(0,numLods-lod);
|
||||
pagedLOD->setPriorityScale(0,1.0f);
|
||||
pagedLOD->setNumChildrenThatCannotBeExpired(1);
|
||||
pagedLOD->setTileId(tileX,tileY,tileLOD);
|
||||
if(childrenChildLoc.size() > 0)
|
||||
{
|
||||
std::string childInfoStr;
|
||||
createChildrenLocationString(childrenChildLoc, childInfoStr);
|
||||
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
char pagedLODfile[1024];
|
||||
sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d%s.txp",
|
||||
archive->getDir(),
|
||||
loc.lod,
|
||||
loc.x,
|
||||
loc.y,
|
||||
archive->getId(),
|
||||
childInfoStr.c_str());
|
||||
|
||||
// there are tile sets which do not maintain the z extents in
|
||||
// the tile table. This attempt to address the issue by using
|
||||
// the geometry bounding sphere. The downside is that this is
|
||||
// not coupled to the generation and may result in runtime cracks
|
||||
if (info.center.z() == 0)
|
||||
{
|
||||
osg::Vec3d center(info.center - parentInfo.bbox._min);
|
||||
osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);
|
||||
sw[2] = 0.0;
|
||||
pagedLOD->setCenter(center - sw);
|
||||
osg::Matrix offset;
|
||||
offset.setTrans(sw);
|
||||
osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
|
||||
tform->addChild(pagedLOD.get());
|
||||
subtiles->addChild(tform);
|
||||
}
|
||||
else
|
||||
subtiles->addChild(pagedLOD.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
subtiles->setUserData(new TileIdentifier(tileX,tileY,tileLOD));
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
osg::Vec3d center(info.center - parentInfo.bbox._min);
|
||||
osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);
|
||||
sw[2] = 0.0;
|
||||
osg::Matrix offset;
|
||||
offset.setTrans(sw);
|
||||
osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
|
||||
tform->addChild(tileContent.get());
|
||||
subtiles->addChild(tform);
|
||||
}
|
||||
else
|
||||
subtiles->addChild(tileContent.get());
|
||||
}
|
||||
osg::BoundingSphere bSphere = tileContent->getBound();
|
||||
|
||||
info.center.z() = bSphere.center().z();
|
||||
info.radius = bSphere.radius();
|
||||
}
|
||||
|
||||
osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;
|
||||
// note: use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.
|
||||
pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));
|
||||
pagedLOD->setFileName(1,pagedLODfile);
|
||||
pagedLOD->setRange(1,0,info.minRange);
|
||||
pagedLOD->setCenter(info.center);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setPriorityOffset(0,numLods - loc.lod);
|
||||
pagedLOD->setPriorityScale(0,1.0f);
|
||||
pagedLOD->setNumChildrenThatCannotBeExpired(1);
|
||||
pagedLOD->setTileId(loc.x, loc.y, loc.lod);
|
||||
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
osg::Vec3d center(info.center - parentInfo.bbox._min);
|
||||
osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);
|
||||
sw[2] = 0.0;
|
||||
pagedLOD->setCenter(center - sw);
|
||||
osg::Matrix offset;
|
||||
offset.setTrans(sw);
|
||||
osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
|
||||
tform->addChild(pagedLOD.get());
|
||||
subtiles->addChild(tform);
|
||||
}
|
||||
else
|
||||
subtiles->addChild(pagedLOD.get());
|
||||
subtiles->setUserData(new TileIdentifier(loc.x, loc.y, loc.lod)); // is this really needed?
|
||||
}
|
||||
else
|
||||
{
|
||||
subtiles->setUserData(new TileIdentifier(loc.x, loc.y, loc.lod));
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
osg::Vec3d center(info.center - parentInfo.bbox._min);
|
||||
osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);
|
||||
sw[2] = 0.0;
|
||||
osg::Matrix offset;
|
||||
offset.setTrans(sw);
|
||||
osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
|
||||
tform->addChild(tileContent.get());
|
||||
subtiles->addChild(tform);
|
||||
}
|
||||
else
|
||||
subtiles->addChild(tileContent.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//osg::notify(osg::NOTICE) << "Subtiles for " << x << " " << y << " " << lod << " lodaded" << std::endl;
|
||||
else
|
||||
{
|
||||
|
||||
int sizeX, sizeY;
|
||||
archive->getLODSize(lod+1,sizeX,sizeY);
|
||||
|
||||
const trpgHeader* header = archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
header->GetTileOriginType(tileType);
|
||||
|
||||
TXPArchive::TileInfo parentInfo;
|
||||
archive->getTileInfo(x,y,lod,parentInfo);
|
||||
|
||||
for (int ix = 0; ix < 2; ix++)
|
||||
{
|
||||
for (int iy = 0; iy < 2; iy++)
|
||||
{
|
||||
int tileX = x*2+ix;
|
||||
int tileY = y*2+iy;
|
||||
int tileLOD = lod+1;
|
||||
|
||||
TXPArchive::TileInfo info;
|
||||
if (!archive->getTileInfo(tileX,tileY,tileLOD,info))
|
||||
continue;
|
||||
|
||||
osg::ref_ptr<osg::Node> tileContent = getTileContent(info,tileX,tileY,tileLOD,archive, childrenLoc);
|
||||
|
||||
tileContent->setName("TileContent");
|
||||
|
||||
if (tileLOD < (numLods-1))
|
||||
{
|
||||
char pagedLODfile[1024];
|
||||
sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d.txp",
|
||||
archive->getDir(),
|
||||
tileLOD,
|
||||
tileX,
|
||||
tileY,
|
||||
archive->getId());
|
||||
|
||||
// there are tile sets which do not maintain the z extents in
|
||||
// the tile table. This attempt to address the issue by using
|
||||
// the geometry bounding sphere. The downside is that this is
|
||||
// not coupled to the generation and may result in runtime cracks
|
||||
if (info.center.z() == 0)
|
||||
{
|
||||
osg::BoundingSphere bSphere = tileContent->getBound();
|
||||
|
||||
info.center.z() = bSphere.center().z();
|
||||
info.radius = bSphere.radius();
|
||||
}
|
||||
|
||||
osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;
|
||||
// note: use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.
|
||||
pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));
|
||||
pagedLOD->setFileName(1,pagedLODfile);
|
||||
pagedLOD->setRange(1,0,info.minRange);
|
||||
pagedLOD->setCenter(info.center);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setPriorityOffset(0,numLods-lod);
|
||||
pagedLOD->setPriorityScale(0,1.0f);
|
||||
pagedLOD->setNumChildrenThatCannotBeExpired(1);
|
||||
pagedLOD->setTileId(tileX,tileY,tileLOD);
|
||||
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
osg::Vec3d center(info.center - parentInfo.bbox._min);
|
||||
osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);
|
||||
sw[2] = 0.0;
|
||||
pagedLOD->setCenter(center - sw);
|
||||
osg::Matrix offset;
|
||||
offset.setTrans(sw);
|
||||
osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
|
||||
tform->addChild(pagedLOD.get());
|
||||
subtiles->addChild(tform);
|
||||
}
|
||||
else
|
||||
subtiles->addChild(pagedLOD.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
subtiles->setUserData(new TileIdentifier(tileX,tileY,tileLOD));
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
osg::Vec3d center(info.center - parentInfo.bbox._min);
|
||||
osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);
|
||||
sw[2] = 0.0;
|
||||
osg::Matrix offset;
|
||||
offset.setTrans(sw);
|
||||
osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
|
||||
tform->addChild(tileContent.get());
|
||||
subtiles->addChild(tform);
|
||||
}
|
||||
else
|
||||
subtiles->addChild(tileContent.get());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//osg::notify(osg::NOTICE) << "Subtiles for " << x << " " << y << " " << lod << " lodaded" << std::endl;
|
||||
return subtiles.get();
|
||||
}
|
||||
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
// If you change this then you have to change extractChildrenLocation()
|
||||
void ReaderWriterTXP::createChildrenLocationString(const std::vector<TXPArchive::TileLocationInfo>& locs, std::string& locString) const
|
||||
{
|
||||
std::stringstream theLoc;
|
||||
|
||||
if(locs.size() == 0)
|
||||
{
|
||||
theLoc << "_" << locs.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
theLoc << "_" << locs.size() << "_" << "{" ;
|
||||
|
||||
for(unsigned int idx = 0; idx < locs.size(); ++idx)
|
||||
{
|
||||
const TXPArchive::TileLocationInfo& loc = locs[idx];
|
||||
|
||||
theLoc << loc.x
|
||||
<< "_"
|
||||
<< loc.y
|
||||
<< "_"
|
||||
<< loc.addr.file
|
||||
<< "_"
|
||||
<< loc.addr.offset
|
||||
<< "_"
|
||||
<< loc.zmin
|
||||
<< "_"
|
||||
<< loc.zmax;
|
||||
if(idx != locs.size() -1)
|
||||
theLoc << "_";
|
||||
}
|
||||
}
|
||||
|
||||
theLoc << "}" << std::ends;
|
||||
|
||||
locString = theLoc.str();
|
||||
}
|
||||
bool ReaderWriterTXP::extractChildrenLocations(const std::string& name, int parentLod, std::vector<TXPArchive::TileLocationInfo>& locs, int nbChild) const
|
||||
{
|
||||
locs.clear();
|
||||
|
||||
if(nbChild == 0)
|
||||
return true;
|
||||
|
||||
locs.resize(nbChild);
|
||||
|
||||
// We look for '{', which should be the start of the list of {x,y,addr} children data
|
||||
// '}' should end the list.
|
||||
// We expect: X,Y,FID,FOFFSET,ZMIN,ZMAX
|
||||
std::string::size_type startOfList = name.find_last_of('{');
|
||||
if(startOfList == std::string::npos)
|
||||
return false;
|
||||
|
||||
std::string::size_type endOfList = name.find_last_of('}');
|
||||
if(endOfList == std::string::npos)
|
||||
return false;
|
||||
|
||||
// Extract the data
|
||||
strcpy(gbuf, name.substr(startOfList + 1, endOfList - startOfList - 1).c_str());
|
||||
char *token = strtok( gbuf, "_" );
|
||||
|
||||
int nbTokenRead = 0;
|
||||
for(int idx = 0; idx < nbChild; idx++)
|
||||
{
|
||||
// X
|
||||
if(!token)
|
||||
break;
|
||||
locs[idx].x = atoi(token);
|
||||
nbTokenRead++;
|
||||
|
||||
// Y
|
||||
token = strtok(0, "_");
|
||||
if(!token)
|
||||
break;
|
||||
locs[idx].y = atoi(token);
|
||||
nbTokenRead++;
|
||||
|
||||
// FID
|
||||
token = strtok(0, "_");
|
||||
if(!token)
|
||||
break;
|
||||
locs[idx].addr.file = atoi(token);
|
||||
nbTokenRead++;
|
||||
|
||||
// OFFSET
|
||||
token = strtok(0, "_");
|
||||
if(!token)
|
||||
break;
|
||||
locs[idx].addr.offset = atoi(token);
|
||||
nbTokenRead++;
|
||||
|
||||
// ZMIN
|
||||
token = strtok(0, "_");
|
||||
if(!token)
|
||||
break;
|
||||
locs[idx].zmin = (float)atof(token);
|
||||
nbTokenRead++;
|
||||
|
||||
// ZMAX
|
||||
token = strtok(0, "_");
|
||||
if(!token)
|
||||
break;
|
||||
locs[idx].zmax= (float)atof(token);
|
||||
nbTokenRead++;
|
||||
|
||||
locs[idx].lod = parentLod+1;
|
||||
|
||||
|
||||
|
||||
token = strtok(0, "_");
|
||||
}
|
||||
|
||||
if(nbTokenRead != nbChild*6)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
TXPArchive *ReaderWriterTXP::getArchive(int id, const std::string& dir)
|
||||
{
|
||||
TXPArchive* archive = NULL;
|
||||
@ -279,45 +616,50 @@ TXPArchive *ReaderWriterTXP::getArchive(int id, const std::string& dir)
|
||||
class SeamFinder: public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
SeamFinder(int x, int y, int lod, TXPArchive::TileInfo& info, TXPArchive *archive ):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_x(x), _y(y), _lod(lod), _info(info), _archive(archive)
|
||||
{};
|
||||
SeamFinder(int x, int y, int lod, const TXPArchive::TileInfo& info, TXPArchive *archive ):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_x(x), _y(y), _lod(lod), _info(info), _archive(archive)
|
||||
{}
|
||||
|
||||
virtual void apply(osg::Group& group)
|
||||
{
|
||||
for (unsigned int i = 0; i < group.getNumChildren(); i++)
|
||||
{
|
||||
osg::Node* child = group.getChild(i);
|
||||
osg::Node* seam = seamReplacement(child);
|
||||
if (child != seam)
|
||||
{
|
||||
group.replaceChild(child,seam);
|
||||
}
|
||||
else
|
||||
{
|
||||
child->accept(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
for (unsigned int i = 0; i < group.getNumChildren(); i++)
|
||||
{
|
||||
osg::Node* child = group.getChild(i);
|
||||
osg::Node* seam = seamReplacement(child);
|
||||
if (child != seam)
|
||||
{
|
||||
group.replaceChild(child,seam);
|
||||
}
|
||||
else
|
||||
{
|
||||
child->accept(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
osg::Node* seamReplacement(osg::Node* node);
|
||||
|
||||
int _x, _y, _lod;
|
||||
TXPArchive::TileInfo& _info;
|
||||
const TXPArchive::TileInfo& _info;
|
||||
TXPArchive *_archive;
|
||||
};
|
||||
|
||||
osg::Node* SeamFinder::seamReplacement(osg::Node* node)
|
||||
{
|
||||
osg::Group* group = node->asGroup();
|
||||
if (group == 0) return node;
|
||||
if ( group == 0 )
|
||||
return node;
|
||||
|
||||
std::vector<osg::Node*> nonSeamChildren;
|
||||
osg::LOD* hiRes = 0;
|
||||
osg::LOD* loRes = 0;
|
||||
|
||||
const trpgHeader* header = _archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
header->GetTileOriginType(tileType);
|
||||
|
||||
for (unsigned int i = 0; i < group->getNumChildren(); i++)
|
||||
{
|
||||
osg::LOD* lod = dynamic_cast<osg::LOD*>(group->getChild(i));
|
||||
@ -329,11 +671,32 @@ osg::Node* SeamFinder::seamReplacement(osg::Node* node)
|
||||
|
||||
bool nonSeamChild = true;
|
||||
|
||||
// looks like the problem is in here - likely due to seamLOD info
|
||||
// not being adjusted properly in tiled databases
|
||||
// seam center is outside the bounding box of the tile
|
||||
if (!_info.bbox.contains(lod->getCenter()))
|
||||
osg::Vec3 lodCenter = lod->getCenter();
|
||||
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
trpg2dPoint tileExtents;
|
||||
header->GetTileSize(0, tileExtents);
|
||||
osg::BoundingBox bbox;
|
||||
_archive->getExtents(bbox);
|
||||
osg::Vec3 offset(0.0, 0.0, 0.0);
|
||||
|
||||
int divider = (0x1 << _lod);
|
||||
// calculate which tile model is located in
|
||||
tileExtents.x /= divider;
|
||||
tileExtents.y /= divider;
|
||||
offset[0] = _x*tileExtents.x;// + tileExtents.x*0.5;
|
||||
offset[1] = _y*tileExtents.y;// + tileExtents.y*0.5;
|
||||
lodCenter += offset;
|
||||
}
|
||||
|
||||
if (!_info.bbox.contains(lodCenter))
|
||||
{
|
||||
// seams have center as the neighbour tile
|
||||
osg::Vec3 d = _info.center - lod->getCenter();
|
||||
osg::Vec3 d = _info.center - lodCenter;
|
||||
if (((fabs(d.x())-_info.size.x()) > 0.0001) && ((fabs(d.y())-_info.size.y()) > 0.0001))
|
||||
{
|
||||
nonSeamChildren.push_back(lod);
|
||||
@ -372,19 +735,43 @@ osg::Node* SeamFinder::seamReplacement(osg::Node* node)
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
int lod = _lod;
|
||||
osg::Vec3 delta = loRes->getCenter()-_info.center;
|
||||
osg::Vec3 lodCenter = loRes->getCenter();
|
||||
|
||||
if(tileType == trpgHeader::TileLocal)
|
||||
{
|
||||
trpg2dPoint tileExtents;
|
||||
header->GetTileSize(0, tileExtents);
|
||||
osg::BoundingBox bbox;
|
||||
_archive->getExtents(bbox);
|
||||
osg::Vec3 offset(0.0, 0.0, 0.0);
|
||||
|
||||
int divider = (0x1 << _lod);
|
||||
// calculate which tile model is located in
|
||||
tileExtents.x /= divider;
|
||||
tileExtents.y /= divider;
|
||||
offset[0] = _x*tileExtents.x;// + tileExtents.x*0.5;
|
||||
offset[1] = _y*tileExtents.y;// + tileExtents.y*0.5;
|
||||
lodCenter += offset;
|
||||
}
|
||||
|
||||
osg::Vec3 delta = lodCenter-_info.center;
|
||||
if (fabs(delta.x())>fabs(delta.y()))
|
||||
{
|
||||
if (delta.x()<0.0) --dx; // west
|
||||
else dx++; // east
|
||||
if ( delta.x() < 0.0 )
|
||||
--dx; // west
|
||||
else
|
||||
dx++; // east
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta.y()<0.0) --dy; // south
|
||||
else ++dy; // north
|
||||
if ( delta.y() < 0.0 )
|
||||
--dy; // south
|
||||
else
|
||||
++dy; // north
|
||||
}
|
||||
|
||||
TXPSeamLOD* seam = new TXPSeamLOD(_x, _y, lod, dx, dy);
|
||||
seam->setCenter(loRes->getCenter());
|
||||
seam->addChild(loRes->getChild(0)); // low res
|
||||
if (hiRes)
|
||||
{
|
||||
@ -411,28 +798,34 @@ osg::Node* SeamFinder::seamReplacement(osg::Node* node)
|
||||
return node;
|
||||
}
|
||||
|
||||
osg::Node* ReaderWriterTXP::getTileContent(TXPArchive::TileInfo &info, int x, int y, int lod, TXPArchive* archive)
|
||||
osg::Node* ReaderWriterTXP::getTileContent(const TXPArchive::TileInfo &info, int x, int y, int lod, TXPArchive* archive, std::vector<TXPArchive::TileLocationInfo>& childrenLoc)
|
||||
{
|
||||
if (archive == 0) return false;
|
||||
if ( archive == 0 )
|
||||
return false;
|
||||
|
||||
int numLods = archive->getNumLODs();
|
||||
int majorVersion, minorVersion;
|
||||
archive->GetVersion(majorVersion, minorVersion);
|
||||
|
||||
double realMinRange = info.minRange;
|
||||
double realMaxRange = info.maxRange;
|
||||
double usedMaxRange = osg::maximum(info.maxRange,1e7);
|
||||
double usedMaxRange = osg::maximum(info.maxRange,1e7);
|
||||
osg::Vec3 tileCenter;
|
||||
osg::Group* tileGroup = archive->getTileContent(x,y,lod,realMinRange,realMaxRange,usedMaxRange,tileCenter);
|
||||
osg::Group* tileGroup = archive->getTileContent(x,y,lod,realMinRange,realMaxRange,usedMaxRange,tileCenter, childrenLoc);
|
||||
|
||||
// if group has only one child, then simply use its child.
|
||||
#if 1
|
||||
while (tileGroup->getNumChildren()==1 && tileGroup->getChild(0)->asGroup())
|
||||
{
|
||||
tileGroup = tileGroup->getChild(0)->asGroup();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool doSeam = false;
|
||||
if(majorVersion == 2 && minorVersion >= 1)
|
||||
doSeam = (childrenLoc.size() > 0);
|
||||
else
|
||||
doSeam = (lod < (archive->getNumLODs() - 1));
|
||||
|
||||
// Handle seams
|
||||
if (lod < (numLods-1))
|
||||
if (doSeam)
|
||||
{
|
||||
SeamFinder sfv(x,y,lod,info,archive);
|
||||
tileGroup->accept(sfv);
|
||||
@ -441,5 +834,35 @@ osg::Node* ReaderWriterTXP::getTileContent(TXPArchive::TileInfo &info, int x, in
|
||||
return tileGroup;
|
||||
}
|
||||
|
||||
// this version only gets called if the TXP version is >= than 2.1
|
||||
osg::Node* ReaderWriterTXP::getTileContent(const TXPArchive::TileInfo &info, const TXPArchive::TileLocationInfo& loc, TXPArchive* archive, std::vector<TXPArchive::TileLocationInfo>& childrenLoc)
|
||||
{
|
||||
if ( archive == 0 )
|
||||
return false;
|
||||
|
||||
// int numLods = archive->getNumLODs();
|
||||
|
||||
double realMinRange = info.minRange;
|
||||
double realMaxRange = info.maxRange;
|
||||
double usedMaxRange = osg::maximum(info.maxRange,1e7);
|
||||
osg::Vec3 tileCenter;
|
||||
osg::Group* tileGroup = archive->getTileContent(loc,realMinRange,realMaxRange,usedMaxRange,tileCenter, childrenLoc);
|
||||
|
||||
// if group has only one child, then simply use its child.
|
||||
while (tileGroup->getNumChildren()==1 && tileGroup->getChild(0)->asGroup())
|
||||
{
|
||||
tileGroup = tileGroup->getChild(0)->asGroup();
|
||||
}
|
||||
|
||||
// Handle seams
|
||||
if (childrenLoc.size() > 0)
|
||||
{
|
||||
SeamFinder sfv(loc.x, loc.y, loc.lod, info, archive);
|
||||
tileGroup->accept(sfv);
|
||||
}
|
||||
|
||||
return tileGroup;
|
||||
}
|
||||
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterTXP> g_txpReaderWriterProxy;
|
||||
|
||||
|
@ -80,9 +80,13 @@ protected:
|
||||
|
||||
TXPArchive *getArchive(int id, const std::string&);
|
||||
|
||||
osg::Node* getTileContent(TXPArchive::TileInfo &info, int x, int y, int lod, TXPArchive* archive);
|
||||
|
||||
osg::Node* getTileContent(const TXPArchive::TileInfo &info, int x, int y, int lod, TXPArchive* archive, std::vector<TXPArchive::TileLocationInfo>& childrenLoc);
|
||||
osg::Node* getTileContent(const TXPArchive::TileInfo &info, const TXPArchive::TileLocationInfo& loc, TXPArchive* archive, std::vector<TXPArchive::TileLocationInfo>& childrenLoc);
|
||||
void createChildrenLocationString(const std::vector<TXPArchive::TileLocationInfo>& locs, std::string& locString) const;
|
||||
bool extractChildrenLocations(const std::string& name, int parentLod, std::vector<TXPArchive::TileLocationInfo>& locs, int nbChild) const;
|
||||
|
||||
mutable osgDB::ReentrantMutex _serializerMutex;
|
||||
|
||||
std::map< int,osg::ref_ptr<TXPArchive> > _archives;
|
||||
static int _archiveId;
|
||||
};
|
||||
|
@ -25,6 +25,10 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#if defined(linux)
|
||||
# include <unistd.h>
|
||||
# define _access access
|
||||
#endif
|
||||
|
||||
#include "TXPArchive.h"
|
||||
#include "TXPParser.h"
|
||||
@ -36,12 +40,36 @@ using namespace txp;
|
||||
|
||||
#define TXPArchiveERROR(s) osg::notify(osg::NOTICE) << "txp::TXPArchive::" << (s) << " error: "
|
||||
|
||||
|
||||
void TXPArchive::SetTexMap(int key,osg::ref_ptr<osg::Texture2D> ref)
|
||||
{
|
||||
_texmap[key] = ref;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> TXPArchive::GetTexMapEntry(int key)
|
||||
{
|
||||
return _texmap[key];
|
||||
}
|
||||
|
||||
void TXPArchive::SetStatesMap(int key,osg::ref_ptr<osg::StateSet> ref)
|
||||
{
|
||||
_statesMap[key] = ref;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::StateSet> TXPArchive::GetStatesMapEntry(int key)
|
||||
{
|
||||
return _statesMap[key];
|
||||
}
|
||||
|
||||
TXPArchive::TXPArchive():
|
||||
trpgr_Archive(),
|
||||
_id(-1),
|
||||
_numLODs(0),
|
||||
_swExtents(0.0,0.0),
|
||||
_neExtents(0.0,0.0)
|
||||
trpgr_Archive(),
|
||||
_id(-1),
|
||||
_numLODs(0),
|
||||
_swExtents(0.0,0.0),
|
||||
_neExtents(0.0,0.0),
|
||||
_majorVersion(-1),
|
||||
_minorVersion(-1),
|
||||
_isMaster(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -87,7 +115,7 @@ bool TXPArchive::openFile(const std::string& archiveName)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ReadHeader())
|
||||
if (!ReadHeader(false))
|
||||
{
|
||||
TXPArchiveERROR("openFile()") << "couldn't read header for archive: " << archiveName << std::endl;
|
||||
return false;
|
||||
@ -98,19 +126,19 @@ bool TXPArchive::openFile(const std::string& archiveName)
|
||||
{
|
||||
header->GetNumLods(_numLODs);
|
||||
header->GetExtents(_swExtents,_neExtents);
|
||||
header->GetVersion(_majorVersion, _minorVersion);
|
||||
_isMaster = header->GetIsMaster();
|
||||
}
|
||||
|
||||
int numTextures;
|
||||
texTable.GetNumTextures(numTextures);
|
||||
_textures.resize(numTextures);
|
||||
|
||||
int numModel;
|
||||
modelTable.GetNumModels(numModel);
|
||||
_models.resize(numModel);
|
||||
_models.clear();
|
||||
|
||||
int numMaterials;
|
||||
materialTable.GetNumMaterial(numMaterials);
|
||||
_gstates.resize(numMaterials);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -119,7 +147,9 @@ bool TXPArchive::loadMaterial(int ix)
|
||||
{
|
||||
int i = ix;
|
||||
|
||||
if (_gstates[ix].get()) return true;
|
||||
|
||||
if (GetStatesMapEntry(ix).get())
|
||||
return true;
|
||||
|
||||
osg::StateSet* osg_state_set = new osg::StateSet;
|
||||
|
||||
@ -145,17 +175,17 @@ bool TXPArchive::loadMaterial(int ix)
|
||||
trpgColor color;
|
||||
mat->GetAmbient(color);
|
||||
osg_material->setAmbient( osg::Material::FRONT_AND_BACK ,
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
mat->GetDiffuse(color);
|
||||
osg_material->setDiffuse(osg::Material::FRONT_AND_BACK ,
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
|
||||
mat->GetSpecular(color);
|
||||
osg_material->setSpecular(osg::Material::FRONT_AND_BACK ,
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
mat->GetEmission(color);
|
||||
osg_material->setEmission(osg::Material::FRONT_AND_BACK ,
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
osg::Vec4(color.red, color.green, color.blue, alpha));
|
||||
|
||||
float64 shinines;
|
||||
mat->GetShininess(shinines);
|
||||
@ -213,7 +243,7 @@ bool TXPArchive::loadMaterial(int ix)
|
||||
texEnv.GetWrap(wrap_s, wrap_t);
|
||||
|
||||
loadTexture(texId);
|
||||
osg::Texture2D* osg_texture = _textures[texId].get();
|
||||
osg::Texture2D* osg_texture = GetTexMapEntry(texId).get();
|
||||
if(osg_texture)
|
||||
{
|
||||
|
||||
@ -299,7 +329,7 @@ bool TXPArchive::loadMaterial(int ix)
|
||||
osg_state_set->setAttributeAndModes(cull_face, osg::StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
_gstates[i] = osg_state_set;
|
||||
SetStatesMap(i,osg_state_set);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -311,19 +341,29 @@ bool TXPArchive::loadMaterials()
|
||||
|
||||
bool TXPArchive::loadTexture(int i)
|
||||
{
|
||||
if (_textures[i].get()) return true;
|
||||
|
||||
trpgrImageHelper image_helper(this->GetEndian(),getDir(),materialTable,texTable);
|
||||
if (GetTexMapEntry(i).get())
|
||||
return true;
|
||||
|
||||
bool separateGeo = false;
|
||||
int majorVer,minorVer;
|
||||
GetVersion(majorVer,minorVer);
|
||||
if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer>=TRPG_NOMERGE_VERSION_MINOR))
|
||||
{
|
||||
separateGeo = true;
|
||||
}
|
||||
trpgrImageHelper image_helper(this->GetEndian(),getDir(),materialTable,texTable,separateGeo);
|
||||
|
||||
const trpgTexture *tex;
|
||||
tex = texTable.GetTextureRef(i);
|
||||
if (!tex) return false;
|
||||
if (!tex)
|
||||
return false;
|
||||
|
||||
trpgTexture::ImageMode mode;
|
||||
tex->GetImageMode(mode);
|
||||
if(mode == trpgTexture::External)
|
||||
{
|
||||
char texName[1024]; texName[0] = 0;
|
||||
char texName[ 1024 ];
|
||||
texName[ 0 ] = 0;
|
||||
tex->GetName(texName,1023);
|
||||
|
||||
// Create a texture by name.
|
||||
@ -356,30 +396,32 @@ bool TXPArchive::loadTexture(int i)
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN) << "TrPageArchive::LoadMaterials() error: "
|
||||
<< "couldn't open image: " << filename << std::endl;
|
||||
<< "couldn't open image: " << filename << std::endl;
|
||||
}
|
||||
_textures[i] = osg_texture;
|
||||
SetTexMap(i,osg_texture);
|
||||
}
|
||||
else if( mode == trpgTexture::Local )
|
||||
{
|
||||
_textures[i] = getLocalTexture(image_helper,tex);
|
||||
SetTexMap(i,getLocalTexture(image_helper,tex));
|
||||
}
|
||||
else if( mode == trpgTexture::Template )
|
||||
{
|
||||
_textures[i] = 0L; //GetTemplateTexture(image_helper,0, tex);
|
||||
SetTexMap(i,0L);
|
||||
}
|
||||
else
|
||||
{
|
||||
_textures[i] = 0;
|
||||
SetTexMap(i,0L);
|
||||
}
|
||||
|
||||
return (_textures[i].get() != 0);
|
||||
return (GetTexMapEntry(i).get() != 0);
|
||||
}
|
||||
|
||||
bool TXPArchive::loadModel(int ix)
|
||||
{
|
||||
trpgModel *mod = modelTable.GetModelRef(ix);
|
||||
int type;
|
||||
if(!mod)
|
||||
return false;
|
||||
mod->GetType(type);
|
||||
|
||||
// Only dealing with external models currently
|
||||
@ -389,24 +431,24 @@ bool TXPArchive::loadModel(int ix)
|
||||
mod->GetName(name,1023);
|
||||
|
||||
// Load the model. It's probably not TerraPage
|
||||
osg::Node *osg_model = osgDB::readNodeFile(name);
|
||||
if (!osg_model)
|
||||
osg::Node *osg_model = osgDB::readNodeFile( name );
|
||||
if ( !osg_model )
|
||||
{
|
||||
osg::notify(osg::WARN) << "TrPageArchive::LoadModels() error: "
|
||||
<< "failed to load model: "
|
||||
<< name << std::endl;
|
||||
<< "failed to load model: "
|
||||
<< name << std::endl;
|
||||
}
|
||||
// Do this even if it's NULL
|
||||
_models[ix] = osg_model;
|
||||
// Do this even if it's NULL
|
||||
_models[ ix ] = osg_model;
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
trpgMemReadBuffer buf(GetEndian());
|
||||
mod->Read(buf);
|
||||
Group *osg_model = parse->ParseScene(buf, m_gstates , m_models);
|
||||
m_models.push_back(osg_model);
|
||||
}
|
||||
else
|
||||
{
|
||||
trpgMemReadBuffer buf(GetEndian());
|
||||
mod->Read(buf);
|
||||
Group *osg_model = parse->ParseScene(buf, m_gstates , m_models);
|
||||
m_models.push_back(osg_model);
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
@ -417,14 +459,14 @@ bool TXPArchive::loadModels()
|
||||
|
||||
int numModel;
|
||||
modelTable.GetNumModels(numModel);
|
||||
_models.resize(numModel);
|
||||
|
||||
// Iterate over the models
|
||||
for (int i=0; i< numModel; i++)
|
||||
// use a pointer to the models map to bootstrap our map
|
||||
trpgModelTable::ModelMapType *mt = modelTable.GetModelMap();
|
||||
trpgModelTable::ModelMapType::iterator itr = mt->begin();
|
||||
for ( ; itr != mt->end( ); itr++)
|
||||
{
|
||||
loadModel(i);
|
||||
loadModel(itr->first);
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE) << "txp:: ... done." << std::endl;
|
||||
return true;
|
||||
}
|
||||
@ -433,11 +475,11 @@ bool TXPArchive::loadLightAttributes()
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "txp:: Loading light attributes ..." << std::endl;
|
||||
|
||||
int num;
|
||||
lightTable.GetNumLightAttrs(num);
|
||||
for ( int attr_num = 0; attr_num < num; attr_num++ )
|
||||
trpgLightTable::LightMapType *lm = lightTable.getLightMap();
|
||||
trpgLightTable::LightMapType::iterator itr = lm->begin();
|
||||
for ( ; itr != lm->end() ; itr++)
|
||||
{
|
||||
trpgLightAttr* ref = const_cast<trpgLightAttr*>(lightTable.GetLightAttrRef(attr_num));
|
||||
trpgLightAttr* ref = &itr->second;
|
||||
|
||||
osgSim::LightPointNode* osgLight = new osgSim::LightPointNode();
|
||||
|
||||
@ -523,11 +565,12 @@ bool TXPArchive::loadLightAttributes()
|
||||
lp._sector = back;
|
||||
osgLight->addLightPoint(lp);
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
osgLight->addLightPoint(lp);
|
||||
}
|
||||
|
||||
addLightAttribute(osgLight, stateSet, osg::Vec3(normal.x,normal.y,normal.z));
|
||||
addLightAttribute(osgLight, stateSet, osg::Vec3(normal.x,normal.y,normal.z),itr->first);
|
||||
}
|
||||
|
||||
osg::notify(osg::NOTICE) << "txp:: ... done." << std::endl;
|
||||
@ -537,15 +580,17 @@ bool TXPArchive::loadLightAttributes()
|
||||
void trim(std::string& str)
|
||||
{
|
||||
while (!str.empty() && isspace(str[str.length()-1]))
|
||||
str.erase(str.length()-1);
|
||||
str.erase(str.length()-1);
|
||||
while (!str.empty() && isspace(str[0]))
|
||||
str.erase(0,1);
|
||||
}
|
||||
bool TXPArchive::loadTextStyles()
|
||||
{
|
||||
const trpgTextStyleTable *textStyleTable = GetTextStyleTable();
|
||||
if (!textStyleTable) return false;
|
||||
if (textStyleTable->GetNumStyle() < 1) return true;
|
||||
if ( !textStyleTable )
|
||||
return false;
|
||||
if ( textStyleTable->GetNumStyle() < 1 )
|
||||
return true;
|
||||
|
||||
// try fontmap.txt
|
||||
std::map< std::string, std::string > fontmap;
|
||||
@ -556,78 +601,81 @@ bool TXPArchive::loadTextStyles()
|
||||
|
||||
if (fmapfile.is_open())
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "txp:: Font map file found: " << fmapfname << std::endl;
|
||||
std::string line;
|
||||
while (std::getline(fmapfile,line))
|
||||
{
|
||||
unsigned int ix = line.find_first_of('=');
|
||||
if (ix != std::string::npos)
|
||||
{
|
||||
std::string fontname = line.substr(0,ix);
|
||||
std::string fontfilename = line.substr(ix+1,line.length()-ix+1);
|
||||
osg::notify(osg::NOTICE) << "txp:: Font map file found: " << fmapfname << std::endl;
|
||||
std::string line;
|
||||
while (std::getline(fmapfile,line))
|
||||
{
|
||||
std::string::size_type ix = line.find_first_of('=');
|
||||
if (ix != std::string::npos)
|
||||
{
|
||||
std::string fontname = line.substr(0,ix);
|
||||
std::string fontfilename = line.substr(ix+1,line.length()-ix+1);
|
||||
|
||||
trim(fontname);
|
||||
trim(fontfilename);
|
||||
trim(fontname);
|
||||
trim(fontfilename);
|
||||
|
||||
fontmap[fontname] = fontfilename;
|
||||
fontmap[fontname] = fontfilename;
|
||||
|
||||
}
|
||||
}
|
||||
fmapfile.close();
|
||||
}
|
||||
}
|
||||
fmapfile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "txp:: No font map file found: " << fmapfname << std::endl;
|
||||
osg::notify(osg::NOTICE) << "txp:: All fonts defaulted to arial.ttf" << std::endl;
|
||||
osg::notify(osg::NOTICE) << "txp:: No font map file found: " << fmapfname << std::endl;
|
||||
osg::notify(osg::NOTICE) << "txp:: All fonts defaulted to arial.ttf" << std::endl;
|
||||
}
|
||||
|
||||
_fonts.resize(textStyleTable->GetNumStyle());
|
||||
_fcolors.resize(textStyleTable->GetNumStyle());
|
||||
for (int i = 0; i < textStyleTable->GetNumStyle(); i++)
|
||||
const trpgTextStyleTable::StyleMapType *smap = textStyleTable->getStyleMap();
|
||||
trpgTextStyleTable::StyleMapType::const_iterator itr = smap->begin();
|
||||
for ( ; itr != smap->end(); itr++)
|
||||
{
|
||||
const trpgTextStyle *textStyle = textStyleTable->GetStyleRef(i);
|
||||
if (!textStyle) continue;
|
||||
const trpgTextStyle *textStyle = &itr->second;
|
||||
if ( !textStyle )
|
||||
continue;
|
||||
|
||||
const std::string *fontName = textStyle->GetFont();
|
||||
if (!fontName) continue;
|
||||
const std::string *fontName = textStyle->GetFont();
|
||||
if ( !fontName )
|
||||
continue;
|
||||
|
||||
std::string fontfilename = fontmap[*fontName];
|
||||
if (!fontfilename.length()) fontfilename = "arial.ttf";
|
||||
osg::ref_ptr< osgText::Font > font = osgText::readFontFile(fontfilename);
|
||||
std::string fontfilename = fontmap[*fontName];
|
||||
if ( !fontfilename.length() )
|
||||
fontfilename = "arial.ttf";
|
||||
osg::ref_ptr< osgText::Font > font = osgText::readFontFile(fontfilename);
|
||||
|
||||
_fonts[i] = font;
|
||||
_fonts[itr->first] = font;
|
||||
|
||||
const trpgMatTable* matTable = GetMaterialTable();
|
||||
if (matTable)
|
||||
{
|
||||
int matId = textStyle->GetMaterial();
|
||||
const trpgMaterial* mat = matTable->GetMaterialRef(0,matId);
|
||||
if (mat)
|
||||
{
|
||||
trpgColor faceColor;
|
||||
mat->GetColor(faceColor);
|
||||
const trpgMatTable* matTable = GetMaterialTable();
|
||||
if (matTable)
|
||||
{
|
||||
int matId = textStyle->GetMaterial();
|
||||
const trpgMaterial* mat = matTable->GetMaterialRef(0,matId);
|
||||
if (mat)
|
||||
{
|
||||
trpgColor faceColor;
|
||||
mat->GetColor(faceColor);
|
||||
|
||||
float64 alpha;
|
||||
mat->GetAlpha(alpha);
|
||||
float64 alpha;
|
||||
mat->GetAlpha(alpha);
|
||||
|
||||
_fcolors[i] = osg::Vec4(faceColor.red, faceColor.green, faceColor.blue, alpha );
|
||||
}
|
||||
}
|
||||
_fcolors[itr->first] = osg::Vec4(faceColor.red, faceColor.green, faceColor.blue, alpha );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TXPArchive::addLightAttribute(osgSim::LightPointNode* lpn, osg::StateSet* fallback, const osg::Vec3& att)
|
||||
void TXPArchive::addLightAttribute(osgSim::LightPointNode* lpn, osg::StateSet* fallback, const osg::Vec3& att,int handle)
|
||||
{
|
||||
DeferredLightAttribute la;
|
||||
la.lightPoint = lpn;
|
||||
la.fallback = fallback;
|
||||
la.attitude = att;
|
||||
_lights.push_back(la);
|
||||
_lights[handle] = la;
|
||||
}
|
||||
|
||||
bool TXPArchive::getTileInfo(int x, int y, int lod, TileInfo& info)
|
||||
bool TXPArchive::getTileInfo(const TileLocationInfo& loc, TileInfo& info)
|
||||
{
|
||||
info.minRange = 0.0;
|
||||
info.maxRange = 0.0;
|
||||
@ -637,104 +685,150 @@ bool TXPArchive::getTileInfo(int x, int y, int lod, TileInfo& info)
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
header.GetLodRange(lod,info.maxRange);
|
||||
header.GetLodRange(lod+1,info.minRange);
|
||||
header.GetLodRange(loc.lod,info.maxRange);
|
||||
header.GetLodRange(loc.lod+1,info.minRange);
|
||||
header.GetLodRange(0,info.lod0Range);
|
||||
|
||||
trpg2dPoint sw,ne;
|
||||
header.GetExtents(sw,ne);
|
||||
|
||||
trpg2dPoint size;
|
||||
header.GetTileSize(lod,size);
|
||||
header.GetTileSize(loc.lod,size);
|
||||
|
||||
info.size.x() = size.x;
|
||||
info.size.y() = size.y;
|
||||
info.size.z() = 0.f;
|
||||
|
||||
trpgwAppAddress addr;
|
||||
float minz = 0.f;
|
||||
float maxz = 0.f;
|
||||
tileTable.GetTile(x,y,lod,addr,minz,maxz);
|
||||
|
||||
info.center.set(
|
||||
sw.x+(x*size.x)+(size.x/2.f),
|
||||
sw.y+(y*size.y)+(size.y/2.f),
|
||||
(minz+maxz)/2.f
|
||||
);
|
||||
sw.x+(loc.x*size.x)+(size.x/2.f),
|
||||
sw.y+(loc.y*size.y)+(size.y/2.f),
|
||||
(loc.zmin + loc.zmax)/2.f
|
||||
);
|
||||
info.bbox.set(
|
||||
osg::Vec3(
|
||||
info.center.x()-(size.x/2.f),
|
||||
info.center.y()-(size.y/2.f),
|
||||
minz
|
||||
),
|
||||
loc.zmin
|
||||
),
|
||||
osg::Vec3(
|
||||
info.center.x()+(size.x/2.f),
|
||||
info.center.y()+(size.y/2.f),
|
||||
maxz
|
||||
)
|
||||
);
|
||||
loc.zmax
|
||||
)
|
||||
);
|
||||
info.radius = osg::Vec3(size.x/2.f, size.y/2.f,0.f).length() * 1.3;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
class ModelVisitor : public osg::NodeVisitor
|
||||
bool TXPArchive::getTileInfo(int x, int y, int lod, TileInfo& info)
|
||||
{
|
||||
TXPArchive* _archive;
|
||||
int _x;
|
||||
int _y;
|
||||
int _lod;
|
||||
|
||||
public:
|
||||
ModelVisitor(TXPArchive* archive, int x, int y, int lod):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_archive(archive), _x(x), _y(y), _lod(lod)
|
||||
|
||||
if(_majorVersion == 2 && _minorVersion >=1)
|
||||
{
|
||||
// Version 2.1
|
||||
// Tile table contain only lod 0
|
||||
if(lod > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void apply(osg::MatrixTransform& xform)
|
||||
{
|
||||
const trpgHeader* header = _archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
header->GetTileOriginType(tileType);
|
||||
const osg::Referenced* ref = xform.getUserData();
|
||||
const TileIdentifier* tileID = dynamic_cast<const txp::TileIdentifier*>(ref);
|
||||
|
||||
if(!tileID) return; // bail early - this isn't a loaded model
|
||||
trpgwAppAddress addr;
|
||||
float minz = 0.f;
|
||||
float maxz = 0.f;
|
||||
tileTable.GetTile(x, y, lod, addr, minz, maxz);
|
||||
|
||||
if(tileType == trpgHeader::TileLocal && tileID->lod == 9999)
|
||||
{
|
||||
trpg2dPoint tileExtents;
|
||||
header->GetTileSize(0, tileExtents);
|
||||
osg::BoundingBox bbox;
|
||||
_archive->getExtents(bbox);
|
||||
osg::Vec3 offset(xform.getMatrix().getTrans());
|
||||
offset[0] -= bbox._min[0];
|
||||
offset[1] -= bbox._min[1];
|
||||
|
||||
trpg2dPoint offsetXY, tileID(_x,_y);
|
||||
int divider = (0x01 << _lod);
|
||||
// calculate which tile model is located in
|
||||
tileExtents.x /= divider;
|
||||
tileExtents.y /= divider;
|
||||
offset[0] -= tileID.x*tileExtents.x;
|
||||
offset[1] -= tileID.y*tileExtents.y;
|
||||
|
||||
osg::Matrix mat(xform.getMatrix());
|
||||
mat.setTrans(offset);
|
||||
xform.setMatrix(mat);
|
||||
}
|
||||
}
|
||||
};
|
||||
TileLocationInfo loc(x, y, lod, addr, minz, maxz);
|
||||
|
||||
return getTileInfo(loc, info);
|
||||
}
|
||||
|
||||
osg::Group* TXPArchive::getTileContent(
|
||||
int x, int y, int lod,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter)
|
||||
osg::Vec3& tileCenter,
|
||||
std::vector<TXPArchive::TileLocationInfo>& childInfoList)
|
||||
{
|
||||
if(_majorVersion == 2 && _minorVersion >= 1)
|
||||
{
|
||||
// Version 2.1
|
||||
// This call is valid only for lod = 0
|
||||
if(lod != 0)
|
||||
return new osg::Group;
|
||||
}
|
||||
|
||||
trpgwAppAddress addr;
|
||||
float minz = 0.f;
|
||||
float maxz = 0.f;
|
||||
tileTable.GetTile(x, y, lod, addr, minz, maxz);
|
||||
TileLocationInfo loc(x,y,lod,addr, minz,maxz);
|
||||
|
||||
return getTileContent(loc, realMinRange, realMaxRange, usedMaxRange, tileCenter, childInfoList);
|
||||
|
||||
}
|
||||
|
||||
class ModelVisitor : public osg::NodeVisitor
|
||||
{
|
||||
TXPArchive* _archive;
|
||||
TXPArchive::TileLocationInfo _tileInfo;
|
||||
// int _x;
|
||||
// int _y;
|
||||
// int _lod;
|
||||
|
||||
public:
|
||||
ModelVisitor(TXPArchive* archive, const TXPArchive::TileLocationInfo& loc):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_archive(archive), _tileInfo(loc)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void apply(osg::MatrixTransform& xform)
|
||||
{
|
||||
const trpgHeader* header = _archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
header->GetTileOriginType(tileType);
|
||||
const osg::Referenced* ref = xform.getUserData();
|
||||
const TileIdentifier* tileID = dynamic_cast<const txp::TileIdentifier*>(ref);
|
||||
|
||||
if(!tileID) return; // bail early - this isn't a loaded model
|
||||
|
||||
if(tileType == trpgHeader::TileLocal && tileID->lod == 9999)
|
||||
{
|
||||
trpg2dPoint tileExtents;
|
||||
header->GetTileSize(0, tileExtents);
|
||||
osg::BoundingBox bbox;
|
||||
_archive->getExtents(bbox);
|
||||
osg::Vec3 offset(xform.getMatrix().getTrans());
|
||||
offset[0] -= bbox._min[0];
|
||||
offset[1] -= bbox._min[1];
|
||||
|
||||
trpg2dPoint offsetXY, tileID(_tileInfo.x,_tileInfo.y);
|
||||
int divider = (0x01 << _tileInfo.lod);
|
||||
// calculate which tile model is located in
|
||||
tileExtents.x /= divider;
|
||||
tileExtents.y /= divider;
|
||||
offset[0] -= tileID.x*tileExtents.x;
|
||||
offset[1] -= tileID.y*tileExtents.y;
|
||||
|
||||
osg::Matrix mat(xform.getMatrix());
|
||||
mat.setTrans(offset);
|
||||
xform.setMatrix(mat);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
osg::Group* TXPArchive::getTileContent(
|
||||
const TileLocationInfo& loc,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter,
|
||||
std::vector<TileLocationInfo>& childInfoList)
|
||||
{
|
||||
|
||||
if (_parser.get() == 0)
|
||||
{
|
||||
_parser = new TXPParser();
|
||||
@ -742,28 +836,99 @@ osg::Group* TXPArchive::getTileContent(
|
||||
}
|
||||
|
||||
trpgMemReadBuffer buf(GetEndian());
|
||||
if (!ReadTile(x,y,lod,buf))
|
||||
bool readStatus;
|
||||
trpgTileTable::TileMode tileMode;
|
||||
tileTable.GetMode(tileMode);
|
||||
if(tileMode == trpgTileTable::External)
|
||||
readStatus = ReadExternalTile(loc.x, loc.y, loc.lod, buf);
|
||||
else
|
||||
readStatus = ReadTile(loc.addr, buf);
|
||||
|
||||
if(!readStatus)
|
||||
return new osg::Group;
|
||||
trpgTileHeader *tilehdr = _parser->getTileHeaderRef();
|
||||
|
||||
int majVersion,minVersion;
|
||||
GetVersion(majVersion,minVersion);
|
||||
// only compute block # if we are a master archive.
|
||||
if((majVersion >= TRPG_NOMERGE_VERSION_MAJOR) && (minVersion >= TRPG_NOMERGE_VERSION_MINOR) && (_isMaster))
|
||||
{
|
||||
return new osg::Group;
|
||||
if(tilehdr)
|
||||
{
|
||||
int x,y;
|
||||
unsigned int denom = (1 << loc.lod); // this should work up to lod 31
|
||||
x = loc.x/denom;
|
||||
y = loc.y/denom;
|
||||
tilehdr->SetBlockNo(y,x);
|
||||
}
|
||||
}
|
||||
|
||||
osg::Group *tileGroup = _parser->parseScene(buf,_gstates,_models,realMinRange,realMaxRange,usedMaxRange);
|
||||
osg::Group *tileGroup = _parser->parseScene(buf,_statesMap,_models,realMinRange,realMaxRange,usedMaxRange);
|
||||
tileCenter = _parser->getTileCenter();
|
||||
|
||||
int nbChild = _parser->GetNbChildrenRef();
|
||||
|
||||
childInfoList.clear();
|
||||
for(int idx = 0; idx < nbChild; idx++)
|
||||
{
|
||||
const trpgChildRef *childRef = _parser->GetChildRef(idx);
|
||||
|
||||
if(childRef)
|
||||
{
|
||||
TileLocationInfo loc;
|
||||
childRef->GetTileLoc(loc.x, loc.y, loc.lod);
|
||||
childRef->GetTileZValue(loc.zmin, loc.zmax);
|
||||
childRef->GetTileAddress(loc.addr);
|
||||
childInfoList.push_back(loc);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Fix up model MatrixTransform
|
||||
ModelVisitor mv(this, x, y, lod);
|
||||
ModelVisitor mv(this, loc);
|
||||
tileGroup->accept(mv);
|
||||
|
||||
// Prune
|
||||
unsigned int i = 0;
|
||||
for (i = 0; i < _gstates.size(); i++)
|
||||
OSGStatesMapType::iterator itr = _statesMap.begin();
|
||||
while( itr != _statesMap.end( ) )
|
||||
{
|
||||
if (_gstates[i].valid() && (_gstates[i]->referenceCount()==1)) _gstates[i] = 0;
|
||||
if(itr->second.valid() &&
|
||||
(itr->second->referenceCount()==1))
|
||||
{
|
||||
// unreference it.
|
||||
itr->second = NULL;
|
||||
|
||||
OSGStatesMapType::iterator toRemove = itr;
|
||||
++itr;
|
||||
|
||||
// remove it from the map
|
||||
_statesMap.erase( toRemove );
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < _textures.size(); i++)
|
||||
OSGTexMapType::iterator mitr = _texmap.begin();
|
||||
while( mitr != _texmap.end( ) )
|
||||
{
|
||||
if (_textures[i].valid() && (_textures[i]->referenceCount()==1)) _textures[i] = 0;
|
||||
if(mitr->second.valid() &&
|
||||
(mitr->second->referenceCount()==1))
|
||||
{
|
||||
// unreference it.
|
||||
mitr->second = NULL;
|
||||
|
||||
OSGTexMapType::iterator toRemove = mitr;
|
||||
++mitr;
|
||||
|
||||
// remove it from the map
|
||||
_texmap.erase( toRemove );
|
||||
}
|
||||
else
|
||||
{
|
||||
++mitr;
|
||||
}
|
||||
}
|
||||
|
||||
return tileGroup;
|
||||
|
@ -50,155 +50,210 @@
|
||||
|
||||
namespace txp
|
||||
{
|
||||
// this one handles different placement of light direction in osg and terrapage
|
||||
struct DeferredLightAttribute
|
||||
{
|
||||
// light point at (0,0,0) looking in (0,0,0) direction
|
||||
osg::ref_ptr<osgSim::LightPointNode> lightPoint;
|
||||
osg::ref_ptr<osg::StateSet> fallback;
|
||||
osg::Vec3 attitude;
|
||||
};
|
||||
|
||||
class TXPParser;
|
||||
class TXPArchive : public trpgr_Archive, public osg::Referenced
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
TXPArchive();
|
||||
|
||||
// Opens the archive file and reads the header
|
||||
bool openFile(const std::string& archiveName);
|
||||
|
||||
// Load the materials from the archve
|
||||
bool loadMaterials();
|
||||
bool loadMaterial(int ix);
|
||||
bool loadTexture(int i);
|
||||
|
||||
// Load the models from the archive
|
||||
bool loadModels();
|
||||
bool loadModel(int ix);
|
||||
|
||||
// Load the light attribs from the archive
|
||||
bool loadLightAttributes();
|
||||
|
||||
// Load the text styles from the archive
|
||||
bool loadTextStyles();
|
||||
inline std::vector< osg::ref_ptr<osgText::Font> >& getStyles() { return _fonts; }
|
||||
inline std::vector< osg::Vec4 >& getTextColors() { return _fcolors; }
|
||||
|
||||
// Add light attrib
|
||||
void addLightAttribute(osgSim::LightPointNode* lpn, osg::StateSet* fallback , const osg::Vec3& attitude);
|
||||
|
||||
int getNumLightAttributes() { return _lights.size(); }
|
||||
|
||||
// Get light attrib
|
||||
inline DeferredLightAttribute& getLightAttribute(unsigned int i)
|
||||
// this one handles different placement of light direction in osg and terrapage
|
||||
struct DeferredLightAttribute
|
||||
{
|
||||
return _lights[i];
|
||||
// light point at (0,0,0) looking in (0,0,0) direction
|
||||
osg::ref_ptr<osgSim::LightPointNode> lightPoint;
|
||||
osg::ref_ptr<osg::StateSet> fallback;
|
||||
osg::Vec3 attitude;
|
||||
};
|
||||
|
||||
// Gets some informations for a given tile
|
||||
struct TileInfo
|
||||
|
||||
class TXPParser;
|
||||
class TXPArchive : public trpgr_Archive, public osg::Referenced
|
||||
{
|
||||
osg::Vec3 center;
|
||||
double minRange;
|
||||
double maxRange;
|
||||
double lod0Range;
|
||||
float radius;
|
||||
osg::Vec3 size;
|
||||
osg::BoundingBox bbox;
|
||||
};
|
||||
bool getTileInfo(int x, int y, int lod, TileInfo& info);
|
||||
public:
|
||||
// Constructor
|
||||
TXPArchive();
|
||||
|
||||
// Set/Get the archive id
|
||||
inline void setId(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
inline const int& getId() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
// Opens the archive file and reads the header
|
||||
bool openFile(const std::string& archiveName);
|
||||
// Load the materials from the archve
|
||||
bool loadMaterials();
|
||||
bool loadMaterial(int ix);
|
||||
bool loadTexture(int i);
|
||||
|
||||
// Returns the number of LODs for this archive
|
||||
inline const int& getNumLODs() const
|
||||
{
|
||||
return _numLODs;
|
||||
}
|
||||
// Load the models from the archive
|
||||
bool loadModels();
|
||||
bool loadModel(int ix);
|
||||
|
||||
// Returns the extents of the archive
|
||||
// FIXME - Needs to change for databases that aren't flat-earth
|
||||
void getExtents(osg::BoundingBox& extents);
|
||||
// Load the light attribs from the archive
|
||||
bool loadLightAttributes();
|
||||
|
||||
// Load the text styles from the archive
|
||||
bool loadTextStyles();
|
||||
inline std::map<int, osg::ref_ptr<osgText::Font> >& getStyles()
|
||||
{
|
||||
return _fonts;
|
||||
}
|
||||
inline std::map<int, osg::Vec4 >& getTextColors()
|
||||
{
|
||||
return _fcolors;
|
||||
}
|
||||
|
||||
// Add light attrib
|
||||
void addLightAttribute(osgSim::LightPointNode* lpn, osg::StateSet* fallback , const osg::Vec3& attitude,int handle);
|
||||
|
||||
int getNumLightAttributes()
|
||||
{
|
||||
return _lights.size();
|
||||
}
|
||||
|
||||
// Get light attrib
|
||||
inline DeferredLightAttribute& getLightAttribute(unsigned int i)
|
||||
{
|
||||
return _lights[i];
|
||||
};
|
||||
|
||||
// Gets some informations for a given tile
|
||||
struct TileInfo
|
||||
{
|
||||
osg::Vec3 center;
|
||||
double minRange;
|
||||
double maxRange;
|
||||
double lod0Range;
|
||||
float radius;
|
||||
osg::Vec3 size;
|
||||
osg::BoundingBox bbox;
|
||||
};
|
||||
struct TileLocationInfo
|
||||
{
|
||||
TileLocationInfo() : x( -1 ), y( -1 ), lod( -1 )
|
||||
{}
|
||||
TileLocationInfo(int gx, int gy, int glod, const trpgwAppAddress& gaddr, float gzmin = 0.0f, float gzmax = 0.0f):
|
||||
x( gx ), y( gy ), lod( glod ), addr( gaddr ), zmin( gzmin ), zmax( gzmax )
|
||||
{}
|
||||
int x, y, lod;
|
||||
trpgwAppAddress addr;
|
||||
float zmin, zmax;
|
||||
};
|
||||
|
||||
bool getTileInfo(int x, int y, int lod, TileInfo& info);
|
||||
bool getTileInfo(const TileLocationInfo& loc, TileInfo& info);
|
||||
|
||||
// Set/Get the archive id
|
||||
inline void setId(int id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
inline const int& getId() const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
// Returns the number of LODs for this archive
|
||||
inline const int& getNumLODs() const
|
||||
{
|
||||
return _numLODs;
|
||||
}
|
||||
|
||||
// Returns the extents of the archive
|
||||
// FIXME - Needs to change for databases that aren't flat-earth
|
||||
void getExtents(osg::BoundingBox& extents);
|
||||
// {
|
||||
// extents.set(_swExtents.x,_swExtents.y,0.0f,_neExtents.x,_neExtents.y,0.0f);
|
||||
// }
|
||||
|
||||
// Returns the origin of the archive
|
||||
inline void getOrigin(double& x, double& y)
|
||||
{
|
||||
x=_swExtents.x;
|
||||
y=_swExtents.y;
|
||||
}
|
||||
// Returns the origin of the archive
|
||||
inline void getOrigin(double& x, double& y)
|
||||
{
|
||||
x=_swExtents.x;
|
||||
y=_swExtents.y;
|
||||
}
|
||||
|
||||
// Returns global texture
|
||||
inline osg::Texture2D* getGlobalTexture(int id)
|
||||
{
|
||||
return _textures[id].get();
|
||||
}
|
||||
// Returns global texture
|
||||
inline osg::Texture2D* getGlobalTexture(int id)
|
||||
{
|
||||
return GetTexMapEntry(id).get();
|
||||
}
|
||||
|
||||
// Returns scenegraph representing the Tile
|
||||
osg::Group* getTileContent(
|
||||
int x,
|
||||
int y,
|
||||
int lod,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter);
|
||||
// Returns scenegraph representing the Tile.
|
||||
// For version 2.1 and over this function can only be call
|
||||
// with lod = 0, since the archive tile table will contain
|
||||
// only tiles with lod = 0
|
||||
osg::Group* TXPArchive::getTileContent(
|
||||
int x,
|
||||
int y,
|
||||
int lod,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter,
|
||||
std::vector<TXPArchive::TileLocationInfo>& childInfoList);
|
||||
|
||||
// Get the number of tiles for given LOD
|
||||
bool getLODSize(int lod, int& x, int& y);
|
||||
// To be used for Version 2.1 with lod > 0
|
||||
osg::Group* TXPArchive::getTileContent(
|
||||
const TileLocationInfo& loc,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter,
|
||||
std::vector<TXPArchive::TileLocationInfo>& childInfoList);
|
||||
|
||||
// Get the number of tiles for given LOD
|
||||
bool getLODSize(int lod, int& x, int& y);
|
||||
|
||||
void GetVersion(int& majorVer, int& minorVer) const
|
||||
{
|
||||
majorVer = _majorVersion;
|
||||
minorVer = _minorVersion;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
// Destructor
|
||||
virtual ~TXPArchive();
|
||||
// Destructor
|
||||
virtual ~TXPArchive();
|
||||
|
||||
// Id of the archive
|
||||
int _id;
|
||||
// Id of the archive
|
||||
int _id;
|
||||
|
||||
// Number of the LODs
|
||||
int _numLODs;
|
||||
// Number of the LODs
|
||||
int _numLODs;
|
||||
|
||||
// Archive extents
|
||||
trpg2dPoint _swExtents;
|
||||
trpg2dPoint _neExtents;
|
||||
// Archive extents
|
||||
trpg2dPoint _swExtents;
|
||||
trpg2dPoint _neExtents;
|
||||
|
||||
// Terra Page Parser
|
||||
osg::ref_ptr<TXPParser> _parser;
|
||||
// Terra Page Parser
|
||||
osg::ref_ptr<TXPParser> _parser;
|
||||
|
||||
// Textures
|
||||
std::vector< osg::ref_ptr<osg::Texture2D> > _textures;
|
||||
|
||||
// States
|
||||
std::vector< osg::ref_ptr<osg::StateSet> > _gstates;
|
||||
|
||||
// Models
|
||||
std::vector< osg::ref_ptr<osg::Node> > _models;
|
||||
|
||||
// Light attributes vector
|
||||
std::vector<DeferredLightAttribute> _lights;
|
||||
// Textures
|
||||
typedef std::map<int,osg::ref_ptr<osg::Texture2D> > OSGTexMapType;
|
||||
OSGTexMapType _texmap;
|
||||
|
||||
// Text styles / Fonts
|
||||
std::vector< osg::ref_ptr<osgText::Font> > _fonts;
|
||||
void SetTexMap(int key,osg::ref_ptr<osg::Texture2D> ref);
|
||||
osg::ref_ptr<osg::Texture2D> GetTexMapEntry(int key);
|
||||
|
||||
// Text colors
|
||||
std::vector< osg::Vec4 > _fcolors;
|
||||
|
||||
//
|
||||
OpenThreads::Mutex _mutex;
|
||||
|
||||
};
|
||||
// States
|
||||
typedef std::map<int,osg::ref_ptr<osg::StateSet> > OSGStatesMapType;
|
||||
OSGStatesMapType _statesMap;
|
||||
|
||||
void SetStatesMap(int key,osg::ref_ptr<osg::StateSet> ref);
|
||||
osg::ref_ptr<osg::StateSet> GetStatesMapEntry(int key);
|
||||
|
||||
// Models
|
||||
typedef std::map<int,osg::ref_ptr<osg::Node> > OSGModelsMapType;
|
||||
OSGModelsMapType _models;
|
||||
|
||||
// Light attributes vector
|
||||
std::map<int, DeferredLightAttribute> _lights;
|
||||
|
||||
// Text styles / Fonts
|
||||
std::map<int, osg::ref_ptr<osgText::Font> > _fonts;
|
||||
|
||||
// Text colors
|
||||
std::map<int, osg::Vec4 > _fcolors;
|
||||
|
||||
//
|
||||
OpenThreads::Mutex _mutex;
|
||||
|
||||
// Cache those: TerraPage version
|
||||
int _majorVersion, _minorVersion;
|
||||
|
||||
bool _isMaster;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -49,7 +49,8 @@ bool TXPNode_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
class Dump2Osg : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
Dump2Osg(osgDB::Output &fw) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _fw(fw) {};
|
||||
Dump2Osg( osgDB::Output &fw ) : osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN ), _fw( fw )
|
||||
{}
|
||||
|
||||
virtual void apply(osg::Node& node)
|
||||
{
|
||||
@ -64,8 +65,10 @@ bool TXPNode_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
||||
{
|
||||
const txp::TXPNode &txpNode = static_cast<const txp::TXPNode&>(obj);
|
||||
|
||||
if (!txpNode.getOptions().empty()) fw.indent() << "databaseOptions \"" << txpNode.getOptions() << "\""<<std::endl;
|
||||
if (!txpNode.getArchiveName().empty()) fw.indent() << "databaseName \"" << txpNode.getArchiveName() << "\"" << std::endl;
|
||||
if ( !txpNode.getOptions().empty() )
|
||||
fw.indent() << "databaseOptions \"" << txpNode.getOptions() << "\"" << std::endl;
|
||||
if ( !txpNode.getArchiveName().empty() )
|
||||
fw.indent() << "databaseName \"" << txpNode.getArchiveName() << "\"" << std::endl;
|
||||
|
||||
osg::Group* grp = const_cast<osg::Group*>(txpNode.asGroup());
|
||||
|
||||
|
@ -20,6 +20,41 @@ using namespace osg;
|
||||
|
||||
|
||||
|
||||
class RetestCallback : public osg::NodeCallback
|
||||
{
|
||||
|
||||
public:
|
||||
RetestCallback()
|
||||
{
|
||||
timer = osg::Timer::instance(); // get static timer
|
||||
prevTime = 0; // should this be instantiated with current time?
|
||||
}
|
||||
|
||||
virtual void operator () ( osg::Node * node, osg::NodeVisitor * nv )
|
||||
{
|
||||
osg::Group *pLOD = (osg::Group *) node;
|
||||
osg::Group *n = NULL;
|
||||
if ((pLOD->getNumChildren() > 0) &&
|
||||
(n = (osg::Group *) pLOD->getChild(0)) &&
|
||||
(n->getNumChildren() == 0))
|
||||
{
|
||||
osg::Timer_t curTime = timer->tick();
|
||||
if ((prevTime + 2.0/timer->getSecondsPerTick() ) < curTime)
|
||||
{
|
||||
prevTime = curTime;
|
||||
pLOD->removeChildren( 0, pLOD->getNumChildren());
|
||||
}
|
||||
}
|
||||
|
||||
NodeCallback::traverse( node, nv );
|
||||
}
|
||||
|
||||
protected:
|
||||
const osg::Timer* timer;
|
||||
osg::Timer_t prevTime;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define TXPNodeERROR(s) osg::notify(osg::NOTICE) << "txp::TXPNode::" << (s) << " error: "
|
||||
|
||||
@ -29,6 +64,7 @@ _originX(0.0),
|
||||
_originY(0.0)
|
||||
{
|
||||
setNumChildrenRequiringUpdateTraversal(1);
|
||||
setCullingActive(false);
|
||||
}
|
||||
|
||||
TXPNode::TXPNode(const TXPNode& txpNode,const osg::CopyOp& copyop):
|
||||
@ -52,18 +88,18 @@ void TXPNode::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getVisitorType())
|
||||
{
|
||||
case osg::NodeVisitor::CULL_VISITOR:
|
||||
{
|
||||
case osg::NodeVisitor::CULL_VISITOR:
|
||||
{
|
||||
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
|
||||
if (cv)
|
||||
{
|
||||
//#define PRINT_TILEMAPP_TIMEINFO
|
||||
#ifdef PRINT_TILEMAPP_TIMEINFO
|
||||
//#define PRINT_TILEMAPP_TIMEINFO
|
||||
#ifdef PRINT_TILEMAPP_TIMEINFO
|
||||
const osg::Timer& timer = *osg::Timer::instance();
|
||||
osg::Timer_t start = timer.tick();
|
||||
std::cout<<"Doing visible tile search"<<std::endl;
|
||||
#endif // PRINT_TILEMAPP_TIMEINFO
|
||||
#endif // PRINT_TILEMAPP_TIMEINFO
|
||||
|
||||
osg::ref_ptr<TileMapper> tileMapper = new TileMapper;
|
||||
tileMapper->setLODScale(cv->getLODScale());
|
||||
@ -92,11 +128,11 @@ void TXPNode::traverse(osg::NodeVisitor& nv)
|
||||
|
||||
updateEye(nv);
|
||||
break;
|
||||
}
|
||||
case osg::NodeVisitor::UPDATE_VISITOR:
|
||||
}
|
||||
case osg::NodeVisitor::UPDATE_VISITOR:
|
||||
updateSceneGraph();
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Group::traverse(nv);
|
||||
@ -186,7 +222,10 @@ bool TXPNode::loadArchive()
|
||||
_archive->GetHeader()->GetLodSize(0,tileSize);
|
||||
|
||||
_pageManager = new TXPPageManager;
|
||||
_pageManager->Init(_archive.get());
|
||||
|
||||
// We are going to use _pageManager to manage lod 0 only, all other lod
|
||||
// are managed by this OSG plugin
|
||||
_pageManager->Init(_archive.get(), 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -227,7 +266,7 @@ void TXPNode::updateEye(osg::NodeVisitor& nv)
|
||||
tile->GetTileLoc(x,y,lod);
|
||||
if (lod==0)
|
||||
{
|
||||
osg::Node* node = addPagedLODTile(x,y,lod);
|
||||
osg::Node* node = addPagedLODTile(x,y);
|
||||
tile->SetLocalData(node);
|
||||
//osg::notify(osg::NOTICE) << "Tile load: " << x << " " << y << " " << lod << std::endl;
|
||||
}
|
||||
@ -237,8 +276,12 @@ void TXPNode::updateEye(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
osg::Node* TXPNode::addPagedLODTile(int x, int y, int lod)
|
||||
osg::Node* TXPNode::addPagedLODTile(int x, int y)
|
||||
{
|
||||
// For TerraPage 2.1 and over this method must only be use with lod = 0.
|
||||
// If you look at the code that calls it, it is effectively called only when
|
||||
// lod = 0. So all is OK
|
||||
int lod = 0;
|
||||
char pagedLODfile[1024];
|
||||
sprintf(pagedLODfile,"%s\\tile%d_%dx%d_%d.txp",_archive->getDir(),lod,x,y,_archive->getId());
|
||||
|
||||
@ -254,6 +297,7 @@ osg::Node* TXPNode::addPagedLODTile(int x, int y, int lod)
|
||||
pagedLOD->setCenter(info.center);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setNumChildrenThatCannotBeExpired(1);
|
||||
pagedLOD->setUpdateCallback(new RetestCallback);
|
||||
|
||||
const trpgHeader* header = _archive->GetHeader();
|
||||
trpgHeader::trpgTileType tileType;
|
||||
@ -274,9 +318,10 @@ osg::Node* TXPNode::addPagedLODTile(int x, int y, int lod)
|
||||
}
|
||||
else
|
||||
{
|
||||
_nodesToAdd.push_back(pagedLOD);
|
||||
return pagedLOD;
|
||||
}
|
||||
_nodesToAdd.push_back(pagedLOD);
|
||||
|
||||
return pagedLOD;
|
||||
}
|
||||
}
|
||||
|
||||
void TXPNode::updateSceneGraph()
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
namespace txp
|
||||
{
|
||||
|
||||
class TXPNode : public osg::Group
|
||||
{
|
||||
public:
|
||||
@ -68,32 +69,35 @@ public:
|
||||
|
||||
TXPArchive* getArchive();
|
||||
|
||||
void setArchive(TXPArchive* archive) { _archive = archive; }
|
||||
void setArchive( TXPArchive* archive )
|
||||
{
|
||||
_archive = archive;
|
||||
}
|
||||
|
||||
virtual osg::BoundingSphere computeBound() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~TXPNode();
|
||||
|
||||
|
||||
void updateEye(osg::NodeVisitor& nv);
|
||||
void updateSceneGraph();
|
||||
|
||||
osg::Node* addPagedLODTile(int x, int y, int lod);
|
||||
// Create a page lod for lod 0 with givin grid location (x,y)
|
||||
osg::Node* addPagedLODTile(int x, int y);
|
||||
|
||||
std::string _archiveName;
|
||||
std::string _options;
|
||||
std::string _archiveName;
|
||||
std::string _options;
|
||||
|
||||
osg::ref_ptr<TXPArchive> _archive;
|
||||
osg::ref_ptr<TXPPageManager> _pageManager;
|
||||
osg::ref_ptr<TXPArchive> _archive;
|
||||
osg::ref_ptr<TXPPageManager> _pageManager;
|
||||
|
||||
double _originX;
|
||||
double _originY;
|
||||
osg::BoundingBox _extents;
|
||||
double _originX;
|
||||
double _originY;
|
||||
osg::BoundingBox _extents;
|
||||
|
||||
std::vector<osg::Node*> _nodesToAdd;
|
||||
std::vector<osg::Node*> _nodesToRemove;
|
||||
std::vector<osg::Node*> _nodesToAdd;
|
||||
std::vector<osg::Node*> _nodesToRemove;
|
||||
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,8 @@ void TXPPagedLOD::traverse(osg::NodeVisitor& nv)
|
||||
bool needToLoadChild = false;
|
||||
|
||||
unsigned maxRangeSize = _rangeList.size();
|
||||
if (maxRangeSize!=0 && forceUseOfFirstChild) maxRangeSize=1;
|
||||
if (maxRangeSize!=0 && forceUseOfFirstChild)
|
||||
maxRangeSize=1;
|
||||
|
||||
for(unsigned int i=0;i<maxRangeSize;++i)
|
||||
{
|
||||
@ -50,9 +51,9 @@ void TXPPagedLOD::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
if (i<_children.size())
|
||||
{
|
||||
if (updateTimeStamp) _perRangeDataList[i]._timeStamp=timeStamp;
|
||||
if (updateTimeStamp)
|
||||
_perRangeDataList[i]._timeStamp=timeStamp;
|
||||
|
||||
//std::cout<<"PagedLOD::traverse() - Selecting child "<<i<<std::endl;
|
||||
_children[i]->accept(nv);
|
||||
lastChildTraversed = (int)i;
|
||||
}
|
||||
@ -72,7 +73,8 @@ void TXPPagedLOD::traverse(osg::NodeVisitor& nv)
|
||||
if (numChildren>0 && ((int)numChildren-1)!=lastChildTraversed)
|
||||
{
|
||||
//std::cout<<" to child "<<numChildren-1<<std::endl;
|
||||
if (updateTimeStamp) _perRangeDataList[numChildren-1]._timeStamp=timeStamp;
|
||||
if (updateTimeStamp)
|
||||
_perRangeDataList[numChildren-1]._timeStamp=timeStamp;
|
||||
_children[numChildren-1]->accept(nv);
|
||||
}
|
||||
|
||||
@ -110,7 +112,7 @@ osg::BoundingSphere TXPPagedLOD::computeBound() const
|
||||
|
||||
if (_centerMode==USER_DEFINED_CENTER && _radius>=0.0f)
|
||||
{
|
||||
float tempRadius = osg::maximum( _radius, result.radius() );
|
||||
float tempRadius = osg::maximum( _radius, result.radius() );
|
||||
result = osg::BoundingSphere(_userDefinedCenter,tempRadius);
|
||||
}
|
||||
return result;
|
||||
|
@ -1,3 +1,4 @@
|
||||
// -*-c++-*-
|
||||
/***************************************************************************
|
||||
* December 2003
|
||||
*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -79,11 +79,11 @@ class GeodeGroup : public osg::Group
|
||||
public:
|
||||
|
||||
GeodeGroup() : osg::Group(), _geode(NULL)
|
||||
{};
|
||||
{}
|
||||
|
||||
GeodeGroup(const GeodeGroup& gg,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Group(gg, copyop), _geode(gg._geode)
|
||||
{};
|
||||
{}
|
||||
|
||||
META_Node(txp, GeodeGroup);
|
||||
|
||||
@ -103,6 +103,7 @@ protected:
|
||||
|
||||
|
||||
class TXPArchive;
|
||||
class childRefRead;
|
||||
struct DeferredLightAttribute;
|
||||
|
||||
class TXPParser : public trpgSceneParser, public osg::Referenced
|
||||
@ -116,14 +117,17 @@ public:
|
||||
_archive = archive;
|
||||
}
|
||||
|
||||
// Gets the archive
|
||||
inline TXPArchive* getArchive() { return _archive; }
|
||||
// Gets the archive
|
||||
inline TXPArchive* getArchive()
|
||||
{
|
||||
return _archive;
|
||||
}
|
||||
|
||||
// Scene parser
|
||||
osg::Group *parseScene(
|
||||
trpgReadBuffer &buf,
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > &materials,
|
||||
std::vector<osg::ref_ptr<osg::Node> > &models,
|
||||
std::map<int,osg::ref_ptr<osg::StateSet> > &materials,
|
||||
std::map<int,osg::ref_ptr<osg::Node> > &models,
|
||||
double realMinRange, double realMaxRange, double usedMaxRange);
|
||||
|
||||
// Returns the current Top Group
|
||||
@ -139,13 +143,16 @@ public:
|
||||
}
|
||||
|
||||
// Return the current material list (passed in to ParseScene())
|
||||
inline std::vector<osg::ref_ptr<osg::StateSet> >* getMaterials()
|
||||
inline std::map<int,osg::ref_ptr<osg::StateSet> >* getMaterials()
|
||||
{
|
||||
return _materials;
|
||||
return _materialMap;
|
||||
}
|
||||
|
||||
// Ensure material is loaded
|
||||
inline void loadMaterial(int ix) { _archive->loadMaterial(ix); }
|
||||
// Ensure material is loaded
|
||||
inline void loadMaterial( int ix )
|
||||
{
|
||||
_archive->loadMaterial( ix );
|
||||
}
|
||||
|
||||
// New to TerraPage 2.0 - local materials
|
||||
std::vector<osg::ref_ptr<osg::StateSet> >* getLocalMaterials()
|
||||
@ -157,7 +164,7 @@ public:
|
||||
void loadLocalMaterials();
|
||||
|
||||
// Return the current model list
|
||||
std::vector<osg::ref_ptr<osg::Node> >* getModels()
|
||||
std::map<int,osg::ref_ptr<osg::Node> >* getModels()
|
||||
{
|
||||
return _models;
|
||||
}
|
||||
@ -260,9 +267,23 @@ public:
|
||||
}
|
||||
|
||||
// gets tile center, from the top lod node
|
||||
inline const osg::Vec3 getTileCenter() const { return _tileCenter; }
|
||||
inline const osg::Vec3 getTileCenter() const
|
||||
{
|
||||
return _tileCenter;
|
||||
}
|
||||
|
||||
inline void setCurrentNode(osg::Node* node) { _currentNode = node; }
|
||||
inline void setCurrentNode( osg::Node* node )
|
||||
{
|
||||
_currentNode = node;
|
||||
}
|
||||
|
||||
// After parsing this will return the number of trpgChildRef node found.
|
||||
unsigned int GetNbChildrenRef() const;
|
||||
|
||||
// This will return the trpgChildRef node pointer associated with the index.
|
||||
// Will return 0 if index is out of bound
|
||||
const trpgChildRef* GetChildRef(unsigned int idx) const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
@ -300,13 +321,15 @@ protected:
|
||||
void replaceTileLod(osg::Group*);
|
||||
|
||||
// Materials
|
||||
std::vector<osg::ref_ptr<osg::StateSet> >* _materials;
|
||||
typedef std::map<int,osg::ref_ptr<osg::StateSet> >* MaterialMapType;
|
||||
MaterialMapType _materialMap;
|
||||
|
||||
// Local materials
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > _localMaterials;
|
||||
|
||||
// Model list
|
||||
std::vector<osg::ref_ptr<osg::Node> >* _models;
|
||||
typedef std::map<int,osg::ref_ptr<osg::Node> > OSGModelsMapType;
|
||||
OSGModelsMapType* _models;
|
||||
|
||||
// Tile header
|
||||
trpgTileHeader _tileHeader;
|
||||
@ -342,6 +365,11 @@ protected:
|
||||
|
||||
// TEMP
|
||||
osg::Geode* createBoundingBox(int x,int y, int lod);
|
||||
|
||||
private:
|
||||
|
||||
childRefRead *_childRefCB;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -353,7 +381,7 @@ class geomRead : public trpgr_Callback
|
||||
public:
|
||||
|
||||
geomRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -365,7 +393,7 @@ class groupRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
groupRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -376,10 +404,48 @@ class attachRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
attachRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
class childRefRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
typedef std::vector<trpgChildRef> ChildRefList;
|
||||
|
||||
childRefRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{}
|
||||
void Reset();
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
|
||||
// After parsing this will return the number of trpgChildRef node found.
|
||||
unsigned int GetNbChildrenRef() const
|
||||
{
|
||||
return childRefList.size();
|
||||
}
|
||||
// This will return the trpgChildRef node associated with the index.
|
||||
// this will return 0 if idx is out of bound
|
||||
const trpgChildRef* GetChildRef(unsigned int idx) const
|
||||
{
|
||||
if(idx >= childRefList.size())
|
||||
return 0;
|
||||
else
|
||||
return &childRefList[idx];
|
||||
}
|
||||
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ChildRefList childRefList;
|
||||
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -387,7 +453,7 @@ class lodRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
lodRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -398,7 +464,7 @@ class tileHeaderRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
tileHeaderRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -410,7 +476,7 @@ class modelRefRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
modelRefRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -421,7 +487,7 @@ class billboardRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
billboardRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -432,7 +498,7 @@ class lightRead: public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
lightRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -443,7 +509,7 @@ class layerRead: public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
layerRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
@ -454,7 +520,7 @@ class labelRead: public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
labelRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
{}
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
|
@ -37,6 +37,7 @@ void TXPSeamLOD::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
|
||||
TileMapper* tileMapper = dynamic_cast<TileMapper*>(nv.getUserData());
|
||||
|
||||
if (tileMapper && !tileMapper->isTileNeighbourALowerLODLevel(_tid,_dx,_dy))
|
||||
{
|
||||
getChild(1)->accept(nv);
|
||||
|
@ -1,3 +1,4 @@
|
||||
// -*-c++-*-
|
||||
/***************************************************************************
|
||||
* December 2003
|
||||
*
|
||||
@ -58,12 +59,15 @@ public:
|
||||
|
||||
virtual void traverse(osg::NodeVisitor& nv);
|
||||
|
||||
void setCenter( const osg::Vec3& center ) { _center = center; }
|
||||
osg::Vec3 getCenter() { return _center; }
|
||||
protected:
|
||||
|
||||
TileIdentifier _tid;
|
||||
|
||||
int _dx;
|
||||
int _dy;
|
||||
osg::Vec3 _center;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,8 +21,10 @@ using namespace txp;
|
||||
|
||||
float TileMapper::getDistanceToEyePoint(const osg::Vec3& pos, bool withLODScale) const
|
||||
{
|
||||
if (withLODScale) return (pos-getEyeLocal()).length()*getLODScale();
|
||||
else return (pos-getEyeLocal()).length();
|
||||
if (withLODScale)
|
||||
return (pos-getEyeLocal()).length()*getLODScale();
|
||||
else
|
||||
return (pos-getEyeLocal()).length();
|
||||
}
|
||||
|
||||
inline TileMapper::value_type distance(const osg::Vec3& coord,const osg::Matrix& matrix)
|
||||
@ -30,7 +32,10 @@ inline TileMapper::value_type distance(const osg::Vec3& coord,const osg::Matrix&
|
||||
|
||||
//std::cout << "distance("<<coord<<", "<<matrix<<")"<<std::endl;
|
||||
|
||||
return -((TileMapper::value_type)coord[0]*(TileMapper::value_type)matrix(0,2)+(TileMapper::value_type)coord[1]*(TileMapper::value_type)matrix(1,2)+(TileMapper::value_type)coord[2]*(TileMapper::value_type)matrix(2,2)+matrix(3,2));
|
||||
return -((TileMapper::value_type)coord[0]*(TileMapper::value_type)matrix(0,2)+
|
||||
(TileMapper::value_type)coord[1]*(TileMapper::value_type)matrix(1,2)+
|
||||
(TileMapper::value_type)coord[2]*(TileMapper::value_type)matrix(2,2)+
|
||||
matrix(3,2));
|
||||
}
|
||||
|
||||
float TileMapper::getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODScale) const
|
||||
@ -38,8 +43,10 @@ float TileMapper::getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODScal
|
||||
const osg::Matrix& matrix = *_modelviewStack.back();
|
||||
float dist = distance(pos,matrix);
|
||||
|
||||
if (withLODScale) return dist*getLODScale();
|
||||
else return dist;
|
||||
if (withLODScale)
|
||||
return dist*getLODScale();
|
||||
else
|
||||
return dist;
|
||||
}
|
||||
|
||||
void TileMapper::apply(osg::Node& node)
|
||||
@ -50,7 +57,8 @@ void TileMapper::apply(osg::Node& node)
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCulled(node)) return;
|
||||
if (isCulled(node))
|
||||
return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
@ -69,11 +77,12 @@ void TileMapper::apply(osg::Group& node)
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCulled(node)) return;
|
||||
if (isCulled(node))
|
||||
return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
|
||||
TileIdentifier* tid = dynamic_cast<TileIdentifier*>(node.getUserData());
|
||||
|
||||
if (tid)
|
||||
@ -95,9 +104,9 @@ void TileMapper::apply(osg::Group& node)
|
||||
|
||||
#if 0
|
||||
std::cout<<"found Group="<<tid->lod
|
||||
<<" X="<<tid->x
|
||||
<<" Y="<<tid->y
|
||||
<<" ptr="<<&node<<std::endl;
|
||||
<<" X="<<tid->x
|
||||
<<" Y="<<tid->y
|
||||
<<" ptr="<<&node<<std::endl;
|
||||
|
||||
std::cout<<" inheritance list "<<_tileStack.size()<<std::endl;
|
||||
for(TileStack::iterator itr=_tileStack.begin();
|
||||
@ -144,7 +153,8 @@ void TileMapper::apply(osg::Geode&)
|
||||
|
||||
void TileMapper::apply(osg::PagedLOD& node)
|
||||
{
|
||||
if (isCulled(node)) return;
|
||||
if (isCulled(node))
|
||||
return;
|
||||
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
@ -171,9 +181,9 @@ void TileMapper::apply(osg::PagedLOD& node)
|
||||
|
||||
#if 0
|
||||
std::cout<<"found txpPagedLOD LOD="<<txpPagedLOD->_tileIdentifier.lod
|
||||
<<" X="<<txpPagedLOD->_tileIdentifier.x
|
||||
<<" Y="<<txpPagedLOD->_tileIdentifier.y
|
||||
<<" ptr="<<txpPagedLOD<<std::endl;
|
||||
<<" X="<<txpPagedLOD->_tileIdentifier.x
|
||||
<<" Y="<<txpPagedLOD->_tileIdentifier.y
|
||||
<<" ptr="<<txpPagedLOD<<std::endl;
|
||||
|
||||
std::cout<<" inheritance list "<<_tileStack.size()<<std::endl;
|
||||
for(TileStack::iterator itr=_tileStack.begin();
|
||||
@ -187,12 +197,11 @@ void TileMapper::apply(osg::PagedLOD& node)
|
||||
<<" ptr="<<itr->second<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
osg::StateSet* stateset = txpPagedLOD->getOrCreateStateSet();
|
||||
osg::Material* material = new osg::Material;
|
||||
material->setColorMode(osg::Material::OFF);
|
||||
stateset->setAttribute(material);
|
||||
|
||||
|
||||
switch(txpPagedLOD->_tileIdentifier.lod)
|
||||
{
|
||||
case(0): material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(1.0f,1.0f,1.0f,1.0f)); break;
|
||||
@ -201,14 +210,11 @@ void TileMapper::apply(osg::PagedLOD& node)
|
||||
case(3): material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,1.0f,1.0f)); break;
|
||||
case(4): material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(1.0f,0.0f,1.0f,1.0f)); break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
_tileStack.pop_back();
|
||||
}
|
||||
|
||||
|
||||
// pop the culling mode.
|
||||
popCurrentMask();
|
||||
}
|
||||
@ -360,20 +366,23 @@ void TileMapper::checkValidityOfAllVisibleTiles()
|
||||
_tileMap.insert(TileMap::value_type(aitr->back().first,*aitr));
|
||||
}
|
||||
|
||||
} while (!toRemoveList.empty());
|
||||
}
|
||||
while (!toRemoveList.empty());
|
||||
|
||||
|
||||
#if 0
|
||||
if (!_blackListedNodeSet.empty()) std::cout<<"********** We have blacked list "<<_blackListedNodeSet.size()<<std::endl;
|
||||
|
||||
if ( !_blackListedNodeSet.empty() )
|
||||
std::cout << "********** We have blacked list " << _blackListedNodeSet.size() << std::endl;
|
||||
|
||||
std::cout<<"TileMap contains "<<_tileMap.size()<<std::endl;
|
||||
for(TileMap::iterator itr=_tileMap.begin();
|
||||
itr!=_tileMap.end();
|
||||
++itr)
|
||||
{
|
||||
std::cout<<" tile="<<itr->first.lod
|
||||
<<" X="<<itr->first.x
|
||||
<<" Y="<<itr->first.y<<std::endl;
|
||||
std::cout<<" tile="<<itr->first.lod
|
||||
<<" X="<<itr->first.x
|
||||
<<" Y="<<itr->first.y<<std::endl;
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -388,7 +397,6 @@ bool TileMapper::isTileNeighbourALowerLODLevel(const TileIdentifier& tid, int dx
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// find the tiles parents.
|
||||
TileMap::const_iterator itr = _tileMap.find(tid);
|
||||
if (itr==_tileMap.end())
|
||||
@ -396,8 +404,8 @@ bool TileMapper::isTileNeighbourALowerLODLevel(const TileIdentifier& tid, int dx
|
||||
// not found tile in _tileMap, what should we do??
|
||||
// return true as a fallback right now.
|
||||
#if 0
|
||||
std::cout<<"TileMapper::isTileNeighbourALowerLODLevel() Not found tile in map,"<<std::endl;
|
||||
std::cout<<" LOD="<<tid.lod<<" X="<<tid.x<<" Y="<<tid.y<<std::endl;
|
||||
std::cout << "TileMapper::isTileNeighbourALowerLODLevel() Not found tile in map," << std::endl;
|
||||
std::cout << " LOD=" << tid.lod << " X=" << tid.x << " Y=" << tid.y << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@ -409,7 +417,7 @@ bool TileMapper::isTileNeighbourALowerLODLevel(const TileIdentifier& tid, int dx
|
||||
|
||||
if (!tile)
|
||||
{
|
||||
// no tile, so must assume taht neight is now at a lower level
|
||||
// no tile, so must assume that neighbor is now at a lower level
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -424,10 +432,10 @@ bool TileMapper::isTileNeighbourALowerLODLevel(const TileIdentifier& tid, int dx
|
||||
|
||||
const TileIdentifier& parent_tid = parent->first;
|
||||
|
||||
bool parentHasNorthNeighour = _tileMap.count(TileIdentifier(parent_tid.x,parent_tid.y+1,parent_tid.lod))!=0;
|
||||
bool parentHasEastNeighour = _tileMap.count(TileIdentifier(parent_tid.x+1,parent_tid.y,parent_tid.lod))!=0;
|
||||
bool parentHasSouthNeighour = _tileMap.count(TileIdentifier(parent_tid.x,parent_tid.y-1,parent_tid.lod))!=0;
|
||||
bool parentHasWestNeighour = _tileMap.count(TileIdentifier(parent_tid.x-1,parent_tid.y,parent_tid.lod))!=0;
|
||||
bool parentHasNorthNeighour = _tileMap.count(TileIdentifier(parent_tid.x, parent_tid.y+1,parent_tid.lod))!=0;
|
||||
bool parentHasEastNeighour = _tileMap.count(TileIdentifier(parent_tid.x+1,parent_tid.y, parent_tid.lod))!=0;
|
||||
bool parentHasSouthNeighour = _tileMap.count(TileIdentifier(parent_tid.x, parent_tid.y-1,parent_tid.lod))!=0;
|
||||
bool parentHasWestNeighour = _tileMap.count(TileIdentifier(parent_tid.x-1,parent_tid.y, parent_tid.lod))!=0;
|
||||
|
||||
|
||||
// identify whether the tile is a NE/SE/SW/NW tile relative to its parent.
|
||||
@ -438,14 +446,18 @@ bool TileMapper::isTileNeighbourALowerLODLevel(const TileIdentifier& tid, int dx
|
||||
if (delta.x()>=0.0f)
|
||||
{
|
||||
// NE
|
||||
if (dy==1) return parentHasNorthNeighour;
|
||||
else if (dx==1) return parentHasEastNeighour;
|
||||
if (dy==1)
|
||||
return parentHasNorthNeighour;
|
||||
else if (dx==1)
|
||||
return parentHasEastNeighour;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NW
|
||||
if (dy==1) return parentHasNorthNeighour;
|
||||
else if (dx==-1) return parentHasWestNeighour;
|
||||
if (dy==1)
|
||||
return parentHasNorthNeighour;
|
||||
else if (dx==-1)
|
||||
return parentHasWestNeighour;
|
||||
}
|
||||
}
|
||||
else // south side
|
||||
@ -453,14 +465,18 @@ bool TileMapper::isTileNeighbourALowerLODLevel(const TileIdentifier& tid, int dx
|
||||
if (delta.x()>=0.0f)
|
||||
{
|
||||
// SE
|
||||
if (dy==-1) return parentHasSouthNeighour;
|
||||
else if (dx==1) return parentHasEastNeighour;
|
||||
if (dy==-1)
|
||||
return parentHasSouthNeighour;
|
||||
else if (dx==1)
|
||||
return parentHasEastNeighour;
|
||||
}
|
||||
else
|
||||
{
|
||||
// SW
|
||||
if (dy==-1) return parentHasSouthNeighour;
|
||||
else if (dx==-1) return parentHasWestNeighour;
|
||||
if (dy==-1)
|
||||
return parentHasSouthNeighour;
|
||||
else if (dx==-1)
|
||||
return parentHasWestNeighour;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,18 +30,21 @@ struct TileIdentifier : public osg::Referenced
|
||||
TileIdentifier():
|
||||
x(-1),
|
||||
y(-1),
|
||||
lod(-1) {}
|
||||
lod(-1)
|
||||
{}
|
||||
|
||||
TileIdentifier(int ax, int ay, int alod):
|
||||
x(ax),
|
||||
y(ay),
|
||||
lod(alod) {}
|
||||
lod(alod)
|
||||
{}
|
||||
|
||||
TileIdentifier(const TileIdentifier& rhs):
|
||||
osg::Referenced(),
|
||||
x(rhs.x),
|
||||
y(rhs.y),
|
||||
lod(rhs.lod) {}
|
||||
lod(rhs.lod)
|
||||
{}
|
||||
|
||||
TileIdentifier& operator = (const TileIdentifier& rhs)
|
||||
{
|
||||
@ -91,7 +94,10 @@ public:
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) {}
|
||||
|
||||
|
||||
virtual osg::Vec3 getEyePoint() const { return getEyeLocal(); }
|
||||
virtual osg::Vec3 getEyePoint() const
|
||||
{
|
||||
return getEyeLocal();
|
||||
}
|
||||
virtual float getDistanceToEyePoint(const osg::Vec3& pos, bool withLODScale) const;
|
||||
virtual float getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODScale) const;
|
||||
|
||||
|
@ -14,9 +14,9 @@
|
||||
*/
|
||||
|
||||
/* trdll.h
|
||||
Windows Only
|
||||
Windows Only
|
||||
|
||||
This header file defines the declaration macros for DLLs.
|
||||
This header file defines the declaration macros for DLLs.
|
||||
*/
|
||||
|
||||
// Export/import declaration for classes and functions
|
||||
|
@ -14,8 +14,8 @@
|
||||
*/
|
||||
|
||||
/* trpage_basic.cpp
|
||||
Methods for checkable base class.
|
||||
*/
|
||||
Methods for checkable base class.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -23,20 +23,22 @@
|
||||
#include <trpage_io.h>
|
||||
|
||||
/* Checkable
|
||||
This is just a class that checks validity.
|
||||
Starts out invalid.
|
||||
*/
|
||||
This is just a class that checks validity.
|
||||
Starts out invalid.
|
||||
*/
|
||||
|
||||
trpgCheckable::trpgCheckable()
|
||||
{
|
||||
valid = false;
|
||||
valid = false;
|
||||
handle = -1;
|
||||
writeHandle = false;
|
||||
}
|
||||
trpgCheckable::~trpgCheckable()
|
||||
{
|
||||
valid = false;
|
||||
valid = false;
|
||||
}
|
||||
bool trpgCheckable::isValid() const
|
||||
{
|
||||
return valid;
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
@ -18,19 +18,19 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_compat.cpp
|
||||
This file and the accompanying trpage_compat.h 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.
|
||||
This file and the accompanying trpage_compat.h 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.
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <trpage_geom.h>
|
||||
#include <trpage_read.h>
|
||||
#include <trpage_compat.h>
|
||||
|
||||
/* Old short Material definition from 1.0.
|
||||
{secret}
|
||||
*/
|
||||
{secret}
|
||||
*/
|
||||
class trpgShortMaterial {
|
||||
public:
|
||||
// Full trpgMaterial definition this one is based on
|
||||
@ -56,64 +56,65 @@ bool trpgMatTable1_0::Read(trpgReadBuffer &buf)
|
||||
std::vector<trpgMaterial> baseMats;
|
||||
|
||||
try {
|
||||
buf.Get(numTable);
|
||||
buf.Get(numMat);
|
||||
if (numTable <= 0 || numMat < 0) throw 1;
|
||||
buf.Get(numTable);
|
||||
buf.Get(numMat);
|
||||
if (numTable <= 0 || numMat < 0) throw 1;
|
||||
|
||||
// Short material tables are always full size
|
||||
shortTable.resize(numTable*numMat);
|
||||
// Short material tables are always full size
|
||||
shortTable.resize(numTable*numMat);
|
||||
|
||||
// Look for short material table
|
||||
buf.GetToken(matTok,len);
|
||||
if (matTok == TRPGSHORTMATTABLE) {
|
||||
int32 numTex,texId;
|
||||
buf.PushLimit(len);
|
||||
// Look for short material table
|
||||
buf.GetToken(matTok,len);
|
||||
if (matTok == TRPGSHORTMATTABLE) {
|
||||
int32 numTex,texId;
|
||||
buf.PushLimit(len);
|
||||
for (i=0;i<(unsigned int)numTable;i++)
|
||||
for (j=0;j<(unsigned int)numMat;j++) {
|
||||
trpgShortMaterial &smat = shortTable[i*numMat+j];
|
||||
buf.Get(smat.baseMat);
|
||||
buf.Get(numTex);
|
||||
trpgShortMaterial &smat = shortTable[i*numMat+j];
|
||||
buf.Get(smat.baseMat);
|
||||
buf.Get(numTex);
|
||||
for (k=0;k<(unsigned int)numTex;k++) {
|
||||
buf.Get(texId);
|
||||
smat.texids.push_back(texId);
|
||||
}
|
||||
}
|
||||
buf.PopLimit();
|
||||
buf.Get(texId);
|
||||
smat.texids.push_back(texId);
|
||||
}
|
||||
}
|
||||
buf.PopLimit();
|
||||
|
||||
// Now read the base materials
|
||||
int32 numBaseMat;
|
||||
buf.Get(numBaseMat);
|
||||
if (numBaseMat < 0) throw 1;
|
||||
baseMats.resize(numBaseMat);
|
||||
// Now read the base materials
|
||||
int32 numBaseMat;
|
||||
buf.Get(numBaseMat);
|
||||
if (numBaseMat < 0) throw 1;
|
||||
baseMats.resize(numBaseMat);
|
||||
for (i=0;i<(unsigned int)numBaseMat;i++) {
|
||||
buf.GetToken(matTok,len);
|
||||
if (matTok != TRPGMATERIAL) throw 1;
|
||||
buf.PushLimit(len);
|
||||
mat.Reset();
|
||||
status = mat.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
baseMats[i] = mat;
|
||||
}
|
||||
}
|
||||
buf.GetToken(matTok,len);
|
||||
if (matTok != TRPGMATERIAL) throw 1;
|
||||
buf.PushLimit(len);
|
||||
mat.Reset();
|
||||
status = mat.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
baseMats[i] = mat;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now convert to the new style material table
|
||||
for (i=0;i<shortTable.size();i++) {
|
||||
trpgShortMaterial &shortMat = shortTable[i];
|
||||
trpgMaterial &baseMat = baseMats[shortMat.baseMat];
|
||||
matTables.push_back(baseMat);
|
||||
trpgMaterial &newMat = matTables[matTables.size()-1];
|
||||
newMat.SetNumTexture(shortMat.texids.size());
|
||||
for (j=0;j<shortMat.texids.size();j++) {
|
||||
int texId;
|
||||
trpgTextureEnv texEnv;
|
||||
baseMat.GetTexture(j,texId,texEnv);
|
||||
newMat.SetTexture(j,shortMat.texids[j],texEnv);
|
||||
}
|
||||
trpgShortMaterial &shortMat = shortTable[i];
|
||||
trpgMaterial &baseMat = baseMats[shortMat.baseMat];
|
||||
AddMaterial(baseMat,false);
|
||||
|
||||
trpgMaterial newMat = baseMat;
|
||||
newMat.SetNumTexture(shortMat.texids.size());
|
||||
for (j=0;j<shortMat.texids.size();j++) {
|
||||
int texId;
|
||||
trpgTextureEnv texEnv;
|
||||
baseMat.GetTexture(j,texId,texEnv);
|
||||
newMat.SetTexture(j,shortMat.texids[j],texEnv);
|
||||
}
|
||||
}
|
||||
|
||||
valid = true;
|
||||
@ -123,28 +124,31 @@ bool trpgMatTable1_0::Read(trpgReadBuffer &buf)
|
||||
bool trpgMatTable1_0::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Create one short material for every material
|
||||
std::vector<trpgShortMaterial> shortMats;
|
||||
shortMats.resize(numTable*numMat);
|
||||
|
||||
// Iterate over the existing materials
|
||||
int i;
|
||||
for (i=0;i<numTable*numMat;i++) {
|
||||
trpgMaterial &mat = matTables[i];
|
||||
// Fill in the short material
|
||||
trpgShortMaterial &sMat = shortMats[i];
|
||||
sMat.baseMat = 0;
|
||||
int numTex;
|
||||
mat.GetNumTexture(numTex);
|
||||
for (int j=0;j<numTex;j++) {
|
||||
int texId;
|
||||
trpgTextureEnv texEnv;
|
||||
mat.GetTexture(j,texId,texEnv);
|
||||
sMat.texids.push_back(texId);
|
||||
sMat.baseMat = i;
|
||||
}
|
||||
int i=0;
|
||||
|
||||
MaterialMapType::iterator itr = materialMap.begin();
|
||||
for ( ; itr != materialMap.end( ); itr++) {
|
||||
//for (i=0;i<numTable*numMat;i++) {
|
||||
trpgMaterial &mat = itr->second; //matTables[i];
|
||||
// Fill in the short material
|
||||
trpgShortMaterial &sMat = shortMats[i];
|
||||
sMat.baseMat = 0;
|
||||
int numTex;
|
||||
mat.GetNumTexture(numTex);
|
||||
for (int j=0;j<numTex;j++) {
|
||||
int texId;
|
||||
trpgTextureEnv texEnv;
|
||||
mat.GetTexture(j,texId,texEnv);
|
||||
sMat.texids.push_back(texId);
|
||||
sMat.baseMat = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// Write the 1.0 material table
|
||||
@ -154,23 +158,27 @@ bool trpgMatTable1_0::Write(trpgWriteBuffer &buf)
|
||||
|
||||
// Write the short materials
|
||||
buf.Begin(TRPGSHORTMATTABLE);
|
||||
for (i=0;i<(int)shortMats.size();i++) {
|
||||
trpgShortMaterial &sMat = shortMats[i];
|
||||
buf.Add(sMat.baseMat);
|
||||
buf.Add((int)(sMat.texids.size()));
|
||||
unsigned int j;
|
||||
for (j=0;j<sMat.texids.size();j++)
|
||||
buf.Add(sMat.texids[j]);
|
||||
for (i=0;i<static_cast<int>(shortMats.size());i++) {
|
||||
trpgShortMaterial &sMat = shortMats[i];
|
||||
buf.Add(sMat.baseMat);
|
||||
buf.Add((int)(sMat.texids.size()));
|
||||
unsigned int j;
|
||||
for (j=0;j<sMat.texids.size();j++)
|
||||
buf.Add(sMat.texids[j]);
|
||||
}
|
||||
buf.End();
|
||||
|
||||
// Write the regular materials
|
||||
buf.Add(numTable*numMat);
|
||||
for (i=0;i<numTable*numMat;i++) {
|
||||
trpgMaterial &mat = matTables[i];
|
||||
// This will be bigger than the old 1.0 material, but it doesn't matter since
|
||||
// the new stuff is on the end.
|
||||
mat.Write(buf);
|
||||
buf.Add((int)materialMap.size());//numTable*numMat);
|
||||
//for (i=0;i<numTable*numMat;i++) {
|
||||
itr = materialMap.begin();
|
||||
for ( ; itr != materialMap.end( ); itr++) {
|
||||
|
||||
trpgMaterial &mat = itr->second; //matTables[i];
|
||||
|
||||
// This will be bigger than the old 1.0 material, but it doesn't matter since
|
||||
// the new stuff is on the end.
|
||||
mat.Write(buf);
|
||||
}
|
||||
|
||||
// Close Mat Table
|
||||
@ -191,13 +199,13 @@ bool trpgTexture1_0::Read(trpgReadBuffer &buf)
|
||||
mode = External;
|
||||
|
||||
try {
|
||||
char texName[1024];
|
||||
buf.Get(texName,1023);
|
||||
SetName(texName);
|
||||
buf.Get(useCount);
|
||||
char texName[1024];
|
||||
buf.Get(texName,1023);
|
||||
SetName(texName);
|
||||
buf.Get(useCount);
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -207,7 +215,7 @@ bool trpgTexture1_0::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
// Can only deal with external textures in 1.0
|
||||
if (mode != External)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Write the name and use count
|
||||
buf.Add(name);
|
||||
@ -226,16 +234,17 @@ bool trpgTexTable1_0::Read(trpgReadBuffer &buf)
|
||||
int32 numTex;
|
||||
|
||||
try {
|
||||
buf.Get(numTex);
|
||||
texList.resize(numTex);
|
||||
for (unsigned int i=0;i<(unsigned int)numTex;i++) {
|
||||
trpgTexture1_0 tex1_0;
|
||||
tex1_0.Read(buf);
|
||||
texList[i] = tex1_0;
|
||||
}
|
||||
buf.Get(numTex);
|
||||
//texList.resize(numTex);
|
||||
for (int i=0;i<numTex;i++) {
|
||||
trpgTexture1_0 tex1_0;
|
||||
tex1_0.Read(buf);
|
||||
AddTexture(tex1_0);
|
||||
//texList[i] = tex1_0;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
valid = true;
|
||||
@ -247,16 +256,18 @@ bool trpgTexTable1_0::Write(trpgWriteBuffer &buf)
|
||||
int32 numTex;
|
||||
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGTEXTABLE);
|
||||
numTex = texList.size();
|
||||
|
||||
numTex = textureMap.size();
|
||||
buf.Add(numTex);
|
||||
for (unsigned int i=0;i<texList.size();i++) {
|
||||
trpgTexture1_0 tex1_0;
|
||||
tex1_0 = texList[i];
|
||||
if (!tex1_0.Write(buf))
|
||||
return false;
|
||||
TextureMapType::const_iterator itr = textureMap.begin();
|
||||
for ( ; itr != textureMap.end( ); itr++) {
|
||||
trpgTexture1_0 tex1_0;
|
||||
tex1_0 = itr->second;
|
||||
if (!tex1_0.Write(buf))
|
||||
return false;
|
||||
}
|
||||
buf.End();
|
||||
|
||||
@ -272,12 +283,12 @@ trpgTileTable1_0::trpgTileTable1_0(const trpgTileTable& /*inTable*/)
|
||||
bool trpgTileTable1_0::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Begin(TRPGTILETABLE);
|
||||
buf.Add("");
|
||||
buf.End();
|
||||
buf.Begin(TRPGTILETABLE);
|
||||
buf.Add("");
|
||||
buf.End();
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -34,13 +34,13 @@ public:
|
||||
trpgMatTable1_0(const trpgMatTable &);
|
||||
|
||||
/* This read method overrides the one from trpgMatTable and knows
|
||||
how to read the old school material tables.
|
||||
how to read the old school material tables.
|
||||
*/
|
||||
bool Read(trpgReadBuffer &);
|
||||
bool Read(trpgReadBuffer &);
|
||||
/* This write method can write a 2.0 material table as 1.0
|
||||
style for backward compatibility.
|
||||
style for backward compatibility.
|
||||
*/
|
||||
bool Write(trpgWriteBuffer &);
|
||||
bool Write(trpgWriteBuffer &);
|
||||
protected:
|
||||
};
|
||||
|
||||
@ -56,13 +56,13 @@ public:
|
||||
trpgTexTable1_0(const trpgTexTable &);
|
||||
|
||||
/* This read method overrides the one from trpgTexTable and
|
||||
knows how to read the old style texture table.
|
||||
knows how to read the old style texture table.
|
||||
*/
|
||||
bool Read(trpgReadBuffer &);
|
||||
bool Read(trpgReadBuffer &);
|
||||
/* The write method can write a 2.0 texture table as 1.0
|
||||
style for backward compatibility.
|
||||
style for backward compatibility.
|
||||
*/
|
||||
bool Write(trpgWriteBuffer &);
|
||||
bool Write(trpgWriteBuffer &);
|
||||
protected:
|
||||
};
|
||||
|
||||
@ -76,9 +76,9 @@ public:
|
||||
trpgTexture1_0 operator = (const trpgTexture &);
|
||||
|
||||
// Knows how to read old style textures
|
||||
bool Read(trpgReadBuffer &);
|
||||
bool Read(trpgReadBuffer &);
|
||||
// Can write old style textures
|
||||
bool Write(trpgWriteBuffer &);
|
||||
bool Write(trpgWriteBuffer &);
|
||||
protected:
|
||||
};
|
||||
|
||||
@ -90,7 +90,7 @@ class trpgTileTable1_0 : public trpgTileTable {
|
||||
public:
|
||||
trpgTileTable1_0(const trpgTileTable &);
|
||||
// Can write old style tile table
|
||||
bool Write(trpgWriteBuffer &);
|
||||
bool Write(trpgWriteBuffer &);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -18,22 +18,22 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_header.cpp
|
||||
Source for trpgHeader methods.
|
||||
The only reason to change this is if you want to add something
|
||||
to the header definition.
|
||||
*/
|
||||
Source for trpgHeader methods.
|
||||
The only reason to change this is if you want to add something
|
||||
to the header definition.
|
||||
*/
|
||||
|
||||
#include <trpage_geom.h>
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* Write Header class
|
||||
Fill it in and write it out.
|
||||
*/
|
||||
Fill it in and write it out.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgHeader::trpgHeader()
|
||||
{
|
||||
Reset();
|
||||
Reset();
|
||||
}
|
||||
trpgHeader::~trpgHeader()
|
||||
{
|
||||
@ -42,152 +42,181 @@ trpgHeader::~trpgHeader()
|
||||
// Validity check
|
||||
bool trpgHeader::isValid() const
|
||||
{
|
||||
if (numLods <= 0)
|
||||
{
|
||||
strcpy(errMess, "Number of LOD <= 0");
|
||||
return false;
|
||||
}
|
||||
if (sw.x == ne.x && sw.y == ne.y)
|
||||
{
|
||||
strcpy(errMess, "Mbr is invalid");
|
||||
// We also need to check that this is a 'master' archive here.
|
||||
if((verMajor>=TRPG_NOMERGE_VERSION_MAJOR) && (verMinor>=TRPG_NOMERGE_VERSION_MINOR))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (numLods <= 0)
|
||||
{
|
||||
strcpy(errMess, "Number of LOD <= 0");
|
||||
return false;
|
||||
}
|
||||
if (sw.x == ne.x && sw.y == ne.y)
|
||||
{
|
||||
strcpy(errMess, "Mbr is invalid");
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reset contents
|
||||
void trpgHeader::Reset()
|
||||
{
|
||||
// Initialize to a default state
|
||||
verMinor = TRPG_VERSION_MINOR;
|
||||
verMajor = TRPG_VERSION_MAJOR;
|
||||
dbVerMinor = 0;
|
||||
dbVerMajor = 0;
|
||||
origin = trpg3dPoint(0,0,0);
|
||||
sw = ne = trpg2dPoint(0,0);
|
||||
tileType = DatabaseLocal;
|
||||
// Initialize to a default state
|
||||
verMinor = TRPG_VERSION_MINOR;
|
||||
verMajor = TRPG_VERSION_MAJOR;
|
||||
dbVerMinor = 0;
|
||||
dbVerMajor = 0;
|
||||
origin = trpg3dPoint(0,0,0);
|
||||
sw = ne = trpg2dPoint(0,0);
|
||||
tileType = DatabaseLocal;
|
||||
|
||||
numLods = 0;
|
||||
lodSizes.resize(0);
|
||||
lodRanges.resize(0);
|
||||
tileSize.resize(0);
|
||||
maxGroupID = -1;
|
||||
|
||||
errMess[0] = '\0';
|
||||
numLods = 0;
|
||||
lodSizes.resize(0);
|
||||
lodRanges.resize(0);
|
||||
tileSize.resize(0);
|
||||
maxGroupID = -1;
|
||||
flags = 0;
|
||||
errMess[0] = '\0';
|
||||
cols = -1;
|
||||
rows = -1;
|
||||
}
|
||||
|
||||
// Set functions
|
||||
void trpgHeader::SetVersion(int32 vmaj,int32 vmin)
|
||||
{
|
||||
verMinor = vmin;
|
||||
verMajor = vmaj;
|
||||
verMinor = vmin;
|
||||
verMajor = vmaj;
|
||||
}
|
||||
void trpgHeader::SetDbVersion(int32 vmaj,int32 vmin)
|
||||
{
|
||||
dbVerMinor = vmin;
|
||||
dbVerMajor = vmaj;
|
||||
dbVerMinor = vmin;
|
||||
dbVerMajor = vmaj;
|
||||
}
|
||||
void trpgHeader::SetTileSize(int id,const trpg2dPoint &pt)
|
||||
{
|
||||
if (id < 0 || id >= (int)tileSize.size()) return;
|
||||
tileSize[id] = pt;
|
||||
if (id < 0 || id >= (int)tileSize.size()) return;
|
||||
tileSize[id] = pt;
|
||||
}
|
||||
void trpgHeader::SetOrigin(const trpg3dPoint &pt)
|
||||
{
|
||||
origin = pt;
|
||||
origin = pt;
|
||||
}
|
||||
void trpgHeader::SetExtents(const trpg2dPoint &in_sw,const trpg2dPoint &in_ne)
|
||||
{
|
||||
sw = in_sw;
|
||||
ne = in_ne;
|
||||
sw = in_sw;
|
||||
ne = in_ne;
|
||||
}
|
||||
void trpgHeader::SetTileOriginType(trpgTileType type)
|
||||
{
|
||||
tileType = type;
|
||||
tileType = type;
|
||||
}
|
||||
void trpgHeader::SetNumLods(int no)
|
||||
{
|
||||
if (no < 0) return;
|
||||
numLods = no;
|
||||
if (no < 0) return;
|
||||
numLods = no;
|
||||
|
||||
lodSizes.resize(no);
|
||||
lodRanges.resize(no);
|
||||
lodSizes.resize(no);
|
||||
lodRanges.resize(no);
|
||||
}
|
||||
void trpgHeader::SetLodSize(int no,const trpg2iPoint &pt)
|
||||
{
|
||||
if (no < 0 || no >= numLods)
|
||||
return;
|
||||
if (no < 0 || no >= numLods)
|
||||
return;
|
||||
|
||||
lodSizes[no] = pt;
|
||||
lodSizes[no] = pt;
|
||||
}
|
||||
void trpgHeader::SetLodSize(const trpg2iPoint *pt)
|
||||
{
|
||||
for (int i=0;i<numLods;i++)
|
||||
lodSizes[i] = pt[i];
|
||||
for (int i=0;i<numLods;i++)
|
||||
lodSizes[i] = pt[i];
|
||||
}
|
||||
void trpgHeader::SetLodRange(int no,float64 r)
|
||||
{
|
||||
if (no < 0 || no >= numLods)
|
||||
return;
|
||||
if (no < 0 || no >= numLods)
|
||||
return;
|
||||
|
||||
lodRanges[no] = r;
|
||||
lodRanges[no] = r;
|
||||
}
|
||||
void trpgHeader::SetLodRange(const float64 *r)
|
||||
{
|
||||
for (int i=0;i<numLods;i++)
|
||||
lodRanges[i] = r[i];
|
||||
for (int i=0;i<numLods;i++)
|
||||
lodRanges[i] = r[i];
|
||||
}
|
||||
void trpgHeader::AddLod(const trpg2iPoint &pt,const trpg2dPoint &sz,float64 r)
|
||||
{
|
||||
lodRanges.push_back(r);
|
||||
lodSizes.push_back(pt);
|
||||
tileSize.push_back(sz);
|
||||
numLods++;
|
||||
lodRanges.push_back(r);
|
||||
lodSizes.push_back(pt);
|
||||
tileSize.push_back(sz);
|
||||
numLods++;
|
||||
}
|
||||
void trpgHeader::SetLod(const trpg2iPoint &pt,const trpg2dPoint &sz,float64 r,unsigned int lod)
|
||||
{
|
||||
if (lodRanges.size()<=lod)
|
||||
lodRanges.resize(lod+1);
|
||||
lodRanges[lod]=r;
|
||||
if (lodSizes.size()<=lod)
|
||||
lodSizes.resize(lod+1);
|
||||
lodSizes[lod]=pt;
|
||||
if (tileSize.size()<=lod)
|
||||
tileSize.resize(lod+1);
|
||||
tileSize[lod]=sz;
|
||||
if (numLods<=static_cast<int>(lod))
|
||||
numLods=lod+1;
|
||||
}
|
||||
void trpgHeader::SetMaxGroupID(int id)
|
||||
{
|
||||
maxGroupID = id;
|
||||
maxGroupID = id;
|
||||
}
|
||||
int trpgHeader::AddGroupID(void)
|
||||
{
|
||||
maxGroupID++;
|
||||
return maxGroupID;
|
||||
maxGroupID++;
|
||||
return maxGroupID;
|
||||
}
|
||||
|
||||
// Write out to a buffer
|
||||
bool trpgHeader::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGHEADER);
|
||||
buf.Add((int32)verMajor);
|
||||
buf.Add((int32)verMinor);
|
||||
buf.Add((int32)dbVerMajor);
|
||||
buf.Add((int32)dbVerMinor);
|
||||
buf.Add(origin);
|
||||
buf.Add(sw);
|
||||
buf.Add(ne);
|
||||
buf.Add((uint8)tileType);
|
||||
buf.Begin(TRPGHEADER);
|
||||
buf.Add((int32)verMajor);
|
||||
buf.Add((int32)verMinor);
|
||||
buf.Add((int32)dbVerMajor);
|
||||
buf.Add((int32)dbVerMinor);
|
||||
buf.Add(origin);
|
||||
buf.Add(sw);
|
||||
buf.Add(ne);
|
||||
buf.Add((uint8)tileType);
|
||||
|
||||
buf.Add((int32)numLods);
|
||||
buf.Add((int32)numLods);
|
||||
|
||||
buf.Begin(TRPGHEAD_LODINFO);
|
||||
for (int i=0;i<numLods;i++) {
|
||||
buf.Add(lodSizes[i]);
|
||||
buf.Add(lodRanges[i]);
|
||||
buf.Add(tileSize[i]);
|
||||
}
|
||||
buf.End();
|
||||
buf.Begin(TRPGHEAD_LODINFO);
|
||||
for (int i=0;i<numLods;i++) {
|
||||
buf.Add(lodSizes[i]);
|
||||
buf.Add(lodRanges[i]);
|
||||
buf.Add(tileSize[i]);
|
||||
}
|
||||
buf.End();
|
||||
|
||||
buf.Add(maxGroupID);
|
||||
buf.Add(maxGroupID);
|
||||
|
||||
buf.End();
|
||||
if((verMajor >= TRPG_NOMERGE_VERSION_MAJOR) && (verMinor >=TRPG_NOMERGE_VERSION_MINOR)) {
|
||||
buf.Add(flags);
|
||||
buf.Add(rows);
|
||||
buf.Add(cols);
|
||||
}
|
||||
|
||||
return true;
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ********
|
||||
@ -197,128 +226,133 @@ bool trpgHeader::Write(trpgWriteBuffer &buf)
|
||||
// Get Functions
|
||||
bool trpgHeader::GetVersion(int32 &vmaj,int32 &vmin) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
vmin = verMinor;
|
||||
vmaj = verMajor;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
vmin = verMinor;
|
||||
vmaj = verMajor;
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetDbVersion(int32 &vmaj,int32 &vmin) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
vmaj = dbVerMajor;
|
||||
vmin = dbVerMinor;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
vmaj = dbVerMajor;
|
||||
vmin = dbVerMinor;
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetTileSize(int id,trpg2dPoint &pt) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (id < 0 || id >= (int)tileSize.size()) return false;
|
||||
pt = tileSize[id];
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
if (id < 0 || id >= (int)tileSize.size()) return false;
|
||||
pt = tileSize[id];
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetOrigin(trpg3dPoint &pt) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
pt = origin;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
pt = origin;
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetTileOriginType(trpgTileType &type) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
type = tileType;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
type = tileType;
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetNumLods(int32 &no) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
no = numLods;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
no = numLods;
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetLodSize(int32 id,trpg2iPoint &pt) const
|
||||
{
|
||||
if (!isValid() || (id < 0 || id >= numLods)) return false;
|
||||
pt = lodSizes[id];
|
||||
return true;
|
||||
if (!isValid() || (id < 0 || id >= numLods)) return false;
|
||||
pt = lodSizes[id];
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetLodRange(int32 id,float64 &range) const
|
||||
{
|
||||
if (!isValid() || (id < 0 || id >= numLods)) return false;
|
||||
range = lodRanges[id];
|
||||
return true;
|
||||
if (!isValid() || (id < 0 || id >= numLods)) return false;
|
||||
range = lodRanges[id];
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetExtents(trpg2dPoint &osw,trpg2dPoint &one) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
osw = sw;
|
||||
one = ne;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
osw = sw;
|
||||
one = ne;
|
||||
return true;
|
||||
}
|
||||
bool trpgHeader::GetMaxGroupID(int &id) const
|
||||
{
|
||||
id = maxGroupID;
|
||||
return true;
|
||||
id = maxGroupID;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read in the header
|
||||
bool trpgHeader::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
uint8 i8;
|
||||
trpgToken tok;
|
||||
bool status;
|
||||
int32 len;
|
||||
uint8 i8;
|
||||
trpgToken tok;
|
||||
bool status;
|
||||
int32 len;
|
||||
|
||||
try {
|
||||
buf.Get(verMajor);
|
||||
buf.Get(verMinor);
|
||||
buf.Get(dbVerMajor);
|
||||
buf.Get(dbVerMinor);
|
||||
buf.Get(origin);
|
||||
buf.Get(sw);
|
||||
buf.Get(ne);
|
||||
buf.Get(i8); tileType = (trpgTileType)i8;
|
||||
buf.Get(numLods);
|
||||
if (numLods < 0) throw 1;
|
||||
try {
|
||||
buf.Get(verMajor);
|
||||
buf.Get(verMinor);
|
||||
buf.Get(dbVerMajor);
|
||||
buf.Get(dbVerMinor);
|
||||
buf.Get(origin);
|
||||
buf.Get(sw);
|
||||
buf.Get(ne);
|
||||
buf.Get(i8); tileType = (trpgTileType)i8;
|
||||
buf.Get(numLods);
|
||||
if (numLods < 0) throw 1;
|
||||
|
||||
// Read in the LOD range info
|
||||
buf.GetToken(tok,len);
|
||||
if (tok != TRPGHEAD_LODINFO) throw 1;
|
||||
buf.PushLimit(len);
|
||||
status = ReadLodInfo(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
// Read in the LOD range info
|
||||
buf.GetToken(tok,len);
|
||||
if (tok != TRPGHEAD_LODINFO) throw 1;
|
||||
buf.PushLimit(len);
|
||||
status = ReadLodInfo(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
|
||||
// Added after the first version (but still in 1.0)
|
||||
buf.Get(maxGroupID);
|
||||
}
|
||||
// Added after the first version (but still in 1.0)
|
||||
buf.Get(maxGroupID);
|
||||
if((verMajor >= TRPG_NOMERGE_VERSION_MAJOR) && (verMinor >=TRPG_NOMERGE_VERSION_MINOR)) {
|
||||
buf.Get(flags);
|
||||
buf.Get(rows);
|
||||
buf.Get(cols);
|
||||
}
|
||||
}
|
||||
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
return isValid();
|
||||
}
|
||||
|
||||
// Read the LOD info (seperate token)
|
||||
bool trpgHeader::ReadLodInfo(trpgReadBuffer &buf)
|
||||
{
|
||||
float64 range;
|
||||
trpg2iPoint pt;
|
||||
trpg2dPoint sz;
|
||||
float64 range;
|
||||
trpg2iPoint pt;
|
||||
trpg2dPoint sz;
|
||||
|
||||
try {
|
||||
for (int i=0;i<numLods;i++) {
|
||||
buf.Get(pt);
|
||||
buf.Get(range);
|
||||
buf.Get(sz);
|
||||
lodSizes.push_back(pt);
|
||||
lodRanges.push_back(range);
|
||||
tileSize.push_back(sz);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
for (int i=0;i<numLods;i++) {
|
||||
buf.Get(pt);
|
||||
buf.Get(range);
|
||||
buf.Get(sz);
|
||||
lodSizes.push_back(pt);
|
||||
lodRanges.push_back(range);
|
||||
tileSize.push_back(sz);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,13 +14,13 @@
|
||||
*/
|
||||
|
||||
/* trpage_label.cpp
|
||||
Methods for the trpgLable object and its associated support structure
|
||||
including trpgTextStyle and trpgTextStyleTable.
|
||||
*/
|
||||
Methods for the trpgLable object and its associated support structure
|
||||
including trpgTextStyle and trpgTextStyleTable.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <math.h>
|
||||
|
||||
#include <trpage_geom.h>
|
||||
@ -114,9 +114,9 @@ bool trpgTextStyle::Write(trpgWriteBuffer &buf)
|
||||
|
||||
buf.Begin(TRPG_TEXT_STYLE_BASIC);
|
||||
buf.Add(font);
|
||||
buf.Add(bold);
|
||||
buf.Add(italic);
|
||||
buf.Add(underline);
|
||||
buf.Add((int32)bold);
|
||||
buf.Add((int32)italic);
|
||||
buf.Add((int32)underline);
|
||||
buf.Add(characterSize);
|
||||
buf.Add(matId);
|
||||
buf.End();
|
||||
@ -129,8 +129,9 @@ bool trpgTextStyle::Write(trpgWriteBuffer &buf)
|
||||
// TextStyle CB
|
||||
// Used to parse tokens from the text style structure.
|
||||
// If we do it this way it's easier to expand later.
|
||||
class textStyleCB : public trpgr_Callback {
|
||||
public:
|
||||
class textStyleCB : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
void * Parse(trpgToken,trpgReadBuffer &);
|
||||
trpgTextStyle *style;
|
||||
};
|
||||
@ -141,8 +142,10 @@ void * textStyleCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
int iVal;
|
||||
float32 fVal;
|
||||
|
||||
try {
|
||||
switch (tok) {
|
||||
try
|
||||
{
|
||||
switch (tok)
|
||||
{
|
||||
case TRPG_TEXT_STYLE_BASIC:
|
||||
buf.Get(sVal);
|
||||
style->SetFont(sVal);
|
||||
@ -161,7 +164,8 @@ void * textStyleCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -196,7 +200,7 @@ bool trpgTextStyle::isValid(void) const
|
||||
|
||||
bool trpgTextStyle::operator == (const trpgTextStyle& in) const
|
||||
{
|
||||
if (font.compare(in.font) != 0)
|
||||
if (font != in.font)
|
||||
return false;
|
||||
|
||||
if (bold != in.bold ||
|
||||
@ -220,19 +224,22 @@ trpgTextStyleTable::trpgTextStyleTable()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
trpgTextStyleTable::~trpgTextStyleTable()
|
||||
{
|
||||
}
|
||||
|
||||
void trpgTextStyleTable::Reset()
|
||||
{
|
||||
styles.resize(0);
|
||||
styleMap.clear();
|
||||
}
|
||||
|
||||
bool trpgTextStyleTable::isValid() const
|
||||
{
|
||||
for (unsigned int i=0;i<styles.size();i++)
|
||||
if (!styles[i].isValid())
|
||||
//for (int i=0;i<styles.size();i++)
|
||||
StyleMapType::const_iterator itr = styleMap.begin();
|
||||
for ( ; itr != styleMap.end( ); itr++)
|
||||
if (!itr->second.isValid())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -240,30 +247,38 @@ bool trpgTextStyleTable::isValid() const
|
||||
|
||||
int trpgTextStyleTable::AddStyle(const trpgTextStyle &style)
|
||||
{
|
||||
styles.push_back(style);
|
||||
return styles.size() -1;
|
||||
int handle = style.GetHandle();
|
||||
if(handle==-1) {
|
||||
handle = styleMap.size();
|
||||
}
|
||||
styleMap[handle] = style;
|
||||
return handle;
|
||||
}
|
||||
|
||||
int trpgTextStyleTable::FindAddStyle(const trpgTextStyle &style)
|
||||
{
|
||||
for (unsigned int i=0;i<styles.size();i++)
|
||||
if (styles[i] == style)
|
||||
return i;
|
||||
StyleMapType::const_iterator itr = styleMap.begin();
|
||||
for ( ; itr != styleMap.end( ); itr++)
|
||||
if (itr->second == style)
|
||||
return itr->first;
|
||||
|
||||
return AddStyle(style);
|
||||
}
|
||||
|
||||
int trpgTextStyleTable::GetNumStyle() const
|
||||
{
|
||||
return styles.size();
|
||||
return styleMap.size();
|
||||
}
|
||||
|
||||
const trpgTextStyle *trpgTextStyleTable::GetStyleRef(int id) const
|
||||
{
|
||||
if (id < 0 || id >= (int)styles.size())
|
||||
if (id < 0)
|
||||
return NULL;
|
||||
|
||||
return &styles[id];
|
||||
StyleMapType::const_iterator itr = styleMap.find(id);
|
||||
if(itr == styleMap.end())
|
||||
return NULL;
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
bool trpgTextStyleTable::Write(trpgWriteBuffer &buf)
|
||||
@ -274,12 +289,13 @@ bool trpgTextStyleTable::Write(trpgWriteBuffer &buf)
|
||||
buf.Begin(TRPG_TEXT_STYLE_TABLE);
|
||||
|
||||
// Number of styles
|
||||
int numStyle = styles.size();
|
||||
int numStyle = styleMap.size();
|
||||
buf.Add((int32)numStyle);
|
||||
|
||||
// Write the styles
|
||||
for (unsigned int i=0;i<styles.size();i++)
|
||||
styles[i].Write(buf);
|
||||
StyleMapType::iterator itr = styleMap.begin();
|
||||
for ( ; itr != styleMap.end( ); itr++)
|
||||
itr->second.Write(buf);
|
||||
|
||||
buf.End();
|
||||
|
||||
@ -293,16 +309,17 @@ bool trpgTextStyleTable::Read(trpgReadBuffer &buf)
|
||||
int32 len;
|
||||
bool status;
|
||||
int numStyle;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
Reset();
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
buf.Get(numStyle);
|
||||
if (numStyle < 0)
|
||||
throw 1;
|
||||
styles.resize(numStyle);
|
||||
for (i=0;i<numStyle;i++) {
|
||||
|
||||
for (i=0;i<numStyle;i++) {
|
||||
buf.GetToken(styleTok,len);
|
||||
if (styleTok != TRPG_TEXT_STYLE) throw 1;
|
||||
buf.PushLimit(len);
|
||||
@ -310,10 +327,11 @@ bool trpgTextStyleTable::Read(trpgReadBuffer &buf)
|
||||
status = style.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
styles[i] = style;
|
||||
AddStyle(style);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -338,6 +356,8 @@ void trpgSupportStyle::Reset(void)
|
||||
{
|
||||
type = Line;
|
||||
matId = -1;
|
||||
handle = -1;
|
||||
writeHandle = false;
|
||||
}
|
||||
|
||||
void trpgSupportStyle::SetType(SupportType s)
|
||||
@ -378,7 +398,8 @@ bool trpgSupportStyle::Write(trpgWriteBuffer &buf)
|
||||
// SupportStyle CB
|
||||
// Used to parse tokens from the support style structure.
|
||||
// If we do it this way it's easier to expand later.
|
||||
class supportStyleCB : public trpgr_Callback {
|
||||
class supportStyleCB : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
void * Parse(trpgToken,trpgReadBuffer &);
|
||||
trpgSupportStyle *style;
|
||||
@ -388,8 +409,10 @@ void * supportStyleCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
{
|
||||
int iVal;
|
||||
|
||||
try {
|
||||
switch (tok) {
|
||||
try
|
||||
{
|
||||
switch (tok)
|
||||
{
|
||||
case TRPG_SUPPORT_STYLE_BASIC:
|
||||
buf.Get(iVal);
|
||||
style->SetType(trpgSupportStyle::SupportType(iVal));
|
||||
@ -400,7 +423,8 @@ void * supportStyleCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -450,44 +474,56 @@ trpgSupportStyleTable::~trpgSupportStyleTable()
|
||||
|
||||
void trpgSupportStyleTable::Reset()
|
||||
{
|
||||
styles.resize(0);
|
||||
//styles.resize(0);
|
||||
supportStyleMap.clear();
|
||||
}
|
||||
|
||||
bool trpgSupportStyleTable::isValid() const
|
||||
{
|
||||
for (unsigned int i=0;i<styles.size();i++)
|
||||
if (!styles[i].isValid())
|
||||
//for (int i=0;i<styles.size();i++)
|
||||
SupportStyleMapType::const_iterator itr = supportStyleMap.begin();
|
||||
for ( ; itr != supportStyleMap.end( ); itr++)
|
||||
{
|
||||
if (!itr->second.isValid())
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int trpgSupportStyleTable::AddStyle(const trpgSupportStyle &style)
|
||||
{
|
||||
styles.push_back(style);
|
||||
return styles.size() -1;
|
||||
int handle = style.GetHandle();
|
||||
if(handle==-1)
|
||||
{
|
||||
handle = supportStyleMap.size();
|
||||
}
|
||||
supportStyleMap[handle] = style;
|
||||
return handle;
|
||||
}
|
||||
|
||||
int trpgSupportStyleTable::FindAddStyle(const trpgSupportStyle &style)
|
||||
{
|
||||
for (unsigned int i=0;i<styles.size();i++)
|
||||
if (styles[i] == style)
|
||||
return i;
|
||||
SupportStyleMapType::const_iterator itr = supportStyleMap.begin();
|
||||
for ( ; itr != supportStyleMap.end( ); itr++)
|
||||
if (itr->second == style)
|
||||
return itr->first;
|
||||
|
||||
return AddStyle(style);
|
||||
}
|
||||
|
||||
int trpgSupportStyleTable::GetNumStyle() const
|
||||
{
|
||||
return styles.size();
|
||||
return supportStyleMap.size();
|
||||
}
|
||||
|
||||
const trpgSupportStyle *trpgSupportStyleTable::GetStyleRef(int id) const
|
||||
{
|
||||
if (id < 0 || id >= (int)styles.size())
|
||||
if (id < 0)
|
||||
return NULL;
|
||||
|
||||
return &styles[id];
|
||||
SupportStyleMapType::const_iterator itr = supportStyleMap.find(id);
|
||||
if(itr == supportStyleMap.end())
|
||||
return NULL;
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
bool trpgSupportStyleTable::Write(trpgWriteBuffer &buf)
|
||||
@ -498,12 +534,13 @@ bool trpgSupportStyleTable::Write(trpgWriteBuffer &buf)
|
||||
buf.Begin(TRPG_SUPPORT_STYLE_TABLE);
|
||||
|
||||
// Number of styles
|
||||
int numStyle = styles.size();
|
||||
int numStyle = supportStyleMap.size();
|
||||
buf.Add((int32)numStyle);
|
||||
|
||||
// Write the styles
|
||||
for (unsigned int i=0;i<styles.size();i++)
|
||||
styles[i].Write(buf);
|
||||
SupportStyleMapType::iterator itr = supportStyleMap.begin();
|
||||
for ( ; itr != supportStyleMap.end( ); itr++)
|
||||
itr->second.Write(buf);
|
||||
|
||||
buf.End();
|
||||
|
||||
@ -517,15 +554,17 @@ bool trpgSupportStyleTable::Read(trpgReadBuffer &buf)
|
||||
int32 len;
|
||||
bool status;
|
||||
int numStyle;
|
||||
int i;
|
||||
|
||||
Reset();
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
buf.Get(numStyle);
|
||||
if (numStyle < 0)
|
||||
throw 1;
|
||||
styles.resize(numStyle);
|
||||
for (int i=0;i<numStyle;i++) {
|
||||
//styles.resize(numStyle);
|
||||
for (i=0;i<numStyle;i++) {
|
||||
buf.GetToken(styleTok,len);
|
||||
if (styleTok != TRPG_SUPPORT_STYLE) throw 1;
|
||||
buf.PushLimit(len);
|
||||
@ -533,10 +572,11 @@ bool trpgSupportStyleTable::Read(trpgReadBuffer &buf)
|
||||
status = style.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
styles[i] = style;
|
||||
AddStyle(style);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -561,6 +601,8 @@ void trpgLabelProperty::Reset(void)
|
||||
fontId = -1;
|
||||
supportId = -1;
|
||||
type = VertBillboard;
|
||||
handle = -1;
|
||||
writeHandle = false;
|
||||
}
|
||||
|
||||
void trpgLabelProperty::SetType(LabelType inType)
|
||||
@ -612,7 +654,8 @@ bool trpgLabelProperty::Write(trpgWriteBuffer &buf)
|
||||
// LabelProperty CB
|
||||
// Used to parse tokens from the label property structure.
|
||||
// If we do it this way it's easier to expand later.
|
||||
class labelPropertyCB : public trpgr_Callback {
|
||||
class labelPropertyCB : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
void * Parse(trpgToken,trpgReadBuffer &);
|
||||
trpgLabelProperty *property;
|
||||
@ -622,9 +665,11 @@ void * labelPropertyCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
{
|
||||
int iVal;
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
int ival;
|
||||
switch (tok) {
|
||||
switch (tok)
|
||||
{
|
||||
case TRPG_LABEL_PROPERTY_BASIC:
|
||||
buf.Get(iVal);
|
||||
property->SetFontStyle(iVal);
|
||||
@ -637,7 +682,8 @@ void * labelPropertyCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -686,44 +732,56 @@ trpgLabelPropertyTable::~trpgLabelPropertyTable()
|
||||
|
||||
void trpgLabelPropertyTable::Reset()
|
||||
{
|
||||
properties.resize(0);
|
||||
labelPropertyMap.clear();
|
||||
}
|
||||
|
||||
bool trpgLabelPropertyTable::isValid() const
|
||||
{
|
||||
for (unsigned int i=0;i<properties.size();i++)
|
||||
if (!properties[i].isValid())
|
||||
LabelPropertyMapType::const_iterator itr = labelPropertyMap.begin();
|
||||
for ( ; itr != labelPropertyMap.end( ); itr++)
|
||||
{
|
||||
if (!itr->second.isValid())
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int trpgLabelPropertyTable::AddProperty(const trpgLabelProperty &property)
|
||||
{
|
||||
properties.push_back(property);
|
||||
return properties.size() -1;
|
||||
int handle = property.GetHandle();
|
||||
if(handle==-1)
|
||||
{
|
||||
handle = labelPropertyMap.size();
|
||||
}
|
||||
labelPropertyMap[handle] = property;
|
||||
return handle;
|
||||
}
|
||||
|
||||
int trpgLabelPropertyTable::FindAddProperty(const trpgLabelProperty& property)
|
||||
{
|
||||
for (unsigned int i=0;i<properties.size();i++)
|
||||
if (properties[i] == property)
|
||||
return i;
|
||||
|
||||
LabelPropertyMapType::const_iterator itr = labelPropertyMap.begin();
|
||||
for ( ; itr != labelPropertyMap.end( ); itr++)
|
||||
{
|
||||
if (itr->second == property)
|
||||
return itr->first;
|
||||
}
|
||||
return AddProperty(property);
|
||||
}
|
||||
|
||||
int trpgLabelPropertyTable::GetNumProperty() const
|
||||
{
|
||||
return properties.size();
|
||||
return labelPropertyMap.size();
|
||||
}
|
||||
|
||||
const trpgLabelProperty *trpgLabelPropertyTable::GetPropertyRef(int id) const
|
||||
{
|
||||
if (id < 0 || id >= (int)properties.size())
|
||||
if (id < 0)
|
||||
return NULL;
|
||||
|
||||
return &properties[id];
|
||||
LabelPropertyMapType::const_iterator itr = labelPropertyMap.find(id);
|
||||
if(itr == labelPropertyMap.end())
|
||||
return NULL;
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
bool trpgLabelPropertyTable::Write(trpgWriteBuffer &buf)
|
||||
@ -734,12 +792,15 @@ bool trpgLabelPropertyTable::Write(trpgWriteBuffer &buf)
|
||||
buf.Begin(TRPG_LABEL_PROPERTY_TABLE);
|
||||
|
||||
// Number of styles
|
||||
int numProperty = properties.size();
|
||||
int numProperty = labelPropertyMap.size();
|
||||
buf.Add((int32)numProperty);
|
||||
|
||||
// Write the properties
|
||||
for (unsigned int i=0;i<properties.size();i++)
|
||||
properties[i].Write(buf);
|
||||
LabelPropertyMapType::iterator itr = labelPropertyMap.begin();
|
||||
for ( ; itr != labelPropertyMap.end( ); itr++)
|
||||
{
|
||||
itr->second.Write(buf);
|
||||
}
|
||||
|
||||
buf.End();
|
||||
|
||||
@ -753,15 +814,17 @@ bool trpgLabelPropertyTable::Read(trpgReadBuffer &buf)
|
||||
int32 len;
|
||||
bool status;
|
||||
int numProperty;
|
||||
int i;
|
||||
|
||||
Reset();
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
buf.Get(numProperty);
|
||||
if (numProperty < 0)
|
||||
throw 1;
|
||||
properties.resize(numProperty);
|
||||
for (unsigned int i=0;i<(unsigned int)numProperty;i++) {
|
||||
//properties.resize(numProperty);
|
||||
for (i=0;i<numProperty;i++) {
|
||||
buf.GetToken(propertyTok,len);
|
||||
if (propertyTok != TRPG_LABEL_PROPERTY) throw 1;
|
||||
buf.PushLimit(len);
|
||||
@ -769,10 +832,12 @@ bool trpgLabelPropertyTable::Read(trpgReadBuffer &buf)
|
||||
status = property.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
properties[i] = property;
|
||||
//properties[i] = property;
|
||||
AddProperty(property);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -920,6 +985,8 @@ const std::vector<trpg3dPoint> *trpgLabel::GetSupports() const
|
||||
|
||||
bool trpgLabel::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
buf.Begin(TRPG_LABEL);
|
||||
buf.Add(propertyId);
|
||||
buf.Add(text);
|
||||
@ -931,7 +998,7 @@ bool trpgLabel::Write(trpgWriteBuffer &buf)
|
||||
buf.Add(url);
|
||||
buf.Add(location);
|
||||
buf.Add((int)supports.size());
|
||||
for (unsigned i=0;i<supports.size();i++)
|
||||
for (i=0;i<supports.size();i++)
|
||||
buf.Add(supports[i]);
|
||||
buf.End();
|
||||
|
||||
@ -940,11 +1007,12 @@ bool trpgLabel::Write(trpgWriteBuffer &buf)
|
||||
|
||||
bool trpgLabel::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
int numSupport,i;
|
||||
int numSupport,i;
|
||||
trpg3dPoint support;
|
||||
int iVal;
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
buf.Get(iVal);
|
||||
propertyId = iVal;
|
||||
buf.Get(text);
|
||||
@ -958,12 +1026,13 @@ bool trpgLabel::Read(trpgReadBuffer &buf)
|
||||
buf.Get(location);
|
||||
buf.Get(numSupport);
|
||||
if (numSupport < 0) throw 1;
|
||||
for (i=0;i<numSupport;i++) {
|
||||
for (i=0;i<numSupport;i++) {
|
||||
buf.Get(support);
|
||||
supports.push_back(support);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,9 +14,9 @@
|
||||
*/
|
||||
|
||||
/* trpage_main.cpp
|
||||
This file is here to provide a DLL Main.
|
||||
Note: #ifdef this out on non-windows machines
|
||||
*/
|
||||
This file is here to provide a DLL Main.
|
||||
Note: #ifdef this out on non-windows machines
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,21 +19,31 @@
|
||||
#include <deque>
|
||||
|
||||
/* This file contains class definitions for managers
|
||||
that help you keep track of data related to
|
||||
paging. For instance, which tiles to load
|
||||
in at any given time and what textures you need
|
||||
to read for a given tile.
|
||||
that help you keep track of data related to
|
||||
paging. For instance, which tiles to load
|
||||
in at any given time and what textures you need
|
||||
to read for a given tile.
|
||||
*/
|
||||
|
||||
class trpgPageManager;
|
||||
|
||||
// Grid and file location of a tile
|
||||
struct TileLocationInfo
|
||||
{
|
||||
TileLocationInfo(): x(-1), y(-1), lod(-1) {}
|
||||
TileLocationInfo(int gx, int gy, int glod, const trpgwAppAddress& gaddr): x(gx), y(gy), lod(glod), addr(gaddr) {}
|
||||
int x, y, lod;
|
||||
trpgwAppAddress addr;
|
||||
};
|
||||
|
||||
/* Managed Tiles are used by the trpgPageManager to keep
|
||||
track of which tiles are loaded and what textures (and
|
||||
models) they need loaded into memory with them.
|
||||
track of which tiles are loaded and what textures (and
|
||||
models) they need loaded into memory with them.
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL trpgManagedTile {
|
||||
friend class trpgPageManager;
|
||||
public:
|
||||
TX_EXDECL class TX_CLDECL trpgManagedTile
|
||||
{
|
||||
friend class trpgPageManager;
|
||||
public:
|
||||
trpgManagedTile(void);
|
||||
|
||||
// Called to clear any info out of this tile
|
||||
@ -43,41 +53,49 @@ public:
|
||||
Scene parser callback. The managed tile
|
||||
can then keep track of which textures and models
|
||||
go with this tile.
|
||||
*/
|
||||
*/
|
||||
bool ParseTileHeader(trpgReadBuffer &);
|
||||
|
||||
// Check if the tile is loaded (e.g. the header read in)
|
||||
bool IsLoaded(void);
|
||||
|
||||
/* Set the tile location. This resets any internal
|
||||
state we may be keeping.
|
||||
*/
|
||||
state we may be keeping.
|
||||
*/
|
||||
bool SetTileLoc(int x,int y,int lod);
|
||||
|
||||
// Get the tile location
|
||||
bool GetTileLoc(int &x,int &y,int &lod);
|
||||
bool GetTileLoc(int &x,int &y,int &lod) const;
|
||||
|
||||
// In version 2.1 we no longer have the tile table to
|
||||
// find the tiles, only by traversing the parent can it be
|
||||
// found. So when we have this info, this is were to save it.
|
||||
void SetTileAddress(const trpgwAppAddress& gAddr);
|
||||
void SetTileAddress(int32 file, int32 offset);
|
||||
const trpgwAppAddress& GetTileAddress() const;
|
||||
|
||||
|
||||
|
||||
// Return a pointer to the tile header
|
||||
const trpgTileHeader *GetTileHead(void);
|
||||
|
||||
/* Return a pointer to the list of locally defined
|
||||
materials. As soon as the tile header is read by
|
||||
ParseTileHeader (which you call) you'll want to get
|
||||
this list and load the pageable textures. You can
|
||||
use SetMatData to keep track of our internal texture
|
||||
structures.
|
||||
*/
|
||||
materials. As soon as the tile header is read by
|
||||
ParseTileHeader (which you call) you'll want to get
|
||||
this list and load the pageable textures. You can
|
||||
use SetMatData to keep track of our internal texture
|
||||
structures.
|
||||
*/
|
||||
const std::vector<trpgLocalMaterial> *GetLocMatList(void) const;
|
||||
|
||||
/* Returns a pointer to a single local material, if within
|
||||
the valid range of local materials for this tile.
|
||||
*/
|
||||
the valid range of local materials for this tile.
|
||||
*/
|
||||
const trpgLocalMaterial *GetLocMaterial(int id) const;
|
||||
|
||||
/* Set Local Data for managed tile. The local data would
|
||||
probably be a pointer to the top of the scene graph you're
|
||||
using to represent just this tile.
|
||||
*/
|
||||
probably be a pointer to the top of the scene graph you're
|
||||
using to represent just this tile.
|
||||
*/
|
||||
void SetLocalData(void *);
|
||||
|
||||
/* Returns the local data you set with SetLocalData.
|
||||
@ -85,25 +103,25 @@ public:
|
||||
void *GetLocalData(void) const;
|
||||
|
||||
/* Associates a void * with one of the materials referenced
|
||||
within this tile. The idea here is that you'll want
|
||||
to load the texture for a given local material and then
|
||||
pass your own internal texture structure into here as
|
||||
a void *. That way, the trpgPageManager will keep track
|
||||
of which textures you should unload when this tile goes
|
||||
out of range.
|
||||
*/
|
||||
within this tile. The idea here is that you'll want
|
||||
to load the texture for a given local material and then
|
||||
pass your own internal texture structure into here as
|
||||
a void *. That way, the trpgPageManager will keep track
|
||||
of which textures you should unload when this tile goes
|
||||
out of range.
|
||||
*/
|
||||
bool SetMatData(int id,void *);
|
||||
|
||||
/* Gets the void * data you associated with a given local
|
||||
material index. See SetMatData for more information.
|
||||
*/
|
||||
material index. See SetMatData for more information.
|
||||
*/
|
||||
void *GetMatData(int id) const;
|
||||
|
||||
/* Add Group ID to this tile. This is called by the page
|
||||
manager to keep track of which group IDs belong to this tile.
|
||||
We use this information to NULL out the appropriate positions
|
||||
in the group map help by the page manager.
|
||||
*/
|
||||
manager to keep track of which group IDs belong to this tile.
|
||||
We use this information to NULL out the appropriate positions
|
||||
in the group map help by the page manager.
|
||||
*/
|
||||
void AddGroupID(int id);
|
||||
|
||||
/* Retrieve the list of group IDs for this tile.
|
||||
@ -111,14 +129,28 @@ public:
|
||||
const std::vector<int> *GetGroupIDs(void) const;
|
||||
|
||||
/* Print the current status and information about this managed
|
||||
Tile.
|
||||
*/
|
||||
Tile.
|
||||
*/
|
||||
void Print(trpgPrintBuffer &);
|
||||
protected:
|
||||
|
||||
// Children info, will throw exception if child index is out of bound
|
||||
unsigned int GetNbChildren() const
|
||||
{
|
||||
return (unsigned int)childLocationInfo.size();
|
||||
}
|
||||
bool SetChildLocationInfo(int childIdx, int x, int y, const trpgwAppAddress& addr);
|
||||
bool SetChildLocationInfo(int childIdx, const TileLocationInfo& info);
|
||||
const TileLocationInfo& GetChildLocationInfo(int childIdx) const;
|
||||
bool GetChildTileLoc(int childIdx, int &x,int &y,int &lod) const;
|
||||
const trpgwAppAddress& GetChildTileAddress(int childIdx) const;
|
||||
|
||||
|
||||
protected:
|
||||
// Set if a tile is currently loaded
|
||||
bool isLoaded;
|
||||
// Tile location info
|
||||
int x,y,lod;
|
||||
TileLocationInfo location;
|
||||
|
||||
// Tile Header associated with this tile
|
||||
trpgTileHeader tileHead;
|
||||
// Data to keep associated with each individual local material index
|
||||
@ -128,194 +160,268 @@ protected:
|
||||
// Local data (probably the top of the local scene graph)
|
||||
void *localData;
|
||||
|
||||
// What are the children: this to be used for version 2.1 and up.
|
||||
// Both vector should have the same size
|
||||
std::vector<TileLocationInfo> childLocationInfo;
|
||||
|
||||
// Note: Should do models too if anyone wanted them.
|
||||
};
|
||||
|
||||
/* The Page Manager is a helper class that can be used
|
||||
to keep track of: (1) which tiles need to be loaded
|
||||
into memory for a given viewer position, (2) which tiles
|
||||
are currently loaded and (3) which tiles need to be unloaded
|
||||
when the viewer position moves. The tile list this
|
||||
class generates is guaranteed to be in the right order
|
||||
for loading. You would use this class if you're implementing
|
||||
a TerraPage reader for your visual run-time system.
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL trpgPageManager {
|
||||
public:
|
||||
to keep track of: (1) which tiles need to be loaded
|
||||
into memory for a given viewer position, (2) which tiles
|
||||
are currently loaded and (3) which tiles need to be unloaded
|
||||
when the viewer position moves. The tile list this
|
||||
class generates is guaranteed to be in the right order
|
||||
for loading. You would use this class if you're implementing
|
||||
a TerraPage reader for your visual run-time system.
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL trpgPageManager
|
||||
{
|
||||
public:
|
||||
trpgPageManager(void);
|
||||
virtual ~trpgPageManager(void);
|
||||
|
||||
// Initialize with an archive
|
||||
virtual void Init(trpgr_Archive *);
|
||||
virtual void Init(trpgr_Archive *inArch, int maxLod);
|
||||
|
||||
/* Set Paging Distance
|
||||
This is the extra distance outside the visible range
|
||||
we want to page. The defaults will be valid. You would
|
||||
set this if you want to pull tiles in earlier. Be sure
|
||||
to call it before you call Init(), however.
|
||||
*/
|
||||
This is the extra distance outside the visible range
|
||||
we want to page. The defaults will be valid. You would
|
||||
set this if you want to pull tiles in earlier. Be sure
|
||||
to call it before you call Init(), however.
|
||||
*/
|
||||
virtual bool SetPageDistFactor(double);
|
||||
|
||||
/* Updates the current location for paging purposes.
|
||||
Returns true if any load or unloads need to happen.
|
||||
*/
|
||||
Returns true if any load or unloads need to happen.
|
||||
*/
|
||||
virtual bool SetLocation(trpg2dPoint &);
|
||||
|
||||
/* Get next tile to load.
|
||||
The paging manager is keeping track of which tiles
|
||||
need to be loaded and in what order. This method
|
||||
returns a pointer to the next one. The user is
|
||||
expected to call AckLoad() after the tile is loaded.
|
||||
*/
|
||||
The paging manager is keeping track of which tiles
|
||||
need to be loaded and in what order. This method
|
||||
returns a pointer to the next one. The user is
|
||||
expected to call AckLoad() after the tile is loaded.
|
||||
*/
|
||||
virtual trpgManagedTile *GetNextLoad(void);
|
||||
/* Acknowledge Tile Load.
|
||||
This method should be called when a tile has been
|
||||
loaded by the caller. This method is used in conjunction
|
||||
with GetNextLoad().
|
||||
*/
|
||||
virtual void AckLoad(void);
|
||||
/* Acknowledge Tile Load.
|
||||
This method should be called when a tile has been
|
||||
loaded by the caller. This method is used in conjunction
|
||||
with GetNextLoad().
|
||||
|
||||
Version 2.1 and over supports variable lod so that we cannot know
|
||||
from the tile table if a tile exist or not. So to manage this
|
||||
the user must parse the loaded tile and extract its list of children
|
||||
and pass it on to AckLoad() which will add to the appropriate lod list
|
||||
the children info. If this is not done then only lod 0 will be pageable.
|
||||
*/
|
||||
|
||||
virtual void AckLoad(std::vector<TileLocationInfo> const& children);
|
||||
|
||||
// Using this call with version 2.1 and over will only page lod 0 tiles
|
||||
virtual void AckLoad();
|
||||
|
||||
/* Add Group ID to map.
|
||||
This should be called when the user encounters a group-like
|
||||
object while processing the scene graph data from a tile.
|
||||
The groupId is given by TerraPage and the data should be
|
||||
the corresponding group object that the user creates in
|
||||
their own scenegraph toolkit. This information can then
|
||||
be retrieved later by GetGroupData().
|
||||
*/
|
||||
This should be called when the user encounters a group-like
|
||||
object while processing the scene graph data from a tile.
|
||||
The groupId is given by TerraPage and the data should be
|
||||
the corresponding group object that the user creates in
|
||||
their own scenegraph toolkit. This information can then
|
||||
be retrieved later by GetGroupData().
|
||||
*/
|
||||
virtual void AddGroupID(trpgManagedTile *,int groupID,void *data);
|
||||
|
||||
/* Get Group Data fetches the data cached by the user and
|
||||
associated with the given groupID. This would be used in
|
||||
conjunction with trpgAttach nodes to implement geometry paging.
|
||||
*/
|
||||
associated with the given groupID. This would be used in
|
||||
conjunction with trpgAttach nodes to implement geometry paging.
|
||||
*/
|
||||
virtual void *GetGroupData(int groupID);
|
||||
|
||||
/* Get next tile to unload.
|
||||
The paging manager keeps track of which tiles need
|
||||
to be unloaded based on a change of location. It's
|
||||
best if you unload tiles before loading them, but
|
||||
that's really up to you.
|
||||
*/
|
||||
The paging manager keeps track of which tiles need
|
||||
to be unloaded based on a change of location. It's
|
||||
best if you unload tiles before loading them, but
|
||||
that's really up to you.
|
||||
*/
|
||||
virtual trpgManagedTile *GetNextUnload(void);
|
||||
/* Acknowledge a tile unload.
|
||||
You should call this after you've "unloaded" a tile
|
||||
and all its associated textures.
|
||||
*/
|
||||
You should call this after you've "unloaded" a tile
|
||||
and all its associated textures.
|
||||
*/
|
||||
virtual void AckUnload(void);
|
||||
|
||||
|
||||
/* Stop paging entirely. Call this right before you want to
|
||||
shut down paging. Everything active will wind up on the
|
||||
unload lists. Then you can unload those tiles and move on.
|
||||
*/
|
||||
shut down paging. Everything active will wind up on the
|
||||
unload lists. Then you can unload those tiles and move on.
|
||||
*/
|
||||
virtual bool Stop(void);
|
||||
|
||||
// Print current status and content information
|
||||
virtual void Print(trpgPrintBuffer &);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
trpgr_Archive *archive;
|
||||
|
||||
// Center of paging
|
||||
trpg2dPoint pagePt;
|
||||
|
||||
/* Information associated with each terrain level of
|
||||
detail as related to paging.
|
||||
*/
|
||||
class LodPageInfo {
|
||||
friend class trpgPageManager;
|
||||
detail as related to paging.
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL LodPageInfo {
|
||||
friend class trpgPageManager;
|
||||
public:
|
||||
LodPageInfo(void);
|
||||
virtual ~LodPageInfo(void);
|
||||
LodPageInfo(void);
|
||||
virtual ~LodPageInfo(void);
|
||||
|
||||
/* Initializes the class with its current LOD.
|
||||
It figures out all the rest.
|
||||
*/
|
||||
virtual bool Init(trpgr_Archive *, int myLod, double scale);
|
||||
/* Initializes the class with its current LOD.
|
||||
It figures out all the rest.
|
||||
*/
|
||||
virtual bool Init(trpgr_Archive *, int myLod, double scale, int freeListDivider = 1);
|
||||
|
||||
/* Reset the location. This forces a recalculation
|
||||
of what to load and unload if the cell has changed
|
||||
or if this is the first SetLocation.
|
||||
The location passed in must be relative to the southwest
|
||||
corner of the TerraPage archive.
|
||||
*/
|
||||
virtual bool SetLocation(trpg2dPoint &);
|
||||
/* Reset the location. This forces a recalculation
|
||||
of what to load and unload if the cell has changed
|
||||
or if this is the first SetLocation.
|
||||
The location passed in must be relative to the southwest
|
||||
corner of the TerraPage archive.
|
||||
*/
|
||||
virtual bool SetLocation(trpg2dPoint &);
|
||||
|
||||
// Return the next tile to load for this terrain lod
|
||||
virtual trpgManagedTile *GetNextLoad(void);
|
||||
// Acknowledge the load. Move the active tile to the
|
||||
// loaded list.
|
||||
virtual void AckLoad();
|
||||
|
||||
// Get the lsit of
|
||||
//bool GetLoadedTile
|
||||
|
||||
// Return the next tile to unload for this terrain lod
|
||||
virtual trpgManagedTile *GetNextUnload(void);
|
||||
// Acknowledge the unload. Move the active tile to the
|
||||
// free list.
|
||||
virtual void AckUnload(void);
|
||||
// Called to stop paging. Everything active is dumped on
|
||||
// the unload list.
|
||||
virtual bool Stop(void);
|
||||
// Print current status and content information
|
||||
virtual void Print(trpgPrintBuffer &);
|
||||
|
||||
const trpg2iPoint& GetLodSize() const
|
||||
{
|
||||
return lodSize;
|
||||
}
|
||||
|
||||
int GetLod() const
|
||||
{
|
||||
return lod;
|
||||
}
|
||||
|
||||
double GetPageDistance() const
|
||||
{
|
||||
return pageDist;
|
||||
}
|
||||
|
||||
const trpg2dPoint& GetCellSize() const
|
||||
{
|
||||
return cellSize;
|
||||
}
|
||||
|
||||
// The unit are cellSize
|
||||
const trpg2iPoint& GetAreaOfInterest() const
|
||||
{
|
||||
return aoiSize;
|
||||
}
|
||||
|
||||
|
||||
// The middle of this cell correspond to our paging
|
||||
// location
|
||||
const trpg2iPoint& GetCellPagingLocation() const
|
||||
{
|
||||
return cell;
|
||||
}
|
||||
|
||||
// Return the next tile to load for this terrain lod
|
||||
virtual trpgManagedTile *GetNextLoad(void);
|
||||
// Acknowledge the load. Move the active tile to the
|
||||
// loaded list.
|
||||
virtual void AckLoad(void);
|
||||
// Return the next tile to unload for this terrain lod
|
||||
virtual trpgManagedTile *GetNextUnload(void);
|
||||
// Acknowledge the unload. Move the active tile to the
|
||||
// free list.
|
||||
virtual void AckUnload(void);
|
||||
// Called to stop paging. Everything active is dumped on
|
||||
// the unload list.
|
||||
virtual bool Stop(void);
|
||||
// Print current status and content information
|
||||
virtual void Print(trpgPrintBuffer &);
|
||||
protected:
|
||||
virtual void Clean(void);
|
||||
virtual void Update(void);
|
||||
virtual void Clean(void);
|
||||
virtual void Update(void);
|
||||
|
||||
// Check if the given tile is within the area we care about
|
||||
bool isWithin(trpgManagedTile *,trpg2iPoint &sw,trpg2iPoint &ne);
|
||||
// Add to the load list the given tile if it is within the proper
|
||||
// bound
|
||||
bool AddToLoadList(int x, int y, const trpgwAppAddress& addr);
|
||||
|
||||
bool valid;
|
||||
// Add the children of the given parent list
|
||||
// to the load list if it it not already loaded
|
||||
// or if it is not already in the list
|
||||
void AddChildrenToLoadList(std::vector<trpgManagedTile*>& parentList);
|
||||
|
||||
// Terrain LOD we're responsible for
|
||||
int lod;
|
||||
// Check if the given tile is within the area we care about
|
||||
bool isWithin(trpgManagedTile *,trpg2iPoint &sw,trpg2iPoint &ne);
|
||||
|
||||
/* Adjusted (e.g. paranoid) distance outward from
|
||||
which to page this terrain LOD. This takes into
|
||||
account the distance in the header as well as
|
||||
any factor the user may have added.
|
||||
*/
|
||||
double pageDist;
|
||||
// Get the list of currently loaded tiles that fall within
|
||||
// the region calculated from the given paging distance.
|
||||
void GetLoadedTileWithin(double pagingDistance, std::vector<trpgManagedTile*>& tileList);
|
||||
|
||||
/* Max tiles we could have loaded in at any given time.
|
||||
This is just a guess because it's up to the user
|
||||
to load (and, more importantly) unload.
|
||||
*/
|
||||
int maxNumTiles;
|
||||
bool valid;
|
||||
|
||||
// Size of a single cell. Copied from the archive.
|
||||
trpg2dPoint cellSize;
|
||||
// Terrain LOD we're responsible for
|
||||
int lod;
|
||||
|
||||
// Number of tiles (cells) in each direction
|
||||
trpg2iPoint lodSize;
|
||||
/* Adjusted (e.g. paranoid) distance outward from
|
||||
which to page this terrain LOD. This takes into
|
||||
account the distance in the header as well as
|
||||
any factor the user may have added.
|
||||
*/
|
||||
double pageDist;
|
||||
|
||||
/* Area of interest size in cells
|
||||
This is a linear distance "ahead" of the center cell.
|
||||
*/
|
||||
trpg2iPoint aoiSize;
|
||||
/* Max tiles we could have loaded in at any given time.
|
||||
This is just a guess because it's up to the user
|
||||
to load (and, more importantly) unload.
|
||||
*/
|
||||
int maxNumTiles;
|
||||
|
||||
/* Our effective paging location sits at the middle
|
||||
of this cell. We don't recalculate unless the
|
||||
cell changes. */
|
||||
trpg2iPoint cell;
|
||||
// Size of a single cell. Copied from the archive.
|
||||
trpg2dPoint cellSize;
|
||||
|
||||
// List of tiles to load
|
||||
std::deque<trpgManagedTile *> load;
|
||||
// List of tiles to unload
|
||||
std::deque<trpgManagedTile *> unload;
|
||||
// List of currently loaded tiles
|
||||
std::deque<trpgManagedTile *> current;
|
||||
// Number of tiles (cells) in each direction
|
||||
trpg2iPoint lodSize;
|
||||
|
||||
// Used by Update. Here because we want to avoid memory allocs, if possible.
|
||||
std::vector<bool> tmpCurrent;
|
||||
/* Area of interest size in cells
|
||||
This is a linear distance "ahead" of the center cell.
|
||||
*/
|
||||
trpg2iPoint aoiSize;
|
||||
|
||||
// Set if a load is in progress
|
||||
// Load w/o ACK
|
||||
bool activeLoad;
|
||||
// Set if an unload is in progress
|
||||
// Unload w/o ACK
|
||||
bool activeUnload;
|
||||
/* Our effective paging location sits at the middle
|
||||
of this cell. We don't recalculate unless the
|
||||
cell changes. */
|
||||
trpg2iPoint cell;
|
||||
|
||||
// List of tile pointers we can reuse
|
||||
std::deque<trpgManagedTile *> freeList;
|
||||
// List of tiles to load
|
||||
std::deque<trpgManagedTile *> load;
|
||||
// List of tiles to unload
|
||||
std::deque<trpgManagedTile *> unload;
|
||||
// List of currently loaded tiles
|
||||
std::deque<trpgManagedTile *> current;
|
||||
|
||||
// Used by Update. Here because we want to avoid memory allocs, if possible.
|
||||
std::vector<bool> tmpCurrent;
|
||||
|
||||
// Set if a load is in progress
|
||||
// Load w/o ACK
|
||||
bool activeLoad;
|
||||
// Set if an unload is in progress
|
||||
// Unload w/o ACK
|
||||
bool activeUnload;
|
||||
|
||||
// List of tile pointers we can reuse
|
||||
std::deque<trpgManagedTile *> freeList;
|
||||
|
||||
// TerraPage version
|
||||
int majorVersion, minorVersion;
|
||||
|
||||
const trpgTileTable *tileTable;
|
||||
};
|
||||
|
||||
// Per terrain lod paging information
|
||||
@ -324,8 +430,8 @@ protected:
|
||||
// Enumerated type for lastLoad
|
||||
typedef enum {Load,Unload,None} LoadType;
|
||||
/* Information about what the pending load/unload operation
|
||||
is. It's up to the user to complete and acknowledge it.
|
||||
*/
|
||||
is. It's up to the user to complete and acknowledge it.
|
||||
*/
|
||||
LoadType lastLoad;
|
||||
// LOD for the pending load/unload requested operation
|
||||
int lastLod;
|
||||
@ -339,40 +445,80 @@ protected:
|
||||
typedef std::map<int,void *> ManageGroupMap;
|
||||
ManageGroupMap groupMap;
|
||||
|
||||
// Terrapge Version
|
||||
int majorVersion, minorVersion;
|
||||
|
||||
bool valid;
|
||||
};
|
||||
|
||||
// For Version 2.1 an over, the tile table only contains
|
||||
// tiles of lod 0. To get access the other tiles, parent tile
|
||||
// must be parsed to get at trpgChildRef nodes that will contain
|
||||
// location info about the children. This callback can be use to
|
||||
// parse the tile data. After parsing the callback object will contain
|
||||
// the list of trpgChildRef nodes found.
|
||||
TX_EXDECL class TX_CLDECL trpgr_ChildRefCB : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
void *Parse(trpgToken tok, trpgReadBuffer& rbuf);
|
||||
// After parsing this will return the number of trpgChildRef node found.
|
||||
unsigned int GetNbChildren() const;
|
||||
// This will return the trpgChildRef node associated with the index.
|
||||
// Will throw an exception if the index is out of bound
|
||||
const trpgChildRef& GetChildRef(unsigned int idx) const;
|
||||
|
||||
// Clear the children list
|
||||
void Reset();
|
||||
protected:
|
||||
// typedef std::vector<const trpgChildRef> ChildList;
|
||||
// The const in the template parameter was removed because it causes GCC to
|
||||
// freak out. I am of the opinion that const doesn't make sense in a template
|
||||
// parameter for std::vector anyway... const prevents you from changing the
|
||||
// value, so what exactly is the point? How does one add entries to the vector
|
||||
// without giving them a value? -ADS
|
||||
typedef std::vector<trpgChildRef> ChildList;
|
||||
ChildList childList;
|
||||
};
|
||||
|
||||
/* Page Manager Tester. This class tests a given paging manager
|
||||
by applying likely
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL trpgPageManageTester {
|
||||
public:
|
||||
by applying likely
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL trpgPageManageTester
|
||||
{
|
||||
public:
|
||||
trpgPageManageTester();
|
||||
virtual ~trpgPageManageTester();
|
||||
|
||||
/* Initialize the tester with a paging manager
|
||||
and an archive.
|
||||
*/
|
||||
and an archive.
|
||||
*/
|
||||
void Init(trpgPrintBuffer *,trpgPageManager *,trpgr_Archive *);
|
||||
|
||||
/* Feeds the paging manager coordinates starting from
|
||||
the lower left to upper right of the database in the
|
||||
given increment.
|
||||
*/
|
||||
the lower left to upper right of the database in the
|
||||
given increment.
|
||||
*/
|
||||
void Fly_LL_to_UR(double dist=100.0);
|
||||
|
||||
/* Jumps around randomly within the archive loading and
|
||||
unloading as needed.
|
||||
*/
|
||||
unloading as needed.
|
||||
*/
|
||||
void RandomTest(int no=100,int seed=-1);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
// Does the work of "load" and "unloading"
|
||||
void ProcessChanges();
|
||||
|
||||
trpgPageManager *manager;
|
||||
trpgr_Archive *archive;
|
||||
trpgPrintBuffer *printBuf;
|
||||
|
||||
trpgr_ChildRefCB childRefCB;
|
||||
trpgr_Parser tileParser;
|
||||
|
||||
// TerraPage version
|
||||
int majorVersion, minorVersion;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,204 +17,280 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_mode.cpp
|
||||
This source file contains the methods trpgModel and trpgModelTable.
|
||||
You should only modify this code if you want to add data to these classes.
|
||||
*/
|
||||
#define OLDMODELSTYLE
|
||||
|
||||
/* trpage_model.cpp
|
||||
This source file contains the methods trpgModel and trpgModelTable.
|
||||
You should only modify this code if you want to add data to these classes.
|
||||
*/
|
||||
|
||||
#include <trpage_geom.h>
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* Write Model class
|
||||
Represents a model reference.
|
||||
*/
|
||||
Represents a model reference.
|
||||
*/
|
||||
trpgModel::trpgModel()
|
||||
{
|
||||
name = NULL;
|
||||
type = External;
|
||||
useCount = 0;
|
||||
name = NULL;
|
||||
type = External;
|
||||
useCount = 0;
|
||||
diskRef = -1;
|
||||
handle = -1;
|
||||
writeHandle = false;
|
||||
}
|
||||
|
||||
trpgModel::trpgModel(const trpgModel &in):
|
||||
trpgReadWriteable(in)
|
||||
{
|
||||
name = NULL;
|
||||
type = External;
|
||||
*this = in;
|
||||
if (in.name)
|
||||
{
|
||||
name = new char[strlen(in.name)+1];
|
||||
strcpy(name,in.name);
|
||||
}
|
||||
else
|
||||
name = NULL;
|
||||
|
||||
type=in.type;
|
||||
useCount=in.useCount;
|
||||
diskRef=in.diskRef;
|
||||
handle = in.handle;
|
||||
writeHandle = in.writeHandle;
|
||||
}
|
||||
|
||||
|
||||
// Reset function
|
||||
void trpgModel::Reset()
|
||||
{
|
||||
if (name)
|
||||
delete [] name;
|
||||
name = NULL;
|
||||
useCount = 0;
|
||||
if (name)
|
||||
delete [] name;
|
||||
name = NULL;
|
||||
useCount = 0;
|
||||
diskRef = -1;
|
||||
handle = -1;
|
||||
writeHandle = false;
|
||||
}
|
||||
|
||||
trpgModel::~trpgModel()
|
||||
{
|
||||
Reset();
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Set functions
|
||||
void trpgModel::SetType(int t)
|
||||
{
|
||||
type = t;
|
||||
}
|
||||
|
||||
void trpgModel::SetName(const char *nm)
|
||||
{
|
||||
if (name)
|
||||
delete [] name;
|
||||
if (name)
|
||||
delete [] name;
|
||||
|
||||
name = new char[(nm ? strlen(nm) : 0)+1];
|
||||
strcpy(name,nm);
|
||||
|
||||
type = External;
|
||||
if (nm)
|
||||
{
|
||||
name = new char[(nm ? strlen(nm) : 0)+1];
|
||||
strcpy(name,nm);
|
||||
}
|
||||
}
|
||||
void trpgModel::SetReference(trpgDiskRef pos)
|
||||
{
|
||||
if (name)
|
||||
delete [] name;
|
||||
|
||||
diskRef = pos;
|
||||
|
||||
type = Local;
|
||||
diskRef = pos;
|
||||
}
|
||||
void trpgModel::SetNumTiles(int num)
|
||||
{
|
||||
useCount = num;
|
||||
useCount = num;
|
||||
}
|
||||
void trpgModel::AddTile()
|
||||
{
|
||||
useCount++;
|
||||
useCount++;
|
||||
}
|
||||
|
||||
// Validity check
|
||||
bool trpgModel::isValid() const
|
||||
{
|
||||
if (type == External && !name)
|
||||
{
|
||||
strcpy(errMess, "Model is external with no name");
|
||||
return false;
|
||||
}
|
||||
if (type == External && !name)
|
||||
{
|
||||
strcpy(errMess, "Model is external with no name");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy from one to another
|
||||
trpgModel& trpgModel::operator = (const trpgModel &in)
|
||||
{
|
||||
if (name) {
|
||||
delete [] name;
|
||||
name = NULL;
|
||||
}
|
||||
if (name) {
|
||||
delete [] name;
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
type = in.type;
|
||||
if (in.name)
|
||||
SetName(in.name);
|
||||
diskRef = in.diskRef;
|
||||
useCount = in.useCount;
|
||||
|
||||
return *this;
|
||||
type = in.type;
|
||||
if (in.name)
|
||||
SetName(in.name);
|
||||
diskRef = in.diskRef;
|
||||
useCount = in.useCount;
|
||||
writeHandle = in.writeHandle;
|
||||
handle = in.handle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Compare two models
|
||||
int trpgModel::operator == (const trpgModel &in) const
|
||||
{
|
||||
if (type != in.type)
|
||||
return 0;
|
||||
if (type != in.type)
|
||||
return 0;
|
||||
|
||||
switch (type) {
|
||||
case Local:
|
||||
if (diskRef == in.diskRef)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case External:
|
||||
if (!name && !in.name)
|
||||
return 1;
|
||||
if (!name || !in.name)
|
||||
return 0;
|
||||
if (strcmp(name,in.name))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
switch (type) {
|
||||
case Local:
|
||||
if (diskRef == in.diskRef)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case External:
|
||||
if (!name && !in.name)
|
||||
return 1;
|
||||
if (!name || !in.name)
|
||||
return 0;
|
||||
if (strcmp(name,in.name))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Write a model reference out
|
||||
bool trpgModel::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGMODELREF);
|
||||
buf.Add(type);
|
||||
if (name)
|
||||
buf.Add(name);
|
||||
else
|
||||
// We will use two different tokens to track the
|
||||
// format used in terrapage 2.2, and older versions
|
||||
int tok = TRPGMODELREF;
|
||||
if(writeHandle)
|
||||
tok = TRPGMODELREF2;
|
||||
|
||||
// Nick messed up the model entries when checking into txv4; now we're
|
||||
// a bit stuck because U3 dbs don't have models in the U2 viewer.
|
||||
// This will force the old behavior.
|
||||
#ifdef OLDMODELSTYLE
|
||||
buf.Begin(tok);
|
||||
buf.Add(type);
|
||||
//writeHandle is only set for terrapage 2.2, and we use the different token.
|
||||
if(writeHandle) {
|
||||
buf.Add((int)handle);
|
||||
}
|
||||
if (name)
|
||||
buf.Add(name);
|
||||
else
|
||||
buf.Add(diskRef);
|
||||
buf.Add(useCount);
|
||||
buf.Add(useCount);
|
||||
|
||||
buf.End();
|
||||
#else
|
||||
buf.Begin(tok);
|
||||
if(writeHandle) {
|
||||
buf.Add((int)handle);
|
||||
}
|
||||
buf.Add(type);
|
||||
buf.Add(name);
|
||||
buf.Add(diskRef);
|
||||
buf.Add(useCount);
|
||||
#endif
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* *******************
|
||||
Model Read Methods
|
||||
*******************
|
||||
*/
|
||||
/* *******************
|
||||
Model Read Methods
|
||||
*******************
|
||||
*/
|
||||
// Get methods
|
||||
bool trpgModel::GetType(int &t)
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
t = type;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
t = type;
|
||||
return true;
|
||||
}
|
||||
bool trpgModel::GetName(char *str,int strLen) const
|
||||
{
|
||||
if (!isValid() || type != External) return false;
|
||||
int len = (name ? strlen(name) : 0);
|
||||
strncpy(str,name,MIN(len,strLen)+1);
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
int len = (name ? strlen(name) : 0);
|
||||
strncpy(str,name,MIN(len,strLen)+1);
|
||||
return true;
|
||||
}
|
||||
bool trpgModel::GetNumTiles(int &ret) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid()) return false;
|
||||
|
||||
ret = useCount;
|
||||
return true;
|
||||
ret = useCount;
|
||||
return true;
|
||||
}
|
||||
bool trpgModel::GetReference(trpgDiskRef &ref) const
|
||||
{
|
||||
if (!isValid() || type != Local) return false;
|
||||
ref = diskRef;
|
||||
return true;
|
||||
if (!isValid() || type != Local) return false;
|
||||
ref = diskRef;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgModel::Read(trpgReadBuffer &buf)
|
||||
bool trpgModel::Read(trpgReadBuffer &buf, bool hasHandle)
|
||||
{
|
||||
char tmpName[1024];
|
||||
// MD: added complexity here - written multiple ways by
|
||||
// mistake, unraveling the various cases.
|
||||
char tmpName[1024];
|
||||
|
||||
try {
|
||||
buf.Get(type);
|
||||
if (type == Local)
|
||||
buf.Get(diskRef);
|
||||
else {
|
||||
buf.Get(tmpName,1023);
|
||||
SetName(tmpName);
|
||||
}
|
||||
buf.Get(useCount);
|
||||
}
|
||||
catch(...) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
buf.Get(type);
|
||||
// TerraPage 2.2 will store the unique handle after the type
|
||||
// we use a different token, so this is backwards compatible.
|
||||
if(hasHandle) {
|
||||
buf.Get((int32 &)handle);
|
||||
}
|
||||
else
|
||||
handle = -1;
|
||||
if (type == Local) {
|
||||
// two possibilities:
|
||||
// name, diskRef, useCount
|
||||
// diskRef, useCount
|
||||
// diskRef + useCount = 12 bytes...
|
||||
if (buf.TestLimit(13))
|
||||
{
|
||||
buf.Get(tmpName,1023);
|
||||
SetName(tmpName);
|
||||
}
|
||||
buf.Get(diskRef);
|
||||
buf.Get(useCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
// two possibilities:
|
||||
// name, diskRef, useCount
|
||||
// name, useCount
|
||||
buf.Get(tmpName,1023);
|
||||
SetName(tmpName);
|
||||
// useCount = 4 bytes...
|
||||
if (buf.TestLimit(5))
|
||||
buf.Get(diskRef);
|
||||
buf.Get(useCount);
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
// going to make this fail if the buffer isn't empty.
|
||||
if (buf.TestLimit(1)) return false;
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* Write Model Reference table
|
||||
Groups of models for the entire file.
|
||||
*/
|
||||
Groups of models for the entire file.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgModelTable::trpgModelTable()
|
||||
@ -227,50 +303,73 @@ trpgModelTable::~trpgModelTable()
|
||||
// Reset function
|
||||
void trpgModelTable::Reset()
|
||||
{
|
||||
models.resize(0);
|
||||
modelsMap.clear();
|
||||
}
|
||||
|
||||
// Set functions
|
||||
void trpgModelTable::SetNumModels(int no)
|
||||
void trpgModelTable::SetNumModels(int /*no*/)
|
||||
{
|
||||
models.resize(no);
|
||||
// This method isn't needed with a map
|
||||
//models.resize(no);
|
||||
}
|
||||
void trpgModelTable::SetModel(int id,const trpgModel &mod)
|
||||
{
|
||||
if (id < 0 || (unsigned int)id >= models.size())
|
||||
return;
|
||||
if (id < 0)
|
||||
return;
|
||||
|
||||
models[id] = mod;
|
||||
modelsMap[id] = mod;
|
||||
//models[id] = mod;
|
||||
}
|
||||
int trpgModelTable::AddModel(const trpgModel &mod)
|
||||
{
|
||||
models.push_back(mod);
|
||||
|
||||
return models.size()-1;
|
||||
int trpgModelTable::AddModel(trpgModel &mod)
|
||||
{
|
||||
int hdl = modelsMap.size();
|
||||
if(mod.GetHandle()==-1) {
|
||||
modelsMap[hdl] = mod;
|
||||
return hdl;
|
||||
}
|
||||
modelsMap[mod.GetHandle()] = mod;
|
||||
return mod.GetHandle();
|
||||
}
|
||||
int trpgModelTable::FindAddModel(const trpgModel &mod)
|
||||
{
|
||||
for (unsigned int i=0;i<models.size();i++)
|
||||
if (models[i] == mod)
|
||||
return i;
|
||||
|
||||
return AddModel(mod);
|
||||
int trpgModelTable::FindAddModel(trpgModel &mod)
|
||||
{
|
||||
|
||||
ModelMapType::iterator itr = modelsMap.begin();
|
||||
for ( ; itr != modelsMap.end( ); itr++) {
|
||||
if(itr->second == mod) {
|
||||
return itr->first;
|
||||
}
|
||||
}
|
||||
return AddModel(mod);
|
||||
}
|
||||
|
||||
bool trpgModelTable::FindByName(const char *name, unsigned int &mId)
|
||||
{
|
||||
ModelMapType::const_iterator itr = modelsMap.begin();
|
||||
for ( ; itr != modelsMap.end( ); itr++) {
|
||||
char theName[1023];
|
||||
itr->second.GetName(theName,1023);
|
||||
if(strcmp(name,theName)==0) {
|
||||
mId = itr->first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validity check
|
||||
bool trpgModelTable::isValid() const
|
||||
{
|
||||
for (unsigned int i=0;i<models.size();i++)
|
||||
{
|
||||
if (!models[i].isValid())
|
||||
{
|
||||
if(models[i].getErrMess())
|
||||
strcpy(errMess, models[i].getErrMess());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
ModelMapType::const_iterator itr = modelsMap.begin();
|
||||
for ( ; itr != modelsMap.end( ); itr++) {
|
||||
if(!itr->second.isValid()) {
|
||||
if(itr->second.getErrMess())
|
||||
strcpy(errMess, itr->second.getErrMess());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -278,67 +377,85 @@ bool trpgModelTable::isValid() const
|
||||
// Write out the model table
|
||||
bool trpgModelTable::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGMODELTABLE);
|
||||
buf.Add((int32)models.size());
|
||||
for (unsigned int i=0;i<models.size();i++)
|
||||
models[i].Write(buf);
|
||||
buf.End();
|
||||
buf.Begin(TRPGMODELTABLE);
|
||||
buf.Add((int32)modelsMap.size());
|
||||
ModelMapType::iterator itr = modelsMap.begin();
|
||||
for ( ; itr != modelsMap.end( ); itr++) {
|
||||
itr->second.Write(buf);
|
||||
}
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ***************
|
||||
Model Table Read methods
|
||||
***************
|
||||
*/
|
||||
/* ***************
|
||||
Model Table Read methods
|
||||
***************
|
||||
*/
|
||||
|
||||
// Get methods
|
||||
bool trpgModelTable::GetNumModels(int &nm) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
nm = models.size();
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
nm = modelsMap.size();
|
||||
return true;
|
||||
}
|
||||
bool trpgModelTable::GetModel(int id,trpgModel &model) const
|
||||
{
|
||||
if (!isValid() || id < 0 || id >= (int)models.size())
|
||||
return false;
|
||||
model = models[id];
|
||||
return true;
|
||||
if (!isValid() || id < 0 ) //|| id >= models.size())
|
||||
return false;
|
||||
//model = models[id];
|
||||
ModelMapType::const_iterator itr = modelsMap.find(id);
|
||||
if(itr == modelsMap.end()) {
|
||||
return false;
|
||||
}
|
||||
model = itr->second;
|
||||
return true;
|
||||
}
|
||||
trpgModel *trpgModelTable::GetModelRef(int id)
|
||||
{
|
||||
if (id < 0 || id >= (int)models.size())
|
||||
return NULL;
|
||||
return &models[id];
|
||||
if (id < 0 ) //|| id >= models.size())
|
||||
return NULL;
|
||||
//return &models[id];
|
||||
ModelMapType::iterator itr = modelsMap.find(id);
|
||||
if(itr == modelsMap.end()) {
|
||||
return false;
|
||||
}
|
||||
return &(itr->second);
|
||||
}
|
||||
|
||||
bool trpgModelTable::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
int32 numModel;
|
||||
trpgModel model;
|
||||
trpgToken tok;
|
||||
int32 len;
|
||||
bool status;
|
||||
int32 numModel;
|
||||
trpgToken tok;
|
||||
int32 len;
|
||||
bool status;
|
||||
|
||||
try {
|
||||
buf.Get(numModel);
|
||||
for (int i=0;i<numModel;i++) {
|
||||
buf.GetToken(tok,len);
|
||||
if (tok != TRPGMODELREF) throw 1;
|
||||
buf.PushLimit(len);
|
||||
status = model.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
models.push_back(model);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
buf.Get(numModel);
|
||||
for (int i=0;i<numModel;i++) {
|
||||
trpgModel model;
|
||||
buf.GetToken(tok,len);
|
||||
bool readHandle;
|
||||
if (tok == TRPGMODELREF)
|
||||
readHandle = false;
|
||||
else if (tok == TRPGMODELREF2)
|
||||
readHandle = true;
|
||||
else
|
||||
throw 1;
|
||||
buf.PushLimit(len);
|
||||
status = model.Read(buf,readHandle);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
AddModel(model);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
return isValid();
|
||||
}
|
||||
|
@ -18,18 +18,18 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_nodes.cpp
|
||||
The methods for all the hierarchy nodes (e.g. groups, transforms, etc...)
|
||||
is here.
|
||||
You should only need to modify this if you want to add something to one
|
||||
of these classes.
|
||||
*/
|
||||
The methods for all the hierarchy nodes (e.g. groups, transforms, etc...)
|
||||
is here.
|
||||
You should only need to modify this if you want to add something to one
|
||||
of these classes.
|
||||
*/
|
||||
|
||||
#include <trpage_geom.h>
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* Write Group
|
||||
Basic group.
|
||||
*/
|
||||
Basic group.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgGroup::trpgGroup()
|
||||
@ -49,8 +49,8 @@ void trpgGroup::Reset()
|
||||
numChild = 0;
|
||||
id = -1;
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,15 +71,18 @@ void trpgGroup::SetID(int inID)
|
||||
|
||||
void trpgGroup::SetName(const char* newname )
|
||||
{
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
if ( name )
|
||||
{
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
if (newname) {
|
||||
if ( strlen(newname) ) {
|
||||
name = new char[strlen(newname)+1];
|
||||
strcpy(name,newname);
|
||||
}
|
||||
if (newname)
|
||||
{
|
||||
if ( strlen(newname) )
|
||||
{
|
||||
name = new char[strlen(newname)+1];
|
||||
strcpy(name,newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,14 +118,14 @@ bool trpgGroup::isValid() const
|
||||
bool trpgGroup::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPG_GROUP);
|
||||
buf.Add(numChild);
|
||||
buf.Add(id);
|
||||
|
||||
if ( name && strlen(name) ) {
|
||||
buf.Add(name);
|
||||
buf.Add(name);
|
||||
}
|
||||
|
||||
buf.End();
|
||||
@ -134,27 +137,27 @@ bool trpgGroup::Write(trpgWriteBuffer &buf)
|
||||
bool trpgGroup::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Get(numChild);
|
||||
if (numChild < 0) throw 1;
|
||||
buf.Get(id);
|
||||
if (id < 0) throw 1;
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
buf.Get(numChild);
|
||||
if (numChild < 0) throw 1;
|
||||
buf.Get(id);
|
||||
if (id < 0) throw 1;
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* Write Billboard
|
||||
Represents rotational billboarded geometry.
|
||||
*/
|
||||
Represents rotational billboarded geometry.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgBillboard::trpgBillboard()
|
||||
@ -176,9 +179,10 @@ void trpgBillboard::Reset()
|
||||
axis = trpg3dPoint(0,0,1);
|
||||
center = trpg3dPoint(0,0,0);
|
||||
numChild = 0;
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
if ( name )
|
||||
{
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +235,7 @@ bool trpgBillboard::GetType(int &t) const
|
||||
bool trpgBillboard::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPG_BILLBOARD);
|
||||
buf.Add(numChild);
|
||||
@ -242,7 +246,7 @@ bool trpgBillboard::Write(trpgWriteBuffer &buf)
|
||||
buf.Add(axis);
|
||||
|
||||
if ( name && strlen(name) ) {
|
||||
buf.Add(name);
|
||||
buf.Add(name);
|
||||
}
|
||||
buf.End();
|
||||
|
||||
@ -255,28 +259,28 @@ bool trpgBillboard::Read(trpgReadBuffer &buf)
|
||||
uint8 uChar;
|
||||
|
||||
try {
|
||||
buf.Get(numChild);
|
||||
buf.Get(id);
|
||||
buf.Get(uChar); type = uChar;
|
||||
buf.Get(uChar); mode = uChar;
|
||||
buf.Get(center);
|
||||
buf.Get(axis);
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
buf.Get(numChild);
|
||||
buf.Get(id);
|
||||
buf.Get(uChar); type = uChar;
|
||||
buf.Get(uChar); mode = uChar;
|
||||
buf.Get(center);
|
||||
buf.Get(axis);
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* Write Level of Detail
|
||||
Represents LOD information.
|
||||
*/
|
||||
Represents LOD information.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgLod::trpgLod()
|
||||
@ -299,8 +303,8 @@ void trpgLod::Reset()
|
||||
rangeIndex = -1;
|
||||
valid = true;
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,7 +317,7 @@ void trpgLod::SetCenter(const trpg3dPoint &pt)
|
||||
void trpgLod::SetNumChild(int no)
|
||||
{
|
||||
if (no < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
numRange = no;
|
||||
}
|
||||
@ -331,14 +335,14 @@ void trpgLod::SetID(int inID)
|
||||
void trpgLod::SetName(const char* newname )
|
||||
{
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
if (newname) {
|
||||
if ( strlen(newname) ) {
|
||||
name = new char[strlen(newname)+1];
|
||||
strcpy(name,newname);
|
||||
}
|
||||
if ( strlen(newname) ) {
|
||||
name = new char[strlen(newname)+1];
|
||||
strcpy(name,newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,7 +397,7 @@ bool trpgLod::GetRangeIndex(int &ri) const
|
||||
bool trpgLod::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPG_LOD);
|
||||
buf.Add(id);
|
||||
@ -404,9 +408,9 @@ bool trpgLod::Write(trpgWriteBuffer &buf)
|
||||
buf.Add(width);
|
||||
|
||||
if ( name && strlen(name) ) {
|
||||
buf.Add(name);
|
||||
buf.Add(name);
|
||||
} else
|
||||
buf.Add("");
|
||||
buf.Add("");
|
||||
|
||||
|
||||
buf.End();
|
||||
@ -418,33 +422,33 @@ bool trpgLod::Write(trpgWriteBuffer &buf)
|
||||
bool trpgLod::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Get(id);
|
||||
buf.Get(numRange);
|
||||
if (numRange < 0) throw 1;
|
||||
buf.Get(center);
|
||||
buf.Get(switchIn);
|
||||
buf.Get(switchOut);
|
||||
buf.Get(width);
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
if (*nm)
|
||||
SetName(nm);
|
||||
// Look for a range index
|
||||
if (!buf.isEmpty())
|
||||
buf.Get(rangeIndex);
|
||||
}
|
||||
buf.Get(id);
|
||||
buf.Get(numRange);
|
||||
if (numRange < 0) throw 1;
|
||||
buf.Get(center);
|
||||
buf.Get(switchIn);
|
||||
buf.Get(switchOut);
|
||||
buf.Get(width);
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
if (*nm)
|
||||
SetName(nm);
|
||||
// Look for a range index
|
||||
if (!buf.isEmpty())
|
||||
buf.Get(rangeIndex);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* Write Layer
|
||||
A layer is just a group with a different opcode.
|
||||
*/
|
||||
A layer is just a group with a different opcode.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgLayer::trpgLayer()
|
||||
@ -461,17 +465,17 @@ trpgLayer::~trpgLayer()
|
||||
bool trpgLayer::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPG_LAYER);
|
||||
buf.Add(numChild);
|
||||
buf.Add(id);
|
||||
|
||||
if ( name && strlen(name) ) {
|
||||
buf.Add(name);
|
||||
buf.Add(name);
|
||||
}
|
||||
|
||||
buf.End();
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -480,18 +484,18 @@ bool trpgLayer::Write(trpgWriteBuffer &buf)
|
||||
bool trpgLayer::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Get(numChild);
|
||||
if (numChild < 0) throw 1;
|
||||
buf.Get(id);
|
||||
if (id < 0) throw 1;
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
buf.Get(numChild);
|
||||
if (numChild < 0) throw 1;
|
||||
buf.Get(id);
|
||||
if (id < 0) throw 1;
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
@ -502,14 +506,14 @@ void trpgLayer::Reset()
|
||||
{
|
||||
numChild = 0;
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write Transform
|
||||
Matrix defining the transform with children.
|
||||
*/
|
||||
Matrix defining the transform with children.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgTransform::trpgTransform()
|
||||
@ -533,8 +537,8 @@ void trpgTransform::Reset()
|
||||
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
|
||||
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,9 +556,9 @@ bool trpgTransform::GetMatrix(float64 *rm) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
// Note: is this right?
|
||||
rm[i*4+j] = m[i][j];
|
||||
for (int j=0;j<4;j++)
|
||||
// Note: is this right?
|
||||
rm[i*4+j] = m[i][j];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -562,17 +566,17 @@ bool trpgTransform::GetMatrix(float64 *rm) const
|
||||
bool trpgTransform::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPG_TRANSFORM);
|
||||
buf.Add(numChild);
|
||||
buf.Add(id);
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Add(m[i][j]);
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Add(m[i][j]);
|
||||
|
||||
if ( name && strlen(name) ) {
|
||||
buf.Add(name);
|
||||
buf.Add(name);
|
||||
}
|
||||
buf.End();
|
||||
|
||||
@ -583,28 +587,28 @@ bool trpgTransform::Write(trpgWriteBuffer &buf)
|
||||
bool trpgTransform::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Get(numChild);
|
||||
buf.Get(id);
|
||||
if (numChild < 0) throw 1;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Get(m[i][j]);
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
buf.Get(numChild);
|
||||
buf.Get(id);
|
||||
if (numChild < 0) throw 1;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Get(m[i][j]);
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* Model Reference
|
||||
This is just a matrix transform and a model ID.
|
||||
*/
|
||||
This is just a matrix transform and a model ID.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgModelRef::trpgModelRef()
|
||||
@ -650,9 +654,9 @@ bool trpgModelRef::GetMatrix(float64 *rm) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
// Note: is this right?
|
||||
rm[i*4+j] = m[i][j];
|
||||
for (int j=0;j<4;j++)
|
||||
// Note: is this right?
|
||||
rm[i*4+j] = m[i][j];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -660,13 +664,13 @@ bool trpgModelRef::GetMatrix(float64 *rm) const
|
||||
bool trpgModelRef::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPG_MODELREF);
|
||||
buf.Add(modelRef);
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Add(m[i][j]);
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Add(m[i][j]);
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
@ -676,14 +680,15 @@ bool trpgModelRef::Write(trpgWriteBuffer &buf)
|
||||
bool trpgModelRef::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Get(modelRef);
|
||||
if (modelRef < 0) throw 1;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Get(m[i][j]);
|
||||
buf.Get(modelRef);
|
||||
if (modelRef < 0)
|
||||
throw 1;
|
||||
for (int i=0;i<4;i++)
|
||||
for (int j=0;j<4;j++)
|
||||
buf.Get(m[i][j]);
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
valid = true;
|
||||
@ -691,10 +696,10 @@ bool trpgModelRef::Read(trpgReadBuffer &buf)
|
||||
}
|
||||
|
||||
/* Attach Node
|
||||
You'll find one of these in each tile, except for the lowest LOD.
|
||||
It's basically a group with some extra info that tells you where to attach it.
|
||||
The ID corresponds to the one in Group and LOD.
|
||||
*/
|
||||
You'll find one of these in each tile, except for the lowest LOD.
|
||||
It's basically a group with some extra info that tells you where to attach it.
|
||||
The ID corresponds to the one in Group and LOD.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgAttach::trpgAttach()
|
||||
@ -713,8 +718,8 @@ void trpgAttach::Reset()
|
||||
parentID = -1;
|
||||
childPos = -1;
|
||||
if ( name ) {
|
||||
delete [] name;
|
||||
name = 0;
|
||||
delete [] name;
|
||||
name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,7 +767,7 @@ bool trpgAttach::Write(trpgWriteBuffer &buf)
|
||||
buf.Add(childPos);
|
||||
|
||||
if ( name && strlen(name) ) {
|
||||
buf.Add(name);
|
||||
buf.Add(name);
|
||||
}
|
||||
|
||||
buf.End();
|
||||
@ -774,22 +779,165 @@ bool trpgAttach::Write(trpgWriteBuffer &buf)
|
||||
bool trpgAttach::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try {
|
||||
buf.Get(numChild);
|
||||
buf.Get(id);
|
||||
if (id < 0) throw 1;
|
||||
buf.Get(parentID);
|
||||
if (parentID < 0) throw 1;
|
||||
buf.Get(childPos);
|
||||
if (childPos < 0) throw 1;
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
buf.Get(numChild);
|
||||
buf.Get(id);
|
||||
if (id < 0) throw 1;
|
||||
buf.Get(parentID);
|
||||
if (parentID < 0) throw 1;
|
||||
buf.Get(childPos);
|
||||
if (childPos < 0) throw 1;
|
||||
if ( !buf.isEmpty() ) {
|
||||
char nm[1024] = {0};
|
||||
buf.Get(nm,1024);
|
||||
SetName(nm);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ChildRef Node
|
||||
You'll find in the parent tile one of these for each tile children.
|
||||
It gives the children grid location and file address.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgChildRef::trpgChildRef()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
trpgChildRef::~trpgChildRef()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Reset
|
||||
void trpgChildRef::Reset()
|
||||
{
|
||||
x = -1;
|
||||
y = -1;
|
||||
lod = -1;
|
||||
addr.file = -1;
|
||||
addr.offset = -1;
|
||||
}
|
||||
|
||||
void trpgChildRef::SetTileLoc(int gx,int gy,int glod)
|
||||
{
|
||||
x = gx;
|
||||
y = gy;
|
||||
lod = glod;
|
||||
}
|
||||
|
||||
bool trpgChildRef::GetTileLoc(int &gx,int &gy,int &glod) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
|
||||
gx = x;
|
||||
gy = y;
|
||||
glod = lod;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void trpgChildRef::SetTileAddress(const trpgwAppAddress& gAddr)
|
||||
{
|
||||
addr = gAddr;
|
||||
}
|
||||
void trpgChildRef::SetTileAddress(int32 file, int32 offset)
|
||||
{
|
||||
addr.file = file;
|
||||
addr.offset = offset;
|
||||
}
|
||||
bool trpgChildRef::GetTileAddress(int32& file, int32& offset) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
|
||||
file = addr.file;
|
||||
offset = addr.offset;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool trpgChildRef::GetTileAddress(trpgwAppAddress& gAddr) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
|
||||
gAddr = addr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void trpgChildRef::SetTileZValue( float gZmin, float gZmax)
|
||||
{
|
||||
zmin = gZmin;
|
||||
zmax = gZmax;
|
||||
}
|
||||
|
||||
bool trpgChildRef::GetTileZValue( float& gZmin, float& gZmax) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
|
||||
gZmin = zmin;
|
||||
gZmax = zmax;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Validity check
|
||||
bool trpgChildRef::isValid() const
|
||||
{
|
||||
if (lod < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Write Attach node
|
||||
bool trpgChildRef::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
|
||||
buf.Begin(TRPG_CHILDREF);
|
||||
|
||||
buf.Add(lod);
|
||||
buf.Add(x);
|
||||
buf.Add(y);
|
||||
buf.Add(addr.file);
|
||||
buf.Add(addr.offset);
|
||||
buf.Add(zmin);
|
||||
buf.Add(zmax);
|
||||
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read Attach node
|
||||
bool trpgChildRef::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
buf.Get(lod);
|
||||
if (lod < 0) throw 1;
|
||||
buf.Get(x);
|
||||
buf.Get(y);
|
||||
buf.Get(addr.file);
|
||||
buf.Get(addr.offset);
|
||||
buf.Get(zmin);
|
||||
buf.Get(zmax);
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -17,23 +17,23 @@
|
||||
#include <stdio.h>
|
||||
|
||||
/* trpage_parse.cpp
|
||||
This source file contains methods for the trpgr_Parser and trpgr_Token classes.
|
||||
trpgr_Parser is the main class. It parses the basic structure of paging archive
|
||||
data out of Read Buffers. You should not need to change this.
|
||||
If you want to parse data out of a different structure instead, look at
|
||||
subclassing trpgReadBuffer and replacing its virtual methods. That's what
|
||||
trpgMemReadBuffer is doing.
|
||||
|
||||
This file also contains the implementation of trpgSceneParser().
|
||||
That class implements a set of callbacks for handling the Pushes and Pops
|
||||
in an archive. You fill in the Start/EndChildren callbacks and register
|
||||
for the rest of the tokens that you want.
|
||||
*/
|
||||
This source file contains methods for the trpgr_Parser and trpgr_Token classes.
|
||||
trpgr_Parser is the main class. It parses the basic structure of paging archive
|
||||
data out of Read Buffers. You should not need to change this.
|
||||
If you want to parse data out of a different structure instead, look at
|
||||
subclassing trpgReadBuffer and replacing its virtual methods. That's what
|
||||
trpgMemReadBuffer is doing.
|
||||
|
||||
This file also contains the implementation of trpgSceneParser().
|
||||
That class implements a set of callbacks for handling the Pushes and Pops
|
||||
in an archive. You fill in the Start/EndChildren callbacks and register
|
||||
for the rest of the tokens that you want.
|
||||
*/
|
||||
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* ***************************
|
||||
Paging token callback structure
|
||||
Paging token callback structure
|
||||
***************************
|
||||
*/
|
||||
trpgr_Token::trpgr_Token()
|
||||
@ -59,13 +59,13 @@ void trpgr_Token::init(int in_tok,trpgr_Callback *in_cb,bool in_dest)
|
||||
void trpgr_Token::Destruct()
|
||||
{
|
||||
if (cb && destroy)
|
||||
delete cb;
|
||||
delete cb;
|
||||
cb = NULL;
|
||||
destroy = true;
|
||||
}
|
||||
|
||||
/* ***************************
|
||||
Paging parser implementation.
|
||||
Paging parser implementation.
|
||||
***************************
|
||||
*/
|
||||
|
||||
@ -98,10 +98,10 @@ class WriteWrapper : public trpgr_Callback {
|
||||
public:
|
||||
WriteWrapper(trpgReadWriteable *in_wr) { wr = in_wr; };
|
||||
void *Parse(trpgToken,trpgReadBuffer &buf) {
|
||||
if (wr->Read(buf))
|
||||
return wr;
|
||||
else
|
||||
return NULL;
|
||||
if (wr->Read(buf))
|
||||
return wr;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
protected:
|
||||
trpgReadWriteable *wr;
|
||||
@ -114,6 +114,25 @@ void trpgr_Parser::AddCallback(trpgToken tok,trpgReadWriteable *wr)
|
||||
AddCallback(tok,new WriteWrapper(wr),true);
|
||||
}
|
||||
|
||||
// Get the claaback associated with a token, will return 0 if none
|
||||
const trpgr_Callback *trpgr_Parser::GetCallback(trpgToken tok) const
|
||||
{
|
||||
tok_map::const_iterator iter = tokenMap.find(tok);
|
||||
if(iter != tokenMap.end())
|
||||
return iter->second.cb;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
trpgr_Callback *trpgr_Parser::GetCallback(trpgToken tok)
|
||||
{
|
||||
tok_map::iterator iter = tokenMap.find(tok);
|
||||
if(iter != tokenMap.end())
|
||||
return iter->second.cb;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Remove Callback
|
||||
void trpgr_Parser::RemoveCallback(trpgToken tok)
|
||||
{
|
||||
@ -129,13 +148,13 @@ void trpgr_Parser::SetDefaultCallback(trpgr_Callback *cb,bool in_dest)
|
||||
}
|
||||
|
||||
/* Token Is Valid
|
||||
Checks if something *could be* a token.
|
||||
Doesn't necessarily mean that it is.
|
||||
*/
|
||||
Checks if something *could be* a token.
|
||||
Doesn't necessarily mean that it is.
|
||||
*/
|
||||
bool trpgr_Parser::TokenIsValid(trpgToken tok)
|
||||
{
|
||||
if (tok < 0)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -144,97 +163,112 @@ bool trpgr_Parser::TokenIsValid(trpgToken tok)
|
||||
This runs through the given buffer parsing token sets until
|
||||
it (1) runs out of buffer or (2) fails.
|
||||
Note: Good place to return an exception, but keep it simple for now.
|
||||
*/
|
||||
*/
|
||||
bool trpgr_Parser::Parse(trpgReadBuffer &buf)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
try {
|
||||
while (!buf.isEmpty()) {
|
||||
/* We're expecting the following
|
||||
Token (int32)
|
||||
Length (int32)
|
||||
Data (variable)
|
||||
*/
|
||||
trpgToken tok;
|
||||
int32 len;
|
||||
if (!buf.Get(tok)) throw 1;
|
||||
// Push and Pop are special - no data
|
||||
if (tok != TRPG_PUSH && tok != TRPG_POP) {
|
||||
if (!buf.Get(len)) throw 1;
|
||||
if (!TokenIsValid(tok)) throw 1;
|
||||
if (len < 0) throw 1;
|
||||
// Limit what we're reading to the length of this
|
||||
buf.PushLimit(len);
|
||||
}
|
||||
try
|
||||
{
|
||||
while (!buf.isEmpty())
|
||||
{
|
||||
/* We're expecting the following
|
||||
Token (int32)
|
||||
Length (int32)
|
||||
Data (variable)
|
||||
*/
|
||||
trpgToken tok;
|
||||
int32 len;
|
||||
if (!buf.Get(tok)) throw 1;
|
||||
// Push and Pop are special - no data
|
||||
if (tok != TRPG_PUSH && tok != TRPG_POP)
|
||||
{
|
||||
if (!buf.Get(len)) throw 1;
|
||||
if (!TokenIsValid(tok)) throw 1;
|
||||
if (len < 0) throw 1;
|
||||
// Limit what we're reading to the length of this
|
||||
buf.PushLimit(len);
|
||||
}
|
||||
|
||||
// Call our token handler for this one
|
||||
try {
|
||||
const trpgr_Token *tcb = NULL;
|
||||
tok_map::const_iterator p = tokenMap.find(tok);
|
||||
if (p != tokenMap.end())
|
||||
tcb = &(*p).second;
|
||||
if (!tcb)
|
||||
// No such token, call the default
|
||||
tcb = &defCb;
|
||||
// Call our token handler for this one
|
||||
try
|
||||
{
|
||||
const trpgr_Token *tcb = NULL;
|
||||
tok_map::const_iterator p = tokenMap.find(tok);
|
||||
if (p != tokenMap.end())
|
||||
tcb = &(*p).second;
|
||||
if (!tcb)
|
||||
// No such token, call the default
|
||||
tcb = &defCb;
|
||||
|
||||
// Run the callback
|
||||
if (tcb->cb) {
|
||||
void *ret = tcb->cb->Parse(tok,buf);
|
||||
// Note: Do something with the return value
|
||||
lastObject = ret;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// Don't want to screw up the limit stack
|
||||
}
|
||||
// No limit to worry about with push and pop
|
||||
if (tok != TRPG_PUSH && tok != TRPG_POP) {
|
||||
buf.SkipToLimit();
|
||||
buf.PopLimit();
|
||||
}
|
||||
}
|
||||
// Run the callback
|
||||
if (tcb->cb)
|
||||
{
|
||||
void *ret = tcb->cb->Parse(tok,buf);
|
||||
// Note: Do something with the return value
|
||||
lastObject = ret;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Don't want to screw up the limit stack
|
||||
}
|
||||
// No limit to worry about with push and pop
|
||||
if (tok != TRPG_PUSH && tok != TRPG_POP)
|
||||
{
|
||||
buf.SkipToLimit();
|
||||
buf.PopLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// Failed to parse.
|
||||
ret = false;
|
||||
catch (...)
|
||||
{
|
||||
// Failed to parse.
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ****************
|
||||
Scene Parser
|
||||
****************
|
||||
*/
|
||||
/* ****************
|
||||
Scene Parser
|
||||
****************
|
||||
*/
|
||||
// Helper - callback for Push
|
||||
class trpgSceneHelperPush : public trpgr_Callback {
|
||||
class trpgSceneHelperPush : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
trpgSceneHelperPush(trpgSceneParser *in_parse) { parse = in_parse; };
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer& /*buf*/) {
|
||||
// Call the start children callback
|
||||
parse->StartChildren(parse->lastObject);
|
||||
parse->parents.push_back(parse->lastObject);
|
||||
return (void *)1;
|
||||
trpgSceneHelperPush(trpgSceneParser *in_parse)
|
||||
{ parse = in_parse; };
|
||||
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer& /*buf*/)
|
||||
{
|
||||
// Call the start children callback
|
||||
parse->StartChildren(parse->lastObject);
|
||||
parse->parents.push_back(parse->lastObject);
|
||||
return (void *)1;
|
||||
}
|
||||
protected:
|
||||
trpgSceneParser *parse;
|
||||
};
|
||||
|
||||
// Helper - callback for Pop
|
||||
class trpgSceneHelperPop : public trpgr_Callback {
|
||||
class trpgSceneHelperPop : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
trpgSceneHelperPop(trpgSceneParser *in_parse) { parse = in_parse; };
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer& /*buf*/) {
|
||||
// Make sure we don't have an extra pop
|
||||
if (parse->parents.size() == 0)
|
||||
// Note: let someone know about the extra pop
|
||||
return NULL;
|
||||
// Call the end children callback
|
||||
int len = parse->parents.size();
|
||||
parse->EndChildren(parse->parents[len-1]);
|
||||
parse->parents.resize(len-1);
|
||||
return (void *)1;
|
||||
trpgSceneHelperPop(trpgSceneParser *in_parse)
|
||||
{ parse = in_parse; };
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer& /*buf*/)
|
||||
{
|
||||
// Make sure we don't have an extra pop
|
||||
if (parse->parents.size() == 0)
|
||||
// Note: let someone know about the extra pop
|
||||
return NULL;
|
||||
// Call the end children callback
|
||||
int len = parse->parents.size();
|
||||
parse->EndChildren(parse->parents[len-1]);
|
||||
parse->parents.resize(len-1);
|
||||
return (void *)1;
|
||||
}
|
||||
protected:
|
||||
trpgSceneParser *parse;
|
||||
@ -243,12 +277,14 @@ protected:
|
||||
// Helper - default callback
|
||||
// Puts a 1 on the parent stack
|
||||
// Note: Need to use this fact above
|
||||
class trpgSceneHelperDefault : public trpgr_Callback {
|
||||
class trpgSceneHelperDefault : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
trpgSceneHelperDefault(trpgSceneParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer& /*buf*/) {
|
||||
// Absorb it quietly
|
||||
return (void *)1;
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer& /*buf*/)
|
||||
{
|
||||
// Absorb it quietly
|
||||
return (void *)1;
|
||||
}
|
||||
protected:
|
||||
trpgSceneParser *parse;
|
||||
|
@ -18,183 +18,293 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_pparse.cpp
|
||||
This file contains classes that can parse a TerraPage
|
||||
archive for the purpose of printing it out.
|
||||
This file contains classes that can parse a TerraPage
|
||||
archive for the purpose of printing it out.
|
||||
*/
|
||||
|
||||
#include <trpage_print.h>
|
||||
#include <trpage_scene.h>
|
||||
#include <trpage_managers.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
// This will recursivelly call itself up until
|
||||
// all the tiule are done
|
||||
void printBuf(int lod, int x, int y, trpgr_Archive *archive, trpgPrintGraphParser& parser, trpgMemReadBuffer &buf, trpgPrintBuffer &pBuf)
|
||||
{
|
||||
char ls[1024];
|
||||
sprintf(ls,"Tile (lod) (x,y) = (%d) (%d,%d)", lod, x, y);
|
||||
pBuf.prnLine(ls);
|
||||
pBuf.IncreaseIndent();
|
||||
parser.Reset();
|
||||
parser.Parse(buf);
|
||||
pBuf.DecreaseIndent();
|
||||
|
||||
// Save the list
|
||||
// std::vector<const trpgChildRef> childRefList;
|
||||
// The const in the template parameter was removed because it causes GCC to
|
||||
// freak out. I am of the opinion that const doesn't make sense in a template
|
||||
// parameter for std::vector anyway... const prevents you from changing the
|
||||
// value, so what exactly is the point? How does one add entries to the vector
|
||||
// without giving them a value? -ADS
|
||||
std::vector<trpgChildRef> childRefList;
|
||||
for(unsigned int idx =0; idx < parser.GetNbChildrenRef(); idx++)
|
||||
childRefList.push_back(*parser.GetChildRef(idx));
|
||||
|
||||
|
||||
for(unsigned int idx =0; idx < childRefList.size(); idx++)
|
||||
{
|
||||
const trpgChildRef& childRef = childRefList[idx];
|
||||
trpgMemReadBuffer childBuf(archive->GetEndian());
|
||||
trpgwAppAddress tileAddr;
|
||||
int glod, gx, gy;
|
||||
|
||||
childRef.GetTileAddress(tileAddr);
|
||||
childRef.GetTileLoc(gx,gy,glod);
|
||||
|
||||
trpgTileTable::TileMode mode;
|
||||
archive->GetTileTable()->GetMode(mode);
|
||||
bool status;
|
||||
if(mode == trpgTileTable::Local)
|
||||
status = archive->ReadTile(tileAddr, childBuf);
|
||||
else
|
||||
status = archive->ReadExternalTile(gx, gy, glod, childBuf);
|
||||
|
||||
if(status)
|
||||
printBuf(glod, gx, gy, archive, parser, childBuf, pBuf);
|
||||
|
||||
}
|
||||
}
|
||||
} // end namespace
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Set up the callbacks for the scene graph parser.
|
||||
In our case this is just one read helper with
|
||||
a switch statement.
|
||||
In our case this is just one read helper with
|
||||
a switch statement.
|
||||
*/
|
||||
trpgPrintGraphParser::trpgPrintGraphParser(trpgr_Archive *inArch,trpgrImageHelper *inImg,trpgPrintBuffer *inBuf)
|
||||
trpgPrintGraphParser::trpgPrintGraphParser(trpgr_Archive *inArch,trpgrImageHelper *inImg,trpgPrintBuffer *inBuf):printBuf(inBuf), archive(inArch), imageHelp(inImg), childRefCB(0)
|
||||
{
|
||||
printBuf = inBuf;
|
||||
archive = inArch;
|
||||
imageHelp = inImg;
|
||||
|
||||
// Register the readers
|
||||
AddCallback(TRPG_GEOMETRY,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_GROUP,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_ATTACH,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_BILLBOARD,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LOD,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_TRANSFORM,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_MODELREF,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LAYER,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LIGHT,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LABEL,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPGTILEHEADER,new ReadHelper(this,printBuf));
|
||||
// Register the readers
|
||||
AddCallback(TRPG_GEOMETRY,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_GROUP,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_ATTACH,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_CHILDREF,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_BILLBOARD,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LOD,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_TRANSFORM,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_MODELREF,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LAYER,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LIGHT,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPG_LABEL,new ReadHelper(this,printBuf));
|
||||
AddCallback(TRPGTILEHEADER,new ReadHelper(this,printBuf));
|
||||
|
||||
childRefCB = dynamic_cast<ReadHelper *>(GetCallback(TRPG_CHILDREF));
|
||||
}
|
||||
|
||||
/* Start Children is called when the parser hits a Push
|
||||
in the read buffer. We just want to indent further when
|
||||
that happens.
|
||||
in the read buffer. We just want to indent further when
|
||||
that happens.
|
||||
*/
|
||||
bool trpgPrintGraphParser::StartChildren(void *)
|
||||
{
|
||||
printBuf->IncreaseIndent();
|
||||
printBuf->IncreaseIndent();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* End Children is called when the parser hits a Pop
|
||||
in the read buffer. We just want to reduce the indent
|
||||
when that happens.
|
||||
in the read buffer. We just want to reduce the indent
|
||||
when that happens.
|
||||
*/
|
||||
bool trpgPrintGraphParser::EndChildren(void *)
|
||||
{
|
||||
printBuf->DecreaseIndent();
|
||||
printBuf->DecreaseIndent();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int trpgPrintGraphParser::GetNbChildrenRef() const
|
||||
{
|
||||
if(childRefCB)
|
||||
return childRefCB->GetNbChildrenRef();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
const trpgChildRef* trpgPrintGraphParser::GetChildRef(unsigned int idx) const
|
||||
{
|
||||
if(childRefCB)
|
||||
return childRefCB->GetChildRef(idx);
|
||||
else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void trpgPrintGraphParser::Reset()
|
||||
{
|
||||
if(childRefCB)
|
||||
childRefCB->Reset();
|
||||
}
|
||||
|
||||
void trpgPrintGraphParser::ReadHelper::Reset()
|
||||
{
|
||||
childRefList.clear();
|
||||
}
|
||||
|
||||
unsigned int trpgPrintGraphParser::ReadHelper::GetNbChildrenRef() const
|
||||
{
|
||||
return childRefList.size();
|
||||
}
|
||||
const trpgChildRef* trpgPrintGraphParser::ReadHelper::GetChildRef(unsigned int idx) const
|
||||
{
|
||||
if(idx >= childRefList.size())
|
||||
return 0;
|
||||
else
|
||||
return &childRefList[idx];
|
||||
}
|
||||
|
||||
/* Read Helper parse method sets up the correct class depending
|
||||
on the token and asks it to read and print itself.
|
||||
on the token and asks it to read and print itself. It will save
|
||||
any child ref node encountered that a user can access to continue
|
||||
traversal.
|
||||
*/
|
||||
void *trpgPrintGraphParser::ReadHelper::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
{
|
||||
trpgReadWriteable *obj = NULL;
|
||||
trpgTileHeader *tileHead = NULL;
|
||||
// This will celar any child ref list from a previous parse.
|
||||
trpgReadWriteable *obj = NULL;
|
||||
trpgTileHeader *tileHead = NULL;
|
||||
|
||||
switch (tok) {
|
||||
case TRPG_GEOMETRY:
|
||||
obj = new trpgGeometry();
|
||||
break;
|
||||
case TRPG_GROUP:
|
||||
obj = new trpgGroup();
|
||||
break;
|
||||
case TRPG_ATTACH:
|
||||
obj = new trpgAttach();
|
||||
break;
|
||||
case TRPG_BILLBOARD:
|
||||
obj = new trpgBillboard();
|
||||
break;
|
||||
case TRPG_LOD:
|
||||
obj = new trpgLod();
|
||||
break;
|
||||
case TRPG_TRANSFORM:
|
||||
obj = new trpgTransform();
|
||||
break;
|
||||
case TRPG_MODELREF:
|
||||
obj = new trpgModelRef();
|
||||
break;
|
||||
case TRPG_LAYER:
|
||||
obj = new trpgLayer();
|
||||
break;
|
||||
case TRPG_LIGHT:
|
||||
obj = new trpgLight();
|
||||
break;
|
||||
case TRPG_LABEL:
|
||||
obj = new trpgLabel();
|
||||
break;
|
||||
switch (tok) {
|
||||
case TRPG_GEOMETRY:
|
||||
obj = new trpgGeometry();
|
||||
break;
|
||||
case TRPG_GROUP:
|
||||
obj = new trpgGroup();
|
||||
break;
|
||||
case TRPG_ATTACH:
|
||||
obj = new trpgAttach();
|
||||
break;
|
||||
case TRPG_CHILDREF:
|
||||
childRefList.push_back(trpgChildRef());
|
||||
obj = &childRefList.back();
|
||||
break;
|
||||
case TRPG_BILLBOARD:
|
||||
obj = new trpgBillboard();
|
||||
break;
|
||||
case TRPG_LOD:
|
||||
obj = new trpgLod();
|
||||
break;
|
||||
case TRPG_TRANSFORM:
|
||||
obj = new trpgTransform();
|
||||
break;
|
||||
case TRPG_MODELREF:
|
||||
obj = new trpgModelRef();
|
||||
break;
|
||||
case TRPG_LAYER:
|
||||
obj = new trpgLayer();
|
||||
break;
|
||||
case TRPG_LIGHT:
|
||||
obj = new trpgLight();
|
||||
break;
|
||||
case TRPG_LABEL:
|
||||
obj = new trpgLabel();
|
||||
break;
|
||||
|
||||
case TRPGTILEHEADER:
|
||||
obj = tileHead = new trpgTileHeader();
|
||||
break;
|
||||
};
|
||||
case TRPGTILEHEADER:
|
||||
obj = tileHead = new trpgTileHeader();
|
||||
break;
|
||||
};
|
||||
|
||||
if (obj) {
|
||||
if (obj->Read(buf))
|
||||
obj->Print(*pBuf);
|
||||
// For the tile header, do a little more work
|
||||
if (tok == TRPGTILEHEADER) {
|
||||
int numMat;
|
||||
tileHead->GetNumLocalMaterial(numMat);
|
||||
for (int i=0;i<numMat;i++) {
|
||||
trpgLocalMaterial locMat;
|
||||
tileHead->GetLocalMaterial(i,locMat);
|
||||
const trpgMaterial *baseMat;
|
||||
const trpgTexture *baseTex;
|
||||
int totSize;
|
||||
trpgrImageHelper *imageHelp = parse->GetImageHelp();
|
||||
int numImages=1;
|
||||
locMat.GetNumLocals(numImages);
|
||||
for (int imgN=0;imgN<numImages;imgN++) {
|
||||
// read all the images for each local material
|
||||
imageHelp->GetNthImageInfoForLocalMat(&locMat,imgN,&baseMat,&baseTex,totSize);
|
||||
if (obj) {
|
||||
if (obj->Read(buf))
|
||||
obj->Print(*pBuf);
|
||||
// For the tile header, do a little more work
|
||||
if (tok == TRPGTILEHEADER) {
|
||||
int numMat;
|
||||
tileHead->GetNumLocalMaterial(numMat);
|
||||
for (int i=0;i<numMat;i++) {
|
||||
trpgLocalMaterial locMat;
|
||||
tileHead->GetLocalMaterial(i,locMat);
|
||||
const trpgMaterial *baseMat;
|
||||
const trpgTexture *baseTex;
|
||||
int totSize;
|
||||
trpgrImageHelper *imageHelp = parse->GetImageHelp();
|
||||
int numImages=1;
|
||||
locMat.GetNumLocals(numImages);
|
||||
for (int imgN=0;imgN<numImages;imgN++) {
|
||||
// read all the images for each local material
|
||||
imageHelp->GetNthImageInfoForLocalMat(&locMat,imgN,&baseMat,&baseTex,totSize);
|
||||
|
||||
// Fetch the whole image
|
||||
{
|
||||
char *pixels = new char[totSize];
|
||||
bool failed = false;
|
||||
try {
|
||||
failed = !imageHelp->GetNthImageForLocalMat(&locMat,imgN,pixels,totSize);
|
||||
}
|
||||
catch (...) {
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
fprintf(stderr,"Failed to read local image %d from local material %d.\n",imgN,i);
|
||||
} else
|
||||
fprintf(stderr,"Read local image %d from local material %d successfully.\n",imgN,i);
|
||||
delete [] pixels;
|
||||
}
|
||||
// Fetch the whole image
|
||||
{
|
||||
char *pixels = new char[totSize];
|
||||
bool failed = false;
|
||||
try {
|
||||
failed = !imageHelp->GetNthImageForLocalMat(&locMat,imgN,pixels,totSize);
|
||||
}
|
||||
catch (...) {
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
fprintf(stderr,"Failed to read local image %d from local material %d.\n",imgN,i);
|
||||
} else
|
||||
fprintf(stderr,"Read local image %d from local material %d successfully.\n",imgN,i);
|
||||
delete [] pixels;
|
||||
}
|
||||
|
||||
// Fetch the individual mipmap levels
|
||||
{
|
||||
int numMipmap;
|
||||
bool hasMipmap;
|
||||
baseTex->GetIsMipmap(hasMipmap);
|
||||
numMipmap = hasMipmap ? baseTex->CalcNumMipmaps() : 0;
|
||||
for (int j=1;j<numMipmap;j++) {
|
||||
//int mipOffset = (const_cast<trpgTexture *>(baseTex))->MipLevelOffset(j);
|
||||
int mipSize = (const_cast<trpgTexture *>(baseTex))->MipLevelSize(j);
|
||||
if (mipSize) {
|
||||
char *pixels = new char[mipSize];
|
||||
bool failed = false;
|
||||
try {
|
||||
failed = !imageHelp->GetNthImageMipLevelForLocalMat(j,&locMat,imgN,pixels,mipSize);
|
||||
}
|
||||
catch (...) {
|
||||
failed = true;
|
||||
}
|
||||
if (failed)
|
||||
fprintf(stderr,"Failed to read mipmap level %d for local image %d from local material %d.\n",j,imgN,i);
|
||||
else
|
||||
fprintf(stderr,"Read mipmap level %d for local image %d from local material %d.\n",j,imgN,i);
|
||||
delete [] pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fetch the individual mipmap levels
|
||||
{
|
||||
int numMipmap;
|
||||
bool hasMipmap;
|
||||
baseTex->GetIsMipmap(hasMipmap);
|
||||
numMipmap = hasMipmap ? baseTex->CalcNumMipmaps() : 0;
|
||||
for (int j=1;j<numMipmap;j++) {
|
||||
//int mipOffset = (const_cast<trpgTexture *>(baseTex))->MipLevelOffset(j);
|
||||
int mipSize = (const_cast<trpgTexture *>(baseTex))->MipLevelSize(j);
|
||||
if (mipSize) {
|
||||
char *pixels = new char[mipSize];
|
||||
bool failed = false;
|
||||
try {
|
||||
failed = !imageHelp->GetNthImageMipLevelForLocalMat(j,&locMat,imgN,pixels,mipSize);
|
||||
}
|
||||
catch (...) {
|
||||
failed = true;
|
||||
}
|
||||
if (failed)
|
||||
fprintf(stderr,"Failed to read mipmap level %d for local image %d from local material %d.\n",j,imgN,i);
|
||||
else
|
||||
fprintf(stderr,"Read mipmap level %d for local image %d from local material %d.\n",j,imgN,i);
|
||||
delete [] pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete obj;
|
||||
}
|
||||
// We delete all object except the child ref node
|
||||
if(tok != TRPG_CHILDREF)
|
||||
delete obj;
|
||||
}
|
||||
|
||||
// Need to return non-zero. Otherwise it's interpreted as an error
|
||||
return (void *)1;
|
||||
// Need to return non-zero. Otherwise it's interpreted as an error
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
// The following routine is not compiled if there's no _splitpath
|
||||
#ifdef _splitpath
|
||||
/* This is a convenience function to print out the contents
|
||||
of an entire TerraPage archive.
|
||||
of an entire TerraPage archive.
|
||||
|
||||
There are two versions of this function. The first takes
|
||||
a file name and the second an opened archive where the header
|
||||
@ -202,88 +312,120 @@ void *trpgPrintGraphParser::ReadHelper::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
*/
|
||||
bool trpgPrintArchive(char *filename,trpgPrintBuffer &pBuf,int flags)
|
||||
{
|
||||
trpgr_Archive archive;
|
||||
trpgr_Archive archive;
|
||||
|
||||
// Break path apart so we can find the directory
|
||||
char drive[100],dir[1024],fname[1024],ext[1024];
|
||||
_splitpath(filename,drive,dir,fname,ext);
|
||||
// Break path apart so we can find the directory
|
||||
char drive[100],dir[1024],fname[1024],ext[1024];
|
||||
_splitpath(filename,drive,dir,fname,ext);
|
||||
|
||||
char rname[1024],baseDir[1024];
|
||||
sprintf(baseDir,"%s%s",drive,dir);
|
||||
sprintf(rname,"%s%s",fname,ext);
|
||||
char rname[1024],baseDir[1024];
|
||||
sprintf(baseDir,"%s%s",drive,dir);
|
||||
sprintf(rname,"%s%s",fname,ext);
|
||||
|
||||
if (!*baseDir) strcpy(baseDir,".");
|
||||
archive.SetDirectory(baseDir);
|
||||
if (!archive.OpenFile(rname)) {
|
||||
fprintf(stdout,"Failed to open archive.\n");
|
||||
return false;
|
||||
}
|
||||
if (!archive.ReadHeader()) {
|
||||
fprintf(stdout,"Failed to read header.\n");
|
||||
return false;
|
||||
}
|
||||
if (!*baseDir) strcpy(baseDir,".");
|
||||
archive.SetDirectory(baseDir);
|
||||
if (!archive.OpenFile(rname)) {
|
||||
fprintf(stdout,"Failed to open archive.\n");
|
||||
return false;
|
||||
}
|
||||
if (!archive.ReadHeader()) {
|
||||
fprintf(stdout,"Failed to read header.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool status = trpgPrintArchive(&archive,pBuff,flags);
|
||||
return status;
|
||||
bool status = trpgPrintArchive(&archive,pBuff,flags);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool trpgPrintArchive(trpgr_Archive *archive,trpgPrintBuffer &pBuf,int flags)
|
||||
{
|
||||
char ls[1024];
|
||||
char ls[1024];
|
||||
|
||||
if (!archive->isValid()) return false;
|
||||
|
||||
pBuf.prnLine("====Header Structures====");
|
||||
if (!archive->isValid()) return false;
|
||||
|
||||
pBuf.prnLine("====Header Structures====");
|
||||
|
||||
// Print out the header portion
|
||||
archive->GetHeader()->Print(pBuf);
|
||||
archive->GetMaterialTable()->Print(pBuf);
|
||||
archive->GetTexTable()->Print(pBuf);
|
||||
archive->GetModelTable()->Print(pBuf);
|
||||
archive->GetTileTable()->Print(pBuf);
|
||||
archive->GetLightTable()->Print(pBuf);
|
||||
archive->GetRangeTable()->Print(pBuf);
|
||||
archive->GetTextStyleTable()->Print(pBuf);
|
||||
archive->GetSupportStyleTable()->Print(pBuf);
|
||||
archive->GetLabelPropertyTable()->Print(pBuf);
|
||||
pBuf.prnLine();
|
||||
// Print out the header portion
|
||||
archive->GetHeader()->Print(pBuf);
|
||||
archive->GetMaterialTable()->Print(pBuf);
|
||||
archive->GetTexTable()->Print(pBuf);
|
||||
archive->GetModelTable()->Print(pBuf);
|
||||
archive->GetTileTable()->Print(pBuf);
|
||||
archive->GetLightTable()->Print(pBuf);
|
||||
archive->GetRangeTable()->Print(pBuf);
|
||||
archive->GetTextStyleTable()->Print(pBuf);
|
||||
archive->GetSupportStyleTable()->Print(pBuf);
|
||||
archive->GetLabelPropertyTable()->Print(pBuf);
|
||||
pBuf.prnLine();
|
||||
|
||||
// Read the local images and do the math for the templates
|
||||
// Read the local images and do the math for the templates
|
||||
|
||||
// Now do the tiles
|
||||
if (!archive->isValid()) return false;
|
||||
// Now do the tiles
|
||||
if (!archive->isValid()) return false;
|
||||
|
||||
// Parser that prints out a tile scene graph
|
||||
trpgrImageHelper imageHelp(archive->GetEndian(),archive->getDir(),*archive->GetMaterialTable(),
|
||||
*archive->GetTexTable());
|
||||
trpgPrintGraphParser parser(archive,&imageHelp,&pBuf);
|
||||
int majorVersion, minorVersion;
|
||||
archive->GetHeader()->GetVersion(majorVersion, minorVersion);
|
||||
|
||||
pBuf.prnLine("====Tile Data====");
|
||||
int nl,x,y;
|
||||
trpgMemReadBuffer buf(archive->GetEndian());
|
||||
// Iterate over the terrain lods
|
||||
int numLod;
|
||||
archive->GetHeader()->GetNumLods(numLod);
|
||||
trpg2iPoint tileSize;
|
||||
for (nl=0;nl<numLod;nl++) {
|
||||
archive->GetHeader()->GetLodSize(nl,tileSize);
|
||||
// Iterate over the tiles
|
||||
for (x=tileSize.x-1;x>=0;x--)
|
||||
for (y=0;y<tileSize.y;y++) {
|
||||
sprintf(ls,"Tile (lod) (x,y) = (%d) (%d,%d)",nl,x,y);
|
||||
pBuf.prnLine(ls);
|
||||
if (archive->ReadTile(x,y,nl,buf)) {
|
||||
if (flags & TRPGPRN_BODY) {
|
||||
pBuf.IncreaseIndent();
|
||||
// Parse it (also prints it
|
||||
parser.Parse(buf);
|
||||
pBuf.DecreaseIndent();
|
||||
}
|
||||
} else
|
||||
pBuf.prnLine(" Couldn't read tile.");
|
||||
}
|
||||
}
|
||||
// Parser that prints out a tile scene graph
|
||||
trpgrImageHelper* imageHelp=archive->GetNewRImageHelper(archive->GetEndian(),archive->getDir(),
|
||||
*archive->GetMaterialTable(),*archive->GetTexTable());
|
||||
|
||||
return true;
|
||||
trpgPrintGraphParser parser(archive,imageHelp,&pBuf);
|
||||
|
||||
pBuf.prnLine("====Tile Data====");
|
||||
int nl,x,y;
|
||||
trpgMemReadBuffer buf(archive->GetEndian());
|
||||
// Iterate over the terrain lods
|
||||
int numLod;
|
||||
archive->GetHeader()->GetNumLods(numLod);
|
||||
trpg2iPoint tileSize;
|
||||
if(majorVersion == 2 && minorVersion >= 1)
|
||||
{
|
||||
// Version 2.1
|
||||
// Because of variable lod support in version 2.1 and over, we can
|
||||
// no longer suppose that all lod level are all populated with tiles
|
||||
// in all of the gaming area. We have to parse the parent to know that.
|
||||
// Also the tile table only contains lod 0 tiles so we can no longer access
|
||||
// the tile directly from its grid location. So we have to traverse.
|
||||
trpg2iPoint blockTileSize;
|
||||
if(archive->GetHeader()->GetLodSize(0,blockTileSize)) {
|
||||
for(x = 0; x < blockTileSize.x; x++)
|
||||
for( y = 0; y < blockTileSize.y; y++)
|
||||
if (archive->ReadTile(x,y,0,buf))
|
||||
printBuf(0, x, y, archive, parser, buf, pBuf);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for (nl=0;nl<numLod;nl++) {
|
||||
archive->GetHeader()->GetLodSize(nl,tileSize);
|
||||
// Iterate over the tiles
|
||||
for (x=tileSize.x-1;x>=0;x--)
|
||||
for (y=0;y<tileSize.y;y++) {
|
||||
sprintf(ls,"Tile (lod) (x,y) = (%d) (%d,%d)",nl,x,y);
|
||||
pBuf.prnLine(ls);
|
||||
if (archive->ReadTile(x,y,nl,buf)) {
|
||||
if (flags & TRPGPRN_BODY) {
|
||||
pBuf.IncreaseIndent();
|
||||
// Parse it (also prints it
|
||||
if (!parser.Parse(buf))
|
||||
{
|
||||
char errString[80];
|
||||
sprintf(errString, "**** Warning: tile anomaly detected: (%d) (%d,%d) ****",nl,x,y);
|
||||
// send it both ways so it's easier to spot
|
||||
pBuf.prnLine(errString);
|
||||
fprintf(stderr,"%s\n",errString);
|
||||
}
|
||||
pBuf.DecreaseIndent();
|
||||
}
|
||||
} else
|
||||
pBuf.prnLine(" Couldn't read tile.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -18,20 +18,20 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_print.cpp
|
||||
Print out the contents of a TerraPage archive.
|
||||
This module provides an example of how to access each of the classes
|
||||
within a TerraPage archive.
|
||||
*/
|
||||
Print out the contents of a TerraPage archive.
|
||||
This module provides an example of how to access each of the classes
|
||||
within a TerraPage archive.
|
||||
*/
|
||||
|
||||
#include <trpage_print.h>
|
||||
|
||||
/* ******************************************
|
||||
Print Buffer implementation
|
||||
The print buffer is a way to dump debugging data out
|
||||
to a file (or console). You can make your own subclass
|
||||
of trpgPrintBuffer if you have specific needs.
|
||||
The print buffer is a way to dump debugging data out
|
||||
to a file (or console). You can make your own subclass
|
||||
of trpgPrintBuffer if you have specific needs.
|
||||
******************************************
|
||||
*/
|
||||
*/
|
||||
|
||||
trpgPrintBuffer::trpgPrintBuffer()
|
||||
{
|
||||
@ -96,7 +96,8 @@ bool trpgFilePrintBuffer::prnLine(char *str)
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
if (str) {
|
||||
if (str)
|
||||
{
|
||||
fprintf(fp,indentStr);
|
||||
fprintf(fp,str);
|
||||
fprintf(fp,"\n");
|
||||
@ -112,7 +113,7 @@ bool trpgFilePrintBuffer::prnLine(char *str)
|
||||
is readable/writeable are here. These are used for
|
||||
debugging.
|
||||
*************************************
|
||||
*/
|
||||
*/
|
||||
|
||||
/* Print out the header information.
|
||||
*/
|
||||
@ -122,14 +123,20 @@ bool trpgHeader::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine("----Archive Header----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"verMinor = %d, verMajor = %d",verMinor,verMajor); buf.prnLine(ls);
|
||||
if((verMajor >= TRPG_NOMERGE_VERSION_MAJOR) && (verMinor >=TRPG_NOMERGE_VERSION_MINOR))
|
||||
{
|
||||
sprintf(ls,"isMaster = %s, numRows = %d, numCols = %d",GetIsMaster()?"YES":"NO",rows,cols); buf.prnLine(ls);
|
||||
}
|
||||
sprintf(ls,"dbVerMinor = %d, dbVerMajor = %d",dbVerMinor,dbVerMajor); buf.prnLine(ls);
|
||||
|
||||
sprintf(ls,"maxGroupID = %d",maxGroupID); buf.prnLine(ls);
|
||||
sprintf(ls,"sw = (%f,%f), ne = (%f,%f)",sw.x,sw.y,ne.x,ne.y); buf.prnLine(ls);
|
||||
sprintf(ls,"tileType = %d, origin = (%f,%f,%f)",tileType,origin.x,origin.y,origin.z); buf.prnLine(ls);
|
||||
|
||||
sprintf(ls,"numLods = %d",numLods); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (int i=0;i<numLods;i++) {
|
||||
for (int i=0;i<numLods;i++)
|
||||
{
|
||||
sprintf(ls,"tileSize = (%f,%f), lodSizes = (%d,%d), lodRanges = %f",tileSize[i].x,tileSize[i].y,lodSizes[i].x,lodSizes[i].y,lodRanges[i]); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent(2);
|
||||
@ -176,7 +183,8 @@ bool trpgMaterial::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"numTile = %d",numTile); buf.prnLine(ls);
|
||||
sprintf(ls,"numTex = %d",numTex); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (int i=0;i<numTex;i++) {
|
||||
for (int i=0;i<numTex;i++)
|
||||
{
|
||||
sprintf(ls,"texID[%d] = %d",i,texids[i]); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
texEnvs[i].Print(buf);
|
||||
@ -199,16 +207,18 @@ bool trpgMatTable::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"numTable = %d",numTable); buf.prnLine(ls);
|
||||
sprintf(ls,"numMat = %d",numMat); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (int j=0;j<numTable;j++) {
|
||||
sprintf(ls,"----Sub Table %d----",j); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (int i=0;i<numMat;i++) {
|
||||
const trpgMaterial *mat;
|
||||
sprintf(ls,"Material %d",i); buf.prnLine(ls);
|
||||
mat = (const_cast<trpgMatTable *>(this))->GetMaterialRef(j,i);
|
||||
mat->Print(buf);
|
||||
MaterialMapType::const_iterator itr = materialMap.begin();
|
||||
for ( ; itr != materialMap.end( ); itr++)
|
||||
{
|
||||
const trpgMaterial *mat;
|
||||
sprintf(ls,"Material %d",itr->first); buf.prnLine(ls);
|
||||
mat = (const_cast<trpgMatTable *>(this))->GetMaterialRef(0,itr->first);
|
||||
if(!mat)
|
||||
{
|
||||
sprintf(ls,"Error: Unable to load material!"); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
else
|
||||
mat->Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent(2);
|
||||
|
||||
@ -227,9 +237,10 @@ bool trpgTexture::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"Name = %s",name); buf.prnLine(ls);
|
||||
sprintf(ls,"useCount = %d",useCount); buf.prnLine(ls);
|
||||
sprintf(ls,"sizeX = %d, sizeY = %d, sizeZ = %d",sizeX,sizeY,numLayer); buf.prnLine(ls);
|
||||
sprintf(ls,"sensor band organization = %d",org); buf.prnLine(ls);
|
||||
// sprintf(ls,"sensor band organization = %d",org); buf.prnLine(ls); // does this need to be added?
|
||||
sprintf(ls,"ismipmap = %d",isMipmap); buf.prnLine(ls);
|
||||
sprintf(ls,"addr.file = %d, addr.offset = %d",addr.file,addr.offset); buf.prnLine(ls);
|
||||
sprintf(ls,"addr.col = %d, addr.row = %d",addr.col,addr.row); buf.prnLine(ls);
|
||||
buf.DecreaseIndent();
|
||||
|
||||
buf.prnLine();
|
||||
@ -245,9 +256,11 @@ bool trpgTexTable::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
buf.prnLine("----Texture Table----");
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<texList.size();i++) {
|
||||
sprintf(ls,"Texture %d",i); buf.prnLine(ls);
|
||||
texList[i].Print(buf);
|
||||
TextureMapType::const_iterator itr = textureMap.begin();
|
||||
for ( ; itr != textureMap.end( ); itr++)
|
||||
{
|
||||
sprintf(ls,"Texture %d",itr->first); buf.prnLine(ls);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
|
||||
@ -264,9 +277,11 @@ bool trpgModelTable::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
buf.prnLine("----Model Table----");
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<models.size();i++) {
|
||||
sprintf(ls,"Model %d",i); buf.prnLine(ls);
|
||||
models[i].Print(buf);
|
||||
ModelMapType::const_iterator itr = modelsMap.begin();
|
||||
for ( ; itr != modelsMap.end( ); itr++)
|
||||
{
|
||||
sprintf(ls,"Model %d",itr->first); buf.prnLine(ls);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
|
||||
@ -284,7 +299,8 @@ bool trpgModel::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine("----Model----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"type = %d",type); buf.prnLine(ls);
|
||||
if (name) {
|
||||
if (name)
|
||||
{
|
||||
sprintf(ls,"name = %s",name); buf.prnLine(ls);
|
||||
}
|
||||
sprintf(ls,"diskRef = %d",(int)diskRef), buf.prnLine(ls);
|
||||
@ -308,14 +324,16 @@ bool trpgTileHeader::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"matList size = %d",static_cast<int>(matList.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
unsigned int i;
|
||||
for (i=0;i<matList.size();i++) {
|
||||
for (i=0;i<matList.size();i++)
|
||||
{
|
||||
sprintf(ls,"matList[%d] = %d",i,matList[i]); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
|
||||
sprintf(ls,"modelList size = %d",static_cast<int>(modelList.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<modelList.size();i++) {
|
||||
for (i=0;i<modelList.size();i++)
|
||||
{
|
||||
sprintf(ls,"modelList[%d] = %d",i,modelList[i]); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
@ -344,7 +362,8 @@ bool trpgColorInfo::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"type = %d, bind = %d",type,bind); buf.prnLine(ls);
|
||||
sprintf(ls,"colorData size = %d",static_cast<int>(data.size()));
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<data.size();i++) {
|
||||
for (unsigned int i=0;i<data.size();i++)
|
||||
{
|
||||
sprintf(ls,"color[%d] = (%f,%f,%f)",i,data[i].red,data[i].blue,data[i].green); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent(2);
|
||||
@ -363,18 +382,24 @@ bool trpgTexData::Print(trpgPrintBuffer &buf) const
|
||||
buf.IncreaseIndent();
|
||||
|
||||
sprintf(ls,"bind = %d",bind); buf.prnLine(ls);
|
||||
if (floatData.size()) {
|
||||
if (floatData.size())
|
||||
{
|
||||
sprintf(ls,"tex coords (float) = %d",static_cast<int>(floatData.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<floatData.size()/2;i++) {
|
||||
for (unsigned int i=0;i<floatData.size()/2;i++)
|
||||
{
|
||||
sprintf(ls,"tex coord[%d] = (%f,%f)",i,floatData[i*2+0],floatData[i*2+1]); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
} else {
|
||||
if (doubleData.size()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (doubleData.size())
|
||||
{
|
||||
sprintf(ls,"tex coords (double) = %d",static_cast<int>(doubleData.size()));
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<doubleData.size()/2;i++) {
|
||||
for (unsigned int i=0;i<doubleData.size()/2;i++)
|
||||
{
|
||||
sprintf(ls,"tex coord[%d] = (%f,%f)",i,doubleData[i*2+0],doubleData[i*2+1]), buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
@ -400,7 +425,8 @@ bool trpgGeometry::Print(trpgPrintBuffer &buf) const
|
||||
buf.IncreaseIndent();
|
||||
ls[0] = 0;
|
||||
unsigned int i;
|
||||
for (i=0;i<materials.size();i++) {
|
||||
for (i=0;i<materials.size();i++)
|
||||
{
|
||||
char locStr[100];
|
||||
sprintf(locStr,"%d ",materials[i]);
|
||||
strcat(ls,locStr);
|
||||
@ -412,7 +438,8 @@ bool trpgGeometry::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"primLength size = %d",static_cast<int>(primLength.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
ls[0] = 0;
|
||||
for (i=0;i<primLength.size();i++) {
|
||||
for (i=0;i<primLength.size();i++)
|
||||
{
|
||||
char locStr[100];
|
||||
sprintf(locStr,"%d ",primLength[i]);
|
||||
strcat(ls,locStr);
|
||||
@ -420,21 +447,27 @@ bool trpgGeometry::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine(ls);
|
||||
buf.DecreaseIndent();
|
||||
|
||||
if (vertDataFloat.size()) {
|
||||
if (vertDataFloat.size())
|
||||
{
|
||||
sprintf(ls,"vert data (float) length = %d",static_cast<int>(vertDataFloat.size()));
|
||||
buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<vertDataFloat.size()/3;i++) {
|
||||
for (i=0;i<vertDataFloat.size()/3;i++)
|
||||
{
|
||||
sprintf(ls,"(%f, %f, %f)",vertDataFloat[3*i],vertDataFloat[3*i+1],vertDataFloat[3*i+2]);
|
||||
buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
} else {
|
||||
if (vertDataDouble.size()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vertDataDouble.size())
|
||||
{
|
||||
sprintf(ls,"vert data (double) length = %d",static_cast<int>(vertDataDouble.size()));
|
||||
buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<vertDataDouble.size()/3;i++) {
|
||||
for (i=0;i<vertDataDouble.size()/3;i++)
|
||||
{
|
||||
sprintf(ls,"(%f, %f, %f)",vertDataDouble[3*i],vertDataDouble[3*i+1],vertDataDouble[3*i+2]);
|
||||
buf.prnLine(ls);
|
||||
}
|
||||
@ -444,21 +477,27 @@ bool trpgGeometry::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
sprintf(ls,"normBind = %d",normBind); buf.prnLine(ls);
|
||||
|
||||
if (normDataFloat.size()) {
|
||||
if (normDataFloat.size())
|
||||
{
|
||||
sprintf(ls,"norm data (float) length = %d",static_cast<int>(normDataFloat.size()));
|
||||
buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<normDataFloat.size()/3;i++) {
|
||||
for (i=0;i<normDataFloat.size()/3;i++)
|
||||
{
|
||||
sprintf(ls,"(%f, %f, %f)",normDataFloat[3*i],normDataFloat[3*i+1],normDataFloat[3*i+2]);
|
||||
buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
} else {
|
||||
if (normDataDouble.size()) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (normDataDouble.size())
|
||||
{
|
||||
sprintf(ls,"norm data (double) length = %d",static_cast<int>(normDataDouble.size()));
|
||||
buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<normDataDouble.size()/3;i++) {
|
||||
for (i=0;i<normDataDouble.size()/3;i++)
|
||||
{
|
||||
sprintf(ls,"(%f, %f, %f)",normDataDouble[3*i],normDataDouble[3*i+1],normDataDouble[3*i+2]);
|
||||
buf.prnLine(ls);
|
||||
}
|
||||
@ -468,14 +507,16 @@ bool trpgGeometry::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
sprintf(ls,"color info size = %d",static_cast<int>(colors.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<colors.size();i++) {
|
||||
for (i=0;i<colors.size();i++)
|
||||
{
|
||||
colors[i].Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
|
||||
sprintf(ls,"tex data size = %d",static_cast<int>(texData.size()));
|
||||
buf.IncreaseIndent();
|
||||
for (i=0;i<texData.size();i++) {
|
||||
for (i=0;i<texData.size();i++)
|
||||
{
|
||||
texData[i].Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
@ -497,7 +538,7 @@ bool trpgGroup::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine("----Group Node----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"id = %d, numChild = %d",id,numChild); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
|
||||
|
||||
buf.DecreaseIndent();
|
||||
@ -515,7 +556,25 @@ bool trpgAttach::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine("----Attach Node----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"id = %d, parentID = %d, childPos = %d",id,parentID,childPos); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent();
|
||||
buf.prnLine();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Print ChildRef info
|
||||
*/
|
||||
bool trpgChildRef::Print(trpgPrintBuffer &buf) const
|
||||
{
|
||||
char ls[1024];
|
||||
|
||||
buf.prnLine("----RefChild Node----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"lod = %d, x = %d, y = %d", lod, x, y); buf.prnLine(ls);
|
||||
sprintf(ls,"file = %d, offset = %d", addr.file, addr.offset); buf.prnLine(ls);
|
||||
sprintf(ls,"zmin = %f, zmax = %f", zmin, zmax); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent();
|
||||
buf.prnLine();
|
||||
@ -534,7 +593,7 @@ bool trpgBillboard::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"id = %d, type = %d, mode = %d",id,type,mode); buf.prnLine(ls);
|
||||
sprintf(ls,"center = (%f,%f,%f)",center.x,center.y,center.z); buf.prnLine(ls);
|
||||
sprintf(ls,"axis = (%f,%f,%f)",axis.x,axis.y,axis.z); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent();
|
||||
buf.prnLine();
|
||||
@ -554,7 +613,7 @@ bool trpgLod::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"numRange (hint) = %d",numRange); buf.prnLine(ls);
|
||||
sprintf(ls,"switchIn = %f, switchOut = %f, width = %f",switchIn,switchOut,width); buf.prnLine(ls);
|
||||
sprintf(ls,"center = (%f,%f,%f)",center.x,center.y,center.z);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
sprintf(ls,"rangeIndex = %d",rangeIndex); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent();
|
||||
@ -572,7 +631,7 @@ bool trpgLayer::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine("----Layer Node----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"id = %d",id); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent();
|
||||
buf.prnLine();
|
||||
@ -590,12 +649,13 @@ bool trpgTransform::Print(trpgPrintBuffer &buf) const
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"id = %d",id); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (int i=0;i<4;i++) {
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
sprintf(ls,"%f %f %f %f",m[i][0],m[i][1],m[i][2],m[i][3]);
|
||||
buf.prnLine(ls);
|
||||
}
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
|
||||
sprintf(ls,"name = %s", name ? name : "noname" ); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent(2);
|
||||
buf.prnLine();
|
||||
|
||||
@ -612,11 +672,12 @@ bool trpgModelRef::Print(trpgPrintBuffer &buf) const
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"modelRef = %d",modelRef); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (int i=0;i<4;i++) {
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
sprintf(ls,"%f %f %f %f",m[i][0],m[i][1],m[i][2],m[i][3]);
|
||||
buf.prnLine(ls);
|
||||
}
|
||||
|
||||
|
||||
buf.DecreaseIndent(2);
|
||||
buf.prnLine();
|
||||
|
||||
@ -631,14 +692,30 @@ bool trpgTileTable::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
buf.prnLine("----Tile Table----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"mode = %d",mode); buf.prnLine(ls);
|
||||
switch(mode)
|
||||
{
|
||||
case Local:
|
||||
sprintf(ls,"mode = %d(Local)",mode); buf.prnLine(ls);
|
||||
break;
|
||||
case External:
|
||||
sprintf(ls,"mode = %d(External)",mode); buf.prnLine(ls);
|
||||
break;
|
||||
case ExternalSaved:
|
||||
sprintf(ls,"mode = %d(ExternalSaved)",mode); buf.prnLine(ls);
|
||||
break;
|
||||
default:
|
||||
sprintf(ls,"mode = %d",mode); buf.prnLine(ls);
|
||||
}
|
||||
|
||||
sprintf(ls,"numLod = %d",static_cast<int>(lodInfo.size())); buf.prnLine(ls);
|
||||
for (unsigned int i=0;i<lodInfo.size();i++) {
|
||||
for (unsigned int i=0;i<lodInfo.size();i++)
|
||||
{
|
||||
const LodInfo &li = lodInfo[i];
|
||||
sprintf(ls,"LOD %d, numX = %d, numY = %d",i,li.numX,li.numY); buf.prnLine(ls);
|
||||
buf.prnLine("File ID, Offset, Zmin, Zmax");
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int j=0;j<li.addr.size();j++) {
|
||||
for (unsigned int j=0;j<li.addr.size();j++)
|
||||
{
|
||||
sprintf(ls,"%d %d %f %f",li.addr[j].file,li.addr[j].offset,li.elev_min[j],li.elev_max[j]); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
@ -660,7 +737,8 @@ bool trpgLocalMaterial::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"baseMat = %d",baseMat); buf.prnLine(ls);
|
||||
sprintf(ls,"(sx,sy) -> (ex,ey) = (%d,%d) -> (%d,%d)",sx,sy,ex,ey); buf.prnLine(ls);
|
||||
sprintf(ls,"dest (width,height) = (%d,%d)",destWidth,destHeight); buf.prnLine(ls);
|
||||
for (unsigned int i=0;i<addr.size();i++) {
|
||||
for (unsigned int i=0;i<addr.size();i++)
|
||||
{
|
||||
sprintf(ls,"addr (file,offset) = (%d,%d)",addr[i].file,addr[i].offset); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
@ -670,7 +748,7 @@ bool trpgLocalMaterial::Print(trpgPrintBuffer &buf) const
|
||||
}
|
||||
|
||||
/* Light Attribute Print
|
||||
*/
|
||||
*/
|
||||
bool trpgLightAttr::Print(trpgPrintBuffer &buf) const
|
||||
{
|
||||
char ls[1024];
|
||||
@ -681,84 +759,85 @@ bool trpgLightAttr::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
buf.prnLine("----Light Attribute----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"type = %s",strType[(int)(data.type)]); buf.prnLine(ls);
|
||||
sprintf(ls,"directionality = %s",strDirect[(int)(data.directionality)]);buf.prnLine(ls);
|
||||
sprintf(ls,"type = %s",strType[(int)(data.type)]); buf.prnLine(ls);
|
||||
sprintf(ls,"directionality = %s",strDirect[(int)(data.directionality)]); buf.prnLine(ls);
|
||||
sprintf(ls,"front color (RGB) = %.2lf, %.2lf, %.2lf",
|
||||
data.frontColor.red, data.frontColor.green,data.frontColor.blue ); buf.prnLine(ls);
|
||||
sprintf(ls,"front intensity = %.2lf", data.frontIntensity ); buf.prnLine(ls);
|
||||
data.frontColor.red, data.frontColor.green,data.frontColor.blue ); buf.prnLine(ls);
|
||||
sprintf(ls,"front intensity = %.2lf", data.frontIntensity ); buf.prnLine(ls);
|
||||
sprintf(ls,"back color (RGB) = %.2lf, %.2lf, %.2lf",
|
||||
data.backColor.red, data.backColor.green,data.backColor.blue ); buf.prnLine(ls);
|
||||
sprintf(ls,"back intensity = %.2lf", data.backIntensity ); buf.prnLine(ls);
|
||||
data.backColor.red, data.backColor.green,data.backColor.blue ); buf.prnLine(ls);
|
||||
sprintf(ls,"back intensity = %.2lf", data.backIntensity ); buf.prnLine(ls);
|
||||
sprintf(ls,"normal (xyz) = %.2lf,%.2lf,%.2lf",
|
||||
data.normal.x,data.normal.y,data.normal.z ); buf.prnLine(ls);
|
||||
sprintf(ls,"smc = %d",data.smc); buf.prnLine(ls);
|
||||
sprintf(ls,"fid = %d",data.fid); buf.prnLine(ls);
|
||||
data.normal.x,data.normal.y,data.normal.z ); buf.prnLine(ls);
|
||||
sprintf(ls,"smc = %d",data.smc); buf.prnLine(ls);
|
||||
sprintf(ls,"fid = %d",data.fid); buf.prnLine(ls);
|
||||
sprintf(ls,"visible at DAY = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Day ? "yes" : "no") ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Day ? "yes" : "no") ); buf.prnLine(ls);
|
||||
sprintf(ls,"visible at DUSK = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Dusk ? "yes" : "no") ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Dusk ? "yes" : "no") ); buf.prnLine(ls);
|
||||
sprintf(ls,"visible at NIGHT = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Night ? "yes" : "no") ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Night ? "yes" : "no") ); buf.prnLine(ls);
|
||||
sprintf(ls,"enable directionality = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Directional ? "yes" : "no" )); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Directional ? "yes" : "no" )); buf.prnLine(ls);
|
||||
sprintf(ls,"enable back color = %s",
|
||||
(data.flags & trpgLightAttr::trpg_BackColor ? "yes" : "no" )); buf.prnLine(ls);
|
||||
sprintf(ls,"horizontal lobe angle = %.2lf",data.horizontalLobeAngle); buf.prnLine(ls);
|
||||
sprintf(ls,"vertical lobe angle = %.2lf",data.verticalLobeAngle); buf.prnLine(ls);
|
||||
sprintf(ls,"lobe roll angle = %.2lf",data.lobeRollAngle); buf.prnLine(ls);
|
||||
sprintf(ls,"lobe falloff = %.2lf",data.lobeFalloff); buf.prnLine(ls);
|
||||
sprintf(ls,"ambient intensity = %.2lf",data.ambientIntensity); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_BackColor ? "yes" : "no" )); buf.prnLine(ls);
|
||||
sprintf(ls,"horizontal lobe angle = %.2lf",data.horizontalLobeAngle); buf.prnLine(ls);
|
||||
sprintf(ls,"vertical lobe angle = %.2lf",data.verticalLobeAngle); buf.prnLine(ls);
|
||||
sprintf(ls,"lobe roll angle = %.2lf",data.lobeRollAngle); buf.prnLine(ls);
|
||||
sprintf(ls,"lobe falloff = %.2lf",data.lobeFalloff); buf.prnLine(ls);
|
||||
sprintf(ls,"ambient intensity = %.2lf",data.ambientIntensity); buf.prnLine(ls);
|
||||
sprintf(ls,"reflective only = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Reflective ? "yes" : "no") ); buf.prnLine(ls);
|
||||
sprintf(ls,"quality = %s", strQuality[(int)(data.quality)]); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Reflective ? "yes" : "no") ); buf.prnLine(ls);
|
||||
sprintf(ls,"quality = %s", strQuality[(int)(data.quality)]); buf.prnLine(ls);
|
||||
sprintf(ls,"significance for RASCAL lights = %.2lf",
|
||||
data.rascalSignificance ); buf.prnLine(ls);
|
||||
data.rascalSignificance ); buf.prnLine(ls);
|
||||
sprintf(ls,"calligraphic draw order = %d",
|
||||
data.calligraphicAttr.drawOrder ); buf.prnLine(ls);
|
||||
data.calligraphicAttr.drawOrder ); buf.prnLine(ls);
|
||||
sprintf(ls,"calligraphic lights maximum defocus = %f",
|
||||
data.calligraphicAttr.maxDefocus ); buf.prnLine(ls);
|
||||
data.calligraphicAttr.maxDefocus ); buf.prnLine(ls);
|
||||
sprintf(ls,"calligraphic lights minimum defocus = %f",
|
||||
data.calligraphicAttr.minDefocus ); buf.prnLine(ls);
|
||||
data.calligraphicAttr.minDefocus ); buf.prnLine(ls);
|
||||
sprintf(ls,"randomize intensity = %s",
|
||||
strQuality[(int)(data.randomIntensity)]); buf.prnLine(ls);
|
||||
strQuality[(int)(data.randomIntensity)]); buf.prnLine(ls);
|
||||
sprintf(ls,"performer perspective mode = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Perspective ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Perspective ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer fade = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Fade ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Fade ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer fog punch = %s",
|
||||
(data.flags & trpgLightAttr::trpg_FogPunch ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_FogPunch ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer range mode enable Z buffer = %s",
|
||||
(data.flags & trpgLightAttr::trpg_ZBuffer ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_ZBuffer ? "yes" : "no" ) ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer maximum pixel size = %.2lf",
|
||||
data.performerAttr.maxPixelSize ); buf.prnLine(ls);
|
||||
data.performerAttr.maxPixelSize ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer minimum pixel size = %.2lf",
|
||||
data.performerAttr.minPixelSize ); buf.prnLine(ls);
|
||||
data.performerAttr.minPixelSize ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer actual size = %.2lf",
|
||||
data.performerAttr.actualSize ); buf.prnLine(ls);
|
||||
data.performerAttr.actualSize ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer transparent pixel size = %.2lf",
|
||||
data.performerAttr.transparentPixelSize ); buf.prnLine(ls);
|
||||
data.performerAttr.transparentPixelSize ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer transparent falloff exponent = %.2lf",
|
||||
data.performerAttr.transparentFallofExp ); buf.prnLine(ls);
|
||||
data.performerAttr.transparentFallofExp ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer transparent scale = %.2lf",
|
||||
data.performerAttr.transparentScale ); buf.prnLine(ls);
|
||||
data.performerAttr.transparentScale ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer transparent clamp = %.2lf",
|
||||
data.performerAttr.transparentClamp ); buf.prnLine(ls);
|
||||
data.performerAttr.transparentClamp ); buf.prnLine(ls);
|
||||
sprintf(ls,"performer fog scale = %.2lf",
|
||||
data.performerAttr.fogScale ); buf.prnLine(ls);
|
||||
sprintf(ls,"animation period = %.2lf",data.animationAttr.period); buf.prnLine(ls);
|
||||
data.performerAttr.fogScale ); buf.prnLine(ls);
|
||||
sprintf(ls,"animation period = %.2lf",data.animationAttr.period); buf.prnLine(ls);
|
||||
sprintf(ls,"animation phase delay = %.2lf",
|
||||
data.animationAttr.phaseDelay ); buf.prnLine(ls);
|
||||
sprintf(ls,"animation time on = %.2lf",data.animationAttr.timeOn); buf.prnLine(ls);
|
||||
data.animationAttr.phaseDelay ); buf.prnLine(ls);
|
||||
sprintf(ls,"animation time on = %.2lf",data.animationAttr.timeOn); buf.prnLine(ls);
|
||||
sprintf(ls,"animation vector (ijk) = %.2lf, %.2lf, %.2lf",
|
||||
data.animationAttr.vector.x,data.animationAttr.vector.y,
|
||||
data.animationAttr.vector.z); buf.prnLine(ls);
|
||||
data.animationAttr.vector.x,data.animationAttr.vector.y,
|
||||
data.animationAttr.vector.z); buf.prnLine(ls);
|
||||
sprintf(ls,"animation - flashing = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Flashing ? "yes" : "no" )); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Flashing ? "yes" : "no" )); buf.prnLine(ls);
|
||||
sprintf(ls,"animation - rotating = %s",
|
||||
(data.flags & trpgLightAttr::trpg_Rotating ? "yes" : "no" )); buf.prnLine(ls);
|
||||
(data.flags & trpgLightAttr::trpg_Rotating ? "yes" : "no" )); buf.prnLine(ls);
|
||||
sprintf(ls,"animation - counter clockwise = %s",
|
||||
(data.flags & trpgLightAttr::trpg_ClockWise ? "yes" : "no" )); buf.prnLine(ls);
|
||||
if (data.commentStr) {
|
||||
(data.flags & trpgLightAttr::trpg_ClockWise ? "yes" : "no" )); buf.prnLine(ls);
|
||||
if (data.commentStr)
|
||||
{
|
||||
sprintf(ls,"comment = %s",data.commentStr); buf.prnLine(ls);
|
||||
}
|
||||
|
||||
@ -776,19 +855,21 @@ bool trpgLightTable::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
buf.prnLine("----Light Table----");
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<lightList.size();i++) {
|
||||
sprintf(ls,"Light %d",i); buf.prnLine(ls);
|
||||
lightList[i].Print(buf);
|
||||
LightMapType::const_iterator itr = lightMap.begin();
|
||||
for ( ; itr != lightMap.end( ); itr++)
|
||||
{
|
||||
sprintf(ls,"Light %d",itr->first); buf.prnLine(ls);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
|
||||
buf.prnLine();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Print out a light node
|
||||
*/
|
||||
*/
|
||||
|
||||
bool trpgLight::Print(trpgPrintBuffer &buf) const
|
||||
{
|
||||
@ -797,8 +878,8 @@ bool trpgLight::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine("----Light----");
|
||||
buf.IncreaseIndent();
|
||||
|
||||
sprintf(ls,"Light Index = %d",index); buf.prnLine(ls);
|
||||
sprintf(ls,"# Light Locations = %d",static_cast<int>(lightPoints.size()) ); buf.prnLine(ls);
|
||||
sprintf(ls,"Light Index = %d",index); buf.prnLine(ls);
|
||||
sprintf(ls,"# Light Locations = %d",static_cast<int>(lightPoints.size()) ); buf.prnLine(ls);
|
||||
|
||||
buf.DecreaseIndent();
|
||||
|
||||
@ -834,9 +915,11 @@ bool trpgRangeTable::Print(trpgPrintBuffer &buf) const
|
||||
|
||||
buf.prnLine("----Range Table----");
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<rangeList.size();i++) {
|
||||
RangeMapType::const_iterator itr = rangeMap.begin();
|
||||
for (int i = 0; itr != rangeMap.end( ); itr++, i++)
|
||||
{
|
||||
sprintf(ls,"----Range %d----",i); buf.prnLine(ls);
|
||||
rangeList[i].Print(buf);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
|
||||
buf.DecreaseIndent();
|
||||
@ -863,8 +946,9 @@ bool trpgLabel::Print(trpgPrintBuffer &buf) const
|
||||
sprintf(ls,"location: (%f %f %f)",location.x,location.y,location.z); buf.prnLine(ls);
|
||||
sprintf(ls,"%d support points",static_cast<int>(supports.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<supports.size();i++) {
|
||||
sprintf(ls,"%f %f %f",supports[i].x,supports[i].y,supports[i].z); buf.prnLine(ls);
|
||||
for (unsigned int i=0;i<supports.size();i++)
|
||||
{
|
||||
sprintf(ls,"%f %f %f",supports[i].x,supports[i].y,supports[i].z); buf.prnLine(ls);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
buf.prnLine();
|
||||
@ -899,11 +983,13 @@ bool trpgTextStyleTable::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine();
|
||||
buf.prnLine("----Text Style Table----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"numStyle = %d",static_cast<int>(styles.size())); buf.prnLine(ls);
|
||||
sprintf(ls,"numStyle = %d",static_cast<int>(styleMap.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<styles.size();i++) {
|
||||
StyleMapType::const_iterator itr = styleMap.begin();
|
||||
for (int i = 0; itr != styleMap.end( ); itr++, i++)
|
||||
{
|
||||
sprintf(ls,"Style %d",i); buf.prnLine(ls);
|
||||
styles[i].Print(buf);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
buf.DecreaseIndent();
|
||||
@ -935,11 +1021,13 @@ bool trpgSupportStyleTable::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine();
|
||||
buf.prnLine("----Support Style Table----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"numStyle = %d",static_cast<int>(styles.size())); buf.prnLine(ls);
|
||||
sprintf(ls,"numStyle = %d",static_cast<int>(supportStyleMap.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<styles.size();i++) {
|
||||
SupportStyleMapType::const_iterator itr = supportStyleMap.begin();
|
||||
for (int i = 0; itr != supportStyleMap.end( ); itr++, i++)
|
||||
{
|
||||
sprintf(ls,"Style %d",i); buf.prnLine(ls);
|
||||
styles[i].Print(buf);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
buf.DecreaseIndent();
|
||||
@ -973,11 +1061,13 @@ bool trpgLabelPropertyTable::Print(trpgPrintBuffer &buf) const
|
||||
buf.prnLine();
|
||||
buf.prnLine("----Label Property Table----");
|
||||
buf.IncreaseIndent();
|
||||
sprintf(ls,"numProperty = %d",static_cast<int>(properties.size())); buf.prnLine(ls);
|
||||
sprintf(ls,"numProperty = %d",static_cast<int>(labelPropertyMap.size())); buf.prnLine(ls);
|
||||
buf.IncreaseIndent();
|
||||
for (unsigned int i=0;i<properties.size();i++) {
|
||||
LabelPropertyMapType::const_iterator itr = labelPropertyMap.begin();
|
||||
for (int i = 0; itr != labelPropertyMap.end( ); itr++, i++)
|
||||
{
|
||||
sprintf(ls,"Property %d",i); buf.prnLine(ls);
|
||||
properties[i].Print(buf);
|
||||
itr->second.Print(buf);
|
||||
}
|
||||
buf.DecreaseIndent();
|
||||
buf.DecreaseIndent();
|
||||
|
@ -17,13 +17,16 @@
|
||||
#define trpage_print_h_
|
||||
|
||||
#include <trpage_read.h>
|
||||
#include <trpage_managers.h>
|
||||
#include <stack>
|
||||
|
||||
/* 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.
|
||||
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 {
|
||||
TX_EXDECL class TX_CLDECL trpgPrintBuffer
|
||||
{
|
||||
public:
|
||||
trpgPrintBuffer(void);
|
||||
virtual ~trpgPrintBuffer(void) { };
|
||||
@ -38,17 +41,17 @@ public:
|
||||
virtual void IncreaseIndent(int amount=1);
|
||||
// Decreases the current indentation by the amount given (defaults to one)
|
||||
virtual void DecreaseIndent(int amount=1);
|
||||
protected:
|
||||
protected:
|
||||
void updateIndent(void);
|
||||
int curIndent;
|
||||
char indentStr[200];
|
||||
};
|
||||
|
||||
/* File print buffer for TerraPage. The file print buffer writes
|
||||
debugging output to a file.
|
||||
*/
|
||||
debugging output to a file.
|
||||
*/
|
||||
TX_EXDECL class TX_CLDECL trpgFilePrintBuffer : public trpgPrintBuffer {
|
||||
public:
|
||||
public:
|
||||
// This class can be constructed with either a FILE pointer or a file name
|
||||
trpgFilePrintBuffer(FILE *);
|
||||
trpgFilePrintBuffer(char *);
|
||||
@ -59,47 +62,83 @@ public:
|
||||
|
||||
// For a file printer buffer, this writes a string out to a file
|
||||
bool prnLine(char *str = NULL);
|
||||
protected:
|
||||
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:
|
||||
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(trpgr_Archive *,trpgrImageHelper *,trpgPrintBuffer *);
|
||||
virtual ~trpgPrintGraphParser(void) { };
|
||||
|
||||
// Clear all list and free associated pointer
|
||||
void Reset();
|
||||
|
||||
// After parsing this will return the number of trpgChildRef node found.
|
||||
unsigned int GetNbChildrenRef() const;
|
||||
// This will return the trpgChildRef node pointer associated with the index.
|
||||
// Will return 0 if index is out of bound
|
||||
const trpgChildRef* GetChildRef(unsigned int idx) const;
|
||||
|
||||
/* 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 {
|
||||
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(trpgPrintGraphParser *inPG,trpgPrintBuffer *inBuf) {pBuf = inBuf; parse = inPG;};
|
||||
void *Parse(trpgToken,trpgReadBuffer &buf);
|
||||
// typedef std::vector<const trpgChildRef> ChildRefList;
|
||||
// The const in the template parameter was removed because it causes GCC to
|
||||
// freak out. I am of the opinion that const doesn't make sense in a template
|
||||
// parameter for std::vector anyway... const prevents you from changing the
|
||||
// value, so what exactly is the point? How does one add entries to the vector
|
||||
// without giving them a value? -ADS
|
||||
typedef std::vector<trpgChildRef> ChildRefList;
|
||||
|
||||
ReadHelper(trpgPrintGraphParser *inPG,trpgPrintBuffer *inBuf): pBuf(inBuf), parse(inPG) {}
|
||||
~ReadHelper() { Reset();}
|
||||
|
||||
void *Parse(trpgToken,trpgReadBuffer &buf);
|
||||
void Reset();
|
||||
// After parsing this will return the number of trpgChildRef node found.
|
||||
unsigned int GetNbChildrenRef() const;
|
||||
// This will return the trpgChildRef node associated with the index.
|
||||
// this will retrun 0 if idx is out of bound
|
||||
const trpgChildRef* GetChildRef(unsigned int idx) const;
|
||||
protected:
|
||||
trpgPrintBuffer *pBuf;
|
||||
trpgPrintGraphParser *parse;
|
||||
trpgPrintBuffer *pBuf;
|
||||
trpgPrintGraphParser *parse;
|
||||
|
||||
private:
|
||||
|
||||
ChildRefList childRefList;
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Fetch the archive associated with this print
|
||||
trpgr_Archive *GetArchive() {return archive; };
|
||||
trpgrImageHelper *GetImageHelp() {return imageHelp; };
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
bool StartChildren(void *);
|
||||
bool EndChildren(void *);
|
||||
|
||||
trpgPrintBuffer *printBuf;
|
||||
trpgr_Archive *archive;
|
||||
trpgrImageHelper *imageHelp;
|
||||
|
||||
ReadHelper *childRefCB;
|
||||
|
||||
};
|
||||
|
||||
// Print utitility for while archive
|
||||
|
@ -14,9 +14,9 @@
|
||||
*/
|
||||
|
||||
/* trpage_range.cpp
|
||||
Methods for the Range Table. Consult trpg_geom.h for details
|
||||
on what this is and how it works.
|
||||
*/
|
||||
Methods for the Range Table. Consult trpg_geom.h for details
|
||||
on what this is and how it works.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -26,290 +26,328 @@
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* *******************
|
||||
Range Methods
|
||||
Range Methods
|
||||
*******************
|
||||
*/
|
||||
|
||||
trpgRange::trpgRange(void)
|
||||
{
|
||||
category = NULL;
|
||||
subCategory = NULL;
|
||||
Reset();
|
||||
category = NULL;
|
||||
subCategory = NULL;
|
||||
Reset();
|
||||
}
|
||||
|
||||
trpgRange::~trpgRange(void)
|
||||
{
|
||||
Reset();
|
||||
Reset();
|
||||
}
|
||||
|
||||
trpgRange::trpgRange(const trpgRange &in):
|
||||
trpgReadWriteable(in)
|
||||
{
|
||||
category = NULL;
|
||||
subCategory = NULL;
|
||||
*this = in;
|
||||
category = NULL;
|
||||
subCategory = NULL;
|
||||
*this = in;
|
||||
}
|
||||
|
||||
void trpgRange::Reset(void)
|
||||
{
|
||||
errMess[0] = '\0';
|
||||
if (category)
|
||||
delete [] category;
|
||||
category = NULL;
|
||||
if (subCategory)
|
||||
delete [] subCategory;
|
||||
subCategory = NULL;
|
||||
errMess[0] = '\0';
|
||||
if (category)
|
||||
delete [] category;
|
||||
category = NULL;
|
||||
if (subCategory)
|
||||
delete [] subCategory;
|
||||
subCategory = NULL;
|
||||
|
||||
inLod = outLod = 0.0;
|
||||
priority = 0;
|
||||
inLod = outLod = 0.0;
|
||||
priority = 0;
|
||||
handle = -1;
|
||||
writeHandle = false;
|
||||
}
|
||||
|
||||
void trpgRange::SetCategory(const char *cat,const char *subCat)
|
||||
{
|
||||
if (category) delete [] category;
|
||||
category = NULL;
|
||||
if (cat) {
|
||||
category = new char[strlen(cat)+1];
|
||||
strcpy(category,cat);
|
||||
}
|
||||
if (category) delete [] category;
|
||||
category = NULL;
|
||||
if (cat) {
|
||||
category = new char[strlen(cat)+1];
|
||||
strcpy(category,cat);
|
||||
}
|
||||
|
||||
if (subCategory) delete [] subCategory;
|
||||
subCategory = NULL;
|
||||
if (subCat) {
|
||||
subCategory = new char[strlen(subCat)+1];
|
||||
strcpy(subCategory,subCat);
|
||||
}
|
||||
if (subCategory) delete [] subCategory;
|
||||
subCategory = NULL;
|
||||
if (subCat) {
|
||||
subCategory = new char[strlen(subCat)+1];
|
||||
strcpy(subCategory,subCat);
|
||||
}
|
||||
}
|
||||
|
||||
void trpgRange::GetCategory(char *cat,int catLen,char *subCat,int subCatLen) const
|
||||
{
|
||||
if (category && cat) {
|
||||
strncpy(cat,category,catLen);
|
||||
} else
|
||||
*cat = 0;
|
||||
if (subCategory && subCat) {
|
||||
strncpy(subCat,subCategory,subCatLen);
|
||||
} else
|
||||
*subCat = 0;
|
||||
if (category && cat) {
|
||||
strncpy(cat,category,catLen);
|
||||
} else
|
||||
*cat = 0;
|
||||
if (subCategory && subCat) {
|
||||
strncpy(subCat,subCategory,subCatLen);
|
||||
} else
|
||||
*subCat = 0;
|
||||
}
|
||||
|
||||
void trpgRange::SetLodInfo(double in,double out)
|
||||
{
|
||||
inLod = in;
|
||||
outLod = out;
|
||||
inLod = in;
|
||||
outLod = out;
|
||||
}
|
||||
|
||||
void trpgRange::GetLodInfo(double &in,double &out) const
|
||||
{
|
||||
in = inLod;
|
||||
out = outLod;
|
||||
in = inLod;
|
||||
out = outLod;
|
||||
}
|
||||
|
||||
void trpgRange::SetPriority(int prior)
|
||||
{
|
||||
priority = prior;
|
||||
priority = prior;
|
||||
}
|
||||
|
||||
void trpgRange::GetPriority(int &prior) const
|
||||
{
|
||||
prior = priority;
|
||||
prior = priority;
|
||||
}
|
||||
|
||||
trpgRange & trpgRange::operator = (const trpgRange &other)
|
||||
{
|
||||
Reset();
|
||||
inLod = other.inLod;
|
||||
outLod = other.outLod;
|
||||
SetCategory(other.category,other.subCategory);
|
||||
priority = other.priority;
|
||||
|
||||
return *this;
|
||||
Reset();
|
||||
inLod = other.inLod;
|
||||
outLod = other.outLod;
|
||||
SetCategory(other.category,other.subCategory);
|
||||
priority = other.priority;
|
||||
handle = other.handle;
|
||||
writeHandle = other.writeHandle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool trpgRange::operator == (const trpgRange &in) const
|
||||
{
|
||||
if (inLod != in.inLod || outLod != in.outLod)
|
||||
return false;
|
||||
if (priority != in.priority) return false;
|
||||
if (inLod != in.inLod || outLod != in.outLod)
|
||||
return false;
|
||||
if (priority != in.priority) return false;
|
||||
|
||||
if (category && in.category) {
|
||||
if (strcmp(category,in.category))
|
||||
return false;
|
||||
} else {
|
||||
if (category && !in.category ||
|
||||
!category && in.category)
|
||||
return false;
|
||||
}
|
||||
if (category && in.category) {
|
||||
if (strcmp(category,in.category))
|
||||
return false;
|
||||
} else {
|
||||
if (category && !in.category ||
|
||||
!category && in.category)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (subCategory && in.subCategory) {
|
||||
if (strcmp(subCategory,in.subCategory))
|
||||
return false;
|
||||
} else {
|
||||
if (subCategory && !in.subCategory ||
|
||||
!subCategory && in.subCategory)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (subCategory && in.subCategory) {
|
||||
if (strcmp(subCategory,in.subCategory))
|
||||
return false;
|
||||
} else {
|
||||
if (subCategory && !in.subCategory ||
|
||||
!subCategory && in.subCategory)
|
||||
return false;
|
||||
}
|
||||
if(handle != in.handle)
|
||||
return false;
|
||||
if(writeHandle != in.writeHandle)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgRange::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
buf.Begin(TRPG_RANGE);
|
||||
buf.Add(inLod);
|
||||
buf.Add(outLod);
|
||||
buf.Add(priority);
|
||||
buf.Add((category ? category : ""));
|
||||
buf.Add((subCategory ? subCategory : ""));
|
||||
buf.End();
|
||||
buf.Begin(TRPG_RANGE);
|
||||
buf.Add(inLod);
|
||||
buf.Add(outLod);
|
||||
buf.Add(priority);
|
||||
buf.Add((category ? category : ""));
|
||||
buf.Add((subCategory ? subCategory : ""));
|
||||
if(writeHandle) {
|
||||
buf.Add((int32)handle);
|
||||
}
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgRange::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
char catStr[1024],subStr[1024];
|
||||
char catStr[1024],subStr[1024];
|
||||
|
||||
Reset();
|
||||
valid = false;
|
||||
Reset();
|
||||
valid = false;
|
||||
|
||||
try {
|
||||
buf.Get(inLod);
|
||||
buf.Get(outLod);
|
||||
buf.Get(priority);
|
||||
buf.Get(catStr,1024);
|
||||
buf.Get(subStr,1024);
|
||||
SetCategory(catStr,subStr);
|
||||
valid = true;
|
||||
}
|
||||
try {
|
||||
buf.Get(inLod);
|
||||
buf.Get(outLod);
|
||||
buf.Get(priority);
|
||||
buf.Get(catStr,1024);
|
||||
buf.Get(subStr,1024);
|
||||
SetCategory(catStr,subStr);
|
||||
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
// Read the handle if we can..
|
||||
try {
|
||||
if(!buf.Get((int32 &)handle)) {
|
||||
handle = -1;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
handle = -1;
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* ***************
|
||||
Range Table methods
|
||||
***************
|
||||
Range Table methods
|
||||
***************
|
||||
*/
|
||||
|
||||
trpgRangeTable::trpgRangeTable(void)
|
||||
{
|
||||
valid = true;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
trpgRangeTable::~trpgRangeTable(void)
|
||||
{
|
||||
// vector cleans up itself
|
||||
// vector cleans up itself
|
||||
}
|
||||
|
||||
void trpgRangeTable::Reset(void)
|
||||
{
|
||||
rangeList.resize(0);
|
||||
valid = true;
|
||||
rangeMap.clear();
|
||||
valid = true;
|
||||
}
|
||||
|
||||
bool trpgRangeTable::GetRange(int id,trpgRange &ret) const
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
if (id < 0 || id >= (int)rangeList.size())
|
||||
return false;
|
||||
if (id < 0)// || id >= rangeList.size())
|
||||
return false;
|
||||
|
||||
ret = rangeList[id];
|
||||
|
||||
return true;
|
||||
RangeMapType::const_iterator itr = rangeMap.find(id);
|
||||
if(itr == rangeMap.end()) {
|
||||
return false;
|
||||
}
|
||||
ret = itr->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgRangeTable::SetRange(int id,trpgRange &inRange)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
if (id < 0 || id >= (int)rangeList.size())
|
||||
return false;
|
||||
if (id < 0)// || id >= rangeList.size())
|
||||
return false;
|
||||
|
||||
rangeList[id] = inRange;
|
||||
rangeMap[id] = inRange;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int trpgRangeTable::AddRange(trpgRange &range)
|
||||
{
|
||||
rangeList.push_back(range);
|
||||
int handle = range.GetHandle();
|
||||
if(handle==-1) {
|
||||
handle = rangeMap.size();
|
||||
}
|
||||
rangeMap[handle] = range;
|
||||
return handle;
|
||||
|
||||
return rangeList.size()-1;
|
||||
}
|
||||
|
||||
int trpgRangeTable::FindAddRange(trpgRange &range)
|
||||
{
|
||||
for (unsigned int i=0;i<rangeList.size();i++) {
|
||||
if (range == rangeList[i])
|
||||
return i;
|
||||
}
|
||||
RangeMapType::iterator itr = rangeMap.begin();
|
||||
for ( ; itr != rangeMap.end( ); itr++) {
|
||||
if(itr->second==range)
|
||||
return itr->first;
|
||||
}
|
||||
|
||||
return AddRange(range);
|
||||
#if 0
|
||||
for (int i=0;i<rangeList.size();i++) {
|
||||
if (range == rangeList[i])
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
return AddRange(range);
|
||||
}
|
||||
|
||||
bool trpgRangeTable::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGRANGETABLE);
|
||||
buf.Add((int32)rangeList.size());
|
||||
buf.Begin(TRPGRANGETABLE);
|
||||
buf.Add((int32)rangeMap.size());
|
||||
|
||||
for (unsigned int i=0;i<rangeList.size();i++) {
|
||||
trpgRange &range = rangeList[i];
|
||||
range.Write(buf);
|
||||
}
|
||||
RangeMapType::iterator itr = rangeMap.begin();
|
||||
for ( ; itr != rangeMap.end( ); itr++) {
|
||||
trpgRange &range = itr->second;
|
||||
range.Write(buf);
|
||||
}
|
||||
|
||||
buf.End();
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgRangeTable::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
int32 numRange;
|
||||
trpgToken tok;
|
||||
int32 len;
|
||||
valid = false;
|
||||
int32 numRange;
|
||||
trpgToken tok;
|
||||
int32 len;
|
||||
valid = false;
|
||||
|
||||
try {
|
||||
buf.Get(numRange);
|
||||
if (numRange < 0) throw 1;
|
||||
for (int i=0;i<numRange;i++) {
|
||||
// Read in the individual range
|
||||
buf.GetToken(tok,len);
|
||||
if (tok != TRPG_RANGE) throw 1;
|
||||
buf.PushLimit(len);
|
||||
trpgRange range;
|
||||
bool status = range.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
rangeList.push_back(range);
|
||||
}
|
||||
try {
|
||||
buf.Get(numRange);
|
||||
if (numRange < 0) throw 1;
|
||||
for (int i=0;i<numRange;i++) {
|
||||
// Read in the individual range
|
||||
buf.GetToken(tok,len);
|
||||
if (tok != TRPG_RANGE) throw 1;
|
||||
buf.PushLimit(len);
|
||||
trpgRange range;
|
||||
bool status = range.Read(buf);
|
||||
buf.PopLimit();
|
||||
if (!status) throw 1;
|
||||
AddRange(range);
|
||||
}
|
||||
|
||||
valid = true;
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
return isValid();
|
||||
}
|
||||
|
||||
trpgRangeTable & trpgRangeTable::operator = (const trpgRangeTable &inTab)
|
||||
{
|
||||
Reset();
|
||||
Reset();
|
||||
RangeMapType::const_iterator itr = inTab.rangeMap.begin();
|
||||
for ( ; itr != inTab.rangeMap.end( ); itr++)
|
||||
rangeMap[itr->first] = itr->second;
|
||||
|
||||
for (unsigned int i=0;i<inTab.rangeList.size();i++)
|
||||
rangeList.push_back(inTab.rangeList[i]);
|
||||
|
||||
return *this;
|
||||
#if 0
|
||||
for (int i=0;i<inTab.rangeList.size();i++)
|
||||
rangeList.push_back(inTab.rangeList[i]);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
@ -18,9 +18,9 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_rarchive.cpp
|
||||
This source file implements the methods for a trpgr_Archive.
|
||||
The Read Archive is used to read a paging archive from disk.
|
||||
*/
|
||||
This source file implements the methods for a trpgr_Archive.
|
||||
The Read Archive is used to read a paging archive from disk.
|
||||
*/
|
||||
|
||||
#include <trpage_read.h>
|
||||
#include <trpage_compat.h>
|
||||
@ -38,10 +38,15 @@ trpgr_Archive::trpgr_Archive()
|
||||
trpgr_Archive::~trpgr_Archive()
|
||||
{
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
if (tileCache)
|
||||
delete tileCache;
|
||||
delete tileCache;
|
||||
}
|
||||
|
||||
int32 trpgr_Archive::GetHeaderData(char *dataPtr, int length, FILE *filehandle)
|
||||
{
|
||||
return fread(dataPtr,1,length,filehandle);
|
||||
}
|
||||
|
||||
// Set the directory where the archive is
|
||||
@ -60,72 +65,169 @@ bool trpgr_Archive::OpenFile(const char *name)
|
||||
CloseFile();
|
||||
|
||||
if (!(fp = fopen(file,"rb")))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Look for a magic # and endianness
|
||||
int32 magic;
|
||||
if (fread(&magic,sizeof(int32),1,fp) != 1)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
headerRead = false;
|
||||
|
||||
// Figure out the endianness from the magic number
|
||||
trpgEndian cpuNess = trpg_cpu_byte_order();
|
||||
if (magic == TRPG_MAGIC) {
|
||||
ness = cpuNess;
|
||||
return true;
|
||||
if (magic == GetMagicNumber()) {
|
||||
ness = cpuNess;
|
||||
return true;
|
||||
}
|
||||
if (trpg_byteswap_int(magic) == TRPG_MAGIC) {
|
||||
if (cpuNess == LittleEndian)
|
||||
ness = BigEndian;
|
||||
else
|
||||
ness = LittleEndian;
|
||||
return true;
|
||||
if (trpg_byteswap_int(magic) == GetMagicNumber()) {
|
||||
if (cpuNess == LittleEndian)
|
||||
ness = BigEndian;
|
||||
else
|
||||
ness = LittleEndian;
|
||||
return true;
|
||||
}
|
||||
if (magic != TRPG_MAGIC)
|
||||
return false;
|
||||
if (magic != GetMagicNumber())
|
||||
return false;
|
||||
|
||||
// Not one of our files
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get new reading app file cache
|
||||
trpgrAppFileCache* trpgr_Archive::GetNewRAppFileCache(const char *fullBase, const char *ext)
|
||||
{
|
||||
return new trpgrAppFileCache(fullBase,ext);
|
||||
}
|
||||
|
||||
trpgrImageHelper* trpgr_Archive::GetNewRImageHelper(trpgEndian ness,char *dir,const trpgMatTable &matTable,const trpgTexTable &texTable)
|
||||
{
|
||||
bool separateGeo = false;
|
||||
int majorVer,minorVer;
|
||||
GetHeader()->GetVersion(majorVer,minorVer);
|
||||
if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer>=TRPG_NOMERGE_VERSION_MINOR)) {
|
||||
separateGeo = true;
|
||||
}
|
||||
return new trpgrImageHelper(ness,dir,matTable,texTable,separateGeo);
|
||||
}
|
||||
|
||||
// Close File
|
||||
// Close the currently open file
|
||||
void trpgr_Archive::CloseFile()
|
||||
{
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
if (tileCache)
|
||||
delete tileCache;
|
||||
delete tileCache;
|
||||
tileCache = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a sub block from a 2.2 TXP database. This can be called any time after ReadHeader is called
|
||||
* if ReadHeader is called with the false parameter to specify not to read all the sub-archives.
|
||||
* This can make a huge improvement in startup time for loading a very large archive with many blocks.
|
||||
**/
|
||||
bool trpgr_Archive::ReadSubArchive(int row, int col, trpgEndian cpuNess)
|
||||
{
|
||||
int ret;
|
||||
trpgHeader blockHeader;
|
||||
trpgr_Parser bparser;
|
||||
|
||||
char blockpath[1024];
|
||||
//open the block archive
|
||||
// the block archive will be in the base dir + \\cols\\row\\archive.txp
|
||||
sprintf(blockpath,"%s%s%d%s%d%sarchive.txp",dir,PATHSEPERATOR,col,PATHSEPERATOR,row,PATHSEPERATOR);
|
||||
FILE *bfp = fopen(blockpath,"rb");
|
||||
if(!bfp) {
|
||||
return false;
|
||||
}
|
||||
// Look for a magic # and endianness
|
||||
int32 bmagic;
|
||||
if (fread(&bmagic,sizeof(int32),1,bfp) != 1)
|
||||
return false;
|
||||
// The block archive will always be the same endianness as the master
|
||||
if ( (bmagic != GetMagicNumber()) && (trpg_byteswap_int(bmagic) != GetMagicNumber()) )
|
||||
return false;
|
||||
|
||||
int32 bheaderSize=0;
|
||||
if (fread(&bheaderSize,sizeof(int32),1,bfp) != 1)
|
||||
return false;
|
||||
if (ness != cpuNess)
|
||||
bheaderSize = trpg_byteswap_int(bheaderSize);
|
||||
int bheadLen = bheaderSize;
|
||||
if (bheadLen < 0)
|
||||
return false;
|
||||
|
||||
// Read in the header whole
|
||||
trpgMemReadBuffer bbuf(ness);
|
||||
bbuf.SetLength(bheadLen);
|
||||
char *bdata = bbuf.GetDataPtr();
|
||||
if ((ret = GetHeaderData(bdata,bheadLen,bfp)) != bheadLen)
|
||||
return false;
|
||||
//keep track of where this came from in the master table.
|
||||
tileTable.SetCurrentBlock(row,col,true);
|
||||
texTable.SetCurrentBlock(row,col);
|
||||
|
||||
bparser.AddCallback(TRPGHEADER,&blockHeader);
|
||||
bparser.AddCallback(TRPGMATTABLE,&materialTable); // Went back to oldest style for 2.0
|
||||
//if(!headerHasTexTable) {
|
||||
bparser.AddCallback(TRPGTEXTABLE2,&texTable); // Added for 2.0
|
||||
//}
|
||||
bparser.AddCallback(TRPGMODELTABLE,&modelTable);
|
||||
bparser.AddCallback(TRPGLIGHTTABLE,&lightTable); // Added for 2.0
|
||||
bparser.AddCallback(TRPGRANGETABLE,&rangeTable); // Added for 2.0
|
||||
bparser.AddCallback(TRPG_TEXT_STYLE_TABLE,&textStyleTable); // Added for 2.1
|
||||
bparser.AddCallback(TRPG_SUPPORT_STYLE_TABLE,&supportStyleTable);
|
||||
bparser.AddCallback(TRPG_LABEL_PROPERTY_TABLE,&labelPropertyTable);
|
||||
// Don't read the tile table for v1.0 archives
|
||||
// It's only really used for 2.0 archives
|
||||
bparser.AddCallback(TRPGTILETABLE2,&tileTable);
|
||||
|
||||
// Parse the buffer
|
||||
if (!bparser.Parse(bbuf))
|
||||
return false;
|
||||
//close the block archive
|
||||
fclose(bfp);
|
||||
|
||||
tileTable.SetCurrentBlock(-1,-1,false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgr_Archive::ReadHeader()
|
||||
{
|
||||
return ReadHeader(true);
|
||||
}
|
||||
|
||||
// Read Header
|
||||
// Run through the rest of the header information
|
||||
bool trpgr_Archive::ReadHeader()
|
||||
bool trpgr_Archive::ReadHeader(bool readAllBlocks)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!fp || headerRead)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
headerRead = true;
|
||||
|
||||
// Next int64 should be the header size
|
||||
trpgEndian cpuNess = trpg_cpu_byte_order();
|
||||
int32 headerSize;
|
||||
if (fread(&headerSize,sizeof(int32),1,fp) != 1) return false;
|
||||
if (fread(&headerSize,sizeof(int32),1,fp) != 1)
|
||||
return false;
|
||||
if (ness != cpuNess)
|
||||
headerSize = trpg_byteswap_int(headerSize);
|
||||
headerSize = trpg_byteswap_int(headerSize);
|
||||
int headLen = headerSize;
|
||||
if (headLen < 0) return false;
|
||||
if (headLen < 0)
|
||||
return false;
|
||||
|
||||
// Read in the header whole
|
||||
trpgMemReadBuffer buf(ness);
|
||||
buf.SetLength(headLen);
|
||||
char *data = buf.GetDataPtr();
|
||||
if ((ret = fread(data,1,headLen,fp)) != headLen) return false;
|
||||
if ((ret = GetHeaderData(data,headLen,fp)) != headLen)
|
||||
return false;
|
||||
|
||||
// Set up a parser
|
||||
// Catch the tables we need for the archive
|
||||
@ -136,37 +238,72 @@ bool trpgr_Archive::ReadHeader()
|
||||
parser.AddCallback(TRPGMATTABLE,&materialTable); // Went back to oldest style for 2.0
|
||||
parser.AddCallback(TRPGMATTABLE2,&oldMatTable); // Added 11-14-98 (1.0 material table)
|
||||
parser.AddCallback(TRPGTEXTABLE,&oldTexTable);
|
||||
parser.AddCallback(TRPGTEXTABLE2,&texTable); // Added for 2.0
|
||||
parser.AddCallback(TRPGTEXTABLE2,&texTable); // Added for 2.0
|
||||
parser.AddCallback(TRPGMODELTABLE,&modelTable);
|
||||
parser.AddCallback(TRPGLIGHTTABLE,&lightTable); // Added for 2.0
|
||||
parser.AddCallback(TRPGRANGETABLE,&rangeTable); // Added for 2.0
|
||||
parser.AddCallback(TRPG_TEXT_STYLE_TABLE,&textStyleTable); // Added for 2.1
|
||||
parser.AddCallback(TRPG_SUPPORT_STYLE_TABLE,&supportStyleTable);
|
||||
parser.AddCallback(TRPG_LABEL_PROPERTY_TABLE,&labelPropertyTable);
|
||||
parser.AddCallback(TRPGLIGHTTABLE,&lightTable); // Added for 2.0
|
||||
parser.AddCallback(TRPGRANGETABLE,&rangeTable); // Added for 2.0
|
||||
parser.AddCallback(TRPG_TEXT_STYLE_TABLE,&textStyleTable); // Added for 2.1
|
||||
parser.AddCallback(TRPG_SUPPORT_STYLE_TABLE,&supportStyleTable);
|
||||
parser.AddCallback(TRPG_LABEL_PROPERTY_TABLE,&labelPropertyTable);
|
||||
// Don't read the tile table for v1.0 archives
|
||||
// It's only really used for 2.0 archives
|
||||
parser.AddCallback(TRPGTILETABLE2,&tileTable);
|
||||
|
||||
// Parse the buffer
|
||||
if (!parser.Parse(buf))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
if(header.GetIsMaster())
|
||||
{
|
||||
// bool firstBlock = true;
|
||||
bool headerHasTexTable = false;
|
||||
//if the master has textures, we want to use them instead of the tables in the
|
||||
//block archives
|
||||
int numTex = 0;
|
||||
texTable.GetNumTextures(numTex);
|
||||
if(numTex)
|
||||
headerHasTexTable = true;
|
||||
// int numTiles = 0;
|
||||
//tileTable.
|
||||
int totalrows,totalcols;
|
||||
trpg2dPoint mhdr_swExtents;
|
||||
trpg2dPoint mhdr_neExtents;
|
||||
trpg3dPoint mhdr_Origin;
|
||||
// integrate header information from the block header.
|
||||
header.GetExtents(mhdr_swExtents,mhdr_neExtents);
|
||||
header.GetOrigin(mhdr_Origin);
|
||||
header.GetBlocks(totalrows,totalcols);
|
||||
if(readAllBlocks) {
|
||||
for(int row=0;row<totalrows;row++) {
|
||||
for(int col=0;col<totalcols;col++) {
|
||||
// Read each block -- Warning, this can take a while!!!
|
||||
ReadSubArchive( row, col, cpuNess);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ReadSubArchive( 0, 0, cpuNess);//Get the first archive!
|
||||
}
|
||||
|
||||
}
|
||||
tileTable.SetCurrentBlock(-1,-1,false);
|
||||
|
||||
// 1.0 Compatibility
|
||||
// If we see an older style material table, convert it to the new style
|
||||
// This isn't terribly memory efficient, but it does work
|
||||
if (oldMatTable.isValid())
|
||||
materialTable = oldMatTable;
|
||||
materialTable = oldMatTable;
|
||||
if (oldTexTable.isValid())
|
||||
texTable = oldTexTable;
|
||||
texTable = oldTexTable;
|
||||
|
||||
// Set up a tile cache, if needed
|
||||
trpgTileTable::TileMode tileMode;
|
||||
tileTable.GetMode(tileMode);
|
||||
if (tileMode == trpgTileTable::Local) {
|
||||
if (tileCache) delete tileCache;
|
||||
char fullBase[1024];
|
||||
sprintf(fullBase,"%s" PATHSEPERATOR "tileFile",dir);
|
||||
tileCache = new trpgrAppFileCache(fullBase,"tpf");
|
||||
if (tileCache) delete tileCache;
|
||||
char fullBase[1024];
|
||||
sprintf(fullBase,"%s" PATHSEPERATOR "tileFile",dir);
|
||||
tileCache = GetNewRAppFileCache(fullBase,"tpf");
|
||||
}
|
||||
|
||||
valid = true;
|
||||
@ -176,65 +313,116 @@ bool trpgr_Archive::ReadHeader()
|
||||
|
||||
// Read Tile
|
||||
// Read a tile into a read buffer
|
||||
// For version 2.1 only tile with lod=0 are stored in the tile table, so an
|
||||
// error will be returned if you try to use the table with a differrent lod.
|
||||
bool trpgr_Archive::ReadTile(uint32 x,uint32 y,uint32 lod,trpgMemReadBuffer &buf)
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
// Reality check the address
|
||||
int32 numLods;
|
||||
header.GetNumLods(numLods);
|
||||
if (lod >= (unsigned int)numLods) return false;
|
||||
if (static_cast<int>(lod) >= numLods)
|
||||
return false;
|
||||
trpg2iPoint lodSize;
|
||||
header.GetLodSize(lod,lodSize);
|
||||
if (x >= (unsigned int)lodSize.x || y >= (unsigned int)lodSize.y) return false;
|
||||
if (static_cast<int>(x) >= lodSize.x || static_cast<int>(y) >= lodSize.y)
|
||||
return false;
|
||||
|
||||
trpgTileTable::TileMode tileMode;
|
||||
tileTable.GetMode(tileMode);
|
||||
|
||||
if (tileMode == trpgTileTable::External) {
|
||||
// Figure out the file name
|
||||
// Note: This assumes External tiles
|
||||
char filename[1024];
|
||||
sprintf(filename,"%s" PATHSEPERATOR "tile_%d_%d_%d.tpt",dir,x,y,lod);
|
||||
|
||||
// Open the file and read the contents
|
||||
FILE *fp=NULL;
|
||||
try {
|
||||
if (!(fp = fopen(filename,"rb"))) throw 1;
|
||||
// Find the file end
|
||||
if (fseek(fp,0,SEEK_END)) throw 1;
|
||||
// Note: This means tile is capped at 2 gigs
|
||||
long pos = ftell(fp);
|
||||
if (fseek(fp,0,SEEK_SET)) throw 1;
|
||||
// Now we know the size. Read the whole file
|
||||
buf.SetLength(pos);
|
||||
char *data = buf.GetDataPtr();
|
||||
if (fread(data,pos,1,fp) != 1) throw 1;
|
||||
fclose(fp); fp = NULL;
|
||||
}
|
||||
catch (...) {
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
bool status = true;
|
||||
if (tileMode == trpgTileTable::External || tileMode == trpgTileTable::ExternalSaved) {
|
||||
status = ReadExternalTile(x, y, lod, buf);
|
||||
|
||||
} else {
|
||||
// Local tile. Figure out where it is (which file)
|
||||
trpgwAppAddress addr;
|
||||
float zmin,zmax;
|
||||
if (!tileTable.GetTile(x,y,lod,addr,zmin,zmax))
|
||||
return false;
|
||||
// Local tile. Figure out where it is (which file)
|
||||
int majorVersion, minorVersion;
|
||||
header.GetVersion(majorVersion, minorVersion);
|
||||
if(majorVersion == 2 && minorVersion >=1)
|
||||
{
|
||||
// Version 2.1
|
||||
// Tile table contains only lod 0 tiles
|
||||
if(lod != 0)
|
||||
status = false;
|
||||
}
|
||||
|
||||
// Fetch the appendable file from the cache
|
||||
trpgrAppFile *tf = tileCache->GetFile(ness,addr.file);
|
||||
if (!tf) return false;
|
||||
if(status)
|
||||
{
|
||||
trpgwAppAddress addr;
|
||||
float zmin,zmax;
|
||||
status = tileTable.GetTile(x,y,lod,addr,zmin,zmax);
|
||||
|
||||
// Fetch the tile
|
||||
if (!tf->Read(&buf,addr.offset))
|
||||
return false;
|
||||
if(status)
|
||||
status = ReadTile(addr, buf);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool trpgr_Archive::ReadExternalTile(uint32 x,uint32 y,uint32 lod,trpgMemReadBuffer &buf)
|
||||
{
|
||||
// Figure out the file name
|
||||
char filename[1024];
|
||||
int majorVer,minorVer;
|
||||
header.GetVersion(majorVer,minorVer);
|
||||
if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer >= TRPG_NOMERGE_VERSION_MINOR)) {
|
||||
int blockx,blocky;
|
||||
unsigned int denom = (1 << lod); // this should work up to lod 31
|
||||
blockx = x/denom;
|
||||
blocky = y/denom;
|
||||
sprintf(filename,"%s" PATHSEPERATOR "%d" PATHSEPERATOR "%d" PATHSEPERATOR "tile_%d_%d_%d.tpt",
|
||||
dir,blockx,blocky,x,y,lod);
|
||||
}
|
||||
else {
|
||||
sprintf(filename,"%s" PATHSEPERATOR "tile_%d_%d_%d.tpt",dir,x,y,lod);
|
||||
}
|
||||
// Open the file and read the contents
|
||||
FILE *fp= 0;
|
||||
try {
|
||||
if (!(fp = fopen(filename,"rb"))) {
|
||||
|
||||
throw 1;
|
||||
}
|
||||
// Find the file end
|
||||
if (fseek(fp,0,SEEK_END))
|
||||
throw 1;
|
||||
// Note: This means tile is capped at 2 gigs
|
||||
long pos = ftell(fp);
|
||||
if (fseek(fp,0,SEEK_SET))
|
||||
throw 1;
|
||||
// Now we know the size. Read the whole file
|
||||
buf.SetLength(pos);
|
||||
char *data = buf.GetDataPtr();
|
||||
if (fread(data,pos,1,fp) != 1)
|
||||
throw 1;
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
catch (...) {
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool trpgr_Archive::ReadTile(const trpgwAppAddress& addr, trpgMemReadBuffer &buf)
|
||||
{
|
||||
// Fetch the appendable file from the cache
|
||||
trpgrAppFile *tf = tileCache->GetFile(ness,addr.file,addr.col,addr.row);
|
||||
if (!tf)
|
||||
return false;
|
||||
|
||||
// Fetch the tile
|
||||
if (!tf->Read(&buf,addr.offset))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get methods
|
||||
const trpgHeader *trpgr_Archive::GetHeader() const
|
||||
@ -245,7 +433,7 @@ const trpgMatTable *trpgr_Archive::GetMaterialTable() const
|
||||
{
|
||||
return &materialTable;
|
||||
}
|
||||
const trpgTexTable *trpgr_Archive::GetTexTable() const
|
||||
trpgTexTable *trpgr_Archive::GetTexTable()
|
||||
{
|
||||
return &texTable;
|
||||
}
|
||||
@ -286,13 +474,13 @@ trpgEndian trpgr_Archive::GetEndian() const
|
||||
bool trpgr_Archive::trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,trpg3dPoint &ll,trpg3dPoint &ur) const
|
||||
{
|
||||
if (!header.isValid())
|
||||
return false;
|
||||
return false;
|
||||
int32 numLod;
|
||||
header.GetNumLods(numLod);
|
||||
trpg2iPoint maxXY;
|
||||
header.GetLodSize(lod,maxXY);
|
||||
if (x >= (unsigned int)maxXY.x || y>= (unsigned int)maxXY.y)
|
||||
return false;
|
||||
if (static_cast<int>(x) >= maxXY.x || static_cast<int>(y)>= maxXY.y)
|
||||
return false;
|
||||
|
||||
trpg3dPoint origin;
|
||||
header.GetOrigin(origin);
|
||||
@ -316,13 +504,20 @@ bool trpgr_Archive::trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,trpg3dPoint &ll,
|
||||
/* *****************
|
||||
Read Image Helper
|
||||
*****************
|
||||
*/
|
||||
*/
|
||||
|
||||
trpgrImageHelper::trpgrImageHelper(trpgEndian inNess,char *inDir,
|
||||
const trpgMatTable &inMatTable,const trpgTexTable &inTexTable)
|
||||
const trpgMatTable &inMatTable,const trpgTexTable &inTexTable,bool separateGeoTyp)
|
||||
{
|
||||
Init(inNess,inDir,inMatTable,inTexTable,separateGeoTyp);
|
||||
}
|
||||
|
||||
void trpgrImageHelper::Init(trpgEndian inNess,char *inDir,
|
||||
const trpgMatTable &inMatTable,const trpgTexTable &inTexTable,bool separateGeoTyp)
|
||||
{
|
||||
ness = inNess;
|
||||
strcpy(dir,inDir);
|
||||
this->separateGeoTyp = separateGeoTyp;
|
||||
matTable = &inMatTable;
|
||||
texTable = &inTexTable;
|
||||
|
||||
@ -330,13 +525,32 @@ trpgrImageHelper::trpgrImageHelper(trpgEndian inNess,char *inDir,
|
||||
// It doesn't do anything until it's called anyway
|
||||
char fullBase[1024];
|
||||
sprintf(fullBase,"%s" PATHSEPERATOR "texFile",dir);
|
||||
texCache = new trpgrAppFileCache(fullBase,"txf");
|
||||
texCache = GetNewRAppFileCache(fullBase,"txf");
|
||||
if(separateGeoTyp) {
|
||||
sprintf(fullBase,"%s" PATHSEPERATOR "geotypFile",dir);
|
||||
geotypCache = GetNewRAppFileCache(fullBase,"txf");
|
||||
}
|
||||
else {
|
||||
geotypCache = texCache;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trpgrImageHelper::~trpgrImageHelper()
|
||||
{
|
||||
if (texCache)
|
||||
delete texCache;
|
||||
if (texCache) {
|
||||
delete texCache;
|
||||
texCache = NULL;
|
||||
}
|
||||
if(separateGeoTyp && geotypCache) {
|
||||
delete geotypCache;
|
||||
geotypCache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
trpgrAppFileCache* trpgrImageHelper::GetNewRAppFileCache(const char *fullBase,const char* /*ext*/)
|
||||
{
|
||||
return new trpgrAppFileCache(fullBase,"txf");
|
||||
}
|
||||
|
||||
bool trpgrImageHelper::GetLocalGL(const trpgTexture *tex,char *data,int32 size)
|
||||
@ -345,16 +559,16 @@ bool trpgrImageHelper::GetLocalGL(const trpgTexture *tex,char *data,int32 size)
|
||||
trpgTexture::ImageMode mode;
|
||||
tex->GetImageMode(mode);
|
||||
if (mode != trpgTexture::Local)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Fetch data data
|
||||
trpgwAppAddress addr;
|
||||
tex->GetImageAddr(addr);
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
|
||||
trpgrAppFile *af = geotypCache->GetFile(ness,addr.file,addr.col,addr.row);
|
||||
if (!af)
|
||||
return false;
|
||||
return false;
|
||||
if (!af->Read(data,addr.offset,0,size))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -362,37 +576,37 @@ bool trpgrImageHelper::GetLocalGL(const trpgTexture *tex,char *data,int32 size)
|
||||
bool trpgrImageHelper::GetMipLevelLocalGL(int miplevel, const trpgTexture *tex,char *data,int32 dataSize)
|
||||
{
|
||||
if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 )
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Make sure the texture is Local
|
||||
trpgTexture::ImageMode mode;
|
||||
tex->GetImageMode(mode);
|
||||
if (mode != trpgTexture::Local)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Fetch data data
|
||||
trpgwAppAddress addr;
|
||||
tex->GetImageAddr(addr);
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file,addr.col,addr.row);
|
||||
if (!af)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
int level_offset = (const_cast<trpgTexture*>(tex))->MipLevelOffset(miplevel);
|
||||
if (!af->Read(data,addr.offset,level_offset,dataSize))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool trpgrImageHelper::GetImageInfoForLocalMat(const trpgLocalMaterial *locMat,
|
||||
const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
|
||||
const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
|
||||
{
|
||||
return GetNthImageInfoForLocalMat(locMat, 0, retMat, retTex, totSize);
|
||||
}
|
||||
|
||||
bool trpgrImageHelper::GetNthImageInfoForLocalMat(const trpgLocalMaterial *locMat, int index,
|
||||
const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
|
||||
const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
|
||||
{
|
||||
// Get the base material for the Local Material
|
||||
int32 matSubTable,matID;
|
||||
@ -401,18 +615,23 @@ bool trpgrImageHelper::GetNthImageInfoForLocalMat(const trpgLocalMaterial *locMa
|
||||
// Eventually, either store multiple base materials for each local material,
|
||||
// or overhaul this in some other fashion.
|
||||
int numTables;
|
||||
if (!matTable->GetNumTable(numTables)) return false;
|
||||
if (index>=numTables) return false;
|
||||
if (!matTable->GetNumTable(numTables))
|
||||
return false;
|
||||
if (index>=numTables)
|
||||
return false;
|
||||
if (index>0) matSubTable=index; // otherwise, leave it alone - could be nonzero
|
||||
const trpgMaterial *mat = matTable->GetMaterialRef(matSubTable,matID);
|
||||
if (!mat) return false;
|
||||
if (!mat)
|
||||
return false;
|
||||
|
||||
// Now get the texture (always the first one)
|
||||
trpgTextureEnv texEnv;
|
||||
int32 texID;
|
||||
if (!mat->GetTexture(0,texID,texEnv)) return false;
|
||||
if (!mat->GetTexture(0,texID,texEnv))
|
||||
return false;
|
||||
const trpgTexture *tex = texTable->GetTextureRef(texID);
|
||||
if (!tex) return false;
|
||||
if (!tex)
|
||||
return false;
|
||||
|
||||
totSize = tex->CalcTotalSize();
|
||||
|
||||
@ -428,36 +647,38 @@ bool trpgrImageHelper::GetImageForLocalMat(const trpgLocalMaterial *locMat,char
|
||||
|
||||
bool trpgrImageHelper::GetNthImageForLocalMat(const trpgLocalMaterial *locMat,int index, char *data,int dataSize)
|
||||
{
|
||||
if (!locMat->isValid()) return false;
|
||||
if (!locMat->isValid())
|
||||
return false;
|
||||
|
||||
const trpgMaterial *mat;
|
||||
const trpgTexture *tex;
|
||||
int totSize;
|
||||
if (!GetNthImageInfoForLocalMat(locMat,index,&mat,&tex,totSize))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Determine the type
|
||||
trpgTexture::ImageMode imageMode;
|
||||
tex->GetImageMode(imageMode);
|
||||
switch (imageMode) {
|
||||
case trpgTexture::Template:
|
||||
{
|
||||
// Read the image data out of the Local image (in an archive somewhere)
|
||||
trpgwAppAddress addr;
|
||||
if (!locMat->GetNthAddr(index,addr)) return false;
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
|
||||
if (!af) return false;
|
||||
if (!af->Read(data,addr.offset,0,dataSize))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
{
|
||||
// Read the image data out of the Local image (in an archive somewhere)
|
||||
trpgwAppAddress addr;
|
||||
if (!locMat->GetNthAddr(index,addr)) return false;
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file,addr.col,addr.row);
|
||||
if (!af)
|
||||
return false;
|
||||
if (!af->Read(data,addr.offset,0,dataSize))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case trpgTexture::Global:
|
||||
// Note: Not dealing with Global textures yet
|
||||
return false;
|
||||
break;
|
||||
// Note: Not dealing with Global textures yet
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
// This is not a valid Local Material
|
||||
return false;
|
||||
// This is not a valid Local Material
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
@ -477,35 +698,35 @@ bool trpgrImageHelper::GetNthImageMipLevelForLocalMat(int miplevel, const trpgLo
|
||||
const trpgTexture *tex;
|
||||
int totSize;
|
||||
if (!GetNthImageInfoForLocalMat(locMat,index,&mat,&tex,totSize))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 )
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Determine the type
|
||||
trpgTexture::ImageMode imageMode;
|
||||
tex->GetImageMode(imageMode);
|
||||
switch (imageMode) {
|
||||
case trpgTexture::Template:
|
||||
{
|
||||
// Read the image data out of the Local image (in an archive somewhere)
|
||||
trpgwAppAddress addr;
|
||||
if (!locMat->GetNthAddr(index,addr)) return false;
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
|
||||
if (!af) return false;
|
||||
{
|
||||
// Read the image data out of the Local image (in an archive somewhere)
|
||||
trpgwAppAddress addr;
|
||||
if (!locMat->GetNthAddr(index,addr)) return false;
|
||||
trpgrAppFile *af = texCache->GetFile(ness,addr.file,addr.col,addr.row);
|
||||
if (!af) return false;
|
||||
|
||||
int level_offset = (const_cast<trpgTexture*>(tex))->MipLevelOffset(miplevel);
|
||||
if (!af->Read(data,addr.offset,level_offset,dataSize))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
int level_offset = (const_cast<trpgTexture*>(tex))->MipLevelOffset(miplevel);
|
||||
if (!af->Read(data,addr.offset,level_offset,dataSize))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case trpgTexture::Global:
|
||||
// Note: Not dealing with Global textures yet
|
||||
return false;
|
||||
break;
|
||||
// Note: Not dealing with Global textures yet
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
// This is not a valid Local Material
|
||||
return false;
|
||||
// This is not a valid Local Material
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
@ -518,8 +739,8 @@ bool trpgrImageHelper::GetImagePath(const trpgTexture *tex,char *fullPath,int pa
|
||||
tex->GetName(name,nameLen);
|
||||
nameLen = strlen(name);
|
||||
|
||||
if ((int)strlen(dir) + nameLen + 2 > pathLen)
|
||||
return false;
|
||||
if (static_cast<int>(strlen(dir)) + nameLen + 2 > pathLen)
|
||||
return false;
|
||||
|
||||
sprintf(fullPath,"%s" PATHSEPERATOR "%s",dir,name);
|
||||
|
||||
|
@ -18,45 +18,48 @@
|
||||
#define _txpage_read_h_
|
||||
|
||||
/* txpage_read.h
|
||||
Classes used to represent read objects for paging files.
|
||||
*/
|
||||
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:
|
||||
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:
|
||||
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
|
||||
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:
|
||||
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;
|
||||
@ -64,68 +67,75 @@ public:
|
||||
// Add and remove token callbacks
|
||||
virtual void AddCallback(trpgToken,trpgr_Callback *,bool destroy = true);
|
||||
virtual void AddCallback(trpgToken,trpgReadWriteable *);
|
||||
virtual const trpgr_Callback *GetCallback(trpgToken tok) const;
|
||||
virtual trpgr_Callback *GetCallback(trpgToken tok);
|
||||
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:
|
||||
protected:
|
||||
void *lastObject;
|
||||
private:
|
||||
private:
|
||||
// Note: Just how slow is a map<> anyway?
|
||||
// This usage is self-contained and could be replaced with an array
|
||||
// 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;
|
||||
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 &);
|
||||
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.
|
||||
*/
|
||||
class trpgwImageHelper;
|
||||
TX_EXDECL class TX_CLDECL trpgrImageHelper
|
||||
{
|
||||
public:
|
||||
trpgrImageHelper() {;};
|
||||
trpgrImageHelper(trpgEndian ness,char *dir,const trpgMatTable &,const trpgTexTable &,bool separateGeoTyp);
|
||||
// real construction is here
|
||||
virtual void Init(trpgEndian ness,char *dir,const trpgMatTable &,const trpgTexTable &,bool separateGeoTyp);
|
||||
virtual ~trpgrImageHelper(void);
|
||||
|
||||
/* Fetch the bytes for the given texture.
|
||||
This is only valid for Local textures.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
const trpgMaterial **retMat,const trpgTexture **retTex,
|
||||
int &totSize);
|
||||
|
||||
/* Same as above, but gets info for nth image associated with this local material
|
||||
*/
|
||||
virtual bool GetNthImageInfoForLocalMat(const trpgLocalMaterial *locMat, int index,
|
||||
const trpgMaterial **retMat,const trpgTexture **retTex,
|
||||
int &totSize);
|
||||
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.
|
||||
*/
|
||||
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 above, but gets nth image associated with this local material
|
||||
@ -133,48 +143,68 @@ public:
|
||||
virtual bool GetNthImageForLocalMat(const trpgLocalMaterial *locMat, int index, 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);
|
||||
|
||||
/* Get mip levels for one of multiple images
|
||||
*/
|
||||
*/
|
||||
virtual bool GetNthImageMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat, int index, char *data,int dataSize);
|
||||
|
||||
/* Determine the full path of the image in the given
|
||||
trpgTexture class.
|
||||
trpgTexture class.
|
||||
Only useful for External images.
|
||||
*/
|
||||
*/
|
||||
virtual bool GetImagePath(const trpgTexture *,char *,int len);
|
||||
|
||||
protected:
|
||||
virtual trpgrAppFileCache* GetNewRAppFileCache(const char *fullBase,const char *ext);
|
||||
|
||||
trpgrAppFileCache *GetGeoTypCache()
|
||||
{
|
||||
return geotypCache;
|
||||
}
|
||||
void SetTexTable(trpgTexTable *texTable)
|
||||
{
|
||||
this->texTable = texTable;
|
||||
}
|
||||
protected:
|
||||
char dir[1024];
|
||||
trpgEndian ness;
|
||||
const trpgMatTable *matTable;
|
||||
const trpgTexTable *texTable;
|
||||
|
||||
trpgrAppFileCache *texCache;
|
||||
trpgrAppFileCache *geotypCache;
|
||||
bool separateGeoTyp;
|
||||
};
|
||||
|
||||
/* 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:
|
||||
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 bool OpenFile(const char *); // Open File
|
||||
virtual void CloseFile(void);
|
||||
virtual bool ReadHeader(void); // Read header (materials, tile table. etc..)
|
||||
virtual bool ReadHeader(void); // Read header (materials, tile table. etc..)
|
||||
//overload that lets you specify if you want to read all the blocks now,
|
||||
//or defer reading them for later.
|
||||
virtual bool ReadHeader(bool readAllBlocks);
|
||||
bool ReadSubArchive(int row, int col, trpgEndian cpuNess);
|
||||
// In version 2.1, only tile at lod 0 are fetchable via the tile table
|
||||
virtual bool ReadTile(uint32 x, uint32 y, uint32 lod,trpgMemReadBuffer &);
|
||||
virtual bool ReadTile(const trpgwAppAddress& addr, trpgMemReadBuffer &buf);
|
||||
virtual bool ReadExternalTile(uint32 x,uint32 y,uint32 lod,trpgMemReadBuffer &buf);
|
||||
|
||||
// Get access to header info
|
||||
virtual const trpgHeader *GetHeader(void) const;
|
||||
virtual const trpgMatTable *GetMaterialTable(void) const;
|
||||
virtual const trpgTexTable *GetTexTable(void) const;
|
||||
virtual trpgTexTable *GetTexTable(void) ;
|
||||
virtual const trpgModelTable *GetModelTable(void) const;
|
||||
virtual const trpgTileTable *GetTileTable(void) const;
|
||||
virtual const trpgLightTable *GetLightTable(void) const;
|
||||
@ -185,11 +215,15 @@ public:
|
||||
|
||||
// Utility routine to calculate the MBR of a given tile
|
||||
virtual bool trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,
|
||||
trpg3dPoint &ll,trpg3dPoint &ur) const;
|
||||
trpg3dPoint &ll,trpg3dPoint &ur) const;
|
||||
|
||||
trpgEndian GetEndian(void) const;
|
||||
char* getDir(void){return dir;};
|
||||
protected:
|
||||
virtual trpgrImageHelper* GetNewRImageHelper(trpgEndian ness,char *dir,const trpgMatTable &matTable,const trpgTexTable &texTable);
|
||||
virtual trpgrAppFileCache* GetNewRAppFileCache(const char *fullBase, const char *ext);
|
||||
virtual int32 GetHeaderData(char *dataPtr,int32 length,FILE *filehandle);
|
||||
virtual int32 GetMagicNumber() {return TRPG_MAGIC;};
|
||||
protected:
|
||||
bool headerRead;
|
||||
trpgEndian ness;
|
||||
FILE *fp;
|
||||
@ -214,19 +248,20 @@ 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 {
|
||||
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:
|
||||
public:
|
||||
trpgSceneParser(void);
|
||||
virtual ~trpgSceneParser(void);
|
||||
protected:
|
||||
protected:
|
||||
// Start defining children for the given object
|
||||
virtual bool StartChildren(void *) { return true;};
|
||||
virtual bool EndChildren(void *) { return true;};
|
||||
|
@ -18,15 +18,15 @@
|
||||
#include <math.h>
|
||||
|
||||
/* trpage_readbuf.cpp
|
||||
Methods for the trpgReadBuffer and trpgMemReadBuffer classes.
|
||||
trpgReadBuffer is a virtual base class with a few utility functions.
|
||||
It's used as generic interface for reading data out of.
|
||||
trpgMemReadBuffer is a subclass of that which implements methods for
|
||||
reading out of a chunk of memory. Data is read off of disk and then
|
||||
dumped into a read buffer for parsing.
|
||||
If you wanted to read directly from disk, for example, you could
|
||||
implement a trpgDiskReadBuffer as a subclass of trpgReadBuffer.
|
||||
*/
|
||||
Methods for the trpgReadBuffer and trpgMemReadBuffer classes.
|
||||
trpgReadBuffer is a virtual base class with a few utility functions.
|
||||
It's used as generic interface for reading data out of.
|
||||
trpgMemReadBuffer is a subclass of that which implements methods for
|
||||
reading out of a chunk of memory. Data is read off of disk and then
|
||||
dumped into a read buffer for parsing.
|
||||
If you wanted to read directly from disk, for example, you could
|
||||
implement a trpgDiskReadBuffer as a subclass of trpgReadBuffer.
|
||||
*/
|
||||
|
||||
#include <trpage_io.h>
|
||||
#include <trpage_swap.h>
|
||||
@ -43,9 +43,9 @@ bool trpgReadBuffer::Get(int32 &ret)
|
||||
|
||||
if (!GetData((char *)&val,sizeof(int32))) return false;
|
||||
if (ness != cpuNess)
|
||||
ret = trpg_byteswap_int(val);
|
||||
ret = trpg_byteswap_int(val);
|
||||
else
|
||||
ret = val;
|
||||
ret = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -54,10 +54,11 @@ bool trpgReadBuffer::Get(int64 &ret)
|
||||
int64 val;
|
||||
|
||||
if (!GetData((char *)&val,sizeof(int64))) return false;
|
||||
// trpg_byteswap_llong is defined to be 64 bit
|
||||
if (ness != cpuNess)
|
||||
ret = trpg_byteswap_llong(val);
|
||||
ret = trpg_byteswap_llong(val);
|
||||
else
|
||||
ret = val;
|
||||
ret = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -74,7 +75,7 @@ bool trpgReadBuffer::Get(char *ret,int retLen)
|
||||
ret[rlen] = 0;
|
||||
|
||||
// Skip the rest
|
||||
if (!Skip(rlen-len)) return false;
|
||||
if (!Skip(len-rlen)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -86,7 +87,7 @@ bool trpgReadBuffer::Get(std::string &str)
|
||||
if (!Get(len)) return false;
|
||||
|
||||
if (len < 0)
|
||||
return false;
|
||||
return false;
|
||||
// Note: Should fix this
|
||||
char *tmpStr = new char[len+1];
|
||||
|
||||
@ -104,10 +105,10 @@ bool trpgReadBuffer::Get(float32 &ret)
|
||||
|
||||
if (!GetData(cval,sizeof(float32))) return false;
|
||||
try {
|
||||
if (ness == cpuNess)
|
||||
memcpy(&ret,cval,4);
|
||||
else
|
||||
ret = trpg_byteswap_4bytes_to_float(cval);
|
||||
if (ness == cpuNess)
|
||||
memcpy(&ret,cval,4);
|
||||
else
|
||||
ret = trpg_byteswap_4bytes_to_float(cval);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
@ -120,10 +121,10 @@ bool trpgReadBuffer::Get(float64 &ret)
|
||||
|
||||
if (!GetData(cval,sizeof(float64))) return false;
|
||||
try {
|
||||
if (ness == cpuNess)
|
||||
memcpy(&ret,cval,8);
|
||||
else
|
||||
ret = trpg_byteswap_8bytes_to_double(cval);
|
||||
if (ness == cpuNess)
|
||||
memcpy(&ret,cval,8);
|
||||
else
|
||||
ret = trpg_byteswap_8bytes_to_double(cval);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
@ -161,9 +162,9 @@ bool trpgReadBuffer::Get(trpgDiskRef &ret)
|
||||
|
||||
if (!GetData((char *)&val,sizeof(trpgDiskRef))) return false;
|
||||
if (ness == cpuNess)
|
||||
ret = val;
|
||||
ret = val;
|
||||
else
|
||||
ret = trpg_byteswap_llong(val);
|
||||
ret = trpg_byteswap_llong(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -175,9 +176,9 @@ bool trpgReadBuffer::Get(trpgToken &ret)
|
||||
|
||||
if (!GetData((char *)&val,sizeof(trpgToken))) return false;
|
||||
if (ness == cpuNess)
|
||||
ret = val;
|
||||
ret = val;
|
||||
else
|
||||
ret = trpg_byteswap_short(val);
|
||||
ret = trpg_byteswap_short(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -186,13 +187,13 @@ bool trpgReadBuffer::Get(trpgToken &ret)
|
||||
bool trpgReadBuffer::GetArray(int len,float32 **arr)
|
||||
{
|
||||
if (!GetDataRef((char **)arr,sizeof(float32)*len))
|
||||
return false;
|
||||
return false;
|
||||
// Byteswap in place if necessary
|
||||
if (ness != cpuNess) {
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=4)
|
||||
trpg_swap_four(ptr,ptr);
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=4)
|
||||
trpg_swap_four(ptr,ptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -200,39 +201,39 @@ bool trpgReadBuffer::GetArray(int len,float32 **arr)
|
||||
bool trpgReadBuffer::GetArray(int len,float64 **arr)
|
||||
{
|
||||
if (!GetDataRef((char **)arr,sizeof(float64)*len))
|
||||
return false;
|
||||
return false;
|
||||
// Byteswap in place if necessary
|
||||
if (ness != cpuNess) {
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=8)
|
||||
trpg_swap_eight(ptr,ptr);
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=8)
|
||||
trpg_swap_eight(ptr,ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool trpgReadBuffer::GetArray(int len,int32 **arr)
|
||||
{
|
||||
if (!GetDataRef((char **)arr,sizeof(int32)*len))
|
||||
return false;
|
||||
return false;
|
||||
// Byteswap in place if necessary
|
||||
if (ness != cpuNess) {
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=4)
|
||||
trpg_swap_four(ptr,ptr);
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=4)
|
||||
trpg_swap_four(ptr,ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool trpgReadBuffer::GetArray(int len,trpgColor **arr)
|
||||
{
|
||||
if (!GetDataRef((char **)arr,sizeof(trpgColor)*len))
|
||||
return false;
|
||||
return false;
|
||||
// Byteswap in place if necessary
|
||||
if (ness != cpuNess) {
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=8)
|
||||
trpg_swap_four(ptr,ptr);
|
||||
char *ptr;
|
||||
int pos;
|
||||
for (pos=0,ptr = (char *)*arr;pos<len;pos++,ptr+=8)
|
||||
trpg_swap_four(ptr,ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -245,25 +246,25 @@ bool trpgReadBuffer::GetArray(int len,char **arr)
|
||||
bool trpgReadBuffer::Get(trpg2iPoint &pt)
|
||||
{
|
||||
if (!Get(pt.x) || !Get(pt.y))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool trpgReadBuffer::Get(trpg2dPoint &pt)
|
||||
{
|
||||
if (!Get(pt.x) || !Get(pt.y))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool trpgReadBuffer::Get(trpg3dPoint &pt)
|
||||
{
|
||||
if (!Get(pt.x) || !Get(pt.y) || !Get(pt.z))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool trpgReadBuffer::Get(trpgColor &color)
|
||||
{
|
||||
if (!Get(color.red) || !Get(color.green) || !Get(color.blue))
|
||||
return false;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -271,16 +272,16 @@ bool trpgReadBuffer::Get(trpgColor &color)
|
||||
bool trpgReadBuffer::GetToken(trpgToken &tok,int32 &len)
|
||||
{
|
||||
if (!Get(tok) || !Get(len))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Limit Handling functions
|
||||
These impose arbitrary lenght limits on the read buffer.
|
||||
This keeps us from reading pased a token group and parsing
|
||||
random data within an archive.
|
||||
*/
|
||||
These impose arbitrary lenght limits on the read buffer.
|
||||
This keeps us from reading pased a token group and parsing
|
||||
random data within an archive.
|
||||
*/
|
||||
// Push Limit
|
||||
// Add another limit to the top of the stack
|
||||
void trpgReadBuffer::PushLimit(int limit)
|
||||
@ -295,7 +296,7 @@ void trpgReadBuffer::PopLimit()
|
||||
int len = limits.size();
|
||||
|
||||
if (len > 0)
|
||||
limits.resize(len-1);
|
||||
limits.resize(len-1);
|
||||
}
|
||||
|
||||
// Skip To Limit
|
||||
@ -306,10 +307,10 @@ bool trpgReadBuffer::SkipToLimit()
|
||||
int len=0;
|
||||
|
||||
if (limits.size() != 0)
|
||||
len = limits[limits.size()-1];
|
||||
len = limits[limits.size()-1];
|
||||
|
||||
if (len > 0)
|
||||
return Skip(len);
|
||||
return Skip(len);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -319,8 +320,8 @@ bool trpgReadBuffer::SkipToLimit()
|
||||
bool trpgReadBuffer::TestLimit(int len)
|
||||
{
|
||||
for (unsigned int i=0;i<limits.size();i++)
|
||||
if (len > limits[i])
|
||||
return false;
|
||||
if (len > limits[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -330,7 +331,7 @@ bool trpgReadBuffer::TestLimit(int len)
|
||||
void trpgReadBuffer::UpdateLimits(int len)
|
||||
{
|
||||
for (unsigned int i=0;i<limits.size();i++)
|
||||
limits[i] -= len;
|
||||
limits[i] -= len;
|
||||
}
|
||||
|
||||
/* *************************
|
||||
@ -347,7 +348,7 @@ trpgMemReadBuffer::trpgMemReadBuffer(trpgEndian in_ness)
|
||||
trpgMemReadBuffer::~trpgMemReadBuffer()
|
||||
{
|
||||
if (data)
|
||||
delete [] data;
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
// Empty check
|
||||
@ -356,11 +357,11 @@ bool trpgMemReadBuffer::isEmpty()
|
||||
if (!data) return true;
|
||||
|
||||
if (pos >= len)
|
||||
return true;
|
||||
return true;
|
||||
|
||||
// Also test the limits
|
||||
for (unsigned int i=0;i<limits.size();i++)
|
||||
if (limits[i] == 0) return true;
|
||||
if (limits[i] == 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -370,10 +371,10 @@ bool trpgMemReadBuffer::isEmpty()
|
||||
void trpgMemReadBuffer::SetLength(int newLen)
|
||||
{
|
||||
if (newLen > totLen) {
|
||||
if (data)
|
||||
delete [] data;
|
||||
data = new char[newLen];
|
||||
totLen = newLen;
|
||||
if (data)
|
||||
delete [] data;
|
||||
data = new char[newLen];
|
||||
totLen = newLen;
|
||||
}
|
||||
len = newLen;
|
||||
pos = 0;
|
||||
@ -391,7 +392,7 @@ char *trpgMemReadBuffer::GetDataPtr()
|
||||
bool trpgMemReadBuffer::GetData(char *ret,int rlen)
|
||||
{
|
||||
if (rlen < 0)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Test against limits imposed from without
|
||||
if (!TestLimit(rlen)) throw 1;
|
||||
@ -433,8 +434,11 @@ bool trpgMemReadBuffer::GetDataRef(char **ret,int rlen)
|
||||
// Same as read except we're not, uh, reading
|
||||
bool trpgMemReadBuffer::Skip(int rlen)
|
||||
{
|
||||
if (rlen == 0)
|
||||
return true;
|
||||
|
||||
if (rlen < 0)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Test against limits
|
||||
if (!TestLimit(rlen)) return false;
|
||||
@ -451,13 +455,18 @@ bool trpgMemReadBuffer::Skip(int rlen)
|
||||
*/
|
||||
|
||||
trpgrAppFile::trpgrAppFile(trpgEndian inNess,const char *fileName)
|
||||
{
|
||||
Init(inNess,fileName);
|
||||
}
|
||||
|
||||
void trpgrAppFile::Init(trpgEndian inNess,const char *fileName)
|
||||
{
|
||||
valid = false;
|
||||
ness = inNess;
|
||||
cpuNess = trpg_cpu_byte_order();
|
||||
|
||||
if (!(fp = fopen(fileName,"rb")))
|
||||
return;
|
||||
return;
|
||||
|
||||
valid = true;
|
||||
}
|
||||
@ -465,11 +474,16 @@ trpgrAppFile::trpgrAppFile(trpgEndian inNess,const char *fileName)
|
||||
trpgrAppFile::~trpgrAppFile()
|
||||
{
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
|
||||
valid = false;
|
||||
}
|
||||
|
||||
bool trpgrAppFile::isValid(void) const
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
|
||||
// Read a section of data from the given file
|
||||
// and dump it into the given buffer
|
||||
bool trpgrAppFile::Read(trpgMemReadBuffer *buf,int32 offset)
|
||||
@ -478,44 +492,44 @@ bool trpgrAppFile::Read(trpgMemReadBuffer *buf,int32 offset)
|
||||
|
||||
// Seek to the right location
|
||||
if (fseek(fp,offset,SEEK_SET))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Read a length
|
||||
int32 len;
|
||||
if (fread(&len,sizeof(int32),1,fp) != 1) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Byteswap if necessary
|
||||
if (ness != cpuNess)
|
||||
trpg_byteswap_int(len);
|
||||
len = trpg_byteswap_int(len);
|
||||
|
||||
if (len < 0) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
buf->SetLength(len);
|
||||
char *data = buf->GetDataPtr();
|
||||
if (!data) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(data,sizeof(char),len,fp) != (unsigned int)len) {
|
||||
valid = false;
|
||||
return false;
|
||||
if (fread(data,sizeof(char),len,fp) != (uint32)len) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Read a section of data from the given file
|
||||
and dump it into the given memory. Sanity
|
||||
check the length against the size of the memory
|
||||
passed into dataSize.
|
||||
*/
|
||||
and dump it into the given memory. Sanity
|
||||
check the length against the size of the memory
|
||||
passed into dataSize.
|
||||
*/
|
||||
bool trpgrAppFile::Read(char *data,int32 baseOffset,int32 objOffset,int32 dataSize)
|
||||
{
|
||||
if (!valid) return false;
|
||||
@ -523,53 +537,58 @@ bool trpgrAppFile::Read(char *data,int32 baseOffset,int32 objOffset,int32 dataSi
|
||||
// Seek to the right place
|
||||
int result;
|
||||
if ((result = fseek(fp,baseOffset,SEEK_SET))) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the total object length
|
||||
int32 len;
|
||||
if (fread(&len,sizeof(int32),1,fp) != 1) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Byteswap if necessary
|
||||
if (ness != cpuNess)
|
||||
trpg_byteswap_int(len);
|
||||
len = trpg_byteswap_int(len);
|
||||
|
||||
if (len < 0) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// It's all right to read less than the whole data block
|
||||
if (objOffset+dataSize > len)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
// Skip to the object offset
|
||||
if (fseek(fp,objOffset,SEEK_CUR)) {
|
||||
valid = false;
|
||||
return false;
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the raw data
|
||||
// Note: What about byte swapping?
|
||||
if (fread(data,sizeof(char),dataSize,fp) != (unsigned int)dataSize) {
|
||||
valid = false;
|
||||
return false;
|
||||
if (fread(data,sizeof(char),dataSize,fp) != (uint32)dataSize) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* App File Cache
|
||||
This class manages a group of appendable files with
|
||||
the same base name and extension. It will keep a certain
|
||||
number of them open to facilitate caching.
|
||||
*/
|
||||
This class manages a group of appendable files with
|
||||
the same base name and extension. It will keep a certain
|
||||
number of them open to facilitate caching.
|
||||
*/
|
||||
|
||||
trpgrAppFileCache::trpgrAppFileCache(const char *inPre,const char *inExt,int noFiles)
|
||||
{
|
||||
Init(inPre,inExt,noFiles);
|
||||
}
|
||||
|
||||
void trpgrAppFileCache::Init(const char *inPre,const char *inExt,int noFiles)
|
||||
{
|
||||
strcpy(baseName,inPre);
|
||||
strcpy(ext,inExt);
|
||||
@ -580,56 +599,101 @@ trpgrAppFileCache::trpgrAppFileCache(const char *inPre,const char *inExt,int noF
|
||||
|
||||
trpgrAppFileCache::~trpgrAppFileCache()
|
||||
{
|
||||
for (unsigned int i=0;i<files.size();i++) {
|
||||
if (files[i].afile) {
|
||||
delete files[i].afile;
|
||||
files[i].afile = NULL;
|
||||
}
|
||||
unsigned int len = files.size();
|
||||
for (unsigned int i=0;i<len;i++) {
|
||||
if (files[i].afile) {
|
||||
delete files[i].afile;
|
||||
files[i].afile = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trpgrAppFile *trpgrAppFileCache::GetNewRAppFile(trpgEndian ness, const char *fileName)
|
||||
{
|
||||
return new trpgrAppFile(ness,fileName);
|
||||
}
|
||||
|
||||
trpgrAppFile *trpgrAppFileCache::GetFile(trpgEndian ness,int id)
|
||||
{
|
||||
return GetFile(ness,id,-1,-1);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
trpgrAppFile *trpgrAppFileCache::GetFile(trpgEndian ness,int id)
|
||||
trpgrAppFile *trpgrAppFileCache::GetFile(trpgEndian ness,int id,int col,int row)
|
||||
{
|
||||
// Look for it already here
|
||||
int foundID = -1;
|
||||
unsigned int i;
|
||||
for (i=0;i<files.size();i++) {
|
||||
if (files[i].id == id) {
|
||||
foundID = i;
|
||||
break;
|
||||
}
|
||||
if ((files[i].id == id)&&
|
||||
(files[i].col == col) &&
|
||||
(files[i].row == row)) {
|
||||
foundID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Found it in cache, just return
|
||||
if (foundID != -1) {
|
||||
OpenFile &of = files[foundID];
|
||||
of.lastUsed = timeCount;
|
||||
return of.afile;
|
||||
OpenFile &of = files[foundID];
|
||||
|
||||
if (of.afile->isValid())
|
||||
{
|
||||
of.lastUsed = timeCount;
|
||||
return of.afile;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (of.afile)
|
||||
delete of.afile;
|
||||
of.afile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find it. Need to reclaim one
|
||||
// Look for the oldest used
|
||||
int oldTime=-1,oldID=-1;
|
||||
for (i=0;i<files.size();i++) {
|
||||
OpenFile &of = files[i];
|
||||
if (!of.afile || (oldTime == -1) || (of.lastUsed < oldTime)) {
|
||||
oldID = i;
|
||||
oldTime = of.lastUsed;
|
||||
if (!of.afile)
|
||||
break;
|
||||
}
|
||||
OpenFile &of = files[i];
|
||||
if (!of.afile || (oldTime == -1) || (of.lastUsed < oldTime)) {
|
||||
oldID = i;
|
||||
oldTime = of.lastUsed;
|
||||
if (!of.afile)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reclaim this one
|
||||
OpenFile &of = files[oldID];
|
||||
if (of.afile) delete of.afile;
|
||||
if (of.afile)
|
||||
delete of.afile;
|
||||
char fileName[1024];
|
||||
sprintf(fileName,"%s_%d.%s",baseName,id,ext);
|
||||
of.afile = new trpgrAppFile(ness,fileName);
|
||||
if(col==-1) {
|
||||
sprintf(fileName,"%s_%d.%s",baseName,id,ext);
|
||||
}
|
||||
else {
|
||||
char dir[1024];
|
||||
char filebase[1024];
|
||||
//this is very ugly, but it avoids radical API changes
|
||||
// find the last PATHSEPERATOR in the baseName string
|
||||
int len = strlen(baseName);
|
||||
while(--len > 0) {
|
||||
if(baseName[len]==PATHSEPERATOR[0]) {
|
||||
strcpy(filebase,&baseName[len+1]);
|
||||
strcpy(dir,baseName);
|
||||
dir[len]='\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
sprintf(fileName,"%s" PATHSEPERATOR "%d" PATHSEPERATOR "%d" PATHSEPERATOR "%s_%d.%s",
|
||||
dir,col,row,filebase,id,ext);
|
||||
}
|
||||
of.afile = GetNewRAppFile(ness,fileName);
|
||||
of.id = id;
|
||||
of.row = row;
|
||||
of.col = col;
|
||||
of.lastUsed = timeCount;
|
||||
|
||||
timeCount++;
|
||||
|
@ -19,448 +19,473 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_scene.cpp
|
||||
This file implements a bunch of stuff, all of it optional. See trpage_scene.h
|
||||
for more information.
|
||||
Scene Graph nodes -
|
||||
All the methods for the simple scene graph are here.
|
||||
trpgSceneGraphParser -
|
||||
This is a subclass of trpgSceneParser. It uses that utility class to keep track
|
||||
of pushes and pops. It also registers an interest in all the node types it
|
||||
knows about (Geometry,Group,LOD,ModelRef). When one of those is encountered
|
||||
by the trpgr_Parser (which it's also a subclass of) it reads it into the
|
||||
appropriate trpgRead* type.
|
||||
Unless you're reading into the scene graph defined in trpage_scene.h, you won't
|
||||
use this class directly. Instead, copy it and use it as a template for how
|
||||
to read into a scene graph. You'll need to replace the helpers, primarily.
|
||||
*/
|
||||
This file implements a bunch of stuff, all of it optional. See trpage_scene.h
|
||||
for more information.
|
||||
Scene Graph nodes -
|
||||
All the methods for the simple scene graph are here.
|
||||
trpgSceneGraphParser -
|
||||
This is a subclass of trpgSceneParser. It uses that utility class to keep track
|
||||
of pushes and pops. It also registers an interest in all the node types it
|
||||
knows about (Geometry,Group,LOD,ModelRef). When one of those is encountered
|
||||
by the trpgr_Parser (which it's also a subclass of) it reads it into the
|
||||
appropriate trpgRead* type.
|
||||
Unless you're reading into the scene graph defined in trpage_scene.h, you won't
|
||||
use this class directly. Instead, copy it and use it as a template for how
|
||||
to read into a scene graph. You'll need to replace the helpers, primarily.
|
||||
*/
|
||||
|
||||
#include <trpage_read.h>
|
||||
#include <trpage_scene.h>
|
||||
|
||||
/* ****************
|
||||
MBR Calculation and handling
|
||||
****************
|
||||
*/
|
||||
MBR Calculation and handling
|
||||
****************
|
||||
*/
|
||||
trpgMBR::trpgMBR()
|
||||
{
|
||||
valid = false;
|
||||
valid = false;
|
||||
}
|
||||
bool trpgMBR::isValid() const
|
||||
{
|
||||
return valid;
|
||||
return valid;
|
||||
}
|
||||
void trpgMBR::Reset()
|
||||
{
|
||||
valid = false;
|
||||
valid = false;
|
||||
}
|
||||
trpg3dPoint trpgMBR::GetLL() const
|
||||
{
|
||||
return ll;
|
||||
return ll;
|
||||
}
|
||||
trpg3dPoint trpgMBR::GetUR() const
|
||||
{
|
||||
return ur;
|
||||
return ur;
|
||||
}
|
||||
void trpgMBR::AddPoint(const trpg3dPoint &pt)
|
||||
{
|
||||
if (valid) {
|
||||
ll.x = MIN(pt.x,ll.x);
|
||||
ll.y = MIN(pt.y,ll.y);
|
||||
ll.z = MIN(pt.z,ll.z);
|
||||
ur.x = MAX(pt.x,ur.x);
|
||||
ur.y = MAX(pt.y,ur.y);
|
||||
ur.z = MAX(pt.z,ur.z);
|
||||
} else {
|
||||
valid = true;
|
||||
ll = ur = pt;
|
||||
}
|
||||
if (valid) {
|
||||
ll.x = MIN(pt.x,ll.x);
|
||||
ll.y = MIN(pt.y,ll.y);
|
||||
ll.z = MIN(pt.z,ll.z);
|
||||
ur.x = MAX(pt.x,ur.x);
|
||||
ur.y = MAX(pt.y,ur.y);
|
||||
ur.z = MAX(pt.z,ur.z);
|
||||
} else {
|
||||
valid = true;
|
||||
ll = ur = pt;
|
||||
}
|
||||
}
|
||||
void trpgMBR::AddPoint(double x,double y,double z)
|
||||
{
|
||||
AddPoint(trpg3dPoint(x,y,z));
|
||||
AddPoint(trpg3dPoint(x,y,z));
|
||||
}
|
||||
void trpgMBR::GetMBR(trpg3dPoint &oll,trpg3dPoint &our) const
|
||||
{
|
||||
oll = ll;
|
||||
our = ur;
|
||||
oll = ll;
|
||||
our = ur;
|
||||
}
|
||||
// Add the input MBR to this one
|
||||
void trpgMBR::Union(const trpgMBR &in)
|
||||
{
|
||||
if (valid) {
|
||||
if (in.isValid()) {
|
||||
AddPoint(in.GetLL());
|
||||
AddPoint(in.GetUR());
|
||||
}
|
||||
} else {
|
||||
valid = true;
|
||||
*this = in;
|
||||
}
|
||||
if (valid) {
|
||||
if (in.isValid()) {
|
||||
AddPoint(in.GetLL());
|
||||
AddPoint(in.GetUR());
|
||||
}
|
||||
} else {
|
||||
valid = true;
|
||||
*this = in;
|
||||
}
|
||||
}
|
||||
// See if there's any overlap between the two MBRs
|
||||
bool trpgMBR::Overlap(const trpg2dPoint &ill, const trpg2dPoint &iur) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid()) return false;
|
||||
|
||||
trpg2dPoint ilr = trpg2dPoint(iur.x,ill.y);
|
||||
trpg2dPoint iul = trpg2dPoint(ill.x,iur.y);
|
||||
trpg2dPoint ilr = trpg2dPoint(iur.x,ill.y);
|
||||
trpg2dPoint iul = trpg2dPoint(ill.x,iur.y);
|
||||
|
||||
// B MBR falls within A
|
||||
if (Within(ill) || Within(iur) || Within(ilr) || Within(iul))
|
||||
return true;
|
||||
// B MBR falls within A
|
||||
if (Within(ill) || Within(iur) || Within(ilr) || Within(iul))
|
||||
return true;
|
||||
|
||||
// A MBR falls within B
|
||||
if ((inRange(ill.x,iur.x,ll.x) && inRange(ill.y,iur.y,ll.y)) ||
|
||||
(inRange(ill.x,iur.x,ur.x) && inRange(ill.y,iur.y,ll.y)) ||
|
||||
(inRange(ill.x,iur.x,ur.x) && inRange(ill.y,iur.y,ur.y)) ||
|
||||
(inRange(ill.x,iur.x,ll.x) && inRange(ill.y,iur.y,ur.y)))
|
||||
return true;
|
||||
// A MBR falls within B
|
||||
if ((inRange(ill.x,iur.x,ll.x) && inRange(ill.y,iur.y,ll.y)) ||
|
||||
(inRange(ill.x,iur.x,ur.x) && inRange(ill.y,iur.y,ll.y)) ||
|
||||
(inRange(ill.x,iur.x,ur.x) && inRange(ill.y,iur.y,ur.y)) ||
|
||||
(inRange(ill.x,iur.x,ll.x) && inRange(ill.y,iur.y,ur.y)))
|
||||
return true;
|
||||
|
||||
if ((inRange(ll.x,ur.x,ill.x) && ill.y < ll.y && iur.y > ur.y) ||
|
||||
(inRange(ll.y,ur.y,ill.y) && ill.x < ll.x && iur.x > ur.x))
|
||||
return true;
|
||||
if ((inRange(ll.x,ur.x,ill.x) && ill.y < ll.y && iur.y > ur.y) ||
|
||||
(inRange(ll.y,ur.y,ill.y) && ill.x < ll.x && iur.x > ur.x))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
// Check if a given 2d point is within the MBR
|
||||
bool trpgMBR::Within(const trpg2dPoint &pt) const
|
||||
{
|
||||
if (inRange(ll.x,ur.x,pt.x) && inRange(ll.y,ur.y,pt.y))
|
||||
return true;
|
||||
return false;
|
||||
if (inRange(ll.x,ur.x,pt.x) && inRange(ll.y,ur.y,pt.y))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ****************
|
||||
Read Group Base
|
||||
Base class for all group structures.
|
||||
****************
|
||||
*/
|
||||
/* ****************
|
||||
Read Group Base
|
||||
Base class for all group structures.
|
||||
****************
|
||||
*/
|
||||
|
||||
// Destructor
|
||||
trpgReadGroupBase::~trpgReadGroupBase()
|
||||
{
|
||||
DeleteChildren();
|
||||
DeleteChildren();
|
||||
}
|
||||
|
||||
// Delete all children
|
||||
void trpgReadGroupBase::DeleteChildren()
|
||||
{
|
||||
for (unsigned int i=0;i<children.size();i++)
|
||||
if (children[i])
|
||||
delete children[i];
|
||||
for (unsigned int i=0;i<children.size();i++)
|
||||
if (children[i])
|
||||
delete children[i];
|
||||
}
|
||||
|
||||
// Add a child to the list
|
||||
void trpgReadGroupBase::AddChild(trpgReadNode *n)
|
||||
{
|
||||
children.push_back(n);
|
||||
children.push_back(n);
|
||||
}
|
||||
|
||||
// Unref a child (but don't delete it)
|
||||
void trpgReadGroupBase::unRefChild(int id)
|
||||
{
|
||||
if (id < 0 || id >= (int)children.size())
|
||||
return;
|
||||
children[id] = NULL;
|
||||
if (id < 0 || id >= (int)children.size())
|
||||
return;
|
||||
children[id] = NULL;
|
||||
}
|
||||
|
||||
// Unref all the children (they've probably been moved elsewhere)
|
||||
void trpgReadGroupBase::unRefChildren()
|
||||
{
|
||||
for (unsigned int i=0;i<children.size();i++)
|
||||
unRefChild(i);
|
||||
for (unsigned int i=0;i<children.size();i++)
|
||||
unRefChild(i);
|
||||
}
|
||||
|
||||
// Calculate an MBR
|
||||
trpgMBR trpgReadGroupBase::GetMBR() const
|
||||
{
|
||||
if (mbr.isValid())
|
||||
return mbr;
|
||||
else {
|
||||
// Calculate and cache a new MBR
|
||||
trpgMBR *cmbr = const_cast<trpgMBR *>(&mbr);
|
||||
trpgMBR kmbr;
|
||||
// Ask the kids
|
||||
for (unsigned int i=0;i<children.size();i++) {
|
||||
kmbr = children[i]->GetMBR();
|
||||
cmbr->Union(kmbr);
|
||||
}
|
||||
return *cmbr;
|
||||
}
|
||||
if (mbr.isValid())
|
||||
return mbr;
|
||||
else {
|
||||
// Calculate and cache a new MBR
|
||||
trpgMBR *cmbr = const_cast<trpgMBR *>(&mbr);
|
||||
trpgMBR kmbr;
|
||||
// Ask the kids
|
||||
for (unsigned int i=0;i<children.size();i++) {
|
||||
kmbr = children[i]->GetMBR();
|
||||
cmbr->Union(kmbr);
|
||||
}
|
||||
return *cmbr;
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************
|
||||
Read Geometry
|
||||
****************
|
||||
*/
|
||||
Read Geometry
|
||||
****************
|
||||
*/
|
||||
// Calculate an MBR
|
||||
trpgMBR trpgReadGeometry::GetMBR() const
|
||||
{
|
||||
if (mbr.isValid())
|
||||
return mbr;
|
||||
if (mbr.isValid())
|
||||
return mbr;
|
||||
|
||||
trpgMBR *pmbr = const_cast<trpgMBR *>(&mbr);
|
||||
trpgMBR *pmbr = const_cast<trpgMBR *>(&mbr);
|
||||
|
||||
int numVert,i;
|
||||
trpg3dPoint pt;
|
||||
data.GetNumVertex(numVert);
|
||||
numVert /= 3;
|
||||
for (i=0;i<numVert;i++) {
|
||||
data.GetVertex(i,pt);
|
||||
pmbr->AddPoint(pt);
|
||||
}
|
||||
int numVert,i;
|
||||
trpg3dPoint pt;
|
||||
data.GetNumVertex(numVert);
|
||||
numVert /= 3;
|
||||
for (i=0;i<numVert;i++) {
|
||||
data.GetVertex(i,pt);
|
||||
pmbr->AddPoint(pt);
|
||||
}
|
||||
|
||||
return mbr;
|
||||
return mbr;
|
||||
}
|
||||
|
||||
/* ****************
|
||||
Scene Graph Parser
|
||||
****************
|
||||
*/
|
||||
/* ****************
|
||||
Scene Graph Parser
|
||||
****************
|
||||
*/
|
||||
|
||||
/* Scene Graph Parser Helpers
|
||||
Each of these classes reads a certain kind of data (e.g. a group)
|
||||
and creates the appropriate trpgrRead* form and returns that.
|
||||
*/
|
||||
Each of these classes reads a certain kind of data (e.g. a group)
|
||||
and creates the appropriate trpgrRead* form and returns that.
|
||||
*/
|
||||
|
||||
/* This is a helper registered by trpgSceneGraphParser that readers trpgGeometry
|
||||
nodes and adds them to the current scene graph. trpgGeometry nodes are
|
||||
always leaves so there should be no pushes after this node. The Parse method
|
||||
also adds the new node as a child to any existing (e.g. top) group.
|
||||
{group:Demonstration Scene Graph}
|
||||
nodes and adds them to the current scene graph. trpgGeometry nodes are
|
||||
always leaves so there should be no pushes after this node. The Parse method
|
||||
also adds the new node as a child to any existing (e.g. top) group.
|
||||
{group:Demonstration Scene Graph}
|
||||
*/
|
||||
class trpgReadGeometryHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadGeometryHelper(trpgSceneGraphParser *in_parse) { parse = in_parse;}
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadGeometry *geom = new trpgReadGeometry();
|
||||
trpgGeometry *data = geom->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete geom;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(geom);
|
||||
else
|
||||
delete geom;
|
||||
trpgReadGeometryHelper(trpgSceneGraphParser *in_parse) { parse = in_parse;}
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadGeometry *geom = new trpgReadGeometry();
|
||||
trpgGeometry *data = geom->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete geom;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(geom);
|
||||
else
|
||||
delete geom;
|
||||
|
||||
return geom;
|
||||
}
|
||||
return geom;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
|
||||
/* This helper is registered by trpgSceneGraphParser. It reads a trpgGroup
|
||||
from the trpgReadBuffer. It then adds it to our current scene graph.
|
||||
It also adds an index corresponding to the group's group ID in our group
|
||||
mapping in trpgSceneGraphParser. The new group becomes the top one
|
||||
after returning from the Parse call.
|
||||
{group:Demonstration Scene Graph}
|
||||
from the trpgReadBuffer. It then adds it to our current scene graph.
|
||||
It also adds an index corresponding to the group's group ID in our group
|
||||
mapping in trpgSceneGraphParser. The new group becomes the top one
|
||||
after returning from the Parse call.
|
||||
{group:Demonstration Scene Graph}
|
||||
*/
|
||||
class trpgReadGroupHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadGroupHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadGroup *group = new trpgReadGroup();
|
||||
trpgGroup *data = group->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete group;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(group);
|
||||
else
|
||||
delete group;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = group;
|
||||
return group;
|
||||
}
|
||||
trpgReadGroupHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadGroup *group = new trpgReadGroup();
|
||||
trpgGroup *data = group->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete group;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(group);
|
||||
else
|
||||
delete group;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = group;
|
||||
return group;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
class trpgReadBillboardHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadBillboardHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadBillboard *group = new trpgReadBillboard();
|
||||
trpgBillboard *data = group->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete group;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(group);
|
||||
else
|
||||
delete group;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = group;
|
||||
return group;
|
||||
}
|
||||
trpgReadBillboardHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadBillboard *group = new trpgReadBillboard();
|
||||
trpgBillboard *data = group->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete group;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(group);
|
||||
else
|
||||
delete group;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = group;
|
||||
return group;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
class trpgReadAttachHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadAttachHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadAttach *attach = new trpgReadAttach();
|
||||
trpgAttach *data = attach->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete attach;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(attach);
|
||||
else
|
||||
delete attach;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = attach;
|
||||
return attach;
|
||||
}
|
||||
trpgReadAttachHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadAttach *attach = new trpgReadAttach();
|
||||
trpgAttach *data = attach->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete attach;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(attach);
|
||||
else
|
||||
delete attach;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = attach;
|
||||
return attach;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
|
||||
class trpgReadChildRefHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadChildRefHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadChildRef *childRef = new trpgReadChildRef();
|
||||
trpgChildRef *data = childRef->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete childRef;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
// NOTE: this is bad, we delete the pointer then we save it.
|
||||
// this is done everywhere and should be corrected
|
||||
if (top)
|
||||
top->AddChild(childRef);
|
||||
else
|
||||
delete childRef;
|
||||
|
||||
return childRef;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
class trpgReadLodHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadLodHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadLod *lod = new trpgReadLod();
|
||||
trpgLod *data = lod->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete lod;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(lod);
|
||||
else
|
||||
delete lod;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = lod;
|
||||
return lod;
|
||||
}
|
||||
trpgReadLodHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadLod *lod = new trpgReadLod();
|
||||
trpgLod *data = lod->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete lod;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(lod);
|
||||
else
|
||||
delete lod;
|
||||
// Add to the group map
|
||||
int id;
|
||||
data->GetID(id);
|
||||
trpgSceneGraphParser::GroupMap *gmap = parse->GetGroupMap();
|
||||
(*gmap)[id] = lod;
|
||||
return lod;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
class trpgReadModelRefHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadModelRefHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadModelRef *mod = new trpgReadModelRef();
|
||||
trpgModelRef *data = mod->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete mod;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(mod);
|
||||
else
|
||||
delete mod;
|
||||
return mod;
|
||||
}
|
||||
trpgReadModelRefHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadModelRef *mod = new trpgReadModelRef();
|
||||
trpgModelRef *data = mod->GetData();
|
||||
if (!data->Read(buf)) {
|
||||
delete mod;
|
||||
return NULL;
|
||||
}
|
||||
trpgReadGroupBase *top = parse->GetCurrTop();
|
||||
if (top)
|
||||
top->AddChild(mod);
|
||||
else
|
||||
delete mod;
|
||||
return mod;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
class trpgReadTileHeaderHelper : public trpgr_Callback {
|
||||
public:
|
||||
trpgReadTileHeaderHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadTileHeader *th = parse->GetTileHeaderRef();
|
||||
trpgTileHeader *data = th->GetData();
|
||||
if (!data->Read(buf))
|
||||
return NULL;
|
||||
return th;
|
||||
}
|
||||
trpgReadTileHeaderHelper(trpgSceneGraphParser *in_parse) { parse = in_parse; }
|
||||
void *Parse(trpgToken /*tok*/,trpgReadBuffer &buf) {
|
||||
trpgReadTileHeader *th = parse->GetTileHeaderRef();
|
||||
trpgTileHeader *data = th->GetData();
|
||||
if (!data->Read(buf))
|
||||
return NULL;
|
||||
return th;
|
||||
}
|
||||
protected:
|
||||
trpgSceneGraphParser *parse;
|
||||
trpgSceneGraphParser *parse;
|
||||
};
|
||||
|
||||
/* The Scene Graph Parser constructor does two things. First, it sets
|
||||
up any internal variables like a normal constructor. Then it registers
|
||||
an interest in all the node types it knows how to parse. It does this
|
||||
by calling AddCallback, which is a method of its parent. It passes in
|
||||
a token representing the node type (see trpg_io.h) and an object that
|
||||
is capable of parsing the given type.
|
||||
up any internal variables like a normal constructor. Then it registers
|
||||
an interest in all the node types it knows how to parse. It does this
|
||||
by calling AddCallback, which is a method of its parent. It passes in
|
||||
a token representing the node type (see trpg_io.h) and an object that
|
||||
is capable of parsing the given type.
|
||||
|
||||
The objects we pass in here are called helpers. They parse specific
|
||||
objects and add them to the user defined scene graph. Examples include
|
||||
trpgReadGeometryHelper, trpgReadGroupHelper, trpgReadAttachHelper,
|
||||
trpgReadBillboardHelper, trpgReadLodHelper, trpgReadModelRefHelper,
|
||||
trpgReadTileHeaderHelper. These are all derived from trpgr_Callback.
|
||||
You should not use any of these yourself. Instead look at these classes
|
||||
as examples of how to implement your own subclass of trpgSceneParser.
|
||||
*/
|
||||
The objects we pass in here are called helpers. They parse specific
|
||||
objects and add them to the user defined scene graph. Examples include
|
||||
trpgReadGeometryHelper, trpgReadGroupHelper, trpgReadAttachHelper,
|
||||
trpgReadBillboardHelper, trpgReadLodHelper, trpgReadModelRefHelper,
|
||||
trpgReadTileHeaderHelper. These are all derived from trpgr_Callback.
|
||||
You should not use any of these yourself. Instead look at these classes
|
||||
as examples of how to implement your own subclass of trpgSceneParser.
|
||||
*/
|
||||
trpgSceneGraphParser::trpgSceneGraphParser()
|
||||
{
|
||||
top = currTop = NULL;
|
||||
top = currTop = NULL;
|
||||
|
||||
// Register the readers
|
||||
AddCallback(TRPG_GEOMETRY,new trpgReadGeometryHelper(this));
|
||||
AddCallback(TRPG_GROUP,new trpgReadGroupHelper(this));
|
||||
AddCallback(TRPG_ATTACH,new trpgReadAttachHelper(this));
|
||||
AddCallback(TRPG_BILLBOARD,new trpgReadBillboardHelper(this));
|
||||
AddCallback(TRPG_LOD,new trpgReadLodHelper(this));
|
||||
// AddCallback(TRPG_TRANSFORM,new trpgReadTransformHelper(this));
|
||||
AddCallback(TRPG_MODELREF,new trpgReadModelRefHelper(this));
|
||||
// AddCallback(TRPG_LAYER,new trpgReadLayerHelper(this));
|
||||
AddCallback(TRPGTILEHEADER,new trpgReadTileHeaderHelper(this));
|
||||
// Register the readers
|
||||
AddCallback(TRPG_GEOMETRY,new trpgReadGeometryHelper(this));
|
||||
AddCallback(TRPG_GROUP,new trpgReadGroupHelper(this));
|
||||
AddCallback(TRPG_ATTACH,new trpgReadAttachHelper(this));
|
||||
AddCallback(TRPG_CHILDREF,new trpgReadChildRefHelper(this));
|
||||
AddCallback(TRPG_BILLBOARD,new trpgReadBillboardHelper(this));
|
||||
AddCallback(TRPG_LOD,new trpgReadLodHelper(this));
|
||||
// AddCallback(TRPG_TRANSFORM,new trpgReadTransformHelper(this));
|
||||
AddCallback(TRPG_MODELREF,new trpgReadModelRefHelper(this));
|
||||
// AddCallback(TRPG_LAYER,new trpgReadLayerHelper(this));
|
||||
AddCallback(TRPGTILEHEADER,new trpgReadTileHeaderHelper(this));
|
||||
}
|
||||
|
||||
// Get Current Top node
|
||||
trpgReadGroupBase *trpgSceneGraphParser::GetCurrTop()
|
||||
{
|
||||
if (!currTop)
|
||||
return NULL;
|
||||
if (currTop->isGroupType())
|
||||
return (trpgReadGroupBase *)currTop;
|
||||
if (!currTop)
|
||||
return NULL;
|
||||
if (currTop->isGroupType())
|
||||
return (trpgReadGroupBase *)currTop;
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return a pointer to the tile header record
|
||||
trpgReadTileHeader *trpgSceneGraphParser::GetTileHeaderRef()
|
||||
{
|
||||
return &tileHead;
|
||||
return &tileHead;
|
||||
}
|
||||
|
||||
// Parse Scene
|
||||
// Parse a buffer and return the resulting scene graph
|
||||
trpgReadNode *trpgSceneGraphParser::ParseScene(trpgReadBuffer &buf,GroupMap &inGmap)
|
||||
{
|
||||
gmap = &inGmap;
|
||||
trpgTileHeader *data = tileHead.GetData();
|
||||
data->Reset();
|
||||
gmap = &inGmap;
|
||||
trpgTileHeader *data = tileHead.GetData();
|
||||
data->Reset();
|
||||
|
||||
// Always put a group up top, since there might be more than
|
||||
// one node at the top level in the file.
|
||||
top = currTop = new trpgReadGroup();
|
||||
// Always put a group up top, since there might be more than
|
||||
// one node at the top level in the file.
|
||||
top = currTop = new trpgReadGroup();
|
||||
|
||||
// All the setup for tokens is handled in the constructor
|
||||
// Just call parse
|
||||
if (!Parse(buf)) {
|
||||
// Failed to parse correctly. Give up.
|
||||
delete top;
|
||||
return NULL;
|
||||
}
|
||||
// All the setup for tokens is handled in the constructor
|
||||
// Just call parse
|
||||
if (!Parse(buf)) {
|
||||
// Failed to parse correctly. Give up.
|
||||
delete top;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return top;
|
||||
return top;
|
||||
}
|
||||
|
||||
// Start Children
|
||||
@ -468,19 +493,19 @@ trpgReadNode *trpgSceneGraphParser::ParseScene(trpgReadBuffer &buf,GroupMap &inG
|
||||
// We'll want to make the node it's handing us the "top" node
|
||||
bool trpgSceneGraphParser::StartChildren(void *in_node)
|
||||
{
|
||||
trpgReadNode *node = (trpgReadNode *)in_node;
|
||||
trpgReadNode *node = (trpgReadNode *)in_node;
|
||||
|
||||
if (!node || !node->isGroupType()) {
|
||||
// Looks like there's a push in the wrong place
|
||||
// Make the current "top" NULL.
|
||||
// This will drop all node until we pop back above
|
||||
currTop = NULL;
|
||||
} else {
|
||||
// This node is our new "top"
|
||||
currTop = node;
|
||||
}
|
||||
if (!node || !node->isGroupType()) {
|
||||
// Looks like there's a push in the wrong place
|
||||
// Make the current "top" NULL.
|
||||
// This will drop all node until we pop back above
|
||||
currTop = NULL;
|
||||
} else {
|
||||
// This node is our new "top"
|
||||
currTop = node;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is called whent he parser hits a pop.
|
||||
@ -488,67 +513,67 @@ bool trpgSceneGraphParser::StartChildren(void *in_node)
|
||||
for the parent above the current one.
|
||||
If there isn't one, we'll just stick things in our top group.
|
||||
*/
|
||||
bool trpgSceneGraphParser::EndChildren(void * /*in_node*/)
|
||||
bool trpgSceneGraphParser::EndChildren(void* /*in_node*/)
|
||||
{
|
||||
// We don't need it here, but this is the node we just
|
||||
// finished putting children under. If you need to close
|
||||
// it out in some way, do that here
|
||||
//trpgReadNode *node = (trpgReadNode *)in_node;
|
||||
// We don't need it here, but this is the node we just
|
||||
// finished putting children under. If you need to close
|
||||
// it out in some way, do that here
|
||||
//trpgReadNode *node = (trpgReadNode *)in_node;
|
||||
|
||||
// Get the parent above the current one
|
||||
int pos = parents.size()-2;
|
||||
if (pos < 0)
|
||||
// Nothing above the current one. Fall back on our top group
|
||||
currTop = top;
|
||||
else
|
||||
currTop = (trpgReadNode *)parents[pos];
|
||||
// Get the parent above the current one
|
||||
int pos = parents.size()-2;
|
||||
if (pos < 0)
|
||||
// Nothing above the current one. Fall back on our top group
|
||||
currTop = top;
|
||||
else
|
||||
currTop = (trpgReadNode *)parents[pos];
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return group map (for use by helpers)
|
||||
trpgSceneGraphParser::GroupMap *trpgSceneGraphParser::GetGroupMap()
|
||||
{
|
||||
return gmap;
|
||||
return gmap;
|
||||
}
|
||||
|
||||
/* ***********
|
||||
Test functions
|
||||
***********
|
||||
*/
|
||||
Test functions
|
||||
***********
|
||||
*/
|
||||
|
||||
// Test all the tiles in an archive
|
||||
bool trpgTestArchive(trpgr_Archive &archive)
|
||||
{
|
||||
int numLod;
|
||||
trpg2iPoint tileSize;
|
||||
trpgSceneGraphParser parse;
|
||||
trpgReadNode *scene;
|
||||
trpgSceneGraphParser::GroupMap gmap;
|
||||
int numLod;
|
||||
trpg2iPoint tileSize;
|
||||
trpgSceneGraphParser parse;
|
||||
trpgReadNode *scene;
|
||||
trpgSceneGraphParser::GroupMap gmap;
|
||||
|
||||
if (!archive.isValid()) return false;
|
||||
if (!archive.isValid()) return false;
|
||||
|
||||
const trpgHeader *head = archive.GetHeader();
|
||||
head->GetNumLods(numLod);
|
||||
const trpgHeader *head = archive.GetHeader();
|
||||
head->GetNumLods(numLod);
|
||||
|
||||
// Iterate over the lods
|
||||
int nl,x,y;
|
||||
trpgMemReadBuffer buf(archive.GetEndian());
|
||||
trpg3dPoint ll,ur;
|
||||
for (nl = 0;nl < numLod;nl++) {
|
||||
head->GetLodSize(nl,tileSize);
|
||||
// Iterate over the tiles within those
|
||||
for (x = 0; x < tileSize.x; x++)
|
||||
for (y = 0; y < tileSize.y; y++) {
|
||||
archive.trpgGetTileMBR(x,y,nl,ll,ur);
|
||||
if (archive.ReadTile(x,y,nl,buf)) {
|
||||
// Parse it
|
||||
scene = parse.ParseScene(buf,gmap);
|
||||
if (scene)
|
||||
delete scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Iterate over the lods
|
||||
int nl,x,y;
|
||||
trpgMemReadBuffer buf(archive.GetEndian());
|
||||
trpg3dPoint ll,ur;
|
||||
for (nl = 0;nl < numLod;nl++) {
|
||||
head->GetLodSize(nl,tileSize);
|
||||
// Iterate over the tiles within those
|
||||
for (x = 0; x < tileSize.x; x++)
|
||||
for (y = 0; y < tileSize.y; y++) {
|
||||
archive.trpgGetTileMBR(x,y,nl,ll,ur);
|
||||
if (archive.ReadTile(x,y,nl,buf)) {
|
||||
// Parse it
|
||||
scene = parse.ParseScene(buf,gmap);
|
||||
if (scene)
|
||||
delete scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
@ -18,221 +18,234 @@
|
||||
#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.
|
||||
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}
|
||||
*/
|
||||
{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;
|
||||
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;
|
||||
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}
|
||||
// {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(); }
|
||||
virtual ~trpgReadNode(void) { };
|
||||
virtual bool isGroupType(void) = 0;
|
||||
virtual int GetType(void) { return type; }
|
||||
virtual trpgMBR GetMBR(void) const { return trpgMBR(); }
|
||||
protected:
|
||||
int type;
|
||||
int type;
|
||||
};
|
||||
|
||||
// Read Group Base
|
||||
// Base class for all group nodes
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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);
|
||||
virtual ~trpgReadGroupBase(void);
|
||||
void AddChild(trpgReadNode *);
|
||||
bool isGroupType(void) { return true; }
|
||||
int GetNumChildren(void) { return int(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;
|
||||
trpgMBR mbr;
|
||||
void DeleteChildren(void);
|
||||
std::vector<trpgReadNode *> children;
|
||||
};
|
||||
|
||||
// Read Geometry
|
||||
// The leaf for this scene graph
|
||||
// {group:Demonstration 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;
|
||||
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;
|
||||
trpgMBR mbr;
|
||||
trpgGeometry data;
|
||||
};
|
||||
|
||||
// Read Tile Header
|
||||
// One per tile. Info about what materials and models are used
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; };
|
||||
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;
|
||||
trpgTileHeader data;
|
||||
};
|
||||
|
||||
// Read Group
|
||||
// Simple group structure
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadGroup(void) { type = TRPG_GROUP; }
|
||||
~trpgReadGroup(void) { };
|
||||
trpgGroup *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgGroup data;
|
||||
trpgGroup data;
|
||||
};
|
||||
|
||||
// Read Attach
|
||||
// Should be the top of a higher LOD tile
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadAttach(void) { type = TRPG_ATTACH; }
|
||||
~trpgReadAttach(void) { };
|
||||
trpgAttach *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgAttach data;
|
||||
trpgAttach data;
|
||||
};
|
||||
|
||||
// Read ChildRef
|
||||
// Should point to a block tile
|
||||
// {group:Demonstration Scene Graph}
|
||||
TX_EXDECL class TX_CLDECL trpgReadChildRef : public trpgReadGroupBase {
|
||||
public:
|
||||
trpgReadChildRef(void) { type = TRPG_CHILDREF; }
|
||||
~trpgReadChildRef(void) { };
|
||||
bool isGroupType(void) { return false;}
|
||||
trpgChildRef *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgChildRef data;
|
||||
};
|
||||
|
||||
// Read billboard
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadBillboard(void) { type = TRPG_BILLBOARD; }
|
||||
~trpgReadBillboard(void) { };
|
||||
trpgBillboard *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgBillboard data;
|
||||
trpgBillboard data;
|
||||
};
|
||||
|
||||
// Read LOD
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadLod(void) { type = TRPG_LOD; }
|
||||
~trpgReadLod(void) { };
|
||||
trpgLod *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgLod data;
|
||||
trpgLod data;
|
||||
};
|
||||
|
||||
// Read Layer
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadLayer(void) { type = TRPG_LAYER; }
|
||||
~trpgReadLayer(void) { };
|
||||
trpgLayer *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgLayer data;
|
||||
trpgLayer data;
|
||||
};
|
||||
|
||||
// Read Transform
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadTransform(void) { type = TRPG_TRANSFORM; }
|
||||
~trpgReadTransform(void) { };
|
||||
trpgTransform *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgTransform data;
|
||||
trpgTransform data;
|
||||
};
|
||||
|
||||
// Read Model Reference
|
||||
// {group:Demonstration Scene Graph}
|
||||
// {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; }
|
||||
trpgReadModelRef(void) { type = TRPG_MODELREF; }
|
||||
~trpgReadModelRef(void) { };
|
||||
trpgModelRef *GetData(void) { return &data; }
|
||||
protected:
|
||||
trpgModelRef data;
|
||||
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}
|
||||
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;
|
||||
typedef std::map<int,trpgReadGroupBase *> GroupMap;
|
||||
#else
|
||||
typedef std::map<int,trpgReadGroupBase *,std::less<int> > GroupMap;
|
||||
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);
|
||||
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);
|
||||
// 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
|
||||
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}
|
||||
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
|
||||
|
@ -17,15 +17,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
/* trpage_swap.h
|
||||
Byte swapping utility functions.
|
||||
*/
|
||||
Byte swapping utility functions.
|
||||
*/
|
||||
|
||||
#include <trpage_swap.h>
|
||||
|
||||
/*
|
||||
** func: swap_two( in, out )
|
||||
** func: swap_two( in, out )
|
||||
**
|
||||
** desc: byte-swaps a two-byte array.
|
||||
** desc: byte-swaps a two-byte array.
|
||||
*/
|
||||
void trpg_swap_two ( const char *in, char *out )
|
||||
{
|
||||
@ -38,9 +38,9 @@ void trpg_swap_two ( const char *in, char *out )
|
||||
}
|
||||
|
||||
/*
|
||||
** func: swap_four( in, out )
|
||||
** func: swap_four( in, out )
|
||||
**
|
||||
** desc: byte-swaps a four-byte array.
|
||||
** desc: byte-swaps a four-byte array.
|
||||
*/
|
||||
void trpg_swap_four ( const char *in, char *out )
|
||||
{
|
||||
@ -55,9 +55,9 @@ void trpg_swap_four ( const char *in, char *out )
|
||||
}
|
||||
|
||||
/*
|
||||
** func: swap_eight( in, out )
|
||||
** func: swap_eight( in, out )
|
||||
**
|
||||
** desc: byte-swaps an eight-byte array.
|
||||
** desc: byte-swaps an eight-byte array.
|
||||
*/
|
||||
void trpg_swap_eight ( const char *in, char *out )
|
||||
{
|
||||
@ -76,9 +76,9 @@ void trpg_swap_eight ( const char *in, char *out )
|
||||
}
|
||||
|
||||
/*
|
||||
** func: swap_sixteen( in, out )
|
||||
** func: swap_sixteen( in, out )
|
||||
**
|
||||
** desc: byte-swaps an sixteen-byte array.
|
||||
** desc: byte-swaps an sixteen-byte array.
|
||||
*/
|
||||
void trpg_swap_sixteen ( const char *in, char *out )
|
||||
{
|
||||
@ -105,105 +105,105 @@ void trpg_swap_sixteen ( const char *in, char *out )
|
||||
}
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_short( number )
|
||||
** func: tx_byteswap_short( number )
|
||||
**
|
||||
** desc: byte-swaps a short int.
|
||||
** desc: byte-swaps a short int.
|
||||
*/
|
||||
short trpg_byteswap_short( short number )
|
||||
{
|
||||
short result;
|
||||
short result;
|
||||
|
||||
trpg_swap_two( (const char*) &number, (char*) &result );
|
||||
return result;
|
||||
trpg_swap_two( (const char*) &number, (char*) &result );
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_int( number )
|
||||
** func: tx_byteswap_int( number )
|
||||
**
|
||||
** desc: byte-swaps an int.
|
||||
** desc: byte-swaps an int.
|
||||
*/
|
||||
int trpg_byteswap_int( int number )
|
||||
TX_CPPDECL int trpg_byteswap_int( int number )
|
||||
{
|
||||
int result;
|
||||
int result;
|
||||
|
||||
trpg_swap_four( (const char*) &number, (char*) &result );
|
||||
return result;
|
||||
trpg_swap_four( (const char*) &number, (char*) &result );
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_long( number )
|
||||
** func: tx_byteswap_long( number )
|
||||
**
|
||||
** desc: byte-swaps a long int.
|
||||
** desc: byte-swaps a long int.
|
||||
*/
|
||||
long trpg_byteswap_long( long number )
|
||||
{
|
||||
long result;
|
||||
long result;
|
||||
|
||||
trpg_swap_four( (const char*) &number, (char*) &result );
|
||||
return result;
|
||||
trpg_swap_four( (const char*) &number, (char*) &result );
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_float( number )
|
||||
** func: tx_byteswap_float( number )
|
||||
**
|
||||
** desc: byte-swaps a float.
|
||||
** desc: byte-swaps a float.
|
||||
*/
|
||||
void trpg_byteswap_float_to_4bytes( float number, char result[4] )
|
||||
{
|
||||
trpg_swap_four( (const char*) &number, result );
|
||||
trpg_swap_four( (const char*) &number, result );
|
||||
}
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_double_to_8bytes( number )
|
||||
** func: tx_byteswap_double_to_8bytes( number )
|
||||
**
|
||||
** desc: byte-swaps a double.
|
||||
** desc: byte-swaps a double.
|
||||
*/
|
||||
void trpg_byteswap_double_to_8bytes( double number, char result[8] )
|
||||
{
|
||||
trpg_swap_eight( (const char*) &number, result );
|
||||
trpg_swap_eight( (const char*) &number, result );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_float( number )
|
||||
** func: tx_byteswap_float( number )
|
||||
**
|
||||
** desc: byte-swaps a float.
|
||||
** desc: byte-swaps a float.
|
||||
*/
|
||||
float trpg_byteswap_4bytes_to_float( const char result[4] )
|
||||
{
|
||||
float number;
|
||||
trpg_swap_four( result, (char*) &number );
|
||||
return number;
|
||||
float number;
|
||||
trpg_swap_four( result, (char*) &number );
|
||||
return number;
|
||||
}
|
||||
|
||||
/*
|
||||
** func: tx_byteswap_double_to_8bytes( number )
|
||||
** func: tx_byteswap_double_to_8bytes( number )
|
||||
**
|
||||
** desc: byte-swaps a double.
|
||||
** desc: byte-swaps a double.
|
||||
*/
|
||||
double trpg_byteswap_8bytes_to_double( const char result[8] )
|
||||
{
|
||||
double number;
|
||||
trpg_swap_eight( result, (char*) &number );
|
||||
return number;
|
||||
double number;
|
||||
trpg_swap_eight( result, (char*) &number );
|
||||
return number;
|
||||
}
|
||||
|
||||
trpgllong trpg_byteswap_llong ( trpgllong number )
|
||||
{
|
||||
trpgllong result;
|
||||
trpgllong result;
|
||||
|
||||
trpg_swap_sixteen ( (char *) &number, (char *) &result);
|
||||
trpg_swap_sixteen ( (char *) &number, (char *) &result);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
trpgEndian trpg_cpu_byte_order(void)
|
||||
TX_CPPDECL trpgEndian trpg_cpu_byte_order(void)
|
||||
{
|
||||
static char big_endian_100[2] = { 0, 100 };
|
||||
static char big_endian_100[2] = { 0, 100 };
|
||||
|
||||
if ( (*((short*) big_endian_100)) == 100 )
|
||||
return BigEndian;
|
||||
else
|
||||
return LittleEndian;
|
||||
if ( (*((short*) big_endian_100)) == 100 )
|
||||
return BigEndian;
|
||||
else
|
||||
return LittleEndian;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define trpage_swap_h_
|
||||
|
||||
/* trpage_swap.h
|
||||
Byte swapping utility functions.
|
||||
Byte swapping utility functions.
|
||||
*/
|
||||
|
||||
#include <trpage_sys.h>
|
||||
@ -29,7 +29,7 @@
|
||||
short trpg_byteswap_short( short number );
|
||||
// Byte swap and return an integer
|
||||
// {group:Byte Ordering Utilities}
|
||||
int trpg_byteswap_int( int number );
|
||||
TX_CPPDECL int trpg_byteswap_int( int number );
|
||||
// Byte swap and return a long
|
||||
// {group:Byte Ordering Utilities}
|
||||
long trpg_byteswap_long( long number );
|
||||
@ -50,7 +50,7 @@ float trpg_byteswap_4bytes_to_float( const char result[4] );
|
||||
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);
|
||||
TX_CPPDECL trpgEndian trpg_cpu_byte_order(void);
|
||||
|
||||
// Swap two chars
|
||||
// {group:Byte Ordering Utilities}
|
||||
|
@ -14,8 +14,8 @@
|
||||
*/
|
||||
|
||||
/* trpage_sys.h
|
||||
System specific declarations.
|
||||
*/
|
||||
System specific declarations.
|
||||
*/
|
||||
|
||||
#ifndef trpage_sys_h_
|
||||
#define trpage_sys_h_
|
||||
@ -29,11 +29,11 @@
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* *********************
|
||||
System Specific Section.
|
||||
This is currently set up for win32.
|
||||
*********************
|
||||
*/
|
||||
/* *********************
|
||||
System Specific Section.
|
||||
This is currently set up for win32.
|
||||
*********************
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@ -86,15 +86,15 @@ typedef float float32;
|
||||
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
|
||||
|
||||
#if defined(_WIN32) || defined(linux)
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#else
|
||||
#include <vector.h>
|
||||
#include <map.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) // PJM
|
||||
// Had to take this out because of an iostream conflict
|
||||
|
@ -17,234 +17,316 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* trpage_tile.cpp
|
||||
This source file contains the implementation of trpgTileTable and trpgTileHeader.
|
||||
You'll need to edit these if you want to add something to the Tile Table (at
|
||||
the front of an archive) or the Tile Header (at the beginning of each tile).
|
||||
*/
|
||||
This source file contains the implementation of trpgTileTable and trpgTileHeader.
|
||||
You'll need to edit these if you want to add something to the Tile Table (at
|
||||
the front of an archive) or the Tile Header (at the beginning of each tile).
|
||||
*/
|
||||
|
||||
#include <trpage_geom.h>
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* Write Tile Table
|
||||
Keeps track of tiles written to disk.
|
||||
*/
|
||||
Keeps track of tiles written to disk.
|
||||
*/
|
||||
|
||||
// Constructor
|
||||
trpgTileTable::trpgTileTable()
|
||||
{
|
||||
Reset();
|
||||
localBlock = false;
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Reset function
|
||||
void trpgTileTable::Reset()
|
||||
{
|
||||
errMess[0] = '\0';
|
||||
mode = External;
|
||||
lodInfo.resize(0);
|
||||
valid = true;
|
||||
errMess[0] = '\0';
|
||||
mode = External;
|
||||
lodInfo.resize(0);
|
||||
valid = true;
|
||||
currentRow = -1;
|
||||
currentCol = -1;
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
trpgTileTable::~trpgTileTable()
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// Set functions
|
||||
|
||||
void trpgTileTable::SetMode(TileMode inMode)
|
||||
{
|
||||
Reset();
|
||||
mode = inMode;
|
||||
Reset();
|
||||
mode = inMode;
|
||||
}
|
||||
|
||||
void trpgTileTable::SetNumLod(int numLod)
|
||||
{
|
||||
lodInfo.resize(numLod);
|
||||
lodInfo.resize(numLod);
|
||||
}
|
||||
|
||||
|
||||
void trpgTileTable::SetNumTiles(int nx,int ny,int lod)
|
||||
{
|
||||
if (nx <= 0 || ny <= 0 || lod < 0 || lod >= (int)lodInfo.size())
|
||||
return;
|
||||
|
||||
if(localBlock) {
|
||||
LodInfo &li = lodInfo[lod];
|
||||
li.numX = nx; li.numY = ny;
|
||||
li.addr.resize(1);
|
||||
li.elev_min.resize(1,0.0);
|
||||
li.elev_max.resize(1,0.0);
|
||||
valid = true;
|
||||
// no need to do anything else if we only have one block.
|
||||
return;
|
||||
}
|
||||
if (nx <= 0 || ny <= 0 || lod < 0 || lod >= static_cast<int>(lodInfo.size()))
|
||||
return;
|
||||
|
||||
// Got a table we need to maintain
|
||||
if (mode == Local) {
|
||||
// If there's a pre-existing table, we need to preserve the entries
|
||||
LodInfo oldLodInfo = lodInfo[lod];
|
||||
// Got a table we need to maintain
|
||||
if (mode == Local || mode == ExternalSaved) {
|
||||
// If there's a pre-existing table, we need to preserve the entries
|
||||
LodInfo oldLodInfo = lodInfo[lod];
|
||||
|
||||
LodInfo &li = lodInfo[lod];
|
||||
li.numX = nx; li.numY = ny;
|
||||
int numTile = li.numX*li.numY;
|
||||
li.addr.resize(numTile);
|
||||
li.elev_min.resize(numTile,0.0);
|
||||
li.elev_max.resize(numTile,0.0);
|
||||
LodInfo &li = lodInfo[lod];
|
||||
li.numX = nx; li.numY = ny;
|
||||
int numTile = li.numX*li.numY;
|
||||
li.addr.resize(numTile);
|
||||
li.elev_min.resize(numTile,0.0);
|
||||
li.elev_max.resize(numTile,0.0);
|
||||
|
||||
// Copy pre-existing data if it's there
|
||||
if (oldLodInfo.addr.size() > 0) {
|
||||
for (int x=0;x<oldLodInfo.numX;x++) {
|
||||
for (int y=0;y<oldLodInfo.numY;y++) {
|
||||
int oldLoc = y*oldLodInfo.numX + x;
|
||||
int newLoc = y*li.numX + x;
|
||||
li.addr[newLoc] = oldLodInfo.addr[oldLoc];
|
||||
li.elev_min[newLoc] = oldLodInfo.elev_min[oldLoc];
|
||||
li.elev_max[newLoc] = oldLodInfo.elev_max[oldLoc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
valid = true;
|
||||
// Copy pre-existing data if it's there
|
||||
if (oldLodInfo.addr.size() > 0) {
|
||||
for (int x=0;x<oldLodInfo.numX;x++) {
|
||||
for (int y=0;y<oldLodInfo.numY;y++) {
|
||||
int oldLoc = y*oldLodInfo.numX + x;
|
||||
int newLoc = y*li.numX + x;
|
||||
li.addr[newLoc] = oldLodInfo.addr[oldLoc];
|
||||
li.elev_min[newLoc] = oldLodInfo.elev_min[oldLoc];
|
||||
li.elev_max[newLoc] = oldLodInfo.elev_max[oldLoc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
valid = true;
|
||||
}
|
||||
void trpgTileTable::SetTile(int x,int y,int lod,trpgwAppAddress &ref,float32 zmin,float32 zmax)
|
||||
{
|
||||
if (lod < 0 || lod >= (int)lodInfo.size()) return;
|
||||
if (mode != Local)
|
||||
return;
|
||||
LodInfo &li = lodInfo[lod];
|
||||
if (x < 0 || x >= li.numX || y < 0 || y >= li.numY)
|
||||
return;
|
||||
|
||||
int loc = y*li.numX + x;
|
||||
li.addr[loc] = ref;
|
||||
li.elev_min[loc] = zmin;
|
||||
li.elev_max[loc] = zmax;
|
||||
if (lod < 0 || lod >= static_cast<int>(lodInfo.size()))
|
||||
return;
|
||||
if (mode == External)
|
||||
return;
|
||||
LodInfo &li = lodInfo[lod];
|
||||
int loc;
|
||||
if(localBlock) {
|
||||
loc = 0;
|
||||
}
|
||||
else {
|
||||
if (x < 0 || x >= li.numX || y < 0 || y >= li.numY)
|
||||
return;
|
||||
loc = y*li.numX + x;
|
||||
}
|
||||
li.addr[loc] = ref;
|
||||
li.elev_min[loc] = zmin;
|
||||
li.elev_max[loc] = zmax;
|
||||
}
|
||||
|
||||
bool trpgTileTable::isValid() const
|
||||
{
|
||||
return valid;
|
||||
return valid;
|
||||
}
|
||||
|
||||
// Get methods
|
||||
|
||||
bool trpgTileTable::GetMode(TileMode &outMode) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid()) return false;
|
||||
|
||||
outMode = mode;
|
||||
return true;
|
||||
outMode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool trpgTileTable::GetTile(int x,int y,int lod,trpgwAppAddress &ref,float32 &zmin,float32 &zmax) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid()) return false;
|
||||
|
||||
if (lod < 0 || lod >= (int)lodInfo.size()) return false;
|
||||
if (mode != Local)
|
||||
return false;
|
||||
const LodInfo &li = lodInfo[lod];
|
||||
if (x < 0 || x >= li.numX || y < 0 || y >= li.numY)
|
||||
return false;
|
||||
if (lod < 0 || lod >= static_cast<int>(lodInfo.size())) return false;
|
||||
if (mode == External)
|
||||
return false;
|
||||
|
||||
int loc = y*li.numX + x;
|
||||
ref = li.addr[loc];
|
||||
zmin = li.elev_min[loc];
|
||||
zmax = li.elev_max[loc];
|
||||
const LodInfo &li = lodInfo[lod];
|
||||
int loc;
|
||||
if(localBlock) {
|
||||
loc = 0;
|
||||
}
|
||||
else {
|
||||
if (x < 0 || x >= li.numX || y < 0 || y >= li.numY)
|
||||
return false;
|
||||
loc = y*li.numX + x;
|
||||
}
|
||||
|
||||
ref = li.addr[loc];
|
||||
zmin = li.elev_min[loc];
|
||||
zmax = li.elev_max[loc];
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write tile table
|
||||
bool trpgTileTable::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGTILETABLE2);
|
||||
|
||||
// Write the mode
|
||||
buf.Add(mode);
|
||||
buf.Begin(TRPGTILETABLE2);
|
||||
|
||||
// Write the mode
|
||||
buf.Add(mode);
|
||||
|
||||
// Depending on the mode we'll have a lot or a little data
|
||||
if (mode == Local) {
|
||||
// The lod sizing is redundant, but it's convenient here
|
||||
int numLod = lodInfo.size();
|
||||
buf.Add(numLod);
|
||||
// Depending on the mode we'll have a lot or a little data
|
||||
if (mode == Local || mode == ExternalSaved) {
|
||||
// The lod sizing is redundant, but it's convenient here
|
||||
int numLod = lodInfo.size();
|
||||
buf.Add(numLod);
|
||||
|
||||
// Write each terrain LOD set
|
||||
for (int i=0;i<numLod;i++) {
|
||||
LodInfo &li = lodInfo[i];
|
||||
buf.Add(li.numX);
|
||||
buf.Add(li.numY);
|
||||
// Now for the interesting stuff
|
||||
unsigned int j;
|
||||
for (j=0;j<li.addr.size();j++) {
|
||||
trpgwAppAddress &ref = li.addr[j];
|
||||
buf.Add((int32)ref.file);
|
||||
buf.Add((int32)ref.offset);
|
||||
}
|
||||
for (j=0;j<li.elev_min.size();j++) {
|
||||
buf.Add(li.elev_min[j]);
|
||||
buf.Add(li.elev_max[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Write each terrain LOD set
|
||||
for (int i=0;i<numLod;i++) {
|
||||
LodInfo &li = lodInfo[i];
|
||||
if(localBlock) {
|
||||
// only one x and one y in a local archive
|
||||
buf.Add(1);
|
||||
buf.Add(1);
|
||||
// local blocks always use index 0
|
||||
trpgwAppAddress &ref = li.addr[0];
|
||||
buf.Add((int32)ref.file);
|
||||
buf.Add((int32)ref.offset);
|
||||
|
||||
buf.End();
|
||||
buf.Add(li.elev_min[0]);
|
||||
buf.Add(li.elev_max[0]);
|
||||
}
|
||||
else {
|
||||
buf.Add(li.numX);
|
||||
buf.Add(li.numY);
|
||||
// Now for the interesting stuff
|
||||
unsigned int j;
|
||||
for (j=0;j<li.addr.size();j++) {
|
||||
trpgwAppAddress &ref = li.addr[j];
|
||||
buf.Add((int32)ref.file);
|
||||
buf.Add((int32)ref.offset);
|
||||
}
|
||||
for (j=0;j<li.elev_min.size();j++) {
|
||||
buf.Add(li.elev_min[j]);
|
||||
buf.Add(li.elev_max[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* **************
|
||||
Tile Table Read method
|
||||
**************
|
||||
*/
|
||||
/* **************
|
||||
Tile Table Read method
|
||||
**************
|
||||
*/
|
||||
|
||||
|
||||
bool trpgTileTable::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
valid = false;
|
||||
valid = false;
|
||||
|
||||
try {
|
||||
int imode;
|
||||
buf.Get(imode); mode = (TileMode)imode;
|
||||
if (mode != External && mode != Local) throw 1;
|
||||
if (mode == Local) {
|
||||
int numLod;
|
||||
buf.Get(numLod);
|
||||
if (numLod <= 0) throw 1;
|
||||
lodInfo.resize(numLod);
|
||||
try {
|
||||
int imode;
|
||||
buf.Get(imode); mode = (TileMode)imode;
|
||||
if (mode != External && mode != Local && mode != ExternalSaved) throw 1;
|
||||
if (mode == Local || mode == ExternalSaved) {
|
||||
int numLod;
|
||||
buf.Get(numLod);
|
||||
if (numLod <= 0) throw 1;
|
||||
lodInfo.resize(numLod);
|
||||
|
||||
for (int i=0;i<numLod;i++) {
|
||||
LodInfo &li = lodInfo[i];
|
||||
buf.Get(li.numX);
|
||||
buf.Get(li.numY);
|
||||
if (li.numX <= 0 || li.numY <= 0) throw 1;
|
||||
int numTile = li.numX*li.numY;
|
||||
li.addr.resize(numTile);
|
||||
li.elev_min.resize(numTile);
|
||||
li.elev_max.resize(numTile);
|
||||
int j;
|
||||
for (j=0;j<numTile;j++) {
|
||||
trpgwAppAddress &ref = li.addr[j];
|
||||
buf.Get(ref.file);
|
||||
buf.Get(ref.offset);
|
||||
}
|
||||
for (j=0;j<numTile;j++) {
|
||||
buf.Get(li.elev_min[j]);
|
||||
buf.Get(li.elev_max[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0;i<numLod;i++) {
|
||||
|
||||
valid = true;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
LodInfo &li = lodInfo[i];
|
||||
if(localBlock) {
|
||||
if(li.addr.size()==0) {
|
||||
li.addr.resize(1);
|
||||
li.elev_min.resize(1,0.0);
|
||||
li.elev_max.resize(1,0.0);
|
||||
}
|
||||
int32 x,y;
|
||||
buf.Get(x);
|
||||
buf.Get(y);
|
||||
int pos = (currentRow * li.numX) + currentCol;
|
||||
int32 file,offset;
|
||||
buf.Get(file);
|
||||
buf.Get(offset);
|
||||
trpgwAppAddress &ref = li.addr[pos];
|
||||
ref.file = file;
|
||||
ref.offset = offset;
|
||||
ref.col = currentCol;
|
||||
ref.row = currentRow;
|
||||
|
||||
float emin,emax;
|
||||
buf.Get(emin);
|
||||
buf.Get(emax);
|
||||
|
||||
return isValid();
|
||||
li.elev_max[pos] = emax;
|
||||
li.elev_min[pos] = emin;
|
||||
}
|
||||
else {
|
||||
buf.Get(li.numX);
|
||||
buf.Get(li.numY);
|
||||
if (li.numX <= 0 || li.numY <= 0)
|
||||
throw 1;
|
||||
int numTile = li.numX*li.numY;
|
||||
li.addr.resize(numTile);
|
||||
li.elev_min.resize(numTile);
|
||||
li.elev_max.resize(numTile);
|
||||
int j;
|
||||
for (j=0;j<numTile;j++) {
|
||||
int32 file,offset;
|
||||
buf.Get(file);
|
||||
buf.Get(offset);
|
||||
trpgwAppAddress &ref = li.addr[j];
|
||||
ref.file = file;
|
||||
ref.offset = offset;
|
||||
}
|
||||
for (j=0;j<numTile;j++) {
|
||||
float emin,emax;
|
||||
buf.Get(emin);
|
||||
buf.Get(emax);
|
||||
li.elev_max[j] = emax;
|
||||
li.elev_min[j] = emin;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
valid = true;
|
||||
}
|
||||
catch (...) {
|
||||
printf("Caught an exception\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValid();
|
||||
}
|
||||
|
||||
/* Tile Header
|
||||
Each distinct tile (or model) must have a header
|
||||
which tells you what models and materials are
|
||||
referenced in that tile.
|
||||
*/
|
||||
Each distinct tile (or model) must have a header
|
||||
which tells you what models and materials are
|
||||
referenced in that tile.
|
||||
*/
|
||||
// Constructor
|
||||
trpgTileHeader::trpgTileHeader()
|
||||
{
|
||||
col = -1;
|
||||
row = -1;
|
||||
}
|
||||
trpgTileHeader::~trpgTileHeader()
|
||||
{
|
||||
@ -252,45 +334,47 @@ trpgTileHeader::~trpgTileHeader()
|
||||
|
||||
void trpgTileHeader::Reset()
|
||||
{
|
||||
matList.resize(0);
|
||||
modelList.resize(0);
|
||||
locMats.resize(0);
|
||||
matList.resize(0);
|
||||
modelList.resize(0);
|
||||
locMats.resize(0);
|
||||
col = -1;
|
||||
row = -1;
|
||||
}
|
||||
|
||||
// Set functions
|
||||
void trpgTileHeader::SetMaterial(int no,int id)
|
||||
{
|
||||
if (no < 0 || no >= (int)matList.size())
|
||||
return;
|
||||
matList[no] = id;
|
||||
if (no < 0 || no >= static_cast<int>(matList.size()))
|
||||
return;
|
||||
matList[no] = id;
|
||||
}
|
||||
void trpgTileHeader::SetModel(int no,int id)
|
||||
{
|
||||
if (no < 0 || no >= (int)modelList.size())
|
||||
return;
|
||||
modelList[no] = id;
|
||||
if (no < 0 || no >= static_cast<int>(modelList.size()))
|
||||
return;
|
||||
modelList[no] = id;
|
||||
}
|
||||
|
||||
// Set functions
|
||||
void trpgTileHeader::AddMaterial(int id)
|
||||
{
|
||||
// Look for it first
|
||||
// Look for it first
|
||||
for (unsigned int i=0;i<matList.size();i++)
|
||||
if (matList[i] == id)
|
||||
return;
|
||||
// Didn't find it, add it.
|
||||
matList.push_back(id);
|
||||
if (matList[i] == id)
|
||||
return;
|
||||
// Didn't find it, add it.
|
||||
matList.push_back(id);
|
||||
}
|
||||
void trpgTileHeader::AddModel(int id)
|
||||
{
|
||||
for (unsigned int i=0;i<modelList.size();i++)
|
||||
if (modelList[i] == id)
|
||||
return;
|
||||
modelList.push_back(id);
|
||||
if (modelList[i] == id)
|
||||
return;
|
||||
modelList.push_back(id);
|
||||
}
|
||||
void trpgTileHeader::SetDate(int32 d)
|
||||
{
|
||||
date = d;
|
||||
date = d;
|
||||
}
|
||||
|
||||
// Local material methods
|
||||
@ -310,8 +394,8 @@ bool trpgTileHeader::GetNumLocalMaterial(int32 &retNum) const
|
||||
|
||||
bool trpgTileHeader::GetLocalMaterial(int32 id,trpgLocalMaterial &retMat) const
|
||||
{
|
||||
if (id < 0 || id >= (int)locMats.size())
|
||||
return false;
|
||||
if (id < 0 || id >= static_cast<int>(locMats.size()))
|
||||
return false;
|
||||
|
||||
retMat = locMats[id];
|
||||
|
||||
@ -328,78 +412,78 @@ const std::vector<trpgLocalMaterial> *trpgTileHeader::GetLocalMaterialList() con
|
||||
// Get methods
|
||||
bool trpgTileHeader::GetNumMaterial(int32 &no) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
no = matList.size();
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
no = matList.size();
|
||||
return true;
|
||||
}
|
||||
bool trpgTileHeader::GetMaterial(int32 id,int32 &mat) const
|
||||
{
|
||||
if (!isValid() || id < 0 || id >= (int)matList.size())
|
||||
return false;
|
||||
mat = matList[id];
|
||||
return true;
|
||||
if (!isValid() || id < 0 || id >= static_cast<int>(matList.size()))
|
||||
return false;
|
||||
mat = matList[id];
|
||||
return true;
|
||||
}
|
||||
bool trpgTileHeader::GetNumModel(int32 &no) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
no = modelList.size();
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
no = modelList.size();
|
||||
return true;
|
||||
}
|
||||
bool trpgTileHeader::GetModel(int32 id,int32 &m) const
|
||||
{
|
||||
if (!isValid() || id < 0 || id >= (int)modelList.size())
|
||||
return false;
|
||||
m = modelList[id];
|
||||
return true;
|
||||
if (!isValid() || id < 0 || id >= static_cast<int>(modelList.size()))
|
||||
return false;
|
||||
m = modelList[id];
|
||||
return true;
|
||||
}
|
||||
bool trpgTileHeader::GetDate(int32 &d) const
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
d = date;
|
||||
return true;
|
||||
if (!isValid()) return false;
|
||||
d = date;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Validity check
|
||||
bool trpgTileHeader::isValid() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Write to a buffer
|
||||
bool trpgTileHeader::Write(trpgWriteBuffer &buf)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
|
||||
if (!isValid())
|
||||
return false;
|
||||
for (i=0;i<locMats.size();i++)
|
||||
if (!locMats[i].isValid())
|
||||
return false;
|
||||
if (!isValid())
|
||||
return false;
|
||||
for (i=0;i<locMats.size();i++)
|
||||
if (!locMats[i].isValid())
|
||||
return false;
|
||||
|
||||
buf.Begin(TRPGTILEHEADER);
|
||||
buf.Begin(TRPGTILEHEADER);
|
||||
|
||||
buf.Begin(TRPG_TILE_MATLIST);
|
||||
buf.Add((int32)matList.size());
|
||||
for (i=0;i<matList.size();i++)
|
||||
buf.Add(matList[i]);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_MODELLIST);
|
||||
buf.Add((int32)modelList.size());
|
||||
for (i=0;i<modelList.size();i++)
|
||||
buf.Add(modelList[i]);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_DATE);
|
||||
buf.Add(date);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_LOCMATLIST);
|
||||
buf.Add((int32)locMats.size());
|
||||
for (i=0;i<locMats.size();i++)
|
||||
locMats[i].Write(buf);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_MATLIST);
|
||||
buf.Add((int32)matList.size());
|
||||
for (i=0;i<matList.size();i++)
|
||||
buf.Add(matList[i]);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_MODELLIST);
|
||||
buf.Add((int32)modelList.size());
|
||||
for (i=0;i<modelList.size();i++)
|
||||
buf.Add(modelList[i]);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_DATE);
|
||||
buf.Add(date);
|
||||
buf.End();
|
||||
buf.Begin(TRPG_TILE_LOCMATLIST);
|
||||
buf.Add((int32)locMats.size());
|
||||
for (i=0;i<locMats.size();i++)
|
||||
locMats[i].Write(buf);
|
||||
buf.End();
|
||||
|
||||
buf.End();
|
||||
buf.End();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tile Header CB
|
||||
@ -407,81 +491,87 @@ bool trpgTileHeader::Write(trpgWriteBuffer &buf)
|
||||
// We want the tile header to be expandable, so be careful here
|
||||
class tileHeaderCB : public trpgr_Callback {
|
||||
public:
|
||||
void * Parse(trpgToken,trpgReadBuffer &);
|
||||
trpgTileHeader *head;
|
||||
void * Parse(trpgToken,trpgReadBuffer &);
|
||||
trpgTileHeader *head;
|
||||
};
|
||||
|
||||
void * tileHeaderCB::Parse(trpgToken tok,trpgReadBuffer &buf)
|
||||
{
|
||||
int32 no,id,date,i;
|
||||
int32 no,id,date,i;
|
||||
|
||||
try {
|
||||
switch (tok) {
|
||||
case TRPG_TILE_MATLIST:
|
||||
buf.Get(no);
|
||||
if (no < 0) throw 1;
|
||||
for (i = 0;i < no; i++) {
|
||||
buf.Get(id);
|
||||
head->AddMaterial(id);
|
||||
}
|
||||
break;
|
||||
case TRPG_TILE_MODELLIST:
|
||||
buf.Get(no);
|
||||
if (no < 0) throw 1;
|
||||
for (i=0;i<no;i++) {
|
||||
buf.Get(id);
|
||||
head->AddModel(id);
|
||||
}
|
||||
break;
|
||||
case TRPG_TILE_DATE:
|
||||
buf.Get(date);
|
||||
head->SetDate(date);
|
||||
break;
|
||||
case TRPG_TILE_LOCMATLIST:
|
||||
{
|
||||
int32 numLocMat;
|
||||
buf.Get(numLocMat);
|
||||
if (numLocMat < 0) throw 1;
|
||||
std::vector<trpgLocalMaterial> *locMats;
|
||||
locMats = const_cast<std::vector<trpgLocalMaterial> *> (head->GetLocalMaterialList());
|
||||
locMats->resize(numLocMat);
|
||||
for (i=0;i<numLocMat;i++) {
|
||||
trpgToken matTok;
|
||||
int32 len;
|
||||
buf.GetToken(matTok,len);
|
||||
if (matTok != TRPGLOCALMATERIAL) throw 1;
|
||||
buf.PushLimit(len);
|
||||
trpgLocalMaterial &locMat = (*locMats)[i];
|
||||
locMat.Read(buf);
|
||||
buf.PopLimit();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Don't care
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
try {
|
||||
switch (tok) {
|
||||
case TRPG_TILE_MATLIST:
|
||||
buf.Get(no);
|
||||
if (no < 0) throw 1;
|
||||
for (i = 0;i < no; i++) {
|
||||
buf.Get(id);
|
||||
head->AddMaterial(id);
|
||||
}
|
||||
break;
|
||||
case TRPG_TILE_MODELLIST:
|
||||
buf.Get(no);
|
||||
if (no < 0) throw 1;
|
||||
for (i=0;i<no;i++) {
|
||||
buf.Get(id);
|
||||
head->AddModel(id);
|
||||
}
|
||||
break;
|
||||
case TRPG_TILE_DATE:
|
||||
buf.Get(date);
|
||||
head->SetDate(date);
|
||||
break;
|
||||
case TRPG_TILE_LOCMATLIST:
|
||||
{
|
||||
int32 numLocMat;
|
||||
buf.Get(numLocMat);
|
||||
if (numLocMat < 0) throw 1;
|
||||
std::vector<trpgLocalMaterial> *locMats;
|
||||
locMats = const_cast<std::vector<trpgLocalMaterial> *> (head->GetLocalMaterialList());
|
||||
locMats->resize(numLocMat);
|
||||
for (i=0;i<numLocMat;i++) {
|
||||
trpgToken matTok;
|
||||
int32 len;
|
||||
buf.GetToken(matTok,len);
|
||||
if (matTok != TRPGLOCALMATERIAL) throw 1;
|
||||
buf.PushLimit(len);
|
||||
trpgLocalMaterial &locMat = (*locMats)[i];
|
||||
locMat.Read(buf);
|
||||
// Set the row/col for later finding
|
||||
trpgwAppAddress addr;
|
||||
locMat.GetAddr(addr);
|
||||
head->GetBlockNo(addr.row,addr.col);
|
||||
locMat.SetAddr(addr);
|
||||
|
||||
return head;
|
||||
buf.PopLimit();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Don't care
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
// Read tile header
|
||||
bool trpgTileHeader::Read(trpgReadBuffer &buf)
|
||||
{
|
||||
tileHeaderCB tcb;
|
||||
trpgr_Parser parse;
|
||||
tileHeaderCB tcb;
|
||||
trpgr_Parser parse;
|
||||
|
||||
tcb.head = this;
|
||||
parse.AddCallback(TRPG_TILE_MATLIST,&tcb,false);
|
||||
parse.AddCallback(TRPG_TILE_MODELLIST,&tcb,false);
|
||||
parse.AddCallback(TRPG_TILE_DATE,&tcb,false);
|
||||
// New for 2.0
|
||||
parse.AddCallback(TRPG_TILE_LOCMATLIST,&tcb,false);
|
||||
parse.Parse(buf);
|
||||
tcb.head = this;
|
||||
parse.AddCallback(TRPG_TILE_MATLIST,&tcb,false);
|
||||
parse.AddCallback(TRPG_TILE_MODELLIST,&tcb,false);
|
||||
parse.AddCallback(TRPG_TILE_DATE,&tcb,false);
|
||||
// New for 2.0
|
||||
parse.AddCallback(TRPG_TILE_LOCMATLIST,&tcb,false);
|
||||
parse.Parse(buf);
|
||||
|
||||
return isValid();
|
||||
return isValid();
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <trpage_util.h>
|
||||
|
||||
/* trpage_util.cpp
|
||||
This source file implements various utility routines for paging archive
|
||||
*/
|
||||
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.
|
||||
@ -25,4 +25,3 @@
|
||||
Instead, there's a Windows specific program that merges TerraPage archives in
|
||||
the merge/ directory of this distribution.
|
||||
*/
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
*/
|
||||
|
||||
/* trpage_sys.h
|
||||
System specific declarations.
|
||||
*/
|
||||
System specific declarations.
|
||||
*/
|
||||
|
||||
#ifndef trpage_util_h_
|
||||
#define trpage_util_h_
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
TX_EXDECL class TX_CLDECL trpgUtil {
|
||||
public:
|
||||
enum {DoReport = 1<<0,DoCopy = 1<<1, DoTileOpt = 1<<2};
|
||||
int merge(trpgr_Archive &inArch1,trpgr_Archive &inArch2,trpgwArchive &outArch, int flags = 0);
|
||||
enum {DoReport = 1<<0,DoCopy = 1<<1, DoTileOpt = 1<<2};
|
||||
int merge(trpgr_Archive &inArch1,trpgr_Archive &inArch2,trpgwArchive &outArch, int flags = 0);
|
||||
};
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,313 +18,342 @@
|
||||
#define _txpage_write_h_
|
||||
|
||||
/* trpage_write.h
|
||||
Classes that are used to write paging archives.
|
||||
*/
|
||||
Classes that are used to write paging archives.
|
||||
*/
|
||||
|
||||
#include <trpage_sys.h>
|
||||
#include <trpage_io.h>
|
||||
#include <trpage_swap.h>
|
||||
#include <trpage_read.h>
|
||||
|
||||
/* Geometry Stats
|
||||
Used with a Geometry Helper to keep track of what go built.
|
||||
{group:Archive Writing}
|
||||
*/
|
||||
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);
|
||||
trpgwGeomStats(void);
|
||||
~trpgwGeomStats(void);
|
||||
|
||||
int totalTri; // Total # of triangles
|
||||
int totalTri; // Total # of triangles
|
||||
|
||||
int totalQuad; // Total # of quads
|
||||
int totalQuad; // Total # of quads
|
||||
|
||||
// Add up to totalTri
|
||||
int totalStripTri; // triangles in strips
|
||||
int totalFanTri; // triangles in fans
|
||||
int totalBagTri; // loose triangles
|
||||
// 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 numStrip; // Number of distinct strips
|
||||
int numFan; // Number of distinct fans
|
||||
|
||||
int stripStat[15]; // Strip length stats
|
||||
int fanStat[15]; // Fan length stats
|
||||
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 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
|
||||
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;}
|
||||
// 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 += val; }
|
||||
};
|
||||
|
||||
/* 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}
|
||||
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 AddTexCoord(trpg2dPoint &); // for multiple textures
|
||||
virtual void SetNormal(trpg3dPoint &);
|
||||
virtual void SetMaterial(int32);
|
||||
virtual void AddMaterial(int32); // for multiple textures
|
||||
// Pull the state info together and add a vertex
|
||||
virtual void AddVertex(trpg3dPoint &);
|
||||
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 AddTexCoord(trpg2dPoint &); // for multiple textures
|
||||
virtual void SetNormal(trpg3dPoint &);
|
||||
virtual void SetMaterial(int32);
|
||||
virtual void AddMaterial(int32); // for multiple textures
|
||||
// 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);
|
||||
// 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 the Min and Max Z values
|
||||
virtual void GetZMinMax(double &min,double &max);
|
||||
|
||||
// Get statistics for whatever we built
|
||||
trpgwGeomStats *GetStats(void) { return &stats; }
|
||||
// Get statistics for whatever we built
|
||||
trpgwGeomStats *GetStats(void) { return &stats; }
|
||||
protected:
|
||||
int mode;
|
||||
int dataType;
|
||||
trpgWriteBuffer *buf;
|
||||
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);
|
||||
/* 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);
|
||||
// Reset Triangle arrays
|
||||
virtual void ResetTri(void);
|
||||
|
||||
// Collections of geometry
|
||||
trpgGeometry strips,fans,bags;
|
||||
// Collections of geometry
|
||||
trpgGeometry strips,fans,bags;
|
||||
|
||||
// Temporary data arrays for triangles/quads
|
||||
std::vector<int32> matTri;
|
||||
std::vector<trpg2dPoint> tex;
|
||||
std::vector<trpg3dPoint> norm,vert;
|
||||
// Data arrays for a polygon
|
||||
std::vector<int32> matPoly;
|
||||
std::vector<trpg2dPoint> polyTex;
|
||||
std::vector<trpg3dPoint> polyNorm,polyVert;
|
||||
// Single points
|
||||
std::vector<trpg2dPoint> tmpTex;
|
||||
trpg3dPoint tmpNorm;
|
||||
trpgColor tmpCol;
|
||||
// Temporary data arrays for triangles/quads
|
||||
std::vector<int32> matTri;
|
||||
std::vector<trpg2dPoint> tex;
|
||||
std::vector<trpg3dPoint> norm,vert;
|
||||
// Data arrays for a polygon
|
||||
std::vector<int32> matPoly;
|
||||
std::vector<trpg2dPoint> polyTex;
|
||||
std::vector<trpg3dPoint> polyNorm,polyVert;
|
||||
// Single points
|
||||
std::vector<trpg2dPoint> tmpTex;
|
||||
trpg3dPoint tmpNorm;
|
||||
trpgColor tmpCol;
|
||||
|
||||
// Geometry status built up as we go
|
||||
trpgwGeomStats stats;
|
||||
// Geometry status built up as we go
|
||||
trpgwGeomStats stats;
|
||||
|
||||
// Keeps track of min and max z values
|
||||
double zmin,zmax;
|
||||
// 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).
|
||||
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);
|
||||
trpgwImageHelper() {;};
|
||||
trpgwImageHelper(trpgEndian ness,char *dir,trpgTexTable &,bool separateGeoTypical);
|
||||
// construction is really here
|
||||
virtual void Init(trpgEndian ness,char *dir,trpgTexTable &,bool separateGeoTypical);
|
||||
|
||||
// Adds an entry to the texture table for an external texture
|
||||
virtual bool AddExternal(char *name,int &texID,bool lookForExisting=true);
|
||||
virtual ~trpgwImageHelper(void);
|
||||
|
||||
/* 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);
|
||||
virtual bool AddLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,int sizeZ,trpgTexture::ImageOrg org,bool isMipmap,char *data,int &texID);
|
||||
// Adds an entry to the texture table for an external texture
|
||||
virtual bool AddExternal(char *name,int &texID,bool lookForExisting=true);
|
||||
|
||||
/* 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);
|
||||
virtual bool AddTileLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,int sizeZ,trpgTexture::ImageOrg org,bool isMipmap,char *data, int &texID,trpgwAppAddress &addr);
|
||||
/* 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,bool deferWrite);
|
||||
|
||||
/* 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);
|
||||
/* Replaces texture table information for a local texture and
|
||||
writes the data for that texture out to one of our texture
|
||||
archive files.
|
||||
Up to you to ensure data is appropriate for the texture.
|
||||
*/
|
||||
virtual bool ReplaceLocal(char *data,int &texID);
|
||||
|
||||
/* 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);
|
||||
/* 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);
|
||||
|
||||
/* Close the current texture file and go on to one with the
|
||||
given base name. This is used for regenerate.
|
||||
*/
|
||||
virtual bool DesignateTextureFile(int);
|
||||
/* 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);
|
||||
|
||||
// Flush current texture output files
|
||||
virtual bool Flush(void);
|
||||
/* 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 trpgwAppFile * IncrementTextureFile(bool geotyp);
|
||||
|
||||
/* Close the current texture file and go on to one with the
|
||||
given base name. This is used for regenerate.
|
||||
*/
|
||||
virtual bool DesignateTextureFile(int);
|
||||
|
||||
// Flush current texture output files
|
||||
virtual bool Flush(void);
|
||||
|
||||
// Get a new appendable file
|
||||
virtual trpgwAppFile* GetNewWAppFile(trpgEndian inNess,const char *fileName,bool reuse=false);
|
||||
|
||||
// Write the given texture data into one our local archives
|
||||
bool WriteToArchive(const trpgTexture &tex,char *data,trpgwAppAddress &addr,bool geotyp=false);
|
||||
// Merge block textable into a master.
|
||||
|
||||
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;
|
||||
|
||||
trpgEndian ness;
|
||||
char dir[1024];
|
||||
trpgTexTable *texTable;
|
||||
std::vector<int> texFileIDs;
|
||||
trpgwAppFile *texFile;
|
||||
std::vector<int> geotypFileIDs;
|
||||
trpgwAppFile *geotypFile;
|
||||
bool separateGeoTypical;
|
||||
int maxTexFileLen;
|
||||
};
|
||||
|
||||
/* Paging Archive
|
||||
This is a writeable paging archive.
|
||||
It organizes where things get written and how.
|
||||
{group:Archive Writing}
|
||||
*/
|
||||
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;
|
||||
// Tiles can be stored as individual files (External) or grouped together (Local)
|
||||
enum TileMode {TileLocal,TileExternal,TileExternalSaved};
|
||||
|
||||
// Add data to an existing archive
|
||||
trpgwArchive(char *baseDir,char *name,trpg2dPoint &ll,trpg2dPoint &ur);
|
||||
// Start an archive from scratch.
|
||||
trpgwArchive(trpgEndian ness=LittleEndian,TileMode tileMode=TileLocal,int version=2);
|
||||
virtual ~trpgwArchive(void);
|
||||
// real constructor work done in Init(...) now for quasi-virtual ctor action.
|
||||
// Add data to an existing archive
|
||||
trpgwArchive(char *baseDir,char *name,trpg2dPoint &ll,trpg2dPoint &ur, int majorVer=TRPG_VERSION_MAJOR, int minorVer=TRPG_VERSION_MINOR);
|
||||
virtual void Init(char *baseDir,char *name,trpg2dPoint &ll,trpg2dPoint &ur, int majorVer=TRPG_VERSION_MAJOR, int minorVer=TRPG_VERSION_MINOR);
|
||||
// Start an archive from scratch.
|
||||
trpgwArchive(trpgEndian ness=LittleEndian,TileMode tileMode=TileLocal,int majorVer=TRPG_VERSION_MAJOR, int minorVer=TRPG_VERSION_MINOR);
|
||||
virtual void Init(trpgEndian ness=LittleEndian,TileMode tileMode=TileLocal,int majorVer=TRPG_VERSION_MAJOR, int minorVer=TRPG_VERSION_MINOR);
|
||||
// dummy constructor, does nothing so subclasses can have more control
|
||||
trpgwArchive(int ) {;};
|
||||
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 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 &);
|
||||
virtual bool SetLabelPropertyTable(const trpgLabelPropertyTable &);
|
||||
virtual bool SetSupportStyleTable(const trpgSupportStyleTable &);
|
||||
virtual bool SetTextStyleTable(const trpgTextStyleTable &);
|
||||
// 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 &);
|
||||
virtual bool SetLabelPropertyTable(const trpgLabelPropertyTable &);
|
||||
virtual bool SetSupportStyleTable(const trpgSupportStyleTable &);
|
||||
virtual bool SetTextStyleTable(const trpgTextStyleTable &);
|
||||
|
||||
// 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 trpgLabelPropertyTable *GetLabelPropertyTable();
|
||||
virtual trpgTextStyleTable *GetTextStyleTable();
|
||||
virtual trpgSupportStyleTable *GetSupportStyleTable();
|
||||
// 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 trpgLabelPropertyTable *GetLabelPropertyTable();
|
||||
virtual trpgTextStyleTable *GetTextStyleTable();
|
||||
virtual trpgSupportStyleTable *GetSupportStyleTable();
|
||||
|
||||
|
||||
|
||||
virtual bool IncrementTileFile(void);
|
||||
virtual bool DesignateTileFile(int);
|
||||
virtual bool IncrementTileFile(void);
|
||||
virtual bool DesignateTileFile(int);
|
||||
|
||||
// Write functions.
|
||||
// For now, the header is written last.
|
||||
// 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 CheckpointHeader(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;
|
||||
const char *getErrMess() const;
|
||||
char* getDir(void){return dir;};
|
||||
|
||||
class TileFileEntry {
|
||||
public:
|
||||
int x,y,lod; // Identifying info for tile
|
||||
float zmin,zmax;
|
||||
int32 offset; // Offset into file
|
||||
};
|
||||
class TileFile {
|
||||
public:
|
||||
int id;
|
||||
std::vector<TileFileEntry> tiles;
|
||||
};
|
||||
virtual bool OpenFile(const char *,const char *);
|
||||
virtual void CloseFile(void);
|
||||
virtual bool WriteHeader(void);
|
||||
virtual bool CheckpointHeader(void);
|
||||
virtual bool WriteTile(unsigned int,unsigned int,unsigned int,float zmin,float zmax,
|
||||
const trpgMemWriteBuffer *,const trpgMemWriteBuffer *, int32& fileId, int32& fileOffset);
|
||||
// virtual bool WriteModel(unsigned int,trpgMemWriteBuffer &);
|
||||
|
||||
bool isValid(void) const;
|
||||
const char *getErrMess() const;
|
||||
char* getDir(void){return dir;};
|
||||
virtual trpgwImageHelper* GetNewWImageHelper(trpgEndian ness,char *dir,trpgTexTable &);
|
||||
virtual trpgwAppFile* GetNewWAppFile(trpgEndian inNess,const char *fileName,bool reuse=false);
|
||||
virtual trpgr_Archive* GetArchiveReader() {return new trpgr_Archive();};
|
||||
virtual int32 WriteHeaderData(const char *dataPtr,int32 length,FILE *filehandle);
|
||||
virtual int32 GetMagicNumber() {return TRPG_MAGIC;};
|
||||
protected:
|
||||
// Set if we're adding to an existing archive
|
||||
bool isRegenerate;
|
||||
// Set if we're adding to an existing archive
|
||||
bool isRegenerate;
|
||||
|
||||
// Used to keep track of which tiles are in which file
|
||||
// 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;
|
||||
int32 offset; // Offset into file
|
||||
};
|
||||
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
|
||||
trpgEndian ness,cpuNess;
|
||||
int majorVersion, minorVersion;
|
||||
// Fed in from the outside
|
||||
char dir[1024]; // Directory where we're doing all this
|
||||
|
||||
// These are passed in
|
||||
// These are passed in
|
||||
|
||||
trpgHeader header;
|
||||
trpgMatTable matTable;
|
||||
trpgTexTable texTable;
|
||||
trpgModelTable modelTable;
|
||||
trpgLightTable lightTable;
|
||||
trpgRangeTable rangeTable;
|
||||
trpgTextStyleTable textStyleTable;
|
||||
trpgSupportStyleTable supportStyleTable;
|
||||
trpgLabelPropertyTable labelPropertyTable;
|
||||
trpgHeader header;
|
||||
trpgMatTable matTable;
|
||||
trpgTexTable texTable;
|
||||
trpgModelTable modelTable;
|
||||
trpgLightTable lightTable;
|
||||
trpgRangeTable rangeTable;
|
||||
trpgTextStyleTable textStyleTable;
|
||||
trpgSupportStyleTable supportStyleTable;
|
||||
trpgLabelPropertyTable labelPropertyTable;
|
||||
|
||||
|
||||
trpgTileTable tileTable;
|
||||
trpgTileTable tileTable;
|
||||
|
||||
int numX,numY,numLod;
|
||||
TileMode tileMode;
|
||||
int numX,numY,numLod;
|
||||
TileMode tileMode;
|
||||
|
||||
trpgwAppFile *tileFile;
|
||||
int tileFileCount;
|
||||
trpgwAppFile *tileFile;
|
||||
int tileFileCount;
|
||||
|
||||
std::vector<TileFile> tileFiles;
|
||||
std::vector<TileFile> tileFiles;
|
||||
|
||||
int maxTileFileLen;
|
||||
std::vector<TileFileEntry> externalTiles;
|
||||
|
||||
// This offset is used when we're adding to an existing archive
|
||||
trpg2iPoint addOffset;
|
||||
int maxTileFileLen;
|
||||
|
||||
FILE *fp;
|
||||
// This offset is used when we're adding to an existing archive
|
||||
trpg2iPoint addOffset;
|
||||
|
||||
bool firstHeaderWrite;
|
||||
FILE *fp;
|
||||
|
||||
mutable char errMess[512];
|
||||
bool firstHeaderWrite;
|
||||
|
||||
mutable char errMess[512];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,16 +18,16 @@
|
||||
#include <string.h>
|
||||
|
||||
/* trpage_writebuf.cpp
|
||||
This source file contains the implementation of trpgMemWriteBuffer.
|
||||
That is a subclass of trpgWriteBuffer, which implements an interface
|
||||
definition for an object which can accept data to be written.
|
||||
The Mem version is used to write (for example) a tile's worth of data.
|
||||
That data can then be written to a file (or sent over the network).
|
||||
You should not need to change this implementation. Simply sublcass
|
||||
trpgWriteBuffer and implement all of the required methods. The
|
||||
resulting class can then be used in all the places a trpgWriteBuffer
|
||||
is required.
|
||||
*/
|
||||
This source file contains the implementation of trpgMemWriteBuffer.
|
||||
That is a subclass of trpgWriteBuffer, which implements an interface
|
||||
definition for an object which can accept data to be written.
|
||||
The Mem version is used to write (for example) a tile's worth of data.
|
||||
That data can then be written to a file (or sent over the network).
|
||||
You should not need to change this implementation. Simply sublcass
|
||||
trpgWriteBuffer and implement all of the required methods. The
|
||||
resulting class can then be used in all the places a trpgWriteBuffer
|
||||
is required.
|
||||
*/
|
||||
|
||||
#include <trpage_io.h>
|
||||
#include <trpage_swap.h>
|
||||
@ -39,158 +39,158 @@
|
||||
// Constructor
|
||||
trpgMemWriteBuffer::trpgMemWriteBuffer(trpgEndian in_ness)
|
||||
{
|
||||
ness = in_ness;
|
||||
cpuNess = trpg_cpu_byte_order();
|
||||
data = NULL;
|
||||
curLen = totLen = 0;
|
||||
ness = in_ness;
|
||||
cpuNess = trpg_cpu_byte_order();
|
||||
data = NULL;
|
||||
curLen = totLen = 0;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
trpgMemWriteBuffer::~trpgMemWriteBuffer()
|
||||
{
|
||||
if (data)
|
||||
delete [] data;
|
||||
data = NULL;
|
||||
if (data)
|
||||
delete [] data;
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
/* Length()
|
||||
Return the length of the given buffer.
|
||||
*/
|
||||
Return the length of the given buffer.
|
||||
*/
|
||||
int trpgMemWriteBuffer::length() const
|
||||
{
|
||||
return curLen;
|
||||
return curLen;
|
||||
}
|
||||
|
||||
/* getData()
|
||||
Return a pointer to the memory buffer.
|
||||
*/
|
||||
Return a pointer to the memory buffer.
|
||||
*/
|
||||
const char *trpgMemWriteBuffer::getData() const
|
||||
{
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Length()
|
||||
Set the maximum buffer length.
|
||||
*/
|
||||
Set the maximum buffer length.
|
||||
*/
|
||||
void trpgMemWriteBuffer::setLength(unsigned int len)
|
||||
{
|
||||
if ((int)len > totLen) {
|
||||
char *old_data = data;
|
||||
int oldLen = totLen;
|
||||
totLen = 2*len;
|
||||
data = new char[totLen];
|
||||
if ((int)len > totLen) {
|
||||
char *old_data = data;
|
||||
int oldLen = totLen;
|
||||
totLen = 2*len;
|
||||
data = new char[totLen];
|
||||
|
||||
if (old_data) {
|
||||
memcpy(data,old_data,oldLen);
|
||||
delete [] old_data;
|
||||
}
|
||||
}
|
||||
if (old_data) {
|
||||
memcpy(data,old_data,oldLen);
|
||||
delete [] old_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* append()
|
||||
Append the given data to our buffer.
|
||||
*/
|
||||
Append the given data to our buffer.
|
||||
*/
|
||||
void trpgMemWriteBuffer::append(unsigned int len,const char *val)
|
||||
{
|
||||
if (len == 0) return;
|
||||
setLength(curLen+len);
|
||||
memcpy(&data[curLen],val,len);
|
||||
curLen += len;
|
||||
if (len == 0) return;
|
||||
setLength(curLen+len);
|
||||
memcpy(&data[curLen],val,len);
|
||||
curLen += len;
|
||||
}
|
||||
|
||||
/* set()
|
||||
Set a specific portion of the buffer to a given value.
|
||||
*/
|
||||
Set a specific portion of the buffer to a given value.
|
||||
*/
|
||||
void trpgMemWriteBuffer::set(unsigned int pos,unsigned int len,const char *val)
|
||||
{
|
||||
if (len == 0) return;
|
||||
if (pos+len > (unsigned int)curLen) return;
|
||||
if (len == 0) return;
|
||||
if (pos+len > (unsigned int)curLen) return;
|
||||
|
||||
memcpy(&data[pos],val,len);
|
||||
memcpy(&data[pos],val,len);
|
||||
}
|
||||
|
||||
/* --- replacement virtual functions --- */
|
||||
|
||||
/* Reset()
|
||||
Drop whatever's being stored.
|
||||
*/
|
||||
Drop whatever's being stored.
|
||||
*/
|
||||
void trpgMemWriteBuffer::Reset()
|
||||
{
|
||||
curLen = 0;
|
||||
curLen = 0;
|
||||
}
|
||||
|
||||
// Add(Int32)
|
||||
void trpgMemWriteBuffer::Add(int32 val)
|
||||
{
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_int(val);
|
||||
append(sizeof(int32),(const char *)&val);
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_int(val);
|
||||
append(sizeof(int32),(const char *)&val);
|
||||
}
|
||||
|
||||
// Add(int64)
|
||||
void trpgMemWriteBuffer::Add(int64 val)
|
||||
{
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_llong(val);
|
||||
append(sizeof(int64),(const char *)&val);
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_llong(val);
|
||||
append(sizeof(int64),(const char *)&val);
|
||||
}
|
||||
|
||||
// Add(string)
|
||||
// [len] [value...]
|
||||
void trpgMemWriteBuffer::Add(const char *val)
|
||||
{
|
||||
int32 len = (val ? strlen(val) : 0),vlen = len;
|
||||
if (ness != cpuNess)
|
||||
vlen = trpg_byteswap_int(vlen);
|
||||
append(sizeof(int32),(const char *)&vlen);
|
||||
append(len,val);
|
||||
int32 len = (val ? strlen(val) : 0),vlen = len;
|
||||
if (ness != cpuNess)
|
||||
vlen = trpg_byteswap_int(vlen);
|
||||
append(sizeof(int32),(const char *)&vlen);
|
||||
append(len,val);
|
||||
}
|
||||
|
||||
// Add(std::string)
|
||||
void trpgMemWriteBuffer::Add(std::string &val)
|
||||
{
|
||||
Add(val.c_str());
|
||||
Add(val.c_str());
|
||||
}
|
||||
|
||||
// Add(float32)
|
||||
void trpgMemWriteBuffer::Add(float32 val)
|
||||
{
|
||||
char cval[4];
|
||||
if (ness != cpuNess)
|
||||
trpg_byteswap_float_to_4bytes(val,cval);
|
||||
else
|
||||
memcpy(cval,&val,4);
|
||||
char cval[4];
|
||||
if (ness != cpuNess)
|
||||
trpg_byteswap_float_to_4bytes(val,cval);
|
||||
else
|
||||
memcpy(cval,&val,4);
|
||||
|
||||
append(sizeof(float32),cval);
|
||||
append(sizeof(float32),cval);
|
||||
}
|
||||
|
||||
// Add(float64)
|
||||
void trpgMemWriteBuffer::Add(float64 val)
|
||||
{
|
||||
char cval[8];
|
||||
if (ness != cpuNess)
|
||||
trpg_byteswap_double_to_8bytes(val,cval);
|
||||
else
|
||||
memcpy(cval,&val,8);
|
||||
char cval[8];
|
||||
if (ness != cpuNess)
|
||||
trpg_byteswap_double_to_8bytes(val,cval);
|
||||
else
|
||||
memcpy(cval,&val,8);
|
||||
|
||||
append(sizeof(float64),cval);
|
||||
append(sizeof(float64),cval);
|
||||
}
|
||||
|
||||
// Add(int8)
|
||||
void trpgMemWriteBuffer::Add(uint8 val)
|
||||
{
|
||||
// No byte swapping needed
|
||||
append(sizeof(uint8),(const char *)&val);
|
||||
// No byte swapping needed
|
||||
append(sizeof(uint8),(const char *)&val);
|
||||
}
|
||||
|
||||
//#if (bool != int32)
|
||||
// Add(bool)
|
||||
void trpgMemWriteBuffer::Add(bool val)
|
||||
{
|
||||
uint8 ival;
|
||||
uint8 ival;
|
||||
|
||||
ival = (val ? 1 : 0);
|
||||
Add(ival);
|
||||
ival = (val ? 1 : 0);
|
||||
Add(ival);
|
||||
}
|
||||
//#endif
|
||||
|
||||
@ -198,127 +198,169 @@ void trpgMemWriteBuffer::Add(bool val)
|
||||
// Add(trpgDiskRef)
|
||||
void trpgMemWriteBuffer::Add(trpgDiskRef val)
|
||||
{
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_llong(val);
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_llong(val);
|
||||
|
||||
append(sizeof(trpgDiskRef),(const char *)&val);
|
||||
append(sizeof(trpgDiskRef),(const char *)&val);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Add(trpgToken)
|
||||
void trpgMemWriteBuffer::Add(trpgToken val)
|
||||
{
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_short(val);
|
||||
if (ness != cpuNess)
|
||||
val = trpg_byteswap_short(val);
|
||||
|
||||
append(sizeof(trpgToken),(const char *)&val);
|
||||
append(sizeof(trpgToken),(const char *)&val);
|
||||
}
|
||||
|
||||
// Add(tx2iPoint)
|
||||
void trpgWriteBuffer::Add(const trpg2iPoint &val)
|
||||
{
|
||||
Add((int32)val.x);
|
||||
Add((int32)val.y);
|
||||
Add((int32)val.x);
|
||||
Add((int32)val.y);
|
||||
}
|
||||
|
||||
// Add(tx2dPoint)
|
||||
void trpgWriteBuffer::Add(const trpg2dPoint &val)
|
||||
{
|
||||
Add((float64)val.x);
|
||||
Add((float64)val.y);
|
||||
Add((float64)val.x);
|
||||
Add((float64)val.y);
|
||||
}
|
||||
|
||||
// Add(trpg3dPoint)
|
||||
void trpgWriteBuffer::Add(const trpg3dPoint &val)
|
||||
{
|
||||
Add((float64)val.x);
|
||||
Add((float64)val.y);
|
||||
Add((float64)val.z);
|
||||
Add((float64)val.x);
|
||||
Add((float64)val.y);
|
||||
Add((float64)val.z);
|
||||
}
|
||||
|
||||
// Add(trpgColor)
|
||||
void trpgWriteBuffer::Add(const trpgColor &val)
|
||||
{
|
||||
Add(val.red);
|
||||
Add(val.green);
|
||||
Add(val.blue);
|
||||
Add(val.red);
|
||||
Add(val.green);
|
||||
Add(val.blue);
|
||||
}
|
||||
|
||||
// Add(std::string)
|
||||
void trpgWriteBuffer::Add(const std::string &val)
|
||||
{
|
||||
Add(val.c_str());
|
||||
Add(val.c_str());
|
||||
}
|
||||
|
||||
/* Push()
|
||||
Starts defining a new object.
|
||||
Need to keep track of where length goes.
|
||||
*/
|
||||
Starts defining a new object.
|
||||
Need to keep track of where length goes.
|
||||
*/
|
||||
void trpgMemWriteBuffer::Begin(trpgToken tok)
|
||||
{
|
||||
Add(tok);
|
||||
lengths.push_back(curLen);
|
||||
Add((int32)0);
|
||||
Add(tok);
|
||||
lengths.push_back(curLen);
|
||||
Add((int32)0);
|
||||
}
|
||||
|
||||
/* Push()
|
||||
Pushes a level on the stack. For defining children.
|
||||
*/
|
||||
Pushes a level on the stack. For defining children.
|
||||
*/
|
||||
void trpgMemWriteBuffer::Push()
|
||||
{
|
||||
Add((trpgToken)TRPG_PUSH);
|
||||
Add((trpgToken)TRPG_PUSH);
|
||||
}
|
||||
|
||||
/* Pop()
|
||||
Pops a level off the "stack".
|
||||
*/
|
||||
Pops a level off the "stack".
|
||||
*/
|
||||
void trpgMemWriteBuffer::Pop()
|
||||
{
|
||||
Add((trpgToken)TRPG_POP);
|
||||
Add((trpgToken)TRPG_POP);
|
||||
}
|
||||
|
||||
/* Will take out a pop from the end of the buffer, if there is one */
|
||||
bool trpgMemWriteBuffer::UnPop()
|
||||
{
|
||||
//Check to see if there is a pop token ant the end
|
||||
trpgToken tk;
|
||||
memcpy(&tk, &data[curLen - sizeof(trpgToken)], sizeof(trpgToken));
|
||||
if(tk == TRPG_POP)
|
||||
{
|
||||
curLen -= sizeof(trpgToken);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
/* Will take out a push from the end of the buffer, if there is one */
|
||||
bool trpgMemWriteBuffer::UnPush()
|
||||
{
|
||||
//Check to see if there is a push token ant the end
|
||||
trpgToken tk;
|
||||
memcpy(&tk, &data[curLen - sizeof(trpgToken)], sizeof(trpgToken));
|
||||
if(tk == TRPG_PUSH)
|
||||
{
|
||||
curLen -= sizeof(trpgToken);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* End()
|
||||
Finished defining an object.
|
||||
Write the length out where appropriate.
|
||||
*/
|
||||
Finished defining an object.
|
||||
Write the length out where appropriate.
|
||||
*/
|
||||
void trpgMemWriteBuffer::End()
|
||||
{
|
||||
if (lengths.size() == 0)
|
||||
// Note: say something clever here
|
||||
return;
|
||||
if (lengths.size() == 0)
|
||||
// Note: say something clever here
|
||||
return;
|
||||
|
||||
int id = lengths.size()-1;
|
||||
int32 len = curLen - lengths[id];
|
||||
int32 rlen = len-sizeof(int32);
|
||||
if (ness != cpuNess)
|
||||
rlen = trpg_byteswap_int(rlen);
|
||||
set(curLen - len,sizeof(int32),(const char *)&rlen);
|
||||
lengths.resize(id);
|
||||
int id = lengths.size()-1;
|
||||
int32 len = curLen - lengths[id];
|
||||
int32 rlen = len-sizeof(int32);
|
||||
if (ness != cpuNess)
|
||||
rlen = trpg_byteswap_int(rlen);
|
||||
set(curLen - len,sizeof(int32),(const char *)&rlen);
|
||||
lengths.resize(id);
|
||||
}
|
||||
|
||||
/* Appendable File
|
||||
This class is used as a simple appendable file. It's used
|
||||
for dumping tile and texture (or most anything) into.
|
||||
This class is used as a simple appendable file. It's used
|
||||
for dumping tile and texture (or most anything) into.
|
||||
*/
|
||||
|
||||
trpgwAppFile::trpgwAppFile(trpgEndian inNess,const char *fileName)
|
||||
trpgwAppFile::trpgwAppFile(trpgEndian inNess,const char *fileName,bool reuse)
|
||||
{
|
||||
valid = false;
|
||||
ness = inNess;
|
||||
cpuNess = trpg_cpu_byte_order();
|
||||
Init(inNess,fileName,reuse);
|
||||
}
|
||||
|
||||
if (!(fp = fopen(fileName,"wb")))
|
||||
return;
|
||||
void trpgwAppFile::Init(trpgEndian inNess,const char *fileName,bool reuse)
|
||||
{
|
||||
valid = false;
|
||||
ness = inNess;
|
||||
cpuNess = trpg_cpu_byte_order();
|
||||
|
||||
lengthSoFar = 0;
|
||||
valid = true;
|
||||
if (reuse==false) {
|
||||
if (!(fp = fopen(fileName,"wb")))
|
||||
return;
|
||||
lengthSoFar = 0;
|
||||
valid = true;
|
||||
} else {
|
||||
if (!(fp = fopen(fileName,"ab")))
|
||||
return;
|
||||
// ftell is still zero, dammit. Arg.
|
||||
fseek(fp,0,SEEK_END);
|
||||
lengthSoFar = ftell(fp);
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
trpgwAppFile::~trpgwAppFile()
|
||||
{
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
valid = false;
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// Return the amount of data written so far (in total)
|
||||
@ -330,87 +372,87 @@ int trpgwAppFile::GetLengthWritten()
|
||||
// Append the given buffer to our appendable file
|
||||
bool trpgwAppFile::Append(const trpgMemWriteBuffer *buf1,const trpgMemWriteBuffer *buf2)
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid()) return false;
|
||||
|
||||
// Get the total length
|
||||
int totLen = buf1->length() + (buf2 ? buf2->length() : 0);
|
||||
// Get the total length
|
||||
int totLen = buf1->length() + (buf2 ? buf2->length() : 0);
|
||||
|
||||
// Write the length out
|
||||
if (fwrite(&totLen,sizeof(int32),1,fp) != 1) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
// Write the length out
|
||||
if (fwrite(&totLen,sizeof(int32),1,fp) != 1) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the data out
|
||||
const char *data = buf1->getData();
|
||||
int len = buf1->length();
|
||||
if (fwrite(data,sizeof(char),len,fp) != (unsigned int)len) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
if (buf2) {
|
||||
data = buf2->getData();
|
||||
len = buf2->length();
|
||||
if (fwrite(data,sizeof(char),len,fp) != (unsigned int)len) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Write the data out
|
||||
const char *data = buf1->getData();
|
||||
unsigned int len = buf1->length();
|
||||
if (fwrite(data,sizeof(char),len,fp) != len) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
if (buf2) {
|
||||
data = buf2->getData();
|
||||
len = buf2->length();
|
||||
if (fwrite(data,sizeof(char),len,fp) != len) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lengthSoFar += totLen;
|
||||
lengthSoFar += totLen;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Append the given raw data to our appendable file
|
||||
bool trpgwAppFile::Append(const char *data,int size)
|
||||
{
|
||||
if (!isValid()) return false;
|
||||
if (!isValid()) return false;
|
||||
|
||||
if (!data)
|
||||
return false;
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
// Write the length out
|
||||
if (fwrite(&size,sizeof(int32),1,fp) != 1) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
// Write the length out
|
||||
if (fwrite(&size,sizeof(int32),1,fp) != 1) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the data out
|
||||
if (fwrite(data,sizeof(char),size,fp) != (unsigned int)size) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
// Write the data out
|
||||
if (fwrite(data,sizeof(char),size,fp) != (size_t)size) {
|
||||
valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
lengthSoFar += size;
|
||||
lengthSoFar += size;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Flushes the current tile file
|
||||
bool trpgwAppFile::Flush()
|
||||
{
|
||||
// Flush the File *
|
||||
if (fp)
|
||||
fflush(fp);
|
||||
// Flush the File *
|
||||
if (fp)
|
||||
fflush(fp);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return the current file position
|
||||
int64 trpgwAppFile::Pos() const
|
||||
{
|
||||
if (!isValid())
|
||||
return 0;
|
||||
|
||||
// Note: This means an appendable file is capped at 2GB
|
||||
long pos = ftell(fp);
|
||||
if (!isValid())
|
||||
return 0;
|
||||
|
||||
// Note: This means an appendable file is capped at 2GB
|
||||
long pos = ftell(fp);
|
||||
|
||||
return pos;
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Validity check
|
||||
bool trpgwAppFile::isValid() const
|
||||
{
|
||||
return valid;
|
||||
return valid;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user