diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index be32d03a7..b20a78078 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -388,6 +388,10 @@ SOURCE=..\..\src\osg\Projection.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\ProxyNode.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\Quat.cpp # End Source File # Begin Source File @@ -853,6 +857,10 @@ SOURCE=..\..\Include\Osg\Program # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\ProxyNode +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\Quat # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/ive/ive.dsp b/VisualStudio/osgPlugins/ive/ive.dsp index e9a0e6659..945bd36a0 100755 --- a/VisualStudio/osgPlugins/ive/ive.dsp +++ b/VisualStudio/osgPlugins/ive/ive.dsp @@ -308,6 +308,10 @@ SOURCE=..\..\..\src\osgPlugins\ive\PrimitiveSet.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\ive\ProxyNode.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\ive\ReaderWriterIVE.cpp # End Source File # Begin Source File @@ -608,6 +612,10 @@ SOURCE=..\..\..\src\osgPlugins\ive\PrimitiveSet.h # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\ive\ProxyNode.h +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\ive\ReadWrite.h # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 4cfa36eb8..52728d9ba 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -272,6 +272,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\Projection.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\ProxyNode.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\ReaderWriterOSG.cpp # End Source File # Begin Source File diff --git a/include/osg/ProxyNode b/include/osg/ProxyNode new file mode 100644 index 000000000..98b250ca6 --- /dev/null +++ b/include/osg/ProxyNode @@ -0,0 +1,98 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_ProxyNode +#define OSG_ProxyNode 1 + +#include + +namespace osg { + +/** ProxyNode. +*/ +class SG_EXPORT ProxyNode : public Group +{ + public : + + ProxyNode(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + ProxyNode(const ProxyNode&,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_Node(osg, ProxyNode); + + virtual void traverse(NodeVisitor& nv); + + virtual bool addChild(Node *child); + virtual bool addChild(Node *child, const std::string& filename); + virtual bool removeChild(Node *child); + + /** Set the database path to prepend to children's filenames.*/ + void setDatabasePath(const std::string& path); + /** Get the database path used to prepend to children's filenames.*/ + inline const std::string& getDatabasePath() const { return _databasePath; } + + typedef std::vector FileNameList; + + void setFileName(unsigned int childNo, const std::string& filename) { expandFileNameListTo(childNo); _filenameList[childNo]=filename; } + const std::string& getFileName(unsigned int childNo) const { return _filenameList[childNo]; } + unsigned int getNumFileNames() const { return _filenameList.size(); } + + /** Modes which control how the center of object should be determined when computed which child is active.*/ + enum CenterMode + { + USE_BOUNDING_SPHERE_CENTER, + USER_DEFINED_CENTER + }; + + /** Set how the center of object should be determined when computed which child is active.*/ + void setCenterMode(CenterMode mode) { _centerMode=mode; } + + /** Get how the center of object should be determined when computed which child is active.*/ + CenterMode getCenterMode() const { return _centerMode; } + + /** Sets the object-space point which defines the center of the osg::LOD. + center is affected by any transforms in the hierarchy above the osg::LOD.*/ + inline void setCenter(const Vec3& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } + + /** return the LOD center point. */ + inline const Vec3& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } + + + /** Set the object-space reference radius of the volume enclosed by the LOD. + * Used to detmine the bounding sphere of the LOD in the absense of any children.*/ + inline void setRadius(float radius) { _radius = radius; } + + /** Get the object-space radius of the volume enclosed by the LOD.*/ + inline float getRadius() const { return _radius; } + + protected : + + virtual ~ProxyNode() {} + + virtual bool computeBound() const; + + void expandFileNameListTo(unsigned int pos); + + FileNameList _filenameList; + std::string _databasePath; + + CenterMode _centerMode; + Vec3 _userDefinedCenter; + float _radius; + +}; + +} + +#endif diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 4ab78be97..b40c6f51c 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -333,6 +333,9 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** Add a filename,object,timestamp tripple to the Registry::ObjectCache.*/ void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0); + + /** Get an object from the object cache*/ + osg::Object* getFromObjectCache(const std::string& fileName); /** Add archive to archive cache so that future calls reference this archive.*/ void addToArchiveCache(const std::string& fileName, osgDB::Archive* archive); diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index ee4fcb430..8499250f5 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -77,6 +77,7 @@ CXXFILES =\ PositionAttitudeTransform.cpp\ PrimitiveSet.cpp\ Projection.cpp\ + ProxyNode.cpp\ Quat.cpp\ Referenced.cpp\ Sequence.cpp\ diff --git a/src/osg/ProxyNode.cpp b/src/osg/ProxyNode.cpp new file mode 100644 index 000000000..4a352e74f --- /dev/null +++ b/src/osg/ProxyNode.cpp @@ -0,0 +1,122 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include + +using namespace osg; + +ProxyNode::ProxyNode() : + _centerMode(USER_DEFINED_CENTER), + _radius(-1) +{ +} + +ProxyNode::ProxyNode(const ProxyNode& proxynode,const CopyOp& copyop): + Group(proxynode,copyop), + _filenameList(proxynode._filenameList), + _centerMode(proxynode._centerMode), + _userDefinedCenter(proxynode._userDefinedCenter), + _radius(proxynode._radius) +{ +} + +void ProxyNode::setDatabasePath(const std::string& path) +{ + _databasePath = path; + if (!_databasePath.empty()) + { + char& lastCharacter = _databasePath[_databasePath.size()-1]; + const char unixSlash = '/'; + const char winSlash = '\\'; + + if (lastCharacter==winSlash) + { + lastCharacter = unixSlash; + } + else if (lastCharacter!=unixSlash) + { + _databasePath += unixSlash; + } + } +} + +void ProxyNode::traverse(NodeVisitor& nv) +{ + if (_filenameList.size()>_children.size() && nv.getVisitorType()==NodeVisitor::CULL_VISITOR) + { + for(unsigned int i=_children.size()-1; i<_filenameList.size(); ++i) + { + nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_filenameList[i], this, 1.0f, nv.getFrameStamp()); + } + } + else + { + Group::traverse(nv); + } +} + +void ProxyNode::expandFileNameListTo(unsigned int pos) +{ + if (pos>=_filenameList.size()) _filenameList.resize(pos+1); +} + +bool ProxyNode::addChild( Node *child ) +{ + if (Group::addChild(child)) + { + expandFileNameListTo(_children.size()); + return true; + } + return false; +} + +bool ProxyNode::addChild(Node *child, const std::string& filename) +{ + if (Group::addChild(child)) + { + setFileName(_children.size()-1,filename); + return true; + } + return false; +} + +bool ProxyNode::removeChild( Node *child ) +{ + // find the child's position. + unsigned int pos=getChildIndex(child); + if (pos==_children.size()) return false; + + if (pos<_filenameList.size()) _filenameList.erase(_filenameList.begin()+pos); + + return Group::removeChild(child); +} + +bool ProxyNode::computeBound() const +{ + if (_centerMode==USER_DEFINED_CENTER && _radius>=0.0f) + { + _bsphere._center = _userDefinedCenter; + _bsphere._radius = _radius; + _bsphere_computed = true; + + return true; + } + else + { + return Group::computeBound(); + } +} + + diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 322394eaf..2b02051cb 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1568,6 +1568,13 @@ void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* o OpenThreads::ScopedLock lock(_objectCacheMutex); _objectCache[filename]=ObjectTimeStampPair(object,timestamp); } +osg::Object* Registry::getFromObjectCache(const std::string& fileName) +{ + OpenThreads::ScopedLock lock(_objectCacheMutex); + ObjectCache::iterator itr = _objectCache.find(fileName); + if (itr!=_objectCache.end()) return itr->second.first.get(); + else return 0; +} void Registry::updateTimeStampOfObjectsInCacheWithExtenalReferences(double currentTime) { diff --git a/src/osgPlugins/flt/FltFile.cpp b/src/osgPlugins/flt/FltFile.cpp index 1ba5c0f37..08561008d 100644 --- a/src/osgPlugins/flt/FltFile.cpp +++ b/src/osgPlugins/flt/FltFile.cpp @@ -248,7 +248,7 @@ bool FltFile::readFile(const std::string& fileName) //Path for Nested external references osgDB::FilePathList& fpl = options->getDatabasePathList(); - std::string filePath = osgDB::getFilePath(filename); + const std::string& filePath = osgDB::getFilePath(filename); std::string pushAndPopPath; //If absolute path if( (filePath.length()>0 && filePath.find_first_of("/\\")==0) || diff --git a/src/osgPlugins/flt/flt2osg.cpp b/src/osgPlugins/flt/flt2osg.cpp index d61e0f34d..1004a36c7 100644 --- a/src/osgPlugins/flt/flt2osg.cpp +++ b/src/osgPlugins/flt/flt2osg.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,8 @@ static int dprint = 0 ; #define DPRINT if(dprint)fprintf +#define USE_PROXYNODE_FOR_EXTERNAL_FILES + using namespace flt; unsigned int mystrnlen(char *s, unsigned int maxLen) @@ -2424,11 +2427,19 @@ osg::Group* ConvertFromFLT::visitMatrix(osg::Group& osgParent, const osg::Group& osg::Group* ConvertFromFLT::visitExternal(osg::Group& osgParent, ExternalRecord* rec) { - FltFile* pFile = rec->getExternal(); osg::Group* external = NULL; if (pFile) { +#ifdef USE_PROXYNODE_FOR_EXTERNAL_FILES + external = dynamic_cast (osgDB::Registry::instance()->getFromObjectCache(rec->getFilename())); + if(external) + { + osg::Group *tempParent = visitAncillary(osgParent, *external, rec); + tempParent->addChild(external); + return 0; + } +#endif pFile->setDesiredUnits( rec->getFltFile()->getDesiredUnits() ); external = pFile->convert(); if (external) @@ -2450,8 +2461,16 @@ osg::Group* ConvertFromFLT::visitExternal(osg::Group& osgParent, ExternalRecord* std::string modelName = rec->getModelName(); if ( modelName.empty() ) { - // Add the entire externally referenced file - tempParent->addChild(external); +#ifdef USE_PROXYNODE_FOR_EXTERNAL_FILES + // Add the entire externally referenced file + osg::ProxyNode *proxynode = new osg::ProxyNode; + proxynode->setCenterMode(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER); + proxynode->addChild(external, rec->getFilename()); + tempParent->addChild(proxynode); + osgDB::Registry::instance()->addEntryToObjectCache(rec->getFilename(), external); +#else + tempParent->addChild(external); +#endif } else { @@ -2462,7 +2481,15 @@ osg::Group* ConvertFromFLT::visitExternal(osg::Group& osgParent, ExternalRecord* osg::Node *model = findExternalModelVisitor.getModel(); if (model) { - tempParent->addChild(model); +#ifdef USE_PROXYNODE_FOR_EXTERNAL_FILES + osg::ProxyNode *proxynode = new osg::ProxyNode; + proxynode->setCenterMode(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER); + proxynode->addChild(model, rec->getFilename()); + tempParent->addChild(proxynode); + osgDB::Registry::instance()->addEntryToObjectCache(rec->getFilename(), model); +#else + //tempParent->addChild(model); +#endif } else { @@ -2474,7 +2501,6 @@ osg::Group* ConvertFromFLT::visitExternal(osg::Group& osgParent, ExternalRecord* } } } - return external; } diff --git a/src/osgPlugins/ive/DataInputStream.cpp b/src/osgPlugins/ive/DataInputStream.cpp index fa24f383a..16abbd91f 100644 --- a/src/osgPlugins/ive/DataInputStream.cpp +++ b/src/osgPlugins/ive/DataInputStream.cpp @@ -37,6 +37,7 @@ #include "FragmentProgram.h" #include "VertexProgram.h" #include "LightModel.h" +#include "ProxyNode.h" #include "Group.h" #include "MatrixTransform.h" @@ -931,6 +932,10 @@ osg::Node* DataInputStream::readNode() node = new osgSim::VisibilityGroup(); ((ive::VisibilityGroup*)(node))->read(this); } + else if(nodeTypeID== IVEPROXYNODE){ + node = new osg::ProxyNode(); + ((ive::ProxyNode*)(node))->read(this); + } else if(nodeTypeID== IVEGROUP){ node = new osg::Group(); ((ive::Group*)(node))->read(this); diff --git a/src/osgPlugins/ive/DataOutputStream.cpp b/src/osgPlugins/ive/DataOutputStream.cpp index b2e0430ae..3f7ee6639 100644 --- a/src/osgPlugins/ive/DataOutputStream.cpp +++ b/src/osgPlugins/ive/DataOutputStream.cpp @@ -9,7 +9,7 @@ * * HISTORY: Created 11.03.2003 * Updated for 1D textures - Don Burns 27.1.2004 - * Updated for light model - Stan Blinov at 25 august 7512 from World Creation (7.09.2004) + * Updated for light model - Stan Blinov at 25 august 7512 from World Creation (7.09.2004) * * Copyright 2003 VR-C **********************************************************************/ @@ -38,6 +38,7 @@ #include "FragmentProgram.h" #include "VertexProgram.h" #include "LightModel.h" +#include "ProxyNode.h" #include "Group.h" @@ -67,13 +68,42 @@ #include "Shape.h" +#include + using namespace ive; + +void DataOutputStream::setOptions(const osgDB::ReaderWriter::Options* options) +{ + _options = options; + + if (_options.get()) + { + setIncludeImageData(_options->getOptionString().find("noTexturesInIVEFile")==std::string::npos); + osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeImageData()=" << getIncludeImageData() << std::endl; + + setIncludeExternalReferences(_options->getOptionString().find("inlineExternalReferencesInIVEFile")!=std::string::npos); + osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeExternalReferences()=" << getIncludeExternalReferences() << std::endl; + + setWriteExternalReferenceFiles(_options->getOptionString().find("noWriteExternalReferenceFiles")==std::string::npos); + osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setWriteExternalReferenceFiles()=" << getWriteExternalReferenceFiles() << std::endl; + + setUseOriginalExternalReferences(_options->getOptionString().find("useOriginalExternalReferences")!=std::string::npos); + osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setUseOriginalExternalReferences()=" << getUseOriginalExternalReferences() << std::endl; + } +} + DataOutputStream::DataOutputStream(std::ostream * ostream) { _verboseOutput = false; _includeImageData= true; + + _includeExternalReferences = false; + _writeExternalReferenceFiles = true; + _useOriginalExternalReferences = false; + + _ostream = ostream; if(!_ostream) throw Exception("DataOutputStream::DataOutputStream(): null pointer exception in argument."); @@ -688,6 +718,9 @@ void DataOutputStream::writeNode(const osg::Node* node) else if(dynamic_cast(node)){ ((ive::VisibilityGroup*)(node))->write(this); } + else if(dynamic_cast(node)){ + ((ive::ProxyNode*)(node))->write(this); + } else if(dynamic_cast(node)){ ((ive::Group*)(node))->write(this); } diff --git a/src/osgPlugins/ive/DataOutputStream.h b/src/osgPlugins/ive/DataOutputStream.h index 2232cd85a..2e91f69cc 100644 --- a/src/osgPlugins/ive/DataOutputStream.h +++ b/src/osgPlugins/ive/DataOutputStream.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "IveVersion.h" #include "DataTypeSize.h" @@ -29,6 +30,9 @@ public: DataOutputStream(std::ostream* ostream); ~DataOutputStream(); + void setOptions(const osgDB::ReaderWriter::Options* options); + const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); } + unsigned int getVersion() { return VERSION; } void writeBool(bool b); @@ -75,7 +79,19 @@ public: void setIncludeImageData(bool b) {_includeImageData=b;}; bool getIncludeImageData() {return _includeImageData;}; - bool _verboseOutput; + // Set and get include external references in stream + void setIncludeExternalReferences(bool b) {_includeExternalReferences=b;}; + bool getIncludeExternalReferences() {return _includeExternalReferences;}; + + // Set and get if must be generated external reference ive files + void setWriteExternalReferenceFiles(bool b) {_writeExternalReferenceFiles=b;}; + bool getWriteExternalReferenceFiles() {return _writeExternalReferenceFiles;}; + + // Set and get if must be used original external reference files + void setUseOriginalExternalReferences(bool b) {_useOriginalExternalReferences=b;}; + bool getUseOriginalExternalReferences() {return _useOriginalExternalReferences;}; + + bool _verboseOutput; private: std::ostream* _ostream; @@ -94,7 +110,11 @@ private: NodeMap _nodeMap; bool _includeImageData; + bool _includeExternalReferences; + bool _writeExternalReferenceFiles; + bool _useOriginalExternalReferences; + osg::ref_ptr _options; }; } diff --git a/src/osgPlugins/ive/GNUmakefile b/src/osgPlugins/ive/GNUmakefile index 5fcb65af2..8ae353277 100644 --- a/src/osgPlugins/ive/GNUmakefile +++ b/src/osgPlugins/ive/GNUmakefile @@ -55,6 +55,7 @@ CXXFILES =\ PolygonOffset.cpp\ PositionAttitudeTransform.cpp\ PrimitiveSet.cpp\ + ProxyNode.cpp\ ReaderWriterIVE.cpp\ Sequence.cpp\ ShadeModel.cpp\ diff --git a/src/osgPlugins/ive/ProxyNode.cpp b/src/osgPlugins/ive/ProxyNode.cpp new file mode 100644 index 000000000..d9e6bd1d6 --- /dev/null +++ b/src/osgPlugins/ive/ProxyNode.cpp @@ -0,0 +1,169 @@ +/********************************************************************** + * + * FILE: ProxyNode.cpp + * + * DESCRIPTION: Read/Write osg::ProxyNode 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 +#include +#include + +#include "Exception.h" +#include "ProxyNode.h" +#include "Group.h" + +using namespace ive; + + +void ProxyNode::write(DataOutputStream* out) +{ + // Write ProxyNode's identification. + out->writeInt(IVEPROXYNODE); + + // If the osg class is inherited by any other class we should also write this to file. + osg::Group* 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."); + + if ( out->getVersion() > VERSION_0006 ) + { + out->writeString(getDatabasePath()); + } + + out->writeFloat(getRadius()); + out->writeInt(getCenterMode()); + out->writeVec3(getCenter()); + + if(out->getIncludeExternalReferences()) // inlined mode + { + out->writeUInt(getNumChildren()); + unsigned int i; + for(i=0; iwriteNode(getChild(i)); + } + out->writeUInt(getNumFileNames()); + for(i=0; iwriteString(getFileName(i)); + } + } + else //no inlined mode + { + unsigned int numChildrenToWriteOut = 0; + unsigned int i; + for(i=0; iwriteUInt(numChildrenToWriteOut); + for(i=0; iwriteNode(getChild(i)); + } + } + + out->writeUInt(getNumFileNames()); + for(i=0; igetUseOriginalExternalReferences()) + { + out->writeString(getFileName(i)); + } + else + { + std::string ivename = osgDB::getFilePath(getFileName(i)) +"/"+ osgDB::getStrippedName(getFileName(i)) +".ive"; + out->writeString(ivename); + + if(out->getWriteExternalReferenceFiles()) + { + std::string path = getDatabasePath(); + if (path.empty() && out->getOptions() && !out->getOptions()->getDatabasePathList().empty()) + path = out->getOptions()->getDatabasePathList().front(); + if(!path.empty()) path += "/"; + ivename = path + ivename; + osgDB::writeNodeFile(*getChild(i), ivename); + } + } + } + } +} + +void ProxyNode::read(DataInputStream* in) +{ + // Peek on ProxyNode's identification. + int id = in->peekInt(); + if(id == IVEPROXYNODE) + { + // Read ProxyNode's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Group* node = dynamic_cast(this); + if(node) + { + ((ive::Group*)(node))->read(in); + } + else + throw Exception("Group::read(): Could not cast this osg::Group to an osg::Node."); + + + if ( in->getVersion() > VERSION_0006 ) + { + setDatabasePath(in->readString()); + } + + if (getDatabasePath().empty() && in->getOptions() && !in->getOptions()->getDatabasePathList().empty()) + { + const std::string& path = in->getOptions()->getDatabasePathList().front(); + if (!path.empty()) + { + setDatabasePath(path); + } + } + + setRadius(in->readFloat()); + setCenterMode((osg::ProxyNode::CenterMode)in->readInt()); + setCenter(in->readVec3()); + + // Read groups properties. + // Read number of children. + unsigned int size = in->readUInt(); + // Read children. + unsigned int i; + for(i=0; ireadNode()); + } + + size = in->readUInt(); + for(i=0;ireadString()); + std::string filename = in->readString(); + osg::Node *node = osgDB::readNodeFile(getDatabasePath() + filename); // If filename is flt, will need getDatabasePath() + if(node) + addChild(node, filename); + } + } + else + { + throw Exception("ProxyNode::read(): Expected ProxyNode identification."); + } +} diff --git a/src/osgPlugins/ive/ReadWrite.h b/src/osgPlugins/ive/ReadWrite.h index 553311f75..7ff8c593f 100644 --- a/src/osgPlugins/ive/ReadWrite.h +++ b/src/osgPlugins/ive/ReadWrite.h @@ -33,6 +33,7 @@ namespace ive { #define IVEELLIPSOIDMODEL 0x00000024 #define IVETEXGENNODE 0x00000025 #define IVECLIPNODE 0x00000026 +#define IVEPROXYNODE 0x00000027 // Node callbacks #define IVENODECALLBACK 0x00000050 diff --git a/src/osgPlugins/ive/ReaderWriterIVE.cpp b/src/osgPlugins/ive/ReaderWriterIVE.cpp index eb5168c28..eb634bf75 100644 --- a/src/osgPlugins/ive/ReaderWriterIVE.cpp +++ b/src/osgPlugins/ive/ReaderWriterIVE.cpp @@ -76,8 +76,13 @@ class IVEReaderWriter : public ReaderWriter std::string ext = getFileExtension(fileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; + // code for setting up the database path so that internally referenced file are searched for on relative paths. + osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + if(local_opt->getDatabasePathList().empty()) + local_opt->setDatabasePath(osgDB::getFilePath(fileName)); + std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary); - WriteResult result = writeNode(node, fout, options); + WriteResult result = writeNode(node, fout, local_opt.get()); fout.close(); return result; } @@ -95,12 +100,8 @@ class IVEReaderWriter : public ReaderWriter { ive::DataOutputStream out(&fout); - if (options) - { - out.setIncludeImageData(options->getOptionString().find("noTexturesInIVEFile")==std::string::npos); - osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeImageData()=" << out.getIncludeImageData() << std::endl; - } - + out.setOptions(options); + out.writeNode(const_cast(&node)); return WriteResult::FILE_SAVED; } diff --git a/src/osgPlugins/osg/GNUmakefile b/src/osgPlugins/osg/GNUmakefile index 8d2576acb..7a0b1ff88 100644 --- a/src/osgPlugins/osg/GNUmakefile +++ b/src/osgPlugins/osg/GNUmakefile @@ -45,6 +45,7 @@ CXXFILES =\ PolygonOffset.cpp\ PositionAttitudeTransform.cpp\ Projection.cpp\ + ProxyNode.cpp\ ReaderWriterOSG.cpp\ ShadeModel.cpp\ Shape.cpp\ diff --git a/src/osgPlugins/osg/ProxyNode.cpp b/src/osgPlugins/osg/ProxyNode.cpp new file mode 100644 index 000000000..9b6397aa0 --- /dev/null +++ b/src/osgPlugins/osg/ProxyNode.cpp @@ -0,0 +1,168 @@ +#include "osg/ProxyNode" +#include "osg/Notify" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" +#include + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool ProxyNode_readLocalData(Object& obj, Input& fr); +bool ProxyNode_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_ProxyNodeProxy +( + new osg::ProxyNode, + "ProxyNode", + "Object Node ProxyNode", + &ProxyNode_readLocalData, + &ProxyNode_writeLocalData +); + +bool ProxyNode_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + ProxyNode& proxyNode = static_cast(obj); + + if (fr.matchSequence("Center %f %f %f")) + { + Vec3 center; + fr[1].getFloat(center[0]); + fr[2].getFloat(center[1]); + fr[3].getFloat(center[2]); + proxyNode.setCenter(center); + + iteratorAdvanced = true; + fr+=4; + } + else + proxyNode.setCenterMode(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER); + + float radius; + if (fr[0].matchWord("Radius") && fr[1].getFloat(radius)) + { + proxyNode.setRadius(radius); + fr+=2; + iteratorAdvanced = true; + } + + if (proxyNode.getDatabasePath().empty() && fr.getOptions() && !fr.getOptions()->getDatabasePathList().empty()) + { + const std::string& path = fr.getOptions()->getDatabasePathList().front(); + if (!path.empty()) + { + proxyNode.setDatabasePath(path); + } + } + + bool matchFirst; + if ((matchFirst=fr.matchSequence("FileNameList {")) || fr.matchSequence("FileNameList %i {")) + { + + // set up coordinates. + int entry = fr[0].getNoNestedBrackets(); + if (matchFirst) + { + fr += 2; + } + else + { + fr += 3; + } + + unsigned int i=0; + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + if (fr[0].isString() || fr[0].isQuotedString()) + { + if (fr[0].getStr()) + { + osg::Node *node = osgDB::readNodeFile(proxyNode.getDatabasePath() + fr[0].getStr()); // If filename is flt, will need getDatabasePath() + if(node) + { + printf("cargando: %s\n", fr[0].getStr()); + proxyNode.addChild(node, fr[0].getStr()); + } + } + //if (fr[0].getStr()) proxyNode.setFileName(i,fr[0].getStr()); + else proxyNode.setFileName(i,""); + + ++fr; + ++i; + } + else + { + ++fr; + } + } + + iteratorAdvanced = true; + ++fr; + + } + + int num_children; + if (fr[0].matchWord("num_children") && + fr[1].getInt(num_children)) + { + // could allocate space for children here... + fr+=2; + iteratorAdvanced = true; + } + + Node* node = NULL; + while((node=fr.readNode())!=NULL) + { + proxyNode.addChild(node); + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +bool ProxyNode_writeLocalData(const Object& obj, Output& fw) +{ + const ProxyNode& proxyNode = static_cast(obj); + + if (proxyNode.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER) fw.indent() << "Center "<< proxyNode.getCenter() << std::endl; + + fw.indent() << "Radius "<