TXP plugin update from Boris Bralo.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
************************
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user