From Alberto Farre, addition of ProxyNode, with support in .osg, .ive and .flt loaders

This commit is contained in:
Robert Osfield
2005-03-07 14:06:09 +00:00
parent f7f61627a8
commit 5684a130b7
19 changed files with 691 additions and 15 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

98
include/osg/ProxyNode Normal file
View File

@@ -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 <osg/Group>
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<std::string> 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

View File

@@ -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);

View File

@@ -77,6 +77,7 @@ CXXFILES =\
PositionAttitudeTransform.cpp\
PrimitiveSet.cpp\
Projection.cpp\
ProxyNode.cpp\
Quat.cpp\
Referenced.cpp\
Sequence.cpp\

122
src/osg/ProxyNode.cpp Normal file
View File

@@ -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 <osg/ProxyNode>
#include <osg/CullStack>
#include <osg/Notify>
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();
}
}

View File

@@ -1568,6 +1568,13 @@ void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* o
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
_objectCache[filename]=ObjectTimeStampPair(object,timestamp);
}
osg::Object* Registry::getFromObjectCache(const std::string& fileName)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> 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)
{

View File

@@ -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) ||

View File

@@ -31,6 +31,7 @@
#include <osg/Sequence>
#include <osg/ShapeDrawable>
#include <osg/Quat>
#include <osg/ProxyNode>
#include <osgSim/MultiSwitch>
#include <osgSim/DOFTransform>
@@ -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<osg::Group*> (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;
}

View File

@@ -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);

View File

@@ -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 <osg/Notify>
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<const osgSim::VisibilityGroup*>(node)){
((ive::VisibilityGroup*)(node))->write(this);
}
else if(dynamic_cast<const osg::ProxyNode*>(node)){
((ive::ProxyNode*)(node))->write(this);
}
else if(dynamic_cast<const osg::Group*>(node)){
((ive::Group*)(node))->write(this);
}

View File

@@ -13,6 +13,7 @@
#include <osg/Matrix>
#include <osg/Geometry>
#include <osg/Shape>
#include <osgDB/ReaderWriter>
#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<const osgDB::ReaderWriter::Options> _options;
};
}

View File

@@ -55,6 +55,7 @@ CXXFILES =\
PolygonOffset.cpp\
PositionAttitudeTransform.cpp\
PrimitiveSet.cpp\
ProxyNode.cpp\
ReaderWriterIVE.cpp\
Sequence.cpp\
ShadeModel.cpp\

View File

@@ -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 <osgDB/WriteFile>
#include <osgDB/ReadFile>
#include <osgDB/FileNameUtils>
#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<osg::Group*>(this);
if(node)
{
static_cast<ive::Group*>(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; i<getNumChildren(); i++)
{
out->writeNode(getChild(i));
}
out->writeUInt(getNumFileNames());
for(i=0; i<getNumFileNames(); i++)
{
out->writeString(getFileName(i));
}
}
else //no inlined mode
{
unsigned int numChildrenToWriteOut = 0;
unsigned int i;
for(i=0; i<getNumFileNames();++i)
{
if (getFileName(i).empty())
{
++numChildrenToWriteOut;
}
}
out->writeUInt(numChildrenToWriteOut);
for(i=0; i<getNumChildren(); i++)
{
if (getFileName(i).empty())
{
out->writeNode(getChild(i));
}
}
out->writeUInt(getNumFileNames());
for(i=0; i<getNumFileNames(); i++)
{
if(out->getUseOriginalExternalReferences())
{
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<osg::Group*>(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; i<size; i++)
{
addChild(in->readNode());
}
size = in->readUInt();
for(i=0;i<size;i++)
{
//setFileName(i, in->readString());
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.");
}
}

View File

@@ -33,6 +33,7 @@ namespace ive {
#define IVEELLIPSOIDMODEL 0x00000024
#define IVETEXGENNODE 0x00000025
#define IVECLIPNODE 0x00000026
#define IVEPROXYNODE 0x00000027
// Node callbacks
#define IVENODECALLBACK 0x00000050

View File

@@ -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<Options> local_opt = options ? static_cast<Options*>(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<osg::Node*>(&node));
return WriteResult::FILE_SAVED;
}

View File

@@ -45,6 +45,7 @@ CXXFILES =\
PolygonOffset.cpp\
PositionAttitudeTransform.cpp\
Projection.cpp\
ProxyNode.cpp\
ReaderWriterOSG.cpp\
ShadeModel.cpp\
Shape.cpp\

View File

@@ -0,0 +1,168 @@
#include "osg/ProxyNode"
#include "osg/Notify"
#include "osgDB/Registry"
#include "osgDB/Input"
#include "osgDB/Output"
#include <osgDB/ReadFile>
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<ProxyNode&>(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<const ProxyNode&>(obj);
if (proxyNode.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER) fw.indent() << "Center "<< proxyNode.getCenter() << std::endl;
fw.indent() << "Radius "<<proxyNode.getRadius()<<std::endl;
fw.indent() << "FileNameList "<<proxyNode.getNumFileNames()<<" {"<< std::endl;
fw.moveIn();
unsigned int numChildrenToWriteOut = 0;
for(unsigned int i=0; i<proxyNode.getNumFileNames();++i)
{
if (proxyNode.getFileName(i).empty())
{
fw.indent() << "\"\"" << std::endl;
++numChildrenToWriteOut;
}
else
{
fw.indent() << proxyNode.getFileName(i) << std::endl;
}
}
fw.moveOut();
fw.indent() << "}"<< std::endl;
fw.indent() << "num_children " << numChildrenToWriteOut << std::endl;
for(unsigned int j=0;j<proxyNode.getNumChildren();++j)
{
if (proxyNode.getFileName(j).empty())
{
fw.writeObject(*proxyNode.getChild(j));
}
}
return true;
}