Added support for PagedLOD node into .ive format and added support for
Enabled texture object reuse by setting an expiry delay in the TextureObjectManager of 10 seconds - done for both osgDB::DatabasePager and TXP plugin.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -170,6 +170,10 @@ public:
|
||||
void DatabasePager::run()
|
||||
{
|
||||
std::cout<<"DatabasePager::run()"<<std::endl;
|
||||
|
||||
// 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);
|
||||
|
||||
while(true)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<osg::Impostor*>(node)){
|
||||
((ive::Impostor*)(node))->write(this);
|
||||
}
|
||||
else if(dynamic_cast<osg::PagedLOD*>(node)){
|
||||
((ive::PagedLOD*)(node))->write(this);
|
||||
}
|
||||
else if(dynamic_cast<osg::LOD*>(node)){
|
||||
((ive::LOD*)(node))->write(this);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ CXXFILES =\
|
||||
Node.cpp\
|
||||
Object.cpp\
|
||||
OccluderNode.cpp\
|
||||
PagedLOD.cpp\
|
||||
PositionAttitudeTransform.cpp\
|
||||
PolygonOffset.cpp\
|
||||
Point.cpp\
|
||||
|
||||
120
src/osgPlugins/ive/PagedLOD.cpp
Normal file
120
src/osgPlugins/ive/PagedLOD.cpp
Normal file
@@ -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<osg::Node*>(this);
|
||||
if(node){
|
||||
static_cast<ive::Node*>(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;i<size;i++){
|
||||
out->writeFloat(getMinRange(i));
|
||||
out->writeFloat(getMaxRange(i));
|
||||
}
|
||||
|
||||
|
||||
// PagedLOD properties
|
||||
size = getNumFileNames();
|
||||
out->writeInt(size);
|
||||
for(i=0;i<size;i++){
|
||||
out->writeString(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<osg::Node*>(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; i<size; i++)
|
||||
{
|
||||
addChild(in->readNode());
|
||||
}
|
||||
|
||||
// Read centermode
|
||||
setCenterMode((osg::LOD::CenterMode)in->readInt());
|
||||
setCenter(in->readVec3());
|
||||
// Read rangelist
|
||||
size = in->readInt();
|
||||
for(int i=0;i<size;i++){
|
||||
float min = in->readFloat();
|
||||
float max = in->readFloat();
|
||||
setRange(i, min, max);
|
||||
}
|
||||
|
||||
size = in->readInt();
|
||||
for(int i=0;i<size;i++){
|
||||
setFileName(i, in->readString());
|
||||
}
|
||||
}
|
||||
else{
|
||||
throw Exception("LOD::read(): Expected LOD identification.");
|
||||
}
|
||||
}
|
||||
15
src/osgPlugins/ive/PagedLOD.h
Normal file
15
src/osgPlugins/ive/PagedLOD.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef IVE_PAGEDLOD
|
||||
#define IVE_PAGEDLOD 1
|
||||
|
||||
#include <osg/PagedLOD>
|
||||
#include "ReadWrite.h"
|
||||
|
||||
namespace ive{
|
||||
class PagedLOD : public osg::PagedLOD, public ReadWrite {
|
||||
public:
|
||||
void write(DataOutputStream* out);
|
||||
void read(DataInputStream* in);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,6 +27,7 @@ namespace ive {
|
||||
#define IVEIMPOSTOR 0x00000018
|
||||
#define IVECONVEXPLANAROCCLUDER 0x00000019
|
||||
#define IVECONVEXPLANARPOLYGON 0x00000020
|
||||
#define IVEPAGEDLOD 0x00000021
|
||||
|
||||
// Node callbacks
|
||||
#define IVENODECALLBACK 0x00000050
|
||||
|
||||
@@ -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;gi<nextDelete.size();gi++)
|
||||
{
|
||||
if( nextDelete[gi] )
|
||||
nextDelete[gi]->unref();
|
||||
}
|
||||
// Unreference whatever we're supposed to delete
|
||||
for (unsigned int gi=0;gi<nextDelete.size();gi++)
|
||||
{
|
||||
if( nextDelete[gi] )
|
||||
nextDelete[gi]->unref();
|
||||
}
|
||||
#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;ui<unhookList.size();ui++) {
|
||||
@@ -332,14 +336,14 @@ bool OSGPageManager::MergeUpdateThread(osg::Group *rootNode)
|
||||
|
||||
// better safe than sorry
|
||||
|
||||
if(!unhookMe ) continue;
|
||||
if(!unhookMe ) continue;
|
||||
// Look for its parent(s)
|
||||
// Only expecting one, but it doesn't matter
|
||||
const osg::Node::ParentList &parents = unhookMe->getParents();
|
||||
for (unsigned int pi=0;pi<parents.size();pi++) {
|
||||
osg::Group *parent = parents[pi];
|
||||
if(parent != rootNode)
|
||||
parent->removeChild(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;mi<mergeList.size();mi++) {
|
||||
osg::Group *mergeMe = mergeList[mi];
|
||||
// NO need for that - we only put tiles with NULL parent to merge list
|
||||
// NO need for that - we only put tiles with NULL parent to merge list
|
||||
// osg::Group *parent = mergeParentList[mi];
|
||||
// if (parent)
|
||||
// parent->addChild(mergeMe);
|
||||
|
||||
Reference in New Issue
Block a user