Esempio n. 1
0
void trpgwArchive::Init(trpgEndian inNess, trpgwArchive::TileMode inTileMode, int majorVer, int minorVer)
{
    minorVersion = minorVer;
    majorVersion = majorVer;
    if (majorVersion < 1 || majorVersion > TRPG_VERSION_MAJOR)
        throw 1;

    if (majorVersion == TRPG_VERSION_MAJOR)
    {
        if (minorVersion < 0 || minorVersion > TRPG_VERSION_MINOR)
            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
trpgMemWriteBuffer::trpgMemWriteBuffer(trpgEndian in_ness)
{
    ness = in_ness;
    cpuNess = trpg_cpu_byte_order();
    data = NULL;
    curLen = totLen = 0;
}
/* *************************
   Memory Read Buffer
   *************************
   */
trpgMemReadBuffer::trpgMemReadBuffer(trpgEndian in_ness)
{
    data = NULL;
    len = totLen = pos = 0;
    ness = in_ness;
    cpuNess = trpg_cpu_byte_order();
}
void trpgrAppFile::Init(trpgEndian inNess,const char *fileName)
{
    valid = false;
    ness = inNess;
    cpuNess = trpg_cpu_byte_order();

    if (!(fp = osgDB::fopen(fileName,"rb")))
        return;

    valid = true;
}
void trpgwAppFile::Init(trpgEndian inNess,const char *fileName,bool reuse)
{
    valid = false;
    ness = inNess;
    cpuNess = trpg_cpu_byte_order();

    if (reuse==false) {
        if (!(fp = osgDB::fopen(fileName,"wb")))
            return;
        lengthSoFar = 0;
        valid = true;
    } else {
        if (!(fp = osgDB::fopen(fileName,"ab")))
            return;
        // ftell is still zero, dammit.  Arg.
        fseek(fp,0,SEEK_END);
        lengthSoFar = ftell(fp);
        valid = true;
    }    
}
Esempio n. 6
0
// Collect the current vertex data and add a new whole vertex
// Note: Deal with color
void trpgwGeomHelper::AddVertex(trpg3dPoint &pt)
{
    polyTex.insert(polyTex.end(),tmpTex.begin(),tmpTex.end());
    polyNorm.push_back(tmpNorm);
// Note: Turn this back on.  It's not right currently, though
#if 0
    if (buf->GetEndian() != trpg_cpu_byte_order())
    {
        trpg3dPoint tmpVert;
        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);
    }
    else
#endif
        polyVert.push_back(pt);

    // Update min/max
    zmin = MIN(pt.z,zmin);
    zmax = MAX(pt.z,zmax);
}
// Open File
// Open the given file and look for the file specific info
bool trpgr_Archive::OpenFile(const char *name)
{
    char file[1025];
    sprintf(file,"%s" PATHSEPERATOR "%s",dir,name);

    CloseFile();

    if (!(fp = osgDB::fopen(file,"rb")))
        return false;

    // Look for a magic # and endianness
    int32 magic;
    if (fread(&magic,sizeof(int32),1,fp) != 1)
        return false;

    headerRead = false;

    // Figure out the endianness from the magic number
    trpgEndian cpuNess = trpg_cpu_byte_order();
    if (magic == GetMagicNumber()) {
        ness = cpuNess;
        return true;
    }
    if (trpg_byteswap_int(magic) == GetMagicNumber()) {
        if (cpuNess == LittleEndian)
            ness = BigEndian;
        else
            ness = LittleEndian;
        return true;
    }
    if (magic != GetMagicNumber())
        return false;

    // Not one of our files
    return false;
}
// Read Header
// Run through the rest of the header information
bool trpgr_Archive::ReadHeader(bool readAllBlocks)
{
    int ret;

    if (!fp || headerRead)
        return false;

    headerRead = true;

    // Next int64 should be the header size
    trpgEndian cpuNess = trpg_cpu_byte_order();
    int32 headerSize;
    if (fread(&headerSize,sizeof(int32),1,fp) != 1)
        return false;
    if (ness != cpuNess)
        headerSize = trpg_byteswap_int(headerSize);
    int headLen = headerSize;
    if (headLen < 0)
        return false;

    // Read in the header whole
    trpgMemReadBuffer buf(ness);
    buf.SetLength(headLen);
    char *data = buf.GetDataPtr();
    if ((ret = GetHeaderData(data,headLen,fp)) != headLen)
        return false;

    // Set up a parser
    // Catch the tables we need for the archive
    trpgMatTable1_0 oldMatTable;
    trpgTexTable1_0 oldTexTable;
    trpgr_Parser parser;
    parser.AddCallback(TRPGHEADER,&header);
    parser.AddCallback(TRPGMATTABLE,&materialTable);    // Went back to oldest style for 2.0
    parser.AddCallback(TRPGMATTABLE2,&oldMatTable);     // Added 11-14-98 (1.0 material table)
    parser.AddCallback(TRPGTEXTABLE,&oldTexTable);
    parser.AddCallback(TRPGTEXTABLE2,&texTable);            // Added for 2.0
    parser.AddCallback(TRPGMODELTABLE,&modelTable);
    parser.AddCallback(TRPGLIGHTTABLE,&lightTable);                // Added for 2.0
    parser.AddCallback(TRPGRANGETABLE,&rangeTable);                // Added for 2.0
    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;

    if(header.GetIsMaster())
    {
        // bool firstBlock = true;
        //if the master has textures, we want to use them instead of the tables in the
        //block archives

        // int numTiles = 0;
        //tileTable.
        int totalrows,totalcols;
        trpg2dPoint mhdr_swExtents;
        trpg2dPoint mhdr_neExtents;
        trpg3dPoint mhdr_Origin;
        // integrate header information from the block header.
        header.GetExtents(mhdr_swExtents,mhdr_neExtents);
        header.GetOrigin(mhdr_Origin);
        header.GetBlocks(totalrows,totalcols);
        if(readAllBlocks) {
            for(int row=0;row<totalrows;row++) {
                for(int col=0;col<totalcols;col++) {
                    // Read each block -- Warning, this can take a while!!!
                    ReadSubArchive( row, col, cpuNess);
                }
            }
        }
        else {
            ReadSubArchive( 0, 0, cpuNess);//Get the first archive!
        }

    }
    tileTable.SetCurrentBlock(-1,-1,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;

    // Set up a tile cache, if needed
    trpgTileTable::TileMode tileMode;
    tileTable.GetMode(tileMode);
    if (tileMode == trpgTileTable::Local) {
        if (tileCache)  delete tileCache;
        char fullBase[1060];
        sprintf(fullBase,"%s" PATHSEPERATOR "tileFile",dir);
        tileCache = GetNewRAppFileCache(fullBase,"tpf");
    }

    valid = true;

    return true;
}
Esempio n. 9
0
void trpgwArchive::Init(char *inDir,char *inFile,trpg2dPoint &sw, trpg2dPoint &ne, int majorVer, int minorVer)
{
    maxTileFileLen = -1;
    majorVersion = majorVer;
    minorVersion = minorVer;
    fp = NULL;
    strcpy(dir,inDir);
    cpuNess = trpg_cpu_byte_order();
    tileFile = NULL;
    tileFileCount = 0;
    isRegenerate = true;
    errMess[0] = '\0';

    // TODO: have a "setup from file" method for trpgwArchive

    // Open a Read Archive to get the rest of the info we need
    trpgr_Archive *inArch = this->GetArchiveReader();
    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();
    const trpgHeader *inHeader = inArch->GetHeader();

    // use the version in the archive instead.
    inHeader->GetVersion(majorVersion,minorVersion);

    // Expand the coverage
    trpg2dPoint newSW,newNE;
    trpg2dPoint oldSW,oldNE;

    // Or not.  Have to add in something to avoid recalculation
    // when merging geocentric databases.  We don't really support
    // them, and everything goes to hell.  So: hack is:
    // if sw=ne, don't change anything.
    // This will also help a little with MMB TXP merge speed.

    bool extentsUnchanged=false;
    inHeader->GetExtents(oldSW,oldNE);
    // just checking for equality right now.  Bad?
    if ((sw==ne) || ((oldSW==sw) && (oldNE==ne)))
    {
        extentsUnchanged = true;
        // set up passed-in SW and NE as well.
        sw=newSW=oldSW;
        ne=newNE=oldNE;
    }
    else
    {
        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);
    }

    // Decide what the offset should be for new tiles
    if (!extentsUnchanged)
    {
        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 = (int)dx;
        addOffset.y = (int)dy;
        if (dx - addOffset.x > 10e-4 ||
            dy - addOffset.y > 10e-4) {
            delete inArch;
            throw 1;
        }
    }

    // Header can mostly stay the same
    header = *inHeader;
    header.SetExtents(newSW,newNE);
    header.GetNumLods(numLod);
    // Update to the new MBR and tile grid sizes
    if (!extentsUnchanged) {
        for (int i=0;i<numLod;i++) {
            // Figure out the tile grid size
            trpg2dPoint tileSize;
            inHeader->GetTileSize(i,tileSize);
            trpg2iPoint newTileExt;
            newTileExt.x = int((newNE.x - newSW.x)/tileSize.x + 10e-5);
            newTileExt.y = int((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 (maybe)
    // NOTE: Starting with version 2.1, the tile tables will contain only 
    // the lod 0 tiles
    trpgTileTable::TileMode tileTableMode;
    if (!extentsUnchanged) {
        const trpgTileTable *oldTiles = inArch->GetTileTable();
        oldTiles->GetMode(tileTableMode);
        tileTable.SetMode(tileTableMode);
        if(majorVersion == 2 && minorVersion >=1)
        {
            // Version 2.1. we store only lod 0, all other lod tiles are
            // stored in the parent tile
            tileTable.SetNumLod(0);
            // Size the output tile table
            trpg2iPoint tileSize;
            header.GetLodSize(0,tileSize);
            tileTable.SetNumTiles(tileSize.x, tileSize.y, 0);

            // Copy over individual tiles
            trpg2iPoint levelOffset;
            levelOffset.x = addOffset.x;
            levelOffset.y = addOffset.y;
            trpg2iPoint oldTileSize;
            inHeader->GetLodSize(0, oldTileSize);
            for (int ix=0;ix<oldTileSize.x;ix++) {
                for (int iy=0;iy<oldTileSize.y;iy++) {
                    trpgwAppAddress addr;
                    float zmin,zmax;
                    oldTiles->GetTile(ix, iy, 0,addr,zmin,zmax);
                    tileTable.SetTile(ix+addOffset.x, iy+addOffset.y ,0, addr, zmin, zmax);
                }
            }

        }
        else
        {
            tileTable.SetNumLod(numLod);
            for (int lod=0;lod<numLod;lod++) {
                // Size the output tile table
                trpg2iPoint tileSize;
                header.GetLodSize(lod,tileSize);
                tileTable.SetNumTiles(tileSize.x,tileSize.y,lod);

                // Copy over individual tiles
                trpg2iPoint levelOffset;
                levelOffset.x = addOffset.x*(lod+1);
                levelOffset.y = addOffset.y*(lod+1);
                trpg2iPoint oldTileSize;
                inHeader->GetLodSize(lod,oldTileSize);
                for (int ix=0;ix<oldTileSize.x;ix++) {
                    for (int iy=0;iy<oldTileSize.y;iy++) {
                        trpgwAppAddress addr;
                        float zmin,zmax;
                        oldTiles->GetTile(ix,iy,lod,addr,zmin,zmax);
                        tileTable.SetTile(ix+addOffset.x,iy+addOffset.y,lod,addr,zmin,zmax);
                    }
                }
            }
        }
    } else {
        tileTable = *inArch->GetTileTable();
        tileTable.GetMode(tileTableMode);
    }

    // Continue to work in the mode the original database is in
    switch(tileTableMode)
    {
    case trpgTileTable::Local:
        tileMode = TileLocal;
        break;
    case trpgTileTable::External:
        tileMode = TileExternal;
        break;
    case trpgTileTable::ExternalSaved:
        tileMode = TileExternalSaved;
        break;
    }


    // That's it for the read archive
    delete inArch;
}