diff --git a/VisualStudio/osgPlugins/ive/ive.dsp b/VisualStudio/osgPlugins/ive/ive.dsp index 9aa4fad3e..d82bfd128 100755 --- a/VisualStudio/osgPlugins/ive/ive.dsp +++ b/VisualStudio/osgPlugins/ive/ive.dsp @@ -186,6 +186,10 @@ SOURCE=..\..\..\src\osgPlugins\ive\LOD.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\ive\PagedLOD.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\ive\Material.cpp # End Source File # Begin Source File @@ -370,6 +374,10 @@ SOURCE=..\..\..\src\osgPlugins\ive\LOD.h # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\ive\PagedLOD.h +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\ive\Material.h # End Source File # Begin Source File diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index d3ed21ba6..533127f3d 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -170,6 +170,10 @@ public: void DatabasePager::run() { std::cout<<"DatabasePager::run()"<setExpiryDelay(10.0f); while(true) { diff --git a/src/osgPlugins/ive/DataInputStream.cpp b/src/osgPlugins/ive/DataInputStream.cpp index 6c03c9b68..34498b79e 100644 --- a/src/osgPlugins/ive/DataInputStream.cpp +++ b/src/osgPlugins/ive/DataInputStream.cpp @@ -33,6 +33,7 @@ #include "Billboard.h" #include "Sequence.h" #include "LOD.h" +#include "PagedLOD.h" //#include "ViewPoint.h" #include "PositionAttitudeTransform.h" #include "Transform.h" @@ -556,6 +557,10 @@ osg::Node* DataInputStream::readNode() node = new osg::LOD(); ((ive::LOD*)(node))->read(this); } + else if(nodeTypeID== IVEPAGEDLOD){ + node = new osg::PagedLOD(); + ((ive::PagedLOD*)(node))->read(this); + } else if(nodeTypeID== IVESWITCH){ node = new osg::Switch(); ((ive::Switch*)(node))->read(this); diff --git a/src/osgPlugins/ive/DataOutputStream.cpp b/src/osgPlugins/ive/DataOutputStream.cpp index e0ff0b4fb..e060a31e2 100644 --- a/src/osgPlugins/ive/DataOutputStream.cpp +++ b/src/osgPlugins/ive/DataOutputStream.cpp @@ -35,6 +35,7 @@ #include "Billboard.h" #include "Sequence.h" #include "LOD.h" +#include "PagedLOD.h" //#include "ViewPoint.h" #include "PositionAttitudeTransform.h" #include "Transform.h" @@ -421,6 +422,9 @@ void DataOutputStream::writeNode(osg::Node* node) else if(dynamic_cast(node)){ ((ive::Impostor*)(node))->write(this); } + else if(dynamic_cast(node)){ + ((ive::PagedLOD*)(node))->write(this); + } else if(dynamic_cast(node)){ ((ive::LOD*)(node))->write(this); } diff --git a/src/osgPlugins/ive/GNUmakefile b/src/osgPlugins/ive/GNUmakefile index f3ef0c329..24b1bffdb 100644 --- a/src/osgPlugins/ive/GNUmakefile +++ b/src/osgPlugins/ive/GNUmakefile @@ -30,6 +30,7 @@ CXXFILES =\ Node.cpp\ Object.cpp\ OccluderNode.cpp\ + PagedLOD.cpp\ PositionAttitudeTransform.cpp\ PolygonOffset.cpp\ Point.cpp\ diff --git a/src/osgPlugins/ive/PagedLOD.cpp b/src/osgPlugins/ive/PagedLOD.cpp new file mode 100644 index 000000000..80c9834b9 --- /dev/null +++ b/src/osgPlugins/ive/PagedLOD.cpp @@ -0,0 +1,120 @@ +/********************************************************************** + * + * FILE: LOD.cpp + * + * DESCRIPTION: Read/Write osg::LOD in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerate + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 24.3.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "PagedLOD.h" +#include "Node.h" + +using namespace ive; + +void PagedLOD::write(DataOutputStream* out){ + // Write LOD's identification. + out->writeInt(IVEPAGEDLOD); + // If the osg class is inherited by any other class we should also write this to file. + + osg::Node* node = dynamic_cast(this); + if(node){ + static_cast(node)->write(out); + } + else + throw Exception("PagedLOD::write(): Could not cast this osg::PagedLOD to an osg::LOD."); + + unsigned int numChildrenToWriteOut = 0; + + int i; + for(i=0; i<(int)getNumFileNames();++i) + { + if (getFileName(i).empty()) + { + ++numChildrenToWriteOut; + } + } + + // Write Group's properties. + // Write number of children. + out->writeInt(numChildrenToWriteOut); + // Write children. + for(i=0; i<(int)getNumChildren(); i++){ + if (getFileName(i).empty()) + { + osg::Node* child = getChild(i); + out->writeNode(child); + } + } + + // LOD properties + // Write centermode + out->writeInt(getCenterMode()); + out->writeVec3(getCenter()); + // Write rangelist + int size = getNumRanges(); + out->writeInt(size); + for(i=0;iwriteFloat(getMinRange(i)); + out->writeFloat(getMaxRange(i)); + } + + + // PagedLOD properties + size = getNumFileNames(); + out->writeInt(size); + for(i=0;iwriteString(getFileName(i)); + } +} + +void PagedLOD::read(DataInputStream* in){ + // Peek on LOD's identification. + int id = in->peekInt(); + if(id == IVEPAGEDLOD){ + // Read LOD's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Node* node = dynamic_cast(this); + if(node){ + ((ive::Node*)(node))->read(in); + } + else + throw Exception("Group::read(): Could not cast this osg::Group to an osg::Node."); + + + // Read groups properties. + // Read number of children. + int size = in->readInt(); + // Read children. + for(int i=0; ireadNode()); + } + + // Read centermode + setCenterMode((osg::LOD::CenterMode)in->readInt()); + setCenter(in->readVec3()); + // Read rangelist + size = in->readInt(); + for(int i=0;ireadFloat(); + float max = in->readFloat(); + setRange(i, min, max); + } + + size = in->readInt(); + for(int i=0;ireadString()); + } + } + else{ + throw Exception("LOD::read(): Expected LOD identification."); + } +} diff --git a/src/osgPlugins/ive/PagedLOD.h b/src/osgPlugins/ive/PagedLOD.h new file mode 100644 index 000000000..f2c88ff5d --- /dev/null +++ b/src/osgPlugins/ive/PagedLOD.h @@ -0,0 +1,15 @@ +#ifndef IVE_PAGEDLOD +#define IVE_PAGEDLOD 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class PagedLOD : public osg::PagedLOD, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/ReadWrite.h b/src/osgPlugins/ive/ReadWrite.h index d9d4cac40..be99cc8f8 100644 --- a/src/osgPlugins/ive/ReadWrite.h +++ b/src/osgPlugins/ive/ReadWrite.h @@ -27,6 +27,7 @@ namespace ive { #define IVEIMPOSTOR 0x00000018 #define IVECONVEXPLANAROCCLUDER 0x00000019 #define IVECONVEXPLANARPOLYGON 0x00000020 +#define IVEPAGEDLOD 0x00000021 // Node callbacks #define IVENODECALLBACK 0x00000050 diff --git a/src/osgPlugins/txp/trPagePageManager.cpp b/src/osgPlugins/txp/trPagePageManager.cpp index 32ef66c76..32942bfe4 100644 --- a/src/osgPlugins/txp/trPagePageManager.cpp +++ b/src/osgPlugins/txp/trPagePageManager.cpp @@ -33,7 +33,7 @@ OSGPageManager::OSGPageManager(TrPageArchive *in_arch,trpgPageManager *in_pageMa throw 1; - if (pageManage) + if (pageManage) pageManageOurs = false; else { pageManage = new trpgPageManager(); @@ -112,18 +112,22 @@ bool OSGPageManager::UpdateNoThread(osg::Group *rootNode,double locX,double locY // --- Either thread --- struct osgGuard { - ThreadMutex& _mtx; - osgGuard(ThreadMutex &mtx):_mtx(mtx){ - _mtx.lock(); - } - ~osgGuard(){ - _mtx.unlock(); - } + ThreadMutex& _mtx; + osgGuard(ThreadMutex &mtx):_mtx(mtx){ + _mtx.lock(); + } + ~osgGuard(){ + _mtx.unlock(); + } }; void PagingThread::run() { - pager->ThreadLoop(this); + // need to set the texture object manager to be able to reuse textures + // by keeping deleted texture objects around for 10 seconds after being deleted. + osg::Texture::getTextureObjectManager()->setExpiryDelay(10.0f); + + pager->ThreadLoop(this); } /* Start Thread @@ -136,9 +140,9 @@ bool OSGPageManager::StartThread(ThreadMode mode,ThreadID &newThread) //locationChangeEvent is self-initialized. threadMode = mode; - pagingThread.pager = this; - pagingThread.startThread(); - newThread = pagingThread.getThreadId(); + pagingThread.pager = this; + pagingThread.startThread(); + newThread = pagingThread.getThreadId(); return threadMode != ThreadNone; } @@ -149,39 +153,39 @@ bool OSGPageManager::StartThread(ThreadMode mode,ThreadID &newThread) bool OSGPageManager::EndThread() { // locationChangeEvent.release(); - pagingThread.cancel(); + pagingThread.cancel(); return true; } void OSGPageManager::LoadOneTile(trpgManagedTile* tile) { - osg::Group* tileGroup; - osg::Group* parentNode ; - int x,y,lod; - tile->GetTileLoc(x,y,lod); + osg::Group* tileGroup; + osg::Group* parentNode ; + int x,y,lod; + tile->GetTileLoc(x,y,lod); - tileGroup = archive->LoadTile(NULL,pageManage,tile,&parentNode); - if (tileGroup) - { + tileGroup = archive->LoadTile(NULL,pageManage,tile,&parentNode); + if (tileGroup) + { #ifdef USE_THREADLOOP_DELETE - // Make an extra reference to it because we want it back for deletion - // RO, commenting out as we don't want to do delete here, we want it to happen in the merge thread. - tileGroup->ref(); + // Make an extra reference to it because we want it back for deletion + // RO, commenting out as we don't want to do delete here, we want it to happen in the merge thread. + tileGroup->ref(); #endif - // we only put tiles with NULL parent to merge list - // others are referenced when added as a child - osgGuard g(changeListMutex); - if(parentNode) - parentNode->addChild(tileGroup) ; - else - toMerge.push_back( tileGroup) ; - //toMergeParent.push_back(parentNode ); - } - else - { - osg::notify(WARN) << "Failed to load tile (" << x << y << lod << ")" << std::endl ; - } - + // we only put tiles with NULL parent to merge list + // others are referenced when added as a child + osgGuard g(changeListMutex); + if(parentNode) + parentNode->addChild(tileGroup) ; + else + toMerge.push_back( tileGroup) ; + //toMergeParent.push_back(parentNode ); + } + else + { + osg::notify(WARN) << "Failed to load tile (" << x << y << lod << ")" << std::endl ; + } + } /* Thread Loop @@ -200,25 +204,25 @@ bool OSGPageManager::ThreadLoop(PagingThread* t) bool pagingActive = false; while (!t->testCancel()) { - /* Here's how we do it: - Wait for position change - Update manager w/ position - Form delete list - Load tile (if needed) - Add tile to merge list - */ + /* Here's how we do it: + Wait for position change + Update manager w/ position + Form delete list + Load tile (if needed) + Add tile to merge list + */ // Position has already changed or we'll wait for it to do so - // locationChangeEvent.wait(); + // locationChangeEvent.wait(); double myLocX,myLocY; { osgGuard g(locationMutex); myLocX = locX; myLocY = locY; - positionValid = false; + positionValid = false; } - + // Pass the new location on to page manager - int x,y,lod; + int x,y,lod; trpg2dPoint loc; loc.x = myLocX; @@ -228,57 +232,57 @@ bool OSGPageManager::ThreadLoop(PagingThread* t) // Form the delete list first trpgManagedTile *tile=NULL; - unhook.clear(); + unhook.clear(); while ((tile = pageManage->GetNextUnload())) { - tile->GetTileLoc(x,y,lod); - unhook.push_back((Group *)(tile->GetLocalData())); - pageManage->AckUnload(); + tile->GetTileLoc(x,y,lod); + unhook.push_back((Group *)(tile->GetLocalData())); + pageManage->AckUnload(); } - nextDelete.clear(); + nextDelete.clear(); { osgGuard g(changeListMutex); // Add to the unhook list - for(unsigned int kk = 0; kk < unhook.size();kk++) - { - toUnhook.push_back(unhook[kk]); - } + for(unsigned int kk = 0; kk < unhook.size();kk++) + { + toUnhook.push_back(unhook[kk]); + } // Also get the list of deletions while we're here #ifdef USE_THREADLOOP_DELETE - // use the stl Luke :-) swap is constant time operation that do a = b; b.clear() - // if a is empty which is our case + // use the stl Luke :-) swap is constant time operation that do a = b; b.clear() + // if a is empty which is our case nextDelete.swap(toDelete); - // toDelete.clear(); + // toDelete.clear(); #endif } - + #ifdef USE_THREADLOOP_DELETE - // Unreference whatever we're supposed to delete - for (unsigned int gi=0;giunref(); - } + // Unreference whatever we're supposed to delete + for (unsigned int gi=0;giunref(); + } #endif - + // Now do a single load - while((tile = pageManage->GetNextLoad())) - { - tile->GetTileLoc(x,y,lod); + while((tile = pageManage->GetNextLoad())) + { + tile->GetTileLoc(x,y,lod); - osg::notify(WARN) << "Tile to load :" << x << ' ' << y << ' ' << lod << std::endl; - osg::notify(WARN) << "Position :" << loc.x << ' ' << loc.y << std::endl; - LoadOneTile(tile); - // Now add this tile to the merge list - pageManage->AckLoad(); - } + osg::notify(WARN) << "Tile to load :" << x << ' ' << y << ' ' << lod << std::endl; + osg::notify(WARN) << "Position :" << loc.x << ' ' << loc.y << std::endl; + LoadOneTile(tile); + // Now add this tile to the merge list + pageManage->AckLoad(); + } - } - else - sleep(10); + } + else + sleep(10); } return true; @@ -292,7 +296,7 @@ void OSGPageManager::UpdatePositionThread(double inLocX,double inLocY) { // Update the position if(!positionValid) - { + { // Get the location mutex osgGuard g(locationMutex); positionValid = true; @@ -317,14 +321,14 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode) // Make local copies of the merge and unhook lists { osgGuard g(changeListMutex); - // use the stl Luke :-) swap is constant time operation that do a = b; b.clear() - // if a is empty which is our case + // use the stl Luke :-) swap is constant time operation that do a = b; b.clear() + // if a is empty which is our case mergeList.swap(toMerge); - unhookList.swap(toUnhook); + unhookList.swap(toUnhook); // toMerge.clear(); // toMergeParent.clear(); // toUnhook.clear(); - } + } // Do the unhooking first for (unsigned int ui=0;uigetParents(); for (unsigned int pi=0;piremoveChild(unhookMe); + if(parent != rootNode) + parent->removeChild(unhookMe); } } @@ -347,8 +351,8 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode) // Put the unhooked things on the list to delete { osgGuard g(changeListMutex); - for (unsigned int i = 0; i < unhookList.size();i++) - toDelete.push_back(unhookList[i]); + for (unsigned int i = 0; i < unhookList.size();i++) + toDelete.push_back(unhookList[i]); } #endif @@ -356,7 +360,7 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode) { for (unsigned int mi=0;miaddChild(mergeMe);