Added new osga plugin for reading OSG native archives

This commit is contained in:
Robert Osfield 2004-11-10 16:40:08 +00:00
parent 5d3dcd3e18
commit 4973824b1d
7 changed files with 316 additions and 34 deletions

View File

@ -48,6 +48,7 @@ PLUGIN_DIRS = \
osgSim\
osgFX\
osg\
osga\
osgtgz\
pic\
pnm\

View File

@ -2358,6 +2358,27 @@ Package=<4>
###############################################################################
Project: "osgPlugin osga"=.\osgPlugins\osga\osga.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name Core osg
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgDB
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgUtil
End Project Dependency
}}}
###############################################################################
Project: "osgPlugin net"=".\osgPlugins\net\net.dsp" - Package Owner=<4>
Package=<5>

View File

@ -0,0 +1,111 @@
# Microsoft Developer Studio Project File - Name="osgPlugin osga" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=osgPlugin osga - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "osga.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "osga.mak" CFG="osgPlugin osga - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "osgPlugin osga - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "osgPlugin osga - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "osgPlugin osga - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../../lib"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 OpenThreadsWin32.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_osga.dll" /libpath:"../../../lib" /libpath:"../../../../OpenThreads/lib/win32" /libpath:"../../../../Producer/lib" /libpath:"../../../../3rdParty/lib"
# SUBTRACT LINK32 /nodefaultlib
!ELSEIF "$(CFG)" == "osgPlugin osga - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../../lib"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /vmg /vd0 /GR /GX /Zi /Od /I "../../../include" /I "../../../../OpenThreads/include" /I "../../../../Producer/include" /I "../../../../3rdParty/include" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WIN32" /D "_DEBUG" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 OpenThreadsWin32d.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"../../../bin/osgdb_osgad.dll" /pdbtype:sept /libpath:"../../../lib" /libpath:"../../../../OpenThreads/lib/win32" /libpath:"../../../../Producer/lib" /libpath:"../../../../3rdParty/lib"
# SUBTRACT LINK32 /nodefaultlib
!ENDIF
# Begin Target
# Name "osgPlugin osga - Win32 Release"
# Name "osgPlugin osga - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\osga\ReaderWriterOSGA.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -370,11 +370,22 @@ class OSGDB_EXPORT Registry : public osg::Referenced
/** Get whether the Registry::ObjectCache should be used by default.*/
CacheHintOptions getUseObjectCacheHint() const { return _useObjectCacheHint; }
/** Add archive to archive cache so that future calls reference this archive.*/
void addToArchiveCache(const std::string& fileName, osgDB::Archive* archive);
/** Remove archive from cache.*/
void removeFromArchiveCache(const std::string& fileName);
/** Get an archive from the archive cache*/
osgDB::Archive* getFromArchiveCache(const std::string& fileName);
/** Remove all archives from the archive cache.*/
void clearArchiveCache();
/** get the attached library with specified name.*/
DynamicLibrary* getLibrary(const std::string& fileName);
typedef std::vector< osg::ref_ptr<ReaderWriter> > ReaderWriterList;
/** Set the DatabasePager.*/
void setDatabasePager(DatabasePager* databasePager) { _databasePager = databasePager; }
@ -400,12 +411,14 @@ class OSGDB_EXPORT Registry : public osg::Referenced
virtual ~Registry();
typedef std::vector< osg::ref_ptr<ReaderWriter> > ReaderWriterList;
typedef std::map< std::string, osg::ref_ptr<DotOsgWrapper> > DotOsgWrapperMap;
typedef std::vector< osg::ref_ptr<DynamicLibrary> > DynamicLibraryList;
typedef std::map< std::string, std::string> ExtensionAliasMap;
typedef std::pair<osg::ref_ptr<osg::Object>, double > ObjectTimeStampPair;
typedef std::map<std::string, ObjectTimeStampPair > ObjectCache;
typedef std::map<std::string, osg::ref_ptr<osgDB::Archive> > ArchiveCache;
/** constructor is private, as its a singleton, preventing
construction other than via the instance() method and
@ -437,6 +450,7 @@ class OSGDB_EXPORT Registry : public osg::Referenced
const ReaderWriter::Options* _options;
};
// forward declare helper classes
struct ReadObjectFunctor;
struct ReadImageFunctor;
struct ReadHeightFieldFunctor;
@ -444,7 +458,12 @@ class OSGDB_EXPORT Registry : public osg::Referenced
struct ReadArchiveFunctor;
ReaderWriter::ReadResult read(const ReadFunctor& readFunctor);
ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,CacheHintOptions useObjectCache);
ReaderWriter::ReadResult readImplementation(const ReadFunctor& readFunctor,bool useObjectCache);
// forward declar helper class
class AvailableReaderWriterIterator;
osg::ref_ptr<ReadFileCallback> _readFileCallback;
osg::ref_ptr<WriteFileCallback> _writeFileCallback;
@ -475,6 +494,10 @@ class OSGDB_EXPORT Registry : public osg::Referenced
ObjectCache _objectCache;
OpenThreads::Mutex _objectCacheMutex;
ArchiveCache _archiveCache;
OpenThreads::Mutex _archiveCacheMutex;
osg::ref_ptr<DatabasePager> _databasePager;
osg::ref_ptr<SharedStateManager> _sharedStateManager;

View File

@ -32,7 +32,7 @@
using namespace osg;
using namespace osgDB;
class AvailableReaderWriterIterator
class Registry::AvailableReaderWriterIterator
{
public:
AvailableReaderWriterIterator(Registry::ReaderWriterList& rwList):
@ -138,7 +138,7 @@ Registry::Registry()
_createNodeFromImage = false;
_openingLibrary = false;
_useObjectCacheHint = CACHE_NONE;
_useObjectCacheHint = CACHE_ARCHIVES;
initFilePathLists();
@ -220,6 +220,8 @@ Registry::~Registry()
// even some issue with objects be allocated by a plugin that is
// mainted after that plugin is deleted... Robert Osfield, Jan 2004.
clearObjectCache();
clearArchiveCache();
// unload all the plugin before we finally destruct.
closeAllLibraries();
@ -1183,30 +1185,16 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor)
osg::notify(osg::INFO)<<" archive : "<<archiveName<<std::endl;
osg::notify(osg::INFO)<<" filename : "<<fileName<<std::endl;
//ReaderWriter::ReadResult result = openArchiveImplementation(archiveName,ReaderWriter::READ, 4096, CACHE_ARCHIVES);
//osgDB::Archive* archive = result.takeArchive();
ReaderWriter::ReadResult result = openArchiveImplementation(archiveName,ReaderWriter::READ, 4096, CACHE_ARCHIVES);
static osg::ref_ptr<Archive> s_archive;
if (!s_archive)
{
s_archive = new Archive;
s_archive->open(archiveName,ReaderWriter::READ, 4096);
}
if (!result.validArchive()) return result;
osgDB::Archive* archive = result.getArchive();
osg::ref_ptr<ReaderWriter::Options> options = new ReaderWriter::Options;
options->setDatabasePath(archiveName);
if (s_archive.valid())
{
osg::notify(osg::INFO)<<" archive loaded"<<fileName<<std::endl;
return s_archive->readObject(fileName,options.get());
}
else
{
osg::notify(osg::INFO)<<" no archive loaded"<<fileName<<std::endl;
return NULL;
}
return archive->readObject(fileName,options.get());
}
// if filename contains archive
@ -1308,11 +1296,11 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor)
return results.front();
}
ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFunctor, CacheHintOptions useObjectCache)
ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFunctor, bool useObjectCache)
{
std::string file(readFunctor._filename);
if (useObjectCache & CACHE_OBJECTS)
if (useObjectCache)
{
// search for entry in the object cache.
{
@ -1335,13 +1323,16 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
notify(INFO)<<"Adding to object cache "<<file<<std::endl;
addEntryToObjectCache(file,rr.getObject());
}
else
{
notify(INFO)<<"No valid object found for "<<file<<std::endl;
}
return rr;
}
else
{
ObjectCache tmpObjectCache;
{
@ -1365,13 +1356,28 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
ReaderWriter::ReadResult Registry::openArchiveImplementation(const std::string& fileName, ReaderWriter::ArchiveStatus status, unsigned int indexBlockSizeHint, CacheHintOptions useObjectCache)
{
return readImplementation(ReadArchiveFunctor(fileName, status, indexBlockSizeHint, _options.get()),useObjectCache);
if (useObjectCache&CACHE_ARCHIVES)
{
osgDB::Archive* archive = getFromArchiveCache(fileName);
if (archive) return archive;
ReaderWriter::ReadResult result = readImplementation(ReadArchiveFunctor(fileName, status, indexBlockSizeHint, _options.get()),false);
if (result.validArchive())
{
addToArchiveCache(fileName,result.getArchive());
}
return result;
}
else
{
return readImplementation(ReadArchiveFunctor(fileName, status, indexBlockSizeHint, _options.get()),false);
}
}
ReaderWriter::ReadResult Registry::readObjectImplementation(const std::string& fileName,CacheHintOptions useObjectCache)
{
return readImplementation(ReadObjectFunctor(fileName, _options.get()),useObjectCache);
return readImplementation(ReadObjectFunctor(fileName, _options.get()),(useObjectCache&CACHE_OBJECTS)!=0);
}
ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj,const std::string& fileName)
@ -1413,7 +1419,7 @@ ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj,
ReaderWriter::ReadResult Registry::readImageImplementation(const std::string& fileName,CacheHintOptions useObjectCache)
{
return readImplementation(ReadImageFunctor(fileName, _options.get()),useObjectCache);
return readImplementation(ReadImageFunctor(fileName, _options.get()),(useObjectCache&CACHE_IMAGES)!=0);
}
ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image,const std::string& fileName)
@ -1454,7 +1460,7 @@ ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image,
ReaderWriter::ReadResult Registry::readHeightFieldImplementation(const std::string& fileName,CacheHintOptions useObjectCache)
{
return readImplementation(ReadHeightFieldFunctor(fileName, _options.get()),useObjectCache);
return readImplementation(ReadHeightFieldFunctor(fileName, _options.get()),(useObjectCache&CACHE_HEIGHTFIELDS)!=0);
}
ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightField& HeightField,const std::string& fileName)
@ -1495,7 +1501,7 @@ ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightF
ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& fileName,CacheHintOptions useObjectCache)
{
return readImplementation(ReadNodeFunctor(fileName, _options.get()),useObjectCache);
return readImplementation(ReadNodeFunctor(fileName, _options.get()),(useObjectCache&CACHE_NODES)!=0);
}
ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,const std::string& fileName)
@ -1560,6 +1566,8 @@ void Registry::updateTimeStampOfObjectsInCacheWithExtenalReferences(double curre
void Registry::removeExpiredObjectsInCache(double expiryTime)
{
return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
typedef std::vector<std::string> ObjectsToRemove;
@ -1595,6 +1603,37 @@ void Registry::clearObjectCache()
_objectCache.clear();
}
void Registry::addToArchiveCache(const std::string& fileName, osgDB::Archive* archive)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_archiveCacheMutex);
_archiveCache[fileName] = archive;
}
/** Remove archive from cache.*/
void Registry::removeFromArchiveCache(const std::string& fileName)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_archiveCacheMutex);
ArchiveCache::iterator itr = _archiveCache.find(fileName);
if (itr!=_archiveCache.end())
{
_archiveCache.erase(itr);
}
}
osgDB::Archive* Registry::getFromArchiveCache(const std::string& fileName)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_archiveCacheMutex);
ArchiveCache::iterator itr = _archiveCache.find(fileName);
if (itr!=_archiveCache.end()) return itr->second.get();
else return 0;
}
void Registry::clearArchiveCache()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_archiveCacheMutex);
_archiveCache.clear();
}
DatabasePager* Registry::getOrCreateDatabasePager()
{
if (!_databasePager) _databasePager = new DatabasePager;

View File

@ -0,0 +1,16 @@
TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
ReaderWriterOSGA.cpp\
INC += -I$(THISDIR)
LIBS += $(OSG_LIBS) $(OTHER_LIBS)
TARGET_BASENAME = osga
include $(TOPDIR)/Make/cygwin_plugin_def
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,71 @@
#include <osg/Notify>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Archive>
class ReaderWriterOSGA : public osgDB::ReaderWriter
{
public:
ReaderWriterOSGA() { }
virtual const char* className() const { return "OpenSceneGraph Archive Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension)
{
return osgDB::equalCaseInsensitive(extension,"osga");
}
virtual ReadResult openArchive(const std::string& file,ArchiveStatus status, unsigned int indexBlockSize = 4096, const Options* = NULL)
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
osg::ref_ptr<osgDB::Archive> archive = new osgDB::Archive;
if (!archive->open(fileName, status, indexBlockSize))
{
return ReadResult(ReadResult::FILE_NOT_HANDLED);
}
return archive.get();
}
virtual ReadResult readObject(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
virtual ReadResult readNode(const std::string& file,const Options* options)
{
ReadResult result = openArchive(file,osgDB::Archive::READ);
if (!result.validArchive()) return result;
osg::ref_ptr<ReaderWriter::Options> local_options = new ReaderWriter::Options;
local_options->setDatabasePath(file);
ReadResult result_2 = result.getArchive()->readNode(result.getArchive()->getMasterFileName(),local_options.get());
// register the archive so that it is cached for future use.
osgDB::Registry::instance()->addToArchiveCache(file, result.getArchive());
return result_2;
}
virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) {return WriteResult(WriteResult::FILE_NOT_HANDLED); }
virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) { return WriteResult(WriteResult::FILE_NOT_HANDLED); }
protected:
};
// register with Registry to instantiate the above reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterOSGA> g_osgaReaderWriterProxy;