2004-08-06 16:56:18 +08:00
|
|
|
#include <sstream>
|
|
|
|
|
2003-12-08 19:24:43 +08:00
|
|
|
#include <osg/Image>
|
|
|
|
#include <osg/Group>
|
2004-10-13 22:13:17 +08:00
|
|
|
#include <osg/Notify>
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2003-12-08 19:24:43 +08:00
|
|
|
#include <osgDB/FileNameUtils>
|
|
|
|
#include <osgDB/FileUtils>
|
|
|
|
#include <osgDB/Registry>
|
|
|
|
#include <osgDB/Input>
|
|
|
|
#include <osgDB/Output>
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
using namespace osg;
|
|
|
|
using namespace osgDB;
|
|
|
|
|
|
|
|
class OSGReaderWriter : public ReaderWriter
|
|
|
|
{
|
|
|
|
public:
|
2004-10-26 18:26:43 +08:00
|
|
|
virtual const char* className() const { return "OSG Reader/Writer"; }
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual bool acceptsExtension(const std::string& extension) const
|
2001-09-20 05:08:56 +08:00
|
|
|
{
|
|
|
|
return equalCaseInsensitive(extension,"osg");
|
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual ReadResult readObject(const std::string& fileName, const Options* opt) const { return readNode(fileName, opt); }
|
2004-10-01 15:39:15 +08:00
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual ReadResult readObject(std::istream& fin, const Options* opt) const { return readNode(fin, opt); }
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual ReadResult readNode(const std::string& file, const Options* opt) const
|
2001-09-20 05:08:56 +08:00
|
|
|
{
|
2003-12-08 19:24:43 +08:00
|
|
|
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
2001-10-30 22:20:37 +08:00
|
|
|
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2004-11-23 07:54:45 +08:00
|
|
|
std::string fileName = osgDB::findDataFile( file, opt );
|
2003-12-08 19:24:43 +08:00
|
|
|
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
|
|
|
|
2004-11-23 18:46:37 +08:00
|
|
|
// code for setting up the database path so that internally referenced file are searched for on relative paths.
|
2004-11-23 07:54:45 +08:00
|
|
|
osg::ref_ptr<Options> local_opt = opt ? static_cast<Options*>(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
|
|
|
|
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
|
2004-10-13 22:13:17 +08:00
|
|
|
|
2003-05-26 17:27:16 +08:00
|
|
|
std::ifstream fin(fileName.c_str());
|
2001-09-20 05:08:56 +08:00
|
|
|
if (fin)
|
|
|
|
{
|
2004-10-13 22:13:17 +08:00
|
|
|
return readNode(fin, local_opt.get());
|
2003-05-26 17:27:16 +08:00
|
|
|
}
|
|
|
|
return 0L;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual ReadResult readNode(std::istream& fin, const Options* options) const
|
2003-05-26 17:27:16 +08:00
|
|
|
{
|
2007-05-21 14:57:30 +08:00
|
|
|
fin.imbue(std::locale::classic());
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2003-05-26 17:27:16 +08:00
|
|
|
Input fr;
|
|
|
|
fr.attach(&fin);
|
2004-10-06 17:31:34 +08:00
|
|
|
fr.setOptions(options);
|
2004-10-13 22:13:17 +08:00
|
|
|
|
2003-05-26 17:27:16 +08:00
|
|
|
typedef std::vector<osg::Node*> NodeList;
|
|
|
|
NodeList nodeList;
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2003-05-26 17:27:16 +08:00
|
|
|
// load all nodes in file, placing them in a group.
|
|
|
|
while(!fr.eof())
|
|
|
|
{
|
|
|
|
Node *node = fr.readNode();
|
|
|
|
if (node) nodeList.push_back(node);
|
|
|
|
else fr.advanceOverCurrentFieldOrBlock();
|
|
|
|
}
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2003-05-26 17:27:16 +08:00
|
|
|
if (nodeList.empty())
|
|
|
|
{
|
|
|
|
return ReadResult("No data loaded");
|
|
|
|
}
|
|
|
|
else if (nodeList.size()==1)
|
|
|
|
{
|
|
|
|
return nodeList.front();
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-05-26 17:27:16 +08:00
|
|
|
Group* group = new Group;
|
|
|
|
group->setName("import group");
|
|
|
|
for(NodeList::iterator itr=nodeList.begin();
|
|
|
|
itr!=nodeList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
group->addChild(*itr);
|
|
|
|
}
|
|
|
|
return group;
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
2003-05-26 17:27:16 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
void setPrecision(Output& fout, const osgDB::ReaderWriter::Options* options) const
|
2004-08-06 16:56:18 +08:00
|
|
|
{
|
|
|
|
if (options)
|
|
|
|
{
|
|
|
|
std::istringstream iss(options->getOptionString());
|
|
|
|
std::string opt;
|
2005-11-17 23:03:51 +08:00
|
|
|
while (iss >> opt)
|
|
|
|
{
|
|
|
|
if(opt=="PRECISION" || opt=="precision")
|
|
|
|
{
|
2004-08-06 16:56:18 +08:00
|
|
|
int prec;
|
|
|
|
iss >> prec;
|
|
|
|
fout.precision(prec);
|
|
|
|
}
|
2005-09-19 22:07:44 +08:00
|
|
|
if (opt=="OutputTextureFiles")
|
|
|
|
{
|
2007-01-20 17:44:05 +08:00
|
|
|
fout.setOutputTextureFiles(true);
|
2005-09-19 22:07:44 +08:00
|
|
|
}
|
2004-08-06 16:56:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual WriteResult writeObject(const Object& obj,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
2001-09-20 05:08:56 +08:00
|
|
|
{
|
2004-11-18 19:53:51 +08:00
|
|
|
std::string ext = osgDB::getLowerCaseFileExtension(fileName);
|
|
|
|
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
|
|
|
|
|
2004-08-06 16:56:18 +08:00
|
|
|
Output fout(fileName.c_str());
|
2001-09-20 05:08:56 +08:00
|
|
|
if (fout)
|
|
|
|
{
|
2007-05-21 14:57:30 +08:00
|
|
|
fout.setOptions(options);
|
|
|
|
|
2004-08-06 16:56:18 +08:00
|
|
|
setPrecision(fout,options);
|
|
|
|
|
2007-05-21 14:57:30 +08:00
|
|
|
fout.imbue(std::locale::classic());
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
fout.writeObject(obj);
|
|
|
|
fout.close();
|
2001-10-30 22:20:37 +08:00
|
|
|
return WriteResult::FILE_SAVED;
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
2001-10-30 22:20:37 +08:00
|
|
|
return WriteResult("Unable to open file for output");
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual WriteResult writeObject(const Object& obj,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
|
2004-10-01 15:39:15 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
if (fout)
|
|
|
|
{
|
2007-05-21 14:57:30 +08:00
|
|
|
Output foutput;
|
|
|
|
foutput.setOptions(options);
|
|
|
|
|
|
|
|
std::ios &fios = foutput;
|
|
|
|
fios.rdbuf(fout.rdbuf());
|
|
|
|
|
|
|
|
fout.imbue(std::locale::classic());
|
|
|
|
|
2004-10-01 15:39:15 +08:00
|
|
|
setPrecision(foutput,options);
|
|
|
|
|
|
|
|
foutput.writeObject(obj);
|
|
|
|
return WriteResult::FILE_SAVED;
|
|
|
|
}
|
|
|
|
return WriteResult("Unable to write to output stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
|
2001-09-20 05:08:56 +08:00
|
|
|
{
|
2002-02-19 04:46:47 +08:00
|
|
|
std::string ext = getFileExtension(fileName);
|
|
|
|
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
|
|
|
|
|
2004-08-06 16:56:18 +08:00
|
|
|
|
2003-05-26 17:27:16 +08:00
|
|
|
Output fout(fileName.c_str());
|
2001-09-20 05:08:56 +08:00
|
|
|
if (fout)
|
|
|
|
{
|
2007-05-21 14:57:30 +08:00
|
|
|
fout.setOptions(options);
|
|
|
|
|
|
|
|
fout.imbue(std::locale::classic());
|
|
|
|
|
2004-08-06 16:56:18 +08:00
|
|
|
setPrecision(fout,options);
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
fout.writeObject(node);
|
|
|
|
fout.close();
|
2001-10-30 22:20:37 +08:00
|
|
|
return WriteResult::FILE_SAVED;
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
2001-10-30 22:20:37 +08:00
|
|
|
return WriteResult("Unable to open file for output");
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
|
2004-11-23 23:29:52 +08:00
|
|
|
virtual WriteResult writeNode(const Node& node,std::ostream& fout, const osgDB::ReaderWriter::Options* options) const
|
2004-10-01 15:39:15 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if (fout)
|
|
|
|
{
|
2007-05-21 14:57:30 +08:00
|
|
|
Output foutput;
|
|
|
|
foutput.setOptions(options);
|
|
|
|
|
|
|
|
std::ios &fios = foutput;
|
|
|
|
fios.rdbuf(fout.rdbuf());
|
|
|
|
|
|
|
|
foutput.imbue(std::locale::classic());
|
|
|
|
|
2004-10-01 15:39:15 +08:00
|
|
|
setPrecision(foutput,options);
|
|
|
|
|
|
|
|
foutput.writeObject(node);
|
|
|
|
return WriteResult::FILE_SAVED;
|
|
|
|
}
|
|
|
|
return WriteResult("Unable to write to output stream");
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// now register with Registry to instantiate the above
|
|
|
|
// reader/writer.
|
|
|
|
RegisterReaderWriterProxy<OSGReaderWriter> g_OSGReaderWriterProxy;
|