256 lines
7.9 KiB
C++
256 lines
7.9 KiB
C++
#include "osg/ProxyNode"
|
|
#include "osg/Notify"
|
|
#include <osg/io_utils>
|
|
|
|
#include "osgDB/Registry"
|
|
#include "osgDB/Input"
|
|
#include "osgDB/Output"
|
|
#include <osgDB/ReadFile>
|
|
#include <osgDB/WriteFile>
|
|
#include <osgDB/FileUtils>
|
|
#include <osgDB/FileNameUtils>
|
|
|
|
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.
|
|
REGISTER_DOTOSGWRAPPER(ProxyNode)
|
|
(
|
|
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);
|
|
|
|
if (fr.matchSequence("ExtRefMode %s") || fr.matchSequence("ExtRefMode %w"))
|
|
{
|
|
if (fr[1].matchWord("LOAD_IMMEDIATELY"))
|
|
proxyNode.setLoadingExternalReferenceMode(ProxyNode::LOAD_IMMEDIATELY);
|
|
else if (fr[1].matchWord("DEFER_LOADING_TO_DATABASE_PAGER"))
|
|
proxyNode.setLoadingExternalReferenceMode(ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
|
|
else if (fr[1].matchWord("NO_AUTOMATIC_LOADING"))
|
|
proxyNode.setLoadingExternalReferenceMode(ProxyNode::NO_AUTOMATIC_LOADING);
|
|
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
float radius;
|
|
if (fr[0].matchWord("Radius") && fr[1].getFloat(radius))
|
|
{
|
|
proxyNode.setRadius(radius);
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
if (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()) proxyNode.setFileName(i,fr[0].getStr());
|
|
else proxyNode.setFileName(i,"");
|
|
|
|
++fr;
|
|
++i;
|
|
}
|
|
else
|
|
{
|
|
++fr;
|
|
}
|
|
}
|
|
|
|
iteratorAdvanced = true;
|
|
++fr;
|
|
|
|
}
|
|
|
|
unsigned int num_children = 0;
|
|
if (fr[0].matchWord("num_children") &&
|
|
fr[1].getUInt(num_children))
|
|
{
|
|
// could allocate space for children here...
|
|
fr+=2;
|
|
iteratorAdvanced = true;
|
|
}
|
|
|
|
unsigned int i;
|
|
for(i=0; i<num_children; i++)
|
|
{
|
|
osgDB::FilePathList& fpl = ((osgDB::ReaderWriter::Options*)fr.getOptions())->getDatabasePathList();
|
|
fpl.push_front( fpl.empty() ? osgDB::getFilePath(proxyNode.getFileName(i)) : fpl.front()+'/'+ osgDB::getFilePath(proxyNode.getFileName(i)));
|
|
Node* node = NULL;
|
|
if((node=fr.readNode())!=NULL)
|
|
{
|
|
proxyNode.addChild(node);
|
|
iteratorAdvanced = true;
|
|
}
|
|
fpl.pop_front();
|
|
}
|
|
|
|
if(proxyNode.getLoadingExternalReferenceMode() == ProxyNode::LOAD_IMMEDIATELY)
|
|
{
|
|
for(i=0; i<proxyNode.getNumFileNames(); i++)
|
|
{
|
|
if(i>=proxyNode.getNumChildren() && !proxyNode.getFileName(i).empty())
|
|
{
|
|
osgDB::FilePathList& fpl = ((osgDB::ReaderWriter::Options*)fr.getOptions())->getDatabasePathList();
|
|
fpl.push_front( fpl.empty() ? osgDB::getFilePath(proxyNode.getFileName(i)) : fpl.front()+'/'+ osgDB::getFilePath(proxyNode.getFileName(i)));
|
|
osg::Node *node = osgDB::readNodeFile(proxyNode.getFileName(i), fr.getOptions());
|
|
fpl.pop_front();
|
|
if(node)
|
|
{
|
|
proxyNode.insertChild(i, node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return iteratorAdvanced;
|
|
}
|
|
|
|
|
|
bool ProxyNode_writeLocalData(const Object& obj, Output& fw)
|
|
{
|
|
bool includeExternalReferences = false;
|
|
bool useOriginalExternalReferences = true;
|
|
bool writeExternalReferenceFiles = false;
|
|
|
|
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() << "ExtRefMode ";
|
|
|
|
switch(proxyNode.getLoadingExternalReferenceMode())
|
|
{
|
|
case ProxyNode::LOAD_IMMEDIATELY:
|
|
fw.indent() << "LOAD_IMMEDIATELY" <<std::endl;
|
|
break;
|
|
case ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER:
|
|
fw.indent() << "DEFER_LOADING_TO_DATABASE_PAGER" <<std::endl;
|
|
break;
|
|
case ProxyNode::NO_AUTOMATIC_LOADING:
|
|
fw.indent() << "NO_AUTOMATIC_LOADING" <<std::endl;
|
|
break;
|
|
}
|
|
|
|
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
|
|
{
|
|
if(useOriginalExternalReferences)
|
|
{
|
|
fw.indent() << proxyNode.getFileName(i) << std::endl;
|
|
}
|
|
else
|
|
{
|
|
std::string path = osgDB::getFilePath(fw.getFileName());
|
|
std::string new_filename = osgDB::getStrippedName(proxyNode.getFileName(i)) +".osg";
|
|
std::string osgname = path.empty() ? new_filename : (path +"/"+ new_filename) ;
|
|
fw.indent() << osgname << std::endl;
|
|
}
|
|
}
|
|
}
|
|
fw.moveOut();
|
|
fw.indent() << "}"<< std::endl;
|
|
|
|
|
|
if(includeExternalReferences) //out->getIncludeExternalReferences()) // inlined mode
|
|
{
|
|
fw.indent() << "num_children " << proxyNode.getNumChildren() << std::endl;
|
|
for(unsigned int i=0; i<proxyNode.getNumChildren(); i++)
|
|
{
|
|
fw.writeObject(*proxyNode.getChild(i));
|
|
}
|
|
}
|
|
else //----------------------------------------- no inlined mode
|
|
{
|
|
fw.indent() << "num_children " << numChildrenToWriteOut << std::endl;
|
|
for(unsigned int i=0; i<proxyNode.getNumChildren(); ++i)
|
|
{
|
|
if (proxyNode.getFileName(i).empty())
|
|
{
|
|
fw.writeObject(*proxyNode.getChild(i));
|
|
}
|
|
else if(writeExternalReferenceFiles) //out->getWriteExternalReferenceFiles())
|
|
{
|
|
if(useOriginalExternalReferences) //out->getUseOriginalExternalReferences())
|
|
{
|
|
osgDB::writeNodeFile(*proxyNode.getChild(i), proxyNode.getFileName(i));
|
|
}
|
|
else
|
|
{
|
|
std::string path = osgDB::getFilePath(fw.getFileName());
|
|
std::string new_filename = osgDB::getStrippedName(proxyNode.getFileName(i)) +".osg";
|
|
std::string osgname = path.empty() ? new_filename : (path +"/"+ new_filename) ;
|
|
osgDB::writeNodeFile(*proxyNode.getChild(i), osgname);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|