root/OpenSceneGraph/trunk/src/osgPlugins/txp/TXPNode.cpp @ 8437

Revision 8437, 9.3 kB (checked in by robert, 7 years ago)

Added mutex to serialize access to the trpager

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[2570]1#include <osg/Notify>
2#include <osg/BoundingBox>
3#include <osg/PagedLOD>
[2651]4#include <osg/Timer>
[4542]5#include <osg/MatrixTransform>
[2651]6#include <osgUtil/CullVisitor>
[2570]7
8#include <iostream>
9#include <vector>
10#include <algorithm>
11
[2571]12#include "TileMapper.h"
[2570]13#include "TXPNode.h"
[2621]14#include "TXPPagedLOD.h"
[2651]15
16
17
[2570]18using namespace txp;
[2688]19using namespace osg;
[2570]20
21
22
[5188]23class RetestCallback : public osg::NodeCallback
24{
[2570]25
[5188]26public:
27    RetestCallback()
28    {
[8372]29        timer = osg::Timer::instance(); // get static timer
[5188]30        prevTime = 0; // should this be instantiated with current time?
31    }
32
33    virtual void operator () ( osg::Node * node, osg::NodeVisitor * nv )
34    {
35        osg::Group *pLOD = (osg::Group *) node;
36        osg::Group *n = NULL;
37        if ((pLOD->getNumChildren() > 0) &&
38            (n = (osg::Group *) pLOD->getChild(0)) &&
39            (n->getNumChildren() == 0))
40        {
[8372]41            osg::Timer_t curTime = timer->tick();
[5188]42            if ((prevTime + 2.0/timer->getSecondsPerTick() ) < curTime)
43            {
44                prevTime = curTime;
45                pLOD->removeChildren( 0, pLOD->getNumChildren());
46            }
47        }
48
49        NodeCallback::traverse( node, nv );
50    }
51
52protected:
53    const osg::Timer* timer;
54    osg::Timer_t prevTime;
55};
56
57
58
[2570]59#define TXPNodeERROR(s) osg::notify(osg::NOTICE) << "txp::TXPNode::" << (s) << " error: "
60
61TXPNode::TXPNode():
62osg::Group(),
63_originX(0.0),
64_originY(0.0)
65{
66    setNumChildrenRequiringUpdateTraversal(1);
[8372]67    setCullingActive(false);
[2570]68}
69           
70TXPNode::TXPNode(const TXPNode& txpNode,const osg::CopyOp& copyop):
71osg::Group(txpNode,copyop),
72_originX(txpNode._originX),
73_originY(txpNode._originY)
74{
75    setNumChildrenRequiringUpdateTraversal(1);
76}
77
78TXPNode::~TXPNode()
79{
80}
81
82TXPArchive* TXPNode::getArchive()
83{
84    return _archive.get();
85}
86
87void TXPNode::traverse(osg::NodeVisitor& nv)
88{
89    switch(nv.getVisitorType())
90    {
[5188]91    case osg::NodeVisitor::CULL_VISITOR:
92    {
[8437]93
94        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
[2651]95               
96        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
97        if (cv)
98        {
[5188]99//#define PRINT_TILEMAPP_TIMEINFO
100#ifdef PRINT_TILEMAPP_TIMEINFO
[2658]101            const osg::Timer& timer = *osg::Timer::instance();
102            osg::Timer_t start = timer.tick();
103            std::cout<<"Doing visible tile search"<<std::endl;
[5188]104#endif // PRINT_TILEMAPP_TIMEINFO
[2651]105       
106            osg::ref_ptr<TileMapper> tileMapper = new TileMapper;
[2658]107            tileMapper->setLODScale(cv->getLODScale());
[6109]108            tileMapper->pushReferenceViewPoint(cv->getReferenceViewPoint());
[2651]109            tileMapper->pushViewport(cv->getViewport());
[6248]110            tileMapper->pushProjectionMatrix((cv->getProjectionMatrix()));
111            tileMapper->pushModelViewMatrix((cv->getModelViewMatrix()), osg::Transform::RELATIVE_RF);
[2651]112
113            // traverse the scene graph to search for valid tiles
114            accept(*tileMapper);
115
116            tileMapper->popModelViewMatrix();
117            tileMapper->popProjectionMatrix();
118            tileMapper->popViewport();
[6109]119            tileMapper->popReferenceViewPoint();
[2651]120
121            //std::cout<<"   found " << tileMapper._tileMap.size() << std::endl;
122           
123            tileMapper->checkValidityOfAllVisibleTiles();
124           
125            cv->setUserData(tileMapper.get());
126
[2658]127#ifdef PRINT_TILEMAPP_TIMEINFO       
128            std::cout<<"Completed visible tile search in "<<timer.delta_m(start,timer.tick())<<std::endl;
129#endif // PRINT_TILEMAPP_TIMEINFO       
[2651]130
131        }       
132   
[2570]133        updateEye(nv);
134        break;
[5188]135    }
136    case osg::NodeVisitor::UPDATE_VISITOR:
[8437]137    {
138        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
139
[2570]140        updateSceneGraph();
141        break;
[8437]142    }
[5188]143    default:
[2570]144        break;
145    }
[2576]146    Group::traverse(nv);
[2570]147}
148
[4202]149osg::BoundingSphere TXPNode::computeBound() const
[2570]150{
[4641]151#if 1
152
153    // Steve Lunsford 10/28/05 : - Had to avoid using the child group nodes for bounds calculation
154    // because apparently the loader doesn't load all the sub-tiles for this node, resulting in a Group::computeBounds
155    // call which returns a size smaller than the actual size represented by this node so consequently this node gets culled out.
156    // note, submission merged and rearranged by Robert Osfield as an #if #else just in case we need to revert.
157    return osg::BoundingSphere( _extents );
158#else
159    // original code which uses the extents of the children when one is available.
[2570]160    if (getNumChildren() == 0)
161    {
[4202]162        return osg::BoundingSphere( _extents );
[2570]163    }
[2575]164    return Group::computeBound();
[4641]165#endif
[2570]166}
167
168void TXPNode::setArchiveName(const std::string& archiveName)
169{
170    _archiveName = archiveName;
171}
172
173void TXPNode::setOptions(const std::string& options)
174{
175    _options = options;
176}
177
178const std::string& TXPNode::getOptions() const
179{
180    return _options;
181}
182
183const std::string& TXPNode::getArchiveName() const
184{
185    return _archiveName;
186}
187
[8372]188bool TXPNode::loadArchive(TXPArchive* archive)
[2570]189{
[8372]190    //if (_archive.get())
191    //{
192    //    TXPNodeERROR("loadArchive()") << "archive already open" << std::endl;
193    //    return false;
194    //}
[2570]195
196
[8372]197   //modified by Brad Anderegg on May-27-08
198   //if NULL is passed in we will create a new archive and open the database
199   //otherwise we will use the archive provided which should have already been loaded
200   //by ReaderWriterTXP::getArchive(). See line 57-77 of ReaderWriterTXP.cpp.
201   if(archive == NULL)
202   {
203       _archive = new TXPArchive;
204       if (_archive->openFile(_archiveName) == false)
205       {
206           TXPNodeERROR("loadArchive()") << "failed to load archive: \"" << _archiveName << "\"" << std::endl;
207           return false;
208       }
209   }
210   else
211   {
212      _archive = archive;
213   }
[2570]214
215    _archive->getOrigin(_originX,_originY);
216    _archive->getExtents(_extents);
217
218    int32 numLod;
219    _archive->GetHeader()->GetNumLods(numLod);
220
221    trpg2iPoint tileSize;
222    _archive->GetHeader()->GetLodSize(0,tileSize);
223
224    _pageManager = new TXPPageManager;
225
[5188]226    // We are going to use _pageManager to manage lod 0 only, all other lod
227    // are managed by this OSG plugin
228    _pageManager->Init(_archive.get(), 1);
229
[2570]230    return true;
231}
232
233void TXPNode::updateEye(osg::NodeVisitor& nv)
234{
[3391]235    if (!_pageManager)
236    {
237        osg::notify(osg::NOTICE)<<"TXPNode::updateEye() no pageManager created"<<std::endl;
238        return;
239    }
240
[2570]241    trpg2dPoint loc;
242    loc.x = nv.getEyePoint().x() - _originX;
243    loc.y = nv.getEyePoint().y() - _originY;
244
245    if (_pageManager->SetLocation(loc))
246    {
247        trpgManagedTile *tile=NULL;
248
249        while((tile = _pageManager->GetNextUnload()))
250        {
251            int x,y,lod;
252            tile->GetTileLoc(x,y,lod);
253            if (lod == 0)
254            {
255                osg::Node* node = (osg::Node*)(tile->GetLocalData());
256                _nodesToRemove.push_back(node);
257
258                //osg::notify(osg::NOTICE) << "Tile unload: " << x << " " << y << " " << lod << std::endl;
259            }
260            _pageManager->AckUnload();
261        }
262
263        while ((tile = _pageManager->GetNextLoad()))
264        {
265            int x,y,lod;
266            tile->GetTileLoc(x,y,lod);
267            if (lod==0)
268            {
[5188]269                osg::Node* node = addPagedLODTile(x,y);
[2570]270                tile->SetLocalData(node);
271                //osg::notify(osg::NOTICE) << "Tile load: " << x << " " << y << " " << lod << std::endl;
272            }
273            _pageManager->AckLoad();
274           
275        }
276    }
277}
278
[5188]279osg::Node* TXPNode::addPagedLODTile(int x, int y)
[2570]280{
[5188]281    // For TerraPage 2.1 and over this method must only be use with lod = 0.
282    // If you look at the code that calls it, it is effectively called only when
283    // lod = 0. So all is OK
284    int lod = 0;
[2570]285    char pagedLODfile[1024];
286    sprintf(pagedLODfile,"%s\\tile%d_%dx%d_%d.txp",_archive->getDir(),lod,x,y,_archive->getId());
287
288
289    TXPArchive::TileInfo info;
290    _archive->getTileInfo(x,y,lod,info);
291
[2651]292    osg::PagedLOD* pagedLOD = new osg::PagedLOD;
[2570]293    pagedLOD->setFileName(0,pagedLODfile);
[2622]294    pagedLOD->setPriorityOffset(0,_archive->getNumLODs());
[2607]295    pagedLOD->setPriorityScale(0,1.0f);
[2570]296    pagedLOD->setRange(0,0.0,info.maxRange);
297    pagedLOD->setCenter(info.center);
298    pagedLOD->setRadius(info.radius);
299    pagedLOD->setNumChildrenThatCannotBeExpired(1);
[5188]300    pagedLOD->setUpdateCallback(new RetestCallback);
[2570]301
[4542]302    const trpgHeader* header = _archive->GetHeader();
303    trpgHeader::trpgTileType tileType;
304    header->GetTileOriginType(tileType);
305    if(tileType == trpgHeader::TileLocal)
306    {
307        // add in MatrixTransform node with Matrixd offsets
308        // get offsets from tile.bbox
309        osg::Vec3d sw(info.bbox._min);
310        sw[2] = 0.0;
311        osg::Matrix offset;
312        offset.setTrans(sw);
313        osg::MatrixTransform *tform = new osg::MatrixTransform(offset);
314        pagedLOD->setCenter(info.center - sw);
315        tform->addChild(pagedLOD);
316        _nodesToAdd.push_back(tform);
317        return tform;
318    }
319    else
320    {
[5188]321    _nodesToAdd.push_back(pagedLOD);
322   
323    return pagedLOD;
[2570]324}
[5188]325}
[2570]326
327void TXPNode::updateSceneGraph()
328{
329    if (!_nodesToRemove.empty())
330    {
331        for (unsigned int i = 0; i < _nodesToRemove.size(); i++)
332        {
333            removeChild(_nodesToRemove[i]);
334        }
335        _nodesToRemove.clear();
336    }
337
338    if (!_nodesToAdd.empty())
339    {
340        for (unsigned int i = 0; i < _nodesToAdd.size(); i++)
341        {
342            addChild(_nodesToAdd[i]);
343        }
344        _nodesToAdd.clear();
345       
[2651]346    }   
[2570]347}
348
Note: See TracBrowser for help on using the browser.