| 1 | #include <osg/ProxyNode> |
|---|
| 2 | #include <osgDB/ObjectWrapper> |
|---|
| 3 | #include <osgDB/InputStream> |
|---|
| 4 | #include <osgDB/OutputStream> |
|---|
| 5 | #include <osgDB/FileNameUtils> |
|---|
| 6 | #include <osgDB/ReadFile> |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | static bool checkFileNames( const osg::ProxyNode& node ) |
|---|
| 10 | { |
|---|
| 11 | return node.getNumFileNames()>0; |
|---|
| 12 | } |
|---|
| 13 | |
|---|
| 14 | static bool readFileNames( osgDB::InputStream& is, osg::ProxyNode& node ) |
|---|
| 15 | { |
|---|
| 16 | unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET; |
|---|
| 17 | for ( unsigned int i=0; i<size; ++i ) |
|---|
| 18 | { |
|---|
| 19 | std::string value; |
|---|
| 20 | is.readWrappedString( value ); |
|---|
| 21 | node.setFileName( i, value ); |
|---|
| 22 | } |
|---|
| 23 | is >> osgDB::END_BRACKET; |
|---|
| 24 | return true; |
|---|
| 25 | } |
|---|
| 26 | |
|---|
| 27 | static bool writeFileNames( osgDB::OutputStream& os, const osg::ProxyNode& node ) |
|---|
| 28 | { |
|---|
| 29 | os << node.getNumFileNames() << osgDB::BEGIN_BRACKET << std::endl; |
|---|
| 30 | for ( unsigned int i=0; i<node.getNumFileNames(); ++i ) |
|---|
| 31 | { |
|---|
| 32 | os.writeWrappedString( node.getFileName(i) ); |
|---|
| 33 | os << std::endl; |
|---|
| 34 | } |
|---|
| 35 | os << osgDB::END_BRACKET << std::endl; |
|---|
| 36 | return true; |
|---|
| 37 | } |
|---|
| 38 | |
|---|
| 39 | |
|---|
| 40 | static bool checkChildren( const osg::ProxyNode& node ) |
|---|
| 41 | { |
|---|
| 42 | return node.getNumChildren()>0; |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | static bool readChildren( osgDB::InputStream& is, osg::ProxyNode& node ) |
|---|
| 46 | { |
|---|
| 47 | unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET; |
|---|
| 48 | for ( unsigned int i=0; i<size; ++i ) |
|---|
| 49 | { |
|---|
| 50 | osg::Node* child = dynamic_cast<osg::Node*>( is.readObject() ); |
|---|
| 51 | if ( child ) node.addChild( child ); |
|---|
| 52 | } |
|---|
| 53 | is >> osgDB::END_BRACKET; |
|---|
| 54 | return true; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | static bool writeChildren( osgDB::OutputStream& os, const osg::ProxyNode& node ) |
|---|
| 58 | { |
|---|
| 59 | unsigned int size=node.getNumFileNames(), dynamicLoadedSize=0; |
|---|
| 60 | for ( unsigned int i=0; i<size; ++i ) |
|---|
| 61 | { |
|---|
| 62 | if ( !node.getFileName(i).empty() ) |
|---|
| 63 | dynamicLoadedSize++; |
|---|
| 64 | } |
|---|
| 65 | |
|---|
| 66 | unsigned int realSize = size-dynamicLoadedSize; os << realSize; |
|---|
| 67 | if ( realSize>0 ) |
|---|
| 68 | { |
|---|
| 69 | os << osgDB::BEGIN_BRACKET << std::endl; |
|---|
| 70 | for ( unsigned int i=0; i<size; ++i ) |
|---|
| 71 | { |
|---|
| 72 | if ( !node.getFileName(i).empty() ) continue; |
|---|
| 73 | if ( i<node.getNumChildren() ) |
|---|
| 74 | os << node.getChild(i); |
|---|
| 75 | } |
|---|
| 76 | os << osgDB::END_BRACKET; |
|---|
| 77 | } |
|---|
| 78 | os << std::endl; |
|---|
| 79 | return true; |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | |
|---|
| 83 | static bool checkUserCenter( const osg::ProxyNode& node ) |
|---|
| 84 | { |
|---|
| 85 | return (node.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER)||(node.getCenterMode()==osg::ProxyNode::UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED); |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | static bool readUserCenter( osgDB::InputStream& is, osg::ProxyNode& node ) |
|---|
| 89 | { |
|---|
| 90 | osg::Vec3d center; double radius; |
|---|
| 91 | is >> center >> radius; |
|---|
| 92 | node.setCenter( center ); node.setRadius( radius ); |
|---|
| 93 | return true; |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | static bool writeUserCenter( osgDB::OutputStream& os, const osg::ProxyNode& node ) |
|---|
| 97 | { |
|---|
| 98 | os << osg::Vec3d(node.getCenter()) << (double)node.getRadius() << std::endl; |
|---|
| 99 | return true; |
|---|
| 100 | } |
|---|
| 101 | |
|---|
| 102 | struct ProxyNodeFinishedObjectReadCallback : public osgDB::FinishedObjectReadCallback |
|---|
| 103 | { |
|---|
| 104 | virtual void objectRead(osgDB::InputStream& is, osg::Object& obj) |
|---|
| 105 | { |
|---|
| 106 | osg::ProxyNode& proxyNode = static_cast<osg::ProxyNode&>(obj); |
|---|
| 107 | |
|---|
| 108 | if (proxyNode.getLoadingExternalReferenceMode() == osg::ProxyNode::LOAD_IMMEDIATELY) |
|---|
| 109 | { |
|---|
| 110 | for(unsigned int i=0; i<proxyNode.getNumFileNames(); i++) |
|---|
| 111 | { |
|---|
| 112 | if(i >= proxyNode.getNumChildren() && !proxyNode.getFileName(i).empty()) |
|---|
| 113 | { |
|---|
| 114 | osgDB::FilePathList& fpl = ((osgDB::ReaderWriter::Options*)is.getOptions())->getDatabasePathList(); |
|---|
| 115 | fpl.push_front( fpl.empty() ? osgDB::getFilePath(proxyNode.getFileName(i)) : fpl.front()+'/'+ osgDB::getFilePath(proxyNode.getFileName(i))); |
|---|
| 116 | osg::Node* node = osgDB::readNodeFile(proxyNode.getFileName(i), is.getOptions()); |
|---|
| 117 | fpl.pop_front(); |
|---|
| 118 | if(node) |
|---|
| 119 | proxyNode.insertChild(i, node); |
|---|
| 120 | } |
|---|
| 121 | } |
|---|
| 122 | } |
|---|
| 123 | } |
|---|
| 124 | }; |
|---|
| 125 | |
|---|
| 126 | REGISTER_OBJECT_WRAPPER( ProxyNode, |
|---|
| 127 | new osg::ProxyNode, |
|---|
| 128 | osg::ProxyNode, |
|---|
| 129 | "osg::Object osg::Node osg::ProxyNode" ) |
|---|
| 130 | { |
|---|
| 131 | |
|---|
| 132 | |
|---|
| 133 | ADD_USER_SERIALIZER( FileNames ); |
|---|
| 134 | ADD_USER_SERIALIZER( Children ); |
|---|
| 135 | ADD_STRING_SERIALIZER( DatabasePath, "" ); |
|---|
| 136 | |
|---|
| 137 | BEGIN_ENUM_SERIALIZER( LoadingExternalReferenceMode, LOAD_IMMEDIATELY ); |
|---|
| 138 | ADD_ENUM_VALUE( LOAD_IMMEDIATELY ); |
|---|
| 139 | ADD_ENUM_VALUE( DEFER_LOADING_TO_DATABASE_PAGER ); |
|---|
| 140 | ADD_ENUM_VALUE( NO_AUTOMATIC_LOADING ); |
|---|
| 141 | END_ENUM_SERIALIZER(); |
|---|
| 142 | |
|---|
| 143 | BEGIN_ENUM_SERIALIZER( CenterMode, USE_BOUNDING_SPHERE_CENTER ); |
|---|
| 144 | ADD_ENUM_VALUE( USE_BOUNDING_SPHERE_CENTER ); |
|---|
| 145 | ADD_ENUM_VALUE( USER_DEFINED_CENTER ); |
|---|
| 146 | ADD_ENUM_VALUE( UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED ); |
|---|
| 147 | END_ENUM_SERIALIZER(); |
|---|
| 148 | |
|---|
| 149 | ADD_USER_SERIALIZER( UserCenter ); |
|---|
| 150 | |
|---|
| 151 | wrapper->addFinishedObjectReadCallback(new ProxyNodeFinishedObjectReadCallback()); |
|---|
| 152 | } |
|---|