readerwritertxp.cpp

来自「最新osg包」· C++ 代码 · 共 878 行 · 第 1/2 页

CPP
878
字号
#include <osg/Group>#include <osg/Object>#include <osg/Node>#include <osg/Notify>#include <osg/MatrixTransform>#include <osg/BoundingSphere>#include <osgDB/Registry>#include <osgDB/FileUtils>#include <osg/io_utils>#include <iostream>#include <sstream>#include "ReaderWriterTXP.h"#include "TXPNode.h"#include "TXPArchive.h"#include "TXPPagedLOD.h"#include "TXPSeamLOD.h"#include "TileMapper.h"#define ReaderWriterTXPERROR(s) osg::notify(osg::NOTICE) << "txp::ReaderWriterTXP::" << (s) << " error: "namespace{    char gbuf[2048];}using namespace txp;int ReaderWriterTXP::_archiveId = 0;osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::string& file, const osgDB::ReaderWriter::Options* options){    std::string name = osgDB::getSimpleFileName(file);    // We load archive.txp    if (strncmp(name.c_str(),"archive",7)==0)    {        std::string fileName = osgDB::findDataFile( file, options );        if ( fileName.empty() )            return ReadResult::FILE_NOT_FOUND;        osg::ref_ptr<TXPNode> txpNode = new TXPNode;        txpNode->setArchiveName(fileName);        if (options)         {            txpNode->setOptions(options->getOptionString());        }                //modified by Brad Anderegg on May-27-08        //calling getArchive will create a new TXPArchive if the specified one does not exist        //we will set our osgdb loader options on the archive and set the appropriate archive on         //the txpNode.        int id = ++_archiveId;        TXPArchive* archive = getArchive(id,osgDB::getFilePath(fileName));        if (archive != NULL)        {            archive->setId(id);            if (options && options->getOptionString().find("loadMaterialsToStateSet")!=std::string::npos)            {               archive->SetMaterialAttributesToStateSetVar(true);            }            txpNode->loadArchive(archive);                        return txpNode.get();        }        else        {            return ReadResult::ERROR_IN_READING_FILE;        }    }    // We load tileLOD_XxY_ID.txp    else if (strncmp(name.c_str(),"tile",4)==0)    {        int x,y,lod;        unsigned int id;        sscanf(name.c_str(),"tile%d_%dx%d_%u",&lod,&x,&y,&id);        TXPArchive* archive = getArchive(id,osgDB::getFilePath(file));        // The way this is done a 'tile' should only be created for lod 0 only,        // something is wrong if this is no the case        if(lod != 0)        {            ReaderWriterTXPERROR("ReaderWriterTXP::local_readNode()") << "paged 'tile' should be at lod 0" << std::endl;            return ReadResult::ERROR_IN_READING_FILE;        }        trpgEndian endian = archive->GetEndian();        archive->ReadSubArchive( 0, 0, endian);        archive->ReadSubArchive( y, x, endian);//    std::cout << "Attempted " << x << " " << y << std::endl;                TXPArchive::TileInfo info;        if (!archive->getTileInfo(x,y,lod,info))            return ReadResult::ERROR_IN_READING_FILE;        std::vector<TXPArchive::TileLocationInfo> childrenLoc;        osg::ref_ptr<osg::Node> tileContent = getTileContent(info,x,y,lod,archive, childrenLoc);                tileContent->setName("TileContent");        bool asChildren = false;        std::string childrenInfoStr;        int numLods = archive->getNumLODs();        int majorVersion, minorVersion;        archive->GetVersion(majorVersion, minorVersion);        if(majorVersion ==2 && minorVersion >=1)        {        // Version 2.1 and over        // The tile table only contains lod 0 and the children        // info are stored in its parent. SO if we do not want        // to be forced to reparse the parent we need to save that        // info. For now we just add it to the node name        if(childrenLoc.size() > 0)        {        asChildren = true;        createChildrenLocationString(childrenLoc, childrenInfoStr);        }        }        else        {        if (lod < (numLods-1))        asChildren = true;        }    if (asChildren)        {            char pagedLODfile[1024];            sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d",            archive->getDir(),            lod,            x,            y,            archive->getId());            strcat(pagedLODfile, childrenInfoStr.c_str());            strcat(pagedLODfile, ".txp");            // there are tile sets which do not maintain the z extents in            // the tile table.  This attempt to address the issue by using            // the geometry bounding sphere.  The downside is that this is            // not coupled to the generation and may result in runtime cracks            if (info.center.z() == 0)            {                osg::BoundingSphere bSphere = tileContent->getBound();                info.center.z() = bSphere.center().z();                info.radius = bSphere.radius();            }            osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;            // note: use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.            pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));            pagedLOD->setFileName(1,pagedLODfile);            pagedLOD->setRange(1,0,info.minRange);            pagedLOD->setCenter(info.center);            pagedLOD->setRadius(info.radius);            pagedLOD->setPriorityOffset(0,numLods-lod);            pagedLOD->setPriorityScale(0,1.0f);            pagedLOD->setNumChildrenThatCannotBeExpired(1);            pagedLOD->setTileId(x,y,lod);            const trpgHeader* header = archive->GetHeader();            trpgHeader::trpgTileType tileType;            header->GetTileOriginType(tileType);            if(tileType == trpgHeader::TileLocal)            {                osg::Vec3d sw(info.bbox._min);                pagedLOD->setCenter(info.center - sw);            }            return pagedLOD.get();        }        else            return tileContent.get();    }        // For 2.0 and lower we load subtilesLOD_XxY_ID.txp    // For 2.1 and over  we load subtilesLOD_XxY_ID_NBCHILD_{X_Y_FID_FOFFSET_ZMIN_ZMAX_X_Y_ADDR ....}.txp    else if (strncmp(name.c_str(),"sub",3)==0)    {        int x,y,lod;        unsigned int id;        sscanf(name.c_str(),"subtiles%d_%dx%d_%u",&lod,&x,&y,&id);        TXPArchive* archive = getArchive(id,osgDB::getFilePath(file));        int majorVersion, minorVersion;        archive->GetVersion(majorVersion, minorVersion);        std::vector<TXPArchive::TileLocationInfo> childrenLoc;        osg::ref_ptr<osg::Group> subtiles = new osg::Group;        int numLods = archive->getNumLODs();        if(majorVersion == 2  && minorVersion >= 1)        {            int nbChild;            sscanf(name.c_str(),"subtiles%d_%dx%d_%u_%d",&lod,&x,&y,&id, &nbChild);            std::vector<TXPArchive::TileLocationInfo> locs;            bool status = true;            status = extractChildrenLocations(name, lod, locs, nbChild);        if(majorVersion >= TRPG_NOMERGE_VERSION_MAJOR && minorVersion >=TRPG_NOMERGE_VERSION_MINOR && archive->GetHeader()->GetIsMaster())        {        for(int idx=0;idx<nbChild;idx++)        {            //figure out the block row/col            int blockx,blocky;            unsigned int denom = (1 << locs[idx].lod); // this should work up to lod 31            blockx = locs[idx].x/denom;            blocky = locs[idx].y/denom;            locs[idx].addr.col = blockx;            locs[idx].addr.row = blocky;        }        }            if(!status)            {        ReaderWriterTXPERROR("ReaderWriterTXP::local_readNode()") << "'subtile' filename children parsing failed " << std::endl;        return ReadResult::ERROR_IN_READING_FILE;            }            const trpgHeader* header = archive->GetHeader();            trpgHeader::trpgTileType tileType;            header->GetTileOriginType(tileType);        TXPArchive::TileLocationInfo plInfo;        plInfo.x = x;        plInfo.y = y;        plInfo.lod = lod;            TXPArchive::TileInfo parentInfo;            archive->getTileInfo(plInfo,parentInfo);            for(int idx = 0; idx < nbChild; ++idx)            {        std::vector<TXPArchive::TileLocationInfo> childrenChildLoc;                       TXPArchive::TileLocationInfo& loc = locs[idx];                       TXPArchive::TileInfo info;        if (!archive->getTileInfo(loc,info))            continue;        osg::ref_ptr<osg::Node> tileContent = getTileContent(info, loc, archive, childrenChildLoc);        tileContent->setName("TileContent");        if(childrenChildLoc.size() > 0)        {            std::string childInfoStr;            createChildrenLocationString(childrenChildLoc, childInfoStr);            char pagedLODfile[1024];            sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d%s.txp",                archive->getDir(),                loc.lod,                loc.x,                loc.y,                archive->getId(),                childInfoStr.c_str());                    // there are tile sets which do not maintain the z extents in                    // the tile table.  This attempt to address the issue by using                    // the geometry bounding sphere.  The downside is that this is                    // not coupled to the generation and may result in runtime cracks                    if (info.center.z() == 0)                    {                        osg::BoundingSphere bSphere = tileContent->getBound();                        info.center.z() = bSphere.center().z();                        info.radius = bSphere.radius();                    }            osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;                    // note: use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.            pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));            pagedLOD->setFileName(1,pagedLODfile);            pagedLOD->setRange(1,0,info.minRange);            pagedLOD->setCenter(info.center);            pagedLOD->setRadius(info.radius);            pagedLOD->setPriorityOffset(0,numLods - loc.lod);            pagedLOD->setPriorityScale(0,1.0f);            pagedLOD->setNumChildrenThatCannotBeExpired(1);            pagedLOD->setTileId(loc.x, loc.y, loc.lod);            if(tileType == trpgHeader::TileLocal)            {            osg::Vec3d center(info.center - parentInfo.bbox._min);            osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);            sw[2] = 0.0;            pagedLOD->setCenter(center - sw);            osg::Matrix offset;            offset.setTrans(sw);            osg::MatrixTransform *tform = new osg::MatrixTransform(offset);            tform->addChild(pagedLOD.get());            subtiles->addChild(tform);            }            else            subtiles->addChild(pagedLOD.get());            subtiles->setUserData(new TileIdentifier(loc.x, loc.y, loc.lod)); // is this really needed?        }        else        {            subtiles->setUserData(new TileIdentifier(loc.x, loc.y, loc.lod));            if(tileType == trpgHeader::TileLocal)            {            osg::Vec3d center(info.center - parentInfo.bbox._min);            osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);            sw[2] = 0.0;            osg::Matrix offset;            offset.setTrans(sw);            osg::MatrixTransform *tform = new osg::MatrixTransform(offset);            tform->addChild(tileContent.get());            subtiles->addChild(tform);            }            else            subtiles->addChild(tileContent.get());        }            }        }        else        {                    int sizeX, sizeY;        archive->getLODSize(lod+1,sizeX,sizeY);        const trpgHeader* header = archive->GetHeader();        trpgHeader::trpgTileType tileType;        header->GetTileOriginType(tileType);        TXPArchive::TileInfo parentInfo;        archive->getTileInfo(x,y,lod,parentInfo);        for (int ix = 0; ix < 2; ix++)        {        for (int iy = 0; iy < 2; iy++)        {            int tileX = x*2+ix;            int tileY = y*2+iy;            int tileLOD = lod+1;            TXPArchive::TileInfo info;            if (!archive->getTileInfo(tileX,tileY,tileLOD,info))            continue;            osg::ref_ptr<osg::Node> tileContent = getTileContent(info,tileX,tileY,tileLOD,archive, childrenLoc);            tileContent->setName("TileContent");            if (tileLOD < (numLods-1))            {            char pagedLODfile[1024];            sprintf(pagedLODfile,"%s\\subtiles%d_%dx%d_%d.txp",                archive->getDir(),                tileLOD,                tileX,                tileY,                archive->getId());            // there are tile sets which do not maintain the z extents in            // the tile table.  This attempt to address the issue by using            // the geometry bounding sphere.  The downside is that this is            // not coupled to the generation and may result in runtime cracks            if (info.center.z() == 0)            {                osg::BoundingSphere bSphere = tileContent->getBound();                info.center.z() = bSphere.center().z();                info.radius = bSphere.radius();            }            osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;                        // note: use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.            pagedLOD->addChild(tileContent.get(),info.minRange,osg::maximum(info.maxRange,1e7));            pagedLOD->setFileName(1,pagedLODfile);            pagedLOD->setRange(1,0,info.minRange);            pagedLOD->setCenter(info.center);            pagedLOD->setRadius(info.radius);            pagedLOD->setPriorityOffset(0,numLods-lod);            pagedLOD->setPriorityScale(0,1.0f);            pagedLOD->setNumChildrenThatCannotBeExpired(1);            pagedLOD->setTileId(tileX,tileY,tileLOD);            if(tileType == trpgHeader::TileLocal)            {                osg::Vec3d center(info.center - parentInfo.bbox._min);                osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);                sw[2] = 0.0;                pagedLOD->setCenter(center - sw);                osg::Matrix offset;                offset.setTrans(sw);                osg::MatrixTransform *tform = new osg::MatrixTransform(offset);                tform->addChild(pagedLOD.get());                subtiles->addChild(tform);            }            else                subtiles->addChild(pagedLOD.get());            }            else            {            subtiles->setUserData(new TileIdentifier(tileX,tileY,tileLOD));            if(tileType == trpgHeader::TileLocal)            {                osg::Vec3d center(info.center - parentInfo.bbox._min);                osg::Vec3d sw(info.bbox._min - parentInfo.bbox._min);                sw[2] = 0.0;                osg::Matrix offset;                offset.setTrans(sw);                osg::MatrixTransform *tform = new osg::MatrixTransform(offset);                tform->addChild(tileContent.get());                subtiles->addChild(tform);            }            else                subtiles->addChild(tileContent.get());            }        }        }        }        //osg::notify(osg::NOTICE) << "Subtiles for " << x << " " << y << " " << lod << " lodaded" << std::endl;        return subtiles.get();    }    

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?