1 #include <osg/PagedLOD>
2 #include <osgDB/ObjectWrapper>
3 #include <osgDB/InputStream>
4 #include <osgDB/OutputStream>
5 #include <osgDB/Options>
6 
7 // _databasePath
checkDatabasePath(const osg::PagedLOD & node)8 static bool checkDatabasePath( const osg::PagedLOD& node )
9 {
10     return true;
11 }
12 
readDatabasePath(osgDB::InputStream & is,osg::PagedLOD & node)13 static bool readDatabasePath( osgDB::InputStream& is, osg::PagedLOD& node )
14 {
15     bool hasPath; is >> hasPath;
16     if ( !hasPath )
17     {
18         if ( is.getOptions() && !is.getOptions()->getDatabasePathList().empty() )
19         {
20             const std::string& optionPath = is.getOptions()->getDatabasePathList().front();
21             if ( !optionPath.empty() ) node.setDatabasePath( optionPath );
22         }
23     }
24     else
25     {
26         std::string path; is.readWrappedString( path );
27         node.setDatabasePath( path );
28     }
29     return true;
30 }
31 
writeDatabasePath(osgDB::OutputStream & os,const osg::PagedLOD & node)32 static bool writeDatabasePath( osgDB::OutputStream& os, const osg::PagedLOD& node )
33 {
34     os << (!node.getDatabasePath().empty());
35     if ( !node.getDatabasePath().empty() )
36         os.writeWrappedString( node.getDatabasePath() );
37     os << std::endl;
38     return true;
39 }
40 
41 // _perRangeDataList
checkRangeDataList(const osg::PagedLOD & node)42 static bool checkRangeDataList( const osg::PagedLOD& node )
43 {
44     return node.getNumFileNames()>0;
45 }
46 
readRangeDataList(osgDB::InputStream & is,osg::PagedLOD & node)47 static bool readRangeDataList( osgDB::InputStream& is, osg::PagedLOD& node )
48 {
49     unsigned int size = 0; is >> size >> is.BEGIN_BRACKET;
50     for ( unsigned int i=0; i<size; ++i )
51     {
52         std::string name; is.readWrappedString( name );
53         node.setFileName( i, name );
54     }
55     is >> is.END_BRACKET;
56 
57     size = 0; is >> is.PROPERTY("PriorityList") >> size >> is.BEGIN_BRACKET;
58     for ( unsigned int i=0; i<size; ++i )
59     {
60         float offset, scale;
61         is >> offset >> scale;
62 
63         node.setPriorityOffset( i, offset );
64         node.setPriorityScale( i, scale );
65     }
66     is >> is.END_BRACKET;
67     return true;
68 }
69 
writeRangeDataList(osgDB::OutputStream & os,const osg::PagedLOD & node)70 static bool writeRangeDataList( osgDB::OutputStream& os, const osg::PagedLOD& node )
71 {
72     unsigned int size = node.getNumFileNames();
73     os << size << os.BEGIN_BRACKET << std::endl;
74     for ( unsigned int i=0; i<size; ++i )
75     {
76         os.writeWrappedString( node.getFileName(i) );
77         os << std::endl;
78     }
79     os << os.END_BRACKET << std::endl;
80 
81     size = node.getNumPriorityOffsets();
82     os << os.PROPERTY("PriorityList") << size << os.BEGIN_BRACKET << std::endl;
83     for ( unsigned int i=0; i<size; ++i )
84     {
85         os << node.getPriorityOffset(i) << node.getPriorityScale(i) << std::endl;
86     }
87     os << os.END_BRACKET << std::endl;
88     return true;
89 }
90 
91 // _children
checkChildren(const osg::PagedLOD & node)92 static bool checkChildren( const osg::PagedLOD& node )
93 {
94     return node.getNumChildren()>0;
95 }
96 
readChildren(osgDB::InputStream & is,osg::PagedLOD & node)97 static bool readChildren( osgDB::InputStream& is, osg::PagedLOD& node )
98 {
99     unsigned int size = 0; is >> size;
100     if (size > 0)
101     {
102         is >> is.BEGIN_BRACKET;
103         for ( unsigned int i=0; i<size; ++i )
104         {
105             osg::ref_ptr<osg::Node> child = is.readObjectOfType<osg::Node>();
106             if ( child ) node.addChild( child );
107         }
108         is >> is.END_BRACKET;
109     }
110     return true;
111 }
112 
writeChildren(osgDB::OutputStream & os,const osg::PagedLOD & node)113 static bool writeChildren( osgDB::OutputStream& os, const osg::PagedLOD& node )
114 {
115     unsigned int size=node.getNumFileNames(), dynamicLoadedSize=0;
116     for ( unsigned int i=0; i<size; ++i )
117     {
118         if ( !node.getFileName(i).empty() )
119             dynamicLoadedSize++;
120     }
121 
122     unsigned int realSize = size-dynamicLoadedSize; os << realSize;
123     if ( realSize>0 )
124     {
125         os << os.BEGIN_BRACKET << std::endl;
126         for ( unsigned int i=0; i<size; ++i )
127         {
128             if ( !node.getFileName(i).empty() ) continue;
129             if ( i<node.getNumChildren() )
130                 os << node.getChild(i);
131         }
132         os << os.END_BRACKET;
133     }
134     os << std::endl;
135     return true;
136 }
137 
138 REGISTER_OBJECT_WRAPPER( PagedLOD,
139                          new osg::PagedLOD,
140                          osg::PagedLOD,
141                          "osg::Object osg::Node osg::LOD osg::PagedLOD" )
142 {
143     // Note: osg::Group is not in the list to prevent recording dynamic loaded children
144 
145     ADD_USER_SERIALIZER( DatabasePath );  // _databasePath
146     ADD_UINT_SERIALIZER( FrameNumberOfLastTraversal, 0 );  // _frameNumberOfLastTraversal, note, not required, removed from soversion 70 onwwards, see below
147     ADD_UINT_SERIALIZER( NumChildrenThatCannotBeExpired, 0 );  // _numChildrenThatCannotBeExpired
148     ADD_BOOL_SERIALIZER( DisableExternalChildrenPaging, false );  // _disableExternalChildrenPaging
149     ADD_USER_SERIALIZER( RangeDataList );  // _perRangeDataList
150     ADD_USER_SERIALIZER( Children );  // _children (which are not loaded from external)
151 
152     {
153         UPDATE_TO_VERSION_SCOPED( 70 )
154         REMOVE_SERIALIZER( FrameNumberOfLastTraversal );
155     }
156 
157 
158 
159 }
160