#include "osg/ProxyNode" #include "osg/Notify" #include #include "osgDB/Registry" #include "osgDB/Input" #include "osgDB/Output" #include #include #include #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. 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(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; igetDatabasePathList(); 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.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; if (fw.getOptions()) { std::string optionsString = fw.getOptions()->getOptionString(); includeExternalReferences = optionsString.find("includeExternalReferences")!=std::string::npos; bool newExternals = optionsString.find("writeExternalReferenceFiles")!=std::string::npos; if (newExternals) { useOriginalExternalReferences = false; writeExternalReferenceFiles = true; } } const ProxyNode& proxyNode = static_cast(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" <getIncludeExternalReferences()) // inlined mode { fw.indent() << "num_children " << proxyNode.getNumChildren() << std::endl; for(unsigned int i=0; igetWriteExternalReferenceFiles()) { if(useOriginalExternalReferences) //out->getUseOriginalExternalReferences()) { std::string origname = proxyNode.getFileName(i); if (!fw.getExternalFileWritten(origname)) { osgDB::writeNodeFile(*proxyNode.getChild(i), origname); fw.setExternalFileWritten(origname, true); } } 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) ; if (!fw.getExternalFileWritten(osgname)) { osgDB::writeNodeFile(*proxyNode.getChild(i), osgname); fw.setExternalFileWritten(osgname, true); } } } } } return true; }