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

Revision 10965, 9.3 kB (checked in by robert, 4 years ago)

Added #include <stdio.h> for Mingw build

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