Ejemplo n.º 1
0
    virtual void apply(osg::MatrixTransform& xform)
    {
        const trpgHeader* header = _archive->GetHeader();
        trpgHeader::trpgTileType tileType;
        header->GetTileOriginType(tileType);
        const osg::Referenced* ref = xform.getUserData();
        const TileIdentifier* tileID = dynamic_cast<const txp::TileIdentifier*>(ref);

        if(!tileID) return; // bail early - this isn't a loaded model

        if(tileType == trpgHeader::TileLocal && tileID->lod == 9999)
        {
        trpg2dPoint tileExtents;
        header->GetTileSize(0, tileExtents);
        osg::BoundingBox bbox;
        _archive->getExtents(bbox);
        osg::Vec3 offset(xform.getMatrix().getTrans());
        offset[0] -= bbox._min[0];
        offset[1] -= bbox._min[1];

        trpg2dPoint offsetXY, tileID(_tileInfo.x,_tileInfo.y);
        int divider = (0x01 << _tileInfo.lod);
        // calculate which tile model is located in
        tileExtents.x /= divider;
        tileExtents.y /= divider;
        offset[0] -= tileID.x*tileExtents.x;
        offset[1] -= tileID.y*tileExtents.y;

        osg::Matrix mat(xform.getMatrix());
        mat.setTrans(offset);
        xform.setMatrix(mat);
        }
    }
Ejemplo n.º 2
0
osg::Node* SeamFinder::seamReplacement(osg::Node* node)
{
    osg::Group* group = node->asGroup();
    if ( group == 0 )
        return node;

    std::vector<osg::Node*> nonSeamChildren;
    osg::LOD* hiRes = 0;
    osg::LOD* loRes = 0;

    const trpgHeader* header = _archive->GetHeader();
    trpgHeader::trpgTileType tileType;
    header->GetTileOriginType(tileType);

    for (unsigned int i = 0; i < group->getNumChildren(); i++)
    {
        osg::LOD* lod = dynamic_cast<osg::LOD*>(group->getChild(i));
        if (lod == 0)
        {
            nonSeamChildren.push_back(group->getChild(i));
            continue;
        }

        bool nonSeamChild = true;

        // looks like the problem is in here - likely due to seamLOD info
        // not being adjusted properly in tiled databases
            // seam center is outside the bounding box of the tile
        osg::Vec3 lodCenter = lod->getCenter();

        if(tileType == trpgHeader::TileLocal)
        {
            trpg2dPoint tileExtents;
            header->GetTileSize(0, tileExtents);
            osg::BoundingBox bbox;
            _archive->getExtents(bbox);
            osg::Vec3 offset(0.0, 0.0, 0.0);

            int divider = (0x1 << _lod);
            // calculate which tile model is located in
            tileExtents.x /= divider;
            tileExtents.y /= divider;
            offset[0] = _x*tileExtents.x;// + tileExtents.x*0.5;
            offset[1] = _y*tileExtents.y;// + tileExtents.y*0.5;
            lodCenter += offset;
        }

        if (!_info.bbox.contains(lodCenter))
        {
            const osg::LOD::RangeList& rangeList = lod->getRangeList();
            if (!rangeList.size())
            {
                // TODO: Warn here
                continue;
            }

            TXPArchive::TileInfo lod_plus_one_info;
            if (!this->_archive->getTileInfo(_x,_y,_lod+1,lod_plus_one_info))
            {
                // TODO: Warn here
                continue;
            }

            double lod_plus_oneSwitchInDistance =  lod_plus_one_info.maxRange;
            double lod0SwitchInDistance =  _info.lod0Range;

            // low res seam has min/max ranges of lod+1 range/lod 0 range
            if (equalDoubles(lod_plus_oneSwitchInDistance,rangeList.at(0).first) && equalDoubles(lod0SwitchInDistance,rangeList.at(0).second))
            {
                if (loRes==0)
                {
                    loRes = lod;
                    nonSeamChild = false;
                }
            }
            else
            // hi res seam has min/max ranges of 0 range/lod+1 range
            if (rangeList.at(0).first==0.0 && equalDoubles(lod_plus_oneSwitchInDistance,rangeList.at(0).second))
            {
                if (hiRes==0)
                {
                    hiRes = lod;
                    nonSeamChild = false;
                }
            }
        }
        if (nonSeamChild)
        {
            nonSeamChildren.push_back(lod);
        }
    }

    if (loRes)
    {
        int dx = 0;
        int dy = 0;
        int lod = _lod;
        osg::Vec3 lodCenter = loRes->getCenter();

        if(tileType == trpgHeader::TileLocal)
        {
            trpg2dPoint tileExtents;
            header->GetTileSize(0, tileExtents);
            osg::BoundingBox bbox;
            _archive->getExtents(bbox);
            osg::Vec3 offset(0.0, 0.0, 0.0);

            int divider = (0x1 << _lod);
            // calculate which tile model is located in
            tileExtents.x /= divider;
            tileExtents.y /= divider;
            offset[0] = _x*tileExtents.x;// + tileExtents.x*0.5;
            offset[1] = _y*tileExtents.y;// + tileExtents.y*0.5;
            lodCenter += offset;
        }

        osg::Vec3 delta = lodCenter-_info.center;
        if (fabs(delta.x())>fabs(delta.y()))
        {
            if ( delta.x() < 0.0 )
                --dx;    // west
            else
                dx++;                  // east
        }
        else
        {
            if ( delta.y() < 0.0 )
                --dy;    // south
            else
                ++dy;                  // north
        }

        TXPSeamLOD* seam = new TXPSeamLOD(_x, _y, lod, dx, dy);
        seam->setCenter(loRes->getCenter());
        seam->addChild(loRes->getChild(0));        // low res
        if (hiRes)
        {
            seam->addChild(hiRes->getChild(0));    // high res
        }

        if (nonSeamChildren.empty())
        {
            return seam;
        }
        else
        {
            osg::Group* newGroup = new osg::Group;

            newGroup->addChild(seam);

            for (unsigned int i = 0; i < nonSeamChildren.size(); i++)
                newGroup->addChild(nonSeamChildren[i]);

            return newGroup;
        }
    }

    return node;
}