email comments from Andew Sampson, "I've contacted Terrex, and obtained the 2.2 version of their trpage library. The library included a fork of OSG 0.9.8's txp plugin, modified to load 2.1+ txp DBs. I've done the work of incorporating the changes made to OSG's txp plugin since 0.9.8 into Terrex's fork. The forked version is now up-to-date with the changes made to OSG 0.9.9 and 1.0. Terrex made a lot of changes (especially differences in whitespace), so the diff between the forked version and OSG 1.0's txp plugin is yucky. I did my best, but keep in mind that this is the result of a 4-way merge (kinda... terrex-0.9.8, stock-0.9.8, stock-0.9.9, stock-1.0). I really want to see this forked version merged back into the main OSG branch. The new features offered by this version of the plugin (2.1+ support, variable LOD support, bug fixes) are worth the trouble." -- Don Tidrow then took this code and added his work. -- Robert Osfield then fixed all the warnings that abound in the trpage code base.
944 lines
15 KiB
C++
944 lines
15 KiB
C++
/* ************************
|
|
Copyright Terrain Experts Inc.
|
|
Terrain Experts Inc (TERREX) reserves all rights to this source code
|
|
unless otherwise specified in writing by the President of TERREX.
|
|
This copyright may be updated in the future, in which case that version
|
|
supercedes this one.
|
|
-------------------
|
|
Terrex Experts Inc.
|
|
4400 East Broadway #314
|
|
Tucson, AZ 85711
|
|
info@terrex.com
|
|
Tel: (520) 323-7990
|
|
************************
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
/* trpage_nodes.cpp
|
|
The methods for all the hierarchy nodes (e.g. groups, transforms, etc...)
|
|
is here.
|
|
You should only need to modify this if you want to add something to one
|
|
of these classes.
|
|
*/
|
|
|
|
#include <trpage_geom.h>
|
|
#include <trpage_read.h>
|
|
|
|
/* Write Group
|
|
Basic group.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgGroup::trpgGroup()
|
|
{
|
|
name = 0;
|
|
Reset();
|
|
|
|
}
|
|
trpgGroup::~trpgGroup()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Reset
|
|
void trpgGroup::Reset()
|
|
{
|
|
numChild = 0;
|
|
id = -1;
|
|
if ( name ) {
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
}
|
|
|
|
// Set functions
|
|
void trpgGroup::SetNumChild(int no)
|
|
{
|
|
numChild = no;
|
|
}
|
|
int trpgGroup::AddChild()
|
|
{
|
|
numChild++;
|
|
return numChild-1;
|
|
}
|
|
void trpgGroup::SetID(int inID)
|
|
{
|
|
id = inID;
|
|
}
|
|
|
|
void trpgGroup::SetName(const char* newname )
|
|
{
|
|
if ( name )
|
|
{
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
if (newname)
|
|
{
|
|
if ( strlen(newname) )
|
|
{
|
|
name = new char[strlen(newname)+1];
|
|
strcpy(name,newname);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get methods
|
|
const char* trpgGroup::GetName(void) const
|
|
{
|
|
return name;
|
|
}
|
|
|
|
bool trpgGroup::GetNumChild(int &n) const
|
|
{
|
|
if (!isValid()) return false;
|
|
n = numChild;
|
|
return true;
|
|
}
|
|
bool trpgGroup::GetID(int &inID) const
|
|
{
|
|
if (!isValid()) return false;
|
|
inID = id;
|
|
return true;
|
|
}
|
|
|
|
// Validity check
|
|
bool trpgGroup::isValid() const
|
|
{
|
|
if (numChild <= 0) return false;
|
|
if (id < 0) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Write group
|
|
bool trpgGroup::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid())
|
|
return false;
|
|
|
|
buf.Begin(TRPG_GROUP);
|
|
buf.Add(numChild);
|
|
buf.Add(id);
|
|
|
|
if ( name && strlen(name) ) {
|
|
buf.Add(name);
|
|
}
|
|
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read group
|
|
bool trpgGroup::Read(trpgReadBuffer &buf)
|
|
{
|
|
try {
|
|
buf.Get(numChild);
|
|
if (numChild < 0) throw 1;
|
|
buf.Get(id);
|
|
if (id < 0) throw 1;
|
|
if ( !buf.isEmpty() ) {
|
|
char nm[1024] = {0};
|
|
buf.Get(nm,1024);
|
|
SetName(nm);
|
|
}
|
|
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
return isValid();
|
|
}
|
|
|
|
/* Write Billboard
|
|
Represents rotational billboarded geometry.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgBillboard::trpgBillboard()
|
|
{
|
|
name = 0;
|
|
Reset();
|
|
}
|
|
trpgBillboard::~trpgBillboard()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Reset function
|
|
void trpgBillboard::Reset()
|
|
{
|
|
id = -1;
|
|
mode = Axial;
|
|
type = Group;
|
|
axis = trpg3dPoint(0,0,1);
|
|
center = trpg3dPoint(0,0,0);
|
|
numChild = 0;
|
|
if ( name )
|
|
{
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
}
|
|
|
|
// Set functions
|
|
void trpgBillboard::SetCenter(const trpg3dPoint &pt)
|
|
{
|
|
center = pt;
|
|
valid = true;
|
|
}
|
|
void trpgBillboard::SetMode(int m)
|
|
{
|
|
mode = m;
|
|
}
|
|
void trpgBillboard::SetAxis(const trpg3dPoint &pt)
|
|
{
|
|
axis = pt;
|
|
}
|
|
void trpgBillboard::SetType(int t)
|
|
{
|
|
type = t;
|
|
}
|
|
|
|
// Get methods
|
|
bool trpgBillboard::GetCenter(trpg3dPoint &pt) const
|
|
{
|
|
if (!isValid()) return false;
|
|
pt = center;
|
|
return true;
|
|
}
|
|
bool trpgBillboard::GetMode(int &m) const
|
|
{
|
|
if (!isValid()) return false;
|
|
m = mode;
|
|
return true;
|
|
}
|
|
bool trpgBillboard::GetAxis(trpg3dPoint &pt) const
|
|
{
|
|
if (!isValid()) return false;
|
|
pt = axis;
|
|
return true;
|
|
}
|
|
bool trpgBillboard::GetType(int &t) const
|
|
{
|
|
if (!isValid()) return false;
|
|
t = type;
|
|
return true;
|
|
}
|
|
|
|
// Write billboard
|
|
bool trpgBillboard::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid())
|
|
return false;
|
|
|
|
buf.Begin(TRPG_BILLBOARD);
|
|
buf.Add(numChild);
|
|
buf.Add(id);
|
|
buf.Add((uint8)type);
|
|
buf.Add((uint8)mode);
|
|
buf.Add(center);
|
|
buf.Add(axis);
|
|
|
|
if ( name && strlen(name) ) {
|
|
buf.Add(name);
|
|
}
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read billboard
|
|
bool trpgBillboard::Read(trpgReadBuffer &buf)
|
|
{
|
|
uint8 uChar;
|
|
|
|
try {
|
|
buf.Get(numChild);
|
|
buf.Get(id);
|
|
buf.Get(uChar); type = uChar;
|
|
buf.Get(uChar); mode = uChar;
|
|
buf.Get(center);
|
|
buf.Get(axis);
|
|
if ( !buf.isEmpty() ) {
|
|
char nm[1024] = {0};
|
|
buf.Get(nm,1024);
|
|
SetName(nm);
|
|
}
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
return isValid();
|
|
}
|
|
|
|
/* Write Level of Detail
|
|
Represents LOD information.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgLod::trpgLod()
|
|
{
|
|
name = 0;
|
|
Reset();
|
|
}
|
|
trpgLod::~trpgLod()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Reset function
|
|
void trpgLod::Reset()
|
|
{
|
|
id = -1;
|
|
numRange = 0;
|
|
center = trpg3dPoint(0,0,0);
|
|
switchIn = switchOut = width = 0;
|
|
rangeIndex = -1;
|
|
valid = true;
|
|
if ( name ) {
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
}
|
|
|
|
// Set functions
|
|
void trpgLod::SetCenter(const trpg3dPoint &pt)
|
|
{
|
|
center = pt;
|
|
valid = true;
|
|
}
|
|
void trpgLod::SetNumChild(int no)
|
|
{
|
|
if (no < 0)
|
|
return;
|
|
|
|
numRange = no;
|
|
}
|
|
void trpgLod::SetLOD(double in,double out,double wid)
|
|
{
|
|
switchIn = in;
|
|
switchOut = out;
|
|
width = wid;
|
|
}
|
|
void trpgLod::SetID(int inID)
|
|
{
|
|
id = inID;
|
|
}
|
|
|
|
void trpgLod::SetName(const char* newname )
|
|
{
|
|
if ( name ) {
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
if (newname) {
|
|
if ( strlen(newname) ) {
|
|
name = new char[strlen(newname)+1];
|
|
strcpy(name,newname);
|
|
}
|
|
}
|
|
}
|
|
|
|
void trpgLod::SetRangeIndex(int ri)
|
|
{
|
|
rangeIndex = ri;
|
|
}
|
|
|
|
// Get methods
|
|
const char* trpgLod::GetName(void) const
|
|
{
|
|
return name;
|
|
}
|
|
|
|
// Get functions
|
|
bool trpgLod::GetCenter(trpg3dPoint &pt) const
|
|
{
|
|
if (!isValid()) return false;
|
|
pt = center;
|
|
return true;
|
|
}
|
|
bool trpgLod::GetNumChild(int &n) const
|
|
{
|
|
if (!isValid()) return false;
|
|
n = numRange;
|
|
return true;
|
|
}
|
|
bool trpgLod::GetLOD(double &in,double &out,double &wid) const
|
|
{
|
|
if (!isValid()) return false;
|
|
in = switchIn;
|
|
out = switchOut;
|
|
wid = width;
|
|
return true;
|
|
}
|
|
bool trpgLod::GetID(int &outID) const
|
|
{
|
|
if (!isValid()) return false;
|
|
outID = id;
|
|
return true;
|
|
}
|
|
bool trpgLod::GetRangeIndex(int &ri) const
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
ri = rangeIndex;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Write out LOD
|
|
bool trpgLod::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid())
|
|
return false;
|
|
|
|
buf.Begin(TRPG_LOD);
|
|
buf.Add(id);
|
|
buf.Add(numRange);
|
|
buf.Add(center);
|
|
buf.Add(switchIn);
|
|
buf.Add(switchOut);
|
|
buf.Add(width);
|
|
|
|
if ( name && strlen(name) ) {
|
|
buf.Add(name);
|
|
} else
|
|
buf.Add("");
|
|
|
|
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read in LOD
|
|
bool trpgLod::Read(trpgReadBuffer &buf)
|
|
{
|
|
try {
|
|
buf.Get(id);
|
|
buf.Get(numRange);
|
|
if (numRange < 0) throw 1;
|
|
buf.Get(center);
|
|
buf.Get(switchIn);
|
|
buf.Get(switchOut);
|
|
buf.Get(width);
|
|
if ( !buf.isEmpty() ) {
|
|
char nm[1024] = {0};
|
|
buf.Get(nm,1024);
|
|
if (*nm)
|
|
SetName(nm);
|
|
// Look for a range index
|
|
if (!buf.isEmpty())
|
|
buf.Get(rangeIndex);
|
|
}
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
return isValid();
|
|
}
|
|
|
|
/* Write Layer
|
|
A layer is just a group with a different opcode.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgLayer::trpgLayer()
|
|
{
|
|
name = 0;
|
|
}
|
|
|
|
trpgLayer::~trpgLayer()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Write it
|
|
bool trpgLayer::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid())
|
|
return false;
|
|
|
|
buf.Begin(TRPG_LAYER);
|
|
buf.Add(numChild);
|
|
buf.Add(id);
|
|
|
|
if ( name && strlen(name) ) {
|
|
buf.Add(name);
|
|
}
|
|
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read layer
|
|
bool trpgLayer::Read(trpgReadBuffer &buf)
|
|
{
|
|
try {
|
|
buf.Get(numChild);
|
|
if (numChild < 0) throw 1;
|
|
buf.Get(id);
|
|
if (id < 0) throw 1;
|
|
if ( !buf.isEmpty() ) {
|
|
char nm[1024] = {0};
|
|
buf.Get(nm,1024);
|
|
SetName(nm);
|
|
}
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
return isValid();
|
|
}
|
|
|
|
// Reset function
|
|
void trpgLayer::Reset()
|
|
{
|
|
numChild = 0;
|
|
if ( name ) {
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
}
|
|
|
|
/* Write Transform
|
|
Matrix defining the transform with children.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgTransform::trpgTransform()
|
|
{
|
|
name = 0;
|
|
Reset();
|
|
}
|
|
trpgTransform::~trpgTransform()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Reset function
|
|
void trpgTransform::Reset()
|
|
{
|
|
id = -1;
|
|
// Note: Is this row major or column major?
|
|
m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
|
|
m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
|
|
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
|
|
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
|
|
|
|
if ( name ) {
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
}
|
|
|
|
// Set functions
|
|
void trpgTransform::SetMatrix(const float64 *im)
|
|
{
|
|
m[0][0] = im[4*0+0]; m[0][1] = im[4*0+1]; m[0][2] = im[4*0+2]; m[0][3] = im[4*0+3];
|
|
m[1][0] = im[4*1+0]; m[1][1] = im[4*1+1]; m[1][2] = im[4*1+2]; m[1][3] = im[4*1+3];
|
|
m[2][0] = im[4*2+0]; m[2][1] = im[4*2+1]; m[2][2] = im[4*2+2]; m[2][3] = im[4*2+3];
|
|
m[3][0] = im[4*3+0]; m[3][1] = im[4*3+1]; m[3][2] = im[4*3+2]; m[3][3] = im[4*3+3];
|
|
}
|
|
|
|
// Get methods
|
|
bool trpgTransform::GetMatrix(float64 *rm) const
|
|
{
|
|
if (!isValid()) return false;
|
|
for (int i=0;i<4;i++)
|
|
for (int j=0;j<4;j++)
|
|
// Note: is this right?
|
|
rm[i*4+j] = m[i][j];
|
|
return true;
|
|
}
|
|
|
|
// Write transform
|
|
bool trpgTransform::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid())
|
|
return false;
|
|
|
|
buf.Begin(TRPG_TRANSFORM);
|
|
buf.Add(numChild);
|
|
buf.Add(id);
|
|
for (int i=0;i<4;i++)
|
|
for (int j=0;j<4;j++)
|
|
buf.Add(m[i][j]);
|
|
|
|
if ( name && strlen(name) ) {
|
|
buf.Add(name);
|
|
}
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read transform
|
|
bool trpgTransform::Read(trpgReadBuffer &buf)
|
|
{
|
|
try {
|
|
buf.Get(numChild);
|
|
buf.Get(id);
|
|
if (numChild < 0) throw 1;
|
|
for (int i=0;i<4;i++)
|
|
for (int j=0;j<4;j++)
|
|
buf.Get(m[i][j]);
|
|
if ( !buf.isEmpty() ) {
|
|
char nm[1024] = {0};
|
|
buf.Get(nm,1024);
|
|
SetName(nm);
|
|
}
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
return isValid();
|
|
}
|
|
|
|
/* Model Reference
|
|
This is just a matrix transform and a model ID.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgModelRef::trpgModelRef()
|
|
{
|
|
Reset();
|
|
}
|
|
trpgModelRef::~trpgModelRef()
|
|
{
|
|
}
|
|
|
|
// Reset function
|
|
void trpgModelRef::Reset()
|
|
{
|
|
m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
|
|
m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
|
|
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
|
|
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
|
|
modelRef = -1;
|
|
}
|
|
|
|
// Set functions
|
|
void trpgModelRef::SetModel(int id)
|
|
{
|
|
modelRef = id;
|
|
valid = true;
|
|
}
|
|
void trpgModelRef::SetMatrix(const float64 *im)
|
|
{
|
|
m[0][0] = im[4*0+0]; m[0][1] = im[4*0+1]; m[0][2] = im[4*0+2]; m[0][3] = im[4*0+3];
|
|
m[1][0] = im[4*1+0]; m[1][1] = im[4*1+1]; m[1][2] = im[4*1+2]; m[1][3] = im[4*1+3];
|
|
m[2][0] = im[4*2+0]; m[2][1] = im[4*2+1]; m[2][2] = im[4*2+2]; m[2][3] = im[4*2+3];
|
|
m[3][0] = im[4*3+0]; m[3][1] = im[4*3+1]; m[3][2] = im[4*3+2]; m[3][3] = im[4*3+3];
|
|
}
|
|
|
|
// Get methods
|
|
bool trpgModelRef::GetModel(int32 &mod) const
|
|
{
|
|
if (!isValid()) return false;
|
|
mod = modelRef;
|
|
return true;
|
|
}
|
|
bool trpgModelRef::GetMatrix(float64 *rm) const
|
|
{
|
|
if (!isValid()) return false;
|
|
for (int i=0;i<4;i++)
|
|
for (int j=0;j<4;j++)
|
|
// Note: is this right?
|
|
rm[i*4+j] = m[i][j];
|
|
return true;
|
|
}
|
|
|
|
// Write model reference
|
|
bool trpgModelRef::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid())
|
|
return false;
|
|
|
|
buf.Begin(TRPG_MODELREF);
|
|
buf.Add(modelRef);
|
|
for (int i=0;i<4;i++)
|
|
for (int j=0;j<4;j++)
|
|
buf.Add(m[i][j]);
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read model reference
|
|
bool trpgModelRef::Read(trpgReadBuffer &buf)
|
|
{
|
|
try {
|
|
buf.Get(modelRef);
|
|
if (modelRef < 0)
|
|
throw 1;
|
|
for (int i=0;i<4;i++)
|
|
for (int j=0;j<4;j++)
|
|
buf.Get(m[i][j]);
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
valid = true;
|
|
return isValid();
|
|
}
|
|
|
|
/* Attach Node
|
|
You'll find one of these in each tile, except for the lowest LOD.
|
|
It's basically a group with some extra info that tells you where to attach it.
|
|
The ID corresponds to the one in Group and LOD.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgAttach::trpgAttach()
|
|
{
|
|
name = 0;
|
|
Reset();
|
|
}
|
|
trpgAttach::~trpgAttach()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Reset
|
|
void trpgAttach::Reset()
|
|
{
|
|
parentID = -1;
|
|
childPos = -1;
|
|
if ( name ) {
|
|
delete [] name;
|
|
name = 0;
|
|
}
|
|
}
|
|
|
|
// Parent ID is the node this one gets attached to
|
|
void trpgAttach::SetParentID(int id)
|
|
{
|
|
parentID = id;
|
|
}
|
|
bool trpgAttach::GetParentID(int &id) const
|
|
{
|
|
if (!isValid()) return false;
|
|
id = parentID;
|
|
return true;
|
|
}
|
|
|
|
// Child Position is a unique number of parent
|
|
// It could be used as an array index, for example
|
|
void trpgAttach::SetChildPos(int id)
|
|
{
|
|
childPos = id;
|
|
}
|
|
bool trpgAttach::GetChildPos(int &id) const
|
|
{
|
|
if (!isValid()) return false;
|
|
id = childPos;
|
|
return true;
|
|
}
|
|
|
|
// Validity check
|
|
bool trpgAttach::isValid() const
|
|
{
|
|
if (parentID < 0 || childPos < 0) return false;
|
|
return true;
|
|
}
|
|
|
|
// Write Attach node
|
|
bool trpgAttach::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
buf.Begin(TRPG_ATTACH);
|
|
buf.Add(numChild);
|
|
buf.Add(id);
|
|
buf.Add(parentID);
|
|
buf.Add(childPos);
|
|
|
|
if ( name && strlen(name) ) {
|
|
buf.Add(name);
|
|
}
|
|
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read Attach node
|
|
bool trpgAttach::Read(trpgReadBuffer &buf)
|
|
{
|
|
try {
|
|
buf.Get(numChild);
|
|
buf.Get(id);
|
|
if (id < 0) throw 1;
|
|
buf.Get(parentID);
|
|
if (parentID < 0) throw 1;
|
|
buf.Get(childPos);
|
|
if (childPos < 0) throw 1;
|
|
if ( !buf.isEmpty() ) {
|
|
char nm[1024] = {0};
|
|
buf.Get(nm,1024);
|
|
SetName(nm);
|
|
}
|
|
}
|
|
catch (...) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* ChildRef Node
|
|
You'll find in the parent tile one of these for each tile children.
|
|
It gives the children grid location and file address.
|
|
*/
|
|
|
|
// Constructor
|
|
trpgChildRef::trpgChildRef()
|
|
{
|
|
Reset();
|
|
}
|
|
trpgChildRef::~trpgChildRef()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// Reset
|
|
void trpgChildRef::Reset()
|
|
{
|
|
x = -1;
|
|
y = -1;
|
|
lod = -1;
|
|
addr.file = -1;
|
|
addr.offset = -1;
|
|
}
|
|
|
|
void trpgChildRef::SetTileLoc(int gx,int gy,int glod)
|
|
{
|
|
x = gx;
|
|
y = gy;
|
|
lod = glod;
|
|
}
|
|
|
|
bool trpgChildRef::GetTileLoc(int &gx,int &gy,int &glod) const
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
gx = x;
|
|
gy = y;
|
|
glod = lod;
|
|
|
|
return true;
|
|
}
|
|
|
|
void trpgChildRef::SetTileAddress(const trpgwAppAddress& gAddr)
|
|
{
|
|
addr = gAddr;
|
|
}
|
|
void trpgChildRef::SetTileAddress(int32 file, int32 offset)
|
|
{
|
|
addr.file = file;
|
|
addr.offset = offset;
|
|
}
|
|
bool trpgChildRef::GetTileAddress(int32& file, int32& offset) const
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
file = addr.file;
|
|
offset = addr.offset;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool trpgChildRef::GetTileAddress(trpgwAppAddress& gAddr) const
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
gAddr = addr;
|
|
|
|
return true;
|
|
}
|
|
|
|
void trpgChildRef::SetTileZValue( float gZmin, float gZmax)
|
|
{
|
|
zmin = gZmin;
|
|
zmax = gZmax;
|
|
}
|
|
|
|
bool trpgChildRef::GetTileZValue( float& gZmin, float& gZmax) const
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
gZmin = zmin;
|
|
gZmax = zmax;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Validity check
|
|
bool trpgChildRef::isValid() const
|
|
{
|
|
if (lod < 0)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
|
|
// Write Attach node
|
|
bool trpgChildRef::Write(trpgWriteBuffer &buf)
|
|
{
|
|
if (!isValid()) return false;
|
|
|
|
buf.Begin(TRPG_CHILDREF);
|
|
|
|
buf.Add(lod);
|
|
buf.Add(x);
|
|
buf.Add(y);
|
|
buf.Add(addr.file);
|
|
buf.Add(addr.offset);
|
|
buf.Add(zmin);
|
|
buf.Add(zmax);
|
|
|
|
buf.End();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Read Attach node
|
|
bool trpgChildRef::Read(trpgReadBuffer &buf)
|
|
{
|
|
try
|
|
{
|
|
|
|
buf.Get(lod);
|
|
if (lod < 0) throw 1;
|
|
buf.Get(x);
|
|
buf.Get(y);
|
|
buf.Get(addr.file);
|
|
buf.Get(addr.offset);
|
|
buf.Get(zmin);
|
|
buf.Get(zmax);
|
|
|
|
}
|
|
catch (...)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|