diff --git a/VisualStudio/osgPlugins/txp/txp.dsp b/VisualStudio/osgPlugins/txp/txp.dsp index 24304e6c8..64e176685 100644 --- a/VisualStudio/osgPlugins/txp/txp.dsp +++ b/VisualStudio/osgPlugins/txp/txp.dsp @@ -122,6 +122,10 @@ SOURCE=..\..\..\src\osgPlugins\txp\trpage_header.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\txp\trpage_label.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\txp\trpage_light.cpp # End Source File # Begin Source File @@ -134,6 +138,10 @@ SOURCE=..\..\..\src\osgPlugins\txp\trpage_material.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\txp\trpage_main.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\txp\trpage_model.cpp # End Source File # Begin Source File diff --git a/src/osgPlugins/txp/GNUmakefile b/src/osgPlugins/txp/GNUmakefile index 7d3f30e7c..2b59c6ace 100644 --- a/src/osgPlugins/txp/GNUmakefile +++ b/src/osgPlugins/txp/GNUmakefile @@ -2,38 +2,40 @@ TOPDIR = ../../.. include $(TOPDIR)/Make/makedefs CXXFILES =\ - ReaderWriterTXP.cpp\ - TerrapageNode.cpp\ - IO_TerrapageNode.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\ - trpage_managers.cpp\ - trPagePageManager.cpp\ - trpage_print_parse.cpp\ - trpage_util.cpp\ + IO_TerrapageNode.cpp\ + ReaderWriterTXP.cpp\ + TerrapageNode.cpp\ + TrPageArchive.cpp\ + TrPageParser.cpp\ + trPagePageManager.cpp\ + trpage_basic.cpp\ + trpage_compat.cpp\ + trpage_geom.cpp\ + trpage_header.cpp\ + trpage_label.cpp\ + trpage_light.cpp\ + trpage_main.cpp\ + trpage_managers.cpp\ + trpage_material.cpp\ + trpage_model.cpp\ + trpage_nodes.cpp\ + trpage_parse.cpp\ + trpage_pparse.cpp\ + trpage_print.cpp\ + trpage_print_parse.cpp\ + trpage_range.cpp\ + trpage_rarchive.cpp\ + trpage_readbuf.cpp\ + trpage_scene.cpp\ + trpage_swap.cpp\ + trpage_tile.cpp\ + trpage_util.cpp\ + trpage_warchive.cpp\ + trpage_writebuf.cpp\ -INC += -I$(THISDIR) +INC += -I$(THISDIR) LIBS += $(OSG_LIBS) $(OTHER_LIBS) diff --git a/src/osgPlugins/txp/ReaderWriterTXP.cpp b/src/osgPlugins/txp/ReaderWriterTXP.cpp index 811fb8359..d462cfa7c 100644 --- a/src/osgPlugins/txp/ReaderWriterTXP.cpp +++ b/src/osgPlugins/txp/ReaderWriterTXP.cpp @@ -1,3 +1,4 @@ +#include "ReaderWriterTXP.h" #include #include #include @@ -8,7 +9,6 @@ #include -#include "ReaderWriterTXP.h" #include "TrPageArchive.h" #include "TerrapageNode.h" diff --git a/src/osgPlugins/txp/TerrapageNode.cpp b/src/osgPlugins/txp/TerrapageNode.cpp index bbe8886b1..2ccc7bed3 100644 --- a/src/osgPlugins/txp/TerrapageNode.cpp +++ b/src/osgPlugins/txp/TerrapageNode.cpp @@ -1,5 +1,4 @@ #include "TerrapageNode.h" - #include using namespace osg; @@ -28,7 +27,6 @@ TerrapageNode::~TerrapageNode() { // will the page manger delete the archive? delete _pageManager; - _pageManager = 0L; } void TerrapageNode::traverse(osg::NodeVisitor& nv) @@ -121,7 +119,6 @@ bool TerrapageNode::loadDatabase() addChild(node); } else { - _pageManager = new OSGPageManager(txpArchive); if (threadMode!=OSGPageManager::ThreadNone) diff --git a/src/osgPlugins/txp/TerrapageNode.h b/src/osgPlugins/txp/TerrapageNode.h index 9d726b149..0490b34c9 100644 --- a/src/osgPlugins/txp/TerrapageNode.h +++ b/src/osgPlugins/txp/TerrapageNode.h @@ -3,10 +3,11 @@ #ifndef TERRAPAGENODE_H #define TERRAPAGENODE_H +#include "trPagePageManager.h" + #include #include -#include "trPagePageManager.h" namespace txp { diff --git a/src/osgPlugins/txp/TrPageArchive.cpp b/src/osgPlugins/txp/TrPageArchive.cpp index 3980f60b9..d80f7d85c 100644 --- a/src/osgPlugins/txp/TrPageArchive.cpp +++ b/src/osgPlugins/txp/TrPageArchive.cpp @@ -155,20 +155,25 @@ void TrPageArchive::LoadMaterials() path += _PATHD ; std::string theFile = path + filename ; - ref_ptr image = osgDB::readImageFile(theFile); - if (image.valid()) + Image* image = osgDB::readImageFile(theFile); + if (image) { - osg_texture->setImage(image.get()); + osg_texture->setImage(image); } + else + { + notify(WARN) << "TrPageArchive::LoadMaterials() error: " + << "couldn't open image: " << filename << std::endl; + } m_textures[i] = osg_texture; } else if( mode == trpgTexture::Local ) { - m_textures[i] = GetLocalTexture(image_helper,0, tex); + m_textures[i] = GetLocalTexture(image_helper,tex); } else if( mode == trpgTexture::Template ) { - m_textures[i] = GetLocalTexture(image_helper,0, tex); + m_textures[i] = 0L; //GetTemplateTexture(image_helper,0, tex); } else { @@ -436,7 +441,7 @@ Group* TrPageArchive::LoadTile(Group *rootNode, { int x,y,lod; tile->GetTileLoc(x,y,lod); - std::vector *groupList = parse->GetGroupList(); + std::vector *groupList = parse->GetGroupList(); // Fetch the tile data (but don't parse it) if (!ReadTile(x,y,lod,buf)) @@ -497,6 +502,7 @@ Group* TrPageArchive::LoadAllTiles() int32 numLod; head->GetNumLods(numLod); + // Iterate over the LODs. Lower res LODs must be loaded // first, otherwise there's nothing to hook the higher res // LODs into. @@ -504,7 +510,7 @@ Group* TrPageArchive::LoadAllTiles() // The group list is used to map parent IDs to pfGroup nodes //std::vector groupList; - std::vector *groupList = parse->GetGroupList(); + std::vector *groupList = parse->GetGroupList(); for (int nl=0;nl parse; diff --git a/src/osgPlugins/txp/TrPageParser.cpp b/src/osgPlugins/txp/TrPageParser.cpp index d34b596d7..e6cf2a753 100644 --- a/src/osgPlugins/txp/TrPageParser.cpp +++ b/src/osgPlugins/txp/TrPageParser.cpp @@ -20,6 +20,7 @@ * *****************************************************************************/ #include "trpage_sys.h" + #include #include #include @@ -33,15 +34,11 @@ #include #include #include - +#include #include "TrPageParser.h" #include "TrPageArchive.h" -/* -#include -#include -#include -*/ + #include using namespace txp; @@ -49,7 +46,86 @@ using namespace osg; using std::vector; using std::string; -Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMaterial* locmat, const trpgTexture* tex) +//---------------------------------------------------------------------------- +// Check if the node is billboard +namespace { + bool is_billboard (Node* node) + { + if (node && (node!=(Node*)1) && (strcmp(node->className(),"GeodeGroup") == 0)) + { + GeodeGroup* group = static_cast(node); + return (group->getNumChildren() && (strcmp(group->getChild(0)->className(),"Billboard") == 0)); + } + return false; + }; + + void check_format(trpgTexture::ImageType type, int depth, GLenum& internalFormat, GLenum& pixelFormat, GLenum&) + { + switch(type) + { + case trpgTexture::trpg_RGB8: + internalFormat = GL_RGB; + pixelFormat = GL_RGB; + break; + case trpgTexture::trpg_RGBA8: + internalFormat = GL_RGBA; + pixelFormat = GL_RGBA; + break; + case trpgTexture::trpg_INT8: + internalFormat = GL_LUMINANCE; + pixelFormat = GL_LUMINANCE; + break; + case trpgTexture::trpg_INTA8: + internalFormat = GL_LUMINANCE_ALPHA; + pixelFormat = GL_LUMINANCE_ALPHA; + break; + case trpgTexture::trpg_FXT1: + case trpgTexture::trpg_Filler: + case trpgTexture::trpg_RGBX: // MCM + case trpgTexture::trpg_Unknown: + break; + case trpgTexture::trpg_DDS: + case trpgTexture::trpg_DXT1: + if(depth == 3) + { + internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + pixelFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + } + else + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + } + break; + case trpgTexture::trpg_DXT3: + if(depth == 3) + { + // not supported. + } + else + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + } + break; + case trpgTexture::trpg_DXT5: + if(depth == 3) + { + // not supported. + } + else + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } + break; + } + } +} + +//---------------------------------------------------------------------------- +// Get a template texture via the image helper +Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, const trpgTexture* tex) { Texture2D* osg_texture= 0L; @@ -64,65 +140,7 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria GLenum pixelFormat = (GLenum)-1; GLenum dataType = GL_UNSIGNED_BYTE; - switch(type) - { - case trpgTexture::trpg_RGB8: - internalFormat = GL_RGB; - pixelFormat = GL_RGB; - break; - case trpgTexture::trpg_RGBA8: - internalFormat = GL_RGBA; - pixelFormat = GL_RGBA; - break; - case trpgTexture::trpg_INT8: - internalFormat = GL_LUMINANCE; - pixelFormat = GL_LUMINANCE; - break; - case trpgTexture::trpg_INTA8: - internalFormat = GL_LUMINANCE_ALPHA; - pixelFormat = GL_LUMINANCE_ALPHA; - break; - case trpgTexture::trpg_FXT1: - case trpgTexture::trpg_Filler: - case trpgTexture::trpg_RGBX: // MCM - case trpgTexture::trpg_Unknown: - case trpgTexture::trpg_DDS: - break; - case trpgTexture::trpg_DXT1: - if(depth == 3) - { - internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - pixelFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - } - else - { - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - } - break; - case trpgTexture::trpg_DXT3: - if(depth == 3) - { - // not supported. - } - else - { - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - } - break; - case trpgTexture::trpg_DXT5: - if(depth == 3) - { - // not supported. - } - else - { - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - break; - } + check_format(type,depth,internalFormat , pixelFormat , dataType); if(pixelFormat!=(GLenum)-1) { @@ -141,11 +159,76 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria int32 size = s.x*s.y*depth; // int32 size = const_cast(tex)->MipLevelSize(1) ; data = new char [size]; + image_helper.GetLocalGL(tex,data,size); + image->setImage(s.x,s.y,1,internalFormat, pixelFormat, dataType, + (unsigned char*)data,osg::Image::USE_NEW_DELETE); + } + else + { + int32 size = tex->CalcTotalSize(); + trpgTexture* tmp_tex = const_cast(tex); - if(locmat) - image_helper.GetImageForLocalMat(locmat,data,size); - else - image_helper.GetLocalGL(tex,data,size); + data = new char [size]; + image_helper.GetLocalGL(tex,data,size); + // Load entire texture including mipmaps + image->setImage(s.x,s.y,1,internalFormat, pixelFormat, dataType, + (unsigned char*)data, + osg::Image::USE_NEW_DELETE); + + // now set mipmap data (offsets into image raw data) + Image::MipmapDataType mipmaps; + // number of offsets in osg is one less than num_mipmaps + // because it's assumed that first offset iz 0 + mipmaps.resize(num_mipmaps-1); + for( int k = 1 ; k < num_mipmaps;k++ ) + { + mipmaps[k-1] = tmp_tex->MipLevelOffset(k); + } + image->setMipmapData(mipmaps); + + } + + osg_texture->setImage(image); + } + return osg_texture; +} +//---------------------------------------------------------------------------- +// Get a locale texture via the image helper +Texture2D* txp::GetTemplateTexture(trpgrImageHelper& image_helper, trpgLocalMaterial* locmat, const trpgTexture* tex, int index) +{ + Texture2D* osg_texture= 0L; + + trpg2iPoint s; + tex->GetImageSize(s); + int32 depth; + tex->GetImageDepth(depth); + trpgTexture::ImageType type; + tex->GetImageType(type); + + GLenum internalFormat = (GLenum)-1; + GLenum pixelFormat = (GLenum)-1; + GLenum dataType = GL_UNSIGNED_BYTE; + + check_format(type,depth,internalFormat , pixelFormat , dataType); + + if(pixelFormat!=(GLenum)-1) + { + osg_texture = new Texture2D(); + + Image* image = new Image; + char* data = 0L; + + bool bMipmap; + tex->GetIsMipmap(bMipmap); + int32 num_mipmaps = bMipmap ? tex->CalcNumMipmaps() : 1; // this is currently line 130 + + // osg::Image do their own mipmaps + if(num_mipmaps <= 1) + { + int32 size = s.x*s.y*depth; + // int32 size = const_cast(tex)->MipLevelSize(1) ; + data = new char [size]; + image_helper.GetNthImageForLocalMat(locmat,index, data,size); image->setImage(s.x,s.y,1,internalFormat, pixelFormat, dataType, (unsigned char*)data,osg::Image::USE_NEW_DELETE); @@ -157,10 +240,7 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria data = new char [size]; - if(locmat) - image_helper.GetImageForLocalMat(locmat,data,size); - else - image_helper.GetLocalGL(tex,data,size); + image_helper.GetNthImageForLocalMat(locmat,index, data,size); // Load entire texture including mipmaps image->setImage(s.x,s.y,1,internalFormat, pixelFormat, dataType, @@ -180,29 +260,74 @@ Texture2D* txp::GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMateria } -// // AAAARRRGH! TOOK ME 2 DAYS TO FIGURE IT OUT -// // EVERY IMAGE HAS TO HAVE UNIQUE NAME FOR OPTIMIZER NOT TO OPTIMIZE IT OFF -// // -// static int unique = 0; -// char unique_name[256]; -// sprintf(unique_name,"TXP_TEX_UNIQUE%d",unique++); -// -// image->setFileName(unique_name); - osg_texture->setImage(image); } return osg_texture; } +//---------------------------------------------------------------------------- +// +// Group Reader Class +// +//---------------------------------------------------------------------------- +// Apply transformation on geometry +class TransformFunctor : public osg::Drawable::AttributeFunctor +{ + public: + + osg::Matrix _m; + osg::Matrix _im; + + TransformFunctor(const osg::Matrix& m) + { + _m = m; + _im.invert(_m); + } + + virtual ~TransformFunctor() {} + + virtual void apply(osg::Drawable::AttributeType type,unsigned int count,osg::Vec3* begin) + { + if (type == osg::Drawable::VERTICES) + { + osg::Vec3* end = begin+count; + for (osg::Vec3* itr=begin;itrfront())); // Turn the trpgGeometry into something Performer can understand @@ -246,15 +371,15 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) } } } - + + // The normals Vec3Array* normals = 0L; if (numNorm == numVert) { normals = new Vec3Array(numVert); - geom.GetNormals(&(normals->front())); + geom.GetNormals((float*)&(normals->front())); } - Geode *geode = new Geode(); // Set up the primitive type switch (primType) { @@ -264,6 +389,12 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::TRIANGLES,0,numPrims*3)); } break; + case trpgGeometry::Quads: + { + geometry = new Geometry; + geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,numPrims*4)); + } + break; case trpgGeometry::TriStrips: { // Need primitive lengths too @@ -331,7 +462,8 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // Add it to the current parent group - Group *top = parse->GetCurrTop(); + GeodeGroup *top = parse->GetCurrTop(); + Geode *geode = top->GetGeode(); if (geometry) { // added this set use display list off since terrapage will @@ -359,17 +491,86 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) geometry->setTexCoordArray( texno, tex_coords[texno]); } - geometry->setStateSet(sset.get()); - geode->addDrawable(geometry); - top->addChild(geode); + if ( is_billboard(top) ) + { + geometry->setStateSet(sset.get()); + + Billboard *billboard = static_cast(top->getChild(0)); + + switch (parse->getBillboardType()) { + case trpgBillboard::Individual: + { + // compute center of billboard geometry + const BoundingBox& bbox = geometry->getBound(); + Vec3 center ((bbox._min + bbox._max) * 0.5f); + + // make billboard geometry coordinates relative to computed center + Matrix matrix; + matrix.makeTranslate(-center[0], -center[1], -center[2]); + + TransformFunctor tf(matrix); + geometry->accept(tf); + geometry->dirtyBound(); + + billboard->addDrawable(geometry); + billboard->setPos(0, center); + } + break; + case trpgBillboard::Group: + { + Vec3 center(parse->getBillboardCenter()); + + // make billboard geometry coordinates relative to specified center + Matrix matrix; + matrix.makeTranslate(-center[0], -center[1], -center[2]); + + TransformFunctor tf(matrix); + geometry->accept(tf); + geometry->dirtyBound(); + + billboard->addDrawable(geometry); + billboard->setPos(0, center); + } + break; + default: + billboard->addDrawable(geometry); + notify(WARN) << "TerraPage loader: fell through case: " << __FILE__ << " " << __LINE__ << ".\n"; + break; + } + } + else + { + // if this is part of the layer we turn the PolygonOffset on + + if ( (parse->GetCurrLayer() == top) && geode->getNumDrawables() ) + { + StateSet* poStateSet = new StateSet; + PolygonOffset* polyoffset = new PolygonOffset; + + poStateSet->merge(*sset.get()); + polyoffset->setFactor(-1.0f*geode->getNumDrawables()); + polyoffset->setUnits(-20.0f*geode->getNumDrawables()); + poStateSet->setAttributeAndModes(polyoffset,osg::StateAttribute::ON); + + geometry->setStateSet(poStateSet); + + } + else + { + geometry->setStateSet(sset.get()); + } + + geode->addDrawable(geometry); + } + } return (void *) 1; } +//---------------------------------------------------------------------------- // // Group Reader Class // - //---------------------------------------------------------------------------- groupRead::groupRead(TrPageParser *in_parse) { @@ -383,11 +584,37 @@ void* groupRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if (!group.Read(buf)) return NULL; // Create a new Performer group - Group *osg_Group = new Group(); + GeodeGroup* osg_Group = new GeodeGroup(); // Dump this group into the hierarchy - Group *top = parse->GetCurrTop(); - if (top) - top->addChild(osg_Group); + parse->AddIntoSceneGraph(osg_Group); + // Register the group for attachements + int32 id; + group.GetID(id); + parse->AddToGroupList(id,osg_Group); + return (void *) osg_Group; +} + +//---------------------------------------------------------------------------- +// +// Layer Reader Class +// +//---------------------------------------------------------------------------- +layerRead::layerRead(TrPageParser *in_parse) +{ + parse = in_parse; +} + +//---------------------------------------------------------------------------- +void* layerRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) +{ + trpgLayer group; + if (!group.Read(buf)) + return NULL; + // Create a new Performer group + Layer* osg_Group = new Layer(); + // Dump this group into the hierarchy + parse->AddIntoSceneGraph(osg_Group); + // Register for attachements int32 id; group.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -398,6 +625,7 @@ void* groupRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // // Attach Reader Class // +//---------------------------------------------------------------------------- attachRead::attachRead(TrPageParser *in_parse) { parse = in_parse; @@ -410,11 +638,10 @@ void* attachRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) if (!group.Read(buf)) return NULL; // Create a new Performer group - Group *osg_Group = new Group(); + GeodeGroup* osg_Group = new GeodeGroup(); // Dump this group into the hierarchy - Group *top = parse->GetCurrTop(); - if (top) - top->addChild(osg_Group); + parse->AddIntoSceneGraph(osg_Group); + // Register for attachements int32 id; group.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -429,6 +656,7 @@ void* attachRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // // Billboard Reader Class // +//---------------------------------------------------------------------------- billboardRead::billboardRead(TrPageParser *in_parse) { parse = in_parse; @@ -437,37 +665,61 @@ billboardRead::billboardRead(TrPageParser *in_parse) //---------------------------------------------------------------------------- void* billboardRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) { + // Read in the txp billboard trpgBillboard bill; if (!bill.Read(buf)) return NULL; - - Group* osg_Group = new Group; - int type; - bill.GetType(type); -// Note: Must deal with the billboard type here - if( type == trpgBillboard::Group ) - { - // Create a new Performer group - Billboard* bl = new Billboard(); - int m; - bill.GetMode(m); - if( m == trpgBillboard::Eye) - bl->setMode(Billboard::POINT_ROT_EYE); - else if(m == trpgBillboard::World ) - bl->setMode(Billboard::POINT_ROT_WORLD); - else if(m == trpgBillboard::Axial ) - { - trpg3dPoint p; - bill.GetAxis(p); - bl->setAxis(Vec3(p.x, p.y, p.z)); - bl->setMode(Billboard::AXIAL_ROT); - } - osg_Group->addChild(bl); - } + + // Create a group with a geometry beneath for the billboard + GeodeGroup* osg_Group = new GeodeGroup(); + + if (parse->inBillboard()) { + // we don't allow anything under a billboard except geometry + notify(WARN) << "TerraPage loader: can only have geometry nodes beneath a billboard.\n"; + } + else + { + int type, mode; + trpg3dPoint center, axis; + + if (bill.GetType(type) && bill.GetMode(mode) && bill.GetCenter(center) && bill.GetAxis(axis)) { + Billboard* billboard = new Billboard(); + + osg_Group->SetGeode(billboard); + + // save this state for processing of the geometry node(s) + parse->setBillboardType(type); + parse->setBillboardCenter(center); + + // set the axis + // NOTE: Needs update, when the billboard implementation for + // arbitrary axis is ready + // billboard->setAxis(Vec3(axis.x, axis.y, axis.z)); + billboard->setAxis(Vec3(0.0f,0.0,1.0f) ); + billboard->setNormal(Vec3(0.0f,-1.0,0.0f)); + + // the mode + switch (mode) { + case trpgBillboard::Axial: + billboard->setMode(Billboard::AXIAL_ROT); + break; + case trpgBillboard::World: + billboard->setMode(Billboard::POINT_ROT_WORLD); + break; + case trpgBillboard::Eye: + billboard->setMode(Billboard::POINT_ROT_EYE); + break; + default: + notify(WARN) << "TerraPage loader: Unknown billboard type.\n"; + notify(WARN) << "TerraPage loader: fell through case: " << __FILE__ << " " << __LINE__ << ".\n"; + break; + } + } + } + // Dump this group into the hierarchy - Group *top = parse->GetCurrTop(); - if (top) - top->addChild(osg_Group); + parse->AddIntoSceneGraph(osg_Group); + // Register int32 id; bill.GetID(id); parse->AddToGroupList(id,osg_Group); @@ -479,6 +731,7 @@ void* billboardRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // // LOD Reader Class // +//---------------------------------------------------------------------------- lodRead::lodRead (TrPageParser *in_parse) { parse = in_parse; @@ -496,10 +749,10 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) double in,out,width; lod.GetLOD(in,out,width); double minRange = MIN(in,out); - double maxRange = MAX(in,out); - + double maxRange = MAX(in,out+width); + // Create a new Performer LOD - LOD *osg_Lod = new LOD(); + LOD* osg_Lod = new LOD(); Vec3 osg_Center; osg_Center[0] = center.x; osg_Center[1] = center.y; osg_Center[2] = center.z; osg_Lod->setCenter(osg_Center); @@ -507,13 +760,12 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // Our LODs are binary so we need to add a group under this LOD and attach stuff // to that instead of the LOD - Group *osg_LodG = new Group(); + GeodeGroup *osg_LodG = new GeodeGroup(); osg_Lod->addChild(osg_LodG); // Dump this group into the hierarchy - Group *top = parse->GetCurrTop(); - if (top) - top->addChild(osg_Lod); + parse->AddIntoSceneGraph(osg_Lod); + // Register for attachements int32 id; lod.GetID(id); // Add the sub-group to the group list, not the LOD @@ -525,6 +777,7 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // // Model Reference Reader Class // +//---------------------------------------------------------------------------- modelRefRead::modelRefRead(TrPageParser *in_parse) { parse = in_parse; @@ -573,6 +826,7 @@ void *modelRefRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf) // // Tile Header Reader Class // +//---------------------------------------------------------------------------- tileHeaderRead::tileHeaderRead(TrPageParser *in_parse) { parse = in_parse; @@ -598,6 +852,9 @@ TrPageParser::TrPageParser(TrPageArchive* parent) parent_ = parent; currTop = NULL; top = NULL; + layerDepth = 0; + currLayer = NULL; + in_billboard = false; // Register the readers AddCallback(TRPG_GEOMETRY,new geomRead(this)); @@ -606,6 +863,7 @@ TrPageParser::TrPageParser(TrPageArchive* parent) AddCallback(TRPG_BILLBOARD,new billboardRead(this)); AddCallback(TRPG_LOD,new lodRead(this)); AddCallback(TRPG_MODELREF,new modelRefRead(this)); + AddCallback(TRPG_LAYER,new layerRead(this)); AddCallback(TRPGTILEHEADER,new tileHeaderRead(this)); } @@ -628,7 +886,7 @@ trpgTileHeader *TrPageParser::GetTileHeaderRef() // scene graph. Group *TrPageParser::ParseScene(trpgReadBuffer &buf,vector > &in_mat,vector > &in_model) { - top = currTop = new Group(); + top = currTop = new GeodeGroup(); materials = &in_mat; local_materials.clear(); models = &in_model; @@ -647,6 +905,8 @@ Group *TrPageParser::ParseScene(trpgReadBuffer &buf,vector > & return ret; } +//---------------------------------------------------------------------------- +// Read local materials void TrPageParser::LoadLocalMaterials() { // new to 2.0 LOCAL materials @@ -673,56 +933,79 @@ void TrPageParser::LoadLocalMaterials() const trpgTexture *tex; int32 size; - image_helper.GetImageInfoForLocalMat(&locmat,&mat,&tex,size); + image_helper.GetImageInfoForLocalMat(&locmat, &mat,&tex,size); - int texId; - trpgTextureEnv texEnv; - mat->GetTexture(0,texId,texEnv); + int num_tex; + mat->GetNumTexture(num_tex); + for (int texNo = 0 ; texNo < num_tex; ++texNo) + { + int texId; + trpgTextureEnv texEnv; + mat->GetTexture(texNo,texId,texEnv); - // Set up texture environment - TexEnv *osg_texenv = new TexEnv(); - int32 te_mode; - texEnv.GetEnvMode(te_mode); - switch( te_mode ) - { - case trpgTextureEnv::Alpha : - osg_texenv->setMode(TexEnv::REPLACE); - break; - case trpgTextureEnv::Decal: - osg_texenv->setMode(TexEnv::DECAL); - break; - case trpgTextureEnv::Blend : - osg_texenv->setMode(TexEnv::BLEND); - break; - case trpgTextureEnv::Modulate : - osg_texenv->setMode(TexEnv::MODULATE); + // Set up texture environment + TexEnv *osg_texenv = new TexEnv(); + int32 te_mode; + texEnv.GetEnvMode(te_mode); + switch( te_mode ) + { + case trpgTextureEnv::Alpha : + osg_texenv->setMode(TexEnv::REPLACE); break; + case trpgTextureEnv::Decal: + osg_texenv->setMode(TexEnv::DECAL); + break; + case trpgTextureEnv::Blend : + osg_texenv->setMode(TexEnv::BLEND); + break; + case trpgTextureEnv::Modulate : + osg_texenv->setMode(TexEnv::MODULATE); + break; + } + + osg_state_set->setTextureAttribute(texNo,osg_texenv); + + image_helper.GetNthImageInfoForLocalMat(&locmat, texNo, &mat,&tex,size); + + trpgTexture::ImageMode mode; + tex->GetImageMode(mode); + Texture2D* osg_texture = 0L; + if(mode == trpgTexture::Template) + osg_texture = GetTemplateTexture(image_helper,&locmat, tex, texNo); + else if(mode == trpgTexture::Local) + osg_texture = GetLocalTexture(image_helper,tex); + else if(mode == trpgTexture::Global) + osg_texture = parent_->getGlobalTexture(texId); + + if(osg_texture) + { + if(osg_texture->getImage()) + { + GLenum gltype = osg_texture->getImage()->getPixelFormat(); + if( gltype == GL_RGBA || gltype == GL_LUMINANCE_ALPHA ) + { + osg_state_set->setMode(GL_BLEND,StateAttribute::ON); + osg_state_set->setRenderingHint(StateSet::TRANSPARENT_BIN); + } + } + else + { + notify(WARN) << "No image\n"; + } + osg_state_set->setTextureAttributeAndModes(texNo,osg_texture, StateAttribute::ON); + + int wrap_s, wrap_t; + texEnv.GetWrap(wrap_s, wrap_t); + osg_texture->setWrap(Texture2D::WRAP_S, wrap_s == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); + osg_texture->setWrap(Texture2D::WRAP_T, wrap_t == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); + } + else + { + notify(WARN) << "No texture\n"; + } } - - osg_state_set->setTextureAttribute(0,osg_texenv); - - Texture2D* osg_texture = GetLocalTexture(image_helper,&locmat, tex); - if(osg_texture) - { - if(osg_texture->getImage()) - { - GLenum gltype = osg_texture->getImage()->getPixelFormat(); - if( gltype == GL_RGBA || gltype == GL_LUMINANCE_ALPHA ) - { - osg_state_set->setMode(GL_BLEND,StateAttribute::ON); - osg_state_set->setRenderingHint(StateSet::TRANSPARENT_BIN); - } - } - osg_state_set->setTextureAttributeAndModes(0,osg_texture, StateAttribute::ON); - - int wrap_s, wrap_t; - texEnv.GetWrap(wrap_s, wrap_t); - osg_texture->setWrap(Texture2D::WRAP_S, wrap_s == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); - osg_texture->setWrap(Texture2D::WRAP_T, wrap_t == trpgTextureEnv::Repeat ? Texture2D::REPEAT: Texture2D::CLAMP ); - } - - Material *osg_material = new Material; + Material *osg_material = new Material; float64 alpha; mat->GetAlpha(alpha); @@ -799,9 +1082,30 @@ void TrPageParser::LoadLocalMaterials() // We'll want to make the node it's handing us the "top" node bool TrPageParser::StartChildren(void *in_node) { - Group *node = (Group *)in_node; - - currTop = node; + // Make a node + GeodeGroup *node = (GeodeGroup *)in_node; + + // If we are under layer we need to drop all groups. Then + // the current parent is still the layer node + if (layerDepth==0) + { + // Set it as current parent + currTop = node; + } + + // + // track whether we are under a billboard in the scene graph + // + if (is_billboard(currTop)) + in_billboard = true; + + // Chek if it's layer + if (node && (in_node != (void*)1) && (strcasecmp(node->className(),"Layer") == 0)) + { + if (layerDepth==0) + currLayer = (Layer*)node; + layerDepth++; + } return true; } @@ -811,25 +1115,57 @@ bool TrPageParser::StartChildren(void *in_node) // 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 TrPageParser::EndChildren(void * /* in_node */) +bool TrPageParser::EndChildren(void *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 = (Group *)parents[pos]; - } + // Chek if it's layer + osg::Node* node = (osg::Node*)in_node; + if (node && (in_node != (void*)1) && (strcasecmp(node->className(),"Layer") == 0)) + { + if (layerDepth > 0) + layerDepth--; + else + { + notify(WARN) << "Layer depth < 0 ???\n"; + } + if (layerDepth==0) + { + currLayer = NULL; + for (unsigned int i = 0; i < deadNodes.size(); i++) + { + osg::ref_ptr deadNode = deadNodes[i]; + } + deadNodes.clear(); + } + } + + // + // track whether we are under a billboard in the scene graph + // + if (is_billboard(static_cast(in_node))) + in_billboard = false; + + // if we are under layer all the groups are dropped out, so no need to do this + if (layerDepth==0) + { + // 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 = (GeodeGroup *)parents[pos]; + } + } + return true; } //---------------------------------------------------------------------------- // Return the current top node -Group *TrPageParser::GetCurrTop() +GeodeGroup *TrPageParser::GetCurrTop() { if (currTop) { @@ -843,10 +1179,14 @@ Group *TrPageParser::GetCurrTop() //---------------------------------------------------------------------------- // Add the given pfGroup to the group list at position ID -bool TrPageParser::AddToGroupList(int ID,Group *group) +bool TrPageParser::AddToGroupList(int ID,GeodeGroup *group) { - // Note: check bounds - groupList[ID] = group; + // we dont do this if we are under layer + if (layerDepth==0) + { + // Note: check bounds + groupList[ID] = group; + } return true; } @@ -862,3 +1202,27 @@ void TrPageParser::SetMaxGroupID(int maxGroupID) for (int i=0;iaddChild(node); + } +} + +//---------------------------------------------------------------------------- +// Return the current layer node (also used during parsing) +Layer *TrPageParser::GetCurrLayer() +{ + return currLayer; +} diff --git a/src/osgPlugins/txp/TrPageParser.h b/src/osgPlugins/txp/TrPageParser.h index 2739f83bb..4afa0e0b4 100644 --- a/src/osgPlugins/txp/TrPageParser.h +++ b/src/osgPlugins/txp/TrPageParser.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include "trpage_read.h" @@ -44,14 +45,74 @@ namespace txp int id; } GroupIDInfo; + // This is group that will has geode node + // It is better since all the geometry children will be + // added into one Geode node as drawables, then having one + // geode node per child + // Means, instad of having + // Group + // +----------- + // | | + // Geode Geode + // | | + // Drawable Drawable + // we will have + // Group + // | + // Geode + // +----------- + // | | + // Drawable Drawable + // nick@terrex.com + class GeodeGroup : public osg::Group + { + protected: + osg::Geode* _geode; + public: + GeodeGroup() : osg::Group(), _geode(NULL) {}; + GeodeGroup(const GeodeGroup& gg,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) + : osg::Group(gg, copyop), _geode(gg._geode) {}; + META_Node(txp, GeodeGroup); + osg::Geode* GetGeode() + { + if (!_geode) + { + _geode = new osg::Geode(); + addChild(_geode); + } + return _geode; + }; + void SetGeode(osg::Geode* geode) + { + if ( _geode ) + { + // I assume ref_ptr will destroy it + removeChild(_geode); + } + _geode = geode; + addChild(_geode); + } + }; + + // same as above, we need this to identify the node as Layer node + class Layer : public GeodeGroup + { + public: + Layer() : GeodeGroup() {}; + Layer(const Layer& lr,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) + : GeodeGroup(lr, copyop) {}; + META_Node(txp, Layer); + }; + class TrPageParser : public trpgSceneParser { public: TrPageParser(TrPageArchive* parent); ~TrPageParser(); + // Scene parser osg::Group *ParseScene(trpgReadBuffer & buf, - std::vector > & materials_, + std::vector > & materials_, std::vector > & node ); // Return the parent of a recently parsed tile @@ -61,46 +122,124 @@ namespace txp trpgTileHeader *GetTileHeaderRef(); // Return the current top node (used during parsing) - osg::Group *GetCurrTop(); + GeodeGroup *GetCurrTop(); + + // Return the current layer node (also used during parsing) + Layer *GetCurrLayer(); // Return the current material list (passed in to ParseScene()) std::vector >* GetMaterials() { return materials; } + // new to TerraPage 2.0 - local materials std::vector >* GetLocalMaterials() { return &local_materials; } std::vector >* GetModels() { return models; } // Add the Group to the current group list - bool AddToGroupList(int id,osg::Group *); + bool AddToGroupList(int id,GeodeGroup*); + + // Use this to add nodes into the scenegraph + void AddIntoSceneGraph(osg::Node* node); // Return the group list - std::vector< osg::Group *> *GetGroupList() { return &groupList; } + std::vector< GeodeGroup *> *GetGroupList() { return &groupList; } /// TXP 2.0 - local materials void LoadLocalMaterials(); + // Initialize the group list void SetMaxGroupID(int maxGroupID); + + // Methods for tracking whether we are under a billboard in the scene graph + bool inBillboard() const { return in_billboard; } + void setBillboardType(int type) { billboard_type = type; } + int getBillboardType() { return billboard_type; } + void setBillboardCenter(trpg3dPoint center) { billboard_center = center; } + osg::Vec3 getBillboardCenter() { return osg::Vec3(billboard_center.x, billboard_center.y, billboard_center.z); } + protected: + // Called on start children bool StartChildren(void *); + + // Called on end children bool EndChildren(void *); - + protected: - TrPageArchive* parent_; - osg::Group *currTop; // Current parent group - osg::Group *top; // Top group - trpgTileHeader tileHead; // Dump tile header here + TrPageArchive* parent_; // The archive + GeodeGroup *currTop; // Current parent group + GeodeGroup *top; // Top group + trpgTileHeader tileHead; // Dump tile header here // If there was an attach node, this is // the tile's parent ID. -1 otherwise - int parentID; - std::vector >* materials; - std::vector > local_materials; - std::vector groupList; - std::vector >* models; + int parentID; + // Materials + std::vector >* materials; + // Local materials + std::vector > local_materials; + // Group list. Probably needed for keepinh tracks of the IDs (?) + std::vector groupList; + // Model list + std::vector >* models; + // track whether we are under a billboard in the scene graph + bool in_billboard; + int billboard_type; + trpg3dPoint billboard_center; + // Keeps track how deep are we into the layer subtree + int layerDepth; + // The current layer we are processing nodes below + Layer* currLayer; + // Nodes that are part of the label subtree and will never get + // into the sceen graph. + // Consider this subtree + // Layer0 + // +------------------- + // | | + // Group0(layer0) Group4(layer1) + // | | + // Group1 Geometry3(for layer1) + // +--------------- + // | | + // Geometry0 Layer1 + // +--------------- + // | | + // Group2 Group3 + // | | + // Geometry1 Geometry2 + // + // The idea is to have all the geometries below Layer0 into one Geode + // and set the right PolygonOffset. That means the rest of the nodes will go away + // One problem that can occur is, if there is trpgAttach existing that attach something + // to a trpgGroup from the Layer0 subtree ( or LODs - but I dont think any writer will do + // produce such an archive ). The right way to do this probably is by using + // targettable bin numbers, but I was not able to make it work + // Here's Layer0 in osg representation + // Layer0 (it's GeodeGroup, it has it's own Geode) + // | + // Geode + // +----------------------------------- + // | | | | + // Geometry0 Geometry1 Geometry2 Geometry3 + // + // Geometry1-3 will have PolygonState truned on + // p.s. I have no archive at present to test this against. Usualy, the layers are + // coming out of TerraVista in such a tree as follows: + // Layer + // +--------------- + // | | + // Group(layer0) Group(layer1) + // | | + // Geometry Geometry + // It is tested on this kind of archive and it works. + // nick@terrex.com + std::vector deadNodes; }; - osg::Texture2D* GetLocalTexture(trpgrImageHelper& image_helper, trpgLocalMaterial* locmat, const trpgTexture* tex); + // Gets local texture via the image helper + osg::Texture2D* GetLocalTexture(trpgrImageHelper& image_helper, const trpgTexture* tex); + osg::Texture2D* GetTemplateTexture(trpgrImageHelper& image_helper, trpgLocalMaterial* locmat, const trpgTexture* tex, int index=0); //! callback functions for various scene graph elements + //---------------------------------------------------------------------------- class geomRead : public trpgr_Callback { public: geomRead(TrPageParser *in_parse); @@ -163,6 +302,15 @@ namespace txp protected: TrPageParser*parse; }; + + //---------------------------------------------------------------------------- + class layerRead: public trpgr_Callback { + public: + layerRead(TrPageParser*in_parse); + void *Parse(trpgToken tok,trpgReadBuffer &buf); + protected: + TrPageParser*parse; + }; } // namespace txp #endif diff --git a/src/osgPlugins/txp/WaitBlock.h b/src/osgPlugins/txp/WaitBlock.h index 8d5236231..c112c2ca8 100644 --- a/src/osgPlugins/txp/WaitBlock.h +++ b/src/osgPlugins/txp/WaitBlock.h @@ -1,36 +1,32 @@ #ifndef WAIT_BLOCK_H #define WAIT_BLOCK_H -#if !defined(WIN32) || defined(__CYGWIN__) -#include +#include namespace osgTXP { struct WaitBlock{ - pthread_mutex_t mut; - pthread_cond_t cond; + OpenThreads::Mutex mut; + OpenThreads::Condition cond; WaitBlock() { - pthread_mutex_init( &mut, 0L ); - pthread_cond_init( &cond, 0L ); } void wait() { - pthread_mutex_lock( &mut ); - pthread_cond_wait( &cond, &mut); - pthread_mutex_unlock(&mut); + mut.lock(); + cond.wait(&mut); + mut.unlock(); } void release() { - pthread_mutex_lock( &mut ); - pthread_cond_broadcast( &cond ); - pthread_mutex_unlock( &mut ); +// mut.lock(); + cond.broadcast(); +// mut.unlock(); } }; } #endif -#endif diff --git a/src/osgPlugins/txp/trPagePageManager.cpp b/src/osgPlugins/txp/trPagePageManager.cpp index eeb30aff7..32ef66c76 100644 --- a/src/osgPlugins/txp/trPagePageManager.cpp +++ b/src/osgPlugins/txp/trPagePageManager.cpp @@ -1,18 +1,6 @@ #include #include -#if defined(__CYGWIN__) -#include -#include -#include -#elif defined(_WIN32) -#include -#include -#else -#include -#include -#endif - #include "TrPageArchive.h" #include "trPagePageManager.h" #include "trpage_print.h" @@ -21,8 +9,6 @@ #include #include #include -#include -#include #include #include @@ -32,6 +18,12 @@ using namespace txp; using namespace osg; +#if defined(WIN32) +#define sleep(x) Sleep((x)) +#else +#define sleep(x) usleep((x)*1000) +#endif + OSGPageManager::OSGPageManager(TrPageArchive *in_arch,trpgPageManager *in_pageManage) { archive = in_arch; @@ -40,7 +32,8 @@ OSGPageManager::OSGPageManager(TrPageArchive *in_arch,trpgPageManager *in_pageMa if (!in_arch) throw 1; - if (pageManage) + + if (pageManage) pageManageOurs = false; else { pageManage = new trpgPageManager(); @@ -117,69 +110,22 @@ bool OSGPageManager::UpdateNoThread(osg::Group *rootNode,double locX,double locY // Mutex lock function // --- Either thread --- -void osgLockMutex(ThreadMutex &mtx) +struct osgGuard { -#if defined (_WIN32) - WaitForSingleObject( mtx, INFINITE); -#else - pthread_mutex_lock( &mtx ); -#endif -} + ThreadMutex& _mtx; + osgGuard(ThreadMutex &mtx):_mtx(mtx){ + _mtx.lock(); + } + ~osgGuard(){ + _mtx.unlock(); + } +}; -// Mutex unlock function -// --- Either thread --- -void osgUnLockMutex(ThreadMutex &mtx) +void PagingThread::run() { -#if defined(_WIN32) && !defined(__CYGWIN__) - ReleaseMutex(mtx); -#else - pthread_mutex_unlock( &mtx ); -#endif + pager->ThreadLoop(this); } -// Wait for Event -// --- Either thread (only used in paging thread) --- -void osgWaitEvent(ThreadEvent &ev) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - WaitForSingleObject( ev, INFINITE); -#else - ev.wait(); -#endif -} - -// Set Event (i.e. notify the other thread something's up) -// --- Either thread (only used in main thread) --- -void osgSetEvent(ThreadEvent &ev) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - SetEvent(ev); -#else - ev.release(); -#endif -} - -// Windows specific thread function. -// This just fires up our own loop -// --- Paging Thread --- -#if defined(_WIN32) && !defined(__CYGWIN__) -DWORD WINAPI ThreadFunc( LPVOID lpParam ) -{ - OSGPageManager *myPager = (OSGPageManager *)lpParam; - myPager->ThreadLoop(); - - return 0; -} -#else // Pthreads, cause Pthreads is a POSIX standard and is EVERYWHERE else - -void *ThreadFunc( void *data ) -{ - OSGPageManager *myPager = static_cast(data); - myPager->ThreadLoop(); - return 0L; -} -#endif - /* Start Thread This initialized --- Main Thread --- @@ -188,174 +134,152 @@ bool OSGPageManager::StartThread(ThreadMode mode,ThreadID &newThread) { positionValid = false; -#if defined(_WIN32) && !defined(__CYGWIN__) - // Create the event we'll use to wake up the pager thread when the location changes - locationChangeEvent = CreateEvent(NULL,false,false,"Location Change Event"); - - // Create the mutexes we'll need later - changeListMutex = CreateMutex(NULL,false,"Change List Mutex"); - locationMutex = CreateMutex(NULL,false,"Location Mutex"); - - { - // Create the thread - DWORD dwThreadId=0; - LPVOID dwThrdParam = (LPVOID) this; - - threadID = newThread = CreateThread( - NULL, // default security attributes - 0, // use default stack size - ThreadFunc, // thread function - dwThrdParam, // argument to thread function - 0, // use default creation flags - &dwThreadId); // returns the thread identifier - } - - // Note: Should be optional - // Set the priority low so this is only called when the other thread is idle -// if (!SetThreadPriority(newThread,THREAD_PRIORITY_IDLE)) -// fprintf(stderr,"Couldn't set paging thread priority.\n"); - - // Was successfull - if (newThread != NULL) - threadMode = mode; -#else //locationChangeEvent is self-initialized. - pthread_mutex_init( &changeListMutex, 0L ); - pthread_mutex_init( &locationMutex, 0L ); threadMode = mode; - if( pthread_create( &newThread, 0L, ThreadFunc, (void *)this ) != 0 ) - threadMode = ThreadNone; - threadID = newThread; -#endif + pagingThread.pager = this; + pagingThread.startThread(); + newThread = pagingThread.getThreadId(); return threadMode != ThreadNone; } + /* End Thread Note: Do this */ bool OSGPageManager::EndThread() { - cancel = true; - // claer the path for thred loop to finish - osgSetEvent(locationChangeEvent); -#ifdef _WIN32 - DWORD res = STILL_ACTIVE; - while(res==STILL_ACTIVE){ - GetExitCodeThread(threadID,&res); - Sleep(100); - } -#else - // Need a handle to the thread ID here. - pthread_join( threadID, 0 ); -#endif +// locationChangeEvent.release(); + pagingThread.cancel(); return true; } +void OSGPageManager::LoadOneTile(trpgManagedTile* tile) +{ + osg::Group* tileGroup; + osg::Group* parentNode ; + int x,y,lod; + tile->GetTileLoc(x,y,lod); + + tileGroup = archive->LoadTile(NULL,pageManage,tile,&parentNode); + if (tileGroup) + { +#ifdef USE_THREADLOOP_DELETE + // Make an extra reference to it because we want it back for deletion + // RO, commenting out as we don't want to do delete here, we want it to happen in the merge thread. + tileGroup->ref(); +#endif + // we only put tiles with NULL parent to merge list + // others are referenced when added as a child + osgGuard g(changeListMutex); + if(parentNode) + parentNode->addChild(tileGroup) ; + else + toMerge.push_back( tileGroup) ; + //toMergeParent.push_back(parentNode ); + } + else + { + osg::notify(WARN) << "Failed to load tile (" << x << y << lod << ")" << std::endl ; + } + +} + /* Thread Loop This method is the main loop for the pager when it's working in its own thread. --- Paging Thread --- */ -bool OSGPageManager::ThreadLoop() +bool OSGPageManager::ThreadLoop(PagingThread* t) { // Note: Only works for free running thread if (threadMode != ThreadFree) throw 1; - bool pagingActive = false; - cancel = false; + std::vector unhook; + std::vector nextDelete; - while (!cancel) { - /* Here's how we do it: - Wait for position change - Update manager w/ position - Form delete list - Load tile (if needed) - Add tile to merge list - */ + bool pagingActive = false; + while (!t->testCancel()) { + /* Here's how we do it: + Wait for position change + Update manager w/ position + Form delete list + Load tile (if needed) + Add tile to merge list + */ // Position has already changed or we'll wait for it to do so - osgWaitEvent(locationChangeEvent); + // locationChangeEvent.wait(); double myLocX,myLocY; { - osgLockMutex(locationMutex); + osgGuard g(locationMutex); myLocX = locX; myLocY = locY; - osgUnLockMutex(locationMutex); + positionValid = false; } - + // Pass the new location on to page manager + int x,y,lod; + trpg2dPoint loc; loc.x = myLocX; loc.y = myLocY; - if (pageManage->SetLocation(loc) || pagingActive) { + if (pageManage->SetLocation(loc) ) { // If there were changes, process them // Form the delete list first trpgManagedTile *tile=NULL; - std::vector unhook; + + unhook.clear(); + while ((tile = pageManage->GetNextUnload())) { - unhook.push_back((Group *)(tile->GetLocalData())); - pageManage->AckUnload(); + tile->GetTileLoc(x,y,lod); + unhook.push_back((Group *)(tile->GetLocalData())); + pageManage->AckUnload(); } - // Tell the main thread to unhook tiles - // and get the groups to delete as well. - std::vector nextDelete; + nextDelete.clear(); { - osgLockMutex(changeListMutex); + osgGuard g(changeListMutex); // Add to the unhook list - for (unsigned int ti=0;tiunref(); + // Unreference whatever we're supposed to delete + for (unsigned int gi=0;giunref(); + } #endif + // Now do a single load - while( (tile = pageManage->GetNextLoad()) ) // Sasa's new code - more frame drops, but less missing tiles. - //if( (tile = pageManage->GetNextLoad()) ) // original code (0.9.4 and before) - less frame drops, more missing tiles. - { - osg::Group *tileGroup=NULL; - pagingActive = false; - osg::Group *parentNode = NULL; - tileGroup = archive->LoadTile(NULL,pageManage,tile,&parentNode); - pageManage->AckLoad(); - if (tileGroup) { -#ifdef USE_THREADLOOP_DELETE - // Make an extra reference to it because we want it back for deletion - // RO, commenting out as we don't want to do delete here, we want it to happen in the merge thread. - tileGroup->ref(); -#endif - } - else - { - int x,y,lod; - tile->GetTileLoc(x,y,lod); - fprintf(stderr,"Failed to load tile (%d,%d,%d)\n",x,y,lod); - } - - // Now add this tile to the merge list - if (tileGroup) { - osgLockMutex(changeListMutex); - toMerge.push_back(tileGroup); - toMergeParent.push_back(parentNode); - osgUnLockMutex(changeListMutex); - } - // We're not necessarily done paging, we're just handing control back - // It's likely we'll be back here - pagingActive = true; - } - } - } + while((tile = pageManage->GetNextLoad())) + { + tile->GetTileLoc(x,y,lod); + osg::notify(WARN) << "Tile to load :" << x << ' ' << y << ' ' << lod << std::endl; + osg::notify(WARN) << "Position :" << loc.x << ' ' << loc.y << std::endl; + LoadOneTile(tile); + // Now add this tile to the merge list + pageManage->AckLoad(); + } + + + } + else + sleep(10); + } return true; } @@ -367,81 +291,19 @@ bool OSGPageManager::ThreadLoop() void OSGPageManager::UpdatePositionThread(double inLocX,double inLocY) { // Update the position - { + if(!positionValid) + { // Get the location mutex - osgLockMutex(locationMutex); + osgGuard g(locationMutex); positionValid = true; locX = inLocX-originX; locY = inLocY-originY; - osgUnLockMutex(locationMutex); } // Notify the paging thread there's been a position update - osgSetEvent(locationChangeEvent); +// locationChangeEvent.release(); } -class ReleaseTexturesAndDrawablesVisitor : public osg::NodeVisitor -{ -public: - ReleaseTexturesAndDrawablesVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) - { - } - - virtual void apply(osg::Node& node) - { - apply(node.getStateSet()); - - traverse(node); - } - - virtual void apply(osg::Geode& geode) - { - apply(geode.getStateSet()); - - for(unsigned int i=0;igetTextureAttributeList(); - for(osg::StateSet::TextureAttributeList::iterator itr=tal.begin(); - itr!=tal.end() && !foundTextureState; - ++itr) - { - osg::StateSet::AttributeList& al = *itr; - osg::StateSet::AttributeList::iterator alitr = al.find(osg::StateAttribute::TEXTURE); - if (alitr!=al.end()) - { - // found texture, so place it in the texture list. - osg::Texture* texture = static_cast(alitr->second.first.get()); - texture->dirtyTextureObject(); - } - } - } - } - - inline void apply(osg::Drawable* drawable) - { - apply(drawable->getStateSet()); - - if (drawable->getUseDisplayList() || drawable->getUseVertexBufferObjects()) - { - drawable->dirtyDisplayList(); - } - } - -}; - /* Merge Updates Merge in the new tiles and unhook the ones we'll be deleting. Actually, we'll hand these back to the paging thread for deletion. @@ -450,46 +312,43 @@ public: bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode) { std::vector mergeList; - std::vector mergeParentList; std::vector unhookList; // Make local copies of the merge and unhook lists { - osgLockMutex(changeListMutex); - mergeList = toMerge; - mergeParentList = toMergeParent; - unhookList = toUnhook; - - toMerge.clear(); - toMergeParent.clear(); - toUnhook.clear(); - osgUnLockMutex(changeListMutex); - } + osgGuard g(changeListMutex); + // use the stl Luke :-) swap is constant time operation that do a = b; b.clear() + // if a is empty which is our case + mergeList.swap(toMerge); + unhookList.swap(toUnhook); +// toMerge.clear(); +// toMergeParent.clear(); +// toUnhook.clear(); + } // Do the unhooking first for (unsigned int ui=0;uigetParents(); for (unsigned int pi=0;piremoveChild(unhookMe); + if(parent != rootNode) + parent->removeChild(unhookMe); } } #ifdef USE_THREADLOOP_DELETE // Put the unhooked things on the list to delete { - ReleaseTexturesAndDrawablesVisitor rtadv; - osgLockMutex(changeListMutex); - for (unsigned int di=0;diaccept(rtadv); - } - osgUnLockMutex(changeListMutex); + osgGuard g(changeListMutex); + for (unsigned int i = 0; i < unhookList.size();i++) + toDelete.push_back(unhookList[i]); } #endif @@ -497,13 +356,15 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode) { for (unsigned int mi=0;miaddChild(mergeMe); - else - rootNode->addChild(mergeMe); +// NO need for that - we only put tiles with NULL parent to merge list +// osg::Group *parent = mergeParentList[mi]; +// if (parent) +// parent->addChild(mergeMe); +// else + rootNode->addChild(mergeMe); } } + return true; } diff --git a/src/osgPlugins/txp/trPagePageManager.h b/src/osgPlugins/txp/trPagePageManager.h index 1890fe9ed..8dd9abb42 100644 --- a/src/osgPlugins/txp/trPagePageManager.h +++ b/src/osgPlugins/txp/trPagePageManager.h @@ -17,16 +17,13 @@ #ifndef _TRPAGEMANAGER_H_ #define _TRPAGEMANAGER_H_ -#include - -#if defined(__CYGWIN__) || !defined(WIN32) -#include -#endif - #include #include #include +#include +#include + #include "trpage_geom.h" #include "trpage_read.h" #include "trpage_write.h" @@ -35,6 +32,8 @@ #include "WaitBlock.h" #include "TrPageArchive.h" +#include + // Dec 2002, Robert Osfield -> comment out now, as we actually do want to delete in the main thread // as the deletion of the display and texture object isn't thread safe. // Jan 2002, Robert osfield -> comment back in now, as I've changed the way the @@ -42,7 +41,7 @@ // in theory its still not thread safe, but a point swap should be much faster // and less likely to encounter a race condition on the static caches of display // and texture object lists. -#define USE_THREADLOOP_DELETE +// #define USE_THREADLOOP_DELETE namespace txp { @@ -50,22 +49,31 @@ namespace txp Fill this in for your specific platform. Should be water ID you use for threads. */ -#if defined(_WIN32) && !defined(__CYGWIN__) - typedef HANDLE ThreadID; - typedef HANDLE ThreadMutex; - typedef HANDLE ThreadEvent; -#else - typedef pthread_t ThreadID; - typedef pthread_mutex_t ThreadMutex; + typedef int ThreadID; + typedef OpenThreads::Mutex ThreadMutex; typedef osgTXP::WaitBlock ThreadEvent; -#endif + + class OSGPageManager; + class PagingThread: public OpenThreads::Thread{ + public: + typedef OpenThreads::Thread super; + PagingThread():pager(NULL) + { + } + + virtual void run(); + + OSGPageManager *pager; + private: + volatile bool canceled; + }; /* OSG Page Manager This class handles the paging into */ - class OSGPageManager { + class OSGPageManager{ public: - /* Need a group to put things under and the archive to page. + /* Need a group to put things under and the archive to page. Also, optionally, a Page Manager (if you've made changes to the default one). */ @@ -112,7 +120,12 @@ namespace txp // Called by the thread start function // Don't call this yourself - bool ThreadLoop(); + bool ThreadLoop(PagingThread* t); + + // Load One tile + // @param tile managed tile + // @return tileGroup osg::Group representing managed tile + void LoadOneTile(trpgManagedTile* tile); protected: // Page Manager we'll use is ours (i.e. delete it at the end) @@ -128,7 +141,7 @@ namespace txp // ID of created thread and whether it's valid ThreadMode threadMode; - ThreadID threadID; + PagingThread pagingThread; // Used to notify the paging thread when the location changes ThreadEvent locationChangeEvent; @@ -142,17 +155,17 @@ namespace txp ThreadMutex changeListMutex; // Merge list is filled in by the paging thread. std::vector toMerge; - std::vector toMergeParent; + // no need for that + // std::vector toMergeParent; // Unhook list is filled in by the paging thread std::vector toUnhook; - - volatile bool cancel; #ifdef USE_THREADLOOP_DELETE // Main thread moves groups to the delete list as soon as they are unhooked std::vector toDelete; #endif }; + }; #endif diff --git a/src/osgPlugins/txp/trdll.h b/src/osgPlugins/txp/trdll.h index 54e05feef..7e0a00054 100644 --- a/src/osgPlugins/txp/trdll.h +++ b/src/osgPlugins/txp/trdll.h @@ -14,9 +14,9 @@ */ /* trdll.h - Windows Only + Windows Only - This header file defines the declaration macros for DLLs. + This header file defines the declaration macros for DLLs. */ // Export/import declaration for classes and functions @@ -87,15 +87,11 @@ // 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 (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) \ +BOOL APIENTRY DllMain (HANDLE hDLL, DWORD dwReason, LPVOID lpReserved) \ { \ switch (dwReason) \ { \ @@ -114,8 +110,8 @@ BOOL APIENTRY DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) \ return TRUE; \ } \ } + #endif -*/ #endif #ifndef txdll_h_ diff --git a/src/osgPlugins/txp/trpage_basic.cpp b/src/osgPlugins/txp/trpage_basic.cpp index dee17e4c5..d39d0b8e7 100644 --- a/src/osgPlugins/txp/trpage_basic.cpp +++ b/src/osgPlugins/txp/trpage_basic.cpp @@ -14,29 +14,29 @@ */ /* trpage_basic.cpp - Methods for checkable base class. - */ + Methods for checkable base class. + */ #include #include -#include "trpage_io.h" +#include /* 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; } diff --git a/src/osgPlugins/txp/trpage_compat.cpp b/src/osgPlugins/txp/trpage_compat.cpp index ff1161553..d9d822277 100644 --- a/src/osgPlugins/txp/trpage_compat.cpp +++ b/src/osgPlugins/txp/trpage_compat.cpp @@ -24,19 +24,19 @@ */ -#include "trpage_geom.h" -#include "trpage_read.h" -#include "trpage_compat.h" +#include +#include +#include /* Old short Material definition from 1.0. {secret} */ class trpgShortMaterial { public: - // Full trpgMaterial definition this one is based on - int baseMat; - // Currently the only thing a short material overrides is texture - std::vector texids; + // Full trpgMaterial definition this one is based on + int baseMat; + // Currently the only thing a short material overrides is texture + std::vector texids; }; trpgMatTable1_0::trpgMatTable1_0(const trpgMatTable &inTbl) @@ -46,85 +46,84 @@ trpgMatTable1_0::trpgMatTable1_0(const trpgMatTable &inTbl) bool trpgMatTable1_0::Read(trpgReadBuffer &buf) { - trpgMaterial mat; - trpgToken matTok; - int32 len; - bool status; - int i,j,k; + trpgMaterial mat; + trpgToken matTok; + int32 len; + bool status; + int i,j,k; - std::vector shortTable; - std::vector baseMats; + std::vector shortTable; + std::vector baseMats; - try { - buf.Get(numTable); - buf.Get(numMat); - if (numTable <= 0 || numMat < 0) throw 1; + try { + buf.Get(numTable); + buf.Get(numMat); + if (numTable <= 0 || numMat < 0) throw 1; - // Short material tables are always full size - shortTable.resize(numTable*numMat); + // Short material tables are always full size + shortTable.resize(numTable*numMat); - // Look for short material table - buf.GetToken(matTok,len); - if (matTok == TRPGSHORTMATTABLE) { - int32 numTex,texId; - buf.PushLimit(len); - for (i=0;i(shortTable.size());i++) - { - trpgShortMaterial &shortMat = shortTable[i]; - trpgMaterial &baseMat = baseMats[shortMat.baseMat]; - matTables.push_back(baseMat); - trpgMaterial &newMat = matTables[matTables.size()-1]; - newMat.SetNumTexture(shortMat.texids.size()); - for (unsigned j=0;j shortMats; @@ -132,21 +131,20 @@ bool trpgMatTable1_0::Write(trpgWriteBuffer &buf) // Iterate over the existing materials int i; - for (i=0;i(shortMats.size());i++) - { - trpgShortMaterial &sMat = shortMats[i]; - buf.Add(sMat.baseMat); - buf.Add((int)(sMat.texids.size())); - for (unsigned int j=0;j #include #include -#include "trpage_geom.h" -#include "trpage_read.h" +#include +#include -#include - -#if defined(_WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) #define ALIGNMENT_WORKAROUND false #else #define ALIGNMENT_WORKAROUND true @@ -38,9 +36,9 @@ // Constructor trpgGeometry::trpgGeometry() { - primType = Polygons; - normBind = Overall; - numPrim = 0; + primType = Polygons; + normBind = Overall; + numPrim = 0; } trpgGeometry::~trpgGeometry() { @@ -49,143 +47,143 @@ trpgGeometry::~trpgGeometry() // Reset function void trpgGeometry::Reset() { - primType = Polygons; - numPrim = 0; - primLength.resize(0); - materials.resize(0); - vertDataFloat.resize(0); - vertDataDouble.resize(0); - normBind = Overall; - normDataFloat.resize(0); - normDataDouble.resize(0); - colors.resize(0); - texData.resize(0); - edgeFlags.resize(0); + primType = Polygons; + numPrim = 0; + primLength.resize(0); + materials.resize(0); + vertDataFloat.resize(0); + vertDataDouble.resize(0); + normBind = Overall; + normDataFloat.resize(0); + normDataDouble.resize(0); + colors.resize(0); + texData.resize(0); + edgeFlags.resize(0); } // Set functions void trpgGeometry::SetPrimType(PrimType type) { - primType = type; + primType = type; } void trpgGeometry::SetPrimLengths(int num,const int *len) { - if (num < 0) - return; + if (num < 0) + return; - numPrim = num; - for (int i=0;i= (int)materials.size()) - return; + if (which < 0 || which >= (int)materials.size()) + return; - materials[which] = (isLocal ? -(mat+1) : mat); + materials[which] = (isLocal ? -(mat+1) : mat); } void trpgGeometry::SetMaterials(int32 num,const int32 *mat) { - materials.resize(num); - for (int i=0;i(pt.x)); - vertDataFloat.push_back(static_cast(pt.y)); - vertDataFloat.push_back(static_cast(pt.z)); - } else { - vertDataDouble.push_back(pt.x); - vertDataDouble.push_back(pt.y); - vertDataDouble.push_back(pt.z); - } + if (type == FloatData) { + vertDataFloat.push_back(pt.x); + vertDataFloat.push_back(pt.y); + vertDataFloat.push_back(pt.z); + } else { + vertDataDouble.push_back(pt.x); + vertDataDouble.push_back(pt.y); + vertDataDouble.push_back(pt.z); + } } void trpgGeometry::SetNormals(int num,BindType bind,const float32 *data) { - if (num < 0) - return; + if (num < 0) + return; - normBind = bind; - normDataFloat.resize(0); - normDataDouble.resize(0); - for (int i=0;i<3*num;i++) - normDataFloat.push_back(data[i]); + normBind = bind; + normDataFloat.resize(0); + normDataDouble.resize(0); + for (int i=0;i<3*num;i++) + normDataFloat.push_back(data[i]); } void trpgGeometry::SetNormals(int num,BindType bind,const float64 *data) { - if (num <0) - return; + if (num <0) + return; - normBind = bind; - normDataFloat.resize(0); - normDataDouble.resize(0); - for (int i=0;i<3*num;i++) - normDataDouble.push_back(data[i]); + normBind = bind; + normDataFloat.resize(0); + normDataDouble.resize(0); + for (int i=0;i<3*num;i++) + normDataDouble.push_back(data[i]); } void trpgGeometry::AddNormal(DataType type,trpg3dPoint &pt) { - if (type == FloatData) { - normDataFloat.push_back(static_cast(pt.x)); - normDataFloat.push_back(static_cast(pt.y)); - normDataFloat.push_back(static_cast(pt.z)); - } else { - normDataDouble.push_back(pt.x); - normDataDouble.push_back(pt.y); - normDataDouble.push_back(pt.z); - } + if (type == FloatData) { + normDataFloat.push_back(pt.x); + normDataFloat.push_back(pt.y); + normDataFloat.push_back(pt.z); + } else { + normDataDouble.push_back(pt.x); + normDataDouble.push_back(pt.y); + normDataDouble.push_back(pt.z); + } } // Constructor trpgColorInfo::trpgColorInfo() @@ -196,24 +194,24 @@ trpgColorInfo::~trpgColorInfo() } void trpgColorInfo::Reset() { - bind = 0; - type = 0; - data.resize(0); + bind = 0; + type = 0; + data.resize(0); } void trpgGeometry::SetColors(int num,ColorType type,BindType bind,const trpgColor *data) { - trpgColorInfo ci; + trpgColorInfo ci; - if (num < 0) - return; + if (num < 0) + return; - // Set up color list - ci.type = type; - ci.bind = bind; - for (int i=0;i= texData.size())) + return; + trpgTexData *td = &texData[n]; - if (type == FloatData) { - td->floatData.push_back(static_cast(pt.x)); - td->floatData.push_back(static_cast(pt.y)); - } else { - td->doubleData.push_back(pt.x); - td->doubleData.push_back(pt.y); - } + if (type == FloatData) { + td->floatData.push_back(pt.x); + td->floatData.push_back(pt.y); + } else { + td->doubleData.push_back(pt.x); + td->doubleData.push_back(pt.y); + } +} +void trpgGeometry::AddTexCoord(DataType type,std::vector &pts) +{ + if (texData.size() != pts.size()) + return; + + for (unsigned int loop = 0; loop < pts.size(); loop++ ) { + trpgTexData *td = &texData[loop]; + + if (type == FloatData) { + td->floatData.push_back(pts[loop].x); + td->floatData.push_back(pts[loop].y); + } else { + td->doubleData.push_back(pts[loop].x); + td->doubleData.push_back(pts[loop].y); + } + } } void trpgGeometry::AddTexCoords(BindType bind) { - trpgTexData td; - td.bind = bind; - texData.push_back(td); + trpgTexData td; + td.bind = bind; + texData.push_back(td); } void trpgGeometry::SetEdgeFlags(int num,const char *flags) { - if (num < 0) - return; + if (num < 0) + return; - edgeFlags.resize(0); - for (int i=0;i(id) >= materials.size()) return false; - m = materials[id]; - if (m < 0) { - m = -m - 1; - isLocal = true; - } - return true; + 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 { - if (!isValid()) return false; - int nvf = vertDataFloat.size(); - int nvd = vertDataDouble.size(); - v = MAX(nvf,nvd); - v = v / 3; - return true; + if (!isValid()) return false; + 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) - for (i=0;i(vertDataDouble[i]); - return true; + if (!isValid()) return false; + if (vertDataFloat.size() != 0) + for (i=0;i(vertDataDouble[3*i+0]); - v[i].y() = static_cast(vertDataDouble[3*i+1]); - v[i].z() = static_cast(vertDataDouble[3*i+2]); - } - } - return true; + if (!isValid()) return false; + if (vertDataFloat.size() != 0) + for (i=0;i(idMax) >= vertDataFloat.size() && static_cast(idMax) >= vertDataDouble.size())) - return false; - if (vertDataFloat.size() > vertDataDouble.size()) { - pt.x = vertDataFloat[id]; - pt.y = vertDataFloat[id+1]; - pt.z = vertDataFloat[id+2]; - } else { - pt.x = vertDataDouble[id]; - pt.y = vertDataDouble[id+1]; - pt.z = vertDataDouble[id+2]; - } - return true; + int id = 3*n; + int idMax = 3*n+2; + if (id < 0 || (idMax >= vertDataFloat.size() && idMax >= vertDataDouble.size())) + return false; + if (vertDataFloat.size() > vertDataDouble.size()) { + pt.x = vertDataFloat[id]; + pt.y = vertDataFloat[id+1]; + pt.z = vertDataFloat[id+2]; + } else { + pt.x = vertDataDouble[id]; + pt.y = vertDataDouble[id+1]; + pt.z = vertDataDouble[id+2]; + } + return true; } bool trpgGeometry::GetNumNormal(int32 &n) const { - if (!isValid()) return false; - if (normDataFloat.size() != 0) - n = normDataFloat.size(); - if (normDataDouble.size() != 0) - n = normDataDouble.size(); - n = n / 3; - return true; + if (!isValid()) return false; + if (normDataFloat.size() != 0) + 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) - for (i=0;i(normDataDouble[i]); - return true; + if (!isValid()) return false; + if (normDataFloat.size() != 0) + for (i=0;i(normDataDouble[3*i+0]); - v[i].y() = static_cast(normDataDouble[3*i+1]); - v[i].z() = static_cast(normDataDouble[3*i+2]); - } - } - return true; + if (!isValid()) return false; + if (normDataFloat.size() != 0) + for (i=0;i(id) >= colors.size()) return false; - *ci = colors[id]; - return true; + 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 = texData.size(); - return true; + if (!isValid()) return false; + n = texData.size(); + return true; } bool trpgGeometry::GetTexCoordSet(int id,trpgTexData *tx) const { - if (!isValid() || id < 0 || static_cast(id) >= texData.size()) return false; - *tx = texData[id]; - return true; + 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 = edgeFlags.size(); - return true; + if (!isValid()) return false; + n = edgeFlags.size(); + return true; } bool trpgGeometry::GetEdgeFlags(char *e) const { - if (!isValid()) return false; - for (unsigned int i=0;i 0) { - buf.Begin(TRPG_GEOM_MATERIAL); - buf.Add((int32)materials.size()); - for (unsigned int i=0;i 0) { - buf.Begin(TRPG_GEOM_VERT32); - int32 num = vertDataFloat.size()/3; - buf.Add(num); - for (int i=0;i<3*num;i++) - buf.Add(vertDataFloat[i]); - buf.End(); - } - if (vertDataDouble.size() > 0) { - buf.Begin(TRPG_GEOM_VERT64); - int32 num = vertDataDouble.size()/3; - buf.Add(num); - for (int i=0;i<3*num;i++) - buf.Add(vertDataDouble[i]); - buf.End(); - } + /* Material info + Num materials + Material indicies + */ + if (materials.size() > 0) { + buf.Begin(TRPG_GEOM_MATERIAL); + buf.Add((int32)materials.size()); + for (i=0;i 0) { - buf.Begin(TRPG_GEOM_NORM32); - buf.Add((int32)normBind); - int32 num = normDataFloat.size()/3; - buf.Add(num); - for (int i=0;i<3*num;i++) - buf.Add(normDataFloat[i]); - buf.End(); - } - if (normDataDouble.size() > 0) { - buf.Begin(TRPG_GEOM_NORM64); - buf.Add((int32)normBind); - int32 num = normDataDouble.size()/3; - buf.Add(num); - for (int i=0;i<3*num;i++) - buf.Add(normDataDouble[i]); - buf.End(); - } + /* Vertices + Float and Double should never both be here + Num vertex + Vertex data + */ + if (vertDataFloat.size() > 0) { + buf.Begin(TRPG_GEOM_VERT32); + int32 num = vertDataFloat.size()/3; + buf.Add(num); + for (i=0;i<3*num;i++) + buf.Add(vertDataFloat[i]); + buf.End(); + } + if (vertDataDouble.size() > 0) { + buf.Begin(TRPG_GEOM_VERT64); + int32 num = vertDataDouble.size()/3; + buf.Add(num); + for (i=0;i<3*num;i++) + buf.Add(vertDataDouble[i]); + buf.End(); + } - /* Colors - Color binding - Num colors - Colors - */ - if (colors.size() > 0) { - for (unsigned int i=0;i 0) { + buf.Begin(TRPG_GEOM_NORM32); + buf.Add((int32)normBind); + int32 num = normDataFloat.size()/3; + buf.Add(num); + for (i=0;i<3*num;i++) + buf.Add(normDataFloat[i]); + buf.End(); + } + if (normDataDouble.size() > 0) { + buf.Begin(TRPG_GEOM_NORM64); + buf.Add((int32)normBind); + int32 num = normDataDouble.size()/3; + buf.Add(num); + for (i=0;i<3*num;i++) + buf.Add(normDataDouble[i]); + buf.End(); + } - /* Texture coordinates - Binding - Num coords - Texture coords - */ - for (unsigned int i=0;i 0) { + for (i=0;i 0) { - buf.Begin(TRPG_GEOM_EFLAG); - buf.Add((int32)edgeFlags.size()); - for (unsigned int i=0;i 0) { + buf.Begin(TRPG_GEOM_EFLAG); + buf.Add((int32)edgeFlags.size()); + for (i=0;iSetPrimType((trpgGeometry::PrimType)primType); - buf.Get(num); - if (num < 0) throw 1; - geom->SetNumPrims(num); - buf.Get(hasPrimLen); - if (hasPrimLen) { - buf.GetArray(num,&iData); + try { + switch (tok) { + case TRPG_GEOM_PRIM: + buf.Get(primType); + geom->SetPrimType((trpgGeometry::PrimType)primType); + buf.Get(num); + if (num < 0) throw 1; + geom->SetNumPrims(num); + buf.Get(hasPrimLen); + if (hasPrimLen) { + buf.GetArray(num,&iData); if (ALIGNMENT_WORKAROUND) { int32 *aligned; @@ -699,13 +664,13 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetPrimLengths(num,iData); - } - break; - case TRPG_GEOM_MATERIAL: - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(num,&iData); + geom->SetPrimLengths(num,iData); + } + break; + case TRPG_GEOM_MATERIAL: + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(num,&iData); if (ALIGNMENT_WORKAROUND) { int32 *aligned; @@ -715,12 +680,12 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetMaterials(num,iData); - break; - case TRPG_GEOM_VERT32: - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(3*num,&fData); + geom->SetMaterials(num,iData); + break; + case TRPG_GEOM_VERT32: + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(3*num,&fData); if (ALIGNMENT_WORKAROUND) { float32 *aligned; @@ -730,12 +695,12 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetVertices(num,fData); - break; - case TRPG_GEOM_VERT64: - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(3*num,&dData); + geom->SetVertices(num,fData); + break; + case TRPG_GEOM_VERT64: + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(3*num,&dData); if (ALIGNMENT_WORKAROUND) { float64 *aligned; @@ -745,14 +710,14 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetVertices(num,dData); - break; - case TRPG_GEOM_NORM32: - buf.Get(bind); - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(3*num,&fData); - if (ALIGNMENT_WORKAROUND) + geom->SetVertices(num,dData); + break; + case TRPG_GEOM_NORM32: + buf.Get(bind); + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(3*num,&fData); + if (ALIGNMENT_WORKAROUND) { float32 *aligned; aligned = (float32 *)calloc (3*num, sizeof(float32)); @@ -761,13 +726,13 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetNormals(num,(trpgGeometry::BindType)bind,fData); - break; - case TRPG_GEOM_NORM64: - buf.Get(bind); - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(3*num,&dData); + geom->SetNormals(num,(trpgGeometry::BindType)bind,fData); + break; + case TRPG_GEOM_NORM64: + buf.Get(bind); + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(3*num,&dData); if (ALIGNMENT_WORKAROUND) { float64 *aligned; @@ -777,14 +742,14 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetNormals(num,(trpgGeometry::BindType)bind,dData); - break; - case TRPG_GEOM_COLOR: - buf.Get(num); - if (num < 0) throw 1; - buf.Get(type); - buf.Get(bind); - buf.GetArray(num,&cData); + geom->SetNormals(num,(trpgGeometry::BindType)bind,dData); + break; + case TRPG_GEOM_COLOR: + buf.Get(num); + if (num < 0) throw 1; + buf.Get(type); + buf.Get(bind); + buf.GetArray(num,&cData); if (ALIGNMENT_WORKAROUND) { trpgColor *aligned; @@ -794,13 +759,13 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetColors(num,(trpgGeometry::ColorType)type,(trpgGeometry::BindType)bind,cData); - break; - case TRPG_GEOM_TEX32: - buf.Get(bind); - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(2*num,&fData); + geom->SetColors(num,(trpgGeometry::ColorType)type,(trpgGeometry::BindType)bind,cData); + break; + case TRPG_GEOM_TEX32: + buf.Get(bind); + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(2*num,&fData); if (ALIGNMENT_WORKAROUND) { float32 *aligned; @@ -810,13 +775,13 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetTexCoords(num,(trpgGeometry::BindType)bind,fData); - break; - case TRPG_GEOM_TEX64: - buf.Get(bind); - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(2*num,&dData); + geom->SetTexCoords(num,(trpgGeometry::BindType)bind,fData); + break; + case TRPG_GEOM_TEX64: + buf.Get(bind); + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(2*num,&dData); if (ALIGNMENT_WORKAROUND) { float64 *aligned; @@ -826,44 +791,44 @@ void *geomCB::Parse(trpgToken tok,trpgReadBuffer &buf) free (aligned); } else - geom->SetTexCoords(num,(trpgGeometry::BindType)bind,dData); - break; - case TRPG_GEOM_EFLAG: - buf.Get(num); - if (num < 0) throw 1; - buf.GetArray(num,&charData); - geom->SetEdgeFlags(num,charData); - break; - default: - // Skip - break; - } - } - catch (...) { - return NULL; - } + geom->SetTexCoords(num,(trpgGeometry::BindType)bind,dData); + break; + case TRPG_GEOM_EFLAG: + buf.Get(num); + if (num < 0) throw 1; + buf.GetArray(num,&charData); + geom->SetEdgeFlags(num,charData); + break; + default: + // Skip + break; + } + } + catch (...) { + return NULL; + } - return geom; + return geom; } // Read Geometry bool trpgGeometry::Read(trpgReadBuffer &buf) { - trpgr_Parser parse; - geomCB gcb; + trpgr_Parser parse; + geomCB gcb; - gcb.geom = this; - parse.AddCallback(TRPG_GEOM_PRIM,&gcb,false); - parse.AddCallback(TRPG_GEOM_MATERIAL,&gcb,false); - parse.AddCallback(TRPG_GEOM_VERT32,&gcb,false); - parse.AddCallback(TRPG_GEOM_VERT64,&gcb,false); - parse.AddCallback(TRPG_GEOM_NORM32,&gcb,false); - parse.AddCallback(TRPG_GEOM_NORM64,&gcb,false); - parse.AddCallback(TRPG_GEOM_COLOR,&gcb,false); - parse.AddCallback(TRPG_GEOM_TEX32,&gcb,false); - parse.AddCallback(TRPG_GEOM_TEX64,&gcb,false); - parse.AddCallback(TRPG_GEOM_EFLAG,&gcb,false); - parse.Parse(buf); + gcb.geom = this; + parse.AddCallback(TRPG_GEOM_PRIM,&gcb,false); + parse.AddCallback(TRPG_GEOM_MATERIAL,&gcb,false); + parse.AddCallback(TRPG_GEOM_VERT32,&gcb,false); + parse.AddCallback(TRPG_GEOM_VERT64,&gcb,false); + parse.AddCallback(TRPG_GEOM_NORM32,&gcb,false); + parse.AddCallback(TRPG_GEOM_NORM64,&gcb,false); + parse.AddCallback(TRPG_GEOM_COLOR,&gcb,false); + parse.AddCallback(TRPG_GEOM_TEX32,&gcb,false); + parse.AddCallback(TRPG_GEOM_TEX64,&gcb,false); + parse.AddCallback(TRPG_GEOM_EFLAG,&gcb,false); + parse.Parse(buf); - return isValid(); + return isValid(); } diff --git a/src/osgPlugins/txp/trpage_geom.h b/src/osgPlugins/txp/trpage_geom.h index 952dd744a..c68ac3045 100644 --- a/src/osgPlugins/txp/trpage_geom.h +++ b/src/osgPlugins/txp/trpage_geom.h @@ -17,14 +17,14 @@ #define _trpage_geom_h_ /* trpage_geom.h - Geometry and node definitions. - These are the objects that get read from and written to archives. - */ + Geometry and node definitions. + These are the objects that get read from and written to archives. + */ -#include "trpage_sys.h" +#include -#include "trpage_io.h" -#include "trpage_swap.h" +#include +#include // Forward declarations @@ -32,2504 +32,2938 @@ class trpgMaterial; class trpgTextureEnv; class trpgMatTable; -namespace osg -{ - class Vec3; -} - /* This is the archive header structure. There is one per TerraPage archive. - You don't write it directly, but instead fill it out and pass it to - a trpgwArchive (if you're writing), or get it back from a trpgr_Archive - (if you're reading). - If you're putting together a reader, just use the default methods for - reading this class. Since it's only read once, the overhead is low. - {group:Read/Write Classes} - */ + You don't write it directly, but instead fill it out and pass it to + a trpgwArchive (if you're writing), or get it back from a trpgr_Archive + (if you're reading). + If you're putting together a reader, just use the default methods for + reading this class. Since it's only read once, the overhead is low. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgHeader : public trpgReadWriteable { public: - trpgHeader(void); - ~trpgHeader(void); + trpgHeader(void); + ~trpgHeader(void); - // Set the TerraPage version info. - void SetVersion(int major,int minor); - // Set the database version info. - void SetDbVersion(int major,int minor); - /* Set the tile size for the given LOD. See GetTileSize for more info. - Each LOD must have its size set, otherwise the trpgHeader won't be valid. - You must set the number of LODs with SetNumLods first. - You should use the AddLod method if you can, which handles all of this. + // Set the TerraPage version info. + void SetVersion(int major,int minor); + // Set the database version info. + void SetDbVersion(int major,int minor); + /* Set the tile size for the given LOD. See GetTileSize for more info. + Each LOD must have its size set, otherwise the trpgHeader won't be valid. + You must set the number of LODs with SetNumLods first. + You should use the AddLod method if you can, which handles all of this. + */ + void SetTileSize(int lod,const trpg2dPoint &size); + // Origin defaults to 0,0,0 + void SetOrigin(const trpg3dPoint &); + // 2D archive extents. Must be set. + void SetExtents(const trpg2dPoint &sw,const trpg2dPoint &ne); + + typedef enum {DatabaseLocal,Absolute,TileLocal} trpgTileType; + // How the coordinates are treated with respect to real world values. + void SetTileOriginType(trpgTileType); + + /* Number of terrain LODs. If you use this method when building a database + you have to use the SetLodRange and SetLodSize methods on each LOD as well. + It's better to use AddLod instead of calling these three methods. + */ + void SetNumLods(int); + /* Number of tiles (x,y) for each LOD. + The single argument version assumes lod = 0, num lods = 1. + */ + void SetLodSize(int lod,const trpg2iPoint &); + void SetLodSize(const trpg2iPoint *); + /* Set the range for the given terrain LOD. + The single argument version assumes lod = 0, num lods = 1. + */ + void SetLodRange(int,float64); + void SetLodRange(const float64 *); + // Increase the number of terrain LODs, adding a new one with the given size and range + void AddLod(const trpg2iPoint &size,const trpg2dPoint &ext,float64 range); + + // Keep track of the maximum assigned group IDs (for tile paging) + void SetMaxGroupID(int); + /* Instead of keeping a count of all the group IDs you added and then + calling SetMaxGroupID, you can call this function and it will return + the next valid groupID to you. It will also keep track of the maximum. */ - void SetTileSize(int lod,const trpg2dPoint &size); - // Origin defaults to 0,0,0 - void SetOrigin(const trpg3dPoint &); - // 2D archive extents. Must be set. - void SetExtents(const trpg2dPoint &sw,const trpg2dPoint &ne); + int AddGroupID(void); - typedef enum {DatabaseLocal,Absolute,TileLocal} trpgTileType; - // How the coordinates are treated with respect to real world values. - void SetTileOriginType(trpgTileType); + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - /* Number of terrain LODs. If you use this method when building a database - you have to use the SetLodRange and SetLodSize methods on each LOD as well. - It's better to use AddLod instead of calling these three methods. - */ - void SetNumLods(int); - /* Number of tiles (x,y) for each LOD. - The single argument version assumes lod = 0, num lods = 1. - */ - void SetLodSize(int lod,const trpg2iPoint &); - void SetLodSize(const trpg2iPoint *); - /* Set the range for the given terrain LOD. - The single argument version assumes lod = 0, num lods = 1. - */ - void SetLodRange(int,float64); - void SetLodRange(const float64 *); - // Increase the number of terrain LODs, adding a new one with the given size and range - void AddLod(const trpg2iPoint &size,const trpg2dPoint &ext,float64 range); + // TerraVista version information is two integers. + bool GetVersion(int &,int &) const; + // Database version information is user defined. Put whatever you want here. + bool GetDbVersion(int &,int &) const; + /* This is the extents, in X/Y of a + single tile. All tiles within an LOD should be the same size (although this is not + enforced). It's also assumed that a given tile lives entirely within + its own extents (as calculated with this value), although that's not + enforced either. */ + bool GetTileSize(int,trpg2dPoint &) const; + /* The meaning of the database origin varies depending on the value returned + by GetTileOriginType. If the database is Absolute, then this value + will be the lower left corner. If the database is DatabaseLocal or + TileLocal you can use this value to determine the real world coordinates. + Just add origin + coordinate. + */ + bool GetOrigin(trpg3dPoint &) const; + /* These are the 2D extents that the database covers. You can use this + information to determine where the middle is, for example. + */ + bool GetExtents(trpg2dPoint &sw,trpg2dPoint &ne) const; + /* The tile origin type tells you the coordinate system of each database + tile. There are three type: + * Absolute - All coordinate values are absolute. No translation is required. + * DatabaseLocal - All coordinate values are local to the database. That is + if you want to determine the real world value do: coord + origin. + * TileLocal - Each tile has its own coordinate system starting from the lower left + corner. We do this to get around floating point accuracy problems (although we + can do Double coordinates if necessary, as well). To determine the + real world coordinate value do: tileID*tileSize + coord. + */ + bool GetTileOriginType(trpgTileType &) const; + /* Group IDs are used by TerraPage to hook level of detail structures together. + A TerraPage database can have an arbitrary number of terrain LODs, each stored + seperately. To hook them together we use trpgAttach nodes and number each group & + LOD node. This returns the maximum group ID in the file, which is important + to know if you're keeping an array of them. */ + bool GetMaxGroupID(int &) const; - // Keep track of the maximum assigned group IDs (for tile paging) - void SetMaxGroupID(int); - /* Instead of keeping a count of all the group IDs you added and then - calling SetMaxGroupID, you can call this function and it will return - the next valid groupID to you. It will also keep track of the maximum. - */ - int AddGroupID(void); + /* A TerraPage archive can contain any number of terrain LODs (a typical number is 4). + Each of these terrain LODs is accessed seperately (as are the tiles within them). + This returns the number of terrain LODs in the file. It will be at least 1. + See trpgAttach for instructions on how to hook the terrain LODs together. + */ + bool GetNumLods(int32 &) const; + /* A terrain LOD conceptually covers the entire database and is broken up + into some X x Y set of tiles. We make no assumptions about the number + of tiles in each terrain LOD. That's entirely up to the writer. This + returns the number of tiles in 2D for a given terrain LOD. */ + bool GetLodSize(int32,trpg2iPoint &) const; + /* It's up to the TerraPage archive writer to make their terrain LOD structure + work by using trpgAttach nodes. The scheme they're using may be quad-tree + or replacement LOD or something where the highest LOD isn't even terrain. + It really doesn't matter. However, the reader does need a hint as to + when tiles for a given LOD must be pulled in. This returns that range + in database coordinates (usually meters). + */ + bool GetLodRange(int32,float64 &) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Read/Write functions - // TerraVista version information is two integers. - bool GetVersion(int &,int &) const; - // Database version information is user defined. Put whatever you want here. - bool GetDbVersion(int &,int &) const; - /* This is the extents, in X/Y of a - single tile. All tiles within an LOD should be the same size (although this is not - enforced). It's also assumed that a given tile lives entirely within - its own extents (as calculated with this value), although that's not - enforced either. */ - bool GetTileSize(int,trpg2dPoint &) const; - /* The meaning of the database origin varies depending on the value returned - by GetTileOriginType. If the database is Absolute, then this value - will be the lower left corner. If the database is DatabaseLocal or - TileLocal you can use this value to determine the real world coordinates. - Just add origin + coordinate. - */ - bool GetOrigin(trpg3dPoint &) const; - /* These are the 2D extents that the database covers. You can use this - information to determine where the middle is, for example. - */ - bool GetExtents(trpg2dPoint &sw,trpg2dPoint &ne) const; - /* The tile origin type tells you the coordinate system of each database - tile. There are three type: - * Absolute - All coordinate values are absolute. No translation is required. - * DatabaseLocal - All coordinate values are local to the database. That is - if you want to determine the real world value do: coord + origin. - * TileLocal - Each tile has its own coordinate system starting from the lower left - corner. We do this to get around floating point accuracy problems (although we - can do Double coordinates if necessary, as well). To determine the - real world coordinate value do: tileID*tileSize + coord. - */ - bool GetTileOriginType(trpgTileType &) const; - /* Group IDs are used by TerraPage to hook level of detail structures together. - A TerraPage database can have an arbitrary number of terrain LODs, each stored - seperately. To hook them together we use trpgAttach nodes and number each group & - LOD node. This returns the maximum group ID in the file, which is important - to know if you're keeping an array of them. */ - bool GetMaxGroupID(int &) const; - - /* A TerraPage archive can contain any number of terrain LODs (a typical number is 4). - Each of these terrain LODs is accessed seperately (as are the tiles within them). - This returns the number of terrain LODs in the file. It will be at least 1. - See trpgAttach for instructions on how to hook the terrain LODs together. - */ - bool GetNumLods(int32 &) const; - /* A terrain LOD conceptually covers the entire database and is broken up - into some X x Y set of tiles. We make no assumptions about the number - of tiles in each terrain LOD. That's entirely up to the writer. This - returns the number of tiles in 2D for a given terrain LOD. */ - bool GetLodSize(int32,trpg2iPoint &) const; - /* It's up to the TerraPage archive writer to make their terrain LOD structure - work by using trpgAttach nodes. The scheme they're using may be quad-tree - or replacement LOD or something where the highest LOD isn't even terrain. - It really doesn't matter. However, the reader does need a hint as to - when tiles for a given LOD must be pulled in. This returns that range - in database coordinates (usually meters). - */ - bool GetLodRange(int32,float64 &) const; - - // Read/Write functions - - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; - // {secret} - bool ReadLodInfo(trpgReadBuffer &); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + // {secret} + bool ReadLodInfo(trpgReadBuffer &); protected: - int verMinor,verMajor; - int dbVerMinor,dbVerMajor; - int maxGroupID; - trpg2dPoint sw,ne; - trpg3dPoint origin; - trpgTileType tileType; + int verMinor,verMajor; + int dbVerMinor,dbVerMajor; + int maxGroupID; + trpg2dPoint sw,ne; + trpg3dPoint origin; + trpgTileType tileType; - int numLods; - std::vector tileSize; - std::vector lodSizes; - std::vector lodRanges; + int numLods; + std::vector tileSize; + std::vector lodSizes; + std::vector lodRanges; }; /* The Texture Environment is used by the trpgMaterial to define texture - related parameters. A trpgTextureEnv is associated with each texture - used in a trpgMaterial. So, for example, if there are 2 textures in - a material, there will be two texture environments. - Most of these parameters come straight from the OpenGL specification. It's - best to consult that for an exact meaning. + related parameters. A trpgTextureEnv is associated with each texture + used in a trpgMaterial. So, for example, if there are 2 textures in + a material, there will be two texture environments. + Most of these parameters come straight from the OpenGL specification. It's + best to consult that for an exact meaning. - If you doing a TerraPage reader, expect to get a trpgTextureEnv when - dealing with trpgMaterial definitions. If you're doing a writer, you'll - need to build these in the course of building a trpgMaterial. - {group:Read/Write Classes} - */ + If you doing a TerraPage reader, expect to get a trpgTextureEnv when + dealing with trpgMaterial definitions. If you're doing a writer, you'll + need to build these in the course of building a trpgMaterial. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTextureEnv : public trpgReadWriteable { - friend class trpgMatTable; + friend class trpgMatTable; public: - trpgTextureEnv(void); - ~trpgTextureEnv(void); + trpgTextureEnv(void); + ~trpgTextureEnv(void); - // Environment mode values - enum {Alpha,Blend,Decal,Modulate,AddDetail,ModulateDetail}; - // Set the application mode for the texture. - void SetEnvMode(int); - // Values used by SetMinFilter and SetMagFilter - enum {Point, Linear, MipmapPoint, MipmapLinear, - MipmapBilinear, MipmapTrilinear, Nearest}; - // Set the Minification filter for a texture - void SetMinFilter(int); - // Set the Magnification filter for a texture - void SetMagFilter(int); + // Environment mode values + enum {Alpha,Blend,Decal,Modulate,AddDetail,ModulateDetail}; + // Set the application mode for the texture. + void SetEnvMode(int); + // Values used by SetMinFilter and SetMagFilter + enum {Point, Linear, MipmapPoint, MipmapLinear, + MipmapBilinear, MipmapTrilinear, Nearest}; + // Set the Minification filter for a texture + void SetMinFilter(int); + // Set the Magnification filter for a texture + void SetMagFilter(int); - // Values used by SetWrap - enum {Clamp,Repeat}; - // Set the texture wrapping for S and T, respectively - void SetWrap(int,int); - // Set the texture border color - void SetBorderColor(const trpgColor &); + // Values used by SetWrap + enum {Clamp,Repeat}; + // Set the texture wrapping for S and T, respectively + void SetWrap(int,int); + // Set the texture border color + void SetBorderColor(const trpgColor &); - /* The environment mode controls how the texture is applied. - It can take the following values: - Alpha - Used to change the alpha values on a polygon. - Blend - Blended with the polygont color - Decal - Doesn't take polygon color into account. - Modulate - See openGL spec for definition. - */ - bool GetEnvMode(int32 &) const; - /* The Minification and Magnification filters control how texture - mipmap levels are used. We support the values: Point, Linear, - MipmapPoint, MipmapLinear, - MipmapBilinear, MipmapTrilinear, Nearest - */ - bool GetMinFilter(int32 &) const; - // Get the magnification filter - bool GetMagFilter(int32 &) const; - /* Wrapping controls how textures are used near the edges. - There are two valid values: Clamp, Repeat. - */ - bool GetWrap(int &,int &) const; - /* This maps straight into the OpenGL definition of border color. */ - bool GetBorderColor(trpgColor &) const; + /* The environment mode controls how the texture is applied. + It can take the following values: + Alpha - Used to change the alpha values on a polygon. + Blend - Blended with the polygon color + Decal - Doesn't take polygon color into account. + Modulate - See openGL spec for definition. + AddDetail - See openGL spec for definition. + ModulateDetail - See openGL spec for definition. + */ + bool GetEnvMode(int32 &) const; + /* The Minification and Magnification filters control how texture + mipmap levels are used. We support the values: Point, Linear, + MipmapPoint, MipmapLinear, + MipmapBilinear, MipmapTrilinear, Nearest + */ + bool GetMinFilter(int32 &) const; + // Get the magnification filter + bool GetMagFilter(int32 &) const; + /* Wrapping controls how textures are used near the edges. + There are two valid values: Clamp, Repeat. + */ + bool GetWrap(int &,int &) const; + /* This maps straight into the OpenGL definition of border color. */ + bool GetBorderColor(trpgColor &) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int envMode; - int minFilter; - int magFilter; - int wrapS,wrapT; - trpgColor borderCol; + int envMode; + int minFilter; + int magFilter; + int wrapS,wrapT; + trpgColor borderCol; }; /* The material definition for TerraPage encompasses those things that have to - do with visual display that can be indexed and disassociated from the - polygons themselves. This covers things like color, texture, alpha - and a few more obscure ones. - Materials are indexed centrally in a trpgMatTable. + do with visual display that can be indexed and disassociated from the + polygons themselves. This covers things like color, texture, alpha + and a few more obscure ones. + Materials are indexed centrally in a trpgMatTable. - This material definition borrows heavily from the OpenGL specification. - Please refer to that for a good definition of all the fields. + This material definition borrows heavily from the OpenGL specification. + Please refer to that for a good definition of all the fields. - If you're doing a TerraPage reader you'll need to deal with these in two places. - First, is when you read the archive header and get a trpgMatTable back. You'll - want to translate them into your own internal representation and keep track of - the mapping. Later, when parsing trpgGeometry nodes, you'll run into them - again. This time they will be material indices into a trpgMatTable. At that - point you'll want to map these indices into your own material definition table. + If you're doing a TerraPage reader you'll need to deal with these in two places. + First, is when you read the archive header and get a trpgMatTable back. You'll + want to translate them into your own internal representation and keep track of + the mapping. Later, when parsing trpgGeometry nodes, you'll run into them + again. This time they will be material indices into a trpgMatTable. At that + point you'll want to map these indices into your own material definition table. - If you're doing a TerraPage writer you'll need to create one of these for every - unique material-like object you have. Since trpgMaterial objects are indexed - centrally in a TerraPage archive, you should take advantage of that and use - as few as possible. After defining one, you'll want to add it to a trpgMatTable - and keep track of the material index that returns. This will be the mapping from - your own internal material table (or whatever you've got) into the archive's - material table. A trpgMaterial sets up defaults that work pretty well, so just - fill in what you need to use. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer you'll need to create one of these for every + unique material-like object you have. Since trpgMaterial objects are indexed + centrally in a TerraPage archive, you should take advantage of that and use + as few as possible. After defining one, you'll want to add it to a trpgMatTable + and keep track of the material index that returns. This will be the mapping from + your own internal material table (or whatever you've got) into the archive's + material table. A trpgMaterial sets up defaults that work pretty well, so just + fill in what you need to use. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgMaterial : public trpgReadWriteable { - friend class trpgMatTable; + friend class trpgMatTable; public: - trpgMaterial(void); - ~trpgMaterial(void); - // Set base material color - void SetColor(const trpgColor &); - // Ambient color - void SetAmbient(const trpgColor &); - // Diffuse color (the most commonly used) - void SetDiffuse(const trpgColor &); - // Specular color used in lighting - void SetSpecular(const trpgColor &); - // Emissive color used in lighting - void SetEmission(const trpgColor &); - // Shininess used in lighting - void SetShininess(float64); + trpgMaterial(void); + ~trpgMaterial(void); + // Set base material color + void SetColor(const trpgColor &); + // Ambient color + void SetAmbient(const trpgColor &); + // Diffuse color (the most commonly used) + void SetDiffuse(const trpgColor &); + // Specular color used in lighting + void SetSpecular(const trpgColor &); + // Emissive color used in lighting + void SetEmission(const trpgColor &); + // Shininess used in lighting + void SetShininess(float64); - enum {Smooth,Flat}; - // Shading model - void SetShadeModel(int); - // Point size - void SetPointSize(float64); - // Line width - void SetLineWidth(float64); - enum {Front,Back,FrontAndBack}; - // Cull mode. See GetCullMode - void SetCullMode(int); + enum {Smooth,Flat}; + // Shading model + void SetShadeModel(int); + // Point size + void SetPointSize(float64); + // Line width + void SetLineWidth(float64); + enum {Front,Back,FrontAndBack}; + // Cull mode. See GetCullMode + void SetCullMode(int); #ifdef Always - // None and Always appear to be defined on the SGI - // in such a way as to interfere with a local enum - // declaration within a class - enum {trNone,trAlways,Equal,GreaterThanOrEqual,GreaterThan, - LessThanOrEqual,LessThan,Never,NotEqual}; + // None and Always appear to be defined on the SGI + // in such a way as to interfere with a local enum + // declaration within a class + enum {trNone,trAlways,Equal,GreaterThanOrEqual,GreaterThan, + LessThanOrEqual,LessThan,Never,NotEqual}; #else - enum {None,Always,Equal,GreaterThanOrEqual,GreaterThan, - LessThanOrEqual,LessThan,Never,NotEqual}; + enum {None,Always,Equal,GreaterThanOrEqual,GreaterThan, + LessThanOrEqual,LessThan,Never,NotEqual}; #endif - // Alpha Function. See GetAlphaFunc - void SetAlphaFunc(int); - // Alpha Ref value. See GetAlphaRef - void SetAlphaRef(float64); - // Alpha value for any polygon using this material - void SetAlpha(float64); - // Generate normals automatically from geometry - void SetAutoNormal(bool); + // Alpha Function. See GetAlphaFunc + void SetAlphaFunc(int); + // Alpha Ref value. See GetAlphaRef + void SetAlphaRef(float64); + // Alpha value for any polygon using this material + void SetAlpha(float64); + // Generate normals automatically from geometry + void SetAutoNormal(bool); - /* Set the total number of textures used by this trpgMaterial. - This works with SetTexture. We recommend that you used - AddTexture instead of these two methods. */ - void SetNumTexture(int); - /* Works with SetNumTexture. - This method sets the texture ID and texture environment for the given - texture instance in this material. Use AddTexture instead, if you can. - */ - void SetTexture(int no,int id,const trpgTextureEnv &); - /* This method takes a texture ID that refers to a trpgTexTable and a - trpgTextureEnv which specifies the application information relating - to this texture instance. It returns the reference number (i.e. the - 3rd texture in this material, etc...) - */ - int AddTexture(int,const trpgTextureEnv &); + /* Set the total number of textures used by this trpgMaterial. + This works with SetTexture. We recommend that you used + AddTexture instead of these two methods. */ + void SetNumTexture(int); + /* Works with SetNumTexture. + This method sets the texture ID and texture environment for the given + texture instance in this material. Use AddTexture instead, if you can. + */ + void SetTexture(int no,int id,const trpgTextureEnv &); + /* This method takes a texture ID that refers to a trpgTexTable and a + trpgTextureEnv which specifies the application information relating + to this texture instance. It returns the reference number (i.e. the + 3rd texture in this material, etc...) + */ + int AddTexture(int,const trpgTextureEnv &); - // Number of tiles this material is used in - void SetNumTiles(int); - // Adds a count to the number of tiles this material is used in and returns that number - int AddTile(void); + // Number of tiles this material is used in + void SetNumTiles(int); + // Adds a count to the number of tiles this material is used in and returns that number + int AddTile(void); - // Sets bump map status (color etc... isn't important) - void SetIsBumpMap(bool); + // Sets bump map status (color etc... isn't important) + void SetIsBumpMap(bool); - // Return the current color - bool GetColor(trpgColor &) const; - // Returns the ambient color - bool GetAmbient(trpgColor &) const; - // Returns the diffuse color (the most commonly used color) - bool GetDiffuse(trpgColor &) const; - // Specular color used for lighting - bool GetSpecular(trpgColor &) const; - // Emissive color used for lighting - bool GetEmission(trpgColor &) const; - // Shininess used for lighting - bool GetShininess(float64 &) const; + // Set an attribute (e.g. fid/smc) + enum {TR_FID,TR_SMC,TR_STP,TR_SWC}; + void SetAttr(int attrCode,int val); - // The shading model can be either Smooth or Flat - bool GetShadeModel(int &) const; - // Point size - bool GetPointSize(float64 &) const; - // Line width - bool GetLineWidth(float64 &) const; - /* Cull mode determines whether geometry will be rejected if it's Front facing, Back - facing, or neither (FrontAndBack) - */ - bool GetCullMode(int &) const; - /* This controls what alpha values in a texture mean. It can take the values: - None,Always,Equal,GreaterThanOrEqual,GreaterThan, - LessThanOrEqual,LessThan,Never,NotEqual - */ - bool GetAlphaFunc(int &) const; - /* The Alpha Ref is a value used in some of the Alpha Functions */ - bool GetAlphaRef(float64 &) const; - // Whether or not to generate normals from geometry - bool GetAutoNormal(bool &) const; - // A single Alpha value that applies to any polygons using this material - bool GetAlpha(float64 &) const; - /* One of the useful things about TerraPage is that it contains enough information - to page textures & materials as well as terrain. This is part of that. - It returns the number of tiles this material is used in. The trpgTexture has - its own which is used for paging textures. You only want to pay attention to - this if you have some costly material definition in your hardware and so have - to swap them in and out. - */ - bool GetNumTile(int &) const; + // Return the current color + bool GetColor(trpgColor &) const; + // Returns the ambient color + bool GetAmbient(trpgColor &) const; + // Returns the diffuse color (the most commonly used color) + bool GetDiffuse(trpgColor &) const; + // Specular color used for lighting + bool GetSpecular(trpgColor &) const; + // Emissive color used for lighting + bool GetEmission(trpgColor &) const; + // Shininess used for lighting + bool GetShininess(float64 &) const; - /* There can be multiple textures per material. This returns the number. - The first is the base texture, so just use that if you can only do 1 texture per poly. - */ - bool GetNumTexture(int &) const; - /* TerraPage supports multiple textures per polygon. Some hardware can do this, - some can't. If you can support it, here's how this works. - This method returns the texture definition for the Nth texture used in this material. - That consists of a texture ID which points into a trpgTexTable and a trpgTextureEnv - which contains the texture application information. - Multiple materials can also appear per trpgGeometry, so be aware that there are - two ways to have multiple textures per polygon. - */ - bool GetTexture(int no,int &id,trpgTextureEnv &) const; + // The shading model can be either Smooth or Flat + bool GetShadeModel(int &) const; + // Point size + bool GetPointSize(float64 &) const; + // Line width + bool GetLineWidth(float64 &) const; + /* Cull mode determines whether geometry will be rejected if it's Front facing, Back + facing, or neither (FrontAndBack) + */ + bool GetCullMode(int &) const; + /* This controls what alpha values in a texture mean. It can take the values: + None,Always,Equal,GreaterThanOrEqual,GreaterThan, + LessThanOrEqual,LessThan,Never,NotEqual + */ + bool GetAlphaFunc(int &) const; + /* The Alpha Ref is a value used in some of the Alpha Functions */ + bool GetAlphaRef(float64 &) const; + // Whether or not to generate normals from geometry + bool GetAutoNormal(bool &) const; + // A single Alpha value that applies to any polygons using this material + bool GetAlpha(float64 &) const; + /* One of the useful things about TerraPage is that it contains enough information + to page textures & materials as well as terrain. This is part of that. + It returns the number of tiles this material is used in. The trpgTexture has + its own which is used for paging textures. You only want to pay attention to + this if you have some costly material definition in your hardware and so have + to swap them in and out. + */ + bool GetNumTile(int &) const; - // Return whether or not this material is a bump map - bool GetIsBumpMap(bool &) const; + /* There can be multiple textures per material. This returns the number. + The first is the base texture, so just use that if you can only do 1 texture per poly. + */ + bool GetNumTexture(int &) const; + /* TerraPage supports multiple textures per polygon. Some hardware can do this, + some can't. If you can support it, here's how this works. + This method returns the texture definition for the Nth texture used in this material. + That consists of a texture ID which points into a trpgTexTable and a trpgTextureEnv + which contains the texture application information. + Multiple materials can also appear per trpgGeometry, so be aware that there are + two ways to have multiple textures per polygon. + */ + bool GetTexture(int no,int &id,trpgTextureEnv &) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Return whether or not this material is a bump map + bool GetIsBumpMap(bool &) const; - // Note: Need to do equality operator + // Get an attribute (e.g. fid/smc) + bool GetAttr(int attrCode,int &val) const; + + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + + // Note: Need to do equality operator protected: - bool isBump; - trpgColor color; - trpgColor ambient; - trpgColor diffuse; - trpgColor specular; - trpgColor emission; - float64 shininess; - int shadeModel; - float64 pointSize; - float64 lineWidth; - int cullMode; - int alphaFunc; - float64 alpha; - float64 alphaRef; - bool autoNormal; - int numTex; - int32 numTile; - std::vector texids; - std::vector texEnvs; + bool isBump; + trpgColor color; + trpgColor ambient; + trpgColor diffuse; + trpgColor specular; + trpgColor emission; + float64 shininess; + int shadeModel; + float64 pointSize; + float64 lineWidth; + int cullMode; + int alphaFunc; + float64 alpha; + float64 alphaRef; + bool autoNormal; + int numTex; + int32 numTile; + struct _attrSet { + int fid; + int smc; + int stp; + int swc; + } attrSet; + std::vector texids; + std::vector texEnvs; }; -/* The lights in TerraPage -*/ - +/* Light attributes are used by the trpgLight objects. + They control all aspects of how lights are constructed and + displayed. Lights are very complicated and often system specific. + It's best to consult the Get methods to figure out what options + are available. + */ TX_EXDECL class TX_CLDECL trpgLightAttr : public trpgReadWriteable { public: - // Default constructor - trpgLightAttr(void); - // Copy constructor - trpgLightAttr(const trpgLightAttr &); - // Destructor - ~trpgLightAttr(void); + // Default constructor + trpgLightAttr(void); + // Copy constructor + trpgLightAttr(const trpgLightAttr &); + // Destructor + ~trpgLightAttr(void); - // Light Flags - enum { - // Light flags - trpg_Day = 0x0001, - trpg_Dusk = 0x0002, - trpg_Night = 0x0004, - trpg_Directional = 0x0008, - trpg_BackColor = 0x0010, - trpg_Reflective = 0x0020, + // Light Flags + enum { + // Light flags + trpg_Day = 0x0001, + trpg_Dusk = 0x0002, + trpg_Night = 0x0004, + trpg_Directional = 0x0008, + trpg_BackColor = 0x0010, + trpg_Reflective = 0x0020, - // Animation flags - trpg_Flashing = 0x0100, - trpg_Rotating = 0x0200, - trpg_ClockWise = 0x0400, - trpg_AnimationMask =0x0f00, + // Animation flags + trpg_Flashing = 0x0100, + trpg_Rotating = 0x0200, + trpg_ClockWise = 0x0400, + trpg_AnimationMask =0x0f00, - // Performer light flags - trpg_Perspective = 0x1000, - trpg_Fade = 0x2000, - trpg_ZBuffer = 0x4000, - trpg_FogPunch = 0x8000, - trpg_PerformerMask =0xf000 - } LightFlags; + // Performer light flags + trpg_Perspective = 0x1000, + trpg_Fade = 0x2000, + trpg_ZBuffer = 0x4000, + trpg_FogPunch = 0x8000, + trpg_PerformerMask =0xf000 + } LightFlags; - // Light Type - typedef enum { - trpg_Raster, - trpg_Calligraphic, - trpg_RASCAL - } LightType; + // Light Type + typedef enum { + trpg_Raster, + trpg_Calligraphic, + trpg_RASCAL + } LightType; - // Light Directionality - typedef enum { - trpg_Omnidirectional, - trpg_Bidirectional, - trpg_Unidirectional - } LightDirectionality; + // Light Directionality + typedef enum { + trpg_Omnidirectional, + trpg_Bidirectional, + trpg_Unidirectional + } LightDirectionality; - // Light Quality - typedef enum { - trpg_Off, - trpg_Low, - trpg_Medium, - trpg_High, - trpg_Undefined - } LightQuality; + // Light Quality + typedef enum { + trpg_Off, + trpg_Low, + trpg_Medium, + trpg_High, + trpg_Undefined + } LightQuality; - // Struct for Performer Lights - struct PerformerAttr { - PerformerAttr() : flags(0),minPixelSize(0),maxPixelSize(0),actualSize(0), - transparentPixelSize(0),transparentFallofExp(0),transparentScale(0), - transparentClamp(0),fogScale(0) {}; - int32 flags; - float64 minPixelSize; - float64 maxPixelSize; - float64 actualSize; - float64 transparentPixelSize; - float64 transparentFallofExp; - float64 transparentScale; - float64 transparentClamp; - float64 fogScale; - }; + // Struct for Performer Lights + typedef struct PerformerAttr { + PerformerAttr() : flags(0),minPixelSize(0),maxPixelSize(0),actualSize(0), + transparentPixelSize(0),transparentFallofExp(0),transparentScale(0), + transparentClamp(0),fogScale(0) {}; + int32 flags; + float64 minPixelSize; + float64 maxPixelSize; + float64 actualSize; + float64 transparentPixelSize; + float64 transparentFallofExp; + float64 transparentScale; + float64 transparentClamp; + float64 fogScale; + }; - // Struct for Animated Lights - struct AnimationAttr { - AnimationAttr() : period(0),phaseDelay(0),timeOn(0),vector(trpg3dPoint(0,0,0)),flags(0) {}; - float64 period; - float64 phaseDelay; - float64 timeOn; - trpg3dPoint vector; - int32 flags; - }; + // Struct for Animated Lights + typedef struct AnimationAttr { + AnimationAttr() : period(0),phaseDelay(0),timeOn(0),vector(trpg3dPoint(0,0,0)),flags(0) {}; + float64 period; + float64 phaseDelay; + float64 timeOn; + trpg3dPoint vector; + int32 flags; + }; - // Struct for Calligraphic Lights - struct CalligraphicAttr { - CalligraphicAttr() : drawOrder(0),minDefocus(0),maxDefocus(0) {} ; - int32 drawOrder; - float64 minDefocus; - float64 maxDefocus; - }; + // Struct for Calligraphic Lights + typedef struct CalligraphicAttr { + CalligraphicAttr() : drawOrder(0),minDefocus(0),maxDefocus(0) {} ; + int32 drawOrder; + float64 minDefocus; + float64 maxDefocus; + }; - // Setters - // Set Type - void SetType( trpgLightAttr::LightType ); + // Setters + // Set Type + void SetType( trpgLightAttr::LightType ); - // Set Directionality - void SetDirectionality( trpgLightAttr::LightDirectionality ); + // Set Directionality + void SetDirectionality( trpgLightAttr::LightDirectionality ); - // Set Front Color - void SetFrontColor( trpgColor ); + // Set Front Color + void SetFrontColor( trpgColor ); - // Set Front Intensity - void SetFrontIntensity( float64 ); + // Set Front Intensity + void SetFrontIntensity( float64 ); - // Set Back Color - void SetBackColor( trpgColor ); + // Set Back Color + void SetBackColor( trpgColor ); - // Set Back Intensity - void SetBackIntensity( float64 ); + // Set Back Intensity + void SetBackIntensity( float64 ); - // Set Normal - void SetNormal( trpg3dPoint ); + // Set Normal + void SetNormal( trpg3dPoint ); - // Set SMC - void SetSMC( int32 ); + // Set SMC + void SetSMC( int32 ); - // Set FID - void SetFID( int32 ); + // Set FID + void SetFID( int32 ); - // Set Flags - void SetFlags( int32 ); + // Set Flags + void SetFlags( int32 ); - // Set Horizontal Lobe Angle - void SetHLobeAngle( float64 ); + // Set Horizontal Lobe Angle + void SetHLobeAngle( float64 ); - // Set Vertical Lobe Angle - void SetVLobeAngle( float64 ); + // Set Vertical Lobe Angle + void SetVLobeAngle( float64 ); - // Set Lobe Roll Angle - void SetLobeRollAngle( float64 ); + // Set Lobe Roll Angle + void SetLobeRollAngle( float64 ); - // Set Lobe Falloff - void SetLobeFalloff( float64 ); + // Set Lobe Falloff + void SetLobeFalloff( float64 ); - // Set Ambient Intensity - void SetAmbient( float64 ); + // Set Ambient Intensity + void SetAmbient( float64 ); - // Set Quality - void SetQuality( trpgLightAttr::LightQuality ); + // Set Quality + void SetQuality( trpgLightAttr::LightQuality ); - // Set RASCAL Significance - void SetRascalSignificance( float64 ); + // Set RASCAL Significance + void SetRascalSignificance( float64 ); - // Set Random Intensity - void SetRandomIntensity( trpgLightAttr::LightQuality ); + // Set Random Intensity + void SetRandomIntensity( trpgLightAttr::LightQuality ); - // Set the attributes for Calligraphics Lights - void SetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& ); + // Set the attributes for Calligraphics Lights + void SetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& ); - // Set Calligraphic Draw Order - void SetCalligraphicDrawOrder( int32 ); + // Set Calligraphic Draw Order + void SetCalligraphicDrawOrder( int32 ); - // Set Calligraphic Minimum Defocus - void SetCalligraphicMinDefocus( float64 ); + // Set Calligraphic Minimum Defocus + void SetCalligraphicMinDefocus( float64 ); - // Set Calligraphic Maximum Defocus - void SetCalligraphicMaxDefocus( float64 ); + // Set Calligraphic Maximum Defocus + void SetCalligraphicMaxDefocus( float64 ); - // Set the attributes for Performer Lights - void SetPerformerAttr( trpgLightAttr::PerformerAttr& ); + // Set the attributes for Performer Lights + void SetPerformerAttr( trpgLightAttr::PerformerAttr& ); - // Set the flags for Perfromer Lights - void SetPerformerFlags( int32 ); + // Set the flags for Perfromer Lights + void SetPerformerFlags( int32 ); - // Set the minimum pixel size for Performer Lights - void SetPerformerMinPixelSize( float64 ); + // Set the minimum pixel size for Performer Lights + void SetPerformerMinPixelSize( float64 ); - // Set the maximum pixel size for Performer Lights - void SetPerformerMaxPixelSize( float64 ); + // Set the maximum pixel size for Performer Lights + void SetPerformerMaxPixelSize( float64 ); - // Set the actual size for Performer Lights - void SetPerformerActualSize( float64 ); + // Set the actual size for Performer Lights + void SetPerformerActualSize( float64 ); - // Set the transparent pixel size for Performer Lights - void SetPerformerTpPixelSize( float64 ); + // Set the transparent pixel size for Performer Lights + void SetPerformerTpPixelSize( float64 ); - // Set the transparent Falloff exponent for Performer Lights - void SetPerformerTpFalloffExp( float64 ); + // Set the transparent Falloff exponent for Performer Lights + void SetPerformerTpFalloffExp( float64 ); - // Set the transparent scale for Performer Lights - void SetPerformerTpScale( float64 ); - - // Set the transparent clamp for Performer Lights - void SetPerformerTpClamp( float64 ); + // Set the transparent scale for Performer Lights + void SetPerformerTpScale( float64 ); + + // Set the transparent clamp for Performer Lights + void SetPerformerTpClamp( float64 ); - // Set the fog scale for Performer Lights - void SetPerformerFogScale( float64 ); + // Set the fog scale for Performer Lights + void SetPerformerFogScale( float64 ); - // Set the attributes for animated lights - void SetAnimationAttr( trpgLightAttr::AnimationAttr& ); + // Set the attributes for animated lights + void SetAnimationAttr( trpgLightAttr::AnimationAttr& ); - // Set the animation period for animated lights - void SetAnimationPeriod( float64 ); + // Set the animation period for animated lights + void SetAnimationPeriod( float64 ); - // Set the animation phase delay for animated lights - void SetAnimationPhaseDelay( float64 ); + // Set the animation phase delay for animated lights + void SetAnimationPhaseDelay( float64 ); - // Set the time on for animated lights - void SetAnimationTimeOn( float64 ); + // Set the time on for animated lights + void SetAnimationTimeOn( float64 ); - // Set the animation vector for animated lights - void SetAnimationVector( trpg3dPoint ); + // Set the animation vector for animated lights + void SetAnimationVector( trpg3dPoint ); - // Set the flags for animated lights - void SetAnimationFlags( int32 ); + // Set the flags for animated lights + void SetAnimationFlags( int32 ); - // Getters - // See the comments for the Setters - void GetType( trpgLightAttr::LightType& ); - void GetDirectionality( trpgLightAttr::LightDirectionality& ); - void GetFrontColor( trpgColor& ); - void GetFrontIntensity( float64& ); - void GetBackColor( trpgColor& ); - void GetBackIntensity( float64& ); - void GetNormal( trpg3dPoint& ); - void GetSMC( int32& ); - void GetFID( int32& ); - void GetFlags( int32& ); - void GetHLobeAngle( float64& ); - void GetVLobeAngle( float64& ); - void GetLobeRollAngle( float64& ); - void GetLobeFalloff( float64& ); - void GetAmbient( float64& ); - void GetQuality( trpgLightAttr::LightQuality& ); - void GetRascalSignificance( float64& ); - void GetRandomIntensity( trpgLightAttr::LightQuality& ); - void GetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& ); - void GetCalligraphicDrawOrder( int32& ); - void GetCalligraphicMinDefocus( float64& ); - void GetCalligraphicMaxDefocus( float64& ); - void GetPerformerAttr( trpgLightAttr::PerformerAttr& ); - void GetPerformerFlags( int32& ); - void GetPerformerMinPixelSize( float64& ); - void GetPerformerMaxPixelSize( float64& ); - void GetPerformerActualSize( float64& ); - void GetPerformerTpPixelSize( float64& ); - void GetPerformerTpFalloffExp( float64& ); - void GetPerformerTpScale( float64& ); - void GetPerformerTpClamp( float64& ); - void GetPerformerFogScale( float64& ); - void GetAnimationAttr( trpgLightAttr::AnimationAttr& ); - void GetAnimationPeriod( float64& ); - void GetAnimationPhaseDelay( float64& ); - void GetAnimationTimeOn( float64& ); - void GetAnimationVector( trpg3dPoint& ); - void GetAnimationFlags( int32& ); + // Set the comment for this light point type + void SetComment(const char *); - // operators - trpgLightAttr& operator = (const trpgLightAttr&); - bool operator == (const trpgLightAttr&); - bool operator != (const trpgLightAttr&); + // Getters + // See the comments for the Setters + void GetType( trpgLightAttr::LightType& ); + void GetDirectionality( trpgLightAttr::LightDirectionality& ); + void GetFrontColor( trpgColor& ); + void GetFrontIntensity( float64& ); + void GetBackColor( trpgColor& ); + void GetBackIntensity( float64& ); + void GetNormal( trpg3dPoint& ); + void GetSMC( int32& ); + void GetFID( int32& ); + void GetFlags( int32& ); + void GetHLobeAngle( float64& ); + void GetVLobeAngle( float64& ); + void GetLobeRollAngle( float64& ); + void GetLobeFalloff( float64& ); + void GetAmbient( float64& ); + void GetQuality( trpgLightAttr::LightQuality& ); + void GetRascalSignificance( float64& ); + void GetRandomIntensity( trpgLightAttr::LightQuality& ); + void GetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& ); + void GetCalligraphicDrawOrder( int32& ); + void GetCalligraphicMinDefocus( float64& ); + void GetCalligraphicMaxDefocus( float64& ); + void GetPerformerAttr( trpgLightAttr::PerformerAttr& ); + void GetPerformerFlags( int32& ); + void GetPerformerMinPixelSize( float64& ); + void GetPerformerMaxPixelSize( float64& ); + void GetPerformerActualSize( float64& ); + void GetPerformerTpPixelSize( float64& ); + void GetPerformerTpFalloffExp( float64& ); + void GetPerformerTpScale( float64& ); + void GetPerformerTpClamp( float64& ); + void GetPerformerFogScale( float64& ); + void GetAnimationAttr( trpgLightAttr::AnimationAttr& ); + void GetAnimationPeriod( float64& ); + void GetAnimationPhaseDelay( float64& ); + void GetAnimationTimeOn( float64& ); + void GetAnimationVector( trpg3dPoint& ); + void GetAnimationFlags( int32& ); + const char *GetComment(); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); + // operators + trpgLightAttr& operator = (const trpgLightAttr&); + bool operator == (const trpgLightAttr&); + bool operator != (const trpgLightAttr&); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); - // Validity check - bool isValid(void) const; + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; + + // Resets the contents back to empty + void Reset(void); protected: - struct DataSet { - LightType type; - LightDirectionality directionality; - trpgColor frontColor; - float64 frontIntensity; - trpgColor backColor; - float64 backIntensity; - trpg3dPoint normal; - int32 smc; - int32 fid; - int32 flags; - float64 horizontalLobeAngle; - float64 verticalLobeAngle; - float64 lobeRollAngle; - float64 lobeFalloff; - float64 ambientIntensity; - LightQuality quality; - LightQuality randomIntensity; - float64 rascalSignificance; - CalligraphicAttr calligraphicAttr; - PerformerAttr performerAttr; - AnimationAttr animationAttr; - } data; + struct DataSet { + LightType type; + LightDirectionality directionality; + trpgColor frontColor; + float64 frontIntensity; + trpgColor backColor; + float64 backIntensity; + trpg3dPoint normal; + int32 smc; + int32 fid; + int32 flags; + float64 horizontalLobeAngle; + float64 verticalLobeAngle; + float64 lobeRollAngle; + float64 lobeFalloff; + float64 ambientIntensity; + LightQuality quality; + LightQuality randomIntensity; + float64 rascalSignificance; + CalligraphicAttr calligraphicAttr; + PerformerAttr performerAttr; + AnimationAttr animationAttr; + char *commentStr; + } data; }; +/* Lights in TerraPage are called out as separate objects. The trpgLight + object will appear in the scenegraph as an individual light structure. + These may consist of single lights or light strings. + The trpgLight points into the trpgLightTable for its attributes. + */ TX_EXDECL class TX_CLDECL trpgLight : public trpgReadWriteable { public: - // Default constructor - trpgLight(void); - // Copy constructor - trpgLight(const trpgLight &); - // Destructor - ~trpgLight(void); + // Default constructor + trpgLight(void); + // Copy constructor + trpgLight(const trpgLight &); + // Destructor + ~trpgLight(void); - // Set the index pointing into the Light Table - void SetAttrIndex(int); + // Set the index pointing into the Light Table + void SetAttrIndex(int); - // Add a new location this light is located at - void AddVertex(trpg3dPoint); + // Add a new location this light is located at + void AddVertex(trpg3dPoint); - // Returns the number of locations, this light is located at - void GetNumVertices(uint32 &) const; + // Returns the number of locations, this light is located at + void GetNumVertices(uint32 &) const; - // Returns the location at a given index - bool GetVertex(uint32, trpg3dPoint &) const; + // Returns the location at a given index + bool GetVertex(uint32, trpg3dPoint &) const; - // Returns the whole list of vertices - bool GetVertices(trpg3dPoint *) const; - bool GetVertices(float64 *) const; - bool GetVertices(float32 *) const; + // Returns the whole list of vertices + bool GetVertices(trpg3dPoint *) const; + bool GetVertices(float64 *) const; + bool GetVertices(float32 *) const; -// Returns the index of the Light Attributes in the Light Table - void GetAttrIndex(int &) const; - // Validity check - bool isValid(void) const; + // Returns the index of the Light Attributes in the Light Table + void GetAttrIndex(int &) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); + // Resets the contents back to empty + void Reset(void); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); - // operator - trpgLight& operator = (const trpgLight &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + + // operator + trpgLight& operator = (const trpgLight &); protected: - // Here we store the light locations - std::vector lightPoints; - int index; + // Here we store the light locations + std::vector lightPoints; + int index; }; +/* The Light Table is stored in the TerraPage header and consolidates + the attributes for all light points. trpgLight structures will index + into this table to define their appearance. + */ TX_EXDECL class TX_CLDECL trpgLightTable : public trpgReadWriteable { public: - // Default constructor - trpgLightTable(void); + // Default constructor + trpgLightTable(void); - // Copy constructor - trpgLightTable(const trpgLightTable &); + // Copy constructor + trpgLightTable(const trpgLightTable &); - // Destructor - ~trpgLightTable(void); + // Destructor + ~trpgLightTable(void); - // Adds the given light attrib to the table and increments the total light attrib count. - int AddLightAttr(const trpgLightAttr&); + // Adds the given light attrib to the table and increments the total light attrib count. + int AddLightAttr(const trpgLightAttr&); - /* This is the same as AddLightAttr except that it searches for a matching light attrib - first. This is convenient for writers who aren't keeping track of their - own light attrib internally. - */ - int FindAddLightAttr(const trpgLightAttr&); + /* This is the same as AddLightAttr except that it searches for a matching light attrib + first. This is convenient for writers who aren't keeping track of their + own light attrib internally. + */ + int FindAddLightAttr(const trpgLightAttr&); - // Returns the number of light attrib in this table - bool GetNumLightAttrs(int &) const; + // Returns the number of light attrib in this table + bool GetNumLightAttrs(int &) const; - // Returns a pointer to a light attrib from a given index - const trpgLightAttr* GetLightAttrRef(int) const; + // Returns a pointer to a light attrib from a given index + const trpgLightAttr* GetLightAttrRef(int) const; - // Validity check - bool isValid(void) const; + // Validity check + bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // operator - trpgLightTable & operator = (const trpgLightTable &); + // operator + trpgLightTable & operator = (const trpgLightTable &); protected: - // Here we store the light attributes - std::vector lightList; + // Here we store the light attributes + std::vector lightList; }; /* Range Info - These classes live within the trpgRangeTable. They encapsulate range - information that ties trpgLod nodes together. Their purpose is to provide - data to the run-time system about the relative priorities of classes of - features. See the trpgRangeTable for a complete explanation. + These classes live within the trpgRangeTable. They encapsulate range + information that ties trpgLod nodes together. Their purpose is to provide + data to the run-time system about the relative priorities of classes of + features. See the trpgRangeTable for a complete explanation. */ TX_EXDECL class TX_CLDECL trpgRange : public trpgReadWriteable { public: - trpgRange(void); - ~trpgRange(void); + trpgRange(void); + ~trpgRange(void); - // Copy constructor - trpgRange(const trpgRange &); + // Copy constructor + trpgRange(const trpgRange &); - // Set the name and subName (can be NULL) - void SetCategory(char *cat,char *subCat); + // Set the name and subName (can be NULL) + void SetCategory(const char *cat,const char *subCat); - /* Get the name and subName - Name should be the major category (e.g. "trees") - SubName should be the minor category (e.g. "big trees") - */ - void GetCategory(char *cat,int maxCatLen,char *subCat,int maxSubCatLen) const; + /* Get the name and subName + Name should be the major category (e.g. "trees") + SubName should be the minor category (e.g. "big trees") + */ + void GetCategory(char *cat,int maxCatLen,char *subCat,int maxSubCatLen) const; - // Set the lod info - void SetLodInfo(double in,double out); + // Set the lod info + void SetLodInfo(double in,double out); - // Get the lod info (this will be duplicated in the trpgLod node) - // However, you may want to change these values yourself during a run - void GetLodInfo(double &in,double &out) const; + // Get the lod info (this will be duplicated in the trpgLod node) + // However, you may want to change these values yourself during a run + void GetLodInfo(double &in,double &out) const; - // Set the priority - void SetPriority(int); + // Set the priority + void SetPriority(int); - /* Get the priority. - Priority is a hint to the run-time system as to the relative importance - of range limited features. Features with lower priorities should be - sacrified before those with higher priorities. - */ - void GetPriority(int &) const; + /* Get the priority. + Priority is a hint to the run-time system as to the relative importance + of range limited features. Features with lower priorities should be + sacrified before those with higher priorities. + */ + void GetPriority(int &) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // Reset back to a clean state - void Reset(void); + // Reset back to a clean state + void Reset(void); - // Equality operator - bool operator == (const trpgRange &) const; + // Equality operator + bool operator == (const trpgRange &) const; - // Assignment operator - trpgRange & operator = (const trpgRange &); + // Assignment operator + trpgRange & operator = (const trpgRange &); protected: - double inLod,outLod; - char *category; - char *subCategory; - int priority; + double inLod,outLod; + char *category; + char *subCategory; + int priority; }; /* The Range Table is new to 2.0. The goal is to provide information about - certain classes of features within a TerraPage database. It's intended - to solve the following problem. - - Let's say that you have an Image Generator that must draw a given TerraPage - database at 60Hz. However, it's only hitting 30Hz reliably. Often, some - feature set (e.g. bushes) must be sacrified in order to reach the target frame rate. - Determining which features can be throttled back can often be very difficult. - Scaling all of the LODs will often work, but it's not very elegant. It's - not selective (you may lose important features as well as unimportant ones) - and it doesn't easily let turn whole feature sets off. + certain classes of features within a TerraPage database. It's intended + to solve the following problem. + + Let's say that you have an Image Generator that must draw a given TerraPage + database at 60Hz. However, it's only hitting 30Hz reliably. Often, some + feature set (e.g. bushes) must be sacrified in order to reach the target frame rate. + Determining which features can be throttled back can often be very difficult. + Scaling all of the LODs will often work, but it's not very elegant. It's + not selective (you may lose important features as well as unimportant ones) + and it doesn't easily let turn whole feature sets off. - If you do want to selectively turn features on and off or throttle them - back, you can do so based on node names within the LODs. This can work, however - you've got the additional overhead of traversing the tree looking for LODs - and trying to figure out what the names mean. The range table is intended - to make this task easier. + If you do want to selectively turn features on and off or throttle them + back, you can do so based on node names within the LODs. This can work, however + you've got the additional overhead of traversing the tree looking for LODs + and trying to figure out what the names mean. The range table is intended + to make this task easier. - Each trpgLod can (but isn't required to) have an index into the Range Table. - That index will point to a trpgRange that contains global information - about that class of LODs. This includes the in/out information already contained - within the LOD as well as global info. The global information includes a category - and sub-category as well as an integer priority. The category data is there to - allow run-time systems to tell users what they're dropping (or allow them to pick). - The priority is there to tell systems what to get rid of first (according to the - user who build the TerraPage archive). - - Priorities are relative to each other within the Range Table. There can be - duplicates and there may be holes in the numbering. + Each trpgLod can (but isn't required to) have an index into the Range Table. + That index will point to a trpgRange that contains global information + about that class of LODs. This includes the in/out information already contained + within the LOD as well as global info. The global information includes a category + and sub-category as well as an integer priority. The category data is there to + allow run-time systems to tell users what they're dropping (or allow them to pick). + The priority is there to tell systems what to get rid of first (according to the + user who build the TerraPage archive). + + Priorities are relative to each other within the Range Table. There can be + duplicates and there may be holes in the numbering. {group:Read/Write Classes} */ TX_EXDECL class TX_CLDECL trpgRangeTable : public trpgReadWriteable { public: - trpgRangeTable(void); - ~trpgRangeTable(void); + trpgRangeTable(void); + ~trpgRangeTable(void); - // Get the given range info - bool GetRange(int id,trpgRange &) const; + // Get the given range info + bool GetRange(int id,trpgRange &) const; - // Set the range info for the given ID - bool SetRange(int id,trpgRange &); + // Set the range info for the given ID + bool SetRange(int id,trpgRange &); - // Add a new range and return the ID - int AddRange(trpgRange &); + // Add a new range and return the ID + int AddRange(trpgRange &); - // Find a matching range and return it or add a new one if needed - int FindAddRange(trpgRange &); + // Find a matching range and return it or add a new one if needed + int FindAddRange(trpgRange &); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); - // Assignment operator - trpgRangeTable & operator = (const trpgRangeTable &); + // Assignment operator + trpgRangeTable & operator = (const trpgRangeTable &); protected: - std::vector rangeList; + std::vector rangeList; }; /* All materials are centrally indexed in TerraPage. There is one material - table per archive. All trpgGeometry nodes point to that material table (with indices) - for their trpgMaterial definitions. + table per archive. All trpgGeometry nodes point to that material table (with indices) + for their trpgMaterial definitions. - The material table has one wrinkle. It is divided up into sub-tables or channels. - Each sub-table has the same number of materials, so there will be NxM trpgMaterial - structures in a trpgMatTable. The sub-tables are intended for use in simple sensor - simulations. For example, the base table (0) is the purely visual, out the window - representation. The next table (1) might the Infra-Red version. It's up to the run-time - system to switch between these two. TerraPage simply provides the means for keeping - track of it. + The material table has one wrinkle. It is divided up into sub-tables or channels. + Each sub-table has the same number of materials, so there will be NxM trpgMaterial + structures in a trpgMatTable. The sub-tables are intended for use in simple sensor + simulations. For example, the base table (0) is the purely visual, out the window + representation. The next table (1) might the Infra-Red version. It's up to the run-time + system to switch between these two. TerraPage simply provides the means for keeping + track of it. - If you're doing a TerraPage reader you'll get a trpgMatTable from the trpgr_Archive. - This is your central index for materials. If you can handle the multiple channels/sub-tables - then you can access those as you need. If you can't, just use 0 for the sub-table index where appropriate. - - If you're doing a TerraPage writer you'll need to build up a trpgMatTable to pass to - trpgwArchive. If you're only doing a single sub-table (i.e. visible materials only) - just use AddMaterial and add them as you go. The trpgMaterial object you build up - for a given material are copied when you call the add function. So you can have a single - trpgMaterial, modify just a few fields and call AddMaterial repeatedly. - {group:Read/Write Classes} - */ + If you're doing a TerraPage reader you'll get a trpgMatTable from the trpgr_Archive. + This is your central index for materials. If you can handle the multiple channels/sub-tables + then you can access those as you need. If you can't, just use 0 for the sub-table index where appropriate. + + If you're doing a TerraPage writer you'll need to build up a trpgMatTable to pass to + trpgwArchive. If you're only doing a single sub-table (i.e. visible materials only) + just use AddMaterial and add them as you go. The trpgMaterial object you build up + for a given material are copied when you call the add function. So you can have a single + trpgMaterial, modify just a few fields and call AddMaterial repeatedly. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgMatTable : public trpgReadWriteable { public: - trpgMatTable(void); - ~trpgMatTable(void); - /* If you intend to have more than one material sub-table you'll - need to set this first before doing anything else. - */ - void SetNumTable(int); - /* This sets the total number of materials. Each sub-table will - have this many of its own materials. If you call this function - you can't use AddMaterial. - */ - void SetNumMaterial(int); - /* Sets a material definition for the given sub-table material ID - combination. If you only have one sub-table you can use - AddMaterial instead. - The two argument version assumes subTable = 0 - */ - void SetMaterial(int subTable,int mat,const trpgMaterial &); - void SetMaterial(int,const trpgMaterial &); - - /* This function should be used if you only have a single material sub-table. - It searches for a matching material and then adds a new one if it doesn't - find a match. The new (or old) ID is returned. - */ - int AddMaterial(const trpgMaterial &); + trpgMatTable(void); + ~trpgMatTable(void); + /* If you intend to have more than one material sub-table you'll + need to set this first before doing anything else. + */ + void SetNumTable(int); + /* This sets the total number of materials. Each sub-table will + have this many of its own materials. If you call this function + you can't use AddMaterial. + */ + void SetNumMaterial(int); + /* Sets a material definition for the given sub-table material ID + combination. If you only have one sub-table you can use + AddMaterial instead. + The two argument version assumes subTable = 0 + */ + void SetMaterial(int subTable,int mat,const trpgMaterial &); + void SetMaterial(int,const trpgMaterial &); + + /* This function should be used if you only have a single material sub-table. + It searches for a matching material and then adds a new one if it doesn't + find a match. The new (or old) ID is returned. + */ + int AddMaterial(const trpgMaterial &,bool lookForExisting=true); - /* Return the number of sub-tables. This will, most commonly, be 1. - Any value more than 1 means the archive has alternate material definitions - (think IR or Radar versions). - */ - bool GetNumTable(int &) const; - /* The number of materials per sub-table. Each sub-table has the same number - of materials. So there will be N x M number of materials total, but you'll - only see M of them at any given time. - */ - bool GetNumMaterial(int &) const; + /* This function should be used when adding materials to multiple sub-tables. + It searches for a matching material and then adds a new one if it doesn't + find a match. The new (or old) ID is returned. + */ + int AddMaterialInSubtable(const trpgMaterial &,int table,bool lookForExisting=true); - /* Returns the material definition for the given subTable and the given material - ID. The most common subTable will be 0 (visual). The material ID comes - from the value(s) in trpgGeometry. - */ - bool GetMaterial(int subTable,int matID,trpgMaterial &) const; + /* Return the number of sub-tables. This will, most commonly, be 1. + Any value more than 1 means the archive has alternate material definitions + (think IR or Radar versions). + */ + bool GetNumTable(int &) const; + /* The number of materials per sub-table. Each sub-table has the same number + of materials. So there will be N x M number of materials total, but you'll + only see M of them at any given time. + */ + bool GetNumMaterial(int &) const; - /* This is a convenience method for getting a reference to a trpgMaterial object. - The reason you might want to do this is if you don't want to create a full - trpgMaterial object to pass to GetMaterial. - The returned value is only valid until the next GetMaterialRef call. - */ - const trpgMaterial *GetMaterialRef(int,int) const; + /* Returns the material definition for the given subTable and the given material + ID. The most common subTable will be 0 (visual). The material ID comes + from the value(s) in trpgGeometry. + */ + bool GetMaterial(int subTable,int matID,trpgMaterial &) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + /* This is a convenience method for getting a reference to a trpgMaterial object. + The reason you might want to do this is if you don't want to create a full + trpgMaterial object to pass to GetMaterial. + The returned value is only valid until the next GetMaterialRef call. + */ + const trpgMaterial *GetMaterialRef(int,int) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); + + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int numTable; - int numMat; - std::vector matTables; + int numTable; + int numMat; + std::vector matTables; }; /* This class holds the texture definition TerraPage uses. Textures are a little - different than other TerraPage objects for the following reason: they aren't - stored in the archive. Instead they're stored individually on disk in your - favorite image format. We don't constrain what that format is, although SGI - format (.rgb) is always the safest in this industry. + different than other TerraPage objects for the following reason: they aren't + stored in the archive. Instead they're stored individually on disk in your + favorite image format. We don't constrain what that format is, although SGI + format (.rgb) is always the safest in this industry. - Texture objects are really just references to these on-disk textures. As such, - they're pretty simple. They just consist of a filename. These trpgTexture - objects will be indexed in a trpgTexTable. The indices you get from trpgMaterial - objects point to trpgTexture objects through that table. trpgMaterial objects - should be the only things that have texture indices. + Texture objects are really just references to these on-disk textures. As such, + they're pretty simple. They just consist of a filename. These trpgTexture + objects will be indexed in a trpgTexTable. The indices you get from trpgMaterial + objects point to trpgTexture objects through that table. trpgMaterial objects + should be the only things that have texture indices. - If you're doing a TerraPage reader textures are pretty simple to read in. There - are two ways to do it. First, if you're not doing texture paging, simply read - them all in, using the trpgTexTable to figure out where they all are. If you - are doing texture paging (highly recommended) then you'll need to call GetNumTile - to figure out how many tiles a texture is used in. If it's 1, then this is probably - a geospecific textures and ought to be paged. If it's more than 1, then it's a - geotypical texture (i.e. a tree or road) and should be loaded in at the beginning. + If you're doing a TerraPage reader textures are pretty simple to read in. There + are two ways to do it. First, if you're not doing texture paging, simply read + them all in, using the trpgTexTable to figure out where they all are. If you + are doing texture paging (highly recommended) then you'll need to call GetNumTile + to figure out how many tiles a texture is used in. If it's 1, then this is probably + a geospecific textures and ought to be paged. If it's more than 1, then it's a + geotypical texture (i.e. a tree or road) and should be loaded in at the beginning. - If you're doing a TerraPage writer you'll need to be creating trpgTexture objects - as you go and adding them to your central trpgTexTable. If you want to support - texture paging set the numTile count to 1 for the geospecific textures and more - than 1 for everything else. There are utility functions for keeping track of all - of this. It's best to use those. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer you'll need to be creating trpgTexture objects + as you go and adding them to your central trpgTexTable. If you want to support + texture paging set the numTile count to 1 for the geospecific textures and more + than 1 for everything else. There are utility functions for keeping track of all + of this. It's best to use those. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTexture : public trpgReadWriteable { public: - trpgTexture(void); - trpgTexture(const trpgTexture &); - ~trpgTexture(void); + trpgTexture(void); + trpgTexture(const trpgTexture &); + ~trpgTexture(void); - /* This enum is used to determine where the image is. - External - Stored in an external file, just like TerraPage 1.x. - Local - Stored in one of the archive files. The type and size will be here. - Use trpgrImageHelper to fetch the image, either initially or later. - Global - This image is really large and parts of it will be referenced - later within individual tiles. Use the trpgrImageHelper class - to reference the various parts of the image. Don't load it yourself. - Template - This isn't an image at all. It's here to represent a class of - images with a certain size and type. You'll encounter inline materials - (for pageable textures) in the tiles which make use of this template. - If you use trpgrImageHelper to fetch those textures, you don't need to - do anything with this texture. - */ - typedef enum {External,Local,Global,Template} ImageMode; + /* This enum is used to determine where the image is. + External - Stored in an external file, just like TerraPage 1.x. + Local - Stored in one of the archive files. The type and size will be here. + Use trpgrImageHelper to fetch the image, either initially or later. + Global - This image is really large and parts of it will be referenced + later within individual tiles. Use the trpgrImageHelper class + to reference the various parts of the image. Don't load it yourself. + Template - This isn't an image at all. It's here to represent a class of + images with a certain size and type. You'll encounter inline materials + (for pageable textures) in the tiles which make use of this template. + If you use trpgrImageHelper to fetch those textures, you don't need to + do anything with this texture. + */ + typedef enum {External,Local,Global,Template} ImageMode; - /* These are the types of images TerraPage can support for Local and Template - image modes (see ImageMode). If the image is External or Global, anything - is fair game, but these are the only types TerraPage can store itself. - */ - typedef enum { - trpg_RGB8, - trpg_RGBA8, - trpg_INT8, - trpg_INTA8, - trpg_FXT1, - trpg_Filler, // This is not a texture format. It's here to keep the numbering consistent - trpg_RGBX, // MCM - trpg_Unknown, - trpg_DDS, - trpg_DXT1, - trpg_DXT3, - trpg_DXT5 - } ImageType; + /* These are the types of images TerraPage can support for Local and Template + image modes (see ImageMode). If the image is External or Global, anything + is fair game, but these are the only types TerraPage can store itself. + */ + typedef enum { + trpg_RGB8, + trpg_RGBA8, + trpg_INT8, + trpg_INTA8, + trpg_FXT1, + trpg_Filler, // This is not a texture format. It's here to keep the numbering consistent + trpg_RGBX, // MCM + trpg_Unknown, + trpg_DDS, + trpg_DXT1, + trpg_DXT3, + trpg_DXT5 + } ImageType; - // How the image bit planes are organized - typedef enum {} ImageOrg; + // How the image bit planes are organized + typedef enum { + trpg_RGBX_Neither=0, + trpg_RGBX_AlphaFirst, + trpg_RGBX_RegionFirst + } ImageOrg; - // Set the texture name. - void SetName(const char *); - /* This is the texture name. You pass in a string of a pre-defined length - and it returns the texture name in that. */ - bool GetName(char *retStr,int strLen) const; + // Set the texture name. + void SetName(const char *); + /* This is the texture name. You pass in a string of a pre-defined length + and it returns the texture name in that. */ + bool GetName(char *retStr,int strLen) const; - /* Sets the number of tiles this texture is used in. This hint is used by - readers to determine texture pageability. */ - void SetNumTile(int); - /* Instead of calling SetNumTile after you've built a database, you can call - AddTile as you encounter each texture reference (per tile). */ - void AddTile(void); + /* Sets the number of tiles this texture is used in. This hint is used by + readers to determine texture pageability. */ + void SetNumTile(int); + /* Instead of calling SetNumTile after you've built a database, you can call + AddTile as you encounter each texture reference (per tile). */ + void AddTile(void); - /* This tells you the number of tiles this texture is used in. You can - use this to do texture paging (if you can support it). It's a pretty - general meachanism and will work for large scale geospecific terrain textures - as well as things like specific building pictures. - When GetImageMode returns Global, expect this value to always be 1. For - Template texture, it will be set to the total number of uses of the template - (which should be fairly large). - */ - bool GetNumTile(int &) const; + /* This tells you the number of tiles this texture is used in. You can + use this to do texture paging (if you can support it). It's a pretty + general meachanism and will work for large scale geospecific terrain textures + as well as things like specific building pictures. + When GetImageMode returns Global, expect this value to always be 1. For + Template texture, it will be set to the total number of uses of the template + (which should be fairly large). + */ + bool GetNumTile(int &) const; - // Retrieve the image mode for this texture. See ImageMode for details. - bool GetImageMode(ImageMode &) const; + // Retrieve the image mode for this texture. See ImageMode for details. + bool GetImageMode(ImageMode &) const; - // Retrieve the image type for this texture. See ImageType for details. - // This method is only used if ImageMode is Local or Template - bool GetImageType(ImageType &) const; + // Retrieve the image type for this texture. See ImageType for details. + // This method is only used if ImageMode is Local or Template + bool GetImageType(ImageType &) const; - // Find out how the bit planes are organized. Only important for some types - // of images - bool GetImageOrganization(ImageOrg &) const; + // Find out how the bit planes are organized. Only important for some types + // of images + bool GetImageOrganization(ImageOrg &) const; - // Retrieve the size of this image. Valid only for Local and Template textures. - bool GetImageSize(trpg2iPoint &) const; + // Retrieve the size of this image. Valid only for Local and Template textures. + bool GetImageSize(trpg2iPoint &) const; - // Get the location of a Local image - bool GetImageAddr(trpgwAppAddress &) const; + // Get the location of a Local image + bool GetImageAddr(trpgwAppAddress &) const; - // Figure out the image depth from the type - bool GetImageDepth(int32 &depth) const; + // Figure out the image depth from the type + bool GetImageDepth(int32 &depth) const; - // Determine whether this image (must be Local or Template) has all its mipmaps - bool GetIsMipmap(bool &) const; + // Determine whether this image (must be Local or Template) has all its mipmaps + bool GetIsMipmap(bool &) const; - // Set the image mode of this texture. Used by writers only. - void SetImageMode(ImageMode); + // Set the image mode of this texture. Used by writers only. + void SetImageMode(ImageMode); - // Set the image type of this texture. See GetImageType for details. - void SetImageType(ImageType); + // Set the image type of this texture. See GetImageType for details. + void SetImageType(ImageType); - // Sets a constant the dictates bit plane organization. Not used for all image - // types - void SetImageOrganization(ImageOrg); + // Sets a constant the dictates bit plane organization. Not used for all image + // types + void SetImageOrganization(ImageOrg); - // Set the image size of this texture. See GetImageSize for details - void SetImageSize(const trpg2iPoint &); + // Set the image size of this texture. See GetImageSize for details + void SetImageSize(const trpg2iPoint &); - // Set the image location (For Local images only) - void SetImageAddr(const trpgwAppAddress &); + // Set the image location (For Local images only) + void SetImageAddr(const trpgwAppAddress &); - // Set whether or not this is a full set of mipmaps - void SetIsMipmap(bool); + // Set whether or not this is a full set of mipmaps + void SetIsMipmap(bool); - // Set the storage sizes for all mipmap levels -// void SetStorageSizes(vector &); + // Set the storage sizes for all mipmap levels +// void SetStorageSizes(vector &); - // Get the storage sizes for all mipmap levels. -// bool GetStorageSizes(const vector *) const; + // Get the storage sizes for all mipmap levels. +// bool GetStorageSizes(const vector *) const; - // Set the number of mipmap levels - void SetNumMipmap(int); + // Set the number of mipmap levels + void SetNumMipmap(int); - // Set the number of layers used in an RGBX image - void SetNumLayer(int); + // Set the number of layers used in an RGBX image + void SetNumLayer(int); - // Get the number of layers used in an RGBX image. RGBX images are typically for - // sensors and contain arbitrary data which is not visual. - bool GetNumLayer(int &) const; + // Get the number of layers used in an RGBX image. RGBX images are typically for + // sensors and contain arbitrary data which is not visual. + bool GetNumLayer(int &) const; - /* Utility to figure out the number of mipmap levels this image would have. - Only really necessary for Local or Template images. - */ - int32 CalcNumMipmaps() const; + /* Utility to figure out the number of mipmap levels this image would have. + Only really necessary for Local or Template images. + */ + int32 CalcNumMipmaps() const; - // Calculate the total size of this texture - int32 CalcTotalSize() const; + // Calculate the total size of this texture + int32 CalcTotalSize() const; - // Returns the size of a given mip level - int32 MipLevelSize(int miplevel); + // Returns the size of a given mip level + int32 MipLevelSize(int miplevel); - // Returns the offset of the mip level in the whole texture data buffer - int32 MipLevelOffset(int miplevel); + // Returns the offset of the mip level in the whole texture data buffer + int32 MipLevelOffset(int miplevel); - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - trpgTexture & operator = (const trpgTexture &); - int operator == (const trpgTexture &) const; + trpgTexture & operator = (const trpgTexture &); + int operator == (const trpgTexture &) const; protected: - // Mode for this texture. See ImageMode for details - ImageMode mode; + // Mode for this texture. See ImageMode for details + ImageMode mode; - // Type of texture (only valid if ImageMode is Local or Template) - ImageType type; + // Type of texture (only valid if ImageMode is Local or Template) + ImageType type; - // Organize of image bit planes - ImageOrg org; + // Organize of image bit planes + ImageOrg org; - // The name really only has meaning for External or Global textures - char *name; - int useCount; + // The name really only has meaning for External or Global textures + char *name; + int useCount; - // The size values are used only if this is a Local or Template image - int sizeX,sizeY; + // The size values are used only if this is a Local or Template image + int sizeX,sizeY; - // Whether or not there are mipmap levels - bool isMipmap; + // Whether or not there are mipmap levels + bool isMipmap; - // Number of mipmap levels, 0 if not present - int numMipMap; + // Number of mipmap levels, 0 if not present + int numMipMap; - // Number of layers (for RGBX) - int numLayer; + // Number of layers (for RGBX) + int numLayer; - // Sizes of each level. This is important for compressed textures in particular, - // which may have random sizes. Used only for Local textures. - std::vector storageSize; + // Sizes of each level. This is important for compressed textures in particular, + // which may have random sizes. Used only for Local textures. + std::vector storageSize; - // Offset of each level - std::vector levelOffset; + // Offset of each level + std::vector levelOffset; - // Address is used only for Local textures - trpgwAppAddress addr; + // Address is used only for Local textures + trpgwAppAddress addr; - // calculate the mip level sizes - void CalcMipLevelSizes(); + // calculate the mip level sizes + void CalcMipLevelSizes(); }; /* The texture table keeps track of all the textures in a TerraPage archive. - All textures are indexed centrally here. The indices in trpgMaterial objects - point into a trpgTexTable. Although the trpgMatTable potentially has several - sub-tables for different representations (visual, IR, etc..), the trpgTexTable - is not affected by that. All textures, no matter what their use, are indexed - together here. + All textures are indexed centrally here. The indices in trpgMaterial objects + point into a trpgTexTable. Although the trpgMatTable potentially has several + sub-tables for different representations (visual, IR, etc..), the trpgTexTable + is not affected by that. All textures, no matter what their use, are indexed + together here. - If you're doing a TerraPage reader you'll get a trpgTexTable back from your - trpgr_Archive. You'll then want to iterate over the trpgTexture objects and - load in the ones used in more than one tile. If you can do texture paging - you should leave the ones only used in 1 tile alone initially. You may also - want to set up a mapping from texture indices here into whatever your own texture - repository is. The texture indices in trpgMaterial objects refer to the listing - here. + If you're doing a TerraPage reader you'll get a trpgTexTable back from your + trpgr_Archive. You'll then want to iterate over the trpgTexture objects and + load in the ones used in more than one tile. If you can do texture paging + you should leave the ones only used in 1 tile alone initially. You may also + want to set up a mapping from texture indices here into whatever your own texture + repository is. The texture indices in trpgMaterial objects refer to the listing + here. - If you're doing a TerraPage writer you'll want to create one of these and add - textures as you go. Textures are copied in when you call AddTexture or SetTexture - so you can reused the trpgTexture object you put together to pass in. The texture - index returned by AddTexture should be used in the trpgMaterial you'll need to build. - Textures don't live in isolation and must be applied to geometry through a trpgMaterial. - After the trpgTexTable is built it will get passed to a trpgwArchive for writing. That - can be done right before you close the archive. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer you'll want to create one of these and add + textures as you go. Textures are copied in when you call AddTexture or SetTexture + so you can reused the trpgTexture object you put together to pass in. The texture + index returned by AddTexture should be used in the trpgMaterial you'll need to build. + Textures don't live in isolation and must be applied to geometry through a trpgMaterial. + After the trpgTexTable is built it will get passed to a trpgwArchive for writing. That + can be done right before you close the archive. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTexTable : public trpgReadWriteable { public: - trpgTexTable(void); - trpgTexTable(const trpgTexTable &); - ~trpgTexTable(void); + trpgTexTable(void); + trpgTexTable(const trpgTexTable &); + ~trpgTexTable(void); - /* Sets the total number of textures in this table. This is used in - combination with SetTexture. If you can, you should use AddTexture - and FindAddTexture instead. - */ - void SetNumTextures(int); - /* Adds the given texture to the table and increments the total texture - count. If you use this, you should not use SetNumTextures and SetTexture. - */ - int AddTexture(const trpgTexture &); - /* This is the same as AddTexture except that it searches for a matching texture - first. This is convenient for writers who aren't keeping track of their - own textures internally. - */ - int FindAddTexture(const trpgTexture &); - /* This sets the given texture ID to be the trpgTexture passed in. It's used - in combination with SetNumTextures. Use AddTexture or FindAddTexture instead - if you can. - */ - void SetTexture(int texID,const trpgTexture &); + /* Sets the total number of textures in this table. This is used in + combination with SetTexture. If you can, you should use AddTexture + and FindAddTexture instead. + */ + void SetNumTextures(int); + /* Adds the given texture to the table and increments the total texture + count. If you use this, you should not use SetNumTextures and SetTexture. + */ + int AddTexture(const trpgTexture &); + /* This is the same as AddTexture except that it searches for a matching texture + first. This is convenient for writers who aren't keeping track of their + own textures internally. + */ + int FindAddTexture(const trpgTexture &); + /* This sets the given texture ID to be the trpgTexture passed in. It's used + in combination with SetNumTextures. Use AddTexture or FindAddTexture instead + if you can. + */ + void SetTexture(int texID,const trpgTexture &); - // Returns the number of textures in this table - bool GetNumTextures(int &) const; - // This returns the trpgTexture corresponding to the given ID (from a trpgMaterial) - bool GetTexture(int texID,trpgTexture &) const; - /* Does the same thing as GetTexture only it returns a pointer instead. - You would use this if you don't want a new trpgTexture created for you. - Assume the value it returns is only good until the next GetTextureRef call. - */ - const trpgTexture *GetTextureRef(int) const; + // Returns the number of textures in this table + bool GetNumTextures(int &) const; + // This returns the trpgTexture corresponding to the given ID (from a trpgMaterial) + bool GetTexture(int texID,trpgTexture &) const; + /* Does the same thing as GetTexture only it returns a pointer instead. + You would use this if you don't want a new trpgTexture created for you. + Assume the value it returns is only good until the next GetTextureRef call. + */ + const trpgTexture *GetTextureRef(int) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - trpgTexTable & operator = (const trpgTexTable &); + trpgTexTable & operator = (const trpgTexTable &); protected: - std::vector texList; + std::vector texList; }; /* Models are basically just references in TerraPage. This class just points - to a model from somewhere else. There are two places it can point. (1) It - can point externally to a model in some arbitrary format (OpenFlight(tm) is - a popular one). (2) It can also point to a model within the TerraPage archive. - The first case is much like trpgTexture objects are treated. That is, the actual - thing itself is on disk somewhere corresponding to a file name. The second case is - more like tile terrain geometry. In that case there is scene node type data (LODs, - groups, geometry, etc...) associated with it. + to a model from somewhere else. There are two places it can point. (1) It + can point externally to a model in some arbitrary format (OpenFlight(tm) is + a popular one). (2) It can also point to a model within the TerraPage archive. + The first case is much like trpgTexture objects are treated. That is, the actual + thing itself is on disk somewhere corresponding to a file name. The second case is + more like tile terrain geometry. In that case there is scene node type data (LODs, + groups, geometry, etc...) associated with it. - trpgModel objects live within a trpgModelTable. They are indexed there and refered - to by trpgModelRef objects. Those model references are the only things that explicitly - use trpgModel objects. + trpgModel objects live within a trpgModelTable. They are indexed there and refered + to by trpgModelRef objects. Those model references are the only things that explicitly + use trpgModel objects. - If you're doing a TerraPage reader you'll need to take into account whether the - model is external or internal. If it's external you'll need to read the given file - and convert it to your own representation. If it's internal you've probably already - got the code for dealing with terrain tiles, which is essentially the same thing. - Models can be paged, if you're so inclined. They have tile reference counts just - like trpgTexture objects. If numTile == 1 then page it, if > 1 then don't. + If you're doing a TerraPage reader you'll need to take into account whether the + model is external or internal. If it's external you'll need to read the given file + and convert it to your own representation. If it's internal you've probably already + got the code for dealing with terrain tiles, which is essentially the same thing. + Models can be paged, if you're so inclined. They have tile reference counts just + like trpgTexture objects. If numTile == 1 then page it, if > 1 then don't. - If you're doing a TerraPage writer you'll want to build up a trpgModelTable of these - as you encounter them. If your models are external in some other format then setting - up a trpgModel is pretty easy. If you want to do internal models, the support is not - quite there yet. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer you'll want to build up a trpgModelTable of these + as you encounter them. If your models are external in some other format then setting + up a trpgModel is pretty easy. If you want to do internal models, the support is not + quite there yet. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgModel : public trpgReadWriteable { public: - trpgModel(void); - trpgModel(const trpgModel &); - ~trpgModel(void); - enum {Local,External}; - // Sets the name of the external model file and sets this model to External type. - void SetName(const char *); - // Sets the on-disk reference to an internal model and sets this model to Internal type. - void SetReference(trpgDiskRef); - /* Models are reference counted (per-tile). It's up to the writer to set this - value. */ - void SetNumTiles(int); - /* TerraPage writers can use AddTile (starts at 0) every time they use this model - in a tile. Note that this is not for every instance within a tile. So if - you use a model 40 times within a tile, you call AddTile once. - This is used instead of SetNumTiles. */ - void AddTile(void); + trpgModel(void); + trpgModel(const trpgModel &); + ~trpgModel(void); + enum {Local,External}; + // Sets the name of the external model file and sets this model to External type. + void SetName(const char *); + // Sets the on-disk reference to an internal model and sets this model to Internal type. + void SetReference(trpgDiskRef); + /* Models are reference counted (per-tile). It's up to the writer to set this + value. */ + void SetNumTiles(int); + /* TerraPage writers can use AddTile (starts at 0) every time they use this model + in a tile. Note that this is not for every instance within a tile. So if + you use a model 40 times within a tile, you call AddTile once. + This is used instead of SetNumTiles. */ + void AddTile(void); - /* Returns the type (Local or External) of this model */ - bool GetType(int &); - /* If the model is external, this returns the file name of that model. - You pass in a string and a length and it copies the filename into that. */ - bool GetName(char *ret,int strLen) const; - /* If the model is internal, this returns the disk reference to it. - At some future data you'll be able to simply read these out of an archive. */ - bool GetReference(trpgDiskRef &) const; - /* Models are reference counted, like trpgTexture objects. You can use this - value to determine whether or not you should page models. - */ - bool GetNumTiles(int &) const; + /* Returns the type (Local or External) of this model */ + bool GetType(int &); + /* If the model is external, this returns the file name of that model. + You pass in a string and a length and it copies the filename into that. */ + bool GetName(char *ret,int strLen) const; + /* If the model is internal, this returns the disk reference to it. + At some future data you'll be able to simply read these out of an archive. */ + bool GetReference(trpgDiskRef &) const; + /* Models are reference counted, like trpgTexture objects. You can use this + value to determine whether or not you should page models. + */ + bool GetNumTiles(int &) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - trpgModel & operator = (const trpgModel &); - int operator == (const trpgModel &) const; + trpgModel & operator = (const trpgModel &); + int operator == (const trpgModel &) const; protected: - int type; - char *name; - trpgDiskRef diskRef; - int useCount; + int type; + char *name; + trpgDiskRef diskRef; + int useCount; }; /* Models (trpgModel) are indexed together in a model table. There is one - model table per TerraPage archive. It holds the canonical list of models - for the entire database. It's pretty simple. Just a list of models, really. - the trpgModel object holds the real information. + model table per TerraPage archive. It holds the canonical list of models + for the entire database. It's pretty simple. Just a list of models, really. + the trpgModel object holds the real information. - If you're doing a TerraPage reader you'll get one of these from a trpgr_Archive. - You'll want to iterate over the models in it and figure out which ones to page, - if you're doing model paging. If not, then you can just read them all in - at initialization time and index them as need per-tile. + If you're doing a TerraPage reader you'll get one of these from a trpgr_Archive. + You'll want to iterate over the models in it and figure out which ones to page, + if you're doing model paging. If not, then you can just read them all in + at initialization time and index them as need per-tile. - If you're doing a TerraPage writer you'll build one of these up for the entire - database as you go. Just call AddModel every time you finish a model definition. - The finished table will be passed to trpgwArchive at the end. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer you'll build one of these up for the entire + database as you go. Just call AddModel every time you finish a model definition. + The finished table will be passed to trpgwArchive at the end. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgModelTable : public trpgReadWriteable { public: - trpgModelTable(void); - ~trpgModelTable(void); + trpgModelTable(void); + ~trpgModelTable(void); - /* Set the total number of models in the table. Use this in conjunction - with SetModel. If you can, use AddModel isntead of either of these. - */ - void SetNumModels(int); - /* Add the given model to the table. Makes a copy of the model you pass in - and returns the new model ID which you'll need to reference in trpgModelRef. - */ - int AddModel(const trpgModel &); - /* Look for a given model. If it's not there, add it. */ - int FindAddModel(const trpgModel &); - /* Sets the model definition corresponding to the given ID. Use this in conjunction - with SetNumModels. */ - void SetModel(int,const trpgModel &); + /* Set the total number of models in the table. Use this in conjunction + with SetModel. If you can, use AddModel isntead of either of these. + */ + void SetNumModels(int); + /* Add the given model to the table. Makes a copy of the model you pass in + and returns the new model ID which you'll need to reference in trpgModelRef. + */ + int AddModel(const trpgModel &); + /* Look for a given model. If it's not there, add it. */ + int FindAddModel(const trpgModel &); + /* Sets the model definition corresponding to the given ID. Use this in conjunction + with SetNumModels. */ + void SetModel(int,const trpgModel &); - // Returns the number of models in this table - bool GetNumModels(int &) const; - /* Returns the Nth model. trpgModelRef objects point into this table - and that is where the model ID comes from. */ - bool GetModel(int modID,trpgModel &) const; + // Returns the number of models in this table + bool GetNumModels(int &) const; + /* Returns the Nth model. trpgModelRef objects point into this table + and that is where the model ID comes from. */ + bool GetModel(int modID,trpgModel &) const; - /* The same as GetModel only it returns a pointer to the trpgModel instead. - Use this if you don't want to create a copy of the model. - The result is only good until the next GetModelRef call. - */ - trpgModel *GetModelRef(int); + /* The same as GetModel only it returns a pointer to the trpgModel instead. + Use this if you don't want to create a copy of the model. + The result is only good until the next GetModelRef call. + */ + trpgModel *GetModelRef(int); - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - std::vector models; + std::vector models; }; /* The tile table keeps track of tile locations within a TerraPage archive. - Tiles can be stored either externally (as individual files) or locally - (grouped together into bigger files). The details are hidden from the - reader completely and the writer in most cases. - {group:Read/Write Classes} - */ + Tiles can be stored either externally (as individual files) or locally + (grouped together into bigger files). The details are hidden from the + reader completely and the writer in most cases. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTileTable : public trpgReadWriteable { public: - // Tiles can be stored individually (External) or in grouped files (Local) - typedef enum {Local,External} TileMode; + // Tiles can be stored individually (External) or in grouped files (Local) + typedef enum {Local,External} TileMode; - trpgTileTable(void); - ~trpgTileTable(void); - // Set the tile storage mode: external or local - void SetMode(TileMode); - // Set the total number of LODs - void SetNumLod(int numLod); - // Set the number of tiles in each dimenion for each terrain LOD - // This must agree with trpgHeader - void SetNumTiles(int numX,int numY,int lod); - // Set the external address of a given tile as well as its Z value - void SetTile(int x,int y,int lod,trpgwAppAddress &,float32 min,float32 max); + trpgTileTable(void); + ~trpgTileTable(void); + // Set the tile storage mode: external or local + void SetMode(TileMode); + // Set the total number of LODs + void SetNumLod(int numLod); + // Set the number of tiles in each dimenion for each terrain LOD + // This must agree with trpgHeader + void SetNumTiles(int numX,int numY,int lod); + // Set the external address of a given tile as well as its Z value + void SetTile(int x,int y,int lod,trpgwAppAddress &,float32 min,float32 max); - // Local or external tiles - bool GetMode(TileMode &) const; - // Get the disk reference (local) - bool GetTile(int x,int y,int lod,trpgwAppAddress &,float32 &min,float32 &max) const; + // Local or external tiles + bool GetMode(TileMode &) const; + // Get the disk reference (local) + bool GetTile(int x,int y,int lod,trpgwAppAddress &,float32 &min,float32 &max) const; - // Validity check - bool isValid(void) const; - // Reads this class from a read buffer - void Reset(void); + // Validity check + bool isValid(void) const; + // Reads this class from a read buffer + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - TileMode mode; + TileMode mode; - class LodInfo { - public: - int numX,numY; - // Tile addresses into external Appendable files - std::vector addr; - // Elevation of the midpoint of each tile - // This is used for calculating bounding boxes - std::vector elev_min; - std::vector elev_max; - }; - std::vector lodInfo; + class LodInfo { + public: + int numX,numY; + // Tile addresses into external Appendable files + std::vector addr; + // Elevation of the midpoint of each tile + // This is used for calculating bounding boxes + std::vector elev_min; + std::vector elev_max; + }; + std::vector lodInfo; }; /* Local materials are new to TerraPage 2.0. - The idea is that for pageable one-time textures it makes more sense - to define them in the tiles. This keeps the size of Texture and - Material tables down in the header. It also lets us make use of - Global textures by grabbing subimages. - You'll encounter these in a tile right after the tile header. They'll - be referenced by ID in trpgGeometry nodes within that tile. They - can represent a sub-image of a Global texture or a whole Local texture. - In either case, you can pass this class to trpgrTextureHelper and let - it get the image data for you. + The idea is that for pageable one-time textures it makes more sense + to define them in the tiles. This keeps the size of Texture and + Material tables down in the header. It also lets us make use of + Global textures by grabbing subimages. + You'll encounter these in a tile right after the tile header. They'll + be referenced by ID in trpgGeometry nodes within that tile. They + can represent a sub-image of a Global texture or a whole Local texture. + In either case, you can pass this class to trpgrTextureHelper and let + it get the image data for you. */ TX_EXDECL class TX_CLDECL trpgLocalMaterial : public trpgReadWriteable { public: - trpgLocalMaterial(void); - ~trpgLocalMaterial(void); + trpgLocalMaterial(void); + ~trpgLocalMaterial(void); - // Set the base material for this local material - void SetBaseMaterial(int32 matSubTable,int32 matID); + // Set the base material for this local material + void SetBaseMaterial(int32 matSubTable,int32 matID); - /* Get the base material for this local material. Base materials - define the colors, specularity, texture environments, and in - general everything not having to do with the texture image itself. - In effect you're using the base material as your material definition and - the local material is just telling you what part of the image to use. - By convention, there should only be one global image used in any given - trpgMaterial and it should be at texture index 0 (within that trpgMaterial). - If you want to use multiple pageable textures per polygon, you can do - that with multiple materials per trpgGeometry node. Doing it any - other way makes my head hurt (actually the thought of multiple, pageable - textures per polygon makes my head hurt in general). - */ - bool GetBaseMaterial(int32 &matSubTable,int32 &matID) const; + /* Get the base material for this local material. Base materials + define the colors, specularity, texture environments, and in + general everything not having to do with the texture image itself. + In effect you're using the base material as your material definition and + the local material is just telling you what part of the image to use. + By convention, there should only be one global image used in any given + trpgMaterial and it should be at texture index 0 (within that trpgMaterial). + If you want to use multiple pageable textures per polygon, you can do + that with multiple materials per trpgGeometry node. Doing it any + other way makes my head hurt (actually the thought of multiple, pageable + textures per polygon makes my head hurt in general). + // 2003-06-17. Your prophecy (my headache) has come true. MD + */ + bool GetBaseMaterial(int32 &matSubTable,int32 &matID) const; - class SubImageInfo { - public: - int32 sx,sy; // Source (sx,sy) in pixels - int32 ex,ey; // Source (ex,ey) in pixels - int32 destWidth,destHeight; // Size of destination image (in pixels) - }; + class SubImageInfo { + public: + int32 sx,sy; // Source (sx,sy) in pixels + int32 ex,ey; // Source (ex,ey) in pixels + int32 destWidth,destHeight; // Size of destination image (in pixels) + }; - // Set the sub image info (only for writers) - void SetSubImageInfo(const SubImageInfo &); + // Set the sub image info (only for writers) + void SetSubImageInfo(const SubImageInfo &); - /* Get the sub image info. This is valid only for Global images - (you can check what a given Local Material is by looking at the - base material's texture). - */ - bool GetSubImageInfo(SubImageInfo &) const; + /* Get the sub image info. This is valid only for Global images + (you can check what a given Local Material is by looking at the + base material's texture). + */ + bool GetSubImageInfo(SubImageInfo &) const; - // Set the address info (only for writers) - void SetAddr(const trpgwAppAddress &); + // Set the address info (only for writers) + void SetAddr(const trpgwAppAddress &); - /* Get the address (location in an archive) for an image. - This is valid for Local images only. You can determine what - a Local Material refers to by looking in its base material's texture. - */ - bool GetAddr(trpgwAppAddress &) const; + // Set address info for one of multiple local textures + void SetNthAddr(unsigned int subtable, const trpgwAppAddress &); - // Set the storage sizes for all mipmap levels -// bool SetStorageSizes(vector &); + /* Get the address (location in an archive) for an image. + This is valid for Local images only. You can determine what + a Local Material refers to by looking in its base material's texture. + */ + bool GetAddr(trpgwAppAddress &) const; - // Get the storage sizes for all mipmap levels. -// bool GetStorageSizes(const vector *) const; + // Get address info for one of multiple local textures + bool GetNthAddr(unsigned int subtable, trpgwAppAddress &) const; - // Validity check - bool isValid(void) const; - // Reads this class from a read buffer - void Reset(void); + // Get the number of local images associated with this local material + // Tile Local Images only + bool GetNumLocals(int &) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Set the storage sizes for all mipmap levels +// bool SetStorageSizes(vector &); + + // Get the storage sizes for all mipmap levels. +// bool GetStorageSizes(const vector *) const; + + // Validity check + bool isValid(void) const; + // Reads this class from a read buffer + void Reset(void); + + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int32 baseMatTable,baseMat; - // These are valid for Global images - int32 sx,sy,ex,ey,destWidth,destHeight; - // Storage sizes for each mipmap level. Important for compressed textures. -// vector storageSize; - // This is valid only for Tile Local images - trpgwAppAddress addr; + int32 baseMatTable,baseMat; + // These are valid for Global images + int32 sx,sy,ex,ey,destWidth,destHeight; + // Storage sizes for each mipmap level. Important for compressed textures. +// vector storageSize; + // This is valid only for Tile Local images + std::vector addr; }; /* The tile header is one of the more interesting parts of TerraPage. Basically, - it's a list of all the materials, local material and models used in a tile. Tile headers are - stuck at the beginning of terrain tiles to give you this information. They - can be read separately, in theory, although no one is doing that at present. + it's a list of all the materials, local material and models used in a tile. Tile headers are + stuck at the beginning of terrain tiles to give you this information. They + can be read separately, in theory, although no one is doing that at present. - If you're doing a TerraPage reader you will encounter one of these first thing - when you parse a terrain tile. These are here to aid texture and model paging. - Texture paging is the most common and there are now two ways of doing it. The - simpler one (supported in version 1.0) is as follows. Textures are indexed at - the beginning of a TerraPage archive (in a trpgTexTable) and when listed in the - trpgTileHeader for a tile must be loaded in for use. You can tell the pageable - textures from the non-pageable ones by looking at the tile reference count in - the trpgTexture object. + If you're doing a TerraPage reader you will encounter one of these first thing + when you parse a terrain tile. These are here to aid texture and model paging. + Texture paging is the most common and there are now two ways of doing it. The + simpler one (supported in version 1.0) is as follows. Textures are indexed at + the beginning of a TerraPage archive (in a trpgTexTable) and when listed in the + trpgTileHeader for a tile must be loaded in for use. You can tell the pageable + textures from the non-pageable ones by looking at the tile reference count in + the trpgTexture object. - The second way of doing texture paging (in version 2.0) is more complex, but - much more powerful. One of the big problems we encountered with v1.0 was the - enormous proliferation of texture files. In addition, much information was - duplicated between the different terrain resolutions. Lastly, we (TERREX) have - had a lot of success with wavelet compressed image pyramids for solving quite a - few interesting problems. This second approach to texture paging makes use of - what we've learned from all of this. The idea is that instead of having lots of - little textures, we have a small number of very large images which can support - extraction at any resolution. In this way we re-use information between terrain - levels of detail and we cut down on our disk usage, both in terms of number of - files as well as data size. + The second way of doing texture paging (in version 2.0) is more complex, but + much more powerful. One of the big problems we encountered with v1.0 was the + enormous proliferation of texture files. In addition, much information was + duplicated between the different terrain resolutions. Lastly, we (TERREX) have + had a lot of success with wavelet compressed image pyramids for solving quite a + few interesting problems. This second approach to texture paging makes use of + what we've learned from all of this. The idea is that instead of having lots of + little textures, we have a small number of very large images which can support + extraction at any resolution. In this way we re-use information between terrain + levels of detail and we cut down on our disk usage, both in terms of number of + files as well as data size. - To implement this scheme we added the trpgLocalMaterial object. trpgTexture - objects tell you if they are global images (e.g. parts are pageable). If they - are, then they can be used in a trpgLocalMaterial. These objects define the - sub-image (extents and a resolution) for a texture/material that can be used - within this tile (and only within this tile). The trpgLocalMaterial objects - reside within the trpgTileHeader and should be filled out (e.g. the sub-images - paged) as soon as the trpgTileHeader is parsed because you'll be needing them - in trpgGeometry nodes to follow. + To implement this scheme we added the trpgLocalMaterial object. trpgTexture + objects tell you if they are global images (e.g. parts are pageable). If they + are, then they can be used in a trpgLocalMaterial. These objects define the + sub-image (extents and a resolution) for a texture/material that can be used + within this tile (and only within this tile). The trpgLocalMaterial objects + reside within the trpgTileHeader and should be filled out (e.g. the sub-images + paged) as soon as the trpgTileHeader is parsed because you'll be needing them + in trpgGeometry nodes to follow. - If you want to page models, you can do so by looking at the list of model IDs - used in a tile. - - If you're doing a TerraPage writer you will need to construct one of these for - each tile that you build (remember that tiles are per-terrain LOD). You'll want - to call AddMaterial for every material that you use in a tile and AddModel - for every model. You can call these methods multiple times and it will keep track - of whether you've already added a model or material. The tile header will then - be passed to trpgwArchive along with the tile geometry and written to disk. - {group:Read/Write Classes} - */ + If you want to page models, you can do so by looking at the list of model IDs + used in a tile. + + If you're doing a TerraPage writer you will need to construct one of these for + each tile that you build (remember that tiles are per-terrain LOD). You'll want + to call AddMaterial for every material that you use in a tile and AddModel + for every model. You can call these methods multiple times and it will keep track + of whether you've already added a model or material. The tile header will then + be passed to trpgwArchive along with the tile geometry and written to disk. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTileHeader : public trpgReadWriteable { public: - trpgTileHeader(void); - ~trpgTileHeader(void); - /* Add the given material reference to this tile if it's not already there. - The ID passed in refers to a trpgMatTable. */ - void AddMaterial(int); - /* Add the given model reference to this tile if it's not already there. - The ID passed in refers to a trpgModelTable. */ - void AddModel(int); - /* Add the given local material to the list of local materials in this tile. - Local materials are used to page sub-pieces of very large images and - are referenced by trpgGeometry nodes (in their material indices) within - a given tile. Local materials can't be referenced across tiles. - */ - void AddLocalMaterial(trpgLocalMaterial &); - // {secret} - void SetDate(int32); - /* Set the given material reference to the given value. - It's easier to use AddMaterial(), if possible. - */ - void SetMaterial(int no,int id); - /* Set the given model reference (in this tile) to the given value - It's easier to use AddModel(), if possible. - */ - void SetModel(int no,int id); + trpgTileHeader(void); + ~trpgTileHeader(void); + /* Add the given material reference to this tile if it's not already there. + The ID passed in refers to a trpgMatTable. */ + void AddMaterial(int); + /* Add the given model reference to this tile if it's not already there. + The ID passed in refers to a trpgModelTable. */ + void AddModel(int); + /* Add the given local material to the list of local materials in this tile. + Local materials are used to page sub-pieces of very large images and + are referenced by trpgGeometry nodes (in their material indices) within + a given tile. Local materials can't be referenced across tiles. + */ + void AddLocalMaterial(trpgLocalMaterial &); + // {secret} + void SetDate(int32); + /* Set the given material reference to the given value. + It's easier to use AddMaterial(), if possible. + */ + void SetMaterial(int no,int id); + /* Set the given model reference (in this tile) to the given value + It's easier to use AddModel(), if possible. + */ + void SetModel(int no,int id); - // Returns the number of materials used in this tile - bool GetNumMaterial(int32 &) const; - /* Return the material ID of the Nth material reference. - The ID returned points into a trpgMatTable. */ - bool GetMaterial(int32 nth,int32 &matID) const; - // This is the number of models used in this tile - bool GetNumModel(int32 &) const; - /* Gets the model ID of the Nth model reference. - The ID returned points into a trpgModelTable. */ - bool GetModel(int32 nth,int32 &modID) const; - // Returns the number of local materials in this tile - bool GetNumLocalMaterial(int32 &) const; - /* Return the given local material. Local materials are used - to page sub-pieces of extremely large images. The Local Material - list within a tile is distinct from the list of materials used within - a tile. Local materials will be referenced by trpgGeometry nodes within - a given tile. - */ - bool GetLocalMaterial(int32 nth,trpgLocalMaterial &locMat) const; - /* Return a pointer to the list of locally defined materials. - See GetLocalMaterial for an explantion of local materials. - */ - const std::vector *GetLocalMaterialList(void) const; - // {secret} - bool GetDate(int32 &) const; + // Returns the number of materials used in this tile + bool GetNumMaterial(int32 &) const; + /* Return the material ID of the Nth material reference. + The ID returned points into a trpgMatTable. */ + bool GetMaterial(int32 nth,int32 &matID) const; + // This is the number of models used in this tile + bool GetNumModel(int32 &) const; + /* Gets the model ID of the Nth model reference. + The ID returned points into a trpgModelTable. */ + bool GetModel(int32 nth,int32 &modID) const; + // Returns the number of local materials in this tile + bool GetNumLocalMaterial(int32 &) const; + /* Return the given local material. Local materials are used + to page sub-pieces of extremely large images. The Local Material + list within a tile is distinct from the list of materials used within + a tile. Local materials will be referenced by trpgGeometry nodes within + a given tile. + */ + bool GetLocalMaterial(int32 nth,trpgLocalMaterial &locMat) const; + /* Return a pointer to the list of locally defined materials. + See GetLocalMaterial for an explantion of local materials. + */ + const std::vector *GetLocalMaterialList(void) const; + // {secret} + bool GetDate(int32 &) const; - // Validity check - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); + // Validity check + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - std::vector matList; - std::vector modelList; - std::vector locMats; - // {secret} - int date; + std::vector matList; + std::vector modelList; + std::vector locMats; + // {secret} + int date; }; /* The color info structure is used by the trpgGeometry class to store - per vertex (or per primitive) color information. It can be read directly - by the user (all its data is public). This structure is returned by - trpgGeometry::GetColorSet(). - {group:Read/Write Classes} - */ + per vertex (or per primitive) color information. It can be read directly + by the user (all its data is public). This structure is returned by + trpgGeometry::GetColorSet(). + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgColorInfo { public: - trpgColorInfo(void); - ~trpgColorInfo(void); + trpgColorInfo(void); + ~trpgColorInfo(void); - /* This is a trpgGeometry::ColorType - */ - int type; - /* This refers to how the colors in the data array are used. - It can take the values "Overall", "PerPrim" or "PerVertex". - */ - int bind; - /* The list of colors. There will be one total (bind=Overall), one per - primitive (bind=PerPrim), or one per vertex (bind=PerVertex). - */ - std::vector data; - /* Resets the structure to a default state. - */ - void Reset(void); + /* This is a trpgGeometry::ColorType + */ + int type; + /* This refers to how the colors in the data array are used. + It can take the values "Overall", "PerPrim" or "PerVertex". + */ + int bind; + /* The list of colors. There will be one total (bind=Overall), one per + primitive (bind=PerPrim), or one per vertex (bind=PerVertex). + */ + std::vector data; + /* Resets the structure to a default state. + */ + void Reset(void); - // Print out debugging info - bool Print(trpgPrintBuffer &) const; + // Print out debugging info + bool Print(trpgPrintBuffer &) const; }; /* This class represents a group of texture coordinates applied to a trpgGeometry - class. It is returned by trpgGeometry::GetTexCoordSet. TerraPage supports - multiple materials per polygon. The way we implement this is as multiple - materials on a trpgGeometry node. The first material with be the "primary" - and additional ones will be secondary and so on. - To support this, we need multiple sets of texture coordinates. That's what - this structure is used for. - {group:Read/Write Classes} - */ + class. It is returned by trpgGeometry::GetTexCoordSet. TerraPage supports + multiple materials per polygon. The way we implement this is as multiple + materials on a trpgGeometry node. The first material with be the "primary" + and additional ones will be secondary and so on. + To support this, we need multiple sets of texture coordinates. That's what + this structure is used for. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTexData { public: - trpgTexData(void); - ~trpgTexData(void); - // This should always be set to PerVertex - int bind; - /* List of texture coordinates in 32 bit floating point. - There should be one per vertex. Either this or doubleData will be - set, but never both. - */ - std::vector floatData; - /* List of texture coordinates in 64 bit floating point. - There should be one per vertex. Either this or floatData will be - set, but never both. - */ - std::vector doubleData; - /* Initialize the texture coordinate data set with floating point or double values. - num should correspond to the correct bind. */ - void set(int num,int bind,const float32 *); - void set(int num,int bind,const float64 *); - /* Resets the structure to a default state. - */ - void Reset(void); + trpgTexData(void); + ~trpgTexData(void); + // This should always be set to PerVertex + int bind; + /* List of texture coordinates in 32 bit floating point. + There should be one per vertex. Either this or doubleData will be + set, but never both. + */ + std::vector floatData; + /* List of texture coordinates in 64 bit floating point. + There should be one per vertex. Either this or floatData will be + set, but never both. + */ + std::vector doubleData; + /* Initialize the texture coordinate data set with floating point or double values. + num should correspond to the correct bind. */ + void set(int num,int bind,const float32 *); + void set(int num,int bind,const float64 *); + /* Resets the structure to a default state. + */ + void Reset(void); - // Print out debugging info - bool Print(trpgPrintBuffer &) const; + // Print out debugging info + bool Print(trpgPrintBuffer &) const; }; /* The trpgGeometry class represents a low level geometry node within the - TerraPage "scene graph". This is where the triangles (or quads, polygons, etc...) - are actually kept. If you're writing a TerraPage reader, you'll encounter a - lot of these nodes. If you're doing a writer, you'll need to construct them. - You can use a trpgwGeomHelper to aid you in this process. - We use data arrays to store lists of vertices, colors, texture coordinates, and - normals. These data arrays correspond pretty closely to the respective OpenGL - equivalents. + TerraPage "scene graph". This is where the triangles (or quads, polygons, etc...) + are actually kept. If you're writing a TerraPage reader, you'll encounter a + lot of these nodes. If you're doing a writer, you'll need to construct them. + You can use a trpgwGeomHelper to aid you in this process. + We use data arrays to store lists of vertices, colors, texture coordinates, and + normals. These data arrays correspond pretty closely to the respective OpenGL + equivalents. - In general, you'll want to do a GetPrimType() to figure out what primitive - type (PrimType) a given node is holding. It will typically be TriStrips, - TriFans, or Triangles, but all the other types are valid as well. - The next step is to get the vertices via a GetVertices() call and then get - the normals and texture coordinates (via GetNormals() and GetTexCoordSet() calls). - To get the material information call GetNumMaterial() (if you can support more - than one texture per polygon) and then GetMaterial() for each material. If you - only support one material/texture per polygon then just do one GetMaterial() all. - There's always guaranteed to be at least one material. + In general, you'll want to do a GetPrimType() to figure out what primitive + type (PrimType) a given node is holding. It will typically be TriStrips, + TriFans, or Triangles, but all the other types are valid as well. + The next step is to get the vertices via a GetVertices() call and then get + the normals and texture coordinates (via GetNormals() and GetTexCoordSet() calls). + To get the material information call GetNumMaterial() (if you can support more + than one texture per polygon) and then GetMaterial() for each material. If you + only support one material/texture per polygon then just do one GetMaterial() all. + There's always guaranteed to be at least one material. - It's a good idea to review the OpenGL specification for triangle arrays and - such before diving into this structure. - {group:Read/Write Classes} - */ + It's a good idea to review the OpenGL specification for triangle arrays and + such before diving into this structure. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgGeometry : public trpgReadWriteable { public: - trpgGeometry(void); - ~trpgGeometry(void); - typedef enum {Points,LineStrips,LineLoops,Lines,Polygons,TriStrips, - TriFans,Triangles,QuadStrips,Quads} PrimType; - // Set the primitive type for the geometry node - void SetPrimType(PrimType type); - /* Some primitive types require lengths. These include TriStrips and - TriFans, but not Triangles, for example. */ - void SetPrimLengths(int,const int *); - /* Add a primitive length on to the end of the current primLength array. - Use this if you're adding geometry one vertex at a time. - */ - void AddPrimLength(int); - /* This just increments the number of primitives in the structure. Use this - if you're adding geometry one vertex at a time for a Triangle array, for example. - */ - void AddPrim(void); - /* Set the total number of primitives. You would use this only when the PrimType - does not require primitive lengths (e.g. Triangles, but not TriStrips). Use - SetPrimLengths() or AddPrimLength() in that case. - */ - void SetNumPrims(int); // Only when there are no primitive lengths - /* This function sets the total number of materials applied to this group - of geometry. If you're only using one material, trpgGeometry defaults to - 1, so you can just do a SetMaterial() and ignore this. - */ - void SetNumMaterial(int); - /* Set the given material instance (in this trpgGeometry node) to the given - material ID. The material ID is an index into a trpgMatTable. You would - need to do a SetNumMaterial() call first, before any number of SetMaterial() - calls if there is more than one material. If there is only one material, - you can do a single SetMaterial(0,MatID) call. - Negative materials IDs denote local material definitions (e.g. parts of - a larger, paged image). They will always be returned as positive by - GetMaterial, however you must set them as negative so that GetMaterial - can set its isLocal bit on return. - */ - void SetMaterial(int which,int matID,bool isLocal=false); - /* This is the same as repeated SetMaterial() calls. - */ - void SetMaterials(int32 numMat,const int32 *matIDs); - /* This adds the given material ID to the end of the material list. - You can use this instead of SetNumMaterial() and SetMaterial(). - */ - int AddMaterial(int matID); + trpgGeometry(void); + ~trpgGeometry(void); + typedef enum {Points,LineStrips,LineLoops,Lines,Polygons,TriStrips, + TriFans,Triangles,QuadStrips,Quads} PrimType; + // Set the primitive type for the geometry node + void SetPrimType(PrimType type); + /* Some primitive types require lengths. These include TriStrips and + TriFans, but not Triangles, for example. */ + void SetPrimLengths(int,const int *); + /* Add a primitive length on to the end of the current primLength array. + Use this if you're adding geometry one vertex at a time. + */ + void AddPrimLength(int); + /* This just increments the number of primitives in the structure. Use this + if you're adding geometry one vertex at a time for a Triangle array, for example. + */ + void AddPrim(void); + /* Set the total number of primitives. You would use this only when the PrimType + does not require primitive lengths (e.g. Triangles, but not TriStrips). Use + SetPrimLengths() or AddPrimLength() in that case. + */ + void SetNumPrims(int); // Only when there are no primitive lengths + /* This function sets the total number of materials applied to this group + of geometry. If you're only using one material, trpgGeometry defaults to + 1, so you can just do a SetMaterial() and ignore this. + */ + void SetNumMaterial(int); + /* Set the given material instance (in this trpgGeometry node) to the given + material ID. The material ID is an index into a trpgMatTable. You would + need to do a SetNumMaterial() call first, before any number of SetMaterial() + calls if there is more than one material. If there is only one material, + you can do a single SetMaterial(0,MatID) call. + Negative materials IDs denote local material definitions (e.g. parts of + a larger, paged image). They will always be returned as positive by + GetMaterial, however you must set them as negative so that GetMaterial + can set its isLocal bit on return. + */ + void SetMaterial(int which,int matID,bool isLocal=false); + /* This is the same as repeated SetMaterial() calls. + */ + void SetMaterials(int32 numMat,const int32 *matIDs); + /* This adds the given material ID to the end of the material list. + You can use this instead of SetNumMaterial() and SetMaterial(). + */ + int AddMaterial(int matID); - // These are primitive types used within the trpgGeometry structure. - enum {VertexFloat,VertexDouble,NormalFloat,NormalDouble, - Color,TextureFloat,TextureDouble,EdgeFlag}; + // These are primitive types used within the trpgGeometry structure. + enum {VertexFloat,VertexDouble,NormalFloat,NormalDouble, + Color,TextureFloat,TextureDouble,EdgeFlag}; - /* Used to tell some of the trpgGeometry methods what kind of - data they're getting */ - typedef enum {FloatData,DoubleData} DataType; + /* Used to tell some of the trpgGeometry methods what kind of + data they're getting */ + typedef enum {FloatData,DoubleData} DataType; - /* The SetVertices() methods will set either 32 or 64 bit floating - point vertex arrays within the trpgGeometry structure. - The num passed in is the number of vertices, not the number of individual - floats or doubles (as with GetNumVertex). - */ - void SetVertices(int num,const float32 *); - void SetVertices(int num,const float64 *); - /* This method will add a vertex to the end of the appropriate data array - (either float or double, but never both). You would use this method - if you were building up a trpgGeometry structure vertex by vertex. - */ - void AddVertex(DataType type,trpg3dPoint &); - /* Binding type used by colors, normals, and textures (just PerPrim). - */ - typedef enum {Overall,PerPrim,PerVertex} BindType; - /* The SetNormals() methods will set either the 32 or 64 bit floating - point normal arrays within the trpgGeometry structure. - The num of normals is determined by the bind type. You should - either set the 32 or 64 bit floating point arrays, but not both. - num is the number of individual normals, not float values, unlike - the GetNumNormal() call. - */ - void SetNormals(int num,BindType bind,const float32 *); - void SetNormals(int num,BindType bind,const float64 *); - /* This method is used to add normals one by one of the given type. - You would use this if you were adding geometry one vertex at a time - in conjuntion with AddVertex(). - */ - void AddNormal(DataType type,trpg3dPoint &); - /* This constant is used to select the type of a color array - passed to SetColors(). - */ - typedef enum {Ambient,Diffuse,Specular,Emission} ColorType; - /* This method sets an array of color structures for a trpgGeometry node. - The num should correspond to the bind type. You can set as many of - these color arrays as you like, they're simply stored in an array for - later use. - */ - void SetColors(int num,ColorType type,BindType bind,const trpgColor *); - /* The SetTexCoords() methods set a list of texture coordinates. This - essentially builds a trpgTexData class and pushes it onto the current - list of texture coordinate sets. Choose the appropriate method based - on 32 or 64 bit floating point values. num should be the number of - texture coordinates, not the number of floats passed in. + /* The SetVertices() methods will set either 32 or 64 bit floating + point vertex arrays within the trpgGeometry structure. + The num passed in is the number of vertices, not the number of individual + floats or doubles (as with GetNumVertex). + */ + void SetVertices(int num,const float32 *); + void SetVertices(int num,const float64 *); + /* This method will add a vertex to the end of the appropriate data array + (either float or double, but never both). You would use this method + if you were building up a trpgGeometry structure vertex by vertex. + */ + void AddVertex(DataType type,trpg3dPoint &); + /* Binding type used by colors, normals, and textures (just PerPrim). + */ + typedef enum {Overall,PerPrim,PerVertex} BindType; + /* The SetNormals() methods will set either the 32 or 64 bit floating + point normal arrays within the trpgGeometry structure. + The num of normals is determined by the bind type. You should + either set the 32 or 64 bit floating point arrays, but not both. + num is the number of individual normals, not float values, unlike + the GetNumNormal() call. + */ + void SetNormals(int num,BindType bind,const float32 *); + void SetNormals(int num,BindType bind,const float64 *); + /* This method is used to add normals one by one of the given type. + You would use this if you were adding geometry one vertex at a time + in conjuntion with AddVertex(). + */ + void AddNormal(DataType type,trpg3dPoint &); + /* This constant is used to select the type of a color array + passed to SetColors(). + */ + typedef enum {Ambient,Diffuse,Specular,Emission} ColorType; + /* This method sets an array of color structures for a trpgGeometry node. + The num should correspond to the bind type. You can set as many of + these color arrays as you like, they're simply stored in an array for + later use. + */ + void SetColors(int num,ColorType type,BindType bind,const trpgColor *); + /* The SetTexCoords() methods set a list of texture coordinates. This + essentially builds a trpgTexData class and pushes it onto the current + list of texture coordinate sets. Choose the appropriate method based + on 32 or 64 bit floating point values. num should be the number of + texture coordinates, not the number of floats passed in. - bind should be PerPrim in all cases. - */ - void SetTexCoords(int num,BindType bind,const float32 *); - void SetTexCoords(int num,BindType bind,const float64 *); - /* This is the same as SetTexCoords(0,bind,NULL) */ - void AddTexCoords(BindType bind); - /* This method adds a texture coordinate to array 0. You would use - this if you were adding vertices one at a time. - */ - void AddTexCoord(DataType type,trpg2dPoint &); - /* Edge flags are used by some primitives in OpenGL. We don't typically - use them, but they can be read and written with TerraPage. - */ - void SetEdgeFlags(int num,const char *); + bind should be PerPrim in all cases. + */ + void SetTexCoords(int num,BindType bind,const float32 *); + void SetTexCoords(int num,BindType bind,const float64 *); + /* This is the same as SetTexCoords(0,bind,NULL) */ + void AddTexCoords(BindType bind); + /* This method adds a texture coordinate to array n. You would use + this if you were adding vertices one at a time. + */ + void AddTexCoord(DataType type,trpg2dPoint &,int n=0); + /* This method adds a texture coordinate to each trpgTexData. You would use + this if you were adding vertices one at a time with multiple materials. + */ + void AddTexCoord(DataType type,std::vector &pts); + /* Edge flags are used by some primitives in OpenGL. We don't typically + use them, but they can be read and written with TerraPage. + */ + void SetEdgeFlags(int num,const char *); - /* Returns the primitive type for this trpgGeometry structure. - */ - bool GetPrimType(PrimType &type) const; - /* Number of primitives in this structure. Primitives are things - like a single triangle, a triangle strip or fan. Some primitives - require a primitive length array. - */ - bool GetNumPrims(int &num) const; - /* This returns the primitive length array. Some primitive types, like - TriStrips or TriFans (but not Triangles) require a primitive length - array to tell you how to break up the vertex/normal/texture/color - arrays into individual primitives. The array you pass in must be - of a certain length (returned by GetNumPrims()) and will only be - valid for some primitive types. - */ - bool GetPrimLengths(int *lenArray) const; - /* TerraPage supports multiple materials per geometry set. This method - tells you how many are applied to this structure. There will always - be at least one. - */ - bool GetNumMaterial(int &num) const; - /* Returns the material ID for a material instance. num is the - nth material instance. matId is an index into a trpgMatTable. - isLocal is true if the given material is local to this tile. - Local materials are only used to page small pieces of a larger image. - */ - bool GetMaterial(int num,int32 &matID,bool &isLocal) const; - /* This returns num_vertex. The function returns the length - of the vertex array dived by 3, which is the total number of - vertices. - */ - bool GetNumVertex(int &num) const; - /* The GetVertices() methods return a list of vertices in the given - form (32 or 64 bit floating point). These functions will convert to - the appropriate format, just ask for the one you need. - The length of the vertex array is determined by GetNumVertex(), which - returns 3* the number of vertices. - */ - bool GetVertices(float32 *) const; - bool GetVertices(float64 *) const; + /* Returns the primitive type for this trpgGeometry structure. + */ + bool GetPrimType(PrimType &type) const; + /* Number of primitives in this structure. Primitives are things + like a single triangle, a triangle strip or fan. Some primitives + require a primitive length array. + */ + bool GetNumPrims(int &num) const; + /* This returns the primitive length array. Some primitive types, like + TriStrips or TriFans (but not Triangles) require a primitive length + array to tell you how to break up the vertex/normal/texture/color + arrays into individual primitives. The array you pass in must be + of a certain length (returned by GetNumPrims()) and will only be + valid for some primitive types. + */ + bool GetPrimLengths(int *lenArray) const; + /* TerraPage supports multiple materials per geometry set. This method + tells you how many are applied to this structure. There will always + be at least one. + */ + bool GetNumMaterial(int &num) const; + /* Returns the material ID for a material instance. num is the + nth material instance. matId is an index into a trpgMatTable. + isLocal is true if the given material is local to this tile. + Local materials are only used to page small pieces of a larger image. + */ + bool GetMaterial(int num,int32 &matID,bool &isLocal) const; + /* This returns num_vertex. The function returns the length + of the vertex array dived by 3, which is the total number of + vertices. + */ + bool GetNumVertex(int &num) const; + /* The GetVertices() methods return a list of vertices in the given + form (32 or 64 bit floating point). These functions will convert to + the appropriate format, just ask for the one you need. + The length of the vertex array is determined by GetNumVertex(), which + returns 3* the number of vertices. + */ + bool GetVertices(float32 *) const; + bool GetVertices(float64 *) const; + /* This method lets you get an individual vertex. The number of vertices + can be determined by GetNumVertex()/3. + */ + bool GetVertex(int id,trpg3dPoint &) const; + /* GetNumNormal() returns the number of normals. See GetNumVertex() + for an explanation of why. + */ + bool GetNumNormal(int &num) const; + /* Much, like GetVertices(), these methods will copy the contents of + the normal array into the array passed in. They will convert the + contents to the appropriate format (32 or 64 bit floating point). + The length of the input array can be determined by GetNumNormal(). + */ + bool GetNormals(float32 *) const; + bool GetNormals(float64 *) const; + /* This returns the number of color sets in the trpgGeometry structure. + There can be one color set per ColorType. Color sets are either + per vertex, per primitive, or per geometry unit (i.e. only one) + arrays of color data. + */ + bool GetNumColorSets(int &num) const; + /* This method fills out the trpgColorInfo class that you pass in. + The number of color sets is determined by GetNumColorSets and + the structure you passed can be reused (to save memory). + */ + bool GetColorSet(int id,trpgColorInfo *) const; + /* Returns the number of texture coordinate sets. There could (and + should) be one texture coordinate set per material applied to this + geometry. Tex Coord sets can be retrieved with GetTexCoordSet. + */ + bool GetNumTexCoordSets(int &) const; + /* This method returns the texture coordinate set specified by the given + index. GetNumTexCoordSets determines the total number of texture + coordinate sets. + */ + bool GetTexCoordSet(int id,trpgTexData *) const; + /* Returns the number of edge flags in this geometry node. + Edge flags are used on certain primitive types, but are rather rare. + */ + bool GetNumEdgeFlag(int &num) const; + /* This returns the edge flags for the current set of primitives. + */ + bool GetEdgeFlags(char *) const; - bool GetVertices(osg::Vec3*) const; - /* This method lets you get an individual vertex. The number of vertices - can be determined by GetNumVertex()/3. - */ - bool GetVertex(int id,trpg3dPoint &) const; - /* GetNumNormal() returns the number of normals. See GetNumVertex() - for an explanation of why. - */ - bool GetNumNormal(int &num) const; - /* Much, like GetVertices(), these methods will copy the contents of - the normal array into the array passed in. They will convert the - contents to the appropriate format (32 or 64 bit floating point). - The length of the input array can be determined by GetNumNormal(). - */ - bool GetNormals(float32 *) const; - bool GetNormals(float64 *) const; - bool GetNormals(osg::Vec3*) const; - /* This returns the number of color sets in the trpgGeometry structure. - There can be one color set per ColorType. Color sets are either - per vertex, per primitive, or per geometry unit (i.e. only one) - arrays of color data. - */ - bool GetNumColorSets(int &num) const; - /* This method fills out the trpgColorInfo class that you pass in. - The number of color sets is determined by GetNumColorSets and - the structure you passed can be reused (to save memory). - */ - bool GetColorSet(int id,trpgColorInfo *) const; - /* Returns the number of texture coordinate sets. There could (and - should) be one texture coordinate set per material applied to this - geometry. Tex Coord sets can be retrieved with GetTexCoordSet. - */ - bool GetNumTexCoordSets(int &) const; - /* This method returns the texture coordinate set specified by the given - index. GetNumTexCoordSets determines the total number of texture - coordinate sets. - */ - bool GetTexCoordSet(int id,trpgTexData *) const; - /* Returns the number of edge flags in this geometry node. - Edge flags are used on certain primitive types, but are rather rare. - */ - bool GetNumEdgeFlag(int &num) const; - /* This returns the edge flags for the current set of primitives. - */ - bool GetEdgeFlags(char *) const; + // Returns true if the trpgGeometry structure is valid + bool isValid(void) const; + // Resets the contents back to empty + void Reset(void); - // Returns true if the trpgGeometry structure is valid - bool isValid(void) const; - // Resets the contents back to empty - void Reset(void); - - // Write self to a buffer - bool Write(trpgWriteBuffer &); - // Read self from a buffer. Check isValid() afterwards - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Write self to a buffer + bool Write(trpgWriteBuffer &); + // Read self from a buffer. Check isValid() afterwards + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int primType; - int numPrim; - std::vector primLength; - std::vector materials; - std::vector vertDataFloat; - std::vector vertDataDouble; - int normBind; - std::vector normDataFloat; - std::vector normDataDouble; - std::vector colors; - std::vector texData; - std::vector edgeFlags; + int primType; + int numPrim; + std::vector primLength; + std::vector materials; + std::vector vertDataFloat; + std::vector vertDataDouble; + int normBind; + std::vector normDataFloat; + std::vector normDataDouble; + std::vector colors; + std::vector texData; + std::vector edgeFlags; }; /* This is a standard Group that you might see in any reasonable - scene graph. It holds a number of children. TerraPage isn't - actually a scene graph, it just represents one. That means that there - are no pointers to children here. Instead you'll encounter this group - while reading a terrain tile or model. That tells you to create a group - (or whatever you call it) in your own system and get read to dump child - trees into it. A push will follow this object, then the children (however - deep they may be) then a pop. + scene graph. It holds a number of children. TerraPage isn't + actually a scene graph, it just represents one. That means that there + are no pointers to children here. Instead you'll encounter this group + while reading a terrain tile or model. That tells you to create a group + (or whatever you call it) in your own system and get read to dump child + trees into it. A push will follow this object, then the children (however + deep they may be) then a pop. - All groups have IDs. These IDs are unique among groups and group-like things - (i.e. LODs) and are used to hook trpgAttach geometry into a scene graph hierachy - as you page in higher terrain levels of detail. + All groups have IDs. These IDs are unique among groups and group-like things + (i.e. LODs) and are used to hook trpgAttach geometry into a scene graph hierachy + as you page in higher terrain levels of detail. - If you're doing a TerraPage reader, the group tells you to put together - your generic container in a scene graph and get read for the push/children/pop. - The NumChild field should tell you how many children will follow, but a writer - can easily forget to put it, so be wary. You'll also want to look at the group - ID and build a mapping from that ID (look at the max group ID in trpgHeader) to - your own group structure. A trpgAttach is allowed to page itself into any group. + If you're doing a TerraPage reader, the group tells you to put together + your generic container in a scene graph and get read for the push/children/pop. + The NumChild field should tell you how many children will follow, but a writer + can easily forget to put it, so be wary. You'll also want to look at the group + ID and build a mapping from that ID (look at the max group ID in trpgHeader) to + your own group structure. A trpgAttach is allowed to page itself into any group. - If you're doing a TerraPage writer you'll create one of these, fill out the - numChild hint, the group ID and then write it. You'll then write a Push, then - the children hierarchies (which can be anything) followed by a Pop. You'll want - to keep track of the group ID you assigned in case one of the children is a - pageable chunk of terrain hierarchy. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer you'll create one of these, fill out the + numChild hint, the group ID and then write it. You'll then write a Push, then + the children hierarchies (which can be anything) followed by a Pop. You'll want + to keep track of the group ID you assigned in case one of the children is a + pageable chunk of terrain hierarchy. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgGroup : public trpgReadWriteable { public: - trpgGroup(void); - virtual ~trpgGroup(void); - // Resets the contents back to empty - virtual void Reset(void); + trpgGroup(void); + virtual ~trpgGroup(void); + // Resets the contents back to empty + virtual void Reset(void); - /* Set the total number of children this group will have */ - virtual void SetNumChild(int); - // Starting from 0, increments the number of children - virtual int AddChild(void); - /* The writer is supposed to set this value to the number of - children. */ - virtual bool GetNumChild(int &) const; + /* Set the total number of children this group will have */ + virtual void SetNumChild(int); + // Starting from 0, increments the number of children + virtual int AddChild(void); + /* The writer is supposed to set this value to the number of + children. */ + virtual bool GetNumChild(int &) const; - /* Set the group ID */ - virtual void SetID(int); - // Returns the group ID - virtual bool GetID(int &) const; + /* Set the group ID */ + virtual void SetID(int); + // Returns the group ID + virtual bool GetID(int &) const; - /* Set the group name */ - void SetName(const char* ); - // Returns the group name - const char* GetName(void) const; + /* Set the group name */ + void SetName(const char* ); + // Returns the group name + const char* GetName(void) const; - // Validity check - virtual bool isValid(void) const; - // Writes this class to a write buffer - virtual bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Validity check + virtual bool isValid(void) const; + // Writes this class to a write buffer + virtual bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int id; - int numChild; - char* name; + int id; + int numChild; + char* name; }; /* Structurally, an attach is just like a trpgGroup. It does everything a group - does, plus a little bit more. The attach node is how TerraPage does terrain - database paging across LODs. + does, plus a little bit more. The attach node is how TerraPage does terrain + database paging across LODs. - In TerraPage we don't enfoced a terrain LOD structure. Let's say you built - your database as a quad-tree. That is, there is one root tile per block, - 4 children, each of which has 4 of its own children etc... That would imply - a certain structure (4 children per tile until you reach the bottom). That would - also lock you into a database scheme (quad-tree). However, let's assume that - someone else wanted to do replacement LOD for their terrain. That scheme works - by having one child per tile. If you want to support both of these then you're - asking the reader to do a lot of thinking and you can pretty much assume that the - one you don't test won't work. We decided to avoid all that by coming up with a - generic scene graph paging scheme. It's a little more painfull, but once you deal - with it you get whatever weird scheme the writer is using for free without having to - think about it. + In TerraPage we don't enfoced a terrain LOD structure. Let's say you built + your database as a quad-tree. That is, there is one root tile per block, + 4 children, each of which has 4 of its own children etc... That would imply + a certain structure (4 children per tile until you reach the bottom). That would + also lock you into a database scheme (quad-tree). However, let's assume that + someone else wanted to do replacement LOD for their terrain. That scheme works + by having one child per tile. If you want to support both of these then you're + asking the reader to do a lot of thinking and you can pretty much assume that the + one you don't test won't work. We decided to avoid all that by coming up with a + generic scene graph paging scheme. It's a little more painfull, but once you deal + with it you get whatever weird scheme the writer is using for free without having to + think about it. - Here's how it works. Each trpgGroup and group-like structure (trpgLod for example) - has a unique group ID. You can have one trpgAttach at the start of a given terrain - tile. That trpgAttach can point to any group within the scene graph (with a group ID). - Level of detail for the terrain is controlled by trpgLod nodes as if everything was - loaded in all the time. That is, you'll see the same thing no matter whether every node - is loaded into memory or just the nearby ones. The theoretical scene graph structure - is the same no matter what. It's the ranges in your trpgHeader that tell you when - things ought to be loaded in, but the actual display logic is contained within the trpgLod - objects. It sounds complicated and it is... for the writer. But for the reader it's - really simple. + Here's how it works. Each trpgGroup and group-like structure (trpgLod for example) + has a unique group ID. You can have one trpgAttach at the start of a given terrain + tile. That trpgAttach can point to any group within the scene graph (with a group ID). + Level of detail for the terrain is controlled by trpgLod nodes as if everything was + loaded in all the time. That is, you'll see the same thing no matter whether every node + is loaded into memory or just the nearby ones. The theoretical scene graph structure + is the same no matter what. It's the ranges in your trpgHeader that tell you when + things ought to be loaded in, but the actual display logic is contained within the trpgLod + objects. It sounds complicated and it is... for the writer. But for the reader it's + really simple. - If you're doing a TerraPage reader all you'll need to do is keep a mapping from group - ID's to your own internal scene graph node representation. Then when a trpgAttach shows - up you can turn it into your own group-like thing and stuff it and its children into - the scene graph. When it wanders out of range (the trpgHeader tells you that for a given - terrain LOD) you simply delete it. If you out-run your paging you've got two options: - (1) Display holes. That's what will happen when the LOD above a given tile trpgAttach - turns on without the children in memory; or (2) Don't switch LODs that don't have all - their children loaded in yet. Be aware that a trpgAttach inherits from trpgGroup and - so can have trpgAttach children. So don't absorb the trpgAttach even though it's extra - hierarchy. Also, don't make any assumptions that there is really terrain in a given - tile. The writer may have chosen to page buildings or trees. You never know and there's - no reason to assume. + If you're doing a TerraPage reader all you'll need to do is keep a mapping from group + ID's to your own internal scene graph node representation. Then when a trpgAttach shows + up you can turn it into your own group-like thing and stuff it and its children into + the scene graph. When it wanders out of range (the trpgHeader tells you that for a given + terrain LOD) you simply delete it. If you out-run your paging you've got two options: + (1) Display holes. That's what will happen when the LOD above a given tile trpgAttach + turns on without the children in memory; or (2) Don't switch LODs that don't have all + their children loaded in yet. Be aware that a trpgAttach inherits from trpgGroup and + so can have trpgAttach children. So don't absorb the trpgAttach even though it's extra + hierarchy. Also, don't make any assumptions that there is really terrain in a given + tile. The writer may have chosen to page buildings or trees. You never know and there's + no reason to assume. - If you're doing a TerraPage writer this is slightly more complex than writing a normal - format, depending on the structure of your internal scene graph. If you don't want - to write more than one pageable terrain LOD you can just ignore trpgAttach nodes. This - doesn't mean you can only have one terrain LOD, it only means they won't be pageable. - If you do want to fully support it, what you'll need to - do is give all your groups (or whatever will become groups) unique IDs, keeping in mind - to update the trpgHeader max group ID as you go. Start at the lowest terrain lod. This - one doesn't need to have a trpgAttach node since it's at the top. Traverse toward - the higher lods. When you hit one, spit out a trpgAttach, giving it the group ID of - the trpgGroup directly above it. Then treat the node you just created as a trpgGroup - (i.e. do its children as normal). You will also need to keep the trpgTileHeader for - each tile around. It's best to index these by (x,y,lod) index. You'll need to build - that tile header up *just for this tile geometry*. That means you have to stop adding - material/model references when you start defining the next tile. Depending on how you - write out your scene graph it may make sense to keep a stack of trpgTileHeader and - trpgMemWriteBuffer objects around indexed by tile (x,y,lod). + If you're doing a TerraPage writer this is slightly more complex than writing a normal + format, depending on the structure of your internal scene graph. If you don't want + to write more than one pageable terrain LOD you can just ignore trpgAttach nodes. This + doesn't mean you can only have one terrain LOD, it only means they won't be pageable. + If you do want to fully support it, what you'll need to + do is give all your groups (or whatever will become groups) unique IDs, keeping in mind + to update the trpgHeader max group ID as you go. Start at the lowest terrain lod. This + one doesn't need to have a trpgAttach node since it's at the top. Traverse toward + the higher lods. When you hit one, spit out a trpgAttach, giving it the group ID of + the trpgGroup directly above it. Then treat the node you just created as a trpgGroup + (i.e. do its children as normal). You will also need to keep the trpgTileHeader for + each tile around. It's best to index these by (x,y,lod) index. You'll need to build + that tile header up *just for this tile geometry*. That means you have to stop adding + material/model references when you start defining the next tile. Depending on how you + write out your scene graph it may make sense to keep a stack of trpgTileHeader and + trpgMemWriteBuffer objects around indexed by tile (x,y,lod). - {group:Read/Write Classes} - */ + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgAttach : public trpgGroup { public: - trpgAttach(void); - ~trpgAttach(void); - // Resets the contents back to empty - void Reset(void); + trpgAttach(void); + ~trpgAttach(void); + // Resets the contents back to empty + void Reset(void); - // Set the parent of the group/LOD/whatever to attach to when loaded in - void SetParentID(int); - // Retrieve the parent ID we'll need to attach this thing into the scene graph - bool GetParentID(int &) const; + // Set the parent of the group/LOD/whatever to attach to when loaded in + void SetParentID(int); + // Retrieve the parent ID we'll need to attach this thing into the scene graph + bool GetParentID(int &) const; - /* The writer is supposed to set this value to a unique position with relation - to its parent group. */ - void SetChildPos(int); - /* The child position is a hint as to which child this is in its parent group. - That is, if there are 3 children, of which this is one, then it could be - at child position 0, 1, or 3 in its parent. You can safely ignore this if - you want to just this node to its parent's list of children. */ - bool GetChildPos(int &) const; + /* The writer is supposed to set this value to a unique position with relation + to its parent group. */ + void SetChildPos(int); + /* The child position is a hint as to which child this is in its parent group. + That is, if there are 3 children, of which this is one, then it could be + at child position 0, 1, or 3 in its parent. You can safely ignore this if + you want to just this node to its parent's list of children. */ + bool GetChildPos(int &) const; - // Validity check - bool isValid(void) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Validity check + bool isValid(void) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int parentID,childPos; + int parentID,childPos; }; /* The billboard inherits from the standard trpgGroup. It tells the reader that - everything underneath this node is supposed to be treated like a stamp or billboard - (depending on your terminology). That means it's supposed to be rotated towards - the eye point in some way. There are no restrictions on the number, depth, or type - of children. In theory you could have another billboard as a child, although we have - no idea what that should look like. + everything underneath this node is supposed to be treated like a stamp or billboard + (depending on your terminology). That means it's supposed to be rotated towards + the eye point in some way. There are no restrictions on the number, depth, or type + of children. In theory you could have another billboard as a child, although we have + no idea what that should look like. - If you're doing a TerraPage reader treat everything underneath this group as rotatable. - Pay attention to the Type in particular. There's a shorthand for rotating a bunch - of objects that is a little confusing. + If you're doing a TerraPage reader treat everything underneath this group as rotatable. + Pay attention to the Type in particular. There's a shorthand for rotating a bunch + of objects that is a little confusing. - If you're doing a TerraPage write this is pretty simple. For the standard tree example - use one of these with one or more trpgGeometry children. - {group:Read/Write Classes} - */ + If you're doing a TerraPage write this is pretty simple. For the standard tree example + use one of these with one or more trpgGeometry children. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgBillboard : public trpgGroup { public: - trpgBillboard(void); - ~trpgBillboard(void); - enum {Individual,Group}; - // Set the type. See GetType for details. - void SetType(int); - // Set the center. - void SetCenter(const trpg3dPoint &); - enum {Axial,World,Eye}; - // Set the rotation mode. - void SetMode(int); - // Set the rotation axis if mode == Axial - void SetAxis(const trpg3dPoint &); + trpgBillboard(void); + ~trpgBillboard(void); + enum {Individual,Group}; + // Set the type. See GetType for details. + void SetType(int); + // Set the center. + void SetCenter(const trpg3dPoint &); + enum {Axial,World,Eye}; + // Set the rotation mode. + void SetMode(int); + // Set the rotation axis if mode == Axial + void SetAxis(const trpg3dPoint &); - /* The type controls how the billboard node relates to its children. There - are two modes: (1) Group - This is the obvious one. Everything below - this node rotates around the center in the way specified by GetMode. (2) Individual - This - is a little weirder. Basically, it's here for trees. It's assumed that - there will be one or more trpgGeometry nodes below this node. Each single - primitive is supposed to rotate "seperately". That is, you must take into - account the unique center of each one and rotate it around that. If you have - some optimization scheme where you can deal with groups of billboards (ala Performer) - it is valid to do so in the Individual case. */ - bool GetType(int &) const; - /* Center of the thing to be rotated. For Group this does the obvious thing. - For Individual it should be the center of the group of things you want to rotate. - This has no use if you're going to rotate each primitive seperately, but if you've - got some sort of optimized scheme for doing so (ala Performer) this information is useful. - */ - bool GetCenter(trpg3dPoint &) const; - /* The mode will be one of: (1) Axial - rotate around the Axis. This is the normal - one for tree. (2) Eye - Always rotate toward the eye point. (3) world. - */ - bool GetMode(int &) const; - /* The axis used when GetMode returns Axial. */ - bool GetAxis(trpg3dPoint &) const; + /* The type controls how the billboard node relates to its children. There + are two modes: (1) Group - This is the obvious one. Everything below + this node rotates around the center in the way specified by GetMode. (2) Individual - This + is a little weirder. Basically, it's here for trees. It's assumed that + there will be one or more trpgGeometry nodes below this node. Each single + primitive is supposed to rotate "seperately". That is, you must take into + account the unique center of each one and rotate it around that. If you have + some optimization scheme where you can deal with groups of billboards (ala Performer) + it is valid to do so in the Individual case. */ + bool GetType(int &) const; + /* Center of the thing to be rotated. For Group this does the obvious thing. + For Individual it should be the center of the group of things you want to rotate. + This has no use if you're going to rotate each primitive seperately, but if you've + got some sort of optimized scheme for doing so (ala Performer) this information is useful. + */ + bool GetCenter(trpg3dPoint &) const; + /* The mode will be one of: (1) Axial - rotate around the Axis. This is the normal + one for tree. (2) Eye - Always rotate toward the eye point. (3) world. + */ + bool GetMode(int &) const; + /* The axis used when GetMode returns Axial. */ + bool GetAxis(trpg3dPoint &) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int type; - int mode; - trpg3dPoint center; - trpg3dPoint axis; + int type; + int mode; + trpg3dPoint center; + trpg3dPoint axis; }; /* TerraPage level of detail nodes are pretty simple. Even though they don't inherit from trpgGroup, - they have many of the same calls and act, structurally at least, in much the same way. These - act as a switch. When the user's eye point is within a distance then the children of this - node should be turned on for display. Otherwise, the children will be invisible. + they have many of the same calls and act, structurally at least, in much the same way. These + act as a switch. When the user's eye point is within a distance then the children of this + node should be turned on for display. Otherwise, the children will be invisible. A simple on/off test for a TerraPage lod might look like this: - If ( in < dist < out || out < dist < in) then + If ( in < dist < out || out < dist < in) then Turn children on else Turn children off. - There is also a transition width can be used to fade LODs in and out around - the transition zones. Keep in mind that these LODs are binary. Children - are either on or off (in the process of being turned off). The position of - a child doesn't have any special meaning with respect to range. + There is also a transition width can be used to fade LODs in and out around + the transition zones. Keep in mind that these LODs are binary. Children + are either on or off (in the process of being turned off). The position of + a child doesn't have any special meaning with respect to range. - If you're doing a TerraPage reader you'll need to turn this into your own LOD - structure. Keep in mind that trpgAttach nodes can and do attach to trpgLod - nodes. If you have a general purpose LOD in your scene graph this should be - pretty easy. However, you must have implemented the concept of LOD center and - you definitely should *not* recalculate the LOD center yourself based on the - center of child geometry. They may not be the same. In fact, many terrain - LOD schemes depend on them not being the same. + If you're doing a TerraPage reader you'll need to turn this into your own LOD + structure. Keep in mind that trpgAttach nodes can and do attach to trpgLod + nodes. If you have a general purpose LOD in your scene graph this should be + pretty easy. However, you must have implemented the concept of LOD center and + you definitely should *not* recalculate the LOD center yourself based on the + center of child geometry. They may not be the same. In fact, many terrain + LOD schemes depend on them not being the same. - If you're doing a TerraPage writer you'll need to use these both for geometry - that you want to disappear at certain distances (e.g. trees, houses, etc..), but - also terrain. Any terrain LOD scheme you implement must use these to drop out - polygons in the distance. You'll need to set the center and in/out/width info. - Otherwise it's like a group. + If you're doing a TerraPage writer you'll need to use these both for geometry + that you want to disappear at certain distances (e.g. trees, houses, etc..), but + also terrain. Any terrain LOD scheme you implement must use these to drop out + polygons in the distance. You'll need to set the center and in/out/width info. + Otherwise it's like a group. - In TerraPage 2.0 we added the Range Index field. This field is here to help - run-time systems gracefully degrade visual fidelity. The trpgLod node still acts - like a normal LOD and you can safely ignore the range index field. If, however, - you want to use it, please read the documention on the trpgRangeTable for further - information. + In TerraPage 2.0 we added the Range Index field. This field is here to help + run-time systems gracefully degrade visual fidelity. The trpgLod node still acts + like a normal LOD and you can safely ignore the range index field. If, however, + you want to use it, please read the documention on the trpgRangeTable for further + information. - {group:Read/Write Classes} - */ + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgLod : public trpgReadWriteable { public: - trpgLod(void); - ~trpgLod(void); - // Set the calculated center - void SetCenter(const trpg3dPoint &); - // Set the number of children hint - void SetNumChild(int); - // Set the LOD information - void SetLOD(double in,double out,double width); + trpgLod(void); + ~trpgLod(void); + // Set the calculated center + void SetCenter(const trpg3dPoint &); + // Set the number of children hint + void SetNumChild(int); + // Set the LOD information + void SetLOD(double in,double out,double width); - // Center of this LOD. Distance from the viewer is calculated from this. - bool GetCenter(trpg3dPoint &) const; - // Number of children hint. - bool GetNumChild(int &) const; - // LOD specific information. in and out can be switched. width is - // the transition range for doing fading. - bool GetLOD(double &in,double &out,double &width) const; + // Center of this LOD. Distance from the viewer is calculated from this. + bool GetCenter(trpg3dPoint &) const; + // Number of children hint. + bool GetNumChild(int &) const; + // LOD specific information. in and out can be switched. width is + // the transition range for doing fading. + bool GetLOD(double &in,double &out,double &width) const; - // Set the group ID - void SetID(int); + // Set the group ID + void SetID(int); - // Group IDs are used here the same way as in trpgGroup - bool GetID(int &) const; + // Group IDs are used here the same way as in trpgGroup + bool GetID(int &) const; - /* Set the lod name */ - void SetName(const char* ); - // Returns the lod name - const char* GetName(void) const; + /* Set the lod name */ + void SetName(const char* ); + // Returns the lod name + const char* GetName(void) const; - // Set the range Index - void SetRangeIndex(int ri); - // Get the range index - bool GetRangeIndex(int &ri) const; + // Set the range Index + void SetRangeIndex(int ri); + // Get the range index + bool GetRangeIndex(int &ri) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; protected: - int numRange; - double switchIn,switchOut,width; - trpg3dPoint center; - int id; - char* name; - int rangeIndex; + int numRange; + double switchIn,switchOut,width; + trpg3dPoint center; + int id; + char* name; + int rangeIndex; }; /* Layers are used to draw subface geometry. That is, geometry that is - coplanar. This object should be treated just like a group otherwise. - Its existence implies the layering effect. There is no other associated - information. + coplanar. This object should be treated just like a group otherwise. + Its existence implies the layering effect. There is no other associated + information. - If you're doing a TerraPage reader you should assume that each child, - starting at 0 should be draw one after the other using whatever subfacing - scheme you support. There are no restrictions on what the children may - be, but we strongly recommend that writers keep this simple. Keep in - mind that trpgAttach nodes can legally appear as children. If you can pull - it off this has a rather nice effect (think strips on runways). If not, - don't sweat it. + If you're doing a TerraPage reader you should assume that each child, + starting at 0 should be draw one after the other using whatever subfacing + scheme you support. There are no restrictions on what the children may + be, but we strongly recommend that writers keep this simple. Keep in + mind that trpgAttach nodes can legally appear as children. If you can pull + it off this has a rather nice effect (think strips on runways). If not, + don't sweat it. - If you're doing a TerraPage writer, this is fairly simple. Obey the ordering - contraints and try to keep this simple. Ideally that would mean just a few - trpgGeometry nodes below this node. Also keep in mind that layering works - very poorly on most OpenGL systems. - {group:Read/Write Classes} - */ + If you're doing a TerraPage writer, this is fairly simple. Obey the ordering + contraints and try to keep this simple. Ideally that would mean just a few + trpgGeometry nodes below this node. Also keep in mind that layering works + very poorly on most OpenGL systems. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgLayer : public trpgGroup { public: - trpgLayer(void); - ~trpgLayer(void); - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + trpgLayer(void); + ~trpgLayer(void); + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); protected: }; /* This is pretty much a standard 4x4 static transform. It has a matrix - which controls where its children wind up in 3D. Otherwise it acts just - like a trpgGroup. - {group:Read/Write Classes} - */ + which controls where its children wind up in 3D. Otherwise it acts just + like a trpgGroup. + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgTransform : public trpgGroup { public: - trpgTransform(void); - ~trpgTransform(void); + trpgTransform(void); + ~trpgTransform(void); - // Set the 4x4 matrix - void SetMatrix(const float64 *); + // Set the 4x4 matrix + void SetMatrix(const float64 *); - // Get the 4x4 matrix - bool GetMatrix(float64 *) const; + // Get the 4x4 matrix + bool GetMatrix(float64 *) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); protected: - float64 m[4][4]; + float64 m[4][4]; }; /* TerraPage treats model references pretty much like instances. Models - are organized centrally in a trpgModelTable. This class simply points - into there with a model ID. There is also a 4x4 matrix (ala trpgTransform) - which moves the model to its final location. + are organized centrally in a trpgModelTable. This class simply points + into there with a model ID. There is also a 4x4 matrix (ala trpgTransform) + which moves the model to its final location. - If you're doing a TerraPage reader you should already have dealt with the - trpgModelTable by this point. Presumably you've got a mapping from model IDs - to small scene graphs in your own representation. This can be treated just like - an instance into one of those. + If you're doing a TerraPage reader you should already have dealt with the + trpgModelTable by this point. Presumably you've got a mapping from model IDs + to small scene graphs in your own representation. This can be treated just like + an instance into one of those. - If you're doing a TerraPage writer this is pretty simple. When you encounter - a model (external reference) add it to your trpgModelTable and stuff the resulting - model ID into one of these. Stick that trpgModelRef into your tile data stream. - You'll need to fill out the matrix to scale/translate/rotate it as well. - The model is assumed to be spatially within the tile it's written into. That isn't - enforced, though. + If you're doing a TerraPage writer this is pretty simple. When you encounter + a model (external reference) add it to your trpgModelTable and stuff the resulting + model ID into one of these. Stick that trpgModelRef into your tile data stream. + You'll need to fill out the matrix to scale/translate/rotate it as well. + The model is assumed to be spatially within the tile it's written into. That isn't + enforced, though. - {group:Read/Write Classes} - */ + {group:Read/Write Classes} + */ TX_EXDECL class TX_CLDECL trpgModelRef : public trpgReadWriteable { public: - trpgModelRef(void); - ~trpgModelRef(void); - // Set the model ID. Must come from a trpgModelTable - void SetModel(int); - // Set the 4x4 rotate/translate/scale matrix - void SetMatrix(const float64 *); + trpgModelRef(void); + ~trpgModelRef(void); + // Set the model ID. Must come from a trpgModelTable + void SetModel(int); + // Set the 4x4 rotate/translate/scale matrix + void SetMatrix(const float64 *); - // Model ID pointing into a trpgModelTable - bool GetModel(int32 &) const; - // Positional matrix. Works just like a trpgTransform. - bool GetMatrix(float64 *) const; + // Model ID pointing into a trpgModelTable + bool GetModel(int32 &) const; + // Positional matrix. Works just like a trpgTransform. + bool GetMatrix(float64 *) const; - // Writes this class to a write buffer - bool Write(trpgWriteBuffer &); - // Reads this class from a read buffer - bool Read(trpgReadBuffer &); - // Prints this class to a print buffer - bool Print(trpgPrintBuffer &) const; + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; - // Resets the contents back to empty - void Reset(void); + // Resets the contents back to empty + void Reset(void); protected: - int modelRef; - float64 m[4][4]; + int modelRef; + float64 m[4][4]; +}; + +/* The Text Styles are used to consolidate attributes related to labels. + It would be inefficient to store the font, for instance, for every + single label, so we do it in the Text Style table. + For the most part, text styles are very simple, consisting of + very basic font and material information. + */ +TX_EXDECL class TX_CLDECL trpgTextStyle : public trpgReadWriteable { +public: + trpgTextStyle(void); + ~trpgTextStyle(void); + + bool operator == (const trpgTextStyle&) const; + + // Set the material ID. Should point into trpgMatTable + void SetMaterial(int); + // Get the material ID. Points into trpgMatTable + int GetMaterial(void) const; + + // Set the font description + void SetFont(std::string &); + // Get the font description + const std::string *GetFont(void) const; + + // Set bold to on/off + void SetBold(bool); + // Return value of bold status + bool GetBold(void) const; + + // Set italic on/off + void SetItalic(bool); + // Return value of italic status + bool GetItalic(void) const; + + // Set underline on/off + void SetUnderline(bool); + // Return value of underline status + bool GetUnderline(void) const; + + // Set character size: MUST BE IN METER + void SetCharacterSize(float32); + // Get character (e.g. font) size + float32 GetCharacterSize(void) const; + + // Write this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + + // Reset the contents back to empty + void Reset(void); + + // Return object validity + bool isValid(void) const; +protected: + std::string font; + bool bold,italic,underline; + float32 characterSize; + int matId; +}; + +/* The text style table is just a collection of trpgTextStyle obejcts for the + whole archive. Individual text styles will be indexed by trpgLabelProperty + objects. It is from these that you decide how to display a given label. + */ +TX_EXDECL class TX_CLDECL trpgTextStyleTable : public trpgReadWriteable { +public: + trpgTextStyleTable(void); + ~trpgTextStyleTable(void); + + // Add a single text style + int AddStyle(const trpgTextStyle &); + + int FindAddStyle(const trpgTextStyle &); + + // Figure out how many text styles there are + int GetNumStyle(void) const; + + // Return a reference to the given style + const trpgTextStyle *GetStyleRef(int) const; + + // Validity check + bool isValid(void) const; + // Reset the contents back to empty + void Reset(void); + + // Write this class to a write buffer + bool Write(trpgWriteBuffer &); + // Read this class from a read buffer + bool Read(trpgReadBuffer &); + // Print this class to a print buffer + bool Print(trpgPrintBuffer &) const; + +protected: + std::vector styles; +}; + + + +/* The Support Styles are used to consolidate attributes related to labels. + For the most part, support styles are very simple, consisting of + very basic description of object to use for drawing suport. + */ +TX_EXDECL class TX_CLDECL trpgSupportStyle : public trpgReadWriteable { +public: + trpgSupportStyle(void); + ~trpgSupportStyle(void); + + bool operator == (const trpgSupportStyle&) const; + + typedef enum {Line,Cylinder,MaxSupportType} SupportType; + + // Set the support type. Get GetSupportType() for more information + void SetType(SupportType); + /* Return the support types. Supports are geometry that run from the + bottom middle of the label object to some point in space. + Most likely that point is somewhere on the ground, but not + necessarily. How the support is drawn is controlled both by + the support type and the material ID for the support. + */ + SupportType GetType(void) const; + + // Set the material ID. Should point into trpgMatTable + void SetMaterial(int); + // Get the material ID. Points into trpgMatTable + int GetMaterial(void) const; + + + // Write this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + + // Reset the contents back to empty + void Reset(void); + + // Return object validity + bool isValid(void) const; +protected: + SupportType type; + int matId; +}; + +/* The support style table is just a collection of trpgSupportStyle obejcts for the + whole archive. Individual support styles will be indexed by trpgLabelProperty + objects. It is from these that you decide how to display a given support. + */ +TX_EXDECL class TX_CLDECL trpgSupportStyleTable : public trpgReadWriteable { +public: + trpgSupportStyleTable(void); + ~trpgSupportStyleTable(void); + + // Add a single text style + int AddStyle(const trpgSupportStyle &); + + int FindAddStyle(const trpgSupportStyle &); + + // Figure out how many text styles there are + int GetNumStyle(void) const; + + // Return a reference to the given style + const trpgSupportStyle *GetStyleRef(int) const; + + // Validity check + bool isValid(void) const; + // Reset the contents back to empty + void Reset(void); + + // Write this class to a write buffer + bool Write(trpgWriteBuffer &); + // Read this class from a read buffer + bool Read(trpgReadBuffer &); + // Print this class to a print buffer + bool Print(trpgPrintBuffer &) const; + +protected: + std::vector styles; +}; + + + +/* The Label property are used to consolidate attributes related to labels. + Label properties are very simple, consisting of + basic font style and support properties. + */ +TX_EXDECL class TX_CLDECL trpgLabelProperty : public trpgReadWriteable { +public: + trpgLabelProperty(void); + ~trpgLabelProperty(void); + + typedef enum {VertBillboard,Billboard,Panel,Cube,MaxLabelType} LabelType; + + bool operator == (const trpgLabelProperty&) const; + + // Set the label type. See GetType() for more information. + void SetType(LabelType); + /* Return the label type. This controls the geometry for the label. + Panel labels are simple polygons. Cube labels should display + the text on every side with single sided polygons. + Billboard labels rotate toward the user with no particular axes. + That is, they will always be pointed directly toward the user. + Vertical billboards rotate toward the user, but have an axis along +Z. + */ + LabelType GetType(void) const; + + // Set the font style ID. Should point into trpgTextStyleTable + void SetFontStyle(int); + // Get the font style ID. Points into trpgTextStyleTable + int GetFontStyle(void) const; + + // Set the support style ID. Should point into trpgSupportTable + void SetSupport(int); + // Get the font style ID. Points into trpgSupportTable + int GetSupport(void) const; + + // Write this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + + // Reset the contents back to empty + void Reset(void); + + // Return object validity + bool isValid(void) const; +protected: + int fontId; + int supportId; + LabelType type; +}; + +/* The label property table is just a collection of trpgLabelProperty obejcts for the + whole archive. Individual label property will be indexed by trpgLable + objects. + */ +TX_EXDECL class TX_CLDECL trpgLabelPropertyTable : public trpgReadWriteable { +public: + trpgLabelPropertyTable(void); + ~trpgLabelPropertyTable(void); + + // Add a single label property + int AddProperty(const trpgLabelProperty &); + + // Find or Add a single label property + int FindAddProperty(const trpgLabelProperty& property); + + // Figure out how many properties there are + int GetNumProperty(void) const; + + // Return a reference to the given property + const trpgLabelProperty *GetPropertyRef(int) const; + + // Validity check + bool isValid(void) const; + // Reset the contents back to empty + void Reset(void); + + // Write this class to a write buffer + bool Write(trpgWriteBuffer &); + // Read this class from a read buffer + bool Read(trpgReadBuffer &); + // Print this class to a print buffer + bool Print(trpgPrintBuffer &) const; + +protected: + std::vector properties; +}; + +/* Labels are objects that float above the terrain (usually) and display + some text message to the user. They're primarily used in 3D map sort of + application. In other words, they're not intended to be real world objects. + You would use one if you want to float a message such as "Natural History Museum" + over a specific building in a visual database. + */ +TX_EXDECL class TX_CLDECL trpgLabel : public trpgReadWriteable { +public: + trpgLabel(void); + ~trpgLabel(void); + + bool isValid(void) const; + + + typedef enum {Left,Center,Right,MaxAlignmentType} AlignmentType; + + // Set the label property ID. This is an index into a tprgLabelPropertyTable + void SetProperty(int); + int GetProperty() const; + + + + // Set the text for this label. See GetText() for more information + void SetText(const std::string &); + /* Return the text for this label. The text may contain basic formatting + such as newlines and tabs. Expect to see those as \n and \t respectively. + Eventually, this text might contain HTML formatting, but we do not use + that at present. + Should not be empty. + */ + const std::string *GetText(void) const; + + // Set the text alignment. See GetAlignmentType() for more information. + void SetAlignment(AlignmentType); + /* Return the alignement type. This controls the alignement of the text + with respect to the label geometry. + */ + AlignmentType GetAlignment(void) const; + + // Set the number of spaces between tabs + void SetTab(int); + // Get the number of spaces between tabs + int GetTab(void) const; + + // Set the text scaling value: font size * scale = real world text size in meter + void SetScale(float32); + float32 GetScale() const; + + // Set the text thickness: use to draw 3D text. if thickness = 0, we have + // 2D text only. + void SetThickness(float32); + float32 GetThickness() const; + + // Set the description for this label. Set GetDesc() for more information + void SetDesc(const std::string &); + /* Return the description for this label. Descriptions should contain no + formatting. They are a description of what the label represents and may + appear if a user interacts with the label, but should not be drawn in 3D. + May be empty. + */ + const std::string *GetDesc(void) const; + + // Set the URL for this label. See GetURL() for more information. + void SetURL(const std::string &); + /* Return the URL for this label. The URL would invoke some sort of + web browser if the user of the 3D application clicks on the label. + May be empty. + */ + const std::string *GetURL(void) const; + + // Set the number of spaces between tabs + void SetTabSize(int); + // Get the number of spaces between tabs + int GetTabSize(void) const; + + // Set the location of the label. + void SetLocation(const trpg3dPoint &); + const trpg3dPoint& GetLocation() const; + + // Add a support. See GetSupports() for more information + void AddSupport(const trpg3dPoint &); + /* Return the support array. Supports are linear features that run from + the middle bottom of the label to some set of points in the database. + These will often be on the ground, but need not be. Support display + is controlled by the SupportType and by the Support Material ID. + */ + const std::vector *GetSupports(void) const; + + // Writes this class to a write buffer + bool Write(trpgWriteBuffer &); + // Reads this class from a read buffer + bool Read(trpgReadBuffer &); + // Prints this class to a print buffer + bool Print(trpgPrintBuffer &) const; + + // Resets the contents back to empty + void Reset(void); + +protected: + int propertyId; + std::string text; // Actual label text. May contain formatting + AlignmentType alignment; + int tabSize; + float32 scale; + float32 thickness; + std::string desc; + std::string url; + trpg3dPoint location; + std::vector supports; }; #endif diff --git a/src/osgPlugins/txp/trpage_header.cpp b/src/osgPlugins/txp/trpage_header.cpp index 9382f591b..444775463 100644 --- a/src/osgPlugins/txp/trpage_header.cpp +++ b/src/osgPlugins/txp/trpage_header.cpp @@ -18,22 +18,22 @@ #include /* 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" +#include +#include /* Write Header class - Fill it in and write it out. - */ + Fill it in and write it out. + */ // Constructor trpgHeader::trpgHeader() { - Reset(); + Reset(); } trpgHeader::~trpgHeader() { @@ -42,143 +42,152 @@ 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) + { + strcpy(errMess, "Number of LOD <= 0"); + return false; + } + if (sw.x == ne.x && sw.y == ne.y) + { + strcpy(errMess, "Mbr is invalid"); - return true; + return false; + } + + 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; + + errMess[0] = '\0'; } // 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 || static_cast(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) - return; + if (no < 0 || no >= numLods) + return; - lodRanges[no] = r; + lodRanges[no] = r; } void trpgHeader::SetLodRange(const float64 *r) { - for (int i=0;i(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 (but still in 1.0) - 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 (separate token) +// 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 // Macros we may need #ifndef MIN @@ -33,7 +33,7 @@ #endif // File header Magic Number -#define TRPG_MAGIC 9480372 +#define TRPG_MAGIC 9480372 // Current TerraPage major version #define TRPG_VERSION_MAJOR 2 @@ -42,7 +42,7 @@ // 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; @@ -50,157 +50,188 @@ 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 +#define TRPGMAT_BUMP 408 +// {secret} +#define TRPGMAT_ATTR 409 // {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 +#define TRPGTEXTABLE2 601 // {secret} -#define TRPGTEXTURE 650 +#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 +#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 +#define TRPGLOCALMATERIAL 1004 // {secret} -#define TRPG_TILE_LOCMATLIST 1005 +#define TRPG_TILE_LOCMATLIST 1005 // Lights support added by Nick // {secret} -#define TRPGLIGHTTABLE 1100 +#define TRPGLIGHTTABLE 1100 // {secret} -#define TRPGLIGHTATTR 1150 +#define TRPGLIGHTATTR 1150 // {secret} -#define TRPGLIGHTATTR_BASIC 1151 +#define TRPGLIGHTATTR_BASIC 1151 // {secret} -#define TRPGLIGHTATTR_RASCAL 1152 +#define TRPGLIGHTATTR_RASCAL 1152 // {secret} -#define TRPGLIGHTATTR_CALLIGRAPHIC 1153 +#define TRPGLIGHTATTR_CALLIGRAPHIC 1153 // {secret} -#define TRPGLIGHTATTR_PERFORMER 1154 +#define TRPGLIGHTATTR_PERFORMER 1154 // {secret} -#define TRPGLIGHTATTR_ANIMATION 1155 +#define TRPGLIGHTATTR_ANIMATION 1155 // {secret} -#define TRPGLIGHT 1160 -#define TRPG_LIGHT 1160 +#define TRPGLIGHTATTR_COMMENT 1156 +// {secret} +#define TRPGLIGHT 1160 +// {secret} +#define TRPG_LIGHT 1160 // {secret} -#define TRPGRANGETABLE 1200 +#define TRPGRANGETABLE 1200 // {secret} -#define TRPG_RANGE 1201 +#define TRPG_RANGE 1201 + +// Label and style support added 12-02 +// {secret} +#define TRPG_TEXT_STYLE_TABLE 1300 +// {secret} +#define TRPG_TEXT_STYLE 1301 +// {secret} +#define TRPG_TEXT_STYLE_BASIC 1302 + +// {secret} +#define TRPG_SUPPORT_STYLE_TABLE 1310 +// {secret} +#define TRPG_SUPPORT_STYLE 1311 +// {secret} +#define TRPG_SUPPORT_STYLE_BASIC 1312 + +// {secret} +#define TRPG_LABEL_PROPERTY_TABLE 1320 +// {secret} +#define TRPG_LABEL_PROPERTY 1321 +// {secret} +#define TRPG_LABEL_PROPERTY_BASIC 1322 // {secret} -#define TRPG_GROUP 2001 -// {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_LABEL 1330 + // {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 @@ -212,404 +243,424 @@ 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; }; + bool operator==(const trpg2dPoint& pt ) const { + if ( x != pt.x ) return false; + if ( y != pt.y ) return false; + return true; + }; + bool operator!=(const trpg2dPoint& pt ) const { return !operator==(pt); }; }; /* 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;} - 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); }; + 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 ) const { + 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 ) const { 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) { }; - 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; + 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; -#if (bool != int32) - virtual void Add(bool) = 0; -#endif - virtual void Add(uint8) = 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; +//#endif + virtual void Add(uint8) = 0; #if (trpgDiskRef != int64) - virtual void Add(trpgDiskRef) = 0; + virtual void Add(trpgDiskRef) = 0; #endif - 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; + 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; - // 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 + virtual void Add(const trpg2iPoint &); + virtual void Add(const trpg2dPoint &); + virtual void Add(const trpg3dPoint &); + virtual void Add(const trpgColor &); + virtual void Add(const std::string &); - /* 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); -#if (bool != int32) - // 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 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 *); + // Same as const char * version + virtual void Add(std::string &); + // 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); +//#endif + // 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; - std::vector 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 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 &); -#if (bool != int32) - virtual bool Get(bool &); -#endif - virtual bool Get(uint8 &); + 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(std::string &); + virtual bool Get(float32 &); + virtual bool Get(float64 &); +//#if (bool != int32) + virtual bool Get(bool &); +//#endif + 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); - std::vector 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 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 print method is optional. If it's not there, it won't do anything. - */ - virtual bool Print(trpgPrintBuffer &) const { return true; } + + trpgReadWriteable() { errMess[0] = '\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; } + + const char *getErrMess() const {if(errMess[0] == '\0') return 0;else return &errMess[0];} + protected: + + mutable char errMess[512]; }; /* Pointer into a trpgwAppFile. The full name of the file - is based on the context (e.g. texture vs. tile) - {group:Archive Writing} + 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; + trpgwAppAddress() {file = -1; offset = -1;}; + // 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} + 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(); + 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(); + virtual bool Flush(void); - bool isValid(void) const; + bool isValid(void) const; protected: - bool valid; - trpgEndian ness,cpuNess; - FILE *fp; - int lengthSoFar; + 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. + 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,uint32 dataSize); + trpgrAppFile(trpgEndian,const char *); + virtual ~trpgrAppFile(void); + virtual bool Read(trpgMemReadBuffer *,int32 offset); + virtual bool Read(char *data,int32 baseOffset,int32 objOffset,int32 dataSize); - bool isValid(void) const; + bool isValid(void) const; protected: - bool valid; - trpgEndian ness,cpuNess; - FILE *fp; + bool valid; + trpgEndian ness,cpuNess; + FILE *fp; }; /* Archive File Cache. - This class keeps + 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); + 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]; + // 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 - }; + class OpenFile { + public: + OpenFile(void); + int id; // ID of open file + trpgrAppFile *afile; + int lastUsed; // When the file was last accessed + }; - std::vector files; - int timeCount; // Incremented for every access + std::vector files; + int timeCount; // Incremented for every access }; #endif diff --git a/src/osgPlugins/txp/trpage_label.cpp b/src/osgPlugins/txp/trpage_label.cpp new file mode 100644 index 000000000..8bbf35412 --- /dev/null +++ b/src/osgPlugins/txp/trpage_label.cpp @@ -0,0 +1,978 @@ +/* ************************ + 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 + ************************ + */ + +/* trpage_label.cpp + Methods for the trpgLable object and its associated support structure + including trpgTextStyle and trpgTextStyleTable. + */ + +#include +#include +#include +#include + +#include +#include + +// *************** Text Style implementation + +trpgTextStyle::trpgTextStyle(void) +{ + Reset(); +} + +trpgTextStyle::~trpgTextStyle(void) +{ +} + +void trpgTextStyle::Reset(void) +{ + font = ""; + bold = italic = underline = false; + characterSize = float32(0.0042333333333); // 12 point in meter + matId = -1; +} + +void trpgTextStyle::SetMaterial(int inMatId) +{ + matId = inMatId; +} + +int trpgTextStyle::GetMaterial(void) const +{ + return matId; +} + +void trpgTextStyle::SetFont(std::string &inFont) +{ + font = inFont; +} + +const std::string *trpgTextStyle::GetFont(void) const +{ + return &font; +} + +void trpgTextStyle::SetBold(bool inBold) +{ + bold = inBold; +} + +bool trpgTextStyle::GetBold(void) const +{ + return bold; +} + +void trpgTextStyle::SetItalic(bool inItalic) +{ + italic = inItalic; +} + +bool trpgTextStyle::GetItalic(void) const +{ + return italic; +} + +void trpgTextStyle::SetUnderline(bool inUnder) +{ + underline = inUnder; +} + +bool trpgTextStyle::GetUnderline(void) const +{ + return underline; +} + +void trpgTextStyle::SetCharacterSize(float32 inSize) +{ + characterSize = inSize; +} + +float32 trpgTextStyle::GetCharacterSize(void) const +{ + return characterSize; +} + + +// Write method + +bool trpgTextStyle::Write(trpgWriteBuffer &buf) +{ + buf.Begin(TRPG_TEXT_STYLE); + + buf.Begin(TRPG_TEXT_STYLE_BASIC); + buf.Add(font); + buf.Add(bold); + buf.Add(italic); + buf.Add(underline); + buf.Add(characterSize); + buf.Add(matId); + buf.End(); + + buf.End(); + + return true; +} + +// TextStyle CB +// Used to parse tokens from the text style structure. +// If we do it this way it's easier to expand later. +class textStyleCB : public trpgr_Callback { +public: + void * Parse(trpgToken,trpgReadBuffer &); + trpgTextStyle *style; +}; + +void * textStyleCB::Parse(trpgToken tok,trpgReadBuffer &buf) +{ + std::string sVal; + int iVal; + float32 fVal; + + try { + switch (tok) { + case TRPG_TEXT_STYLE_BASIC: + buf.Get(sVal); + style->SetFont(sVal); + buf.Get(iVal); + style->SetBold((iVal ? true : false)); + buf.Get(iVal); + style->SetItalic((iVal ? true : false)); + buf.Get(iVal); + style->SetUnderline((iVal ? true : false)); + buf.Get(fVal); + style->SetCharacterSize(fVal); + buf.Get(iVal); + style->SetMaterial(iVal); + break; + default: + break; + } + } + catch (...) { + return NULL; + } + + return style; +} + +// Read from a buffer + +bool trpgTextStyle::Read(trpgReadBuffer &buf) +{ + Reset(); + + trpgr_Parser parse; + textStyleCB textStyleCb; + + textStyleCb.style = this; + parse.AddCallback(TRPG_TEXT_STYLE_BASIC,&textStyleCb,false); + parse.Parse(buf); + + return isValid(); +} + +bool trpgTextStyle::isValid(void) const +{ + // Need to have a font designation at least + if (font.size() > 0) + return true; + + return false; +} + + +bool trpgTextStyle::operator == (const trpgTextStyle& in) const +{ + if (font.compare(in.font) != 0) + return false; + + if (bold != in.bold || + italic != in.italic || + underline != in.underline) + return false; + + if(fabs(double(characterSize - in.characterSize)) > 0.0001) + return false; + + + if (matId != in.matId) + return false; + + return true; +} + +// ******************* Text Style Table implementation + +trpgTextStyleTable::trpgTextStyleTable() +{ + Reset(); +} +trpgTextStyleTable::~trpgTextStyleTable() +{ +} + +void trpgTextStyleTable::Reset() +{ + styles.resize(0); +} + +bool trpgTextStyleTable::isValid() const +{ + for (int i=0;i= styles.size()) + return NULL; + + return &styles[id]; +} + +bool trpgTextStyleTable::Write(trpgWriteBuffer &buf) +{ + int i; + if (!isValid()) + return false; + + buf.Begin(TRPG_TEXT_STYLE_TABLE); + + // Number of styles + int numStyle = styles.size(); + buf.Add((int32)numStyle); + + // Write the styles + for (i=0;iSetType(trpgSupportStyle::SupportType(iVal)); + buf.Get(iVal); + style->SetMaterial(iVal); + break; + default: + break; + } + } + catch (...) { + return NULL; + } + + return style; +} + +// Read from a buffer + +bool trpgSupportStyle::Read(trpgReadBuffer &buf) +{ + Reset(); + + trpgr_Parser parse; + supportStyleCB supportStyleCb; + + supportStyleCb.style = this; + parse.AddCallback(TRPG_SUPPORT_STYLE_BASIC,&supportStyleCb,false); + parse.Parse(buf); + + return isValid(); +} + +bool trpgSupportStyle::isValid(void) const +{ + return true; +} + + +bool trpgSupportStyle::operator == (const trpgSupportStyle& in) const +{ + if (type != in.type || matId != in.matId) + return false; + + return true; +} + + +// ******************* Support Style Table implementation + +trpgSupportStyleTable::trpgSupportStyleTable() +{ + Reset(); +} +trpgSupportStyleTable::~trpgSupportStyleTable() +{ +} + +void trpgSupportStyleTable::Reset() +{ + styles.resize(0); +} + +bool trpgSupportStyleTable::isValid() const +{ + for (int i=0;i= styles.size()) + return NULL; + + return &styles[id]; +} + +bool trpgSupportStyleTable::Write(trpgWriteBuffer &buf) +{ + int i; + if (!isValid()) + return false; + + buf.Begin(TRPG_SUPPORT_STYLE_TABLE); + + // Number of styles + int numStyle = styles.size(); + buf.Add((int32)numStyle); + + // Write the styles + for (i=0;iSetFontStyle(iVal); + buf.Get(iVal); + property->SetSupport(iVal); + buf.Get(ival); + property->SetType(trpgLabelProperty::LabelType(ival)); + break; + default: + break; + } + } + catch (...) { + return NULL; + } + + return property; +} + +// Read from a buffer + +bool trpgLabelProperty::Read(trpgReadBuffer &buf) +{ + Reset(); + + trpgr_Parser parse; + labelPropertyCB labelPropertyCb; + + labelPropertyCb.property = this; + parse.AddCallback(TRPG_LABEL_PROPERTY_BASIC,&labelPropertyCb,false); + parse.Parse(buf); + + return isValid(); +} + +bool trpgLabelProperty::isValid(void) const +{ + return supportId != -1 && fontId != -1 && type >=0 && type < MaxLabelType; +} + + +bool trpgLabelProperty::operator == (const trpgLabelProperty& in)const +{ + if (fontId != in.fontId || supportId != in.supportId || type != in.type) + return false; + + return true; +} + +// ******************* Label Property Table implementation + +trpgLabelPropertyTable::trpgLabelPropertyTable() +{ + Reset(); +} +trpgLabelPropertyTable::~trpgLabelPropertyTable() +{ +} + +void trpgLabelPropertyTable::Reset() +{ + properties.resize(0); +} + +bool trpgLabelPropertyTable::isValid() const +{ + for (int i=0;i= properties.size()) + return NULL; + + return &properties[id]; +} + +bool trpgLabelPropertyTable::Write(trpgWriteBuffer &buf) +{ + int i; + if (!isValid()) + return false; + + buf.Begin(TRPG_LABEL_PROPERTY_TABLE); + + // Number of styles + int numProperty = properties.size(); + buf.Add((int32)numProperty); + + // Write the properties + for (i=0;i *trpgLabel::GetSupports() const +{ + return &supports; +} + +bool trpgLabel::Write(trpgWriteBuffer &buf) +{ + int i; + + buf.Begin(TRPG_LABEL); + buf.Add(propertyId); + buf.Add(text); + buf.Add(alignment); + buf.Add(tabSize); + buf.Add(scale); + buf.Add(thickness); + buf.Add(desc); + buf.Add(url); + buf.Add(location); + buf.Add((int)supports.size()); + for (i=0;i #include #include -#include "trpage_geom.h" -#include "trpage_read.h" +#include +#include #if defined(_WIN32) #define ALIGNMENT_WORKAROUND false @@ -34,940 +34,991 @@ #endif /****** - Lights Attribute + Lights Attribute ******/ trpgLightAttr::trpgLightAttr(void) { - Reset(); + data.commentStr = NULL; + Reset(); } -trpgLightAttr::trpgLightAttr(const trpgLightAttr &in):trpgReadWriteable() +trpgLightAttr::trpgLightAttr(const trpgLightAttr &in) { - operator=(in); + data.commentStr = NULL; + operator=(in); } trpgLightAttr::~trpgLightAttr(void) { + if (data.commentStr) + delete [] data.commentStr; + data.commentStr = NULL; } // Setters void trpgLightAttr::SetType( trpgLightAttr::LightType in_type ) { - data.type = in_type; + data.type = in_type; } void trpgLightAttr::SetDirectionality( trpgLightAttr::LightDirectionality in_directionality ) { - data.directionality = in_directionality; + data.directionality = in_directionality; } void trpgLightAttr::SetFrontColor( trpgColor in_frontColor ) { - data.frontColor = in_frontColor; + data.frontColor = in_frontColor; } void trpgLightAttr::SetFrontIntensity( float64 in_frontIntensity ) { - data.frontIntensity = in_frontIntensity; + data.frontIntensity = in_frontIntensity; } void trpgLightAttr::SetBackColor( trpgColor in_backColor ) { - data.backColor = in_backColor; + data.backColor = in_backColor; } void trpgLightAttr::SetBackIntensity( float64 in_backIntensity ) { - data.backIntensity = in_backIntensity; + data.backIntensity = in_backIntensity; } void trpgLightAttr::SetNormal( trpg3dPoint in_normal ) { - data.normal = in_normal; + data.normal = in_normal; } void trpgLightAttr::SetSMC( int32 in_smc ) { - data.smc = in_smc; + data.smc = in_smc; } void trpgLightAttr::SetFID( int32 in_fid ) { - data.fid = in_fid; + data.fid = in_fid; } void trpgLightAttr::SetFlags( int32 in_flags ) { - data.flags = in_flags; + data.flags = in_flags; } void trpgLightAttr::SetHLobeAngle( float64 in_hLobeAngle ) { - data.horizontalLobeAngle = in_hLobeAngle; + data.horizontalLobeAngle = in_hLobeAngle; } void trpgLightAttr::SetVLobeAngle( float64 in_vLobeAngle ) { - data.verticalLobeAngle = in_vLobeAngle; + data.verticalLobeAngle = in_vLobeAngle; } void trpgLightAttr::SetLobeRollAngle( float64 in_lobeRollAngle ) { - data.lobeRollAngle = in_lobeRollAngle; + data.lobeRollAngle = in_lobeRollAngle; } void trpgLightAttr::SetLobeFalloff( float64 in_lobeFalloff ) { - data.lobeFalloff = in_lobeFalloff; + data.lobeFalloff = in_lobeFalloff; } void trpgLightAttr::SetAmbient( float64 in_ambientIntensity ) { - data.ambientIntensity = in_ambientIntensity; + data.ambientIntensity = in_ambientIntensity; } void trpgLightAttr::SetQuality( trpgLightAttr::LightQuality in_quality ) { - data.quality = in_quality; + data.quality = in_quality; } void trpgLightAttr::SetRascalSignificance( float64 in_rascalSignificance ) { - data.rascalSignificance = in_rascalSignificance; + data.rascalSignificance = in_rascalSignificance; } void trpgLightAttr::SetRandomIntensity( trpgLightAttr::LightQuality in_randomIntensity ) { - data.randomIntensity = in_randomIntensity; + data.randomIntensity = in_randomIntensity; } void trpgLightAttr::SetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& in_calligraphicAttr ) { - data.calligraphicAttr = in_calligraphicAttr; + data.calligraphicAttr = in_calligraphicAttr; } void trpgLightAttr::SetCalligraphicDrawOrder( int32 in_drawOrder ) { - data.calligraphicAttr.drawOrder = in_drawOrder; + data.calligraphicAttr.drawOrder = in_drawOrder; } void trpgLightAttr::SetCalligraphicMinDefocus( float64 in_minDefocus ) { - data.calligraphicAttr.minDefocus = in_minDefocus; + data.calligraphicAttr.minDefocus = in_minDefocus; } void trpgLightAttr::SetCalligraphicMaxDefocus( float64 in_maxDefocus ) { - data.calligraphicAttr.maxDefocus = in_maxDefocus; + data.calligraphicAttr.maxDefocus = in_maxDefocus; } void trpgLightAttr::SetPerformerAttr( trpgLightAttr::PerformerAttr& in_performerAttr ) { - data.performerAttr = in_performerAttr; + data.performerAttr = in_performerAttr; } void trpgLightAttr::SetPerformerFlags( int32 in_flags ) { - data.performerAttr.flags = in_flags & trpgLightAttr::trpg_PerformerMask; - data.flags |= data.performerAttr.flags; + data.performerAttr.flags = in_flags & trpgLightAttr::trpg_PerformerMask; + data.flags |= data.performerAttr.flags; } void trpgLightAttr::SetPerformerMinPixelSize( float64 in_minPxSize ) { - data.performerAttr.minPixelSize = in_minPxSize; + data.performerAttr.minPixelSize = in_minPxSize; } void trpgLightAttr::SetPerformerMaxPixelSize( float64 in_maxPxSize ) { - data.performerAttr.maxPixelSize = in_maxPxSize; + data.performerAttr.maxPixelSize = in_maxPxSize; } void trpgLightAttr::SetPerformerActualSize( float64 in_actualSize ) { - data.performerAttr.actualSize = in_actualSize; + data.performerAttr.actualSize = in_actualSize; } void trpgLightAttr::SetPerformerTpPixelSize( float64 in_tpPixelSize ) { - data.performerAttr.transparentPixelSize = in_tpPixelSize; + data.performerAttr.transparentPixelSize = in_tpPixelSize; } void trpgLightAttr::SetPerformerTpFalloffExp( float64 in_tpFalloffExp ) { - data.performerAttr.transparentFallofExp = in_tpFalloffExp; + data.performerAttr.transparentFallofExp = in_tpFalloffExp; } void trpgLightAttr::SetPerformerTpScale( float64 in_tpScale ) { - data.performerAttr.transparentScale = in_tpScale; + data.performerAttr.transparentScale = in_tpScale; } void trpgLightAttr::SetPerformerTpClamp( float64 in_tpClamp ) { - data.performerAttr.transparentClamp = in_tpClamp; + data.performerAttr.transparentClamp = in_tpClamp; } void trpgLightAttr::SetPerformerFogScale( float64 in_fogScale ) { - data.performerAttr.fogScale = in_fogScale; + data.performerAttr.fogScale = in_fogScale; } void trpgLightAttr::SetAnimationAttr( trpgLightAttr::AnimationAttr& in_animationAttr ) { - data.animationAttr = in_animationAttr; + data.animationAttr = in_animationAttr; } void trpgLightAttr::SetAnimationPeriod( float64 in_period ) { - data.animationAttr.period = in_period; + data.animationAttr.period = in_period; } void trpgLightAttr::SetAnimationPhaseDelay( float64 in_phaseDelay ) { - data.animationAttr.phaseDelay = in_phaseDelay; + data.animationAttr.phaseDelay = in_phaseDelay; } void trpgLightAttr::SetAnimationTimeOn( float64 in_timeOn ) { - data.animationAttr.timeOn = in_timeOn; + data.animationAttr.timeOn = in_timeOn; } void trpgLightAttr::SetAnimationVector( trpg3dPoint in_vector ) { - data.animationAttr.vector = in_vector; + data.animationAttr.vector = in_vector; } void trpgLightAttr::SetAnimationFlags( int32 flags ) { - data.animationAttr.flags = flags & trpgLightAttr::trpg_AnimationMask; - data.flags |= data.animationAttr.flags; + data.animationAttr.flags = flags & trpgLightAttr::trpg_AnimationMask; + data.flags |= data.animationAttr.flags; +} +void trpgLightAttr::SetComment(const char *inStr) +{ + if (!inStr) + return; + + if (data.commentStr) + delete [] data.commentStr; + data.commentStr = new char[strlen(inStr)+1]; + strcpy(data.commentStr,inStr); } // Getters void trpgLightAttr::GetType( trpgLightAttr::LightType& out_type ) { - out_type = data.type; + out_type = data.type; } void trpgLightAttr::GetDirectionality( trpgLightAttr::LightDirectionality& out_directionality ) { - out_directionality = data.directionality; + out_directionality = data.directionality; } void trpgLightAttr::GetFrontColor( trpgColor& out_frontColor ) { - out_frontColor = data.frontColor; + out_frontColor = data.frontColor; } void trpgLightAttr::GetFrontIntensity( float64& out_frontIntensity ) { - out_frontIntensity = data.frontIntensity; + out_frontIntensity = data.frontIntensity; } void trpgLightAttr::GetBackColor( trpgColor& out_backColor ) { - out_backColor = data.backColor; + out_backColor = data.backColor; } void trpgLightAttr::GetBackIntensity( float64& out_backIntensity ) { - out_backIntensity = data.backIntensity; + out_backIntensity = data.backIntensity; } void trpgLightAttr::GetNormal( trpg3dPoint& out_normal ) { - out_normal = data.normal; + out_normal = data.normal; } void trpgLightAttr::GetSMC( int32& out_smc ) { - out_smc = data.smc; + out_smc = data.smc; } void trpgLightAttr::GetFID( int32& out_fid ) { - out_fid = data.fid; + out_fid = data.fid; } void trpgLightAttr::GetFlags( int32& out_flags ) { - out_flags = data.flags; + out_flags = data.flags; } void trpgLightAttr::GetHLobeAngle( float64& out_hLobeAngle ) { - out_hLobeAngle = data.horizontalLobeAngle; + out_hLobeAngle = data.horizontalLobeAngle; } void trpgLightAttr::GetVLobeAngle( float64& out_vLobeAngle ) { - out_vLobeAngle = data.verticalLobeAngle; + out_vLobeAngle = data.verticalLobeAngle; } void trpgLightAttr::GetLobeRollAngle( float64& out_lobeRollAngle ) { - out_lobeRollAngle = data.lobeRollAngle; + out_lobeRollAngle = data.lobeRollAngle; } void trpgLightAttr::GetLobeFalloff( float64& out_lobeFalloff ) { - out_lobeFalloff = data.lobeFalloff; + out_lobeFalloff = data.lobeFalloff; } void trpgLightAttr::GetAmbient( float64& out_ambientIntensity ) { - out_ambientIntensity = data.ambientIntensity; + out_ambientIntensity = data.ambientIntensity; } void trpgLightAttr::GetQuality( trpgLightAttr::LightQuality& out_quality ) { - out_quality = data.quality; + out_quality = data.quality; } void trpgLightAttr::GetRascalSignificance( float64& out_rascalSignificance ) { - out_rascalSignificance = data.rascalSignificance; + out_rascalSignificance = data.rascalSignificance; } void trpgLightAttr::GetRandomIntensity( trpgLightAttr::LightQuality& out_randomIntensity ) { - out_randomIntensity = data.randomIntensity; + out_randomIntensity = data.randomIntensity; } void trpgLightAttr::GetCalligraphicAttr( trpgLightAttr::CalligraphicAttr& out_calligraphicAttr ) { - out_calligraphicAttr = data.calligraphicAttr; + out_calligraphicAttr = data.calligraphicAttr; } void trpgLightAttr::GetCalligraphicDrawOrder( int32& out_drawOrder ) { - out_drawOrder = data.calligraphicAttr.drawOrder; + out_drawOrder = data.calligraphicAttr.drawOrder; } void trpgLightAttr::GetCalligraphicMinDefocus( float64& out_minDefocus ) { - out_minDefocus = data.calligraphicAttr.minDefocus; + out_minDefocus = data.calligraphicAttr.minDefocus; } void trpgLightAttr::GetCalligraphicMaxDefocus( float64& out_maxDefocus ) { - out_maxDefocus = data.calligraphicAttr.maxDefocus; + out_maxDefocus = data.calligraphicAttr.maxDefocus; } void trpgLightAttr::GetPerformerAttr( trpgLightAttr::PerformerAttr& out_performerAttr ) { - out_performerAttr = data.performerAttr; + out_performerAttr = data.performerAttr; } void trpgLightAttr::GetPerformerFlags( int32& out_flags ) { - out_flags = data.performerAttr.flags; + out_flags = data.performerAttr.flags; } void trpgLightAttr::GetPerformerMinPixelSize( float64& out_minPxSize ) { - out_minPxSize = data.performerAttr.minPixelSize; + out_minPxSize = data.performerAttr.minPixelSize; } void trpgLightAttr::GetPerformerMaxPixelSize( float64& out_maxPxSize ) { - out_maxPxSize = data.performerAttr.maxPixelSize; + out_maxPxSize = data.performerAttr.maxPixelSize; } void trpgLightAttr::GetPerformerActualSize( float64& out_actualSize ) { - out_actualSize = data.performerAttr.actualSize; + out_actualSize = data.performerAttr.actualSize; } void trpgLightAttr::GetPerformerTpPixelSize( float64& out_tpPixelSize ) { - out_tpPixelSize = data.performerAttr.transparentPixelSize; + out_tpPixelSize = data.performerAttr.transparentPixelSize; } void trpgLightAttr::GetPerformerTpFalloffExp( float64& out_tpFalloffExp ) { - out_tpFalloffExp = data.performerAttr.transparentFallofExp; + out_tpFalloffExp = data.performerAttr.transparentFallofExp; } void trpgLightAttr::GetPerformerTpScale( float64& out_tpScale ) { - out_tpScale = data.performerAttr.transparentScale; + out_tpScale = data.performerAttr.transparentScale; } void trpgLightAttr::GetPerformerTpClamp( float64& out_tpClamp ) { - out_tpClamp = data.performerAttr.transparentClamp; + out_tpClamp = data.performerAttr.transparentClamp; } void trpgLightAttr::GetPerformerFogScale( float64& out_fogScale ) { - out_fogScale = data.performerAttr.fogScale; + out_fogScale = data.performerAttr.fogScale; } void trpgLightAttr::GetAnimationAttr( trpgLightAttr::AnimationAttr& out_animationAttr ) { - out_animationAttr = data.animationAttr; + out_animationAttr = data.animationAttr; } void trpgLightAttr::GetAnimationPeriod( float64& out_period ) { - out_period = data.animationAttr.period; + out_period = data.animationAttr.period; } void trpgLightAttr::GetAnimationPhaseDelay( float64& out_phaseDelay ) { - out_phaseDelay = data.animationAttr.phaseDelay; + out_phaseDelay = data.animationAttr.phaseDelay; } void trpgLightAttr::GetAnimationTimeOn( float64& out_timeOn ) { - out_timeOn = data.animationAttr.timeOn; + out_timeOn = data.animationAttr.timeOn; } void trpgLightAttr::GetAnimationVector( trpg3dPoint& out_vector ) { - out_vector = data.animationAttr.vector; + out_vector = data.animationAttr.vector; } void trpgLightAttr::GetAnimationFlags( int32& flags ) { - flags = data.animationAttr.flags; + flags = data.animationAttr.flags; +} +const char *trpgLightAttr::GetComment() +{ + return data.commentStr; } // Writes this class to a write buffer bool trpgLightAttr::Write(trpgWriteBuffer &buf) { - buf.Begin(TRPGLIGHTATTR); + buf.Begin(TRPGLIGHTATTR); - buf.Begin(TRPGLIGHTATTR_BASIC); - buf.Add((int)data.type); - buf.Add((int)data.directionality); - buf.Add(data.frontColor); - buf.Add(data.frontIntensity); - buf.Add(data.backColor); - buf.Add(data.backIntensity); - buf.Add(data.normal); - buf.Add(data.smc); - buf.Add(data.fid); - buf.Add(data.flags); - buf.Add(data.horizontalLobeAngle); - buf.Add(data.verticalLobeAngle); - buf.Add(data.lobeRollAngle); - buf.Add(data.lobeFalloff); - buf.Add(data.ambientIntensity); - buf.Add((int)data.quality); - buf.Add((int)data.randomIntensity); - buf.End(); + buf.Begin(TRPGLIGHTATTR_BASIC); + buf.Add((int)data.type); + buf.Add((int)data.directionality); + buf.Add(data.frontColor); + buf.Add(data.frontIntensity); + buf.Add(data.backColor); + buf.Add(data.backIntensity); + buf.Add(data.normal); + buf.Add(data.smc); + buf.Add(data.fid); + buf.Add(data.flags); + buf.Add(data.horizontalLobeAngle); + buf.Add(data.verticalLobeAngle); + buf.Add(data.lobeRollAngle); + buf.Add(data.lobeFalloff); + buf.Add(data.ambientIntensity); + buf.Add((int)data.quality); + buf.Add((int)data.randomIntensity); + buf.End(); - buf.Begin(TRPGLIGHTATTR_RASCAL); - buf.Add(data.rascalSignificance); - buf.End(); + buf.Begin(TRPGLIGHTATTR_RASCAL); + buf.Add(data.rascalSignificance); + buf.End(); - buf.Begin(TRPGLIGHTATTR_CALLIGRAPHIC); - buf.Add(data.calligraphicAttr.drawOrder); - buf.Add(data.calligraphicAttr.minDefocus); - buf.Add(data.calligraphicAttr.maxDefocus); - buf.End(); + buf.Begin(TRPGLIGHTATTR_CALLIGRAPHIC); + buf.Add(data.calligraphicAttr.drawOrder); + buf.Add(data.calligraphicAttr.minDefocus); + buf.Add(data.calligraphicAttr.maxDefocus); + buf.End(); - buf.Begin(TRPGLIGHTATTR_PERFORMER); - buf.Add(data.performerAttr.actualSize); - buf.Add(data.performerAttr.fogScale); - buf.Add(data.performerAttr.minPixelSize); - buf.Add(data.performerAttr.maxPixelSize); - buf.Add(data.performerAttr.transparentClamp); - buf.Add(data.performerAttr.transparentFallofExp); - buf.Add(data.performerAttr.transparentPixelSize); - buf.Add(data.performerAttr.transparentScale); - buf.End(); + buf.Begin(TRPGLIGHTATTR_PERFORMER); + buf.Add(data.performerAttr.actualSize); + buf.Add(data.performerAttr.fogScale); + buf.Add(data.performerAttr.minPixelSize); + buf.Add(data.performerAttr.maxPixelSize); + buf.Add(data.performerAttr.transparentClamp); + buf.Add(data.performerAttr.transparentFallofExp); + buf.Add(data.performerAttr.transparentPixelSize); + buf.Add(data.performerAttr.transparentScale); + buf.End(); - buf.Begin(TRPGLIGHTATTR_ANIMATION); - buf.Add(data.animationAttr.period); - buf.Add(data.animationAttr.phaseDelay); - buf.Add(data.animationAttr.timeOn); - buf.Add(data.animationAttr.vector); - buf.End(); + buf.Begin(TRPGLIGHTATTR_ANIMATION); + buf.Add(data.animationAttr.period); + buf.Add(data.animationAttr.phaseDelay); + buf.Add(data.animationAttr.timeOn); + buf.Add(data.animationAttr.vector); + buf.End(); - buf.End(); + if (data.commentStr) { + buf.Begin(TRPGLIGHTATTR_COMMENT); + buf.Add(data.commentStr); + buf.End(); + } - return true; + buf.End(); + + return true; } /* LightAttr CB - Used to parse tokens for a light attribute. - */ + Used to parse tokens for a light attribute. + */ class lightAttrCB : public trpgr_Callback { public: - void * Parse(trpgToken,trpgReadBuffer &); - trpgLightAttr *lightAttr; + void * Parse(trpgToken,trpgReadBuffer &); + trpgLightAttr *lightAttr; }; void * lightAttrCB::Parse(trpgToken tok,trpgReadBuffer &buf) { - int type_data; - int directionality_data; - trpgColor color_data;; - float64 float64_data; - trpg3dPoint point_data;; - int32 int32_data; - int quality_data; + int type_data; + int directionality_data; + trpgColor color_data;; + float64 float64_data; + trpg3dPoint point_data;; + int32 int32_data; + int quality_data; + char commentStr[1024]; - try { - switch (tok) { - case TRPGLIGHTATTR_BASIC: - buf.Get(type_data); - lightAttr->SetType((trpgLightAttr::LightType)type_data); - buf.Get(directionality_data); - lightAttr->SetDirectionality((trpgLightAttr::LightDirectionality)directionality_data); - buf.Get(color_data); - lightAttr->SetFrontColor(color_data); - buf.Get(float64_data); - lightAttr->SetFrontIntensity(float64_data); - buf.Get(color_data); - lightAttr->SetBackColor(color_data); - buf.Get(float64_data); - lightAttr->SetBackIntensity(float64_data); - buf.Get(point_data); - lightAttr->SetNormal(point_data); - buf.Get(int32_data); - lightAttr->SetSMC(int32_data); - buf.Get(int32_data); - lightAttr->SetFID(int32_data); - buf.Get(int32_data); - lightAttr->SetFlags(int32_data); - lightAttr->SetPerformerFlags(int32_data); - lightAttr->SetAnimationFlags(int32_data); - buf.Get(float64_data); - lightAttr->SetHLobeAngle(float64_data); - buf.Get(float64_data); - lightAttr->SetVLobeAngle(float64_data); - buf.Get(float64_data); - lightAttr->SetLobeRollAngle(float64_data); - buf.Get(float64_data); - lightAttr->SetLobeFalloff(float64_data); - buf.Get(float64_data); - lightAttr->SetAmbient(float64_data); - buf.Get(quality_data); - lightAttr->SetQuality((trpgLightAttr::LightQuality)quality_data); - buf.Get(quality_data); - lightAttr->SetRandomIntensity((trpgLightAttr::LightQuality)quality_data); - break; - case TRPGLIGHTATTR_RASCAL: - buf.Get(float64_data); - lightAttr->SetRascalSignificance(float64_data); - break; - case TRPGLIGHTATTR_PERFORMER: - buf.Get(float64_data); - lightAttr->SetPerformerActualSize(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerFogScale(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerMinPixelSize(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerMaxPixelSize(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerTpClamp(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerTpFalloffExp(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerTpPixelSize(float64_data); - buf.Get(float64_data); - lightAttr->SetPerformerTpScale(float64_data); - break; - case TRPGLIGHTATTR_CALLIGRAPHIC: - buf.Get(int32_data); - lightAttr->SetCalligraphicDrawOrder(int32_data); - buf.Get(float64_data); - lightAttr->SetCalligraphicMinDefocus(float64_data); - buf.Get(float64_data); - lightAttr->SetCalligraphicMaxDefocus(float64_data); - break; - case TRPGLIGHTATTR_ANIMATION: - buf.Get(float64_data); - lightAttr->SetAnimationPeriod(float64_data); - buf.Get(float64_data); - lightAttr->SetAnimationPhaseDelay(float64_data); - buf.Get(float64_data); - lightAttr->SetAnimationTimeOn(float64_data); - buf.Get(point_data); - lightAttr->SetAnimationVector(point_data); - break; - default: - break; - } - } - catch (...) { - return NULL; - } + try { + switch (tok) { + case TRPGLIGHTATTR_BASIC: + buf.Get(type_data); + lightAttr->SetType((trpgLightAttr::LightType)type_data); + buf.Get(directionality_data); + lightAttr->SetDirectionality((trpgLightAttr::LightDirectionality)directionality_data); + buf.Get(color_data); + lightAttr->SetFrontColor(color_data); + buf.Get(float64_data); + lightAttr->SetFrontIntensity(float64_data); + buf.Get(color_data); + lightAttr->SetBackColor(color_data); + buf.Get(float64_data); + lightAttr->SetBackIntensity(float64_data); + buf.Get(point_data); + lightAttr->SetNormal(point_data); + buf.Get(int32_data); + lightAttr->SetSMC(int32_data); + buf.Get(int32_data); + lightAttr->SetFID(int32_data); + buf.Get(int32_data); + lightAttr->SetFlags(int32_data); + lightAttr->SetPerformerFlags(int32_data); + lightAttr->SetAnimationFlags(int32_data); + buf.Get(float64_data); + lightAttr->SetHLobeAngle(float64_data); + buf.Get(float64_data); + lightAttr->SetVLobeAngle(float64_data); + buf.Get(float64_data); + lightAttr->SetLobeRollAngle(float64_data); + buf.Get(float64_data); + lightAttr->SetLobeFalloff(float64_data); + buf.Get(float64_data); + lightAttr->SetAmbient(float64_data); + buf.Get(quality_data); + lightAttr->SetQuality((trpgLightAttr::LightQuality)quality_data); + buf.Get(quality_data); + lightAttr->SetRandomIntensity((trpgLightAttr::LightQuality)quality_data); + break; + case TRPGLIGHTATTR_RASCAL: + buf.Get(float64_data); + lightAttr->SetRascalSignificance(float64_data); + break; + case TRPGLIGHTATTR_PERFORMER: + buf.Get(float64_data); + lightAttr->SetPerformerActualSize(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerFogScale(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerMinPixelSize(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerMaxPixelSize(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerTpClamp(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerTpFalloffExp(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerTpPixelSize(float64_data); + buf.Get(float64_data); + lightAttr->SetPerformerTpScale(float64_data); + break; + case TRPGLIGHTATTR_CALLIGRAPHIC: + buf.Get(int32_data); + lightAttr->SetCalligraphicDrawOrder(int32_data); + buf.Get(float64_data); + lightAttr->SetCalligraphicMinDefocus(float64_data); + buf.Get(float64_data); + lightAttr->SetCalligraphicMaxDefocus(float64_data); + break; + case TRPGLIGHTATTR_ANIMATION: + buf.Get(float64_data); + lightAttr->SetAnimationPeriod(float64_data); + buf.Get(float64_data); + lightAttr->SetAnimationPhaseDelay(float64_data); + buf.Get(float64_data); + lightAttr->SetAnimationTimeOn(float64_data); + buf.Get(point_data); + lightAttr->SetAnimationVector(point_data); + break; + case TRPGLIGHTATTR_COMMENT: + buf.Get(commentStr,1024); + lightAttr->SetComment(commentStr); + break; + default: + break; + } + } + catch (...) { + return NULL; + } - return lightAttr; + return lightAttr; } // Reads this class from a read buffer bool trpgLightAttr::Read(trpgReadBuffer &buf) { - Reset(); + Reset(); - trpgr_Parser parse; - lightAttrCB lightAttrCb; + trpgr_Parser parse; + lightAttrCB lightAttrCb; - // Light attribute is just a bunch of unordered tokens. - // Interface to it with a generic parser - lightAttrCb.lightAttr = this; - parse.AddCallback(TRPGLIGHTATTR_BASIC,&lightAttrCb,false); - parse.AddCallback(TRPGLIGHTATTR_PERFORMER,&lightAttrCb,false); - parse.AddCallback(TRPGLIGHTATTR_RASCAL,&lightAttrCb,false); - parse.AddCallback(TRPGLIGHTATTR_CALLIGRAPHIC,&lightAttrCb,false); - parse.AddCallback(TRPGLIGHTATTR_ANIMATION,&lightAttrCb,false); - parse.Parse(buf); + // Light attribute is just a bunch of unordered tokens. + // Interface to it with a generic parser + lightAttrCb.lightAttr = this; + parse.AddCallback(TRPGLIGHTATTR_BASIC,&lightAttrCb,false); + parse.AddCallback(TRPGLIGHTATTR_PERFORMER,&lightAttrCb,false); + parse.AddCallback(TRPGLIGHTATTR_RASCAL,&lightAttrCb,false); + parse.AddCallback(TRPGLIGHTATTR_CALLIGRAPHIC,&lightAttrCb,false); + parse.AddCallback(TRPGLIGHTATTR_ANIMATION,&lightAttrCb,false); + parse.AddCallback(TRPGLIGHTATTR_COMMENT,&lightAttrCb,false); + parse.Parse(buf); - return isValid(); + return isValid(); } bool trpgLightAttr::isValid(void) const { - return true; + return true; } trpgLightAttr& trpgLightAttr::operator = (const trpgLightAttr& in) { - data = in.data; - return *this; + data = in.data; + if (in.data.commentStr) { + data.commentStr = new char[strlen(in.data.commentStr)+1]; + strcpy(data.commentStr,in.data.commentStr); + } + return *this; } bool trpgLightAttr::operator == (const trpgLightAttr& in) { - // this doesn't work, so do it a hard way - // return memcmp( &data,&in.data,sizeof(data) ) == 0; + // this doesn't work, so do it a hard way + // return memcmp( &data,&in.data,sizeof(data) ) == 0; - if ( data.type != in.data.type ) - return false; - if ( data.directionality != in.data.directionality ) - return false; - if ( data.frontColor != in.data.frontColor ) - return false; - if ( data.frontIntensity != in.data.frontIntensity ) - return false; - if ( data.backColor != in.data.backColor ) - return false; - if ( data.backIntensity != in.data.backIntensity ) - return false; - if ( data.normal != in.data.normal ) - return false; - if ( data.smc != in.data.smc ) - return false; - if ( data.fid != in.data.fid ) - return false; - if ( data.flags != in.data.flags ) - return false; - if ( data.horizontalLobeAngle != in.data.horizontalLobeAngle ) - return false; - if ( data.verticalLobeAngle != in.data.verticalLobeAngle ) - return false; - if ( data.lobeRollAngle != in.data.lobeRollAngle ) - return false; - if ( data.lobeFalloff != in.data.lobeFalloff ) - return false; - if ( data.ambientIntensity != in.data.ambientIntensity ) - return false; - if ( data.quality != in.data.quality ) - return false; - if ( data.randomIntensity != in.data.randomIntensity ) - return false; - if ( data.rascalSignificance != in.data.rascalSignificance ) - return false; - if ( data.calligraphicAttr.drawOrder != in.data.calligraphicAttr.drawOrder ) - return false; - if ( data.calligraphicAttr.minDefocus != in.data.calligraphicAttr.minDefocus ) - return false; - if ( data.calligraphicAttr.maxDefocus != in.data.calligraphicAttr.maxDefocus ) - return false; - if ( data.performerAttr.flags != in.data.performerAttr.flags ) - return false; - if ( data.performerAttr.minPixelSize != in.data.performerAttr.minPixelSize ) - return false; - if ( data.performerAttr.maxPixelSize != in.data.performerAttr.maxPixelSize ) - return false; - if ( data.performerAttr.actualSize != in.data.performerAttr.actualSize ) - return false; - if ( data.performerAttr.transparentPixelSize != in.data.performerAttr.transparentPixelSize ) - return false; - if ( data.performerAttr.transparentFallofExp != in.data.performerAttr.transparentFallofExp ) - return false; - if ( data.performerAttr.transparentScale != in.data.performerAttr.transparentScale ) - return false; - if ( data.performerAttr.transparentClamp != in.data.performerAttr.transparentClamp ) - return false; - if ( data.performerAttr.fogScale != in.data.performerAttr.fogScale ) - return false; - if ( data.animationAttr.period != in.data.animationAttr.period ) - return false; - if ( data.animationAttr.phaseDelay != in.data.animationAttr.phaseDelay ) - return false; - if ( data.animationAttr.timeOn != in.data.animationAttr.timeOn ) - return false; - if ( data.animationAttr.vector != in.data.animationAttr.vector ) - return false; - if ( data.animationAttr.flags != in.data.animationAttr.flags ) - return false; + if ( data.type != in.data.type ) + return false; + if ( data.directionality != in.data.directionality ) + return false; + if ( data.frontColor != in.data.frontColor ) + return false; + if ( data.frontIntensity != in.data.frontIntensity ) + return false; + if ( data.backColor != in.data.backColor ) + return false; + if ( data.backIntensity != in.data.backIntensity ) + return false; + if ( data.normal != in.data.normal ) + return false; + if ( data.smc != in.data.smc ) + return false; + if ( data.fid != in.data.fid ) + return false; + if ( data.flags != in.data.flags ) + return false; + if ( data.horizontalLobeAngle != in.data.horizontalLobeAngle ) + return false; + if ( data.verticalLobeAngle != in.data.verticalLobeAngle ) + return false; + if ( data.lobeRollAngle != in.data.lobeRollAngle ) + return false; + if ( data.lobeFalloff != in.data.lobeFalloff ) + return false; + if ( data.ambientIntensity != in.data.ambientIntensity ) + return false; + if ( data.quality != in.data.quality ) + return false; + if ( data.randomIntensity != in.data.randomIntensity ) + return false; + if ( data.rascalSignificance != in.data.rascalSignificance ) + return false; + if ( data.calligraphicAttr.drawOrder != in.data.calligraphicAttr.drawOrder ) + return false; + if ( data.calligraphicAttr.minDefocus != in.data.calligraphicAttr.minDefocus ) + return false; + if ( data.calligraphicAttr.maxDefocus != in.data.calligraphicAttr.maxDefocus ) + return false; + if ( data.performerAttr.flags != in.data.performerAttr.flags ) + return false; + if ( data.performerAttr.minPixelSize != in.data.performerAttr.minPixelSize ) + return false; + if ( data.performerAttr.maxPixelSize != in.data.performerAttr.maxPixelSize ) + return false; + if ( data.performerAttr.actualSize != in.data.performerAttr.actualSize ) + return false; + if ( data.performerAttr.transparentPixelSize != in.data.performerAttr.transparentPixelSize ) + return false; + if ( data.performerAttr.transparentFallofExp != in.data.performerAttr.transparentFallofExp ) + return false; + if ( data.performerAttr.transparentScale != in.data.performerAttr.transparentScale ) + return false; + if ( data.performerAttr.transparentClamp != in.data.performerAttr.transparentClamp ) + return false; + if ( data.performerAttr.fogScale != in.data.performerAttr.fogScale ) + return false; + if ( data.animationAttr.period != in.data.animationAttr.period ) + return false; + if ( data.animationAttr.phaseDelay != in.data.animationAttr.phaseDelay ) + return false; + if ( data.animationAttr.timeOn != in.data.animationAttr.timeOn ) + return false; + if ( data.animationAttr.vector != in.data.animationAttr.vector ) + return false; + if ( data.animationAttr.flags != in.data.animationAttr.flags ) + return false; + if ( (data.commentStr && !in.data.commentStr) || + (!data.commentStr && in.data.commentStr)) + return false; + if (data.commentStr && in.data.commentStr && strcmp(data.commentStr,in.data.commentStr)) + return false; - return true; + return true; } bool trpgLightAttr::operator != (const trpgLightAttr& in) { - return !operator==(in); + return !operator==(in); } void trpgLightAttr::Reset(void) { - data.type = trpg_Raster; - data.directionality = trpg_Omnidirectional; - data.frontColor = trpgColor(0,0,0); - data.frontIntensity = 0; - data.backColor = trpgColor(0,0,0); - data.backIntensity = 0; - data.normal = trpg3dPoint(0,0,1); - data.smc = 0; - data.fid = 0; - data.flags = 0; - data.horizontalLobeAngle = 0; - data.verticalLobeAngle = 0; - data.lobeRollAngle = 0; - data.lobeFalloff = 0; - data.ambientIntensity = 0; - data.quality = trpg_Low; - data.randomIntensity = trpg_Low; - data.rascalSignificance = 0; - data.calligraphicAttr.drawOrder = 0; - data.calligraphicAttr.minDefocus = 0; - data.calligraphicAttr.maxDefocus = 0; - data.performerAttr.flags = 0; - data.performerAttr.minPixelSize = 0; - data.performerAttr.maxPixelSize = 0; - data.performerAttr.actualSize = 0; - data.performerAttr.transparentPixelSize = 0; - data.performerAttr.transparentFallofExp = 0; - data.performerAttr.transparentScale = 0; - data.performerAttr.transparentClamp = 0; - data.performerAttr.fogScale = 0; - data.animationAttr.period = 0; - data.animationAttr.phaseDelay = 0; - data.animationAttr.timeOn = 0; - data.animationAttr.vector = trpg3dPoint(0,0,1); - data.animationAttr.flags = 0; + errMess[0] = '\0'; + data.type = trpg_Raster; + data.directionality = trpg_Omnidirectional; + data.frontColor = trpgColor(0,0,0); + data.frontIntensity = 0; + data.backColor = trpgColor(0,0,0); + data.backIntensity = 0; + data.normal = trpg3dPoint(0,0,1); + data.smc = 0; + data.fid = 0; + data.flags = 0; + data.horizontalLobeAngle = 0; + data.verticalLobeAngle = 0; + data.lobeRollAngle = 0; + data.lobeFalloff = 0; + data.ambientIntensity = 0; + data.quality = trpg_Low; + data.randomIntensity = trpg_Low; + data.rascalSignificance = 0; + data.calligraphicAttr.drawOrder = 0; + data.calligraphicAttr.minDefocus = 0; + data.calligraphicAttr.maxDefocus = 0; + data.performerAttr.flags = 0; + data.performerAttr.minPixelSize = 0; + data.performerAttr.maxPixelSize = 0; + data.performerAttr.actualSize = 0; + data.performerAttr.transparentPixelSize = 0; + data.performerAttr.transparentFallofExp = 0; + data.performerAttr.transparentScale = 0; + data.performerAttr.transparentClamp = 0; + data.performerAttr.fogScale = 0; + data.animationAttr.period = 0; + data.animationAttr.phaseDelay = 0; + data.animationAttr.timeOn = 0; + data.animationAttr.vector = trpg3dPoint(0,0,1); + data.animationAttr.flags = 0; + if (data.commentStr) + delete [] data.commentStr; + data.commentStr = NULL; } /************** - Light + Light */ trpgLight::trpgLight(void) { - index = -1; + index = -1; } -trpgLight::trpgLight(const trpgLight &in):trpgReadWriteable() +trpgLight::trpgLight(const trpgLight &in) { - operator=(in); + operator=(in); } trpgLight::~trpgLight(void) { - Reset(); + Reset(); } // Set the index pointing into the Light Table void trpgLight::SetAttrIndex(int ix) { - index = ix; + index = ix; } // Add a new location this light is located at void trpgLight::AddVertex(trpg3dPoint pt) { - lightPoints.push_back(pt); + lightPoints.push_back(pt); } // Returns the number of locations, this light is located at void trpgLight::GetNumVertices(uint32 &nvertices) const { - nvertices = lightPoints.size(); + nvertices = lightPoints.size(); } // Returns the location at a given index bool trpgLight::GetVertex(uint32 ix, trpg3dPoint &pt) const { - if (ix < lightPoints.size() ) { - pt = lightPoints[ix]; - return true; - } - else - return false; + if (ix < lightPoints.size() ) { + pt = lightPoints[ix]; + return true; + } + else + return false; } bool trpgLight::GetVertices(trpg3dPoint *pts) const { - unsigned int i; + int i; - if (!isValid()) return false; + if (!isValid()) return false; - if (lightPoints.size() != 0) - for (i=0;i= static_cast(lightList.size())) return NULL; - return &lightList[id]; + if (id < 0 || id >= lightList.size()) return NULL; + return &lightList[id]; } bool trpgLightTable::Read(trpgReadBuffer &buf) { - int32 numLights; - trpgToken lightTok; - int32 len; + int32 numLights; + trpgToken lightTok; + int32 len; - try { - buf.Get(numLights); - lightList.resize(numLights); - for (int i=0;i #endif @@ -26,6 +25,6 @@ #include #include -#include "trdll.h" +#include TXDUMMY_DLL_MAIN diff --git a/src/osgPlugins/txp/trpage_managers.cpp b/src/osgPlugins/txp/trpage_managers.cpp index 96eec2ca3..e14395636 100644 --- a/src/osgPlugins/txp/trpage_managers.cpp +++ b/src/osgPlugins/txp/trpage_managers.cpp @@ -17,11 +17,11 @@ #include #include -#include "trpage_sys.h" -#include "trpage_geom.h" -#include "trpage_read.h" -#include "trpage_print.h" -#include "trpage_managers.h" +#include +#include +#include +#include +#include /* Managed Tile class. Check the header file for details. @@ -38,7 +38,7 @@ trpgManagedTile::trpgManagedTile() void trpgManagedTile::Reset() { // Null out the local material data - for (int i=0;i *matList; matList = tileHead.GetLocalMaterialList(); - if (id <0 || id >= int(matList->size())) + if (id <0 || id >= matList->size()) return NULL; return &(*matList)[id]; @@ -120,7 +120,7 @@ void *trpgManagedTile::GetLocalData() const bool trpgManagedTile::SetMatData(int id,void *info) { - if (id < 0 || id >= int(localMatData.size())) + if (id < 0 || id >= localMatData.size()) return false; localMatData[id] = info; @@ -130,7 +130,7 @@ bool trpgManagedTile::SetMatData(int id,void *info) void *trpgManagedTile::GetMatData(int id) const { - if (id < 0 || id >= int(localMatData.size())) + if (id < 0 || id >= localMatData.size()) return NULL; return localMatData[id]; @@ -174,19 +174,19 @@ void trpgPageManager::LodPageInfo::Clean() { // Clean up managed tile structures int i; - for (i=0;iPrint(buf); buf.DecreaseIndent(); sprintf(line,"Unloads: (activeUnload = %s)",(activeUnload ? "yes" : "no")); buf.prnLine(line); buf.IncreaseIndent(); - for (i=0;iPrint(buf); buf.DecreaseIndent(); buf.prnLine("Currently loaded:"); buf.IncreaseIndent(); - for (i=0;iPrint(buf); buf.DecreaseIndent(); @@ -538,7 +538,7 @@ bool trpgPageManager::SetLocation(trpg2dPoint &pt) // Call each terrain LOD and let if figure out if something // has changed. bool change = false; - for (int i=0;i *groupIDs = lastTile->GetGroupIDs(); int i; - for (i=0;isize());i++) { + for (i=0;isize();i++) { ManageGroupMap::iterator p = groupMap.find((*groupIDs)[i]); if (p != groupMap.end()) groupMap.erase(p); @@ -648,7 +648,7 @@ bool trpgPageManager::Stop() { bool res=false; int i; - for (i=0;i /* trpage_material.cpp - This source file contains the methods for trpgMatTable, trpgTextureEnv, - trpgMaterial, and trpgTexTable. - You should only modify this code if you want to add data to these classes. - */ + This source file contains the methods for trpgMatTable, trpgTextureEnv, + trpgMaterial, and trpgTexTable. + You should only modify this code if you want to add data to these classes. + */ -#include "trpage_geom.h" -#include "trpage_read.h" +#include +#include /* Write Material Table class - Keeps track of the materials that have been added. - */ + Keeps track of the materials that have been added. + */ // Constructor trpgMatTable::trpgMatTable() { - numTable = numMat = 0; + numTable = numMat = 0; } trpgMatTable::~trpgMatTable() { @@ -42,209 +42,282 @@ trpgMatTable::~trpgMatTable() // Reset function void trpgMatTable::Reset() { - numTable = 0; - numMat = 0; - matTables.resize(0); + numTable = 0; + numMat = 0; + matTables.resize(0); } // Validity check bool trpgMatTable::isValid() const { - if (numTable <= 0 || numMat <= 0) - return false; + if (numTable <= 0 || numMat <= 0) + return false; - for (unsigned int i=0;i=0;tableIter--) { + int lastEntry; + for (lastEntry=0;lastEntry=0;loop--) + matTables[tableIter*no+loop]=matTables[tableIter*numMat+loop]; + } + // reset the others + for (loop=lastEntry;loop= numTable) - return; - if (nm < 0 || nm >= numMat) - return; + if (nt < 0 || nt >= numTable) + return; + if (nm < 0 || nm >= numMat) + return; - matTables[nt*numMat+nm] = mat; + matTables[nt*numMat+nm] = mat; + // ensure that this entry isn't re-used + if (mat.shadeModel>100) matTables[nt*numMat+nm].shadeModel=trpgMaterial::Smooth; } void trpgMatTable::SetMaterial(int nm,const trpgMaterial &mat) { - if (nm < 0 || nm >= numMat) - return; + if (nm < 0 || nm >= numMat) + return; - for (int i=0;i100) matTables[i*numMat+nm].shadeModel=trpgMaterial::Smooth; + } } + #define CEQ(ca,cb) (ca.red == cb.red && ca.green == cb.green && ca.blue == cb.blue) -int trpgMatTable::AddMaterial(const trpgMaterial &mat) + +int trpgMatTable::AddMaterial(const trpgMaterial &mat,bool lookForExisting) { - // Doesn't work if there's more than one table - if (numTable != 1) - return -1; + return AddMaterialInSubtable(mat, 1, lookForExisting); +} - // Look for a matching base material minus the textures - trpgMaterial cmat = mat; - unsigned int baseMat; - for (baseMat = 0;baseMat < matTables.size();baseMat++) { - trpgMaterial &bm = matTables[baseMat]; - // Compare structures - if (CEQ(cmat.color,bm.color) && CEQ(cmat.ambient,bm.ambient) && - CEQ(cmat.diffuse,bm.diffuse) && CEQ(cmat.specular,bm.specular) && - CEQ(cmat.emission,bm.emission) && cmat.shininess == bm.shininess && - cmat.shadeModel == bm.shadeModel && cmat.pointSize == bm.pointSize && - cmat.lineWidth == bm.lineWidth && cmat.cullMode == bm.cullMode && - cmat.alphaFunc == bm.alphaFunc && cmat.alphaRef == bm.alphaRef && - cmat.autoNormal == bm.autoNormal && cmat.texEnvs.size() == bm.texEnvs.size()) { - // Test the texture envs - bool isSame=true; - unsigned int i; - for (i=0;i= matTables.size()) { - matTables.push_back(cmat); - numMat++; - } else - // Found it. Just return this ID. - return baseMat; +int trpgMatTable::AddMaterialInSubtable(const trpgMaterial &mat,int table, bool lookForExisting) +{ + // Doesn't work if there's more than one table + //if (numTable != 1) + // return -1; - return numMat-1; + trpgMaterial cmat = mat; // necessary? + + // having a shadeModel of 999 indicates that the entry is free. I thought this would + // work fine, until I realized that evidently most of the time the shademodel isn't set + // at all. Now my kludge takes so much work it's almost worth doing it right. + + if (cmat.shadeModel>100) cmat.shadeModel=trpgMaterial::Smooth; + int baseMat=numMat; + int offset=(table-1)*numMat+baseMat; + + if (table>numTable) { + // Add another table. But we don't have to shuffle indices or reset entries + SetNumTable(table); + offset=(table-1)*numMat; + matTables[offset] = cmat; + return 0; + } + + bool spaceInTable=false; + if (lookForExisting) { + // Look for a matching base material minus the textures + for (baseMat = 0;baseMat < numMat;baseMat++) { + offset=(table-1)*numMat+baseMat; + + trpgMaterial &bm = matTables[offset]; + if (bm.shadeModel==999) { + // this is an 'empty' entry. Means we won't find it, either. + spaceInTable=true; + break; + } + + // Compare structures + if (CEQ(cmat.color,bm.color) && CEQ(cmat.ambient,bm.ambient) && + CEQ(cmat.diffuse,bm.diffuse) && CEQ(cmat.specular,bm.specular) && + CEQ(cmat.emission,bm.emission) && cmat.shininess == bm.shininess && + cmat.shadeModel == bm.shadeModel && cmat.pointSize == bm.pointSize && + cmat.lineWidth == bm.lineWidth && cmat.cullMode == bm.cullMode && + cmat.alphaFunc == bm.alphaFunc && cmat.alphaRef == bm.alphaRef && + cmat.attrSet.fid == bm.attrSet.fid && cmat.attrSet.smc == bm.attrSet.smc && + cmat.attrSet.stp == bm.attrSet.stp && cmat.attrSet.swc == bm.attrSet.swc && + cmat.autoNormal == bm.autoNormal && cmat.texEnvs.size() == bm.texEnvs.size()) { + // Test the texture envs + bool isSame=true; + int i; + for (i=0;i= numTable || nm < 0 || nm >= numMat) - return false; - mat = matTables[nt*numMat+nm]; - - return true; + if (!isValid()) return false; + if (nt < 0 || nt >= numTable || nm < 0 || nm >= numMat) + return false; + mat = matTables[nt*numMat+nm]; + + return true; } const trpgMaterial *trpgMatTable::GetMaterialRef(int nt,int nm) const { - if (nt < 0 || nt >= numTable || nm < 0 || nm >= numMat) - return false; - return const_cast(&matTables[nt*numMat+nm]); + if (nt < 0 || nt >= numTable || nm < 0 || nm >= numMat) + return false; + return const_cast(&matTables[nt*numMat+nm]); } bool trpgMatTable::Read(trpgReadBuffer &buf) { - trpgMaterial mat; - trpgToken matTok; - int32 len; - bool status; - int i,j; + trpgMaterial mat; + trpgToken matTok; + int32 len; + bool status; + int i,j; - try { - buf.Get(numTable); - buf.Get(numMat); - if (numTable <= 0 || numMat < 0) throw 1; - // Read the materials - matTables.resize(numTable*numMat); - for (i=0;iSetEnvMode(envMode); - break; - case TRPGMAT_TXENV_FILTER: - buf.Get(minFilter); - buf.Get(magFilter); - tenv->SetMinFilter(minFilter); - tenv->SetMagFilter(magFilter); - break; - case TRPGMAT_TXENV_WRAP: - buf.Get(wrapS); - buf.Get(wrapT); - tenv->SetWrap(wrapS,wrapT); - break; - case TRPGMAT_TXENV_BORDER: - buf.Get(borderCol); - tenv->SetBorderColor(borderCol); - break; - default: - // Don't know this token. Skip - break; - } - } - catch (...) { - return NULL; - } + try { + switch (tok) { + case TRPGMAT_TXENV_MODE: + buf.Get(envMode); + tenv->SetEnvMode(envMode); + break; + case TRPGMAT_TXENV_FILTER: + buf.Get(minFilter); + buf.Get(magFilter); + tenv->SetMinFilter(minFilter); + tenv->SetMagFilter(magFilter); + break; + case TRPGMAT_TXENV_WRAP: + buf.Get(wrapS); + buf.Get(wrapT); + tenv->SetWrap(wrapS,wrapT); + break; + case TRPGMAT_TXENV_BORDER: + buf.Get(borderCol); + tenv->SetBorderColor(borderCol); + break; + default: + // Don't know this token. Skip + break; + } + } + catch (...) { + return NULL; + } - return tenv; + return tenv; } bool trpgTextureEnv::Read(trpgReadBuffer &buf) { - trpgr_Parser parse; - textureEnvCB teCb; + trpgr_Parser parse; + textureEnvCB teCb; - // Texture environment is a bunch of tokens in random order - // Interface to it with a parser - teCb.tenv = this; - parse.AddCallback(TRPGMAT_TXENV_MODE,&teCb,false); - parse.AddCallback(TRPGMAT_TXENV_FILTER,&teCb,false); - parse.AddCallback(TRPGMAT_TXENV_WRAP,&teCb,false); - parse.AddCallback(TRPGMAT_TXENV_BORDER,&teCb,false); - parse.Parse(buf); + // Texture environment is a bunch of tokens in random order + // Interface to it with a parser + teCb.tenv = this; + parse.AddCallback(TRPGMAT_TXENV_MODE,&teCb,false); + parse.AddCallback(TRPGMAT_TXENV_FILTER,&teCb,false); + parse.AddCallback(TRPGMAT_TXENV_WRAP,&teCb,false); + parse.AddCallback(TRPGMAT_TXENV_BORDER,&teCb,false); + parse.Parse(buf); - return isValid(); + return isValid(); } /* Write Material class - Material representation. - */ + Material representation. + */ // Constructor trpgMaterial::trpgMaterial() { - Reset(); + Reset(); } trpgMaterial::~trpgMaterial() { @@ -439,579 +512,669 @@ trpgMaterial::~trpgMaterial() // Reset function void trpgMaterial::Reset() { - color = trpgColor(1,1,1); - ambient = trpgColor(0,0,0); - diffuse = trpgColor(1,1,1); - specular = trpgColor(0,0,0); - emission = trpgColor(0,0,0); - shininess = 0; - shadeModel = Smooth; - pointSize = 1; - lineWidth = 1; - cullMode = Back; - alphaFunc = GreaterThan; - alphaRef = 0; - alpha = 1.0; - autoNormal = false; - numTex = 0; - texids.resize(0); - texEnvs.resize(0); - numTile = 0; - isBump = false; + color = trpgColor(1,1,1); + ambient = trpgColor(0,0,0); + diffuse = trpgColor(1,1,1); + specular = trpgColor(0,0,0); + emission = trpgColor(0,0,0); + shininess = 0; + shadeModel = 999; // kludge to identify 'empty' material table entries + pointSize = 1; + lineWidth = 1; + cullMode = Back; + alphaFunc = GreaterThan; + alphaRef = 0; + alpha = 1.0; + autoNormal = false; + numTex = 0; + texids.resize(0); + texEnvs.resize(0); + numTile = 0; + isBump = false; + attrSet.fid = -1; + attrSet.smc = -1; + attrSet.stp = -1; + attrSet.swc = -1; } // Validity check bool trpgMaterial::isValid() const { - // Only thing we really care about is texture - if (numTex < 0) - return false; + // Only thing we really care about is texture + if (numTex < 0) + return false; - for (int i=0;i= texids.size()) - return; + if (no < 0 || (unsigned int)no >= texids.size()) + return; - texids[no] = id; - texEnvs[no] = env; + texids[no] = id; + texEnvs[no] = env; } int trpgMaterial::AddTexture(int id,const trpgTextureEnv &env) { - texids.push_back(id); - texEnvs.push_back(env); - numTex++; + texids.push_back(id); + texEnvs.push_back(env); + numTex++; - return numTex-1; + return numTex-1; } void trpgMaterial::SetNumTiles(int no) { - numTile = no; + numTile = no; } int trpgMaterial::AddTile() { - return(++numTile); + return(++numTile); } void trpgMaterial::SetIsBumpMap(bool val) { isBump = val; } +void trpgMaterial::SetAttr(int attrCode,int val) +{ + switch (attrCode) { + case TR_FID: + attrSet.fid = val; + break; + case TR_SMC: + attrSet.smc = val; + break; + case TR_STP: + attrSet.stp = val; + break; + case TR_SWC: + attrSet.swc = val; + break; + } + + return; +} // Write to buffer bool trpgMaterial::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + if (!isValid()) + return false; - buf.Begin(TRPGMATERIAL); + buf.Begin(TRPGMATERIAL); - // Bundle the basic material parameters together - buf.Begin(TRPGMAT_BASIC); - buf.Add(color); - buf.Add(ambient); - buf.Add(diffuse); - buf.Add(specular); - buf.Add(emission); - buf.Add(shininess); - buf.Add(numTile); - buf.End(); + // Bundle the basic material parameters together + buf.Begin(TRPGMAT_BASIC); + buf.Add(color); + buf.Add(ambient); + buf.Add(diffuse); + buf.Add(specular); + buf.Add(emission); + buf.Add(shininess); + buf.Add(numTile); + buf.End(); - // Most everything else is a single token. - // This is inefficient, but expandable - buf.Begin(TRPGMAT_SHADE); - buf.Add(shadeModel); - buf.End(); + // Most everything else is a single token. + // This is inefficient, but expandable + buf.Begin(TRPGMAT_SHADE); + buf.Add(shadeModel); + buf.End(); - buf.Begin(TRPGMAT_SIZES); - buf.Add(pointSize); - buf.Add(lineWidth); - buf.End(); + buf.Begin(TRPGMAT_SIZES); + buf.Add(pointSize); + buf.Add(lineWidth); + buf.End(); - buf.Begin(TRPGMAT_CULL); - buf.Add(cullMode); - buf.End(); + buf.Begin(TRPGMAT_CULL); + buf.Add(cullMode); + buf.End(); - buf.Begin(TRPGMAT_ALPHA); - buf.Add(alphaFunc); - buf.Add(alphaRef); - buf.Add(alpha); - buf.End(); + buf.Begin(TRPGMAT_ALPHA); + buf.Add(alphaFunc); + buf.Add(alphaRef); + buf.Add(alpha); + buf.End(); - buf.Begin(TRPGMAT_NORMAL); - buf.Add(autoNormal); - buf.End(); + buf.Begin(TRPGMAT_NORMAL); + buf.Add(autoNormal); + buf.End(); - buf.Begin(TRPGMAT_TEXTURE); - buf.Add(numTex); - for (int i=0;i= numTex) - return false; - id = texids[no]; - te = texEnvs[no]; - return true; + if (!isValid() || no < 0 || no >= numTex) + return false; + id = texids[no]; + te = texEnvs[no]; + return true; } bool trpgMaterial::GetNumTile(int &no) const { - if (!isValid()) return false; - no = numTile; - return true; + if (!isValid()) return false; + no = numTile; + return true; } bool trpgMaterial::GetIsBumpMap(bool &ret) const { - if (!isValid()) return false; - ret = isBump; - return true; + if (!isValid()) return false; + ret = isBump; + return true; +} +bool trpgMaterial::GetAttr(int attrCode,int &ret) const +{ + switch (attrCode) { + case TR_FID: + ret = attrSet.fid; + break; + case TR_SMC: + ret = attrSet.smc; + break; + case TR_STP: + ret = attrSet.stp; + break; + case TR_SWC: + ret = attrSet.swc; + break; + default: + return false; + } + + return true; } /* Material CB - Used to parse tokens for a material. - */ + Used to parse tokens for a material. + */ class materialCB : public trpgr_Callback { public: - void * Parse(trpgToken,trpgReadBuffer &); - trpgMaterial *mat; + void * Parse(trpgToken,trpgReadBuffer &); + trpgMaterial *mat; }; void * materialCB::Parse(trpgToken tok,trpgReadBuffer &buf) { - trpgColor color; - float64 shininess; - int shadeModel; - float64 size; - int cullMode; - int alphaFunc; - float64 alphaRef,alpha; - bool autoNormal; - int numTex,texId; - trpgToken envTok; - trpgTextureEnv texEnv; - int32 len,numtile; - bool status; - int i; + trpgColor color; + float64 shininess; + int shadeModel; + float64 size; + int cullMode; + int alphaFunc; + float64 alphaRef,alpha; + bool autoNormal; + int numTex,texId; + trpgToken envTok; + trpgTextureEnv texEnv; + int32 len,numtile; + bool status; + int i; - try { - switch (tok) { - case TRPGMAT_BASIC: - buf.Get(color); - mat->SetColor(color); - buf.Get(color); - mat->SetAmbient(color); - buf.Get(color); - mat->SetDiffuse(color); - buf.Get(color); - mat->SetSpecular(color); - buf.Get(color); - mat->SetEmission(color); - buf.Get(shininess); - mat->SetShininess(shininess); - buf.Get(numtile); - mat->SetNumTiles(numtile); - break; - case TRPGMAT_SHADE: - buf.Get(shadeModel); - mat->SetShadeModel(shadeModel); - break; - case TRPGMAT_SIZES: - buf.Get(size); - mat->SetPointSize(size); - buf.Get(size); - mat->SetLineWidth(size); - break; - case TRPGMAT_CULL: - buf.Get(cullMode); - mat->SetCullMode(cullMode); - break; - case TRPGMAT_ALPHA: - buf.Get(alphaFunc); - buf.Get(alphaRef); - buf.Get(alpha); - mat->SetAlphaFunc(alphaFunc); - mat->SetAlphaRef(alphaRef); - mat->SetAlpha(alpha); - break; - case TRPGMAT_NORMAL: - { - int tmp; - buf.Get(tmp); - if (tmp) - autoNormal = true; - else - autoNormal = false; - mat->SetAutoNormal(autoNormal); - } - break; - case TRPGMAT_TEXTURE: - buf.Get(numTex); - for (i=0;iSetColor(color); + buf.Get(color); + mat->SetAmbient(color); + buf.Get(color); + mat->SetDiffuse(color); + buf.Get(color); + mat->SetSpecular(color); + buf.Get(color); + mat->SetEmission(color); + buf.Get(shininess); + mat->SetShininess(shininess); + buf.Get(numtile); + mat->SetNumTiles(numtile); + break; + case TRPGMAT_SHADE: + buf.Get(shadeModel); + mat->SetShadeModel(shadeModel); + break; + case TRPGMAT_SIZES: + buf.Get(size); + mat->SetPointSize(size); + buf.Get(size); + mat->SetLineWidth(size); + break; + case TRPGMAT_CULL: + buf.Get(cullMode); + mat->SetCullMode(cullMode); + break; + case TRPGMAT_ALPHA: + buf.Get(alphaFunc); + buf.Get(alphaRef); + buf.Get(alpha); + mat->SetAlphaFunc(alphaFunc); + mat->SetAlphaRef(alphaRef); + mat->SetAlpha(alpha); + break; + case TRPGMAT_NORMAL: + { + int tmp; + buf.Get(tmp); + if (tmp) + autoNormal = true; + else + autoNormal = false; + mat->SetAutoNormal(autoNormal); + } + break; + case TRPGMAT_TEXTURE: + buf.Get(numTex); + for (i=0;iAddTexture(texId,texEnv); - } - break; - case TRPGMAT_BUMP: - { - int tmp; - buf.Get(tmp); - bool isBump = (tmp) ? true : false; - mat->SetIsBumpMap(isBump); - } - default: - break; - } - } - catch (...) { - return NULL; - } + mat->AddTexture(texId,texEnv); + } + break; + case TRPGMAT_BUMP: + { + int tmp; + buf.Get(tmp); + bool isBump = (tmp) ? true : false; + mat->SetIsBumpMap(isBump); + } + break; + case TRPGMAT_ATTR: + { + int tmp; + buf.Get(tmp); + mat->SetAttr(trpgMaterial::TR_FID,tmp); + buf.Get(tmp); + mat->SetAttr(trpgMaterial::TR_SMC,tmp); + buf.Get(tmp); + mat->SetAttr(trpgMaterial::TR_STP,tmp); + buf.Get(tmp); + mat->SetAttr(trpgMaterial::TR_SWC,tmp); + } + break; + default: + break; + } + } + catch (...) { + return NULL; + } - return mat; + return mat; } bool trpgMaterial::Read(trpgReadBuffer &buf) { - trpgr_Parser parse; - materialCB matCb; + trpgr_Parser parse; + materialCB matCb; - // Material is just a bunch of unordered tokens. - // Interface to it with a generic parser - matCb.mat = this; - parse.AddCallback(TRPGMAT_BASIC,&matCb,false); - parse.AddCallback(TRPGMAT_SHADE,&matCb,false); - parse.AddCallback(TRPGMAT_SIZES,&matCb,false); - parse.AddCallback(TRPGMAT_CULL,&matCb,false); - parse.AddCallback(TRPGMAT_ALPHA,&matCb,false); - parse.AddCallback(TRPGMAT_NORMAL,&matCb,false); - parse.AddCallback(TRPGMAT_TEXTURE,&matCb,false); - parse.AddCallback(TRPGMAT_BUMP,&matCb,false); - parse.Parse(buf); + // Material is just a bunch of unordered tokens. + // Interface to it with a generic parser + matCb.mat = this; + parse.AddCallback(TRPGMAT_BASIC,&matCb,false); + parse.AddCallback(TRPGMAT_SHADE,&matCb,false); + parse.AddCallback(TRPGMAT_SIZES,&matCb,false); + parse.AddCallback(TRPGMAT_CULL,&matCb,false); + parse.AddCallback(TRPGMAT_ALPHA,&matCb,false); + parse.AddCallback(TRPGMAT_NORMAL,&matCb,false); + parse.AddCallback(TRPGMAT_TEXTURE,&matCb,false); + parse.AddCallback(TRPGMAT_BUMP,&matCb,false); + parse.AddCallback(TRPGMAT_ATTR,&matCb,false); + parse.Parse(buf); - return isValid(); + return isValid(); } /* Texture - Really just a container for a texture name and use count. - The use count is used for paging. - */ + Really just a container for a texture name and use count. + The use count is used for paging. + */ // Constructor trpgTexture::trpgTexture() { - mode = External; - type = trpg_Unknown; - name = NULL; - useCount = 0; - sizeX = sizeY = -1; - addr.file = 0; - addr.offset = 0; - isMipmap = false; + mode = External; + type = trpg_Unknown; + numLayer = -1; + org = trpg_RGBX_Neither; + name = NULL; + useCount = 0; + sizeX = sizeY = -1; + addr.file = 0; + addr.offset = 0; + isMipmap = false; } // Copy construction -trpgTexture::trpgTexture(const trpgTexture &in):trpgReadWriteable() +trpgTexture::trpgTexture(const trpgTexture &in) { - mode = in.mode; - type = in.type; - name = NULL; - SetName(in.name); - useCount = in.useCount; - sizeX = in.sizeX; sizeY = in.sizeY; - addr.file = in.addr.file; - addr.offset = in.addr.offset; - isMipmap = in.isMipmap; + mode = in.mode; + type = in.type; + numLayer = in.numLayer; // RGBX + org = in.org; // RGBX + name = NULL; + SetName(in.name); + useCount = in.useCount; + sizeX = in.sizeX; sizeY = in.sizeY; + addr.file = in.addr.file; + addr.offset = in.addr.offset; + isMipmap = in.isMipmap; + // storageSize + levelOffset } // Destruction trpgTexture::~trpgTexture() { - Reset(); + Reset(); } // Reset void trpgTexture::Reset() { - mode = External; - type = trpg_Unknown; - if (name) - delete [] name; - name = NULL; - useCount = 0; - sizeX = sizeY = -1; - addr.file = 0; - addr.offset = 0; - isMipmap = false; - storageSize.clear(); - levelOffset.clear(); + mode = External; + type = trpg_Unknown; + numLayer = -1; + org = trpg_RGBX_Neither; + if (name) + delete [] name; + name = NULL; + useCount = 0; + sizeX = sizeY = -1; + addr.file = 0; + addr.offset = 0; + isMipmap = false; + storageSize.clear(); + levelOffset.clear(); } // Valid if we've got a name bool trpgTexture::isValid() const { - switch (mode) { - case External: - return (name != NULL); - break; - case Local: - return (type != trpg_Unknown && sizeX != -1 && sizeY != -1); - break; - case Global: - return (type != trpg_Unknown); - break; - case Template: - return (type != trpg_Unknown && sizeX != -1 && sizeY != -1); - break; - default: - return false; - } + switch (mode) { + case External: + return (name != NULL); + break; + case Local: + return (type != trpg_Unknown && sizeX != -1 && sizeY != -1); + break; + case Global: + return (type != trpg_Unknown); + break; + case Template: + return (type != trpg_Unknown && sizeX != -1 && sizeY != -1); + break; + default: + return false; + } - return false; + return false; } + // Set Name void trpgTexture::SetName(const char *inName) { - if (name) - delete [] name; - name = NULL; + if (name) + delete [] name; + name = NULL; - if (!inName) - return; + if (!inName) + return; - name = new char[strlen(inName)+1]; - strcpy(name,inName); + name = new char[strlen(inName)+1]; + strcpy(name,inName); } // Get Name bool trpgTexture::GetName(char *outName,int outLen) const { - if (!isValid()) return false; + if (!isValid()) return false; - int len = (name) ? strlen(name) : 0; - strncpy(outName,name,MIN(len,outLen)+1); + int len = (name) ? strlen(name) : 0; + strncpy(outName,name,MIN(len,outLen)+1); - return true; + return true; } void trpgTexture::SetImageMode(ImageMode inMode) { - mode = inMode; + mode = inMode; } bool trpgTexture::GetImageMode(ImageMode &outMode) const { - outMode = mode; + outMode = mode; - return true; + return true; } void trpgTexture::SetImageType(ImageType inType) { - type = inType; + type = inType; } bool trpgTexture::GetImageType(ImageType &outType) const { - outType = type; + outType = type; - return true; + return true; } + +void trpgTexture::SetImageOrganization(ImageOrg inOrg) +{ + org = inOrg; +} + +bool trpgTexture::GetImageOrganization(ImageOrg &outOrg) const +{ + outOrg = org; + + return true; +} + void trpgTexture::SetImageSize(const trpg2iPoint &inSize) { - sizeX = inSize.x; - sizeY = inSize.y; + sizeX = inSize.x; + sizeY = inSize.y; } bool trpgTexture::GetImageSize(trpg2iPoint &outSize) const { - if (mode != Local && mode != Template) - return false; - outSize.x = sizeX; - outSize.y = sizeY; + if (mode != Local && mode != Template) + return false; + outSize.x = sizeX; + outSize.y = sizeY; - return true; + return true; } void trpgTexture::SetIsMipmap(bool val) { @@ -1024,69 +1187,84 @@ bool trpgTexture::GetIsMipmap(bool &ret) const } bool trpgTexture::GetImageAddr(trpgwAppAddress &outAddr) const { - if (mode != Local) - return false; + if (mode != Local) + return false; - outAddr = addr; + outAddr = addr; - return true; + return true; } void trpgTexture::SetImageAddr(const trpgwAppAddress &inAddr) { - addr = inAddr; + addr = inAddr; } bool trpgTexture::GetImageDepth(int32 &depth) const { - switch (type) { - case trpg_RGB8: - depth = 3; - break; - case trpg_RGBA8: - depth = 4; - break; - case trpg_INT8: - depth = 1; - break; - case trpg_INTA8: - depth = 2; - break; - case trpg_FXT1: - depth = 3; - break; - case trpg_RGBX: - depth = numLayer; - break; - case trpg_DXT1: - depth = 3; - break; - case trpg_DXT3: - depth = 3; - break; - case trpg_DXT5: - depth = 3; - break; - default: - depth = -1; - break; - } + switch (type) { + case trpg_RGB8: + depth = 3; + break; + case trpg_RGBA8: + depth = 4; + break; + case trpg_INT8: + depth = 1; + break; + case trpg_INTA8: + depth = 2; + break; + case trpg_FXT1: + depth = 3; + break; + case trpg_RGBX: + depth = numLayer; + break; + case trpg_DDS: + depth = 3; + break; + case trpg_DXT1: + depth = 3; + break; + case trpg_DXT3: + depth = 4; + break; + case trpg_DXT5: + depth = 4; + break; + default: + depth = -1; + break; + } - return true; + return true; +} + +void trpgTexture::SetNumLayer(int layers) +{ + numLayer = layers; +} + +bool trpgTexture::GetNumLayer(int &layers) const +{ + if (!isValid()) return false; + layers = numLayer; + return true; } // Use count management void trpgTexture::SetNumTile(int num) { - useCount = num; + useCount = num; } void trpgTexture::AddTile() { - useCount++; + useCount++; } bool trpgTexture::GetNumTile(int &num) const { - if (!isValid()) return false; - num = useCount; - return true; + if (!isValid()) return false; + num = useCount; + return true; } // Copy operator @@ -1096,43 +1274,49 @@ trpgTexture &trpgTexture::operator = (const trpgTexture &in) type = in.type; if (in.name) - SetName(in.name); + SetName(in.name); useCount = in.useCount; sizeX = in.sizeX; sizeY = in.sizeY; + + // RGBX + numLayer = in.numLayer; + org = in.org; + isMipmap = in.isMipmap; addr = in.addr; - return *this; + return *this; } // Equality operator int trpgTexture::operator == (const trpgTexture &in) const { if (mode != in.mode) - return 0; + return 0; switch (mode) { case External: - if (!in.name && !name) - return 1; - if (!in.name || !name) - return 0; - return (!strcmp(in.name,name)); - break; + if (!in.name && !name) + return 1; + if (!in.name || !name) + return 0; + return (!strcmp(in.name,name)); + break; case Local: - if (type == in.type && sizeX == in.sizeX && sizeY == in.sizeY && - isMipmap == in.isMipmap && - addr.file == in.addr.file && addr.offset == in.addr.offset) - return 1; - break; + if (type == in.type && sizeX == in.sizeX && sizeY == in.sizeY && + isMipmap == in.isMipmap && + addr.file == in.addr.file && addr.offset == in.addr.offset && + numLayer == in.numLayer && org == in.org) + return 1; + break; case Global: case Template: - if (type == in.type && sizeX == in.sizeX && sizeY == in.sizeY && - isMipmap == in.isMipmap) - return 1; + if (type == in.type && sizeX == in.sizeX && sizeY == in.sizeY && + isMipmap == in.isMipmap && numLayer == in.numLayer && org == in.org) + return 1; } return 0; @@ -1145,14 +1329,14 @@ int32 trpgTexture::CalcNumMipmaps() const // We're going to assume these are powers of two. // If not, then the writer's a moron. - // :))) The comment line above made me really loughing, Steve. - Nick + // :))) The comment line above made me really loughing, Steve. - Nick int bval = MAX(sizeX,sizeY); // Now look for the highest bit int p2; for (p2=0;p2<32;p2++) - if ((1<(this))->CalcMipLevelSizes(); - // DXT compressed textures need diferent algorithm for this - switch (type) { - case trpg_DXT1: - case trpg_DXT3: - case trpg_DXT5:{ + int totSize = 0; + for (int i=0;i> 3; - - if (x > 1) x /= 2; - if (y > 1) y /= 2; - } - - return totSize; - } - default: - break; - }; - - // Figure out the total data size, including mipmaps if necessary - int32 depth; - GetImageDepth(depth); - totSize = sizeX * sizeY * depth; - - // Do mipmaps if they're there - if (isMipmap) { - trpg2iPoint size(sizeX,sizeY); - int maxSize = MAX(size.x,size.y); - while (maxSize > 1) { - size.x = size.x >> 1; size.x = MAX(1,size.x); - size.y = size.y >> 1; size.y = MAX(1,size.y); - maxSize = maxSize >> 1; - - totSize += size.x*size.y*depth; - } - } - - return totSize; + return totSize; } // Calculate the size of a given mip level int32 trpgTexture::MipLevelSize(int miplevel) { - - if ( miplevel > 0 && miplevel < CalcNumMipmaps() ) { - if ( !storageSize.size() ) - CalcMipLevelSizes(); - return storageSize[miplevel]; - } + + if ( miplevel >= 0 && miplevel < CalcNumMipmaps() ) { + if ( !storageSize.size() ) + CalcMipLevelSizes(); + return storageSize[miplevel]; + } - return 0; + return 0; } int32 trpgTexture::MipLevelOffset(int miplevel) { - if ( miplevel > 0 && miplevel < CalcNumMipmaps() ) { - if ( !levelOffset.size() ) - CalcMipLevelSizes(); - return levelOffset[miplevel]; - } + if ( miplevel > 0 && miplevel < CalcNumMipmaps() ) { + if ( !levelOffset.size() ) + CalcMipLevelSizes(); + return levelOffset[miplevel]; + } - return 0; + return 0; } // Write function bool trpgTexture::Write(trpgWriteBuffer &buf) { - if (!isValid()) return false; + if (!isValid()) return false; - buf.Begin(TRPGTEXTURE); + buf.Begin(TRPGTEXTURE); - buf.Add(name); - buf.Add(useCount); - // New in 2.0 from here down - buf.Add((unsigned char)mode); - buf.Add((unsigned char)type); - buf.Add(sizeX); - buf.Add(sizeY); - buf.Add(addr.file); - buf.Add(addr.offset); - buf.Add(isMipmap); + buf.Add(name); + buf.Add(useCount); + // New in 2.0 from here down + buf.Add((unsigned char)mode); + buf.Add((unsigned char)type); + buf.Add(sizeX); + buf.Add(sizeY); + buf.Add(addr.file); + buf.Add(addr.offset); + buf.Add(isMipmap); + // More for MCMs + buf.Add(numLayer); + buf.Add((unsigned char)org); + buf.End(); - buf.End(); - - return true; + return true; } // Read function bool trpgTexture::Read(trpgReadBuffer &buf) { - char texName[1024]; + char texName[1024]; - try { - buf.Get(texName,1023); - SetName(texName); - buf.Get(useCount); + try { + buf.Get(texName,1023); + SetName(texName); + buf.Get(useCount); - mode = External; - // New in 2.0 from here down - unsigned char bval; - buf.Get(bval); mode = (trpgTexture::ImageMode)bval; - buf.Get(bval); type = (trpgTexture::ImageType)bval; - buf.Get(sizeX); - buf.Get(sizeY); - buf.Get(addr.file); - buf.Get(addr.offset); - int ival; - buf.Get(ival); - isMipmap = (ival) ? true : false; - } - catch (...) { - return false; - } + mode = External; + // New in 2.0 from here down + unsigned char bval; + buf.Get(bval); mode = (trpgTexture::ImageMode)bval; + buf.Get(bval); type = (trpgTexture::ImageType)bval; + buf.Get(sizeX); + buf.Get(sizeY); + buf.Get(addr.file); + buf.Get(addr.offset); + int ival; + buf.Get(ival); + isMipmap = (ival) ? true : false; + if ( !buf.isEmpty() ) { + buf.Get(numLayer); + buf.Get(bval); org = (trpgTexture::ImageOrg)bval; + } + } + catch (...) { + return false; + } - if (!isValid()) return false; + if (!isValid()) return false; - // calculate the mip level sizes - CalcMipLevelSizes(); + // calculate the mip level sizes + CalcMipLevelSizes(); - return true; + return true; } void trpgTexture::CalcMipLevelSizes() { - int num_miplevels = CalcNumMipmaps(); - int level_size = 0; - int level_offset = 0; - int block_size = 0; - int pixel_size = 0; + int num_miplevels = (isMipmap ? CalcNumMipmaps() : 1); + int level_size = 0; + int level_offset = 0; + int block_size = 0; + int pixel_size = 0; + int pad_size = 0; + bool isDXT = false; + bool isFXT = false; - switch (type) { - case trpg_DXT1: - block_size = 8; - break; - case trpg_DXT3: - case trpg_DXT5: - block_size = 16; - break; - case trpg_RGB8: - pixel_size = 3; - break; - case trpg_RGBA8: - pixel_size = 4; - break; - case trpg_INT8: - pixel_size = 1; - break; - case trpg_INTA8: - pixel_size = 2; - break; - default: - break; - } + switch (type) { + case trpg_DXT1: + isDXT = true; + block_size = 8; + break; + case trpg_DXT3: + case trpg_DXT5: + isDXT = true; + block_size = 16; + break; + case trpg_RGB8: + pad_size = 4; + pixel_size = 3; + break; + case trpg_RGBA8: + pad_size = 4; + pixel_size = 4; + break; + case trpg_RGBX: + pad_size = 4; + pixel_size = numLayer; + break; + case trpg_INT8: + pad_size = 4; + pixel_size = 1; + break; + case trpg_INTA8: + pad_size = 4; + pixel_size = 2; + break; + case trpg_FXT1: + isFXT = true; + break; + } - levelOffset.clear(); - storageSize.clear(); - levelOffset.push_back(level_offset); + levelOffset.clear(); + storageSize.clear(); - if ( block_size ) { // DXT compressed - int num_x_blocks = ((sizeX/4)+(sizeX%4?1:0)); - int num_y_blocks = ((sizeY/4)+(sizeY%4?1:0)); + levelOffset.push_back(level_offset); - level_size = num_x_blocks * num_y_blocks * block_size; - storageSize.push_back(level_size); - for ( int i = 1; i < num_miplevels; i++ ) { - level_offset += level_size; - levelOffset.push_back(level_offset); - num_x_blocks /= 2; - num_y_blocks /= 2; - num_x_blocks = MAX(1,num_x_blocks); - num_y_blocks = MAX(1,num_y_blocks); + if ( isDXT ) { // DXT compressed + int num_x_blocks = ((sizeX/4)+(sizeX%4?1:0)); + int num_y_blocks = ((sizeY/4)+(sizeY%4?1:0)); - level_size = num_x_blocks * num_y_blocks * block_size; - storageSize.push_back(level_size); - } - } - else { - int x_size = sizeX; - int y_size = sizeY; + level_size = num_x_blocks * num_y_blocks * block_size; + storageSize.push_back(level_size); - level_size = x_size * y_size * pixel_size; - storageSize.push_back(level_size); - for ( int i = 1; i < num_miplevels; i++ ) { - level_offset += level_size; - levelOffset.push_back(level_offset); + for ( int i = 1; i < num_miplevels; i++ ) { + level_offset += level_size; + levelOffset.push_back(level_offset); - x_size /= 2; - y_size /= 2; - x_size = MAX(1,x_size); - y_size = MAX(1,y_size); + num_x_blocks /= 2; + num_y_blocks /= 2; + num_x_blocks = MAX(1,num_x_blocks); + num_y_blocks = MAX(1,num_y_blocks); - level_size = x_size * y_size * pixel_size; - storageSize.push_back(level_size); - } - } + level_size = num_x_blocks * num_y_blocks * block_size; + storageSize.push_back(level_size); + } + + return; + } + if ( isFXT) { + // bits per pixel and size + int bpp = 4; + int x = sizeX; + int y = sizeY; + + int nummiplevels = (isMipmap ? CalcNumMipmaps() : 1); + for (int i = 0; i < nummiplevels; i++) { + if (i > 0) + levelOffset.push_back(level_offset); + + x = ( x + 0x7 ) & ~0x7; + y = ( y + 0x3 ) & ~0x3; + + // Number of bytes + level_size = ( x * y * bpp ) >> 3; + storageSize.push_back(level_size); + level_offset += level_size; + + if (x > 1) x /= 2; + if (y > 1) y /= 2; + } + + return; + } + + { + int x_size = sizeX; + int y_size = sizeY; + + // Pad to a given size, if necessary + int row_size = x_size * pixel_size; + if (pad_size > 0) { + int left = row_size%pad_size; + if (left) + row_size += pad_size - left; + } + + level_size = row_size * y_size; + storageSize.push_back(level_size); + for ( int i = 1; i < num_miplevels; i++ ) { + level_offset += level_size; + levelOffset.push_back(level_offset); + + x_size /= 2; + y_size /= 2; + x_size = MAX(1,x_size); + y_size = MAX(1,y_size); + + row_size = x_size * pixel_size; + if (pad_size > 0) { + int left = row_size%pad_size; + if (left) + row_size += pad_size - left; + } + level_size = row_size * y_size; + storageSize.push_back(level_size); + } + } } /* Texture Table - Just a list of texture names so we can index. - */ + Just a list of texture names so we can index. + */ // Constructor trpgTexTable::trpgTexTable() { + } -trpgTexTable::trpgTexTable(const trpgTexTable &in):trpgReadWriteable() +trpgTexTable::trpgTexTable(const trpgTexTable &in) { - *this = in; + *this = in; } // Reset function void trpgTexTable::Reset() { - texList.resize(0); + errMess[0] = '\0'; + texList.resize(0); } // Destructor trpgTexTable::~trpgTexTable() { - Reset(); + Reset(); } // Validity check bool trpgTexTable::isValid() const { - if (!texList.size()) - return false; + if (!texList.size()) + { + strcpy(errMess, "Texture table list is empty"); + return false; + } - for (unsigned int i=0;i= texList.size()) - return; + if (id < 0 || (unsigned int)id >= texList.size()) + return; - texList[id] = inTex; + texList[id] = inTex; } // Copy operator trpgTexTable &trpgTexTable::operator = (const trpgTexTable &in) { - Reset(); - for (unsigned int i=0;i= static_cast(texList.size())) return false; + if (!isValid()) return false; + if (id < 0 || id >= texList.size()) return false; - ret = texList[id]; - return true; + ret = texList[id]; + return true; } const trpgTexture *trpgTexTable::GetTextureRef(int id) const { - if (id < 0 || id >= static_cast(texList.size())) return NULL; - return &texList[id]; + if (id < 0 || id >= texList.size()) return NULL; + return &texList[id]; } bool trpgTexTable::Read(trpgReadBuffer &buf) { - int32 numTex; - trpgToken texTok; - int32 len; + int32 numTex; + trpgToken texTok; + int32 len; - try { - buf.Get(numTex); - texList.resize(numTex); - for (int i=0;i *inSizes) { - storageSize.resize(inSizes->size()); - for (int i=0;isize();i++) - storageSize[i] = (*inSizes)[i]; + storageSize.resize(inSizes->size()); + for (int i=0;isize();i++) + storageSize[i] = (*inSizes)[i]; - return true; + return true; }*/ /*bool trpgLocalMaterial::GetStorageSizes(const vector *retSize) { - if (!isValid()) return false; + if (!isValid()) return false; - retSize = storageSize; - return true; + retSize = storageSize; + return true; }*/ bool trpgLocalMaterial::isValid() const { - if (baseMat < 0) return false; + if (baseMat < 0) return false; - return true; + return true; } // Write method bool trpgLocalMaterial::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + if (!isValid()) + return false; - buf.Begin(TRPGLOCALMATERIAL); + buf.Begin(TRPGLOCALMATERIAL); - // Write the data - buf.Add(baseMatTable); - buf.Add(baseMat); - buf.Add(sx); - buf.Add(sy); - buf.Add(ex); - buf.Add(ey); - buf.Add(destWidth); - buf.Add(destHeight); - buf.Add(addr.file); - buf.Add(addr.offset); + // Write the data + buf.Add(baseMatTable); + buf.Add(baseMat); + buf.Add(sx); + buf.Add(sy); + buf.Add(ex); + buf.Add(ey); + buf.Add(destWidth); + buf.Add(destHeight); + buf.Add(addr[0].file); + buf.Add(addr[0].offset); + // and in case there's more... + int numAddrs=(int)(addr.size()); + buf.Add(numAddrs-1); // write even if its zero for reading purposes + if (numAddrs>1) { + for (int i=1;i /* 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" +#include +#include /* 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):trpgReadWriteable() +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) + { + strcpy(errMess, "Model is external with no name"); + return false; + } - return true; + return true; } // Copy from one to another trpgModel& trpgModel::operator = (const trpgModel &in) { - if (name) { - delete [] name; - name = NULL; - } + if (name) { + delete [] name; + name = NULL; + } - type = in.type; - if (in.name) - SetName(in.name); - diskRef = in.diskRef; - useCount = in.useCount; + 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() @@ -223,32 +226,32 @@ 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 || static_cast(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(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 || static_cast(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 /* trpage_nodes.cpp - The methods for all the hierarchy nodes (e.g. groups, transforms, etc...) - is here. - You should only need to modify this if you want to add something to one - of these classes. - */ + The methods for all the hierarchy nodes (e.g. groups, transforms, etc...) + is here. + You should only need to modify this if you want to add something to one + of these classes. + */ -#include "trpage_geom.h" -#include "trpage_read.h" +#include +#include /* Write Group - Basic group. - */ + Basic group. + */ // Constructor trpgGroup::trpgGroup() { - name = 0; - Reset(); + name = 0; + Reset(); } trpgGroup::~trpgGroup() { - Reset(); + Reset(); } // Reset void trpgGroup::Reset() { - numChild = 0; - id = -1; - if ( name ) { - delete [] name; - name = 0; - } + numChild = 0; + id = -1; + if ( name ) { + delete [] name; + name = 0; + } } // Set functions void trpgGroup::SetNumChild(int no) { - numChild = no; + numChild = no; } int trpgGroup::AddChild() { - numChild++; - return numChild-1; + numChild++; + return numChild-1; } void trpgGroup::SetID(int inID) { - id = inID; + id = inID; } void trpgGroup::SetName(const char* newname ) { - if ( name ) { - delete [] name; - name = 0; - } - if ( strlen(newname) ) { - name = new char[strlen(newname)+1]; - strcpy(name,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; + return name; } bool trpgGroup::GetNumChild(int &n) const { - if (!isValid()) return false; - n = numChild; - return true; + if (!isValid()) return false; + n = numChild; + return true; } bool trpgGroup::GetID(int &inID) const { - if (!isValid()) return false; - inID = id; - return true; + if (!isValid()) return false; + inID = id; + return true; } // Validity check bool trpgGroup::isValid() const { - if (numChild <= 0) return false; - if (id < 0) return false; + if (numChild <= 0) return false; + if (id < 0) return false; - return true; + return true; } // Write group bool trpgGroup::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + if (!isValid()) + return false; - buf.Begin(TRPG_GROUP); - buf.Add(numChild); - buf.Add(id); + buf.Begin(TRPG_GROUP); + buf.Add(numChild); + buf.Add(id); - if ( name && strlen(name) ) { - buf.Add(name); - } + if ( name && strlen(name) ) { + buf.Add(name); + } - buf.End(); + buf.End(); - return true; + 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); - } + 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; - } + } + catch (...) { + return false; + } - return isValid(); + return isValid(); } /* Write Billboard - Represents rotational billboarded geometry. - */ + Represents rotational billboarded geometry. + */ // Constructor trpgBillboard::trpgBillboard() { - name = 0; - Reset(); + name = 0; + Reset(); } trpgBillboard::~trpgBillboard() { - Reset(); + 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; - } + 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; + center = pt; + valid = true; } void trpgBillboard::SetMode(int m) { - mode = m; + mode = m; } void trpgBillboard::SetAxis(const trpg3dPoint &pt) { - axis = pt; + axis = pt; } void trpgBillboard::SetType(int t) { - type = t; + type = t; } // Get methods bool trpgBillboard::GetCenter(trpg3dPoint &pt) const { - if (!isValid()) return false; - pt = center; - return true; + if (!isValid()) return false; + pt = center; + return true; } bool trpgBillboard::GetMode(int &m) const { - if (!isValid()) return false; - m = mode; - return true; + if (!isValid()) return false; + m = mode; + return true; } bool trpgBillboard::GetAxis(trpg3dPoint &pt) const { - if (!isValid()) return false; - pt = axis; - return true; + if (!isValid()) return false; + pt = axis; + return true; } bool trpgBillboard::GetType(int &t) const { - if (!isValid()) return false; - t = type; - return true; + if (!isValid()) return false; + t = type; + return true; } // Write billboard bool trpgBillboard::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + 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); + 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(); + if ( name && strlen(name) ) { + buf.Add(name); + } + buf.End(); - return true; + return true; } // Read billboard bool trpgBillboard::Read(trpgReadBuffer &buf) { - uint8 uChar; + 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; - } + 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(); + return isValid(); } /* Write Level of Detail - Represents LOD information. - */ + Represents LOD information. + */ // Constructor trpgLod::trpgLod() { - name = 0; - Reset(); + name = 0; + Reset(); } trpgLod::~trpgLod() { - Reset(); + 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; - } + 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; + center = pt; + valid = true; } void trpgLod::SetNumChild(int no) { - if (no < 0) - return; + if (no < 0) + return; - numRange = no; + numRange = no; } void trpgLod::SetLOD(double in,double out,double wid) { - switchIn = in; - switchOut = out; - width = wid; + switchIn = in; + switchOut = out; + width = wid; } void trpgLod::SetID(int inID) { - id = inID; + id = inID; } void trpgLod::SetName(const char* newname ) { - if ( name ) { - delete [] name; - name = 0; - } - if ( strlen(newname) ) { - name = new char[strlen(newname)+1]; - strcpy(name,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; + rangeIndex = ri; } // Get methods const char* trpgLod::GetName(void) const { - return name; + return name; } // Get functions bool trpgLod::GetCenter(trpg3dPoint &pt) const { - if (!isValid()) return false; - pt = center; - return true; + if (!isValid()) return false; + pt = center; + return true; } bool trpgLod::GetNumChild(int &n) const { - if (!isValid()) return false; - n = numRange; - return true; + 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; + 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; + if (!isValid()) return false; + outID = id; + return true; } bool trpgLod::GetRangeIndex(int &ri) const { - if (!isValid()) return false; + if (!isValid()) return false; - ri = rangeIndex; + ri = rangeIndex; - return true; + return true; } // Write out LOD bool trpgLod::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + 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); + 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(""); + if ( name && strlen(name) ) { + buf.Add(name); + } else + buf.Add(""); - buf.End(); + buf.End(); - return true; + 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; - } + 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(); + return isValid(); } /* Write Layer - A layer is just a group with a different opcode. - */ + A layer is just a group with a different opcode. + */ // Constructor trpgLayer::trpgLayer() { - name = 0; + name = 0; } trpgLayer::~trpgLayer() { - Reset(); + Reset(); } // Write it bool trpgLayer::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + if (!isValid()) + return false; - buf.Begin(TRPG_LAYER); - buf.Add(numChild); - buf.Add(id); + buf.Begin(TRPG_LAYER); + buf.Add(numChild); + buf.Add(id); - if ( name && strlen(name) ) { - buf.Add(name); - } + if ( name && strlen(name) ) { + buf.Add(name); + } - buf.End(); + buf.End(); - return true; + 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; - } + 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(); + return isValid(); } // Reset function void trpgLayer::Reset() { - numChild = 0; - if ( name ) { - delete [] name; - name = 0; - } + numChild = 0; + if ( name ) { + delete [] name; + name = 0; + } } /* Write Transform - Matrix defining the transform with children. - */ + Matrix defining the transform with children. + */ // Constructor trpgTransform::trpgTransform() { - name = 0; - Reset(); + name = 0; + Reset(); } trpgTransform::~trpgTransform() { - Reset(); + 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; + 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; - } + 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]; + 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; + 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; + 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]); + 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(); + if ( name && strlen(name) ) { + buf.Add(name); + } + buf.End(); - return true; + 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; - } + 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(); + return isValid(); } /* Model Reference - This is just a matrix transform and a model ID. - */ + This is just a matrix transform and a model ID. + */ // Constructor trpgModelRef::trpgModelRef() { - Reset(); + Reset(); } trpgModelRef::~trpgModelRef() { @@ -614,178 +618,178 @@ 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; + 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; + 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]; + 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; + 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; + 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(); + 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; + 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; - } + 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(); + 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. - */ + 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(); + name = 0; + Reset(); } trpgAttach::~trpgAttach() { - Reset(); + Reset(); } // Reset void trpgAttach::Reset() { - parentID = -1; - childPos = -1; - if ( name ) { - delete [] name; - name = 0; - } + 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; + parentID = id; } bool trpgAttach::GetParentID(int &id) const { - if (!isValid()) return false; - id = parentID; - return true; + 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; + childPos = id; } bool trpgAttach::GetChildPos(int &id) const { - if (!isValid()) return false; - id = childPos; - return true; + if (!isValid()) return false; + id = childPos; + return true; } // Validity check bool trpgAttach::isValid() const { - if (parentID < 0 || childPos < 0) return false; - return true; + if (parentID < 0 || childPos < 0) return false; + return true; } // Write Attach node bool trpgAttach::Write(trpgWriteBuffer &buf) { - if (!isValid()) return false; + if (!isValid()) return false; - buf.Begin(TRPG_ATTACH); - buf.Add(numChild); - buf.Add(id); - buf.Add(parentID); - buf.Add(childPos); + buf.Begin(TRPG_ATTACH); + buf.Add(numChild); + buf.Add(id); + buf.Add(parentID); + buf.Add(childPos); - if ( name && strlen(name) ) { - buf.Add(name); - } + if ( name && strlen(name) ) { + buf.Add(name); + } - buf.End(); + buf.End(); - return true; + 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; - } + 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; + return true; } diff --git a/src/osgPlugins/txp/trpage_parse.cpp b/src/osgPlugins/txp/trpage_parse.cpp index 91fec2661..e5ccb9f15 100644 --- a/src/osgPlugins/txp/trpage_parse.cpp +++ b/src/osgPlugins/txp/trpage_parse.cpp @@ -17,62 +17,62 @@ #include /* trpage_parse.cpp - This source file contains methods for the trpgr_Parser and trpgr_Token classes. - trpgr_Parser is the main class. It parses the basic structure of paging archive - data out of Read Buffers. You should not need to change this. - If you want to parse data out of a different structure instead, look at - subclassing trpgReadBuffer and replacing its virtual methods. That's what - trpgMemReadBuffer is doing. + This source file contains methods for the trpgr_Parser and trpgr_Token classes. + trpgr_Parser is the main class. It parses the basic structure of paging archive + data out of Read Buffers. You should not need to change this. + If you want to parse data out of a different structure instead, look at + subclassing trpgReadBuffer and replacing its virtual methods. That's what + trpgMemReadBuffer is doing. This file also contains the implementation of trpgSceneParser(). - That class implements a set of callbacks for handling the Pushes and Pops - in an archive. You fill in the Start/EndChildren callbacks and register - for the rest of the tokens that you want. - */ + That class implements a set of callbacks for handling the Pushes and Pops + in an archive. You fill in the Start/EndChildren callbacks and register + for the rest of the tokens that you want. + */ -#include "trpage_read.h" +#include /* *************************** - Paging token callback structure + Paging token callback structure *************************** */ trpgr_Token::trpgr_Token() { - cb = NULL; - destroy = true; + cb = NULL; + destroy = true; } trpgr_Token::~trpgr_Token() { } trpgr_Token::trpgr_Token(int in_tok,trpgr_Callback *in_cb,bool in_dest) { - init(in_tok,in_cb,in_dest); + init(in_tok,in_cb,in_dest); } void trpgr_Token::init(int in_tok,trpgr_Callback *in_cb,bool in_dest) { - Token = in_tok; - cb = in_cb; - destroy = in_dest; + Token = in_tok; + cb = in_cb; + destroy = in_dest; } // Destruct // Destroy our callback if appropriate void trpgr_Token::Destruct() { - if (cb && destroy) - delete cb; - cb = NULL; - destroy = true; + if (cb && destroy) + delete cb; + cb = NULL; + destroy = true; } /* *************************** - Paging parser implementation. + Paging parser implementation. *************************** */ // Constructor trpgr_Parser::trpgr_Parser() { - lastObject = NULL; + lastObject = NULL; } trpgr_Parser::~trpgr_Parser() { @@ -81,63 +81,63 @@ trpgr_Parser::~trpgr_Parser() // Validity check bool trpgr_Parser::isValid() const { - return true; + return true; } // Add Callback // Make the given callback object current for the given token. void trpgr_Parser::AddCallback(trpgToken tok,trpgr_Callback *cb,bool in_dest) { - RemoveCallback(tok); + RemoveCallback(tok); - tokenMap[tok] = trpgr_Token(tok,cb,in_dest); + tokenMap[tok] = trpgr_Token(tok,cb,in_dest); } // Callback used as writeable wrapper class WriteWrapper : public trpgr_Callback { public: - WriteWrapper(trpgReadWriteable *in_wr) { wr = in_wr; }; - void *Parse(trpgToken,trpgReadBuffer &buf) { - if (wr->Read(buf)) - return wr; - else - return NULL; - } + WriteWrapper(trpgReadWriteable *in_wr) { wr = in_wr; }; + void *Parse(trpgToken,trpgReadBuffer &buf) { + if (wr->Read(buf)) + return wr; + else + return NULL; + } protected: - trpgReadWriteable *wr; + trpgReadWriteable *wr; }; // Add Callback (writeable) // Build a wrapper around a trpgWriteable so it can read itself void trpgr_Parser::AddCallback(trpgToken tok,trpgReadWriteable *wr) { - AddCallback(tok,new WriteWrapper(wr),true); + AddCallback(tok,new WriteWrapper(wr),true); } // Remove Callback void trpgr_Parser::RemoveCallback(trpgToken tok) { - tokenMap.erase(tok); + tokenMap.erase(tok); } // Set Default Callback // This gets called for all tokens we don't understand void trpgr_Parser::SetDefaultCallback(trpgr_Callback *cb,bool in_dest) { - defCb.Destruct(); - defCb.init(-1,cb,in_dest); + defCb.Destruct(); + defCb.init(-1,cb,in_dest); } /* Token Is Valid - Checks if something *could be* a token. - Doesn't necessarily mean that it is. - */ + Checks if something *could be* a token. + Doesn't necessarily mean that it is. + */ bool trpgr_Parser::TokenIsValid(trpgToken tok) { - if (tok < 0) - return false; + if (tok < 0) + return false; - return true; + return true; } /* Parse Buffer @@ -147,97 +147,97 @@ bool trpgr_Parser::TokenIsValid(trpgToken tok) */ bool trpgr_Parser::Parse(trpgReadBuffer &buf) { - bool ret = true; + bool ret = true; - try { - while (!buf.isEmpty()) { - /* We're expecting the following - Token (int32) - Length (int32) - Data (variable) - */ - trpgToken tok; - int32 len; - if (!buf.Get(tok)) throw 1; - // Push and Pop are special - no data - if (tok != TRPG_PUSH && tok != TRPG_POP) { - if (!buf.Get(len)) throw 1; - if (!TokenIsValid(tok)) throw 1; - if (len < 0) throw 1; - // Limit what we're reading to the length of this - buf.PushLimit(len); - } + try { + while (!buf.isEmpty()) { + /* We're expecting the following + Token (int32) + Length (int32) + Data (variable) + */ + trpgToken tok; + int32 len; + if (!buf.Get(tok)) throw 1; + // Push and Pop are special - no data + if (tok != TRPG_PUSH && tok != TRPG_POP) { + if (!buf.Get(len)) throw 1; + if (!TokenIsValid(tok)) throw 1; + if (len < 0) throw 1; + // Limit what we're reading to the length of this + buf.PushLimit(len); + } - // Call our token handler for this one - try { - const trpgr_Token *tcb = NULL; - tok_map::const_iterator p = tokenMap.find(tok); - if (p != tokenMap.end()) - tcb = &(*p).second; - if (!tcb) - // No such token, call the default - tcb = &defCb; + // Call our token handler for this one + try { + const trpgr_Token *tcb = NULL; + tok_map::const_iterator p = tokenMap.find(tok); + if (p != tokenMap.end()) + tcb = &(*p).second; + if (!tcb) + // No such token, call the default + tcb = &defCb; - // Run the callback - if (tcb->cb) { - void *ret = tcb->cb->Parse(tok,buf); - // Note: Do something with the return value - lastObject = ret; - } - } - catch (...) { - // Don't want to screw up the limit stack - } - // No limit to worry about with push and pop - if (tok != TRPG_PUSH && tok != TRPG_POP) { - buf.SkipToLimit(); - buf.PopLimit(); - } - } - } - catch (...) { - // Failed to parse. - ret = false; - } + // Run the callback + if (tcb->cb) { + void *ret = tcb->cb->Parse(tok,buf); + // Note: Do something with the return value + lastObject = ret; + } + } + catch (...) { + // Don't want to screw up the limit stack + } + // No limit to worry about with push and pop + if (tok != TRPG_PUSH && tok != TRPG_POP) { + buf.SkipToLimit(); + buf.PopLimit(); + } + } + } + catch (...) { + // Failed to parse. + ret = false; + } - return ret; + return ret; } -/* **************** - Scene Parser - **************** - */ +/* **************** + Scene Parser + **************** + */ // Helper - callback for Push class trpgSceneHelperPush : public trpgr_Callback { public: - trpgSceneHelperPush(trpgSceneParser *in_parse) { parse = in_parse; }; - void *Parse(trpgToken ,trpgReadBuffer &) { - // Call the start children callback - parse->StartChildren(parse->lastObject); - parse->parents.push_back(parse->lastObject); - return (void *)1; - } + trpgSceneHelperPush(trpgSceneParser *in_parse) { parse = in_parse; }; + void *Parse(trpgToken tok,trpgReadBuffer &buf) { + // Call the start children callback + parse->StartChildren(parse->lastObject); + parse->parents.push_back(parse->lastObject); + return (void *)1; + } protected: - trpgSceneParser *parse; + trpgSceneParser *parse; }; // Helper - callback for Pop class trpgSceneHelperPop : public trpgr_Callback { public: - trpgSceneHelperPop(trpgSceneParser *in_parse) { parse = in_parse; }; - void *Parse(trpgToken ,trpgReadBuffer &) { - // Make sure we don't have an extra pop - if (parse->parents.size() == 0) - // Note: let someone know about the extra pop - return NULL; - // Call the end children callback - int len = parse->parents.size(); - parse->EndChildren(parse->parents[len-1]); - parse->parents.resize(len-1); - return (void *)1; - } + trpgSceneHelperPop(trpgSceneParser *in_parse) { parse = in_parse; }; + void *Parse(trpgToken tok,trpgReadBuffer &buf) { + // Make sure we don't have an extra pop + if (parse->parents.size() == 0) + // Note: let someone know about the extra pop + return NULL; + // Call the end children callback + int len = parse->parents.size(); + parse->EndChildren(parse->parents[len-1]); + parse->parents.resize(len-1); + return (void *)1; + } protected: - trpgSceneParser *parse; + trpgSceneParser *parse; }; // Helper - default callback @@ -245,23 +245,23 @@ protected: // Note: Need to use this fact above class trpgSceneHelperDefault : public trpgr_Callback { public: - trpgSceneHelperDefault(trpgSceneParser *in_parse) { parse = in_parse; } - void *Parse(trpgToken ,trpgReadBuffer &) { - // Absorb it quietly - return (void *)1; - } + trpgSceneHelperDefault(trpgSceneParser *in_parse) { parse = in_parse; } + void *Parse(trpgToken tok,trpgReadBuffer &buf) { + // Absorb it quietly + return (void *)1; + } protected: - trpgSceneParser *parse; + trpgSceneParser *parse; }; trpgSceneParser::trpgSceneParser() { - // Register for Push and Pop - AddCallback(TRPG_PUSH,new trpgSceneHelperPush(this)); - AddCallback(TRPG_POP,new trpgSceneHelperPop(this)); + // Register for Push and Pop + AddCallback(TRPG_PUSH,new trpgSceneHelperPush(this)); + AddCallback(TRPG_POP,new trpgSceneHelperPop(this)); - // Register for default - SetDefaultCallback(new trpgSceneHelperDefault(this)); + // Register for default + SetDefaultCallback(new trpgSceneHelperDefault(this)); } trpgSceneParser::~trpgSceneParser() { diff --git a/src/osgPlugins/txp/trpage_pparse.cpp b/src/osgPlugins/txp/trpage_pparse.cpp index 7ac09fbb7..8f76d2da9 100644 --- a/src/osgPlugins/txp/trpage_pparse.cpp +++ b/src/osgPlugins/txp/trpage_pparse.cpp @@ -18,111 +18,183 @@ #include /* trpage_pparse.cpp - This file contains classes that can parse a TerraPage - archive for the purpose of printing it out. + This file contains classes that can parse a TerraPage + archive for the purpose of printing it out. */ -#include "trpage_print.h" -#include "trpage_scene.h" +#include +#include /* Set up the callbacks for the scene graph parser. - In our case this is just one read helper with - a switch statement. + In our case this is just one read helper with + a switch statement. */ -trpgPrintGraphParser::trpgPrintGraphParser(trpgPrintBuffer *inBuf) +trpgPrintGraphParser::trpgPrintGraphParser(trpgr_Archive *inArch,trpgrImageHelper *inImg,trpgPrintBuffer *inBuf) { - printBuf = inBuf; + printBuf = inBuf; + archive = inArch; + imageHelp = inImg; - // Register the readers - AddCallback(TRPG_GEOMETRY,new ReadHelper(printBuf)); - AddCallback(TRPG_GROUP,new ReadHelper(printBuf)); - AddCallback(TRPG_ATTACH,new ReadHelper(printBuf)); - AddCallback(TRPG_BILLBOARD,new ReadHelper(printBuf)); - AddCallback(TRPG_LOD,new ReadHelper(printBuf)); - AddCallback(TRPG_TRANSFORM,new ReadHelper(printBuf)); - AddCallback(TRPG_MODELREF,new ReadHelper(printBuf)); - AddCallback(TRPG_LAYER,new ReadHelper(printBuf)); - AddCallback(TRPG_LIGHT,new ReadHelper(printBuf)); - AddCallback(TRPGTILEHEADER,new ReadHelper(printBuf)); + // Register the readers + AddCallback(TRPG_GEOMETRY,new ReadHelper(this,printBuf)); + AddCallback(TRPG_GROUP,new ReadHelper(this,printBuf)); + AddCallback(TRPG_ATTACH,new ReadHelper(this,printBuf)); + AddCallback(TRPG_BILLBOARD,new ReadHelper(this,printBuf)); + AddCallback(TRPG_LOD,new ReadHelper(this,printBuf)); + AddCallback(TRPG_TRANSFORM,new ReadHelper(this,printBuf)); + AddCallback(TRPG_MODELREF,new ReadHelper(this,printBuf)); + AddCallback(TRPG_LAYER,new ReadHelper(this,printBuf)); + AddCallback(TRPG_LIGHT,new ReadHelper(this,printBuf)); + AddCallback(TRPG_LABEL,new ReadHelper(this,printBuf)); + AddCallback(TRPGTILEHEADER,new ReadHelper(this,printBuf)); } /* Start Children is called when the parser hits a Push - in the read buffer. We just want to indent further when - that happens. + in the read buffer. We just want to indent further when + that happens. */ bool trpgPrintGraphParser::StartChildren(void *) { - printBuf->IncreaseIndent(); + printBuf->IncreaseIndent(); - return true; + return true; } /* End Children is called when the parser hits a Pop - in the read buffer. We just want to reduce the indent - when that happens. + in the read buffer. We just want to reduce the indent + when that happens. */ bool trpgPrintGraphParser::EndChildren(void *) { - printBuf->DecreaseIndent(); + printBuf->DecreaseIndent(); - return true; + return true; } /* Read Helper parse method sets up the correct class depending - on the token and asks it to read and print itself. + on the token and asks it to read and print itself. */ void *trpgPrintGraphParser::ReadHelper::Parse(trpgToken tok,trpgReadBuffer &buf) { - trpgReadWriteable *obj = NULL; + trpgReadWriteable *obj = NULL; + trpgTileHeader *tileHead = NULL; - switch (tok) { - case TRPG_GEOMETRY: - obj = new trpgGeometry(); - break; - case TRPG_GROUP: - obj = new trpgGroup(); - break; - case TRPG_ATTACH: - obj = new trpgAttach(); - break; - case TRPG_BILLBOARD: - obj = new trpgBillboard(); - break; - case TRPG_LOD: - obj = new trpgLod(); - break; - case TRPG_TRANSFORM: - obj = new trpgTransform(); - break; - case TRPG_MODELREF: - obj = new trpgModelRef(); - break; - case TRPG_LAYER: - obj = new trpgLayer(); - break; - case TRPG_LIGHT: - obj = new trpgLight(); - break; - case TRPGTILEHEADER: - obj = new trpgTileHeader(); - break; - }; + switch (tok) { + case TRPG_GEOMETRY: + obj = new trpgGeometry(); + break; + case TRPG_GROUP: + obj = new trpgGroup(); + break; + case TRPG_ATTACH: + obj = new trpgAttach(); + break; + case TRPG_BILLBOARD: + obj = new trpgBillboard(); + break; + case TRPG_LOD: + obj = new trpgLod(); + break; + case TRPG_TRANSFORM: + obj = new trpgTransform(); + break; + case TRPG_MODELREF: + obj = new trpgModelRef(); + break; + case TRPG_LAYER: + obj = new trpgLayer(); + break; + case TRPG_LIGHT: + obj = new trpgLight(); + break; + case TRPG_LABEL: + obj = new trpgLabel(); + break; - if (obj) { - if (obj->Read(buf)) - obj->Print(*pBuf); - delete obj; - } + case TRPGTILEHEADER: + obj = tileHead = new trpgTileHeader(); + break; + }; - // Need to return non-zero. Otherwise it's interpreted as an error - return (void *)1; + if (obj) { + if (obj->Read(buf)) + obj->Print(*pBuf); + // For the tile header, do a little more work + if (tok == TRPGTILEHEADER) { + int numMat; + tileHead->GetNumLocalMaterial(numMat); + for (int i=0;iGetLocalMaterial(i,locMat); + const trpgMaterial *baseMat; + const trpgTexture *baseTex; + int totSize; + trpgrImageHelper *imageHelp = parse->GetImageHelp(); + int numImages=1; + locMat.GetNumLocals(numImages); + for (int imgN=0;imgNGetNthImageInfoForLocalMat(&locMat,imgN,&baseMat,&baseTex,totSize); + + // Fetch the whole image + { + char *pixels = new char[totSize]; + bool failed = false; + try { + failed = !imageHelp->GetNthImageForLocalMat(&locMat,imgN,pixels,totSize); + } + catch (...) { + failed = true; + } + if (failed) { + fprintf(stderr,"Failed to read local image %d from local material %d.\n",imgN,i); + } else + fprintf(stderr,"Read local image %d from local material %d successfully.\n",imgN,i); + delete [] pixels; + } + + // Fetch the individual mipmap levels + { + int numMipmap; + bool hasMipmap; + baseTex->GetIsMipmap(hasMipmap); + numMipmap = hasMipmap ? baseTex->CalcNumMipmaps() : 0; + for (int j=1;j(baseTex))->MipLevelOffset(j); + int mipSize = (const_cast(baseTex))->MipLevelSize(j); + if (mipSize) { + char *pixels = new char[mipSize]; + bool failed = false; + try { + failed = !imageHelp->GetNthImageMipLevelForLocalMat(j,&locMat,imgN,pixels,mipSize); + } + catch (...) { + failed = true; + } + if (failed) + fprintf(stderr,"Failed to read mipmap level %d for local image %d from local material %d.\n",j,imgN,i); + else + fprintf(stderr,"Read mipmap level %d for local image %d from local material %d.\n",j,imgN,i); + delete [] pixels; + } + } + } + } + } + } + + delete obj; + } + + // Need to return non-zero. Otherwise it's interpreted as an error + return (void *)1; } // The following routine is not compiled if there's no _splitpath #ifdef _splitpath /* This is a convenience function to print out the contents - of an entire TerraPage archive. + of an entire TerraPage archive. There are two versions of this function. The first takes a file name and the second an opened archive where the header @@ -130,81 +202,88 @@ void *trpgPrintGraphParser::ReadHelper::Parse(trpgToken tok,trpgReadBuffer &buf) */ bool trpgPrintArchive(char *filename,trpgPrintBuffer &pBuf,int flags) { - trpgr_Archive archive; + trpgr_Archive archive; - // Break path apart so we can find the directory - char drive[100],dir[1024],fname[1024],ext[1024]; - _splitpath(filename,drive,dir,fname,ext); + // Break path apart so we can find the directory + char drive[100],dir[1024],fname[1024],ext[1024]; + _splitpath(filename,drive,dir,fname,ext); - char rname[1024],baseDir[1024]; - sprintf(baseDir,"%s%s",drive,dir); - sprintf(rname,"%s%s",fname,ext); + char rname[1024],baseDir[1024]; + sprintf(baseDir,"%s%s",drive,dir); + sprintf(rname,"%s%s",fname,ext); - if (!*baseDir) strcpy(baseDir,"."); - archive.SetDirectory(baseDir); - if (!archive.OpenFile(rname)) { - fprintf(stdout,"Failed to open archive.\n"); - return false; - } - if (!archive.ReadHeader()) { - fprintf(stdout,"Failed to read header.\n"); - return false; - } + if (!*baseDir) strcpy(baseDir,"."); + archive.SetDirectory(baseDir); + if (!archive.OpenFile(rname)) { + fprintf(stdout,"Failed to open archive.\n"); + return false; + } + if (!archive.ReadHeader()) { + fprintf(stdout,"Failed to read header.\n"); + return false; + } - bool status = trpgPrintArchive(&archive,pBuff,flags); - return status; + bool status = trpgPrintArchive(&archive,pBuff,flags); + return status; } #endif bool trpgPrintArchive(trpgr_Archive *archive,trpgPrintBuffer &pBuf,int flags) { - char ls[1024]; + char ls[1024]; - if (!archive->isValid()) return false; - - pBuf.prnLine("====Header Structures===="); + if (!archive->isValid()) return false; + + pBuf.prnLine("====Header Structures===="); - // Print out the header portion - archive->GetHeader()->Print(pBuf); - archive->GetMaterialTable()->Print(pBuf); - archive->GetTexTable()->Print(pBuf); - archive->GetModelTable()->Print(pBuf); - archive->GetTileTable()->Print(pBuf); - archive->GetLightTable()->Print(pBuf); - archive->GetRangeTable()->Print(pBuf); - pBuf.prnLine(); + // Print out the header portion + archive->GetHeader()->Print(pBuf); + archive->GetMaterialTable()->Print(pBuf); + archive->GetTexTable()->Print(pBuf); + archive->GetModelTable()->Print(pBuf); + archive->GetTileTable()->Print(pBuf); + archive->GetLightTable()->Print(pBuf); + archive->GetRangeTable()->Print(pBuf); + archive->GetTextStyleTable()->Print(pBuf); + archive->GetSupportStyleTable()->Print(pBuf); + archive->GetLabelPropertyTable()->Print(pBuf); + pBuf.prnLine(); - // Now do the tiles - if (!archive->isValid()) return false; + // Read the local images and do the math for the templates - // Parser that prints out a tile scene graph - trpgPrintGraphParser parser(&pBuf); + // Now do the tiles + if (!archive->isValid()) return false; - pBuf.prnLine("====Tile Data===="); - int nl,x,y; - trpgMemReadBuffer buf(archive->GetEndian()); - // Iterate over the terrain lods - int numLod; - archive->GetHeader()->GetNumLods(numLod); - trpg2iPoint tileSize; - for (nl=0;nlGetHeader()->GetLodSize(nl,tileSize); - // Iterate over the tiles - for (x=tileSize.x-1;x>=0;x--) - for (y=0;yReadTile(x,y,nl,buf)) { - if (flags & TRPGPRN_BODY) { - pBuf.IncreaseIndent(); - // Parse it (also prints it - parser.Parse(buf); - pBuf.DecreaseIndent(); - } - } else - pBuf.prnLine(" Couldn't read tile."); - } - } + // Parser that prints out a tile scene graph + trpgrImageHelper imageHelp(archive->GetEndian(),archive->getDir(),*archive->GetMaterialTable(), + *archive->GetTexTable()); + trpgPrintGraphParser parser(archive,&imageHelp,&pBuf); - return true; + pBuf.prnLine("====Tile Data===="); + int nl,x,y; + trpgMemReadBuffer buf(archive->GetEndian()); + // Iterate over the terrain lods + int numLod; + archive->GetHeader()->GetNumLods(numLod); + trpg2iPoint tileSize; + for (nl=0;nlGetHeader()->GetLodSize(nl,tileSize); + // Iterate over the tiles + for (x=tileSize.x-1;x>=0;x--) + for (y=0;yReadTile(x,y,nl,buf)) { + if (flags & TRPGPRN_BODY) { + pBuf.IncreaseIndent(); + // Parse it (also prints it + parser.Parse(buf); + pBuf.DecreaseIndent(); + } + } else + pBuf.prnLine(" Couldn't read tile."); + } + } + + return true; } diff --git a/src/osgPlugins/txp/trpage_print.cpp b/src/osgPlugins/txp/trpage_print.cpp index 45f204d9b..73c7c8282 100644 --- a/src/osgPlugins/txp/trpage_print.cpp +++ b/src/osgPlugins/txp/trpage_print.cpp @@ -18,92 +18,92 @@ #include /* trpage_print.cpp - Print out the contents of a TerraPage archive. - This module provides an example of how to access each of the classes - within a TerraPage archive. + Print out the contents of a TerraPage archive. + This module provides an example of how to access each of the classes + within a TerraPage archive. */ -#include "trpage_print.h" +#include /* ****************************************** Print Buffer implementation The print buffer is a way to dump debugging data out - to a file (or console). You can make your own subclass - of trpgPrintBuffer if you have specific needs. + to a file (or console). You can make your own subclass + of trpgPrintBuffer if you have specific needs. ****************************************** */ trpgPrintBuffer::trpgPrintBuffer() { - curIndent = 0; - indentStr[0] = 0; + curIndent = 0; + indentStr[0] = 0; } // Increase the current indent void trpgPrintBuffer::IncreaseIndent(int amount) { - curIndent+=amount; - updateIndent(); + curIndent+=amount; + updateIndent(); } // Decrease the current indent void trpgPrintBuffer::DecreaseIndent(int amount) { - curIndent-=amount; - curIndent = MAX(0,curIndent); - updateIndent(); + curIndent-=amount; + curIndent = MAX(0,curIndent); + updateIndent(); } // Reprint the indent string void trpgPrintBuffer::updateIndent() { - int i; - for (i=0;i(this))->GetMaterialRef(j,i); - mat->Print(buf); - } - buf.DecreaseIndent(); - } - buf.DecreaseIndent(2); + char ls[1024]; + buf.prnLine("----Material Table----"); + buf.IncreaseIndent(); + sprintf(ls,"numTable = %d",numTable); buf.prnLine(ls); + sprintf(ls,"numMat = %d",numMat); buf.prnLine(ls); + buf.IncreaseIndent(); + for (int j=0;j(this))->GetMaterialRef(j,i); + mat->Print(buf); + } + buf.DecreaseIndent(); + } + buf.DecreaseIndent(2); - return true; + return true; } /* Print out texture. */ bool trpgTexture::Print(trpgPrintBuffer &buf) const { - char ls[1024]; + char ls[1024]; - buf.prnLine("----Texture----"); - buf.IncreaseIndent(); - sprintf(ls,"mode = %d, type = %d",mode,type); buf.prnLine(ls); - sprintf(ls,"Name = %s",name); buf.prnLine(ls); - sprintf(ls,"useCount = %d",useCount); buf.prnLine(ls); - sprintf(ls,"sizeX = %d, sizeY = %d",sizeX,sizeY); buf.prnLine(ls); - sprintf(ls,"ismipmap = %d",isMipmap); buf.prnLine(ls); - sprintf(ls,"addr.file = %d, addr.offset = %d",addr.file,addr.offset); buf.prnLine(ls); - buf.DecreaseIndent(); + buf.prnLine("----Texture----"); + buf.IncreaseIndent(); + sprintf(ls,"mode = %d, type = %d",mode,type); buf.prnLine(ls); + sprintf(ls,"Name = %s",name); buf.prnLine(ls); + sprintf(ls,"useCount = %d",useCount); buf.prnLine(ls); + sprintf(ls,"sizeX = %d, sizeY = %d, sizeZ = %d",sizeX,sizeY,numLayer); buf.prnLine(ls); + sprintf(ls,"sensor band organization = %d",org); buf.prnLine(ls); + sprintf(ls,"ismipmap = %d",isMipmap); buf.prnLine(ls); + sprintf(ls,"addr.file = %d, addr.offset = %d",addr.file,addr.offset); buf.prnLine(ls); + buf.DecreaseIndent(); - buf.prnLine(); + buf.prnLine(); - return true; + return true; } /* Print out texture table */ bool trpgTexTable::Print(trpgPrintBuffer &buf) const { - char ls[1024]; + char ls[1024]; - buf.prnLine("----Texture Table----"); - buf.IncreaseIndent(); - for (unsigned int i=0;i (ex,ey) = (%d,%d) -> (%d,%d)",sx,sy,ex,ey); buf.prnLine(ls); - sprintf(ls,"dest (width,height) = (%d,%d)",destWidth,destHeight); buf.prnLine(ls); - sprintf(ls,"addr (file,offset) = (%d,%d)",addr.file,addr.offset); buf.prnLine(ls); - buf.DecreaseIndent(); - buf.prnLine(); + buf.prnLine("----Local Material Definition----"); + buf.IncreaseIndent(); + sprintf(ls,"baseMat = %d",baseMat); buf.prnLine(ls); + sprintf(ls,"(sx,sy) -> (ex,ey) = (%d,%d) -> (%d,%d)",sx,sy,ex,ey); buf.prnLine(ls); + sprintf(ls,"dest (width,height) = (%d,%d)",destWidth,destHeight); buf.prnLine(ls); + for (int i=0;i /* Print Buffer for TerraPage. Subclasses of this object - are used to print out to stdout or disk (or whatever). - You won't create one of these directly, instead you'll create - something which inherits from it. + are used to print out to stdout or disk (or whatever). + You won't create one of these directly, instead you'll create + something which inherits from it. */ TX_EXDECL class TX_CLDECL trpgPrintBuffer { public: - trpgPrintBuffer(void); - virtual ~trpgPrintBuffer(void) { }; + trpgPrintBuffer(void); + virtual ~trpgPrintBuffer(void) { }; - // Check if print buffer is valid - virtual bool isValid(void) { return true; } + // Check if print buffer is valid + virtual bool isValid(void) { return true; } - // The main print function. Subclasses must fill this in. - virtual bool prnLine(char *str=NULL)=0; + // The main print function. Subclasses must fill this in. + virtual bool prnLine(char *str=NULL)=0; - // This increases the current indentation by the amount given (defaults to one) - virtual void IncreaseIndent(int amount=1); - // Decreases the current indentation by the amount given (defaults to one) - virtual void DecreaseIndent(int amount=1); + // This increases the current indentation by the amount given (defaults to one) + virtual void IncreaseIndent(int amount=1); + // Decreases the current indentation by the amount given (defaults to one) + virtual void DecreaseIndent(int amount=1); protected: - void updateIndent(void); - int curIndent; - char indentStr[200]; + void updateIndent(void); + int curIndent; + char indentStr[200]; }; /* File print buffer for TerraPage. The file print buffer writes - debugging output to a file. + debugging output to a file. */ TX_EXDECL class TX_CLDECL trpgFilePrintBuffer : public trpgPrintBuffer { public: - // This class can be constructed with either a FILE pointer or a file name - trpgFilePrintBuffer(FILE *); - trpgFilePrintBuffer(char *); - ~trpgFilePrintBuffer(void); + // This class can be constructed with either a FILE pointer or a file name + trpgFilePrintBuffer(FILE *); + trpgFilePrintBuffer(char *); + ~trpgFilePrintBuffer(void); - // Check if file print buffer is valid (i.e. if file was opened) - bool isValid(void) { return valid; }; + // Check if file print buffer is valid (i.e. if file was opened) + bool isValid(void) { return valid; }; - // For a file printer buffer, this writes a string out to a file - bool prnLine(char *str = NULL); + // For a file printer buffer, this writes a string out to a file + bool prnLine(char *str = NULL); protected: - bool valid; - bool isMine; - FILE *fp; + bool valid; + bool isMine; + FILE *fp; }; /* The Print Graph Parser is a scene graph parser that - prints out the scene graph as it goes. It's simpler - than the scene example in trpage_scene.cpp since it - isn't trying to build up a working scene graph. + prints out the scene graph as it goes. It's simpler + than the scene example in trpage_scene.cpp since it + isn't trying to build up a working scene graph. */ TX_EXDECL class TX_CLDECL trpgPrintGraphParser : public trpgSceneParser { public: - trpgPrintGraphParser(trpgPrintBuffer *); - virtual ~trpgPrintGraphParser(void) { }; + trpgPrintGraphParser(trpgr_Archive *,trpgrImageHelper *,trpgPrintBuffer *); + virtual ~trpgPrintGraphParser(void) { }; - /* The read helper class is the callback for all the various - token (node) types. Normally we would use a number of - these, probably one per token. However, since we're just - printing we can use a switch statement instead. - */ - class ReadHelper : public trpgr_Callback { - public: - ReadHelper(trpgPrintBuffer *inBuf) {pBuf = inBuf;}; - void *Parse(trpgToken,trpgReadBuffer &buf); - protected: - trpgPrintBuffer *pBuf; - }; - + /* The read helper class is the callback for all the various + token (node) types. Normally we would use a number of + these, probably one per token. However, since we're just + printing we can use a switch statement instead. + */ + class ReadHelper : public trpgr_Callback { + public: + ReadHelper(trpgPrintGraphParser *inPG,trpgPrintBuffer *inBuf) {pBuf = inBuf; parse = inPG;}; + void *Parse(trpgToken,trpgReadBuffer &buf); + protected: + trpgPrintBuffer *pBuf; + trpgPrintGraphParser *parse; + }; + + // Fetch the archive associated with this print + trpgr_Archive *GetArchive() {return archive; }; + trpgrImageHelper *GetImageHelp() {return imageHelp; }; + protected: - bool StartChildren(void *); - bool EndChildren(void *); + bool StartChildren(void *); + bool EndChildren(void *); - trpgPrintBuffer *printBuf; + trpgPrintBuffer *printBuf; + trpgr_Archive *archive; + trpgrImageHelper *imageHelp; }; // Print utitility for while archive diff --git a/src/osgPlugins/txp/trpage_range.cpp b/src/osgPlugins/txp/trpage_range.cpp index 9ee86a58d..94f5cf7df 100644 --- a/src/osgPlugins/txp/trpage_range.cpp +++ b/src/osgPlugins/txp/trpage_range.cpp @@ -14,290 +14,301 @@ */ /* trpage_range.cpp - Methods for the Range Table. Consult trpg_geom.h for details - on what this is and how it works. - */ + Methods for the Range Table. Consult trpg_geom.h for details + on what this is and how it works. + */ #include #include #include -#include "trpage_geom.h" -#include "trpage_read.h" +#include +#include /* ******************* - Range Methods + Range Methods ******************* */ trpgRange::trpgRange(void) { - category = NULL; - subCategory = NULL; - Reset(); + category = NULL; + subCategory = NULL; + Reset(); } trpgRange::~trpgRange(void) { - Reset(); + Reset(); } -trpgRange::trpgRange(const trpgRange &in):trpgReadWriteable() +trpgRange::trpgRange(const trpgRange &in) { - *this = in; + category = NULL; + subCategory = NULL; + *this = in; } void trpgRange::Reset(void) { - if (category) - delete [] category; - category = NULL; - if (subCategory) - delete [] subCategory; - subCategory = NULL; + errMess[0] = '\0'; + if (category) + delete [] category; + category = NULL; + if (subCategory) + delete [] subCategory; + subCategory = NULL; - inLod = outLod = 0.0; - priority = 0; + inLod = outLod = 0.0; + priority = 0; } -void trpgRange::SetCategory(char *cat,char *subCat) +void trpgRange::SetCategory(const char *cat,const char *subCat) { - if (category) delete [] category; - category = NULL; - if (cat) { - category = new char[strlen(cat)+1]; - strcpy(category,cat); - } + if (category) delete [] category; + category = NULL; + if (cat) { + category = new char[strlen(cat)+1]; + strcpy(category,cat); + } - if (subCategory) delete [] subCategory; - subCategory = NULL; - if (subCat) { - subCategory = new char[strlen(subCat)+1]; - strcpy(subCategory,subCat); - } + if (subCategory) delete [] subCategory; + subCategory = NULL; + if (subCat) { + subCategory = new char[strlen(subCat)+1]; + strcpy(subCategory,subCat); + } } void trpgRange::GetCategory(char *cat,int catLen,char *subCat,int subCatLen) const { - if (category && cat) { - strncpy(cat,category,catLen); - } else - *cat = 0; - if (subCategory && subCat) { - strncpy(subCat,subCategory,subCatLen); - } else - *subCat = 0; + if (category && cat) { + strncpy(cat,category,catLen); + } else + *cat = 0; + if (subCategory && subCat) { + strncpy(subCat,subCategory,subCatLen); + } else + *subCat = 0; } void trpgRange::SetLodInfo(double in,double out) { - inLod = in; - outLod = out; + inLod = in; + outLod = out; } void trpgRange::GetLodInfo(double &in,double &out) const { - in = inLod; - out = outLod; + in = inLod; + out = outLod; } void trpgRange::SetPriority(int prior) { - priority = prior; + priority = prior; } void trpgRange::GetPriority(int &prior) const { - prior = priority; + prior = priority; } trpgRange & trpgRange::operator = (const trpgRange &other) { - Reset(); - inLod = other.inLod; - outLod = other.outLod; - SetCategory(other.category,other.subCategory); - priority = other.priority; + Reset(); + inLod = other.inLod; + outLod = other.outLod; + SetCategory(other.category,other.subCategory); + priority = other.priority; - return *this; + return *this; } bool trpgRange::operator == (const trpgRange &in) const { - if (inLod != in.inLod || outLod != in.outLod) - return false; - if (priority != in.priority) return false; + if (inLod != in.inLod || outLod != in.outLod) + return false; + if (priority != in.priority) return false; - if (category && in.category) { - if (strcmp(category,in.category)) - return false; - } else { - if (category && !in.category || - !category && in.category) - return false; - } + if (category && in.category) { + if (strcmp(category,in.category)) + return false; + } else { + if (category && !in.category || + !category && in.category) + return false; + } - if (subCategory && in.subCategory) { - if (strcmp(subCategory,in.subCategory)) - return false; - } else { - if (subCategory && !in.subCategory || - !subCategory && in.subCategory) - return false; - } + if (subCategory && in.subCategory) { + if (strcmp(subCategory,in.subCategory)) + return false; + } else { + if (subCategory && !in.subCategory || + !subCategory && in.subCategory) + return false; + } - return true; + return true; } bool trpgRange::Write(trpgWriteBuffer &buf) { - buf.Begin(TRPG_RANGE); - buf.Add(inLod); - buf.Add(outLod); - buf.Add(priority); - buf.Add((category ? category : "")); - buf.Add((subCategory ? subCategory : "")); - buf.End(); + buf.Begin(TRPG_RANGE); + buf.Add(inLod); + buf.Add(outLod); + buf.Add(priority); + buf.Add((category ? category : "")); + buf.Add((subCategory ? subCategory : "")); + buf.End(); - return true; + return true; } bool trpgRange::Read(trpgReadBuffer &buf) { - char catStr[1024],subStr[1024]; + char catStr[1024],subStr[1024]; - Reset(); - valid = false; + Reset(); + valid = false; - try { - buf.Get(inLod); - buf.Get(outLod); - buf.Get(priority); - buf.Get(catStr,1024); - buf.Get(subStr,1024); - SetCategory(catStr,subStr); - valid = true; - } + try { + buf.Get(inLod); + buf.Get(outLod); + buf.Get(priority); + buf.Get(catStr,1024); + buf.Get(subStr,1024); + SetCategory(catStr,subStr); + valid = true; + } - catch (...) { - return false; - } + catch (...) { + return false; + } - return isValid(); + return isValid(); } /* *************** - Range Table methods - *************** + Range Table methods + *************** */ trpgRangeTable::trpgRangeTable(void) { - valid = true; + valid = true; } trpgRangeTable::~trpgRangeTable(void) { - // vector cleans up itself + // vector cleans up itself } void trpgRangeTable::Reset(void) { - rangeList.resize(0); - valid = true; + rangeList.resize(0); + valid = true; } bool trpgRangeTable::GetRange(int id,trpgRange &ret) const { - if (!isValid()) - return false; + if (!isValid()) + return false; - if (id < 0 || id >= static_cast(rangeList.size())) - return false; + if (id < 0 || id >= rangeList.size()) + return false; - ret = rangeList[id]; + ret = rangeList[id]; - return true; + return true; } bool trpgRangeTable::SetRange(int id,trpgRange &inRange) { - if (!isValid()) - return false; + if (!isValid()) + return false; - if (id < 0 || id >= static_cast(rangeList.size())) - return false; + if (id < 0 || id >= rangeList.size()) + return false; - rangeList[id] = inRange; + rangeList[id] = inRange; - return true; + return true; } int trpgRangeTable::AddRange(trpgRange &range) { - rangeList.push_back(range); + rangeList.push_back(range); - return rangeList.size()-1; + return rangeList.size()-1; } int trpgRangeTable::FindAddRange(trpgRange &range) { - for (unsigned int i=0;i /* 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" +#include +#include // Constructor trpgr_Archive::trpgr_Archive() { - fp = NULL; - ness = LittleEndian; - strcpy(dir,"."); - tileCache = NULL; + fp = NULL; + ness = LittleEndian; + strcpy(dir,"."); + tileCache = NULL; } // Destructor trpgr_Archive::~trpgr_Archive() { - if (fp) - fclose(fp); - fp = NULL; - if (tileCache) - delete tileCache; + 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" PATHSEPARATOR "%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 (tileCache) - delete tileCache; - tileCache = 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; - // 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; + headerRead = true; - // Read in the header whole - trpgMemReadBuffer buf(ness); - buf.SetLength(headLen); - char *data = buf.GetDataPtr(); - if (fread(data,1,headLen,fp) != static_cast(headLen)) 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; - // 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 + // 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; - // Don't read the tile table for v1.0 archives - // It's only really used for 2.0 archives - parser.AddCallback(TRPGTILETABLE2,&tileTable); + // 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 + parser.AddCallback(TRPG_TEXT_STYLE_TABLE,&textStyleTable); // Added for 2.1 + parser.AddCallback(TRPG_SUPPORT_STYLE_TABLE,&supportStyleTable); + parser.AddCallback(TRPG_LABEL_PROPERTY_TABLE,&labelPropertyTable); + // Don't read the tile table for v1.0 archives + // It's only really used for 2.0 archives + parser.AddCallback(TRPGTILETABLE2,&tileTable); - // Parse the buffer - if (!parser.Parse(buf)) - return false; + // Parse the buffer + if (!parser.Parse(buf)) + return false; - // 1.0 Compatibility - // If we see an older style material table, convert it to the new style - // This isn't terribly memory efficient, but it does work - if (oldMatTable.isValid()) - materialTable = oldMatTable; - if (oldTexTable.isValid()) - texTable = oldTexTable; + // 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; - // 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" PATHSEPARATOR "tileFile",dir); - tileCache = new trpgrAppFileCache(fullBase,"tpf"); - } + // 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; + valid = true; - return 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 >= static_cast(numLods)) return false; - trpg2iPoint lodSize; - header.GetLodSize(lod,lodSize); - if (x >= static_cast(lodSize.x) || y >= static_cast(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; - trpgTileTable::TileMode tileMode; - tileTable.GetMode(tileMode); + trpgTileTable::TileMode tileMode; + tileTable.GetMode(tileMode); - if (tileMode == trpgTileTable::External) { - // Figure out the file name - // Note: This assumes External tiles - char filename[1024]; - sprintf(filename,"%s" PATHSEPARATOR "tile_%d_%d_%d.tpt",dir,x,y,lod); + if (tileMode == trpgTileTable::External) { + // Figure out the file name + // Note: This assumes External tiles + char filename[1024]; + sprintf(filename,"%s" PATHSEPERATOR "tile_%d_%d_%d.tpt",dir,x,y,lod); - // Open the file and read the contents - FILE *fp=NULL; - try { - if (!(fp = fopen(filename,"rb"))) throw 1; - // Find the file end - if (fseek(fp,0,SEEK_END)) throw 1; - // Note: This means tile is capped at 2 gigs - long pos = ftell(fp); - if (fseek(fp,0,SEEK_SET)) throw 1; - // Now we know the size. Read the whole file - buf.SetLength(pos); - char *data = buf.GetDataPtr(); - if (fread(data,pos,1,fp) != 1) throw 1; - fclose(fp); fp = NULL; - } - catch (...) { - if (fp) - fclose(fp); - return false; - } - } 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; + // 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 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; - } + // Fetch the tile + if (!tf->Read(&buf,addr.offset)) + return false; + } - return true; + 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; + return &lightTable; } const trpgRangeTable *trpgr_Archive::GetRangeTable() const { - return &rangeTable; + return &rangeTable; +} +const trpgTextStyleTable *trpgr_Archive::GetTextStyleTable() const +{ + return &textStyleTable; +} +const trpgSupportStyleTable *trpgr_Archive::GetSupportStyleTable() const +{ + return &supportStyleTable; +} +const trpgLabelPropertyTable *trpgr_Archive::GetLabelPropertyTable() const +{ + return &labelPropertyTable; } trpgEndian trpgr_Archive::GetEndian() const { - return ness; + return ness; } // Utility MBR routine 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 >= static_cast(maxXY.x) || y>= static_cast(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); - // 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; + // 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; + return true; } /* ***************** @@ -303,185 +319,209 @@ bool trpgr_Archive::trpgGetTileMBR(uint32 x,uint32 y,uint32 lod,trpg3dPoint &ll, */ trpgrImageHelper::trpgrImageHelper(trpgEndian inNess,char *inDir, - const trpgMatTable &inMatTable,const trpgTexTable &inTexTable) + const trpgMatTable &inMatTable,const trpgTexTable &inTexTable) { - ness = inNess; - strcpy(dir,inDir); - matTable = &inMatTable; - texTable = &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" PATHSEPARATOR "texFile",dir); - texCache = new trpgrAppFileCache(fullBase,"txf"); + // 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; + 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; + // 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; + // 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,0,size)) + return false; - return true; + return true; } bool trpgrImageHelper::GetMipLevelLocalGL(int miplevel, const trpgTexture *tex,char *data,int32 dataSize) { - if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 ) - return false; + 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; + // 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; + // Fetch data data + trpgwAppAddress addr; + tex->GetImageAddr(addr); + trpgrAppFile *af = texCache->GetFile(ness,addr.file); + if (!af) + return false; - int level_offset = (const_cast(tex))->MipLevelOffset(miplevel); - if (!af->Read(data,addr.offset+level_offset,dataSize)) - return false; + int level_offset = (const_cast(tex))->MipLevelOffset(miplevel); + if (!af->Read(data,addr.offset,level_offset,dataSize)) + return false; - return true; + return true; } bool trpgrImageHelper::GetImageInfoForLocalMat(const trpgLocalMaterial *locMat, - const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize) + const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize) { - // Get the base material for the Local Material - int32 matSubTable,matID; - locMat->GetBaseMaterial(matSubTable,matID); - const trpgMaterial *mat = matTable->GetMaterialRef(matSubTable,matID); - if (!mat) return false; + return GetNthImageInfoForLocalMat(locMat, 0, retMat, retTex, totSize); +} - // 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; +bool trpgrImageHelper::GetNthImageInfoForLocalMat(const trpgLocalMaterial *locMat, int index, + const trpgMaterial **retMat,const trpgTexture **retTex,int &totSize) +{ + // Get the base material for the Local Material + int32 matSubTable,matID; + locMat->GetBaseMaterial(matSubTable,matID); + // For right now, force the subtable number to match the index. + // Eventually, either store multiple base materials for each local material, + // or overhaul this in some other fashion. + int numTables; + if (!matTable->GetNumTable(numTables)) return false; + if (index>=numTables) return false; + if (index>0) matSubTable=index; // otherwise, leave it alone - could be nonzero + const trpgMaterial *mat = matTable->GetMaterialRef(matSubTable,matID); + if (!mat) return false; - totSize = tex->CalcTotalSize(); + // 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; - *retTex = tex; - *retMat = mat; - return true; + totSize = tex->CalcTotalSize(); + + *retTex = tex; + *retMat = mat; + return true; } bool trpgrImageHelper::GetImageForLocalMat(const trpgLocalMaterial *locMat,char *data,int dataSize) { - if (!locMat->isValid()) return false; + return GetNthImageForLocalMat(locMat, 0, data, dataSize); +} - const trpgMaterial *mat; - const trpgTexture *tex; - int totSize; - if (!GetImageInfoForLocalMat(locMat,&mat,&tex,totSize)) - return false; +bool trpgrImageHelper::GetNthImageForLocalMat(const trpgLocalMaterial *locMat,int index, char *data,int dataSize) +{ + if (!locMat->isValid()) 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; - }; + const trpgMaterial *mat; + const trpgTexture *tex; + int totSize; + if (!GetNthImageInfoForLocalMat(locMat,index,&mat,&tex,totSize)) + return false; - return true; + // Determine the type + trpgTexture::ImageMode imageMode; + tex->GetImageMode(imageMode); + switch (imageMode) { + case trpgTexture::Template: + { + // Read the image data out of the Local image (in an archive somewhere) + trpgwAppAddress addr; + if (!locMat->GetNthAddr(index,addr)) return false; + trpgrAppFile *af = texCache->GetFile(ness,addr.file); + if (!af) return false; + if (!af->Read(data,addr.offset,0,dataSize)) + return false; + } + break; + 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; + return GetNthImageMipLevelForLocalMat(miplevel, locMat, 0, data, dataSize); +} - const trpgMaterial *mat; - const trpgTexture *tex; - int totSize; - if (!GetImageInfoForLocalMat(locMat,&mat,&tex,totSize)) - return false; +bool trpgrImageHelper::GetNthImageMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat, int index, char *data,int dataSize) +{ + if (index>0) return false; // not yet, folks, if ever. index>1 means sensors for now. + if (!locMat->isValid()) return false; - if ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 ) - return false; + const trpgMaterial *mat; + const trpgTexture *tex; + int totSize; + if (!GetNthImageInfoForLocalMat(locMat,index,&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 ( miplevel >= tex->CalcNumMipmaps() || miplevel < 0 ) + return false; - int level_offset = (const_cast(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; - }; + // Determine the type + trpgTexture::ImageMode imageMode; + tex->GetImageMode(imageMode); + switch (imageMode) { + case trpgTexture::Template: + { + // Read the image data out of the Local image (in an archive somewhere) + trpgwAppAddress addr; + if (!locMat->GetNthAddr(index,addr)) return false; + trpgrAppFile *af = texCache->GetFile(ness,addr.file); + if (!af) return false; - return true; + int level_offset = (const_cast(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); + char name[1024]; + int nameLen=1024; + tex->GetName(name,nameLen); + nameLen = strlen(name); - if (strlen(dir) + nameLen + 2 > static_cast(pathLen)) - return false; + if (strlen(dir) + nameLen + 2 > pathLen) + return false; - sprintf(fullPath,"%s" PATHSEPARATOR "%s",dir,name); + sprintf(fullPath,"%s" PATHSEPERATOR "%s",dir,name); - return true; + return true; } diff --git a/src/osgPlugins/txp/trpage_read.h b/src/osgPlugins/txp/trpage_read.h index dcf7f69c8..fdec1a657 100644 --- a/src/osgPlugins/txp/trpage_read.h +++ b/src/osgPlugins/txp/trpage_read.h @@ -18,201 +18,221 @@ #define _txpage_read_h_ /* txpage_read.h - Classes used to represent read objects for paging files. - */ + Classes used to represent read objects for paging files. + */ -#include "trpage_sys.h" +#include -#include "trpage_geom.h" +#include /* Callback base class - Called when a given token is found. - {group:Archive Reading} - */ + Called when a given token is found. + {group:Archive Reading} + */ TX_EXDECL class TX_CLDECL trpgr_Callback { public: - virtual ~trpgr_Callback(void) { }; - virtual void *Parse(trpgToken,trpgReadBuffer &) { return (void *)1; }; + virtual ~trpgr_Callback(void) { }; + virtual void *Parse(trpgToken,trpgReadBuffer &) { return (void *)1; }; }; /* Paging Token - Stores callback info associated with a given token. - {group:Archive Reading} - */ + Stores callback info associated with a given token. + {group:Archive Reading} + */ TX_EXDECL class TX_CLDECL trpgr_Token { public: - trpgr_Token(void); - trpgr_Token(int,trpgr_Callback *,bool destroy=true); - ~trpgr_Token(void); - void init(int,trpgr_Callback *,bool destroy=true); - int Token; // Constant token value - trpgr_Callback *cb; // Callback when we hit this token - bool destroy; // Should we call delete on the callback or not - void Destruct(void); // Not quite like delete + trpgr_Token(void); + trpgr_Token(int,trpgr_Callback *,bool destroy=true); + ~trpgr_Token(void); + void init(int,trpgr_Callback *,bool destroy=true); + int Token; // Constant token value + trpgr_Callback *cb; // Callback when we hit this token + bool destroy; // Should we call delete on the callback or not + void Destruct(void); // Not quite like delete }; /* Parse class for paging data structures. - This executes callbacks - {group:Archive Reading} - */ + This executes callbacks + {group:Archive Reading} + */ TX_EXDECL class TX_CLDECL trpgr_Parser { public: - trpgr_Parser(void); - virtual ~trpgr_Parser(void); - bool isValid(void) const; + trpgr_Parser(void); + virtual ~trpgr_Parser(void); + bool isValid(void) const; - // Add and remove token callbacks - virtual void AddCallback(trpgToken,trpgr_Callback *,bool destroy = true); - virtual void AddCallback(trpgToken,trpgReadWriteable *); - virtual void RemoveCallback(trpgToken); - virtual void SetDefaultCallback(trpgr_Callback *,bool destroy = true); - // Parse a read buffer - virtual bool Parse(trpgReadBuffer &); - virtual bool TokenIsValid(trpgToken); // Check token validity + // Add and remove token callbacks + virtual void AddCallback(trpgToken,trpgr_Callback *,bool destroy = true); + virtual void AddCallback(trpgToken,trpgReadWriteable *); + virtual void RemoveCallback(trpgToken); + virtual void SetDefaultCallback(trpgr_Callback *,bool destroy = true); + // Parse a read buffer + virtual bool Parse(trpgReadBuffer &); + virtual bool TokenIsValid(trpgToken); // Check token validity protected: - void *lastObject; + void *lastObject; 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(__CYGWIN__) - typedef std::map tok_map; + // Note: Just how slow is a map<> anyway? + // This usage is self-contained and could be replaced with an array +#if defined(_WIN32) + typedef std::map tok_map; #else - typedef std::map > tok_map; + typedef std::map > tok_map; #endif - tok_map tokenMap; - trpgr_Token defCb; // Call this when no others are called + 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. + 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); + 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 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); + /* 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); + /* 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 above, but gets info for nth image associated with this local material + */ + virtual bool GetNthImageInfoForLocalMat(const trpgLocalMaterial *locMat, int index, + const trpgMaterial **retMat,const trpgTexture **retTex, + int &totSize); - /* Same as the one above, just fetch single mip levels - */ - virtual bool GetMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat,char *data,int dataSize); + /* 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); - /* 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); + /* Same as above, but gets nth image associated with this local material + */ + virtual bool GetNthImageForLocalMat(const trpgLocalMaterial *locMat, int index, char *data,int dataSize); + + /* Same as the one above, just fetch single mip levels + */ + virtual bool GetMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat,char *data,int dataSize); + + /* Get mip levels for one of multiple images + */ + virtual bool GetNthImageMipLevelForLocalMat(int miplevel, const trpgLocalMaterial *locMat, int index, char *data,int dataSize); + + /* Determine the full path of the image in the given + trpgTexture class. + 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; + char dir[1024]; + trpgEndian ness; + const trpgMatTable *matTable; + const trpgTexTable *texTable; - trpgrAppFileCache *texCache; + trpgrAppFileCache *texCache; }; /* Paging Archive (read version) - This just reads the first bits of the file (and the header) - and lets you parse from there. - {group:Archive Reading} - */ + This just reads the first bits of the file (and the header) + and lets you parse from there. + {group:Archive Reading} + */ TX_EXDECL class TX_CLDECL trpgr_Archive : public trpgCheckable { public: - trpgr_Archive(void); - virtual ~trpgr_Archive(void); + trpgr_Archive(void); + virtual ~trpgr_Archive(void); - virtual void SetDirectory(const char *); - virtual bool OpenFile(const char *); // Open File - virtual void CloseFile(void); - virtual bool ReadHeader(void); // Read header (materials, tile table. etc..) - virtual bool ReadTile(uint32 x, uint32 y, uint32 lod,trpgMemReadBuffer &); + virtual void SetDirectory(const char *); + virtual bool OpenFile(const char *); // Open File + virtual void CloseFile(void); + virtual bool ReadHeader(void); // Read header (materials, tile table. etc..) + virtual bool ReadTile(uint32 x, uint32 y, uint32 lod,trpgMemReadBuffer &); - // Get access to header info - virtual const trpgHeader *GetHeader(void) const; - virtual const trpgMatTable *GetMaterialTable(void) const; - 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; + // Get access to header info + virtual const trpgHeader *GetHeader(void) const; + virtual const trpgMatTable *GetMaterialTable(void) const; + 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; + virtual const trpgLabelPropertyTable *GetLabelPropertyTable() const; + virtual const trpgTextStyleTable *GetTextStyleTable() const; + virtual const trpgSupportStyleTable *GetSupportStyleTable() const; - // Utility routine to calculate the MBR of a given tile - virtual bool trpgGetTileMBR(uint32 x,uint32 y,uint32 lod, - trpg3dPoint &ll,trpg3dPoint &ur) const; + // Utility routine to calculate the MBR of a given tile + virtual bool trpgGetTileMBR(uint32 x,uint32 y,uint32 lod, + trpg3dPoint &ll,trpg3dPoint &ur) const; - trpgEndian GetEndian(void) const; - char* getDir(void){return dir;}; + trpgEndian GetEndian(void) const; + char* getDir(void){return dir;}; protected: - bool headerRead; - trpgEndian ness; - FILE *fp; - int fid; - // Header info - char dir[1024]; - trpgHeader header; - trpgMatTable materialTable; - trpgTexTable texTable; - trpgModelTable modelTable; - trpgTileTable tileTable; - trpgLightTable lightTable; - trpgRangeTable rangeTable; + bool headerRead; + trpgEndian ness; + FILE *fp; + int fid; + // Header info + char dir[1024]; + trpgHeader header; + trpgMatTable materialTable; + trpgTexTable texTable; + trpgModelTable modelTable; + trpgTileTable tileTable; + trpgLightTable lightTable; + trpgRangeTable rangeTable; + trpgTextStyleTable textStyleTable; + trpgSupportStyleTable supportStyleTable; + trpgLabelPropertyTable labelPropertyTable; - trpgrAppFileCache *tileCache; + trpgrAppFileCache *tileCache; }; class trpgSceneHelperPush; class trpgSceneHelperPop; class trpgSceneHelperDefault; /* Scene Parser - This class assists in parsing a scene graph structure (tiles and models). - To use it, do an archive ReadTile and pass the resulting Read Buffer to this - parser. - {group:Archive Reading} - */ + This class assists in parsing a scene graph structure (tiles and models). + To use it, do an archive ReadTile and pass the resulting Read Buffer to this + parser. + {group:Archive Reading} + */ TX_EXDECL class TX_CLDECL trpgSceneParser : public trpgr_Parser { - friend class trpgSceneHelperPush; - friend class trpgSceneHelperPop; - friend class trpgSceneHelperDefault; + friend class trpgSceneHelperPush; + friend class trpgSceneHelperPop; + friend class trpgSceneHelperDefault; public: - trpgSceneParser(void); - virtual ~trpgSceneParser(void); + trpgSceneParser(void); + virtual ~trpgSceneParser(void); protected: - // Start defining children for the given object - virtual bool StartChildren(void *) { return true;}; - virtual bool EndChildren(void *) { return true;}; + // Start defining children for the given object + virtual bool StartChildren(void *) { return true;}; + virtual bool EndChildren(void *) { return true;}; - // List of objects whose children we're working on - std::vector parents; + // List of objects whose children we're working on + std::vector parents; }; #endif diff --git a/src/osgPlugins/txp/trpage_readbuf.cpp b/src/osgPlugins/txp/trpage_readbuf.cpp index 0308c6a03..5394b9d6a 100644 --- a/src/osgPlugins/txp/trpage_readbuf.cpp +++ b/src/osgPlugins/txp/trpage_readbuf.cpp @@ -18,18 +18,18 @@ #include /* 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" +#include +#include /* ********************** Read buffer base class functions @@ -39,243 +39,263 @@ // 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(std::string &str) +{ + int32 len; + + // Get the length first + if (!Get(len)) return false; + + if (len < 0) + return false; + // Note: Should fix this + char *tmpStr = new char[len+1]; + + // Read it + if (!GetData(tmpStr,len)) return false; + tmpStr[len] = 0; + + str = tmpStr; + + 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) +//#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 +//#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 0) - limits.resize(len-1); + if (len > 0) + limits.resize(len-1); } // Skip To Limit @@ -283,34 +303,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[i]) - return false; + for (int i=0;i 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= len) - return true; + if (pos >= len) + return true; - // Also test the limits - for (unsigned int i=0;i 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 @@ -432,185 +452,195 @@ bool trpgMemReadBuffer::Skip(int rlen) trpgrAppFile::trpgrAppFile(trpgEndian inNess,const char *fileName) { - valid = false; - ness = inNess; - cpuNess = trpg_cpu_byte_order(); + valid = false; + ness = inNess; + cpuNess = trpg_cpu_byte_order(); - if (!(fp = fopen(fileName,"rb"))) - return; + if (!(fp = fopen(fileName,"rb"))) + return; - valid = true; + valid = true; } trpgrAppFile::~trpgrAppFile() { - if (fp) - fclose(fp); + if (fp) + fclose(fp); - valid = false; + 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; + if (!valid) return false; - // Seek to the right location - if (fseek(fp,offset,SEEK_SET)) - 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; - } + // Read a length + int32 len; + if (fread(&len,sizeof(int32),1,fp) != 1) { + valid = false; + return false; + } - // Byteswap if necessary - if (ness != cpuNess) - len = trpg_byteswap_int(len); + // Byteswap if necessary + if (ness != cpuNess) + trpg_byteswap_int(len); - if (len < 0) { - valid = false; - return false; - } + if (len < 0) { + valid = false; + return false; + } - buf->SetLength(len); - char *data = buf->GetDataPtr(); - if (!data) { - valid = false; - return false; - } + buf->SetLength(len); + char *data = buf->GetDataPtr(); + if (!data) { + valid = false; + return false; + } - if (fread(data,sizeof(char),len,fp) != static_cast(len)) { - valid = false; - return false; - } + if (fread(data,sizeof(char),len,fp) != len) { + valid = false; + return false; + } - return true; + 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. + check the length against the size of the memory + passed into dataSize. */ -bool trpgrAppFile::Read(char *data,int32 offset,uint32 dataSize) +bool trpgrAppFile::Read(char *data,int32 baseOffset,int32 objOffset,int32 dataSize) { - if (!valid) return false; + if (!valid) return false; - // Seek to the right place - if (fseek(fp,offset,SEEK_SET)) { - valid = false; - return false; - } + // Seek to the right place + int result; + if ((result = fseek(fp,baseOffset,SEEK_SET))) { + valid = false; + return false; + } - // Read the length - int32 len; - if (fread(&len,sizeof(int32),1,fp) != 1) { - valid = false; - return false; - } + // Read the total object length + int32 len; + if (fread(&len,sizeof(int32),1,fp) != 1) { + valid = false; + return false; + } - // Byteswap if necessary - if (ness != cpuNess) - len = trpg_byteswap_int(len); + // 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 > static_cast(len)) - return false; + if (len < 0) { + valid = false; + return false; + } - // Read the raw data - // Note: What about byte swapping? - if (fread(data,sizeof(char),dataSize,fp) != dataSize) { - valid = false; - return false; - } + // It's all right to read less than the whole data block + if (objOffset+dataSize > len) + return false; - return true; + // Skip to the object offset + if (fseek(fp,objOffset,SEEK_CUR)) { + valid = false; + 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. + 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); + strcpy(baseName,inPre); + strcpy(ext,inExt); - files.resize(noFiles); - timeCount = 0; + files.resize(noFiles); + timeCount = 0; } trpgrAppFileCache::~trpgrAppFileCache() { - for (unsigned int i=0;i /* 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 +#include /* **************** - 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= static_cast(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(&mbr); - trpgMBR kmbr; - // Ask the kids - for (unsigned int i=0;iGetMBR(); - cmbr->Union(kmbr); - } - return *cmbr; - } + if (mbr.isValid()) + return mbr; + else { + // Calculate and cache a new MBR + trpgMBR *cmbr = const_cast(&mbr); + trpgMBR kmbr; + // Ask the kids + for (int i=0;iGetMBR(); + 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(&mbr); + trpgMBR *pmbr = const_cast(&mbr); - int numVert,i; - trpg3dPoint pt; - data.GetNumVertex(numVert); - numVert /= 3; - for (i=0;iAddPoint(pt); - } + int numVert,i; + trpg3dPoint pt; + data.GetNumVertex(numVert); + numVert /= 3; + for (i=0;iAddPoint(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,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,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,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,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,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,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,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,19 +468,19 @@ trpgReadNode *trpgSceneGraphParser::ParseScene(trpgReadBuffer &buf,GroupMap &inG // We'll want to make the node it's handing us the "top" node bool trpgSceneGraphParser::StartChildren(void *in_node) { - trpgReadNode *node = (trpgReadNode *)in_node; + trpgReadNode *node = (trpgReadNode *)in_node; - if (!node || !node->isGroupType()) { - // Looks like there's a push in the wrong place - // Make the current "top" NULL. - // This will drop all node until we pop back above - currTop = NULL; - } else { - // This node is our new "top" - currTop = node; - } + if (!node || !node->isGroupType()) { + // Looks like there's a push in the wrong place + // Make the current "top" NULL. + // This will drop all node until we pop back above + currTop = NULL; + } else { + // This node is our new "top" + currTop = node; + } - return true; + return true; } /* This is called whent he parser hits a pop. @@ -489,67 +488,67 @@ bool trpgSceneGraphParser::StartChildren(void *in_node) for the parent above the current one. If there isn't one, we'll just stick things in our top group. */ -bool trpgSceneGraphParser::EndChildren(void *) +bool trpgSceneGraphParser::EndChildren(void *in_node) { - // We don't need it here, but this is the node we just - // finished putting children under. If you need to close - // it out in some way, do that here - //trpgReadNode *node = (trpgReadNode *)in_node; + // We don't need it here, but this is the node we just + // finished putting children under. If you need to close + // it out in some way, do that here + trpgReadNode *node = (trpgReadNode *)in_node; - // Get the parent above the current one - int pos = parents.size()-2; - if (pos < 0) - // Nothing above the current one. Fall back on our top group - currTop = top; - else - currTop = (trpgReadNode *)parents[pos]; + // Get the parent above the current one + int pos = parents.size()-2; + if (pos < 0) + // Nothing above the current one. Fall back on our top group + currTop = top; + else + currTop = (trpgReadNode *)parents[pos]; - return true; + return true; } // Return group map (for use by helpers) trpgSceneGraphParser::GroupMap *trpgSceneGraphParser::GetGroupMap() { - return gmap; + return gmap; } /* *********** - Test functions - *********** - */ + Test functions + *********** + */ // Test all the tiles in an archive bool trpgTestArchive(trpgr_Archive &archive) { - int numLod; - trpg2iPoint tileSize; - trpgSceneGraphParser parse; - trpgReadNode *scene; - trpgSceneGraphParser::GroupMap gmap; + int numLod; + trpg2iPoint tileSize; + trpgSceneGraphParser parse; + trpgReadNode *scene; + trpgSceneGraphParser::GroupMap gmap; - if (!archive.isValid()) return false; + if (!archive.isValid()) return false; - const trpgHeader *head = archive.GetHeader(); - head->GetNumLods(numLod); + const trpgHeader *head = archive.GetHeader(); + head->GetNumLods(numLod); - // Iterate over the lods - int nl,x,y; - trpgMemReadBuffer buf(archive.GetEndian()); - trpg3dPoint ll,ur; - for (nl = 0;nl < numLod;nl++) { - head->GetLodSize(nl,tileSize); - // Iterate over the tiles within those - for (x = 0; x < tileSize.x; x++) - for (y = 0; y < tileSize.y; y++) { - archive.trpgGetTileMBR(x,y,nl,ll,ur); - if (archive.ReadTile(x,y,nl,buf)) { - // Parse it - scene = parse.ParseScene(buf,gmap); - if (scene) - delete scene; - } - } - } + // Iterate over the lods + int nl,x,y; + trpgMemReadBuffer buf(archive.GetEndian()); + trpg3dPoint ll,ur; + for (nl = 0;nl < numLod;nl++) { + head->GetLodSize(nl,tileSize); + // Iterate over the tiles within those + for (x = 0; x < tileSize.x; x++) + for (y = 0; y < tileSize.y; y++) { + archive.trpgGetTileMBR(x,y,nl,ll,ur); + if (archive.ReadTile(x,y,nl,buf)) { + // Parse it + scene = parse.ParseScene(buf,gmap); + if (scene) + delete scene; + } + } + } - return true; + return true; } diff --git a/src/osgPlugins/txp/trpage_scene.h b/src/osgPlugins/txp/trpage_scene.h index ae3015f34..8e41edc07 100644 --- a/src/osgPlugins/txp/trpage_scene.h +++ b/src/osgPlugins/txp/trpage_scene.h @@ -18,221 +18,221 @@ #define _txpage_scene_h_ /* trpage_scene.h - Scene Graph definition. - This is a small scene graph we use for testing. - It's not intended to replace the scene graph you may already be using. - You do not need to translate from this scene graph structure to your own, - at run-time. Instead, use this file and trpage_scene.cpp as a guideline - for how to read TerraPage format into your own scene graph. + Scene Graph definition. + This is a small scene graph we use for testing. + It's not intended to replace the scene graph you may already be using. + You do not need to translate from this scene graph structure to your own, + at run-time. Instead, use this file and trpage_scene.cpp as a guideline + for how to read TerraPage format into your own scene graph. */ -#include "trpage_geom.h" +#include /* - {group:Demonstration Scene Graph} - */ + {group:Demonstration Scene Graph} + */ TX_EXDECL class TX_CLDECL trpgMBR { public: - trpgMBR(void); - ~trpgMBR(void) { }; - bool isValid(void) const; - void Reset(void); - void AddPoint(const trpg3dPoint &); - void AddPoint(double,double,double); - void GetMBR(trpg3dPoint &ll,trpg3dPoint &ur) const; - trpg3dPoint GetLL(void) const; - trpg3dPoint GetUR(void) const; - void Union(const trpgMBR &); -// bool Overlap(const trpgMBR &) const; - bool Overlap(const trpg2dPoint &ll, const trpg2dPoint &ur) const; -// bool Within(const trpg3dPoint &) const - bool Within(const trpg2dPoint &) const; + trpgMBR(void); + ~trpgMBR(void) { }; + bool isValid(void) const; + void Reset(void); + void AddPoint(const trpg3dPoint &); + void AddPoint(double,double,double); + void GetMBR(trpg3dPoint &ll,trpg3dPoint &ur) const; + trpg3dPoint GetLL(void) const; + trpg3dPoint GetUR(void) const; + void Union(const trpgMBR &); +// bool Overlap(const trpgMBR &) const; + bool Overlap(const trpg2dPoint &ll, const trpg2dPoint &ur) const; +// bool Within(const trpg3dPoint &) const + bool Within(const trpg2dPoint &) const; protected: - inline bool inRange(double minv,double maxv,double val) const { return (val >= minv && val <= maxv); } - bool valid; - trpg3dPoint ll,ur; + inline bool inRange(double minv,double maxv,double val) const { return (val >= minv && val <= maxv); } + bool valid; + trpg3dPoint ll,ur; }; // Read Node // Simple Scenegraph node used for read testing -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadNode { public: - virtual ~trpgReadNode(void) { }; - virtual bool isGroupType(void) = 0; - virtual int GetType(void) { return type; } - virtual trpgMBR GetMBR(void) const { return trpgMBR(); } + virtual ~trpgReadNode(void) { }; + virtual bool isGroupType(void) = 0; + virtual int GetType(void) { return type; } + virtual trpgMBR GetMBR(void) const { return trpgMBR(); } protected: - int type; + int type; }; // Read Group Base // Base class for all group nodes -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadGroupBase : public trpgReadNode { public: - virtual ~trpgReadGroupBase(void); - void AddChild(trpgReadNode *); - bool isGroupType(void) { return true; } - int GetNumChildren(void) { return children.size(); } - trpgReadNode *GetChild(int i) { return children[i]; } - trpgMBR GetMBR(void) const; - void unRefChild(int i); - void unRefChildren(void); + virtual ~trpgReadGroupBase(void); + void AddChild(trpgReadNode *); + bool isGroupType(void) { return true; } + int GetNumChildren(void) { return children.size(); } + trpgReadNode *GetChild(int i) { return children[i]; } + trpgMBR GetMBR(void) const; + void unRefChild(int i); + void unRefChildren(void); protected: - trpgMBR mbr; - void DeleteChildren(void); - std::vector children; + trpgMBR mbr; + void DeleteChildren(void); + std::vector children; }; // Read Geometry // The leaf for this scene graph -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadGeometry : public trpgReadNode { public: - trpgReadGeometry(void) { type = TRPG_GEOMETRY; } - ~trpgReadGeometry(void) { }; - bool isGroupType(void) { return false; } - trpgGeometry *GetData(void) { return &data; } - trpgMBR GetMBR(void) const; + trpgReadGeometry(void) { type = TRPG_GEOMETRY; } + ~trpgReadGeometry(void) { }; + bool isGroupType(void) { return false; } + trpgGeometry *GetData(void) { return &data; } + trpgMBR GetMBR(void) const; protected: - trpgMBR mbr; - trpgGeometry data; + trpgMBR mbr; + trpgGeometry data; }; // Read Tile Header // One per tile. Info about what materials and models are used -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadTileHeader : public trpgReadNode { public: - trpgReadTileHeader(void) { type = TRPGTILEHEADER; } - ~trpgReadTileHeader(void) { }; - bool isGroupType(void) { return false; } - trpgTileHeader *GetData(void) { return &data; } - trpgMBR GetMBR(void) const { trpgMBR mbr; return mbr; }; + trpgReadTileHeader(void) { type = TRPGTILEHEADER; } + ~trpgReadTileHeader(void) { }; + bool isGroupType(void) { return false; } + trpgTileHeader *GetData(void) { return &data; } + trpgMBR GetMBR(void) const { trpgMBR mbr; return mbr; }; protected: - trpgTileHeader data; + trpgTileHeader data; }; // Read Group // Simple group structure -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadGroup : public trpgReadGroupBase { public: - trpgReadGroup(void) { type = TRPG_GROUP; } - ~trpgReadGroup(void) { }; - trpgGroup *GetData(void) { return &data; } + trpgReadGroup(void) { type = TRPG_GROUP; } + ~trpgReadGroup(void) { }; + trpgGroup *GetData(void) { return &data; } protected: - trpgGroup data; + trpgGroup data; }; // Read Attach // Should be the top of a higher LOD tile -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadAttach : public trpgReadGroupBase { public: - trpgReadAttach(void) { type = TRPG_ATTACH; } - ~trpgReadAttach(void) { }; - trpgAttach *GetData(void) { return &data; } + trpgReadAttach(void) { type = TRPG_ATTACH; } + ~trpgReadAttach(void) { }; + trpgAttach *GetData(void) { return &data; } protected: - trpgAttach data; + trpgAttach data; }; // Read billboard -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadBillboard : public trpgReadGroupBase { public: - trpgReadBillboard(void) { type = TRPG_BILLBOARD; } - ~trpgReadBillboard(void) { }; - trpgBillboard *GetData(void) { return &data; } + trpgReadBillboard(void) { type = TRPG_BILLBOARD; } + ~trpgReadBillboard(void) { }; + trpgBillboard *GetData(void) { return &data; } protected: - trpgBillboard data; + trpgBillboard data; }; // Read LOD -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadLod : public trpgReadGroupBase { public: - trpgReadLod(void) { type = TRPG_LOD; } - ~trpgReadLod(void) { }; - trpgLod *GetData(void) { return &data; } + trpgReadLod(void) { type = TRPG_LOD; } + ~trpgReadLod(void) { }; + trpgLod *GetData(void) { return &data; } protected: - trpgLod data; + trpgLod data; }; // Read Layer -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadLayer : public trpgReadGroupBase { public: - trpgReadLayer(void) { type = TRPG_LAYER; } - ~trpgReadLayer(void) { }; - trpgLayer *GetData(void) { return &data; } + trpgReadLayer(void) { type = TRPG_LAYER; } + ~trpgReadLayer(void) { }; + trpgLayer *GetData(void) { return &data; } protected: - trpgLayer data; + trpgLayer data; }; // Read Transform -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadTransform : public trpgReadGroupBase { public: - trpgReadTransform(void) { type = TRPG_TRANSFORM; } - ~trpgReadTransform(void) { }; - trpgTransform *GetData(void) { return &data; } + trpgReadTransform(void) { type = TRPG_TRANSFORM; } + ~trpgReadTransform(void) { }; + trpgTransform *GetData(void) { return &data; } protected: - trpgTransform data; + trpgTransform data; }; // Read Model Reference -// {group:Demonstration Scene Graph} +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgReadModelRef : public trpgReadGroupBase { public: - trpgReadModelRef(void) { type = TRPG_MODELREF; } - ~trpgReadModelRef(void) { }; - trpgModelRef *GetData(void) { return &data; } + trpgReadModelRef(void) { type = TRPG_MODELREF; } + ~trpgReadModelRef(void) { }; + trpgModelRef *GetData(void) { return &data; } protected: - trpgModelRef data; + trpgModelRef data; }; /* Scene Graph Parser - Parses a read buffer and returns a full scenegraph. - You don't want to use this if you're reading into your own scenegraph. - Instead, you'll want to sublcass trpgSceneParser, which is a helper - class to keep track of pushes and pops and implement the same functionality - that trpgSceneGraphParser has for your own scene graph. - */ -// {group:Demonstration Scene Graph} + Parses a read buffer and returns a full scenegraph. + You don't want to use this if you're reading into your own scenegraph. + Instead, you'll want to sublcass trpgSceneParser, which is a helper + class to keep track of pushes and pops and implement the same functionality + that trpgSceneGraphParser has for your own scene graph. + */ +// {group:Demonstration Scene Graph} TX_EXDECL class TX_CLDECL trpgSceneGraphParser : public trpgSceneParser { public: -#if defined(_WIN32) && !defined(__CYGWIN__) - typedef std::map GroupMap; +#if defined(_WIN32) + typedef std::map GroupMap; #else - typedef std::map > GroupMap; + typedef std::map > GroupMap; #endif - trpgSceneGraphParser(void); - virtual ~trpgSceneGraphParser(void) { }; - // Call this instead of Parse() - // Deleting it is your responsibility - trpgReadNode *ParseScene(trpgReadBuffer &,GroupMap &); - trpgReadGroupBase *GetCurrTop(void); // Get the current parent object - trpgReadTileHeader *GetTileHeaderRef(void); + trpgSceneGraphParser(void); + virtual ~trpgSceneGraphParser(void) { }; + // Call this instead of Parse() + // Deleting it is your responsibility + trpgReadNode *ParseScene(trpgReadBuffer &,GroupMap &); + trpgReadGroupBase *GetCurrTop(void); // Get the current parent object + trpgReadTileHeader *GetTileHeaderRef(void); - // For use by the helpers only - GroupMap *GetGroupMap(void); + // For use by the helpers only + GroupMap *GetGroupMap(void); protected: - bool StartChildren(void *); - bool EndChildren(void *); - trpgReadNode *currTop; // Current parent group - trpgReadNode *top; // Top of everything - GroupMap *gmap; - trpgReadTileHeader tileHead; // Tile header gets read into here + bool StartChildren(void *); + bool EndChildren(void *); + trpgReadNode *currTop; // Current parent group + trpgReadNode *top; // Top of everything + GroupMap *gmap; + trpgReadTileHeader tileHead; // Tile header gets read into here }; /* Test Archive - Utility function that loads and tests all tiles. - The only reason you'd want to call this is to test a TerraPage archive - you'd written. - */ -// {group:Demonstration Scene Graph} + Utility function that loads and tests all tiles. + The only reason you'd want to call this is to test a TerraPage archive + you'd written. + */ +// {group:Demonstration Scene Graph} TX_CPPDECL bool trpgTestArchive(trpgr_Archive &); #endif diff --git a/src/osgPlugins/txp/trpage_swap.cpp b/src/osgPlugins/txp/trpage_swap.cpp index 3c25dd8f4..a2666b7ad 100644 --- a/src/osgPlugins/txp/trpage_swap.cpp +++ b/src/osgPlugins/txp/trpage_swap.cpp @@ -17,15 +17,15 @@ #include /* trpage_swap.h - Byte swapping utility functions. - */ + Byte swapping utility functions. + */ -#include "trpage_swap.h" +#include /* -** func: swap_two( in, out ) +** func: swap_two( in, out ) ** -** desc: byte-swaps a two-byte array. +** desc: byte-swaps a two-byte array. */ void trpg_swap_two ( const char *in, char *out ) { @@ -38,9 +38,9 @@ void trpg_swap_two ( const char *in, char *out ) } /* -** func: swap_four( in, out ) +** func: swap_four( in, out ) ** -** desc: byte-swaps a four-byte array. +** desc: byte-swaps a four-byte array. */ void trpg_swap_four ( const char *in, char *out ) { @@ -55,9 +55,9 @@ void trpg_swap_four ( const char *in, char *out ) } /* -** func: swap_eight( in, out ) +** func: swap_eight( in, out ) ** -** desc: byte-swaps an eight-byte array. +** desc: byte-swaps an eight-byte array. */ void trpg_swap_eight ( const char *in, char *out ) { @@ -76,9 +76,9 @@ void trpg_swap_eight ( const char *in, char *out ) } /* -** func: swap_sixteen( in, out ) +** func: swap_sixteen( in, out ) ** -** desc: byte-swaps an sixteen-byte array. +** desc: byte-swaps an sixteen-byte array. */ void trpg_swap_sixteen ( const char *in, char *out ) { @@ -105,105 +105,105 @@ void trpg_swap_sixteen ( const char *in, char *out ) } /* -** func: tx_byteswap_short( number ) +** func: tx_byteswap_short( number ) ** -** desc: byte-swaps a short int. +** desc: byte-swaps a short int. */ short trpg_byteswap_short( short number ) { - short result; + short result; - trpg_swap_two( (const char*) &number, (char*) &result ); - return result; + trpg_swap_two( (const char*) &number, (char*) &result ); + return result; } /* -** func: tx_byteswap_int( number ) +** func: tx_byteswap_int( number ) ** -** desc: byte-swaps an int. +** desc: byte-swaps an int. */ -int trpg_byteswap_int( int number ) +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; } diff --git a/src/osgPlugins/txp/trpage_swap.h b/src/osgPlugins/txp/trpage_swap.h index a42e84aaf..9315bd3ed 100644 --- a/src/osgPlugins/txp/trpage_swap.h +++ b/src/osgPlugins/txp/trpage_swap.h @@ -17,19 +17,19 @@ #define trpage_swap_h_ /* trpage_swap.h - Byte swapping utility functions. + Byte swapping utility functions. */ -#include "trpage_sys.h" +#include -#include "trpage_io.h" +#include // Byte swap and return a short // {group:Byte Ordering Utilities} 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 ); diff --git a/src/osgPlugins/txp/trpage_sys.h b/src/osgPlugins/txp/trpage_sys.h index b52d54e15..593fb6907 100644 --- a/src/osgPlugins/txp/trpage_sys.h +++ b/src/osgPlugins/txp/trpage_sys.h @@ -14,53 +14,41 @@ */ /* trpage_sys.h - System specific declarations. - */ + System specific declarations. + */ #ifndef trpage_sys_h_ #define trpage_sys_h_ -#ifndef PATHSEPARATOR +#ifndef PATHSEPERATOR #ifdef macintosh -#define PATHSEPARATOR ":" +#define PATHSEPERATOR ":" #else -#define PATHSEPARATOR "/" +#define PATHSEPERATOR "/" #endif #endif #if defined(_WIN32) -/* ********************* - System Specific Section. - This is currently set up for win32. - ********************* - */ +/* ********************* + System Specific Section. + This is currently set up for win32. + ********************* + */ #include -#include -#if !defined(__GNUC__) // Microsoft Developer warnings that annoy me #pragma warning ( disable : 4251) #pragma warning ( disable : 4275) #pragma warning ( disable : 4786) -#endif // Somewhat system independent file deletion macro -#ifdef __CYGWIN__ -# define TRPGDELETEFILE(file) remove((file)) -#else -# define TRPGDELETEFILE(file) DeleteFile((file)) -#endif +#define TRPGDELETEFILE(file) DeleteFile((file)) #ifndef int64 - // 64 bit long value. Need this for really big files. -#ifdef __GNUC__ - typedef long long int64; -#else - typedef __int64 int64; +// 64 bit long value. Need this for really big files. +typedef __int64 int64; #endif -#endif - #else // Unix @@ -100,6 +88,7 @@ typedef double float64; #include #include +#include #if defined(_WIN32) // PJM // Had to take this out because of an iostream conflict @@ -112,7 +101,7 @@ typedef int64 trpgllong; // These are used to export classes from a DLL // Definitely Windows specific -#include "trpage_ident.h" -#include "trdll.h" +#include +#include #endif diff --git a/src/osgPlugins/txp/trpage_tile.cpp b/src/osgPlugins/txp/trpage_tile.cpp index a4533aac8..da7e553ba 100644 --- a/src/osgPlugins/txp/trpage_tile.cpp +++ b/src/osgPlugins/txp/trpage_tile.cpp @@ -18,229 +18,230 @@ #include /* 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" +#include +#include /* Write Tile Table - Keeps track of tiles written to disk. - */ + Keeps track of tiles written to disk. + */ // Constructor trpgTileTable::trpgTileTable() { - Reset(); + Reset(); } // Reset function void trpgTileTable::Reset() { - mode = External; - lodInfo.resize(0); - valid = true; + errMess[0] = '\0'; + mode = External; + lodInfo.resize(0); + valid = true; } // Destructor trpgTileTable::~trpgTileTable() { - valid = false; + valid = false; } // Set functions void trpgTileTable::SetMode(TileMode inMode) { - Reset(); - mode = inMode; + Reset(); + mode = inMode; } void trpgTileTable::SetNumLod(int numLod) { - lodInfo.resize(numLod); + lodInfo.resize(numLod); } void trpgTileTable::SetNumTiles(int nx,int ny,int lod) { - if (nx <= 0 || ny <= 0 || lod < 0 || static_cast(lod) >= lodInfo.size()) - return; + 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]; + // 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); + LodInfo &li = lodInfo[lod]; + li.numX = nx; li.numY = ny; + int numTile = li.numX*li.numY; + li.addr.resize(numTile); + li.elev_min.resize(numTile,0.0); + li.elev_max.resize(numTile,0.0); - // Copy pre-existing data if it's there - if (oldLodInfo.addr.size() > 0) { - for (int x=0;x 0) { + for (int x=0;x(lod) >= lodInfo.size()) return; - if (mode != Local) - return; - LodInfo &li = lodInfo[lod]; - if (x < 0 || x >= li.numX || y < 0 || y >= li.numY) - return; + 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; + int loc = y*li.numX + x; + li.addr[loc] = ref; + li.elev_min[loc] = zmin; + li.elev_max[loc] = zmax; } bool trpgTileTable::isValid() const { - return valid; + return valid; } // Get methods bool trpgTileTable::GetMode(TileMode &outMode) const { - if (!isValid()) return false; + if (!isValid()) return false; - outMode = mode; - return true; + outMode = mode; + return true; } bool trpgTileTable::GetTile(int x,int y,int lod,trpgwAppAddress &ref,float32 &zmin,float32 &zmax) const { - if (!isValid()) return false; + if (!isValid()) return false; - if (lod < 0 || static_cast(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; + 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]; + int loc = y*li.numX + x; + ref = li.addr[loc]; + zmin = li.elev_min[loc]; + zmax = li.elev_max[loc]; - return true; + return true; } // Write tile table bool trpgTileTable::Write(trpgWriteBuffer &buf) { - if (!isValid()) - return false; + if (!isValid()) + return false; - buf.Begin(TRPGTILETABLE2); - - // Write the mode - buf.Add(mode); + buf.Begin(TRPGTILETABLE2); + + // Write the mode + buf.Add(mode); - // Depending on the mode we'll have a lot or a little data - if (mode == Local) { - // The lod sizing is redundant, but it's convenient here - int numLod = lodInfo.size(); - buf.Add(numLod); + // Depending on the mode we'll have a lot or a little data + if (mode == Local) { + // The lod sizing is redundant, but it's convenient here + int numLod = lodInfo.size(); + buf.Add(numLod); - // Write each terrain LOD set - for (int i=0;i(no) >= 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 || static_cast(no) >= 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(id) >= locMats.size()) - return false; + if (id < 0 || id >= locMats.size()) + return false; retMat = locMats[id]; @@ -327,78 +328,78 @@ const std::vector *trpgTileHeader::GetLocalMaterialList() con // Get methods bool trpgTileHeader::GetNumMaterial(int32 &no) const { - if (!isValid()) return false; - no = matList.size(); - return true; + if (!isValid()) return false; + no = matList.size(); + return true; } bool trpgTileHeader::GetMaterial(int32 id,int32 &mat) const { - if (!isValid() || id < 0 || static_cast(id) >= 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 || static_cast(id) >= 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; - for (i=0;iAddMaterial(id); - } - break; - case TRPG_TILE_MODELLIST: - buf.Get(no); - if (no < 0) throw 1; - for (i=0;iAddModel(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 *locMats; - locMats = const_cast *> (head->GetLocalMaterialList()); - locMats->resize(numLocMat); - for (i=0;iAddMaterial(id); + } + break; + case TRPG_TILE_MODELLIST: + buf.Get(no); + if (no < 0) throw 1; + for (i=0;iAddModel(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 *locMats; + locMats = const_cast *> (head->GetLocalMaterialList()); + locMats->resize(numLocMat); + for (i=0;i /* trpage_util.cpp This source file implements various utility routines for paging archive diff --git a/src/osgPlugins/txp/trpage_util.h b/src/osgPlugins/txp/trpage_util.h index 22368ae60..55c6d2e13 100644 --- a/src/osgPlugins/txp/trpage_util.h +++ b/src/osgPlugins/txp/trpage_util.h @@ -20,14 +20,13 @@ #ifndef trpage_util_h_ #define trpage_util_h_ #include -#include "trpage_read.h" -#include "trpage_write.h" -#include "trpage_scene.h" +#include +#include +#include TX_EXDECL class TX_CLDECL trpgUtil { public: enum {DoReport = 1<<0,DoCopy = 1<<1, DoTileOpt = 1<<2}; int merge(trpgr_Archive &inArch1,trpgr_Archive &inArch2,trpgwArchive &outArch, int flags = 0); }; -#endif - +#endif \ No newline at end of file diff --git a/src/osgPlugins/txp/trpage_warchive.cpp b/src/osgPlugins/txp/trpage_warchive.cpp index f24563587..1ee77a7a2 100644 --- a/src/osgPlugins/txp/trpage_warchive.cpp +++ b/src/osgPlugins/txp/trpage_warchive.cpp @@ -18,101 +18,184 @@ #include /* trpage_warchive.cpp - This source file contains the implementations of trpgwArchive and trpgwGeomHelper. - The Write Archive is used to write TerraPage archives. All its important methods - are virtual, so you shouldn't need to modify any of this code. Simply subclass - and override. - The Geometry Helper is a class that's used to sort out polygons and build - trpgGeometry objects, containing triangle strips and fans out of them. The one - contained here is fairly simple, but all its important methods are virtual. So - again, subclass and override if you need to change them. - */ + This source file contains the implementations of trpgwArchive and trpgwGeomHelper. + The Write Archive is used to write TerraPage archives. All its important methods + are virtual, so you shouldn't need to modify any of this code. Simply subclass + and override. + The Geometry Helper is a class that's used to sort out polygons and build + trpgGeometry objects, containing triangle strips and fans out of them. The one + contained here is fairly simple, but all its important methods are virtual. So + again, subclass and override if you need to change them. + */ -#include "trpage_geom.h" -#include "trpage_write.h" -#include "trpage_compat.h" -#include "trpage_read.h" +#include +#include +#include +#include // Constructor trpgwArchive::trpgwArchive(trpgEndian inNess,TileMode inTileMode,int inVersion) { - version = inVersion; - if (version != 1 && version != 2) - throw 1; - fp = NULL; - strcpy(dir,"."); - ness = inNess; - tileMode = inTileMode; - cpuNess = trpg_cpu_byte_order(); - tileFile = NULL; - tileFileCount = 0; - isRegenerate = false; - maxTileFileLen = -1; + version = inVersion; + if (version != 1 && version != 2) + throw 1; + fp = NULL; + strcpy(dir,"."); + ness = inNess; + tileMode = inTileMode; + cpuNess = trpg_cpu_byte_order(); + tileFile = NULL; + tileFileCount = 0; + isRegenerate = false; + maxTileFileLen = -1; + + firstHeaderWrite = true; } // Constructor for regenerate -trpgwArchive::trpgwArchive(char *inDir,char *inFile) +trpgwArchive::trpgwArchive(char *inDir,char *inFile,trpg2dPoint &sw, trpg2dPoint &ne) { - maxTileFileLen = -1; - version = TRPG_VERSION_MAJOR; - fp = NULL; - strcpy(dir,inDir); - cpuNess = trpg_cpu_byte_order(); - tileFile = NULL; - tileFileCount = 0; - isRegenerate = true; + maxTileFileLen = -1; + version = TRPG_VERSION_MAJOR; + fp = NULL; + strcpy(dir,inDir); + cpuNess = trpg_cpu_byte_order(); + tileFile = NULL; + tileFileCount = 0; + isRegenerate = true; + errMess[0] = '\0'; - // Open a Read Archive to get the rest of the info we need - trpgr_Archive *inArch = new trpgr_Archive(); - inArch->SetDirectory(inDir); - if (!inArch->OpenFile(inFile)) { - delete inArch; - throw 1; - } - // Get the header (this is what we need) - if (!inArch->ReadHeader()) { - delete inArch; - throw 1; - } + // Open a Read Archive to get the rest of the info we need + trpgr_Archive *inArch = new trpgr_Archive(); + inArch->SetDirectory(inDir); + if (!inArch->OpenFile(inFile)) { + delete inArch; + throw 1; + } + // Get the header (this is what we need) + if (!inArch->ReadHeader()) { + delete inArch; + throw 1; + } - ness = inArch->GetEndian(); + ness = inArch->GetEndian(); + const trpgHeader *inHeader = inArch->GetHeader(); - // Copy the header tables - header = *inArch->GetHeader(); - matTable = *inArch->GetMaterialTable(); - texTable = *inArch->GetTexTable(); - modelTable = *inArch->GetModelTable(); - tileTable = *inArch->GetTileTable(); - lightTable = *inArch->GetLightTable(); - rangeTable = *inArch->GetRangeTable(); + // Expand the coverage + trpg2dPoint newSW,newNE; + trpg2dPoint oldSW,oldNE; + inHeader->GetExtents(oldSW,oldNE); + newSW.x = MIN(sw.x,oldSW.x); + newSW.y = MIN(sw.y,oldSW.y); + newNE.x = MAX(ne.x,oldNE.x); + newNE.y = MAX(ne.y,oldNE.y); - trpgTileTable::TileMode inMode; - tileTable.GetMode(inMode); - tileMode = (inMode == trpgTileTable::Local) ? TileLocal : TileExternal; + // Decide what the offset should be for new tiles + { + trpg2dPoint blockSize; + inHeader->GetTileSize(0,blockSize); + double dx = (oldSW.x - newSW.x)/blockSize.x + 10e-10; + double dy = (oldSW.y - newSW.y)/blockSize.y + 10e-10; + addOffset.x = dx; + addOffset.y = dy; + if (dx - addOffset.x > 10e-4 || + dy - addOffset.y > 10e-4) { + delete inArch; + throw 1; + } + } - // That's it for the read archive - delete inArch; + // Header can mostly stay the same + header = *inHeader; + // Update to the new MBR and tile grid sizes + header.SetExtents(newSW,newNE); + header.GetNumLods(numLod); + for (int i=0;iGetTileSize(i,tileSize); + trpg2iPoint newTileExt; + newTileExt.x = (newNE.x - newSW.x)/tileSize.x + 10e-5; + newTileExt.y = (newNE.y - newSW.y)/tileSize.y + 10e-15; + header.SetLodSize(i,newTileExt); + } + + // These tables we can copy straight over + matTable = *inArch->GetMaterialTable(); + texTable = *inArch->GetTexTable(); + modelTable = *inArch->GetModelTable(); + + lightTable = *inArch->GetLightTable(); + rangeTable = *inArch->GetRangeTable(); + textStyleTable = *inArch->GetTextStyleTable(); + supportStyleTable = *inArch->GetSupportStyleTable(); + labelPropertyTable = *inArch->GetLabelPropertyTable(); + + // Need to resize the tile table + const trpgTileTable *oldTiles = inArch->GetTileTable(); + trpgTileTable::TileMode tileTableMode; + oldTiles->GetMode(tileTableMode); + tileTable.SetMode(tileTableMode); + tileTable.SetNumLod(numLod); + for (int lod=0;lodGetLodSize(lod,oldTileSize); + for (int ix=0;ixGetTile(ix,iy,lod,addr,zmin,zmax); + tileTable.SetTile(ix+addOffset.x,iy+addOffset.y,lod,addr,zmin,zmax); + } + } + } + + // Continue to work in the mode the original database is in + tileMode = (tileTableMode == trpgTileTable::Local) ? TileLocal : TileExternal; + + // That's it for the read archive + delete inArch; } // Destructor trpgwArchive::~trpgwArchive() { - if (fp) - fclose(fp); - if (tileFile) { - delete tileFile; - tileFile = NULL; - } + if (fp) + fclose(fp); + if (tileFile) { + delete tileFile; + tileFile = NULL; + } } // IsValid() // Verifies that our file is open bool trpgwArchive::isValid() const { - if (!fp) - return false; + if (!fp) + { + strcpy(errMess, "File object do not exist"); + return false; + } - return true; + return true; +} + +const char *trpgwArchive::getErrMess() const +{ + if(errMess[0] == '\0') + return 0; + else + return &errMess[0]; } // Set the maximum advised size for a tile file @@ -123,42 +206,61 @@ void trpgwArchive::SetMaxTileFileLength(int max) } /* Set Functions - These just copy tables and the header from the input. - If these aren't set, then empty ones are written. - */ + These just copy tables and the header from the input. + If these aren't set, then empty ones are written. + */ bool trpgwArchive::SetHeader(const trpgHeader &head) { - header = head; - return true; + header = head; + return true; } bool trpgwArchive::SetMaterialTable(const trpgMatTable &mat) { - matTable = mat; - return true; + matTable = mat; + return true; } bool trpgwArchive::SetTextureTable(const trpgTexTable &tex) { - texTable = tex; - return true; + texTable = tex; + return true; } bool trpgwArchive::SetModelTable(const trpgModelTable &models) { - modelTable = models; - return true; + modelTable = models; + return true; } bool trpgwArchive::SetLightTable(const trpgLightTable &lights) { - lightTable = lights; - return true; + lightTable = lights; + return true; } bool trpgwArchive::SetRangeTable(const trpgRangeTable &ranges) { - rangeTable = ranges; - return true; + rangeTable = ranges; + return true; } +bool trpgwArchive::SetTextStyleTable(const trpgTextStyleTable &styles) +{ + textStyleTable = styles; + return true; +} + +bool trpgwArchive::SetLabelPropertyTable(const trpgLabelPropertyTable &properties) +{ + labelPropertyTable = properties; + return true; +} +bool trpgwArchive::SetSupportStyleTable(const trpgSupportStyleTable &styles) +{ + + supportStyleTable = styles; + return true; +} + + /* Get Methods - Used in regenerate. + Used in regenerate. */ trpgHeader *trpgwArchive::GetHeader() { @@ -182,207 +284,337 @@ trpgLightTable *trpgwArchive::GetLightTable() } trpgRangeTable *trpgwArchive::GetRangeTable() { - return &rangeTable; + return &rangeTable; +} +trpgTextStyleTable *trpgwArchive::GetTextStyleTable() +{ + return &textStyleTable; +} +trpgSupportStyleTable *trpgwArchive::GetSupportStyleTable() +{ + return &supportStyleTable; +} +trpgLabelPropertyTable *trpgwArchive::GetLabelPropertyTable() +{ + return &labelPropertyTable; } // OpenFile // Same as above, only gets a basename as well bool trpgwArchive::OpenFile(const char *in_dir,const char *name) { - char filename[1024]; + char filename[1024]; - strncpy(dir,in_dir,1023); + strncpy(dir,in_dir,1023); - sprintf(filename,"%s" PATHSEPARATOR "%s",dir,name); + sprintf(filename,"%s" PATHSEPERATOR "%s",dir,name); - if (!(fp = fopen(filename,"wb"))) - return false; + if (!(fp = fopen(filename,"wb"))) + return false; - return true; + return true; } // CloseFile // Close the open file void trpgwArchive::CloseFile() { - if (fp) - fclose(fp); + if (fp) + fclose(fp); - fp = NULL; + fp = NULL; } -/* WriteHeader - For now everything is external, so the header is written last. - The order is this: - Header - Material table - Texture References - Model References - [Future: - Tile Address Table - Model Address Table] - */ +/* Write Header + Flush out the header (checkpoint) and return. + */ bool trpgwArchive::WriteHeader() { - trpgMemWriteBuffer buf(ness); + bool ret = CheckpointHeader(); - if (!isValid()) - return false; + if (tileFile) { + delete tileFile; + tileFile=NULL; + } - if (!header.isValid()) - return false; + return ret; +} - // This will close the appendable files - if (tileFile) { - delete tileFile; - tileFile = NULL; - } +/* CheckpointHeader + The header lives in its own file, so we can write it at any point we + have a valid archive. + This includes all the tables, as well as basic header info. + */ +bool trpgwArchive::CheckpointHeader() +{ + trpgMemWriteBuffer buf(ness); - /* Build a Tile Table - We need to build one from scratch here. However, - we have all the relevant information collected during - the WriteTile calls. - */ - if (tileMode == TileExternal) { - // External tiles are easy - tileTable.SetMode(trpgTileTable::External); - } else { - if (!isRegenerate) { - // Local tiles require more work - tileTable.SetMode(trpgTileTable::Local); - // Set up the sizes - int32 numLod; - header.GetNumLods(numLod); - tileTable.SetNumLod(numLod); - for (int i=0;iFlush(); + } + + /* Build a Tile Table + We need to build one from scratch here. However, + we have all the relevant information collected during + the WriteTile calls. + */ + if (tileMode == TileExternal) { + // External tiles are easy + tileTable.SetMode(trpgTileTable::External); + } else { + if (!isRegenerate && firstHeaderWrite) { + // Local tiles require more work + tileTable.SetMode(trpgTileTable::Local); + // Set up the sizes + int32 numLod; + header.GetNumLods(numLod); + tileTable.SetNumLod(numLod); + for (unsigned int i=0;iisValid()) - return false; + // Open the next one + char filename[1024]; + sprintf(filename,"%s" PATHSEPERATOR "tileFile_%d.tpf",dir,tileFileCount++); + tileFile = new trpgwAppFile(ness,filename); + if (!tileFile->isValid()) + return false; - // Add another TileFiles entry - tileFiles.resize(tileFiles.size()+1); - tileFiles[tileFiles.size()-1].id = tileFiles.size()-1; + // Add another TileFiles entry + tileFiles.resize(tileFiles.size()+1); + tileFiles[tileFiles.size()-1].id = tileFiles.size()-1; - return true; + return true; } /* Designate Tile File - Close the current tile file (if any) and open one with the - given base name. This is used for regenerate. + Close the current tile file (if any) and open one with the + given base name. This is used for regenerate. */ bool trpgwArchive::DesignateTileFile(int id) { if (tileMode != TileLocal) - return false; + return false; // Close the current tile file - if (tileFile) delete tileFile; + if (tileFile) { + delete tileFile; + tileFile=NULL; + } // Open a named on char filename[1024]; - sprintf(filename,"%s" PATHSEPARATOR "tileFile_%d.tpf",dir,id); + sprintf(filename,"%s" PATHSEPERATOR "tileFile_%d.tpf",dir,id); tileFile = new trpgwAppFile(ness,filename); if (!tileFile->isValid()) - return false; + return false; // Add another TileFiles entry tileFiles.resize(tileFiles.size()+1); @@ -392,269 +624,286 @@ bool trpgwArchive::DesignateTileFile(int id) } /* WriteTile. - Write the given tile (x,y,lod) in the appropriate mode (Local or External). - The tile header is given separately from the rest of the tile, but they are - appended together to the file. - */ + Write the given tile (x,y,lod) in the appropriate mode (Local or External). + The tile header is given separately from the rest of the tile, but they are + appended together to the file. + */ bool trpgwArchive::WriteTile(unsigned int x,unsigned int y,unsigned int lod, float zmin, float zmax, - const trpgMemWriteBuffer *head,const trpgMemWriteBuffer *buf) + const trpgMemWriteBuffer *head,const trpgMemWriteBuffer *buf) { - FILE *tfp=NULL; + FILE *tfp=NULL; - if (!isValid()) - return false; + if (!isValid()) + return false; - // External tiles get their own individual files - if (tileMode == TileExternal) { - // Make a new filename - char filename[1024]; - // Note: Windows specific - sprintf(filename,"%s" PATHSEPARATOR "tile_%d_%d_%d.tpt",dir,x,y,lod); - if (!(tfp = fopen(filename,"wb"))) - return false; + // External tiles get their own individual files + if (tileMode == TileExternal) { + // Make a new filename + char filename[1024]; + // Note: Windows specific + sprintf(filename,"%s" PATHSEPERATOR "tile_%d_%d_%d.tpt",dir,x,y,lod); + if (!(tfp = fopen(filename,"wb"))) + return false; - // Write the header first - unsigned int len; - const char *data; - if (head) { - data = head->getData(); - len = head->length(); - if (fwrite(data,sizeof(char),len,tfp) != len) { - fclose(tfp); - return false; - } - } + // Write the header first + int len; + const char *data; + if (head) { + data = head->getData(); + len = head->length(); + if (fwrite(data,sizeof(char),len,tfp) != len) { + fclose(tfp); + return false; + } + } - // Write the buffer out - data = buf->getData(); - len = buf->length(); - if (fwrite(data,sizeof(char),len,tfp) != len) { - fclose(tfp); - return false; - } - fclose(tfp); - } else { - // Local tiles get appended to a tile file - if (!tileFile) { - if (!IncrementTileFile()) - return false; - } else { - // See if we've exceeded the maximum advised size for a tile file - if (maxTileFileLen > 0 && tileFile->GetLengthWritten() > maxTileFileLen) - if (!IncrementTileFile()) - return false; - } + // Write the buffer out + data = buf->getData(); + len = buf->length(); + if (fwrite(data,sizeof(char),len,tfp) != len) { + fclose(tfp); + return false; + } + fclose(tfp); + } else { + // Local tiles get appended to a tile file + if (!tileFile) { + if (!IncrementTileFile()) + return false; + } else { + // See if we've exceeded the maximum advised size for a tile file + if (maxTileFileLen > 0 && tileFile->GetLengthWritten() > maxTileFileLen) + if (!IncrementTileFile()) + return false; + } - int32 pos = static_cast(tileFile->Pos()); - if (!tileFile->Append(head,buf)) - return false; - // Keep track of the fact that this went here - TileFile &tf = tileFiles[tileFiles.size()-1]; - TileFileEntry te; - te.x = x; te.y = y; te.lod = lod; - te.zmin = zmin; te.zmax = zmax; te.offset = pos; - tf.tiles.push_back(te); - } + int32 pos = tileFile->Pos(); + if (!tileFile->Append(head,buf)) + return false; + // Keep track of the fact that this went here + TileFile &tf = tileFiles[tileFiles.size()-1]; + TileFileEntry te; + te.x = x; te.y = y; te.lod = lod; + te.zmin = zmin; te.zmax = zmax; te.offset = pos; + tf.tiles.push_back(te); + } - return true; + return true; } /* **************** - Geometry Stats - Used by the Geometry Helper - **************** - */ + Geometry Stats + Used by the Geometry Helper + **************** + */ trpgwGeomStats::trpgwGeomStats() { - totalTri = totalStripTri = totalFanTri = totalBagTri = 0; - for (int i=0;i<15;i++) { - stripStat[i] = fanStat[i] = 0; - } - stripGeom = fanGeom = bagGeom = 0; - stateChanges = 0; - numStrip = numFan = 0; - totalQuad = 0; + totalTri = totalStripTri = totalFanTri = totalBagTri = 0; + for (int i=0;i<15;i++) { + stripStat[i] = fanStat[i] = 0; + } + stripGeom = fanGeom = bagGeom = 0; + stateChanges = 0; + numStrip = numFan = 0; + totalQuad = 0; } trpgwGeomStats::~trpgwGeomStats() { } /* **************** - Geometry Helper - Here, since it's used with a write archive. - **************** - */ + Geometry Helper + Here, since it's used with a write archive. + **************** + */ trpgwGeomHelper::trpgwGeomHelper() { - buf = NULL; - mode = trpgGeometry::Triangles; + buf = NULL; + mode = trpgGeometry::Triangles; } trpgwGeomHelper::~trpgwGeomHelper() { } void trpgwGeomHelper::SetMode(int m) { - if (m == trpgGeometry::Triangles || m == trpgGeometry::Quads) - mode = m; + if (m == trpgGeometry::Triangles || m == trpgGeometry::Quads) + mode = m; } trpgwGeomHelper::trpgwGeomHelper(trpgWriteBuffer *ibuf, int dtype) { - init(ibuf,dtype); + init(ibuf,dtype); } void trpgwGeomHelper::init(trpgWriteBuffer *ibuf,int dtype) { - buf = ibuf; - dataType = dtype; - zmin = 1e12; - zmax = -1e12; + buf = ibuf; + dataType = dtype; + zmin = 1e12; + zmax = -1e12; } // Reset back to a clean state (except for the buffer) void trpgwGeomHelper::Reset() { - ResetTri(); - ResetPolygon(); - zmin = 1e12; - zmax = -1e12; + ResetTri(); + ResetPolygon(); + zmin = 1e12; + zmax = -1e12; } // Reset triangle arrays (usually after a flush) void trpgwGeomHelper::ResetTri() { - strips.Reset(); - fans.Reset(); - bags.Reset(); + strips.Reset(); + fans.Reset(); + bags.Reset(); - tex.resize(0); - norm.resize(0); - vert.resize(0); + tex.resize(0); + norm.resize(0); + vert.resize(0); } // Start a polygon definition void trpgwGeomHelper::StartPolygon() { - ResetPolygon(); + ResetPolygon(); } // Finish a polygon definition void trpgwGeomHelper::EndPolygon() { - // See if we can add it to the current triangle arrays - if (vert.size() && (matTri != matPoly)) { - // Couldn't flush geometry and move on - FlushGeom(); - } + // See if we can add it to the current triangle arrays + if (vert.size() && (matTri != matPoly)) { + // Couldn't flush geometry and move on + FlushGeom(); + } - // Turn the polygon into triangles - // Note: Only dealing with convex here - matTri = matPoly; + // Turn the polygon into triangles + // Note: Only dealing with convex here + matTri = matPoly; + int numMats=matTri.size(); - switch (mode) { - case trpgGeometry::Triangles: - { - int num = polyVert.size() - 2; - int id1,id2; - for (int i=0;i 1) { - id1 = i+2; id2 = i+1; - } + id1 = i+1; + id2 = i+2; + if (num > 1) { + id1 = i+2; id2 = i+1; + } #else - id1 = i+1; - id2 = i+2; + id1 = i+1; + id2 = i+2; #endif - // Define the triangle - vert.push_back(polyVert[0]); - vert.push_back(polyVert[id1]); - vert.push_back(polyVert[id2]); + // Define the triangle + vert.push_back(polyVert[0]); + vert.push_back(polyVert[id1]); + vert.push_back(polyVert[id2]); - norm.push_back(polyNorm[0]); - norm.push_back(polyNorm[id1]); - norm.push_back(polyNorm[id2]); + norm.push_back(polyNorm[0]); + norm.push_back(polyNorm[id1]); + norm.push_back(polyNorm[id2]); - tex.push_back(polyTex[0]); - tex.push_back(polyTex[id1]); - tex.push_back(polyTex[id2]); - } - } - break; - case trpgGeometry::Quads: - { - int num = polyVert.size(); - if (polyVert.size() == 4) { - for (int i=0;iGetEndian() != trpg_cpu_byte_order()) @@ -663,257 +912,273 @@ void trpgwGeomHelper::AddVertex(trpg3dPoint &pt) tmpVert.x = trpg_byteswap_8bytes_to_double ((char *)&pt.x); tmpVert.y = trpg_byteswap_8bytes_to_double ((char *)&pt.y); tmpVert.z = trpg_byteswap_8bytes_to_double ((char *)&pt.z); - polyVert.push_back(tmpVert); + polyVert.push_back(tmpVert); } else #endif - polyVert.push_back(pt); + polyVert.push_back(pt); - // Update min/max - zmin = MIN(pt.z,zmin); - zmax = MAX(pt.z,zmax); + // Update min/max + zmin = MIN(pt.z,zmin); + zmax = MAX(pt.z,zmax); } // Flush the current set of geometry and move on void trpgwGeomHelper::FlushGeom() { - bool hadGeom = false; + bool hadGeom = false; - switch (mode) { - case trpgGeometry::Triangles: - { - Optimize(); + switch (mode) { + case trpgGeometry::Triangles: + { + Optimize(); - // Write only if we've got something - int numPrim; - if (strips.GetNumPrims(numPrim) && numPrim) { - strips.Write(*buf); - stats.stripGeom++; - hadGeom = true; - } - if (fans.GetNumPrims(numPrim) && numPrim) { - fans.Write(*buf); - stats.fanGeom++; - hadGeom = true; - } - if (bags.GetNumPrims(numPrim) && numPrim) { - bags.Write(*buf); - stats.bagGeom++; - hadGeom = true; - } - } - break; - case trpgGeometry::Quads: - { - int numVert = vert.size(); - // Make sure we've got quads - if (numVert % 4 == 0) { - int dtype = (dataType == UseDouble ? trpgGeometry::DoubleData : trpgGeometry::FloatData); - // Just dump the quads into single geometry node - trpgGeometry quads; - quads.SetPrimType(trpgGeometry::Quads); - quads.AddTexCoords(trpgGeometry::PerVertex); - for (int i=0;i &itex) { v = iv; n = in; tex=itex; valid = true;} + optVert(int numMat, int vid, std::vector &iv, std::vector &in, std::vector &itex); + trpg3dPoint v; + trpg3dPoint n; + std::vector tex; + bool valid; + int operator == (const optVert &in) const { return (v == in.v && n == in.n && tex == in.tex); } }; +optVert::optVert(int numMat, int vid, std::vector &iv, std::vector &in, std::vector &itex) +{ + v=iv[vid]; + n=in[vid]; + tex.resize(0); + for (unsigned int loop=0; loop < numMat; loop++) tex.push_back(itex[vid*numMat+loop]); +} void trpgwGeomHelper::Optimize() { - int dtype = (dataType == UseDouble ? trpgGeometry::DoubleData : trpgGeometry::FloatData); + bool isStrip = false; + int dtype = (dataType == UseDouble ? trpgGeometry::DoubleData : trpgGeometry::FloatData); - // Potentially writing to all of these - strips.SetPrimType(trpgGeometry::TriStrips); - strips.AddMaterial(matTri); - strips.AddTexCoords(trpgGeometry::PerVertex); - fans.SetPrimType(trpgGeometry::TriFans); - fans.AddMaterial(matTri); - fans.AddTexCoords(trpgGeometry::PerVertex); - bags.SetPrimType(trpgGeometry::Triangles); - bags.AddMaterial(matTri); - bags.AddTexCoords(trpgGeometry::PerVertex); + // Potentially writing to all of these + strips.SetPrimType(trpgGeometry::TriStrips); + fans.SetPrimType(trpgGeometry::TriFans); + bags.SetPrimType(trpgGeometry::Triangles); + int numMat = matTri.size(); + for (unsigned int loop =0; loop < numMat; loop++ ) { + strips.AddMaterial(matTri[loop]); + strips.AddTexCoords(trpgGeometry::PerVertex); + fans.AddMaterial(matTri[loop]); + fans.AddTexCoords(trpgGeometry::PerVertex); + bags.AddMaterial(matTri[loop]); + bags.AddTexCoords(trpgGeometry::PerVertex); + } - int numTri = vert.size()/3; + int numTri = vert.size()/3; - if (numTri == 0) - return; + if (numTri == 0) + return; - // Iterate through the triangles - enum {Strip,Fan,Bag}; - int type,triId; - optVert a[3],b[3],c[3]; - for (triId = 0; triIdFindAddTexture(tex); + trpgTexture tex; + tex.SetImageMode(trpgTexture::External); + tex.SetName(name); + if (lookForExisting) + texID = texTable->FindAddTexture(tex); + else + texID = texTable->AddTexture(tex); - return (texID != -1); + return (texID != -1); } void trpgwImageHelper::SetMaxTexFileLength(int len) @@ -921,72 +1186,145 @@ void trpgwImageHelper::SetMaxTexFileLength(int len) maxTexFileLen = len; } +// doing this so people don't have to modify thier code, for both TXP users out there bool trpgwImageHelper::AddLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY, - bool isMipmap,char *data,int &texID) + bool isMipmap,char *data,int &texID) { - // Set up the basic texture - trpgTexture tex; - tex.SetName(name); - tex.SetImageMode(trpgTexture::Local); - tex.SetImageType(type); - tex.SetImageSize(trpg2iPoint(sizeX,sizeY)); - tex.SetIsMipmap(isMipmap); + int depth; + switch (type) { + case trpgTexture::trpg_INT8: + depth = 1; + break; + case trpgTexture::trpg_INTA8: + depth = 2; + break; + case trpgTexture::trpg_RGB8: + case trpgTexture::trpg_FXT1: + case trpgTexture::trpg_DXT1: + case trpgTexture::trpg_DXT3: + case trpgTexture::trpg_DXT5: + depth = 3; + break; + case trpgTexture::trpg_RGBA8: + depth = 4; + break; + default: + depth = -1; + break; + } - // Write the image out to disk - trpgwAppAddress addr; - if (!WriteToArchive(tex,data,addr)) - return false; - - // Now add the specifics to the texture table - tex.SetImageAddr(addr); - texID = texTable->AddTexture(tex); - - return true; + return AddLocal(name,type,sizeX,sizeY,depth,trpgTexture::trpg_RGBX_Neither,isMipmap,data,texID); } -bool trpgwImageHelper::AddTileLocal(char *name,trpgTexture::ImageType type, - int sizeX,int sizeY,bool isMipmap,char *data,int &texID,trpgwAppAddress &addr) +bool trpgwImageHelper::AddLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY, int sizeZ, + trpgTexture::ImageOrg org, bool isMipmap,char *data,int &texID) { - // Set up the texture template and add to the table - trpgTexture tex; - tex.SetName(name); - tex.SetImageMode(trpgTexture::Template); - tex.SetImageType(type); - tex.SetImageSize(trpg2iPoint(sizeX,sizeY)); - tex.SetIsMipmap(isMipmap); - texID = texTable->FindAddTexture(tex); + // Set up the basic texture + trpgTexture tex; + tex.SetName(name); + tex.SetImageMode(trpgTexture::Local); + tex.SetImageType(type); + tex.SetImageSize(trpg2iPoint(sizeX,sizeY)); + tex.SetNumLayer(sizeZ); + tex.SetImageOrganization(org); + tex.SetIsMipmap(isMipmap); - // Write the specific data out to an archive (return the address) - if (!WriteToArchive(tex,data,addr)) - return false; + // Write the image out to disk + trpgwAppAddress addr; + if (!WriteToArchive(tex,data,addr)) + return false; - return true; + // Now add the specifics to the texture table + tex.SetImageAddr(addr); + texID = texTable->AddTexture(tex); + + return true; +} + +// doing this so people don't have to modify thier code, for both TXP users out there +bool trpgwImageHelper::AddTileLocal(char *name,trpgTexture::ImageType type, int sizeX, int sizeY, + bool isMipmap,char *data,int &texID,trpgwAppAddress &addr) +{ + int depth; + switch (type) { + case trpgTexture::trpg_INT8: + depth = 1; + break; + case trpgTexture::trpg_INTA8: + depth = 2; + break; + case trpgTexture::trpg_RGB8: + case trpgTexture::trpg_FXT1: + case trpgTexture::trpg_DXT1: + case trpgTexture::trpg_DXT3: + case trpgTexture::trpg_DXT5: + depth = 3; + break; + case trpgTexture::trpg_RGBA8: + depth = 4; + break; + default: + depth = -1; + break; + } + + return AddTileLocal(name,type,sizeX,sizeY,depth,trpgTexture::trpg_RGBX_Neither,isMipmap,data,texID,addr); +} + +bool trpgwImageHelper::AddTileLocal(char *name,trpgTexture::ImageType type, int sizeX, int sizeY, int sizeZ, + trpgTexture::ImageOrg org, bool isMipmap,char *data,int &texID,trpgwAppAddress &addr) +{ + // Set up the texture template and add to the table + trpgTexture tex; + tex.SetName(name); + tex.SetImageMode(trpgTexture::Template); + tex.SetImageType(type); + tex.SetImageSize(trpg2iPoint(sizeX,sizeY)); + tex.SetNumLayer(sizeZ); + tex.SetImageOrganization(org); + tex.SetIsMipmap(isMipmap); + texID = texTable->FindAddTexture(tex); + + // Write the specific data out to an archive (return the address) + if (!WriteToArchive(tex,data,addr)) + return false; + + return true; } /* Increment Texture File. - Close the current texture file (if any) and open the next one. + Close the current texture file (if any) and open the next one. */ bool trpgwImageHelper::IncrementTextureFile() { - // Closes the current texture file - if (texFile) delete texFile; - texFile = NULL; + // Closes the current texture file + if (texFile) delete texFile; + texFile = NULL; - // Open the next one - char filename[1024]; - sprintf(filename,"%s" PATHSEPARATOR "texFile_%d.txf",dir,texFileIDs.size()); - texFile = new trpgwAppFile(ness,filename); - if (!texFile->isValid()) - return false; + // Open the next one + char filename[1024]; + sprintf(filename,"%s" PATHSEPERATOR "texFile_%d.txf",dir,texFileIDs.size()); + texFile = new trpgwAppFile(ness,filename); + if (!texFile->isValid()) + return false; - texFileIDs.push_back(texFileIDs.size()); + texFileIDs.push_back(texFileIDs.size()); - return true; + return true; +} + +// Flush current texture file (if any) +bool trpgwImageHelper::Flush() +{ + if (texFile) + texFile->Flush(); + + return true; } /* Designate Texture File - Close the curren texture file (if any) and open one with the given - base name. + Close the curren texture file (if any) and open one with the given + base name. */ bool trpgwImageHelper::DesignateTextureFile(int id) { @@ -996,10 +1334,10 @@ bool trpgwImageHelper::DesignateTextureFile(int id) // Open one with the given base name char filename[1024]; - sprintf(filename,"%s" PATHSEPARATOR "texFile_%d.txf",dir,id); + sprintf(filename,"%s" PATHSEPERATOR "texFile_%d.txf",dir,id); texFile = new trpgwAppFile(ness,filename); if (!texFile->isValid()) - return false; + return false; texFileIDs.push_back(id); @@ -1007,36 +1345,36 @@ bool trpgwImageHelper::DesignateTextureFile(int id) } /* Write To Archive. - Write the given image data out to an appropriate archive and - return the address. This is used for Local and Tile Local textures. + Write the given image data out to an appropriate archive and + return the address. This is used for Local and Tile Local textures. */ bool trpgwImageHelper::WriteToArchive(const trpgTexture &tex,char *data,trpgwAppAddress &addr) { - trpg2iPoint size; - tex.GetImageSize(size); - int32 depth; - tex.GetImageDepth(depth); + trpg2iPoint size; + tex.GetImageSize(size); + int32 depth; + tex.GetImageDepth(depth); - // Get a usable texture archive file - if (!texFile) { - if (!IncrementTextureFile()) - return false; - } else { - // Deal with maximum advised size for texture archive - if (maxTexFileLen > 0 && texFile->GetLengthWritten() > maxTexFileLen) { - if (!IncrementTextureFile()) - return false; - } - } + // Get a usable texture archive file + if (!texFile) { + if (!IncrementTextureFile()) + return false; + } else { + // Deal with maximum advised size for texture archive + if (maxTexFileLen > 0 && texFile->GetLengthWritten() > maxTexFileLen) { + if (!IncrementTextureFile()) + return false; + } + } - // Get the current address - addr.file = texFileIDs[texFileIDs.size()-1]; - addr.offset = static_cast(texFile->Pos()); + // Get the current address + addr.file = texFileIDs[texFileIDs.size()-1]; + addr.offset = texFile->Pos(); - // Write the data out to the archive. - int totSize = tex.CalcTotalSize(); - if (!texFile->Append(data,totSize)) - return false; + // Write the data out to the archive. + int totSize = tex.CalcTotalSize(); + if (!texFile->Append(data,totSize)) + return false; - return true; + return true; } diff --git a/src/osgPlugins/txp/trpage_write.h b/src/osgPlugins/txp/trpage_write.h index 8a0858788..e66bcd8db 100644 --- a/src/osgPlugins/txp/trpage_write.h +++ b/src/osgPlugins/txp/trpage_write.h @@ -18,284 +18,311 @@ #define _txpage_write_h_ /* trpage_write.h - Classes that are used to write paging archives. - */ + Classes that are used to write paging archives. + */ -#include "trpage_sys.h" -#include "trpage_io.h" -#include "trpage_swap.h" +#include +#include +#include /* 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(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 &); + trpgwGeomHelper(void); + virtual ~trpgwGeomHelper(void); + enum {UseDouble,UseFloat}; + trpgwGeomHelper(trpgWriteBuffer *,int dataType=UseDouble); + void init(trpgWriteBuffer *,int dataType=UseDouble); + virtual void SetMode(int); // Takes a trpgGeometry primitive type (triangle by default) + virtual void Reset(void); + // Start/End polygon definition + virtual void StartPolygon(void); + virtual void EndPolygon(void); + virtual void ResetPolygon(void); // If you change your mind about the current poly + // Set the current state + // Note: Currently you *must* set all of these + virtual void SetColor(trpgColor &); + virtual void SetTexCoord(trpg2dPoint &); + virtual void AddTexCoord(trpg2dPoint &); // for multiple textures + virtual void SetNormal(trpg3dPoint &); + virtual void SetMaterial(int32); + virtual void AddMaterial(int32); // for multiple textures + // Pull the state info together and add a vertex + virtual void AddVertex(trpg3dPoint &); - // Dump whatever we're doing and move on - virtual void FlushGeom(void); + // Dump whatever we're doing and move on + virtual void FlushGeom(void); - // Get the Min and Max Z values - virtual void GetZMinMax(double &min,double &max); + // Get the Min and Max Z values + virtual void GetZMinMax(double &min,double &max); - // Get statistics for whatever we built - trpgwGeomStats *GetStats(void) { return &stats; } + // Get statistics for whatever we built + trpgwGeomStats *GetStats(void) { return &stats; } protected: - int mode; - int dataType; - trpgWriteBuffer *buf; + int mode; + int dataType; + trpgWriteBuffer *buf; - /* Builds strips and fans from the triangle array. - We (TERREX) are assuming a certain ordering in our vertex array - because we do this optimization elsewhere. This won't work well - for anyone else. What you will need to do if you want good - performance is to implement a more generic form of this method. - All you should have to do is override Optimize(). You've - got the triangle arrays and a guarantee that the triangles - have the same material. All you really need is a decent fan/strip - algorithm. - */ - virtual void Optimize(void); + /* Builds strips and fans from the triangle array. + We (TERREX) are assuming a certain ordering in our vertex array + because we do this optimization elsewhere. This won't work well + for anyone else. What you will need to do if you want good + performance is to implement a more generic form of this method. + All you should have to do is override Optimize(). You've + got the triangle arrays and a guarantee that the triangles + have the same material. All you really need is a decent fan/strip + algorithm. + */ + virtual void Optimize(void); - // Reset Triangle arrays - virtual void ResetTri(void); + // Reset Triangle arrays + virtual void ResetTri(void); - // Collections of geometry - trpgGeometry strips,fans,bags; + // Collections of geometry + trpgGeometry strips,fans,bags; - // Temporary data arrays for triangles/quads - int32 matTri; - std::vector tex; - std::vector norm,vert; - // Data arrays for a polygon - int32 matPoly; - std::vector polyTex; - std::vector polyNorm,polyVert; - // Single points - trpg2dPoint tmpTex; - trpg3dPoint tmpNorm; - trpgColor tmpCol; + // Temporary data arrays for triangles/quads + std::vector matTri; + std::vector tex; + std::vector norm,vert; + // Data arrays for a polygon + std::vector matPoly; + std::vector polyTex; + std::vector polyNorm,polyVert; + // Single points + std::vector tmpTex; + trpg3dPoint tmpNorm; + trpgColor tmpCol; - // Geometry status built up as we go - trpgwGeomStats stats; + // Geometry status built up as we go + trpgwGeomStats stats; - // Keeps track of min and max z values - double zmin,zmax; + // Keeps track of min and max z values + double zmin,zmax; }; /* Image Write Helper. - Used to manage textures being added to a TerraPage archive. - It can write Local and Tile Local textures and also manages - the names of External textures (but you have to write those yourself). + Used to manage textures being added to a TerraPage archive. + It can write Local and Tile Local textures and also manages + the names of External textures (but you have to write those yourself). */ TX_EXDECL class TX_CLDECL trpgwImageHelper { public: - trpgwImageHelper(trpgEndian ness,char *dir,trpgTexTable &); - virtual ~trpgwImageHelper(void); + trpgwImageHelper(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 an external texture + virtual bool AddExternal(char *name,int &texID,bool lookForExisting=true); - /* 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); + /* Adds an entry to the texture table for a local texture and + writes the data for that texture out to one of our texture + archive files. + */ + virtual bool AddLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,bool isMipmap,char *data,int &texID); + virtual bool AddLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,int sizeZ,trpgTexture::ImageOrg org,bool isMipmap,char *data,int &texID); - /* 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); + /* Write a Tile Local texture out to one of our texture archive files. + Also creates a texture template, if necessary. + Caller is responsible for creating the Tile Local material and + placing it in the appropriate tile. + */ + virtual bool AddTileLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,bool isMipmap,char *data, int &texID,trpgwAppAddress &addr); + virtual bool AddTileLocal(char *name,trpgTexture::ImageType type,int sizeX,int sizeY,int sizeZ,trpgTexture::ImageOrg org,bool isMipmap,char *data, int &texID,trpgwAppAddress &addr); - /* 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); + /* 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); + /* 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); + /* Close the current texture file and go on to one with the + given base name. This is used for regenerate. + */ + virtual bool DesignateTextureFile(int); + + // Flush current texture output files + virtual bool Flush(void); protected: - // Write the given texture data into one our local archives - bool WriteToArchive(const trpgTexture &tex,char *data,trpgwAppAddress &addr); + // 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 texFileIDs; - trpgwAppFile *texFile; - int maxTexFileLen; + trpgEndian ness; + char dir[1024]; + trpgTexTable *texTable; + std::vector 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: - // Tiles can be stored as individual files (External) or grouped together (Local) - typedef enum {TileLocal,TileExternal} TileMode; + // Tiles can be stored as individual files (External) or grouped together (Local) + typedef enum {TileLocal,TileExternal} TileMode; - // 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); + // Add data to an existing archive + trpgwArchive(char *baseDir,char *name,trpg2dPoint &ll,trpg2dPoint &ur); + // Start an archive from scratch. + trpgwArchive(trpgEndian ness=LittleEndian,TileMode tileMode=TileLocal,int version=2); + virtual ~trpgwArchive(void); - // Set the maximum length for a tile file (if using them) - // This is only a suggestion for when to stop appending - virtual void SetMaxTileFileLength(int len); + // Set the maximum length for a tile file (if using them) + // This is only a suggestion for when to stop appending + virtual void SetMaxTileFileLength(int len); - // Set functions. Have to fill all these out before writing - virtual bool SetHeader(const trpgHeader &); - virtual bool SetMaterialTable(const trpgMatTable &); - virtual bool SetTextureTable(const trpgTexTable &); - virtual bool SetModelTable(const trpgModelTable &); - virtual bool SetLightTable(const trpgLightTable &); - virtual bool SetRangeTable(const trpgRangeTable &); + // Set functions. Have to fill all these out before writing + virtual bool SetHeader(const trpgHeader &); + virtual bool SetMaterialTable(const trpgMatTable &); + virtual bool SetTextureTable(const trpgTexTable &); + virtual bool SetModelTable(const trpgModelTable &); + virtual bool SetLightTable(const trpgLightTable &); + virtual bool SetRangeTable(const trpgRangeTable &); + virtual bool SetLabelPropertyTable(const trpgLabelPropertyTable &); + virtual bool SetSupportStyleTable(const trpgSupportStyleTable &); + virtual bool SetTextStyleTable(const trpgTextStyleTable &); - // Get functions. If we're doing a regenerate we need to get at these - virtual trpgHeader *GetHeader(); - virtual trpgMatTable *GetMatTable(); - virtual trpgTexTable *GetTextureTable(); - virtual trpgModelTable *GetModelTable(); - virtual trpgLightTable *GetLightTable(); - virtual trpgRangeTable *GetRangeTable(); + // Get functions. If we're doing a regenerate we need to get at these + virtual trpgHeader *GetHeader(); + virtual trpgMatTable *GetMatTable(); + virtual trpgTexTable *GetTextureTable(); + virtual trpgModelTable *GetModelTable(); + virtual trpgLightTable *GetLightTable(); + virtual trpgRangeTable *GetRangeTable(); + virtual trpgLabelPropertyTable *GetLabelPropertyTable(); + virtual trpgTextStyleTable *GetTextStyleTable(); + virtual trpgSupportStyleTable *GetSupportStyleTable(); - virtual bool IncrementTileFile(void); - virtual bool DesignateTileFile(int); - // 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 &); + virtual bool IncrementTileFile(void); + virtual bool DesignateTileFile(int); - bool isValid(void) const; - char* getDir(void){return dir;}; + // Write functions. + // For now, the header is written last. - // 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 - }; + virtual bool OpenFile(const char *,const char *); + virtual void CloseFile(void); + virtual bool WriteHeader(void); + virtual bool CheckpointHeader(void); + virtual bool WriteTile(unsigned int,unsigned int,unsigned int,float zmin,float zmax, + const trpgMemWriteBuffer *,const trpgMemWriteBuffer *); +// virtual bool WriteModel(unsigned int,trpgMemWriteBuffer &); + + bool isValid(void) const; + const char *getErrMess() const; + char* getDir(void){return dir;}; protected: - // Set if we're adding to an existing archive - bool isRegenerate; + // Set if we're adding to an existing archive + bool isRegenerate; - class TileFile { - public: - int id; - std::vector tiles; - }; + // 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 tiles; + }; - trpgEndian ness,cpuNess; - int version; - // Fed in from the outside - char dir[1024]; // Directory where we're doing all this + trpgEndian ness,cpuNess; + int version; + // Fed in from the outside + char dir[1024]; // Directory where we're doing all this - // These are passed in + // These are passed in - trpgHeader header; - trpgMatTable matTable; - trpgTexTable texTable; - trpgModelTable modelTable; - trpgLightTable lightTable; - trpgRangeTable rangeTable; + trpgHeader header; + trpgMatTable matTable; + trpgTexTable texTable; + trpgModelTable modelTable; + trpgLightTable lightTable; + trpgRangeTable rangeTable; + trpgTextStyleTable textStyleTable; + trpgSupportStyleTable supportStyleTable; + trpgLabelPropertyTable labelPropertyTable; - trpgTileTable tileTable; - int numX,numY,numLod; - TileMode tileMode; + trpgTileTable tileTable; - trpgwAppFile *tileFile; - int tileFileCount; + int numX,numY,numLod; + TileMode tileMode; - std::vector tileFiles; + trpgwAppFile *tileFile; + int tileFileCount; - int maxTileFileLen; + std::vector tileFiles; - FILE *fp; + int maxTileFileLen; + + // This offset is used when we're adding to an existing archive + trpg2iPoint addOffset; + + FILE *fp; + + bool firstHeaderWrite; + + mutable char errMess[512]; }; #endif diff --git a/src/osgPlugins/txp/trpage_writebuf.cpp b/src/osgPlugins/txp/trpage_writebuf.cpp index 33cf5eb11..8feb21942 100644 --- a/src/osgPlugins/txp/trpage_writebuf.cpp +++ b/src/osgPlugins/txp/trpage_writebuf.cpp @@ -18,19 +18,19 @@ #include /* 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" +#include +#include /* ********************** Memory Write Buffer functions @@ -39,274 +39,286 @@ // 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 *)&vlen); - append(len,val); + int32 len = (val ? strlen(val) : 0),vlen = len; + if (ness != cpuNess) + vlen = trpg_byteswap_int(vlen); + append(sizeof(int32),(const char *)&vlen); + append(len,val); +} + +// Add(std::string) +void trpgMemWriteBuffer::Add(std::string &val) +{ + Add(val.c_str()); } // Add(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) +//#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 +//#endif #if (trpgDiskRef != int64) // Add(trpgDiskRef) void trpgMemWriteBuffer::Add(trpgDiskRef val) { - if (ness != cpuNess) - val = trpg_byteswap_llong(val); + if (ness != cpuNess) + val = trpg_byteswap_llong(val); - append(sizeof(trpgDiskRef),(const char *)&val); + append(sizeof(trpgDiskRef),(const char *)&val); } #endif // Add(trpgToken) void trpgMemWriteBuffer::Add(trpgToken val) { - if (ness != cpuNess) - val = trpg_byteswap_short(val); + if (ness != cpuNess) + val = trpg_byteswap_short(val); - append(sizeof(trpgToken),(const char *)&val); + append(sizeof(trpgToken),(const char *)&val); } // Add(tx2iPoint) void trpgWriteBuffer::Add(const trpg2iPoint &val) { - Add((int32)val.x); - Add((int32)val.y); + Add((int32)val.x); + Add((int32)val.y); } // Add(tx2dPoint) void trpgWriteBuffer::Add(const trpg2dPoint &val) { - Add((float64)val.x); - Add((float64)val.y); + Add((float64)val.x); + Add((float64)val.y); } // Add(trpg3dPoint) void trpgWriteBuffer::Add(const trpg3dPoint &val) { - Add((float64)val.x); - Add((float64)val.y); - Add((float64)val.z); + Add((float64)val.x); + Add((float64)val.y); + Add((float64)val.z); } // Add(trpgColor) void trpgWriteBuffer::Add(const trpgColor &val) { - Add(val.red); - Add(val.green); - Add(val.blue); + Add(val.red); + Add(val.green); + Add(val.blue); +} + +// Add(std::string) +void trpgWriteBuffer::Add(const std::string &val) +{ + Add(val.c_str()); } /* 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. + 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(); + valid = false; + ness = inNess; + cpuNess = trpg_cpu_byte_order(); - if (!(fp = fopen(fileName,"wb"))) - return; + if (!(fp = fopen(fileName,"wb"))) + return; - lengthSoFar = 0; - valid = true; + lengthSoFar = 0; + valid = true; } trpgwAppFile::~trpgwAppFile() { - if (fp) - fclose(fp); - valid = false; + if (fp) + fclose(fp); + valid = false; } // Return the amount of data written so far (in total) @@ -318,74 +330,87 @@ int trpgwAppFile::GetLengthWritten() // Append the given buffer to our appendable file bool trpgwAppFile::Append(const trpgMemWriteBuffer *buf1,const trpgMemWriteBuffer *buf2) { - if (!isValid()) return false; + if (!isValid()) return false; - // Get the total length - int totLen = buf1->length() + (buf2 ? buf2->length() : 0); + // Get the total length + int totLen = buf1->length() + (buf2 ? buf2->length() : 0); - // Write the length out - if (fwrite(&totLen,sizeof(int32),1,fp) != 1) { - valid = false; - return false; - } + // Write the length out + if (fwrite(&totLen,sizeof(int32),1,fp) != 1) { + valid = false; + return false; + } - // Write the data out - const char *data = buf1->getData(); - int len = buf1->length(); - if (fwrite(data,sizeof(char),len,fp) != static_cast(len)) { - valid = false; - return false; - } - if (buf2) { - data = buf2->getData(); - len = buf2->length(); - if (fwrite(data,sizeof(char),len,fp) != static_cast(len)) { - 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; + lengthSoFar += totLen; - return true; + return true; } // Append the given raw data to our appendable file bool trpgwAppFile::Append(const char *data,int size) { - if (!isValid()) return false; + if (!isValid()) return false; - // Write the length out - if (fwrite(&size,sizeof(int32),1,fp) != 1) { - valid = false; - return false; - } + if (!data) + return false; - // Write the data out - if (fwrite(data,sizeof(char),size,fp) != static_cast(size)) { - valid = false; - return false; - } + // Write the length out + if (fwrite(&size,sizeof(int32),1,fp) != 1) { + valid = false; + return false; + } - lengthSoFar += size; + // Write the data out + if (fwrite(data,sizeof(char),size,fp) != size) { + valid = false; + return false; + } - return true; + lengthSoFar += size; + + return true; +} + +// Flushes the current tile file +bool trpgwAppFile::Flush() +{ + // Flush the File * + if (fp) + fflush(fp); + + return true; } // Return the current file position int64 trpgwAppFile::Pos() const { - if (!isValid()) - return 0; - - // Note: This means an appendable file is capped at 2GB - long pos = ftell(fp); + if (!isValid()) + return 0; + + // Note: This means an appendable file is capped at 2GB + long pos = ftell(fp); - return pos; + return pos; } // Validity check bool trpgwAppFile::isValid() const { - return valid; + return valid; }