TXP plugin update from Boris Bralo.

This commit is contained in:
Robert Osfield
2002-03-09 10:51:09 +00:00
parent 689eca77d7
commit ab5603e3d4
27 changed files with 7786 additions and 4872 deletions

View File

@@ -1,16 +1,15 @@
/* ************************
Copyright Terrain Experts Inc.
Terrain Experts Inc (TERREX) reserves all rights to this source code
unless otherwise specified in writing by the Chief Operating Officer
of TERREX.
unless otherwise specified in writing by the President of TERREX.
This copyright may be updated in the future, in which case that version
supercedes this one.
-------------------
Terrex Experts Inc.
84 West Santa Clara St., Suite 380
San Jose, CA 95113
4400 East Broadway #314
Tucson, AZ 85711
info@terrex.com
Tel: (408) 293-9977
Tel: (520) 323-7990
************************
*/
@@ -19,222 +18,229 @@
#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()
{
// numX = numY = numLod = 0;
numLod = 0;
baseName = NULL;
type = External;
Reset();
}
// Reset function
void trpgTileTable::Reset()
{
if (baseName)
delete baseName;
// center.resize(0);
// tiles.resize(0);
// numX = numY;
numLod = 0;
baseName = NULL;
type = External;
mode = External;
lodInfo.resize(0);
valid = true;
}
// Destructor
trpgTileTable::~trpgTileTable()
{
Reset();
valid = false;
}
// Set functions
void trpgTileTable::SetNumTiles(int nx,int ny)
{
if (nx <= 0 || ny <= 0)
return;
SetNumTiles(nx,ny,1);
}
void trpgTileTable::SetNumTiles(int nx,int ny,int nl)
void trpgTileTable::SetMode(TileMode inMode)
{
if (nx <= 0 || ny <= 0 || nl <= 0 || nl >= numLod)
return;
lodSizes[nl] = trpg2iPoint(nx,ny);
// tiles.resize(nx*ny*nl,0);
}
void trpgTileTable::SetTile(int nx,int ny,int nl,trpgDiskRef ref)
{
if (nx < 0 || nx >= numX ||
ny < 0 || ny >= numY ||
nl < 0 || nl >= numLod)
return;
type = Local;
// tiles[nl*(numX*numY)+ny*numX+nx] = ref;
}
void trpgTileTable::SetTile(int nx,int ny,trpgDiskRef ref)
{
SetTile(nx,ny,0,ref);
}
void trpgTileTable::SetBaseName(const char *name)
{
if (baseName)
delete baseName;
baseName = new char[(name ? strlen(name) : 0)+1];
strcpy(baseName,name);
type = External;
}
void trpgTileTable::SetCenter(int nx,int ny,int nl,const trpg3dPoint &pt)
{
if (nx < 0 || nx >= numX ||
ny < 0 || ny >= numY ||
nl < 0 || nl >= numLod)
return;
// center[nl*(numX*numY)+ny*numX+nx] = pt;
}
void trpgTileTable::SetCenter(int nx,int ny,const trpg3dPoint &pt)
{
SetCenter(nx,ny,0,pt);
Reset();
mode = inMode;
}
// Need the basename when writing an archive
const char *trpgTileTable::GetBaseName() const
void trpgTileTable::SetNumLod(int numLod)
{
return baseName;
lodInfo.resize(numLod);
}
void trpgTileTable::SetNumTiles(int nx,int ny,int lod)
{
if (nx <= 0 || ny <= 0 || lod < 0 || lod >= 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];
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);
li.elev_max.resize(numTile);
// 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 >= 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;
}
// Validity check
bool trpgTileTable::isValid() const
{
// if (numX == 0 || numY == 0 || numLod == 0)
// return false;
return valid;
}
return true;
// Get methods
bool trpgTileTable::GetMode(TileMode &outMode) const
{
if (!isValid()) return false;
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 (lod < 0 || lod >= 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;
int loc = y*li.numX + x;
ref = li.addr[loc];
zmin = li.elev_min[loc];
zmax = li.elev_max[loc];
return true;
}
// Write tile table
bool trpgTileTable::Write(trpgWriteBuffer &buf)
{
if (!isValid())
return false;
if (!isValid())
return false;
buf.Begin(TRPGTILETABLE);
#if 0
numTiles = tiles.size();
buf.Add(numX);
buf.Add(numY);
buf.Add(numLod);
for (unsigned int i=0;i<tiles.size();i++) {
buf.Add(tiles[i]);
buf.Add(center[i]);
}
#endif
buf.Add(baseName);
buf.End();
buf.Begin(TRPGTILETABLE2);
// Write the mode
buf.Add(mode);
return true;
// 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);
// Write each terrain LOD set
for (unsigned 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]);
}
}
}
buf.End();
return true;
}
/* **************
Tile Table Read methods
**************
*/
/* **************
Tile Table Read method
**************
*/
// Get methods
bool trpgTileTable::GetNumTiles(int &x,int &y,int &l) const
{
// if (!isValid()) return false;
x = numX;
y = numY;
l = numLod;
return true;
}
bool trpgTileTable::GetType(int &t) const
{
if (!isValid()) return false;
t = type;
return true;
}
bool trpgTileTable::GetBaseName(char *str,int strLen) const
{
if (!isValid()) return false;
if (type != External) return false;
int len = (baseName ? strlen(baseName) : 0);
strncpy(str,baseName,MIN(len,strLen)+1);
return true;
}
bool trpgTileTable::GetTile(int x,int y,int lod,trpgDiskRef &ref) const
{
if (!isValid() || type != Local) return false;
// Note: fill this in
return false;
}
bool trpgTileTable::GetTile(int x,int y,int lod,char *str,int strLen) const
{
if (!isValid() || type != External) return false;
sprintf(str,"%s\\tile_%d_%d_%d.tpt",baseName,x,y,lod);
return true;
}
bool trpgTileTable::GetCenter(int x,int y,int lod,trpg3dPoint &pt) const
{
if (!isValid() || x < 0 || x >= numX || y < 0 || y >= numY ||
lod < 0 || lod >= numLod)
return false;
// pt = center[lod*(numX*numY)+y*numX+x];
return true;
}
bool trpgTileTable::Read(trpgReadBuffer &buf)
{
// trpg3dPoint pt;
char tmpStr[1024];
valid = false;
try {
type = External; // Note: Read this in
#if 0
buf.Get(numX);
buf.Get(numY);
buf.Get(numLod);
if (numTiles < 0) throw 1;
for (int i=0;i<numTiles;i++) {
buf.Get(diskRef);
buf.Get(pt);
tiles.push_back(diskRef);
center.push_back(pt);
}
#endif
buf.Get(tmpStr,1023);
SetBaseName(tmpStr);
}
catch (...) {
return 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);
return isValid();
for (unsigned 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);
unsigned 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]);
}
}
}
valid = true;
}
catch (...) {
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()
{
@@ -245,171 +251,236 @@ trpgTileHeader::~trpgTileHeader()
void trpgTileHeader::Reset()
{
matList.resize(0);
modelList.resize(0);
matList.resize(0);
modelList.resize(0);
locMats.resize(0);
}
// Set functions
void trpgTileHeader::SetMaterial(int no,int id)
{
if (no < 0 || no >= (int)matList.size())
return;
matList[no] = id;
if (no < 0 || no >= 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 >= modelList.size())
return;
modelList[no] = id;
}
// Set functions
void trpgTileHeader::AddMaterial(int id)
{
// 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);
// Look for it first
for (int i=0;i<matList.size();i++)
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);
for (int i=0;i<modelList.size();i++)
if (modelList[i] == id)
return;
modelList.push_back(id);
}
void trpgTileHeader::SetDate(int32 d)
{
date = d;
date = d;
}
// Local material methods
void trpgTileHeader::AddLocalMaterial(trpgLocalMaterial &locMat)
{
locMats.push_back(locMat);
}
bool trpgTileHeader::GetNumLocalMaterial(int32 &retNum) const
{
if (!isValid()) return false;
retNum = locMats.size();
return true;
}
bool trpgTileHeader::GetLocalMaterial(int32 id,trpgLocalMaterial &retMat) const
{
if (id < 0 || id >= locMats.size())
return false;
retMat = locMats[id];
return true;
}
const std::vector<trpgLocalMaterial> *trpgTileHeader::GetLocalMaterialList() const
{
if (!isValid()) return NULL;
return &locMats;
}
// Get methods
bool trpgTileHeader::GetNumMaterial(int32 &no) const
{
if (!isValid()) return false;
no = (int32)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 >= (int32)matList.size())
return false;
mat = matList[id];
return true;
if (!isValid() || id < 0 || id >= 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 >= (int32)modelList.size())
return false;
m = modelList[id];
return true;
if (!isValid() || id < 0 || id >= 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;
if (!isValid())
return false;
for (i=0;i<locMats.size();i++)
if (!locMats[i].isValid())
return false;
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.End();
buf.Begin(TRPGTILEHEADER);
return true;
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();
return true;
}
// Tile Header CB
// Used to aid in parsing tile header
// Used to aid in parsing tile header
// 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;
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);
buf.PopLimit();
}
}
break;
default:
// Don't care
break;
}
}
catch (...) {
return NULL;
}
return head;
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);
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();
}