root/OpenSceneGraph/trunk/src/osgPlugins/osg/ProxyNode.cpp @ 10331

Revision 10331, 8.6 kB (checked in by robert, 6 years ago)

From Gustav Happalahti, fixed filename usage

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "osg/ProxyNode"
2#include "osg/Notify"
3#include <osg/io_utils>
4
5#include "osgDB/Registry"
6#include "osgDB/Input"
7#include "osgDB/Output"
8#include <osgDB/ReadFile>
9#include <osgDB/WriteFile>
10#include <osgDB/FileUtils>
11#include <osgDB/FileNameUtils>
12
13using namespace osg;
14using namespace osgDB;
15
16// forward declare functions to use later.
17bool ProxyNode_readLocalData(Object& obj, Input& fr);
18bool ProxyNode_writeLocalData(const Object& obj, Output& fw);
19
20// register the read and write functions with the osgDB::Registry.
21REGISTER_DOTOSGWRAPPER(ProxyNode)
22(
23    new osg::ProxyNode,
24    "ProxyNode",
25    "Object Node ProxyNode",
26    &ProxyNode_readLocalData,
27    &ProxyNode_writeLocalData
28);
29
30bool ProxyNode_readLocalData(Object& obj, Input& fr)
31{
32    bool iteratorAdvanced = false;
33
34    ProxyNode& proxyNode = static_cast<ProxyNode&>(obj);
35
36    if (fr.matchSequence("Center %f %f %f"))
37    {
38        Vec3 center;
39        fr[1].getFloat(center[0]);
40        fr[2].getFloat(center[1]);
41        fr[3].getFloat(center[2]);
42        proxyNode.setCenter(center);
43
44        iteratorAdvanced = true;
45        fr+=4;
46    }
47    else
48        proxyNode.setCenterMode(osg::ProxyNode::USE_BOUNDING_SPHERE_CENTER);
49
50    if (fr.matchSequence("ExtRefMode %s") || fr.matchSequence("ExtRefMode %w"))
51    {
52        if      (fr[1].matchWord("LOAD_IMMEDIATELY"))
53            proxyNode.setLoadingExternalReferenceMode(ProxyNode::LOAD_IMMEDIATELY);
54        else if (fr[1].matchWord("DEFER_LOADING_TO_DATABASE_PAGER"))
55            proxyNode.setLoadingExternalReferenceMode(ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
56        else if (fr[1].matchWord("NO_AUTOMATIC_LOADING"))
57            proxyNode.setLoadingExternalReferenceMode(ProxyNode::NO_AUTOMATIC_LOADING);
58           
59        fr+=2;
60        iteratorAdvanced = true;
61    }
62
63    float radius;
64    if (fr[0].matchWord("Radius") && fr[1].getFloat(radius))
65    {
66        proxyNode.setRadius(radius);
67        fr+=2;
68        iteratorAdvanced = true;
69    }
70
71    if (fr.getOptions() && !fr.getOptions()->getDatabasePathList().empty())
72    {
73        const std::string& path = fr.getOptions()->getDatabasePathList().front();
74        if (!path.empty())
75        {
76            proxyNode.setDatabasePath(path);
77        }
78    }
79
80    bool matchFirst;
81    if ((matchFirst=fr.matchSequence("FileNameList {")) || fr.matchSequence("FileNameList %i {"))
82    {
83
84        // set up coordinates.
85        int entry = fr[0].getNoNestedBrackets();
86        if (matchFirst)
87        {
88            fr += 2;
89        }
90        else
91        {
92            fr += 3;
93        }
94
95        unsigned int i=0;
96        while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
97        {
98            if (fr[0].isString() || fr[0].isQuotedString())
99            {
100                if (fr[0].getStr()) proxyNode.setFileName(i,fr[0].getStr());
101                else proxyNode.setFileName(i,"");
102               
103                ++fr;
104                ++i;
105            }
106            else
107            {
108                ++fr;
109            }
110        }
111
112        iteratorAdvanced = true;
113        ++fr;
114
115    }
116
117    unsigned int num_children = 0;
118    if (fr[0].matchWord("num_children") &&
119        fr[1].getUInt(num_children))
120    {
121        // could allocate space for children here...
122        fr+=2;
123        iteratorAdvanced = true;
124    }
125
126    unsigned int i;
127    for(i=0; i<num_children; i++)
128    {
129        osgDB::FilePathList& fpl = ((osgDB::ReaderWriter::Options*)fr.getOptions())->getDatabasePathList();
130        fpl.push_front( fpl.empty() ? osgDB::getFilePath(proxyNode.getFileName(i)) : fpl.front()+'/'+ osgDB::getFilePath(proxyNode.getFileName(i)));
131        Node* node = NULL;
132        if((node=fr.readNode())!=NULL)
133        {
134            proxyNode.addChild(node);
135            iteratorAdvanced = true;
136        }
137        fpl.pop_front();
138    }
139
140    if(proxyNode.getLoadingExternalReferenceMode() == ProxyNode::LOAD_IMMEDIATELY)
141    {
142        for(i=0; i<proxyNode.getNumFileNames(); i++)
143        {
144            if(i>=proxyNode.getNumChildren() && !proxyNode.getFileName(i).empty())
145            {
146                osgDB::FilePathList& fpl = ((osgDB::ReaderWriter::Options*)fr.getOptions())->getDatabasePathList();
147                fpl.push_front( fpl.empty() ? osgDB::getFilePath(proxyNode.getFileName(i)) : fpl.front()+'/'+ osgDB::getFilePath(proxyNode.getFileName(i)));
148                osg::Node *node = osgDB::readNodeFile(proxyNode.getFileName(i), fr.getOptions());
149                fpl.pop_front();
150                if(node)
151                {
152                    proxyNode.insertChild(i, node);
153                }
154            }
155        }
156    }
157
158    return iteratorAdvanced;
159}
160
161
162bool ProxyNode_writeLocalData(const Object& obj, Output& fw)
163{
164    bool includeExternalReferences = false;
165    bool useOriginalExternalReferences = true;
166    bool writeExternalReferenceFiles = false;
167    std::string optionsString = fw.getOptions()->getOptionString();
168    includeExternalReferences = optionsString.find("includeExternalReferences")!=std::string::npos;
169    bool newExternals = optionsString.find("writeExternalReferenceFiles")!=std::string::npos;
170    if (newExternals)
171    {
172        useOriginalExternalReferences = false;
173        writeExternalReferenceFiles = true;
174    }
175
176    const ProxyNode& proxyNode = static_cast<const ProxyNode&>(obj);
177
178    if (proxyNode.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER) fw.indent() << "Center "<< proxyNode.getCenter() << std::endl;
179
180    fw.indent() << "ExtRefMode ";
181   
182    switch(proxyNode.getLoadingExternalReferenceMode())
183    {
184    case ProxyNode::LOAD_IMMEDIATELY:
185        fw.indent() << "LOAD_IMMEDIATELY" <<std::endl;
186        break;
187    case ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER:
188        fw.indent() << "DEFER_LOADING_TO_DATABASE_PAGER" <<std::endl;
189        break;
190    case ProxyNode::NO_AUTOMATIC_LOADING:
191        fw.indent() << "NO_AUTOMATIC_LOADING" <<std::endl;
192        break;
193    }
194
195    fw.indent() << "Radius "<<proxyNode.getRadius()<<std::endl;
196
197    fw.indent() << "FileNameList "<<proxyNode.getNumFileNames()<<" {"<< std::endl;
198    fw.moveIn();
199   
200    unsigned int numChildrenToWriteOut = 0;
201   
202    for(unsigned int i=0; i<proxyNode.getNumFileNames();++i)
203    {
204        if (proxyNode.getFileName(i).empty())
205        {
206            fw.indent() << "\"\"" << std::endl;
207            ++numChildrenToWriteOut;
208        }
209        else 
210        {
211            if(useOriginalExternalReferences)
212            {
213                fw.indent() << proxyNode.getFileName(i) << std::endl;
214            }
215            else
216            {
217                std::string path = osgDB::getFilePath(fw.getFileName());
218                std::string new_filename = osgDB::getStrippedName(proxyNode.getFileName(i)) +".osg";
219                std::string osgname = path.empty() ? new_filename :  (path +"/"+ new_filename) ;
220                fw.indent() << osgname << std::endl;
221            }
222        }
223    }
224    fw.moveOut();
225    fw.indent() << "}"<< std::endl;
226
227
228    if(includeExternalReferences) //out->getIncludeExternalReferences()) // inlined mode
229    {
230        fw.indent() << "num_children " << proxyNode.getNumChildren() << std::endl;
231        for(unsigned int i=0; i<proxyNode.getNumChildren(); i++)
232        {
233            fw.writeObject(*proxyNode.getChild(i));
234        }
235    }
236    else //----------------------------------------- no inlined mode
237    {
238        fw.indent() << "num_children " << numChildrenToWriteOut << std::endl;
239        for(unsigned int i=0; i<proxyNode.getNumChildren(); ++i)
240        {
241            if (proxyNode.getFileName(i).empty())
242            {
243                fw.writeObject(*proxyNode.getChild(i));
244            }
245            else if(writeExternalReferenceFiles) //out->getWriteExternalReferenceFiles())
246            {
247                if(useOriginalExternalReferences) //out->getUseOriginalExternalReferences())
248                {
249                    std::string origname = proxyNode.getFileName(i);
250                    if (!fw.getExternalFileWritten(origname))
251                    {
252                        osgDB::writeNodeFile(*proxyNode.getChild(i), origname);
253                        fw.setExternalFileWritten(origname, true);
254                    }
255                }
256                else
257                {
258                    std::string path = osgDB::getFilePath(fw.getFileName());
259                    std::string new_filename = osgDB::getStrippedName(proxyNode.getFileName(i)) +".osg";
260                    std::string osgname = path.empty() ? new_filename :  (path +"/"+ new_filename) ;
261                    if (!fw.getExternalFileWritten(osgname))
262                    {
263                        osgDB::writeNodeFile(*proxyNode.getChild(i), osgname);
264                        fw.setExternalFileWritten(osgname, true);
265                    }
266                }
267            }
268        }
269    }
270
271    return true;
272}
Note: See TracBrowser for help on using the browser.