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

@@ -4,22 +4,28 @@ SHELL = /bin/sh
include $(OSGHOME)/Make/makedefs
C++FILES = \
ReaderWriterTXP.cpp\
TrPageArchive.cpp\
TrPageParser.cpp\
trpage_basic.cpp\
trpage_geom.cpp\
trpage_header.cpp\
trpage_tile.cpp\
trpage_readbuf.cpp\
trpage_rarchive.cpp\
trpage_writebuf.cpp\
trpage_warchive.cpp\
trpage_parse.cpp\
trpage_nodes.cpp\
trpage_model.cpp\
trpage_material.cpp\
trpage_swap.cpp
ReaderWriterTXP.cpp\
TrPageArchive.cpp\
TrPageParser.cpp\
trpage_basic.cpp\
trpage_geom.cpp\
trpage_header.cpp\
trpage_tile.cpp\
trpage_readbuf.cpp\
trpage_rarchive.cpp\
trpage_writebuf.cpp\
trpage_warchive.cpp\
trpage_parse.cpp\
trpage_nodes.cpp\
trpage_model.cpp\
trpage_material.cpp\
trpage_swap.cpp\
trpage_range.cpp\
trpage_scene.cpp\
trpage_compat.cpp\
trpage_light.cpp\
trpage_pparse.cpp\
trpage_print.cpp
TARGET_BASENAME = osgdb_txp

View File

@@ -45,8 +45,7 @@ public:
notify(INFO) << "TXPFile::loadFile(): loading geometry"
<< std::endl;
ret = new Group;
ret->addChild(archive.LoadAllTiles());
ret = archive.LoadAllTiles();
notify(INFO) << "TXPFile::loadFile(): loaded archive: "
<< foundname << std::endl;
@@ -73,6 +72,9 @@ public:
osgDB::ReaderWriter::ReadResult ReaderWriterTXP::readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*)
{
if( !acceptsExtension(osgDB::getFileExtension(fileName) ))
return ReadResult::FILE_NOT_HANDLED;
TXPFile read;
Object* obj = read.readObject(fileName);
@@ -83,6 +85,9 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::readObject(const std::string& f
osgDB::ReaderWriter::ReadResult ReaderWriterTXP::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*)
{
if( !acceptsExtension(osgDB::getFileExtension(fileName) ))
return ReadResult::FILE_NOT_HANDLED;
TXPFile read;
Node* node = read.readNode(fileName);
if (node) return node;

View File

@@ -89,7 +89,7 @@ void TrPageArchive::LoadMaterials()
{
for (int i=0; i < n_textures ; i++)
{
trpgTexture *tex;
const trpgTexture *tex;
tex = texTable.GetTextureRef(i);
char texName[1024]; texName[0] = 0;
tex->GetName(texName,1023);
@@ -118,7 +118,7 @@ void TrPageArchive::LoadMaterials()
{
StateSet* osg_state_set = new StateSet;
trpgMaterial *mat;
const trpgMaterial *mat;
mat = materialTable.GetMaterialRef(0,i);
// Set texture
int numMatTex;

View File

@@ -72,17 +72,13 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
geom.GetPrimType(primType);
geom.GetNumPrims(numPrims);
geom.GetNumVertex(numVert);
numVert /= 3;
geom.GetMaterial(0,matId);
bool local;
geom.GetMaterial(0,matId, local);
geom.GetNumNormal(numNorm);
numNorm /= 3;
Vec3* vertices = new Vec3[numVert];
// Get vertices
// it can be done this way because standard guaranties that vector is on
// continuous storage and vec3 is POD
geom.GetVertices((float32 *)vertices);
geom.GetVertices(vertices);
// Turn the trpgGeometry into something Performer can understand
GeoSet *gset = 0L;
@@ -103,7 +99,7 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
if (numNorm == numVert)
{
normals = new Vec3[numVert];
geom.GetNormals((float32 *)normals);
geom.GetNormals(normals);
}
Geode *geode = new Geode();

View File

@@ -1,23 +1,22 @@
/* ************************
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
************************
*/
/* 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
@@ -60,6 +59,7 @@
// #endif
// #define TX_CPPDECL extern __declspec(dllimport)
#ifndef TX_CLDECL
// Class declaration. Goes after "class" to handle DLL export in windows.
#define TX_CLDECL
// Goes before "class" to handle DLL export in windows
@@ -69,7 +69,11 @@
// Exports a C function properly in a windows DLL
#define TX_CDECL /* no-op */
// {secret}
#ifndef TXDUMMY_DLL_MAIN
#define TXDUMMY_DLL_MAIN /* no-op */
#endif
#endif
#else
#define TX_CLDECL __declspec( dllexport )
#define TX_EXDECL
@@ -83,11 +87,15 @@
// The following is a DLL Main function for DLLs that wouldn't otherwise
// have one. It's needed to initialize the run time library.
// This should appear once within every DLL
// commented out by Boris Bralo for osg
/*
#ifndef TXDUMMY_DLL_MAIN
#define TXDUMMY_DLL_MAIN \
extern "C" { \
BOOL WINAPI _CRT_INIT (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved); \
BOOL APIENTRY DllMain (HANDLE hDLL, DWORD dwReason, LPVOID lpReserved) \
BOOL APIENTRY DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) \
{ \
switch (dwReason) \
{ \
@@ -106,8 +114,8 @@ BOOL APIENTRY DllMain (HANDLE hDLL, DWORD dwReason, LPVOID lpReserved) \
return TRUE; \
} \
}
#endif
*/
#endif
#ifndef txdll_h_

View File

@@ -1,22 +1,21 @@
/* ************************
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
************************
*/
/* trpage_basic.cpp
Methods for checkable base class.
*/
Methods for checkable base class.
*/
#include <stdlib.h>
#include <stdio.h>
@@ -24,20 +23,20 @@
#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;
}
trpgCheckable::~trpgCheckable()
{
valid = false;
valid = false;
}
bool trpgCheckable::isValid() const
{
return valid;
return valid;
}

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
************************
*/
@@ -28,7 +27,9 @@
#include "trpage_geom.h"
#include "trpage_read.h"
#if defined(_WIN32) && !defined(__GNUC__)
#include <osg/Vec3>
#if defined(_WIN32)
#define ALIGNMENT_WORKAROUND false
#else
#define ALIGNMENT_WORKAROUND true
@@ -99,12 +100,12 @@ void trpgGeometry::SetNumMaterial(int no)
materials.resize(no,-1);
}
void trpgGeometry::SetMaterial(int which,int mat)
void trpgGeometry::SetMaterial(int which,int mat,bool isLocal)
{
if (which < 0 || which >= (int)materials.size())
return;
materials[which] = mat;
materials[which] = (isLocal ? -(mat+1) : mat);
}
void trpgGeometry::SetMaterials(int32 num,const int32 *mat)
{
@@ -318,10 +319,15 @@ bool trpgGeometry::GetNumMaterial(int &n) const
n = materials.size();
return true;
}
bool trpgGeometry::GetMaterial(int id,int32 &m) const
bool trpgGeometry::GetMaterial(int id,int32 &m,bool &isLocal) const
{
if (!isValid() || id < 0 || id >= (int)materials.size()) return false;
isLocal = false;
if (!isValid() || id < 0 || id >= materials.size()) return false;
m = materials[id];
if (m < 0) {
m = -m - 1;
isLocal = true;
}
return true;
}
bool trpgGeometry::GetNumVertex(int &v) const
@@ -330,11 +336,12 @@ bool trpgGeometry::GetNumVertex(int &v) const
int nvf = vertDataFloat.size();
int nvd = vertDataDouble.size();
v = MAX(nvf,nvd);
v = v / 3;
return true;
}
bool trpgGeometry::GetVertices(float32 *v) const
{
unsigned int i;
int i;
if (!isValid()) return false;
if (vertDataFloat.size() != 0)
@@ -347,7 +354,7 @@ bool trpgGeometry::GetVertices(float32 *v) const
}
bool trpgGeometry::GetVertices(float64 *v) const
{
unsigned int i;
int i;
if (!isValid()) return false;
if (vertDataFloat.size() != 0)
@@ -358,11 +365,36 @@ bool trpgGeometry::GetVertices(float64 *v) const
v[i] = vertDataDouble[i];
return true;
}
bool trpgGeometry::GetVertices(osg::Vec3* v) const
{
int i;
if (!isValid()) return false;
if (vertDataFloat.size() != 0)
{
for (i=0;i<vertDataFloat.size()/3;i++ )
{
v[i].x() = vertDataFloat[3*i+0];
v[i].y() = vertDataFloat[3*i+1];
v[i].z() = vertDataFloat[3*i+2];
}
}
else
{
for (i=0;i<vertDataDouble.size()/3;i++ )
{
v[i].x() = vertDataDouble[3*i+0];
v[i].y() = vertDataDouble[3*i+1];
v[i].z() = vertDataDouble[3*i+2];
}
}
return true;
}
bool trpgGeometry::GetVertex(int n,trpg3dPoint &pt) const
{
int id = 3*n;
int idMax = 3*n+2;
if (id < 0 || (idMax >= (int)vertDataFloat.size() && idMax >= (int)vertDataDouble.size()))
if (id < 0 || (idMax >= vertDataFloat.size() && idMax >= vertDataDouble.size()))
return false;
if (vertDataFloat.size() > vertDataDouble.size()) {
pt.x = vertDataFloat[id];
@@ -382,11 +414,12 @@ bool trpgGeometry::GetNumNormal(int32 &n) const
n = normDataFloat.size();
if (normDataDouble.size() != 0)
n = normDataDouble.size();
n = n / 3;
return true;
}
bool trpgGeometry::GetNormals(float32 *v) const
{
unsigned int i;
int i;
if (!isValid()) return false;
if (normDataFloat.size() != 0)
@@ -399,7 +432,7 @@ bool trpgGeometry::GetNormals(float32 *v) const
}
bool trpgGeometry::GetNormals(float64 *v) const
{
unsigned int i;
int i;
if (!isValid()) return false;
if (normDataFloat.size() != 0)
@@ -410,40 +443,66 @@ bool trpgGeometry::GetNormals(float64 *v) const
v[i] = normDataDouble[i];
return true;
}
bool trpgGeometry::GetNormals(osg::Vec3* v) const
{
int i;
if (!isValid()) return false;
if (normDataFloat.size() != 0)
{
for (i=0;i<normDataFloat.size()/3;i++)
{
v[i].x() = normDataFloat[3*i+0];
v[i].y() = normDataFloat[3*i+1];
v[i].z() = normDataFloat[3*i+2];
}
}
else
{
for (i=0;i<normDataDouble.size()/3;i++)
{
v[i].x() = normDataDouble[3*i+0];
v[i].y() = normDataDouble[3*i+1];
v[i].z() = normDataDouble[3*i+2];
}
}
return true;
}
bool trpgGeometry::GetNumColorSets(int &n) const
{
if (!isValid()) return false;
n = (int)colors.size();
n = colors.size();
return true;
}
bool trpgGeometry::GetColorSet(int id,trpgColorInfo *ci) const
{
if (!isValid() || id < 0 || id >= (int)colors.size()) return false;
if (!isValid() || id < 0 || id >= colors.size()) return false;
*ci = colors[id];
return true;
}
bool trpgGeometry::GetNumTexCoordSets(int &n) const
{
if (!isValid()) return false;
n = (int)texData.size();
n = texData.size();
return true;
}
bool trpgGeometry::GetTexCoordSet(int id,trpgTexData *tx) const
{
if (!isValid() || id < 0 || id >= (int)texData.size()) return false;
if (!isValid() || id < 0 || id >= texData.size()) return false;
*tx = texData[id];
return true;
}
bool trpgGeometry::GetNumEdgeFlag(int &n) const
{
if (!isValid()) return false;
n = (int)edgeFlags.size();
n = edgeFlags.size();
return true;
}
bool trpgGeometry::GetEdgeFlags(char *e) const
{
if (!isValid()) return false;
for (unsigned int i=0;i<edgeFlags.size();i++)
for (int i=0;i<edgeFlags.size();i++)
e[i] = edgeFlags[i];
return true;
}
@@ -455,9 +514,8 @@ bool trpgGeometry::isValid() const
return true;
}
// Write geometry fields.
// Order doesn't matter very much for this
// Write geometry fields.
// Order doesn't matter very much for this
bool trpgGeometry::Write(trpgWriteBuffer &buf)
{
unsigned int i,j;
@@ -503,7 +561,7 @@ bool trpgGeometry::Write(trpgWriteBuffer &buf)
buf.Begin(TRPG_GEOM_VERT32);
int32 num = vertDataFloat.size()/3;
buf.Add(num);
for (i=0;i<(unsigned int)3*num;i++)
for (i=0;i<3*num;i++)
buf.Add(vertDataFloat[i]);
buf.End();
}
@@ -511,7 +569,7 @@ bool trpgGeometry::Write(trpgWriteBuffer &buf)
buf.Begin(TRPG_GEOM_VERT64);
int32 num = vertDataDouble.size()/3;
buf.Add(num);
for (i=0;i<(unsigned int)3*num;i++)
for (i=0;i<3*num;i++)
buf.Add(vertDataDouble[i]);
buf.End();
}
@@ -526,7 +584,7 @@ bool trpgGeometry::Write(trpgWriteBuffer &buf)
buf.Add((int32)normBind);
int32 num = normDataFloat.size()/3;
buf.Add(num);
for (i=0;i<(unsigned int)3*num;i++)
for (i=0;i<3*num;i++)
buf.Add(normDataFloat[i]);
buf.End();
}
@@ -535,7 +593,7 @@ bool trpgGeometry::Write(trpgWriteBuffer &buf)
buf.Add((int32)normBind);
int32 num = normDataDouble.size()/3;
buf.Add(num);
for (i=0;i<(unsigned int)3*num;i++)
for (i=0;i<3*num;i++)
buf.Add(normDataDouble[i]);
buf.End();
}
@@ -572,7 +630,7 @@ bool trpgGeometry::Write(trpgWriteBuffer &buf)
buf.Add((int32)td.bind);
int32 num = td.floatData.size()/2;
buf.Add(num);
for (j=0;j<(unsigned int)num*2;j++)
for (j=0;j<num*2;j++)
buf.Add(td.floatData[j]);
buf.End();
}
@@ -581,14 +639,13 @@ bool trpgGeometry::Write(trpgWriteBuffer &buf)
buf.Add((int32)td.bind);
int32 num = td.doubleData.size()/2;
buf.Add(num);
for (j=0;j<(unsigned int)num*2;j++)
for (j=0;j<num*2;j++)
buf.Add(td.doubleData[j]);
buf.End();
// What is going on here? - mcmillan
//float u;
//for (j=0;j<(unsigned int)num*2;j++)
// u = (float)td.doubleData[j];
float u;
for (j=0;j<num*2;j++)
u = (float)td.doubleData[j];
}
}

File diff suppressed because it is too large Load Diff

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,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()
{
@@ -43,143 +42,143 @@ trpgHeader::~trpgHeader()
// Validity check
bool trpgHeader::isValid() const
{
if (numLods <= 0)
return false;
if (sw.x == ne.x && sw.y == ne.y)
return false;
if (numLods <= 0)
return false;
if (sw.x == ne.x && sw.y == ne.y)
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;
numLods = 0;
lodSizes.resize(0);
lodRanges.resize(0);
tileSize.resize(0);
maxGroupID = -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 || (unsigned int)id >= tileSize.size()) return;
tileSize[id] = pt;
if (id < 0 || id >= 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::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();
buf.End();
return true;
return true;
}
/* ********
@@ -189,127 +188,128 @@ 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 || (unsigned int)id >= tileSize.size()) return false;
pt = tileSize[id];
return true;
if (!isValid()) return false;
if (id < 0 || id >= 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
buf.Get(maxGroupID);
}
// Added after the first version (but still in 1.0)
buf.Get(maxGroupID);
}
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;
}

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
************************
*/

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

File diff suppressed because it is too large Load Diff

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,199 +18,199 @@
#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.
*/
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;
}
trpgModel::trpgModel(const trpgModel &in)
{
name = NULL;
type = External;
*this = in;
name = NULL;
type = External;
*this = in;
}
// Reset function
void trpgModel::Reset()
{
if (name)
delete name;
name = NULL;
useCount = 0;
if (name)
delete [] name;
name = NULL;
useCount = 0;
}
trpgModel::~trpgModel()
{
Reset();
Reset();
}
// Set functions
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);
name = new char[(nm ? strlen(nm) : 0)+1];
strcpy(name,nm);
type = External;
type = External;
}
void trpgModel::SetReference(trpgDiskRef pos)
{
if (name)
delete name;
if (name)
delete [] name;
diskRef = pos;
diskRef = pos;
type = Local;
type = Local;
}
void trpgModel::SetNumTiles(int num)
{
useCount = num;
useCount = num;
}
void trpgModel::AddTile()
{
useCount++;
useCount++;
}
// Validity check
bool trpgModel::isValid() const
{
if (type == External && !name)
return false;
if (type == External && !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;
type = in.type;
if (in.name)
SetName(in.name);
diskRef = in.diskRef;
useCount = in.useCount;
return *this;
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
buf.Add(diskRef);
buf.Add(useCount);
buf.Begin(TRPGMODELREF);
buf.Add(type);
if (name)
buf.Add(name);
else
buf.Add(diskRef);
buf.Add(useCount);
buf.End();
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() || type != External) 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)
{
char tmpName[1024];
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);
if (type == Local)
buf.Get(diskRef);
else {
buf.Get(tmpName,1023);
SetName(tmpName);
}
buf.Get(useCount);
}
catch(...) {
return false;
}
return isValid();
return isValid();
}
/* Write Model Reference table
Groups of models for the entire file.
*/
Groups of models for the entire file.
*/
// Constructor
trpgModelTable::trpgModelTable()
@@ -224,102 +223,110 @@ trpgModelTable::~trpgModelTable()
// Reset function
void trpgModelTable::Reset()
{
models.resize(0);
models.resize(0);
}
// Set functions
void trpgModelTable::SetNumModels(int no)
{
models.resize(no);
models.resize(no);
}
void trpgModelTable::SetModel(int id,const trpgModel &mod)
{
if (id < 0 || (unsigned int)id >= models.size())
return;
if (id < 0 || (unsigned int)id >= models.size())
return;
models[id] = mod;
models[id] = mod;
}
int trpgModelTable::AddModel(const trpgModel &mod)
{
models.push_back(mod);
models.push_back(mod);
return models.size()-1;
return models.size()-1;
}
int trpgModelTable::FindAddModel(const trpgModel &mod)
{
for (unsigned int i=0;i<models.size();i++)
if (models[i] == mod)
return i;
return AddModel(mod);
}
// Validity check
bool trpgModelTable::isValid() const
{
for (unsigned int i=0;i<models.size();i++)
if (!models[i].isValid())
return false;
for (unsigned int i=0;i<models.size();i++)
if (!models[i].isValid())
return false;
return true;
return true;
}
// 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)models.size());
for (unsigned int i=0;i<models.size();i++)
models[i].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 = models.size();
return true;
}
bool trpgModelTable::GetModel(int id,trpgModel &model) const
{
if (!isValid() || id < 0 || (unsigned int)id >= models.size())
return false;
model = models[id];
return true;
if (!isValid() || id < 0 || id >= models.size())
return false;
model = models[id];
return true;
}
trpgModel *trpgModelTable::GetModelRef(int id)
{
if (id < 0 || (unsigned int)id >= models.size())
return NULL;
return &models[id];
if (id < 0 || id >= models.size())
return NULL;
return &models[id];
}
bool trpgModelTable::Read(trpgReadBuffer &buf)
{
int32 numModel;
trpgModel model;
trpgToken tok;
int32 len;
bool status;
int32 numModel;
trpgModel model;
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++) {
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;
}
return isValid();
return isValid();
}

File diff suppressed because it is too large Load Diff

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
************************
*/
@@ -171,10 +170,14 @@ bool trpgr_Parser::Parse(trpgReadBuffer &buf)
// Call our token handler for this one
try {
trpgr_Token *tcb = &tokenMap[tok];
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);
@@ -259,8 +262,7 @@ trpgSceneParser::trpgSceneParser()
// Register for default
SetDefaultCallback(new trpgSceneHelperDefault(this));
};
}
trpgSceneParser::~trpgSceneParser()
{
};
}

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,472 @@
#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"
// Constructor
trpgr_Archive::trpgr_Archive()
{
fp = NULL;
ness = LittleEndian;
strcpy(dir,".");
fp = NULL;
ness = LittleEndian;
strcpy(dir,".");
tileCache = NULL;
}
// Destructor
trpgr_Archive::~trpgr_Archive()
{
if (fp)
fclose(fp);
fp = NULL;
if (fp)
fclose(fp);
fp = NULL;
if (tileCache)
delete tileCache;
}
// Set the directory where the archive is
void trpgr_Archive::SetDirectory(const char *in_dir)
{
strncpy(dir,in_dir,1024);
strncpy(dir,in_dir,1024);
}
// Open File
// Open the given file and look for the file specific info
bool trpgr_Archive::OpenFile(const char *name)
{
char file[1024];
sprintf(file,"%s/%s",dir,name);
char file[1024];
sprintf(file,"%s" PATHSEPERATOR "%s",dir,name);
CloseFile();
CloseFile();
if (!(fp = fopen(file,"rb")))
return false;
if (!(fp = fopen(file,"rb")))
return false;
// Look for a magic # and endianness
int32 magic;
if (fread(&magic,sizeof(int32),1,fp) != 1)
return false;
// Look for a magic # and endianness
int32 magic;
if (fread(&magic,sizeof(int32),1,fp) != 1)
return false;
headerRead = 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 (trpg_byteswap_int(magic) == TRPG_MAGIC) {
if (cpuNess == LittleEndian)
ness = BigEndian;
else
ness = LittleEndian;
return true;
}
if (magic != TRPG_MAGIC)
return false;
// Figure out the endianness from the magic number
trpgEndian cpuNess = trpg_cpu_byte_order();
if (magic == TRPG_MAGIC) {
ness = cpuNess;
return true;
}
if (trpg_byteswap_int(magic) == TRPG_MAGIC) {
if (cpuNess == LittleEndian)
ness = BigEndian;
else
ness = LittleEndian;
return true;
}
if (magic != TRPG_MAGIC)
return false;
// Not one of our files
return false;
// Not one of our files
return false;
}
// Close File
// Close the currently open file
void trpgr_Archive::CloseFile()
{
if (fp)
fclose(fp);
fp = NULL;
if (fp)
fclose(fp);
fp = NULL;
if (tileCache)
delete tileCache;
tileCache = NULL;
}
// Read Header
// Run through the rest of the header information
bool trpgr_Archive::ReadHeader()
{
if (!fp || headerRead)
return false;
int ret;
headerRead = true;
if (!fp || headerRead)
return false;
// Eat some bytes
// char stuff[20];
// if (fread(stuff,1,20,fp) != 20) return false;
headerRead = true;
// if (fread(stuff,1,sizeof(trpgllong),fp) != sizeof(trpgllong)) return false;
// 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 (ness != cpuNess)
headerSize = trpg_byteswap_int(headerSize);
int headLen = headerSize;
if (headLen < 0) return false;
// 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 (ness != cpuNess)
headerSize = trpg_byteswap_int(headerSize);
int headLen = headerSize;
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;
// Read in the header whole
trpgMemReadBuffer buf(ness);
buf.SetLength(headLen);
char *data = buf.GetDataPtr();
if (fread(data,1,headLen,fp) != (unsigned int)headLen) return false;
// Set up a parser
// Catch the tables we need for the archive
trpgMatTable1_0 oldMatTable;
trpgTexTable1_0 oldTexTable;
trpgr_Parser parser;
parser.AddCallback(TRPGHEADER,&header);
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(TRPGMODELTABLE,&modelTable);
parser.AddCallback(TRPGLIGHTTABLE,&lightTable); // Added for 2.0
parser.AddCallback(TRPGRANGETABLE,&rangeTable); // Added for 2.0
// Set up a parser
// Catch the tables we need for the archive
trpgr_Parser parser;
parser.AddCallback(TRPGHEADER,&header);
parser.AddCallback(TRPGMATTABLE,&materialTable);
parser.AddCallback(TRPGMATTABLE2,&materialTable); // Added 11-14-98
parser.AddCallback(TRPGTEXTABLE,&texTable);
parser.AddCallback(TRPGMODELTABLE,&modelTable);
parser.AddCallback(TRPGTILETABLE,&tileTable);
// 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;
// Parse the buffer
if (!parser.Parse(buf))
return false;
valid = true;
// 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;
if (oldTexTable.isValid())
texTable = oldTexTable;
return true;
// 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");
}
valid = true;
return true;
}
// Read Tile
// Read a tile into a read buffer
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 < 0 ||*/ (int)lod >= numLods) return false;
trpg2iPoint lodSize;
header.GetLodSize(lod,lodSize);
if (/*x < 0 ||*/ (int)x >= lodSize.x || /*y < 0 ||*/ (int)y >= lodSize.y) return false;
// Reality check the address
int32 numLods;
header.GetNumLods(numLods);
if (lod >= numLods) return false;
trpg2iPoint lodSize;
header.GetLodSize(lod,lodSize);
if (x >= lodSize.x || y >= lodSize.y) return false;
// Figure out the file name
// Note: This assumes External tiles
const char *base = tileTable.GetBaseName();
char filename[1024];
sprintf(filename,"%s/%s/tile_%d_%d_%d.tpt",dir,base,x,y,lod);
trpgTileTable::TileMode tileMode;
tileTable.GetMode(tileMode);
// 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;
}
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);
return true;
// 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;
}
} 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;
// Fetch the appendable file from the cache
trpgrAppFile *tf = tileCache->GetFile(ness,addr.file);
if (!tf) return false;
// Fetch the tile
if (!tf->Read(&buf,addr.offset))
return false;
}
return true;
}
// Get methods
const trpgHeader *trpgr_Archive::GetHeader() const
{
return &header;
return &header;
}
const trpgMatTable *trpgr_Archive::GetMaterialTable() const
{
return &materialTable;
return &materialTable;
}
const trpgTexTable *trpgr_Archive::GetTexTable() const
{
return &texTable;
return &texTable;
}
const trpgModelTable *trpgr_Archive::GetModelTable() const
{
return &modelTable;
return &modelTable;
}
const trpgTileTable *trpgr_Archive::GetTileTable() const
{
return &tileTable;
return &tileTable;
}
const trpgLightTable *trpgr_Archive::GetLightTable() const
{
return &lightTable;
}
const trpgRangeTable *trpgr_Archive::GetRangeTable() const
{
return &rangeTable;
}
trpgEndian trpgr_Archive::GetEndian() const
{
return ness;
return ness;
}
// Utility MBR routine
bool trpgr_Archive::trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,trpg2dPoint &ll,trpg2dPoint &ur) const
bool trpgr_Archive::trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,trpg3dPoint &ll,trpg3dPoint &ur) const
{
if (!header.isValid())
return false;
int32 numLod;
header.GetNumLods(numLod);
trpg2iPoint maxXY;
header.GetLodSize(lod,maxXY);
if (/*x < 0 ||*/ (int)x>= maxXY.x || /*y < 0 ||*/ (int)y>= maxXY.y)
return false;
if (!header.isValid())
return false;
int32 numLod;
header.GetNumLods(numLod);
trpg2iPoint maxXY;
header.GetLodSize(lod,maxXY);
if (x >= maxXY.x || y>= maxXY.y)
return false;
trpg3dPoint origin;
header.GetOrigin(origin);
trpg2dPoint size;
header.GetTileSize(lod,size);
trpg3dPoint origin;
header.GetOrigin(origin);
trpg2dPoint size;
header.GetTileSize(lod,size);
ll.x = origin.x + size.x*x;
ll.y = origin.y + size.y*y;
ur.x = origin.x + size.x*(x+1);
ur.y = origin.y + size.y*(y+1);
ll.x = origin.x + size.x*x;
ll.y = origin.y + size.y*y;
ur.x = origin.x + size.x*(x+1);
ur.y = origin.y + size.y*(y+1);
return true;
// If the tiles are local, we should have Z information
trpgwAppAddress addr;
float elev_min=0.0,elev_max=0.0;
tileTable.GetTile(x,y,lod,addr,elev_min,elev_max);
ll.z = elev_min; ur.z = elev_max;
return true;
}
/* *****************
Read Image Helper
*****************
*/
trpgrImageHelper::trpgrImageHelper(trpgEndian inNess,char *inDir,
const trpgMatTable &inMatTable,const trpgTexTable &inTexTable)
{
ness = inNess;
strcpy(dir,inDir);
matTable = &inMatTable;
texTable = &inTexTable;
// Set up the texture cache
// It doesn't do anything until it's called anyway
char fullBase[1024];
sprintf(fullBase,"%s" PATHSEPERATOR "texFile",dir);
texCache = new trpgrAppFileCache(fullBase,"txf");
}
trpgrImageHelper::~trpgrImageHelper()
{
if (texCache)
delete texCache;
}
bool trpgrImageHelper::GetLocalGL(const trpgTexture *tex,char *data,int32 size)
{
// Make sure the texture is Local
trpgTexture::ImageMode mode;
tex->GetImageMode(mode);
if (mode != trpgTexture::Local)
return false;
// Fetch data data
trpgwAppAddress addr;
tex->GetImageAddr(addr);
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
if (!af)
return false;
if (!af->Read(data,addr.offset,size))
return false;
return true;
}
bool trpgrImageHelper::GetMipLevelLocalGL(int miplevel, const trpgTexture *tex,char *data,int32 dataSize)
{
if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 )
return false;
// Make sure the texture is Local
trpgTexture::ImageMode mode;
tex->GetImageMode(mode);
if (mode != trpgTexture::Local)
return false;
// Fetch data data
trpgwAppAddress addr;
tex->GetImageAddr(addr);
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
if (!af)
return false;
int level_offset = (const_cast<trpgTexture*>(tex))->MipLevelOffset(miplevel);
if (!af->Read(data,addr.offset+level_offset,dataSize))
return false;
return true;
}
bool trpgrImageHelper::GetImageInfoForLocalMat(const trpgLocalMaterial *locMat,
const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize)
{
// Get the base material for the Local Material
int32 matSubTable,matID;
locMat->GetBaseMaterial(matSubTable,matID);
const trpgMaterial *mat = matTable->GetMaterialRef(matSubTable,matID);
if (!mat) return false;
// Now get the texture (always the first one)
trpgTextureEnv texEnv;
int32 texID;
if (!mat->GetTexture(0,texID,texEnv)) return false;
const trpgTexture *tex = texTable->GetTextureRef(texID);
if (!tex) return false;
totSize = tex->CalcTotalSize();
*retTex = tex;
*retMat = mat;
return true;
}
bool trpgrImageHelper::GetImageForLocalMat(const trpgLocalMaterial *locMat,char *data,int dataSize)
{
if (!locMat->isValid()) return false;
const trpgMaterial *mat;
const trpgTexture *tex;
int totSize;
if (!GetImageInfoForLocalMat(locMat,&mat,&tex,totSize))
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;
locMat->GetAddr(addr);
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
if (!af) return false;
if (!af->Read(data,addr.offset,dataSize))
return false;
}
break;
case trpgTexture::Global:
// Note: Not dealing with Global textures yet
return false;
break;
default:
// This is not a valid Local Material
return false;
};
return true;
}
bool trpgrImageHelper::GetMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat,char *data,int dataSize)
{
if (!locMat->isValid()) return false;
const trpgMaterial *mat;
const trpgTexture *tex;
int totSize;
if (!GetImageInfoForLocalMat(locMat,&mat,&tex,totSize))
return false;
if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 )
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;
locMat->GetAddr(addr);
trpgrAppFile *af = texCache->GetFile(ness,addr.file);
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;
case trpgTexture::Global:
// Note: Not dealing with Global textures yet
return false;
break;
default:
// This is not a valid Local Material
return false;
};
return true;
}
bool trpgrImageHelper::GetImagePath(const trpgTexture *tex,char *fullPath,int pathLen)
{
char name[1024];
int nameLen=1024;
tex->GetName(name,nameLen);
nameLen = strlen(name);
if (strlen(dir) + nameLen + 2 > pathLen)
return false;
sprintf(fullPath,"%s" PATHSEPERATOR "%s",dir,name);
return true;
}

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
************************
*/
@@ -75,15 +74,73 @@ protected:
private:
// Note: Just how slow is a map<> anyway?
// This usage is self-contained and could be replaced with an array
#if defined(_WIN32) && !defined(__GNUC__)
typedef map<trpgToken,trpgr_Token> tok_map;
#if defined(_WIN32)
typedef std::map<trpgToken,trpgr_Token> tok_map;
#else
typedef map<trpgToken,trpgr_Token,less<trpgToken> > tok_map;
typedef std::map<trpgToken,trpgr_Token,less<trpgToken> > tok_map;
#endif
tok_map tokenMap;
trpgr_Token defCb; // Call this when no others are called
};
/* Image Read Helper.
Used to help read Local and Tile Local textures into
memory (in OpenGL format). You're on your own for External
textures.
If you want to add additional ways to read textures, feel free
to subclass this object.
*/
TX_EXDECL class TX_CLDECL trpgrImageHelper {
public:
trpgrImageHelper(trpgEndian ness,char *dir,const trpgMatTable &,const trpgTexTable &);
virtual ~trpgrImageHelper(void);
/* Fetch the bytes for the given texture.
This is only valid for Local textures.
*/
virtual bool GetLocalGL(const trpgTexture *,char *data,int32 dataSize);
/* Fetch the bytes for the given mip level of a given texture.
This is only valid for Local textures.
*/
virtual bool GetMipLevelLocalGL(int miplevel, const trpgTexture *,char *data,int32 dataSize);
/* Do the lookups to figure out the correct material
and Template (or Local) texture for a given Local Material.
You'll need this for sizes (among other things).
This routine also calculates the total size, including mipmaps if they're there.
*/
virtual bool GetImageInfoForLocalMat(const trpgLocalMaterial *locMat,
const trpgMaterial **retMat,const trpgTexture **retTex,
int &totSize);
/* Fetch the bytes for the given Local Material (and
associated texture). This is for Tile Local and
Global textures.
Data is a pre-allocated buffer for the data and
dataSize is the size of that buffer.
*/
virtual bool GetImageForLocalMat(const trpgLocalMaterial *locMat,char *data,int dataSize);
/* Same as the one above, just fetch single mip levels
*/
virtual bool GetMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat,char *data,int dataSize);
/* Determine the full path of the image in the given
trpgTexture class.
Only useful for External images.
*/
virtual bool GetImagePath(const trpgTexture *,char *,int len);
protected:
char dir[1024];
trpgEndian ness;
const trpgMatTable *matTable;
const trpgTexTable *texTable;
trpgrAppFileCache *texCache;
};
/* Paging Archive (read version)
This just reads the first bits of the file (and the header)
and lets you parse from there.
@@ -106,13 +163,15 @@ public:
virtual const trpgTexTable *GetTexTable(void) const;
virtual const trpgModelTable *GetModelTable(void) const;
virtual const trpgTileTable *GetTileTable(void) const;
virtual const trpgLightTable *GetLightTable(void) const;
virtual const trpgRangeTable *GetRangeTable(void) const;
// Utility routine to calculate the MBR of a given point
// Utility routine to calculate the MBR of a given tile
virtual bool trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,
trpg2dPoint &ll,trpg2dPoint &ur) const;
trpg3dPoint &ll,trpg3dPoint &ur) const;
trpgEndian GetEndian() const;
char* getDir(){return dir;};
trpgEndian GetEndian(void) const;
char* getDir(void){return dir;};
protected:
bool headerRead;
trpgEndian ness;
@@ -125,6 +184,10 @@ protected:
trpgTexTable texTable;
trpgModelTable modelTable;
trpgTileTable tileTable;
trpgLightTable lightTable;
trpgRangeTable rangeTable;
trpgrAppFileCache *tileCache;
};
class trpgSceneHelperPush;
@@ -149,7 +212,7 @@ protected:
virtual bool EndChildren(void *) { return true;};
// List of objects whose children we're working on
vector<void *> parents;
std::vector<void *> parents;
};
#endif

View File

@@ -1,34 +1,32 @@
/* ************************
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
************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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"
@@ -41,243 +39,243 @@
// Basic get functions
bool trpgReadBuffer::Get(int32 &ret)
{
int32 val;
int32 val;
if (!GetData((char *)&val,sizeof(int32))) return false;
if (ness != cpuNess)
ret = trpg_byteswap_int(val);
else
ret = val;
if (!GetData((char *)&val,sizeof(int32))) return false;
if (ness != cpuNess)
ret = trpg_byteswap_int(val);
else
ret = val;
return true;
return true;
}
bool trpgReadBuffer::Get(int64 &ret)
{
int64 val;
int64 val;
if (!GetData((char *)&val,sizeof(int64))) return false;
if (ness != cpuNess)
ret = trpg_byteswap_llong(val);
else
ret = val;
if (!GetData((char *)&val,sizeof(int64))) return false;
if (ness != cpuNess)
ret = trpg_byteswap_long(val);
else
ret = val;
return true;
return true;
}
bool trpgReadBuffer::Get(char *ret,int retLen)
{
int32 len;
int32 len;
// Get the length first
if (!Get(len)) return false;
// Get the length first
if (!Get(len)) return false;
// Read what we can
int rlen = MIN(len,retLen-1);
if (!GetData(ret,rlen)) return false;
ret[rlen] = 0;
// Read what we can
int rlen = MIN(len,retLen-1);
if (!GetData(ret,rlen)) return false;
ret[rlen] = 0;
// Skip the rest
if (!Skip(rlen-len)) return false;
// Skip the rest
if (!Skip(rlen-len)) return false;
return true;
return true;
}
bool trpgReadBuffer::Get(float32 &ret)
{
char cval[4];
char cval[4];
if (!GetData(cval,sizeof(float32))) return false;
try {
if (ness == cpuNess)
memcpy(&ret,cval,4);
else
ret = trpg_byteswap_4bytes_to_float(cval);
}
catch (...) {
}
if (!GetData(cval,sizeof(float32))) return false;
try {
if (ness == cpuNess)
memcpy(&ret,cval,4);
else
ret = trpg_byteswap_4bytes_to_float(cval);
}
catch (...) {
}
return true;
return true;
}
bool trpgReadBuffer::Get(float64 &ret)
{
char cval[8];
char cval[8];
if (!GetData(cval,sizeof(float64))) return false;
try {
if (ness == cpuNess)
memcpy(&ret,cval,8);
else
ret = trpg_byteswap_8bytes_to_double(cval);
}
catch (...) {
}
if (!GetData(cval,sizeof(float64))) return false;
try {
if (ness == cpuNess)
memcpy(&ret,cval,8);
else
ret = trpg_byteswap_8bytes_to_double(cval);
}
catch (...) {
}
return true;
return true;
}
bool trpgReadBuffer::Get(uint8 &ret)
{
uint8 val;
uint8 val;
if (!GetData((char *)&val,sizeof(uint8))) return false;
// No byte swapping needed
ret = val;
if (!GetData((char *)&val,sizeof(uint8))) return false;
// No byte swapping needed
ret = val;
return true;
return true;
}
#if (bool != int32)
bool trpgReadBuffer::Get(bool &ret)
{
uint8 val;
uint8 val;
if (!GetData((char *)&val,sizeof(uint8))) return false;
// No byte swapping needed
ret = (val == 0) ? false : true;
if (!GetData((char *)&val,sizeof(uint8))) return false;
// No byte swapping needed
ret = (val == 0) ? false : true;
return true;
return true;
}
#endif
#if (trpgDiskRef != int64)
bool trpgReadBuffer::Get(trpgDiskRef &ret)
{
trpgDiskRef val;
trpgDiskRef val;
if (!GetData((char *)&val,sizeof(trpgDiskRef))) return false;
if (ness == cpuNess)
ret = val;
else
ret = trpg_byteswap_llong(val);
if (!GetData((char *)&val,sizeof(trpgDiskRef))) return false;
if (ness == cpuNess)
ret = val;
else
ret = trpg_byteswap_llong(val);
return true;
return true;
}
#endif
bool trpgReadBuffer::Get(trpgToken &ret)
{
trpgToken val;
trpgToken val;
if (!GetData((char *)&val,sizeof(trpgToken))) return false;
if (ness == cpuNess)
ret = val;
else
ret = trpg_byteswap_short(val);
if (!GetData((char *)&val,sizeof(trpgToken))) return false;
if (ness == cpuNess)
ret = val;
else
ret = trpg_byteswap_short(val);
return true;
return true;
}
// Array Get functions
bool trpgReadBuffer::GetArray(int len,float32 **arr)
{
if (!GetDataRef((char **)arr,sizeof(float32)*len))
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);
}
if (!GetDataRef((char **)arr,sizeof(float32)*len))
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);
}
return true;
return true;
}
bool trpgReadBuffer::GetArray(int len,float64 **arr)
{
if (!GetDataRef((char **)arr,sizeof(float64)*len))
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);
}
return true;
if (!GetDataRef((char **)arr,sizeof(float64)*len))
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);
}
return true;
}
bool trpgReadBuffer::GetArray(int len,int32 **arr)
{
if (!GetDataRef((char **)arr,sizeof(int32)*len))
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);
}
return true;
if (!GetDataRef((char **)arr,sizeof(int32)*len))
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);
}
return true;
}
bool trpgReadBuffer::GetArray(int len,trpgColor **arr)
{
if (!GetDataRef((char **)arr,sizeof(trpgColor)*len))
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);
}
return true;
if (!GetDataRef((char **)arr,sizeof(trpgColor)*len))
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);
}
return true;
}
bool trpgReadBuffer::GetArray(int len,char **arr)
{
return GetDataRef((char **)arr,sizeof(char)*len);
return GetDataRef((char **)arr,sizeof(char)*len);
}
// Utility Get functions - Just call the others
bool trpgReadBuffer::Get(trpg2iPoint &pt)
{
if (!Get(pt.x) || !Get(pt.y))
return false;
return true;
if (!Get(pt.x) || !Get(pt.y))
return false;
return true;
}
bool trpgReadBuffer::Get(trpg2dPoint &pt)
{
if (!Get(pt.x) || !Get(pt.y))
return false;
return true;
if (!Get(pt.x) || !Get(pt.y))
return false;
return true;
}
bool trpgReadBuffer::Get(trpg3dPoint &pt)
{
if (!Get(pt.x) || !Get(pt.y) || !Get(pt.z))
return false;
return true;
if (!Get(pt.x) || !Get(pt.y) || !Get(pt.z))
return false;
return true;
}
bool trpgReadBuffer::Get(trpgColor &color)
{
if (!Get(color.red) || !Get(color.green) || !Get(color.blue))
return false;
return true;
if (!Get(color.red) || !Get(color.green) || !Get(color.blue))
return false;
return true;
}
// Get both a token and it's length, since that's fairly common
bool trpgReadBuffer::GetToken(trpgToken &tok,int32 &len)
{
if (!Get(tok) || !Get(len))
return false;
if (!Get(tok) || !Get(len))
return false;
return true;
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)
{
limits.push_back(limit);
limits.push_back(limit);
}
// Pop Limit
// Remove the current limit from the stack
void trpgReadBuffer::PopLimit()
{
int len = limits.size();
int len = limits.size();
if (len > 0)
limits.resize(len-1);
if (len > 0)
limits.resize(len-1);
}
// Skip To Limit
@@ -285,34 +283,34 @@ void trpgReadBuffer::PopLimit()
// This happens when we bag the rest of the current token
bool trpgReadBuffer::SkipToLimit()
{
int len=0;
int len=0;
if (limits.size() != 0)
len = limits[limits.size()-1];
if (limits.size() != 0)
len = limits[limits.size()-1];
if (len > 0)
return Skip(len);
if (len > 0)
return Skip(len);
return true;
return true;
}
// Test Limit
// See if the next read is going to blow the limits
bool trpgReadBuffer::TestLimit(int len)
{
for (unsigned int i=0;i<limits.size();i++)
if (len > limits[i])
return false;
for (int i=0;i<limits.size();i++)
if (len > limits[i])
return false;
return true;
return true;
}
// Update Limits
// We just read a few bytes. Update the limits
void trpgReadBuffer::UpdateLimits(int len)
{
for (unsigned int i=0;i<limits.size();i++)
limits[i] -= len;
for (int i=0;i<limits.size();i++)
limits[i] -= len;
}
/* *************************
@@ -321,110 +319,299 @@ void trpgReadBuffer::UpdateLimits(int len)
*/
trpgMemReadBuffer::trpgMemReadBuffer(trpgEndian in_ness)
{
data = NULL;
len = totLen = pos = 0;
ness = in_ness;
cpuNess = trpg_cpu_byte_order();
data = NULL;
len = totLen = pos = 0;
ness = in_ness;
cpuNess = trpg_cpu_byte_order();
}
trpgMemReadBuffer::~trpgMemReadBuffer()
{
if (data)
delete data;
if (data)
delete [] data;
}
// Empty check
bool trpgMemReadBuffer::isEmpty()
{
if (!data) return true;
if (!data) return true;
if (pos >= len)
return true;
if (pos >= len)
return true;
// Also test the limits
for (unsigned int i=0;i<limits.size();i++)
if (limits[i] == 0) return true;
// Also test the limits
for (int i=0;i<limits.size();i++)
if (limits[i] == 0) return true;
return false;
return false;
}
// Set Length
// Allocate the given space
void trpgMemReadBuffer::SetLength(int newLen)
{
if (newLen > totLen) {
if (data)
delete data;
data = new char[newLen];
totLen = newLen;
}
len = newLen;
pos = 0;
if (newLen > totLen) {
if (data)
delete [] data;
data = new char[newLen];
totLen = newLen;
}
len = newLen;
pos = 0;
}
// Get Data Ptr
// Return a pointer to our data so it can be written to
char *trpgMemReadBuffer::GetDataPtr()
{
return data;
return data;
}
// Get Data
// Protected method for actually retrieving a piece of data
bool trpgMemReadBuffer::GetData(char *ret,int rlen)
{
if (rlen < 0)
return false;
if (rlen < 0)
return false;
// Test against limits imposed from without
if (!TestLimit(rlen)) throw 1;
// Test against limits imposed from without
if (!TestLimit(rlen)) throw 1;
// See if we've actually got the data
if (pos+rlen > len) throw 1;
// See if we've actually got the data
if (pos+rlen > len) throw 1;
// Copy into the return buffer
memcpy(ret,&data[pos],rlen);
// Copy into the return buffer
memcpy(ret,&data[pos],rlen);
// Update any limits we might have
UpdateLimits(rlen);
// Update any limits we might have
UpdateLimits(rlen);
pos += rlen;
pos += rlen;
return true;
return true;
}
// Get Reference to Data
// Protected method that retrieves a reference to the given amoutn of data
bool trpgMemReadBuffer::GetDataRef(char **ret,int rlen)
{
if (rlen < 0) return false;
if (rlen < 0) return false;
// Test against limits
if (!TestLimit(rlen)) throw 1;
if (pos + rlen > len) throw 1;
// Test against limits
if (!TestLimit(rlen)) throw 1;
if (pos + rlen > len) throw 1;
// Set up reference
*ret = &data[pos];
// Set up reference
*ret = &data[pos];
UpdateLimits(rlen);
pos += rlen;
UpdateLimits(rlen);
pos += rlen;
return true;
return true;
}
// Skip
// Same as read except we're not, uh, reading
bool trpgMemReadBuffer::Skip(int rlen)
{
if (rlen < 0)
return false;
if (rlen < 0)
return false;
// Test against limits
if (!TestLimit(rlen)) return false;
if (pos + rlen > len) return false;
// Test against limits
if (!TestLimit(rlen)) return false;
if (pos + rlen > len) return false;
UpdateLimits(rlen);
UpdateLimits(rlen);
pos += rlen;
pos += rlen;
return true;
return true;
}
/* Appendable File read class
*/
trpgrAppFile::trpgrAppFile(trpgEndian inNess,const char *fileName)
{
valid = false;
ness = inNess;
cpuNess = trpg_cpu_byte_order();
if (!(fp = fopen(fileName,"rb")))
return;
valid = true;
}
trpgrAppFile::~trpgrAppFile()
{
if (fp)
fclose(fp);
valid = false;
}
// Read a section of data from the given file
// and dump it into the given buffer
bool trpgrAppFile::Read(trpgMemReadBuffer *buf,int32 offset)
{
if (!valid) return false;
// Seek to the right location
if (fseek(fp,offset,SEEK_SET))
return false;
// Read a length
int32 len;
if (fread(&len,sizeof(int32),1,fp) != 1) {
valid = false;
return false;
}
// Byteswap if necessary
if (ness != cpuNess)
trpg_byteswap_int(len);
if (len < 0) {
valid = false;
return false;
}
buf->SetLength(len);
char *data = buf->GetDataPtr();
if (!data) {
valid = false;
return false;
}
if (fread(data,sizeof(char),len,fp) != 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.
*/
bool trpgrAppFile::Read(char *data,int32 offset,int32 dataSize)
{
if (!valid) return false;
// Seek to the right place
int result;
if ((result = fseek(fp,offset,SEEK_SET))) {
valid = false;
return false;
}
// Read the length
int32 len;
if (fread(&len,sizeof(int32),1,fp) != 1) {
valid = false;
return false;
}
// Byteswap if necessary
if (ness != cpuNess)
trpg_byteswap_int(len);
if (len < 0) {
valid = false;
return false;
}
// It's all right to read less than the whol data block
if (dataSize > len)
return false;
// Read the raw data
// Note: What about byte swapping?
if (fread(data,sizeof(char),dataSize,fp) != 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.
*/
trpgrAppFileCache::trpgrAppFileCache(const char *inPre,const char *inExt,int noFiles)
{
strcpy(baseName,inPre);
strcpy(ext,inExt);
files.resize(noFiles);
timeCount = 0;
}
trpgrAppFileCache::~trpgrAppFileCache()
{
for (unsigned int i=0;i<files.size();i++) {
if (files[i].afile) {
delete files[i].afile;
files[i].afile = NULL;
}
}
}
/*
*/
trpgrAppFile *trpgrAppFileCache::GetFile(trpgEndian ness,int id)
{
// 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;
}
}
// Found it in cache, just return
if (foundID != -1) {
OpenFile &of = files[foundID];
of.lastUsed = timeCount;
return of.afile;
}
// 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 || (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;
char fileName[1024];
sprintf(fileName,"%s_%d.%s",baseName,id,ext);
of.afile = new trpgrAppFile(ness,fileName);
of.id = id;
of.lastUsed = timeCount;
timeCount++;
return of.afile;
}
// Constructor for OpenFile class
trpgrAppFileCache::OpenFile::OpenFile()
{
afile = NULL;
lastUsed = 0;
id = -1;
}

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
************************
*/
@@ -20,448 +19,448 @@
#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>
#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 (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 >= 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 (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 (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 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_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
@@ -469,87 +468,87 @@ 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 when the parser hits a pop.
/* This is called whent he parser hits a pop.
We'll want to look on the parent list (in trpgSceneParser)
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());
trpg2dPoint 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;
}

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
************************
*/
@@ -36,13 +35,13 @@ TX_EXDECL class TX_CLDECL trpgMBR {
public:
trpgMBR(void);
~trpgMBR(void) { };
bool isValid() const;
void Reset();
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() const;
trpg3dPoint GetUR() 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;
@@ -59,10 +58,10 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadNode {
public:
virtual ~trpgReadNode() { };
virtual bool isGroupType() = 0;
virtual int GetType() { return type; }
virtual trpgMBR GetMBR() 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;
};
@@ -72,18 +71,18 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadGroupBase : public trpgReadNode {
public:
virtual ~trpgReadGroupBase();
virtual ~trpgReadGroupBase(void);
void AddChild(trpgReadNode *);
bool isGroupType() { return true; }
int GetNumChildren() { return children.size(); }
bool isGroupType(void) { return true; }
int GetNumChildren(void) { return children.size(); }
trpgReadNode *GetChild(int i) { return children[i]; }
trpgMBR GetMBR() const;
trpgMBR GetMBR(void) const;
void unRefChild(int i);
void unRefChildren();
void unRefChildren(void);
protected:
trpgMBR mbr;
void DeleteChildren();
vector<trpgReadNode *> children;
void DeleteChildren(void);
std::vector<trpgReadNode *> children;
};
// Read Geometry
@@ -91,11 +90,11 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadGeometry : public trpgReadNode {
public:
trpgReadGeometry() { type = TRPG_GEOMETRY; }
~trpgReadGeometry() { };
bool isGroupType() { return false; }
trpgGeometry *GetData() { return &data; }
trpgMBR GetMBR() 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;
@@ -106,11 +105,11 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadTileHeader : public trpgReadNode {
public:
trpgReadTileHeader() { type = TRPGTILEHEADER; }
~trpgReadTileHeader() { };
bool isGroupType() { return false; }
trpgTileHeader *GetData() { return &data; }
trpgMBR GetMBR() 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;
};
@@ -120,9 +119,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadGroup : public trpgReadGroupBase {
public:
trpgReadGroup() { type = TRPG_GROUP; }
~trpgReadGroup() { };
trpgGroup *GetData() { return &data; }
trpgReadGroup(void) { type = TRPG_GROUP; }
~trpgReadGroup(void) { };
trpgGroup *GetData(void) { return &data; }
protected:
trpgGroup data;
};
@@ -132,9 +131,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadAttach : public trpgReadGroupBase {
public:
trpgReadAttach() { type = TRPG_ATTACH; }
~trpgReadAttach() { };
trpgAttach *GetData() { return &data; }
trpgReadAttach(void) { type = TRPG_ATTACH; }
~trpgReadAttach(void) { };
trpgAttach *GetData(void) { return &data; }
protected:
trpgAttach data;
};
@@ -143,9 +142,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadBillboard : public trpgReadGroupBase {
public:
trpgReadBillboard() { type = TRPG_BILLBOARD; }
~trpgReadBillboard() { };
trpgBillboard *GetData() { return &data; }
trpgReadBillboard(void) { type = TRPG_BILLBOARD; }
~trpgReadBillboard(void) { };
trpgBillboard *GetData(void) { return &data; }
protected:
trpgBillboard data;
};
@@ -154,9 +153,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadLod : public trpgReadGroupBase {
public:
trpgReadLod() { type = TRPG_LOD; }
~trpgReadLod() { };
trpgLod *GetData() { return &data; }
trpgReadLod(void) { type = TRPG_LOD; }
~trpgReadLod(void) { };
trpgLod *GetData(void) { return &data; }
protected:
trpgLod data;
};
@@ -165,9 +164,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadLayer : public trpgReadGroupBase {
public:
trpgReadLayer() { type = TRPG_LAYER; }
~trpgReadLayer() { };
trpgLayer *GetData() { return &data; }
trpgReadLayer(void) { type = TRPG_LAYER; }
~trpgReadLayer(void) { };
trpgLayer *GetData(void) { return &data; }
protected:
trpgLayer data;
};
@@ -176,9 +175,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadTransform : public trpgReadGroupBase {
public:
trpgReadTransform() { type = TRPG_TRANSFORM; }
~trpgReadTransform() { };
trpgTransform *GetData() { return &data; }
trpgReadTransform(void) { type = TRPG_TRANSFORM; }
~trpgReadTransform(void) { };
trpgTransform *GetData(void) { return &data; }
protected:
trpgTransform data;
};
@@ -187,9 +186,9 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgReadModelRef : public trpgReadGroupBase {
public:
trpgReadModelRef() { type = TRPG_MODELREF; }
~trpgReadModelRef() { };
trpgModelRef *GetData() { return &data; }
trpgReadModelRef(void) { type = TRPG_MODELREF; }
~trpgReadModelRef(void) { };
trpgModelRef *GetData(void) { return &data; }
protected:
trpgModelRef data;
};
@@ -204,21 +203,21 @@ protected:
// {group:Demonstration Scene Graph}
TX_EXDECL class TX_CLDECL trpgSceneGraphParser : public trpgSceneParser {
public:
#if defined(_WIN32) && !defined(__GNUC__)
typedef map<int,trpgReadGroupBase *> GroupMap;
#if defined(_WIN32)
typedef std::map<int,trpgReadGroupBase *> GroupMap;
#else
typedef map<int,trpgReadGroupBase *,less<int> > GroupMap;
typedef std::map<int,trpgReadGroupBase *,less<int> > GroupMap;
#endif
trpgSceneGraphParser();
~trpgSceneGraphParser() { };
trpgSceneGraphParser(void);
virtual ~trpgSceneGraphParser(void) { };
// Call this instead of Parse()
// Deleting it is your responsibility
trpgReadNode *ParseScene(trpgReadBuffer &,GroupMap &);
trpgReadGroupBase *GetCurrTop(); // Get the current parent object
trpgReadTileHeader *GetTileHeaderRef();
trpgReadGroupBase *GetCurrTop(void); // Get the current parent object
trpgReadTileHeader *GetTileHeaderRef(void);
// For use by the helpers only
GroupMap *GetGroupMap();
GroupMap *GetGroupMap(void);
protected:
bool StartChildren(void *);
bool EndChildren(void *);

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
************************
*/
@@ -18,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 )
{
@@ -39,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 )
{
@@ -56,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 )
{
@@ -77,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 )
{
@@ -106,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 )
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)
{
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;
}

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
************************
*/
@@ -18,7 +17,7 @@
#define trpage_swap_h_
/* trpage_swap.h
Byte swapping utility functions.
Byte swapping utility functions.
*/
#include "trpage_sys.h"
@@ -30,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 );
int trpg_byteswap_int( int number );
// Byte swap and return a long
// {group:Byte Ordering Utilities}
long trpg_byteswap_long( long number );

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
************************
*/
@@ -21,7 +20,15 @@
#ifndef trpage_sys_h_
#define trpage_sys_h_
#if defined(_WIN32) && !defined(__CYGWIN__)
#ifndef PATHSEPERATOR
#ifdef macintosh
#define PATHSEPERATOR ":"
#else
#define PATHSEPERATOR "/"
#endif
#endif
#if defined(_WIN32)
/* *********************
System Specific Section.
This is currently set up for win32.
@@ -39,19 +46,10 @@
#define TRPGDELETEFILE(file) DeleteFile((file))
#ifndef int64
// 64 bit long value. Need this for really big files.
// #ifdef __CYGWIN__
// typedef long long int64;
// #else
typedef __int64 int64;
// #endif
// 64 bit long value. Need this for really big files.
typedef __int64 int64;
#endif
#ifdef __MINGW32__
#include <stdio.h>
#endif
#else // Unix
#include <stdio.h>
@@ -59,38 +57,8 @@
// Delete a file
#define TRPGDELETEFILE(file) remove((file))
//#ifndef int64
//typedef long long int64;
//#endif
#if defined(sgi) && defined(unix)
# include <sgidefs.h>
typedef __int64_t int64;
#elif defined(sun) && defined(unix) && (defined(SUN551) || defined(SUN56))
// NOTE: SUN56 and SUN551 is assumed to be defined in our makefiles.
#include <sys/types.h>
typedef longlong_t int64;
#elif defined(sun) && defined(unix)
// This should work on SunOS 5.7 and later.
#include <sys/types.h>
typedef int64_t int64;
#elif defined(linux)
#include <sys/types.h>
typedef int64_t int64;
//typedef long long int int64;
#elif defined(__ghs__) && defined(__LL_Is_64)
#ifndef int64
typedef long long int64;
#elif defined(__CYGWIN__)
typedef long long int64;
#include <windows.h>
#else
typedef int int64; // DON'T KNOW WHAT TO DO
#endif
#endif
@@ -118,27 +86,19 @@ typedef double float64;
#include <txRogueWave.h>
#endif
#if defined(WIN32) || defined(_WIN32) || defined(vxw) || (defined(sgi) && defined(_STANDARD_C_PLUS_PLUS)) || (defined(__GNUC__) && (__GNUC__>=2) && (__GNUC_MINOR__>=91))
#if defined(_WIN32)
#include <vector>
#include <map>
namespace std {}
using namespace std;
#else
#include <vector.h>
#include <map.h>
#endif
//#if defined(_WIN32)
//#include <vector>
//#include <map>
//#else
//#include <vector.h>
//#include <map.h>
//#endif
//#if defined(_WIN32) // PJM
//using namespace std;
//#endif
#if defined(_WIN32) // PJM
// Had to take this out because of an iostream conflict
// Now referencing everything by std::
// using namespace std;
#endif
// We use long longs for addresses within a paging file
typedef int64 trpgllong;

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();
}

File diff suppressed because it is too large Load Diff

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

View File

@@ -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,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"
@@ -40,152 +39,152 @@
// 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_long(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 *)&len);
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(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
@@ -193,94 +192,200 @@ 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);
}
/* 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);
}
/* 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.
*/
trpgwAppFile::trpgwAppFile(trpgEndian inNess,const char *fileName)
{
valid = false;
ness = inNess;
cpuNess = trpg_cpu_byte_order();
if (!(fp = fopen(fileName,"wb")))
return;
lengthSoFar = 0;
valid = true;
}
trpgwAppFile::~trpgwAppFile()
{
if (fp)
fclose(fp);
valid = false;
}
// Return the amount of data written so far (in total)
int trpgwAppFile::GetLengthWritten()
{
return lengthSoFar;
}
// Append the given buffer to our appendable file
bool trpgwAppFile::Append(const trpgMemWriteBuffer *buf1,const trpgMemWriteBuffer *buf2)
{
if (!isValid()) return false;
// 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 data out
const char *data = buf1->getData();
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;
return true;
}
// Append the given raw data to our appendable file
bool trpgwAppFile::Append(const char *data,int size)
{
if (!isValid()) 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) != size) {
valid = false;
return false;
}
lengthSoFar += size;
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);
return pos;
}
// Validity check
bool trpgwAppFile::isValid() const
{
return valid;
}