root/OpenSceneGraph/trunk/src/osgPlugins/ive/ReaderWriterIVE.cpp @ 10819

Revision 10819, 8.5 kB (checked in by robert, 4 years ago)

From Chris Hanson, " Add support for "OutputTextureFiles?" option to IVE plugin to permit creation of external
.dds texture files from internally-embedded textures during IVE writes."

From Robert Osfield, fixed a bug in the above submission, and changed the way that the filename of the file is passed into DataOutputStream? to avoid issues with the .ive's plugins ability to read from istreams.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "MatrixTransform.h"
2#include "Group.h"
3
4#include <osg/Notify>
5
6#include <osgDB/FileNameUtils>
7#include <osgDB/FileUtils>
8#include <osgDB/fstream>
9#include <osgDB/Registry>
10
11using namespace osg;
12using namespace osgDB;
13
14class ReaderWriterIVE : public ReaderWriter
15{
16    public:
17   
18        ReaderWriterIVE()
19        {
20            supportsExtension("ive","OpenSceneGraph native binary format");
21
22            supportsOption("compressed","Export option, use zlib compression to compress the data in the .ive ");
23            supportsOption("noTexturesInIVEFile","Export option");
24            supportsOption("includeImageFileInIVEFile","Export option");
25            supportsOption("compressImageData","Export option");
26            supportsOption("inlineExternalReferencesInIVEFile","Export option");
27            supportsOption("noWriteExternalReferenceFiles","Export option");
28            supportsOption("useOriginalExternalReferences","Export option");
29            supportsOption("TerrainMaximumErrorToSizeRatio=value","Export option that controls error matric used to determine terrain HieghtField storage precision.");
30            supportsOption("noLoadExternalReferenceFiles","Import option");
31            supportsOption("OutputTextureFiles","Write out the texture images to file");
32        }
33   
34        virtual const char* className() const { return "IVE Reader/Writer"; }
35
36        virtual bool acceptsExtension(const std::string& extension) const
37        {
38            return equalCaseInsensitive(extension,"ive");
39        }
40
41        virtual ReadResult readObject(const std::string& file, const Options* options) const
42        {
43            return readNode(file, options);
44        }
45
46        virtual ReadResult readImage(const std::string& file, const Options* options) const
47        {
48            std::string ext = osgDB::getLowerCaseFileExtension(file);
49            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
50            std::string fileName = osgDB::findDataFile(file, options);
51            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
52
53            // code for setting up the database path so that internally referenced files are searched for on relative paths.
54            osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
55            local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
56
57            osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
58            return readImage(istream, local_opt.get());
59        }
60       
61        virtual ReadResult readNode(const std::string& file, const Options* options) const
62        {
63            std::string ext = osgDB::getLowerCaseFileExtension(file);
64            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
65
66            std::string fileName = osgDB::findDataFile( file, options );
67            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
68
69            // code for setting up the database path so that internally referenced file are searched for on relative paths.
70            osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
71            local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
72
73            osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
74            return readNode(istream,local_opt.get());
75        }
76       
77        virtual ReadResult readObject(std::istream& fin, const Options* options) const
78        {
79            return readNode(fin, options);
80        }
81
82        virtual ReadResult readImage(std::istream& fin, const Options* options) const
83        {
84            ive::DataInputStream in(&fin, options);
85            if (in.getException())
86            {
87                return in.getException()->getError();
88            }
89
90            return in.readImage(ive::IMAGE_INCLUDE_DATA);
91        }
92
93        virtual ReadResult readNode(std::istream& fin, const Options* options) const
94        {
95            // Create datainputstream.
96            ive::DataInputStream in(&fin, options);
97            if (in.getException())
98            {
99                return in.getException()->getError();
100            }
101
102            return in.readNode();
103        }
104
105        virtual WriteResult writeObject(const Object& object,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
106        {
107            const Node* node = dynamic_cast<const Node*>(&object);
108            if (node) return writeNode( *node, fileName, options );
109            const Image* image = dynamic_cast<const Image*>(&object);
110            if (image) return writeImage(*image, fileName, options);
111            return WriteResult::FILE_NOT_HANDLED;
112        }
113
114        virtual WriteResult writeImage(const Image& image,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
115        {
116            std::string ext = getFileExtension(fileName);
117            if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
118            // code for setting up the database path so that internally referenced file are searched for on relative paths.
119            osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
120            if(local_opt->getDatabasePathList().empty())
121                local_opt->setDatabasePath(osgDB::getFilePath(fileName));
122
123            local_opt->setPluginStringData("filename",fileName);
124
125            osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
126            if (!fout) return WriteResult::ERROR_IN_WRITING_FILE;
127            WriteResult result = writeImage(image, fout, local_opt.get());
128            fout.close();
129            return result;
130        }
131
132        virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
133        {
134            std::string ext = getFileExtension(fileName);
135            if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
136
137            // code for setting up the database path so that internally referenced file are searched for on relative paths.
138            osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
139            if(local_opt->getDatabasePathList().empty())
140                local_opt->setDatabasePath(osgDB::getFilePath(fileName));
141
142            local_opt->setPluginStringData("filename",fileName);
143
144            osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);
145            if (!fout) return WriteResult::ERROR_IN_WRITING_FILE;
146   
147            WriteResult result = writeNode(node, fout, local_opt.get());
148            fout.close();
149            return result;
150        }
151       
152        virtual WriteResult writeObject(const Object& object,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
153        {
154            const Node* node = dynamic_cast<const Node*>(&object);
155            if (node) return writeNode( *node, fout, options );
156            const Image* image = dynamic_cast<const Image*>(&object);
157            if (image) return writeImage(*image, fout, options);
158            return WriteResult::FILE_NOT_HANDLED;
159        }
160
161        virtual WriteResult writeImage(const Image& image,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
162        {
163            ive::DataOutputStream out(&fout, options);
164            out.writeImage(ive::IMAGE_INCLUDE_DATA, const_cast<osg::Image*>(&image));
165            if (fout.fail()) return WriteResult::ERROR_IN_WRITING_FILE;
166            if (out.getException())
167            {
168                osg::notify(osg::WARN)<<"Error writing IVE image: "<< out.getException()->getError() << std::endl;
169                return WriteResult::FILE_NOT_HANDLED;
170            }
171            return WriteResult::FILE_SAVED;
172        }
173
174        virtual WriteResult writeNode(const Node& node,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
175        {
176            ive::DataOutputStream out(&fout, options);
177
178            out.writeNode(const_cast<osg::Node*>(&node));
179
180            if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
181            if (out.getException())
182            {
183                osg::notify(osg::WARN)<<"Error writing IVE image: "<< out.getException()->getError() << std::endl;
184                return WriteResult::FILE_NOT_HANDLED;
185            }
186
187            return WriteResult::FILE_SAVED;
188        }
189
190};
191
192// now register with Registry to instantiate the above
193// reader/writer.
194REGISTER_OSGPLUGIN(ive, ReaderWriterIVE)
Note: See TracBrowser for help on using the browser.