Files
OpenSceneGraph/examples/slideshow3D/ReaderWriterXML.cpp
Robert Osfield 83bf813e58 Moved the responsibility for finding file to load on to the ReaderWriter plugins,
instead of osgDB::Registry where it original lay.  This has been done to allow
fileName strings to be encode data rather than just file names, such as one
requires when using PagedLOD along with plugins for doing dynamic tesselation.
2003-12-08 11:24:43 +00:00

531 lines
16 KiB
C++

#include <osgDB/ReaderWriter>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include "SlideShowConstructor.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <sstream>
/**
* OpenSceneGraph plugin wrapper/converter.
*/
class ReaderWriterSS3D : public osgDB::ReaderWriter
{
public:
ReaderWriterSS3D()
{
_colorMap["WHITE"] .set(1.0f,1.0f,1.0f,1.0f);
_colorMap["BLACK"] .set(0.0f,0.0f,0.0f,1.0f);
_colorMap["PURPLE"] .set(1.0f,0.0f,1.0f,1.0f);
_colorMap["BLUE"] .set(0.0f,0.0f,1.0f,1.0f);
_colorMap["RED"] .set(1.0f,0.0f,0.0f,1.0f);
_colorMap["CYAN"] .set(0.0f,1.0f,1.0f,1.0f);
_colorMap["YELLOW"] .set(1.0f,1.0f,0.0f,1.0f);
_colorMap["GREEN"] .set(0.0f,1.0f,0.0f,1.0f);
}
virtual const char* className()
{
return "slideshow3D XML Reader/Writer";
}
virtual bool acceptsExtension(const std::string& extension)
{
return osgDB::equalCaseInsensitive(extension,"ss3d") ||
osgDB::equalCaseInsensitive(extension,"xml") ;
}
virtual ReadResult readNode(const std::string& fileName,
const osgDB::ReaderWriter::Options* options);
void parseModel(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
void parseStereoPair(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
void parseLayer(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
void parseSlide (SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
osg::Vec4 mapStringToColor(const std::string& str)
{
return _colorMap[str];
}
inline bool read(const char* str, float& value) const;
inline bool read(const char* str, osg::Vec2& value) const;
inline bool read(const char* str, osg::Vec3& value) const;
inline bool read(const char* str, osg::Vec4& value) const;
inline bool read(const std::string& str, float& value) const;
inline bool read(const std::string& str, osg::Vec2& value) const;
inline bool read(const std::string& str, osg::Vec3& value) const;
inline bool read(const std::string& str, osg::Vec4& value) const;
bool getProperty(xmlNodePtr cur, const char* token) const;
bool getProperty(xmlNodePtr cur, const char* token, float& value) const;
bool getProperty(xmlNodePtr cur, const char* token, osg::Vec2& value) const;
bool getProperty(xmlNodePtr cur, const char* token, osg::Vec3& value) const;
bool getProperty(xmlNodePtr cur, const char* token, osg::Vec4& value) const;
bool getProperty(xmlNodePtr cur, const char* token, std::string& value) const;
std::map<std::string,osg::Vec4> _colorMap;
};
// Register with Registry to instantiate the above reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterSS3D> g_readerWriter_SS3D_Proxy;
bool ReaderWriterSS3D::read(const char* str, float& value) const
{
if (!str) return false;
std::istringstream iss((const char*)str);
iss >> value;
return !iss.fail();
}
bool ReaderWriterSS3D::read(const char* str, osg::Vec2& value) const
{
if (!str) return false;
std::istringstream iss((const char*)str);
iss >> value.x() >> value.y();
return !iss.fail();
}
bool ReaderWriterSS3D::read(const char* str, osg::Vec3& value) const
{
if (!str) return false;
std::istringstream iss((const char*)str);
iss >> value.x() >> value.y() >> value.z();
return !iss.fail();
}
bool ReaderWriterSS3D::read(const char* str, osg::Vec4& value) const
{
if (!str) return false;
std::istringstream iss((const char*)str);
iss >> value.x() >> value.y() >> value.z() >> value.w();
return !iss.fail();
}
bool ReaderWriterSS3D::read(const std::string& str, float& value) const
{
std::istringstream iss(str);
iss >> value;
return !iss.fail();
}
bool ReaderWriterSS3D::read(const std::string& str, osg::Vec2& value) const
{
std::istringstream iss(str);
iss >> value.x() >> value.y();
return !iss.fail();
}
bool ReaderWriterSS3D::read(const std::string& str, osg::Vec3& value) const
{
std::istringstream iss(str);
iss >> value.x() >> value.y() >> value.z();
return !iss.fail();
}
bool ReaderWriterSS3D::read(const std::string& str, osg::Vec4& value) const
{
std::istringstream iss(str);
iss >> value.x() >> value.y() >> value.z() >> value.w();
return !iss.fail();
}
bool ReaderWriterSS3D::getProperty(xmlNodePtr cur, const char* token) const
{
bool success = false;
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)token);
if (key) success=true;
xmlFree(key);
return success;
}
bool ReaderWriterSS3D::getProperty(xmlNodePtr cur, const char* token, float& value) const
{
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)token);
bool success = read((const char*)key,value);
xmlFree(key);
return success;
}
bool ReaderWriterSS3D::getProperty(xmlNodePtr cur, const char* token, osg::Vec2& value) const
{
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)token);
bool success = read((const char*)key,value);
xmlFree(key);
return success;
}
bool ReaderWriterSS3D::getProperty(xmlNodePtr cur, const char* token, osg::Vec3& value) const
{
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)token);
bool success = read((const char*)key,value);
xmlFree(key);
return success;
}
bool ReaderWriterSS3D::getProperty(xmlNodePtr cur, const char* token, osg::Vec4& value) const
{
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)token);
bool success = read((const char*)key,value);
xmlFree(key);
return success;
}
bool ReaderWriterSS3D::getProperty(xmlNodePtr cur, const char* token, std::string& value) const
{
bool success = false;
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)token);
if (key)
{
success = true;
value = (const char*)key;
}
xmlFree(key);
return success;
}
void ReaderWriterSS3D::parseModel(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
{
std::string filename;
SlideShowConstructor::CoordinateFrame coordinate_frame = SlideShowConstructor::SLIDE;
osg::Vec3 position(0.0f,1.0f,0.0f);
osg::Vec4 rotate(0.0f,0.0f,0.0f,1.0f);
float scale = 1.0f;
osg::Vec4 rotation(0.0f,0.0f,0.0f,1.0f);
std::string animation_path;
std::string camera_path;
// temporary
std::string str;
if (getProperty(cur, "coordinate_frame", str))
{
if (str=="model") coordinate_frame = SlideShowConstructor::MODEL;
else if (str=="slide") coordinate_frame = SlideShowConstructor::SLIDE;
else std::cout<<"Parser error - coordinate_frame=\""<<str<<"\" unrecongonized value"<<std::endl;
}
if (coordinate_frame==SlideShowConstructor::SLIDE)
{
position.set(0.5,0.5,0.0);
if (getProperty(cur, "position", str))
{
osg::Vec2 vec2;
osg::Vec3 vec3;
bool fail = false;
if (str=="center") position.set(0.5f,.5f,0.0f);
else if (str=="eye") position.set(0.0f,0.0f,1.0f);
else if (read(str,vec3)) position = vec3;
else if (read(str,vec2)) position.set(vec3.x(),vec3.y(),0.0f);
else fail = true;
if (fail) std::cout<<"Parser error - position=\""<<str<<"\" unrecongonized value"<<std::endl;
else std::cout<<"Read position="<<position<<std::endl;
}
}
else // coordinate_frame==SlideShowConstructor::MODEL
{
position.set(0.0,0.0,0.0);
if (getProperty(cur, "position", str))
{
bool fail = false;
if (str=="center") position.set(0.0f,1.0f,0.0f);
else if (str=="eye") position.set(0.0f,0.0f,0.0f);
else if (!read(str,position)) fail = true;
if (fail) std::cout<<"Parser error - position=\""<<str<<"\" unrecongonized value"<<std::endl;
else std::cout<<"Read position="<<position<<std::endl;
}
}
if (getProperty(cur, "scale", scale))
{
std::cout<<"scale read "<<scale<<std::endl;
}
if (getProperty(cur, "rotate", rotate))
{
std::cout<<"rotate read "<<rotate<<std::endl;
}
if (getProperty(cur, "rotation", rotation))
{
std::cout<<"rotation read "<<rotation<<std::endl;
}
if (getProperty(cur, "path", animation_path))
{
std::cout<<"path read "<<animation_path<<std::endl;
}
if (getProperty(cur, "camera_path", camera_path))
{
std::cout<<"camera path read "<<camera_path<<std::endl;
}
xmlChar *key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) filename = (const char*)key;
xmlFree(key);
if (!filename.empty())
{
if (!camera_path.empty())
{
constructor.addModelWithCameraPath(filename,coordinate_frame,position,scale,rotate,camera_path);
}
else if (!animation_path.empty())
{
constructor.addModelWithPath(filename,coordinate_frame,position,scale,rotate,animation_path);
}
else
{
constructor.addModel(filename,coordinate_frame,position,scale,rotate,rotation);
}
}
}
void ReaderWriterSS3D::parseStereoPair(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
{
std::string filenameLeft;
std::string filenameRight;
float height = 1.0f;
xmlChar *key;
key = xmlGetProp (cur, (const xmlChar *)"height");
if (key) height = atof((const char*)key);
xmlFree(key);
cur = cur->xmlChildrenNode;
while (cur != NULL)
{
if ((!xmlStrcmp(cur->name, (const xmlChar *)"image_left")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) filenameLeft = (const char*)key;
xmlFree(key);
}
if ((!xmlStrcmp(cur->name, (const xmlChar *)"image_right")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) filenameRight = (const char*)key;
xmlFree(key);
}
cur = cur->next;
}
if (!filenameLeft.empty() && !filenameRight.empty())
constructor.addStereoImagePair(filenameLeft,filenameRight,height);
}
void ReaderWriterSS3D::parseLayer(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
{
constructor.addLayer();
xmlChar *key;
cur = cur->xmlChildrenNode;
while (cur != NULL)
{
if ((!xmlStrcmp(cur->name, (const xmlChar *)"bullet")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.addBullet((const char*)key);
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"paragraph")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.addParagraph((const char*)key);
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"image")))
{
std::string filename;
float height = 1.0f;
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) filename = (const char*)key;
xmlFree(key);
key = xmlGetProp (cur, (const xmlChar *)"height");
if (key) height = atoi((const char*)key);
xmlFree(key);
if (!filename.empty()) constructor.addImage(filename,height);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"stereo_pair")))
{
parseStereoPair(constructor, doc,cur);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"model")))
{
parseModel(constructor, doc,cur);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"duration")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setLayerDuration(atof((const char*)key));
xmlFree(key);
}
cur = cur->next;
}
}
void ReaderWriterSS3D::parseSlide (SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
{
constructor.addSlide();
xmlChar *key;
cur = cur->xmlChildrenNode;
while (cur != NULL)
{
if ((!xmlStrcmp(cur->name, (const xmlChar *)"title")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setSlideTitle((const char*)key);
else constructor.setSlideTitle("");
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"background")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setSlideBackground((const char*)key);
else constructor.setSlideBackground("");
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"layer")))
{
parseLayer (constructor, doc, cur);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"duration")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setSlideDuration(atof((const char*)key));
xmlFree(key);
}
cur = cur->next;
}
return;
}
osgDB::ReaderWriter::ReadResult ReaderWriterSS3D::readNode(const std::string& file,
const osgDB::ReaderWriter::Options*)
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file );
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
xmlDocPtr doc;
xmlNodePtr cur;
doc = xmlParseFile(fileName.c_str());
if (doc == NULL ) {
fprintf(stderr,"Document not parsed successfully. \n");
return ReadResult::FILE_NOT_HANDLED;
}
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
fprintf(stderr,"empty document\n");
xmlFreeDoc(doc);
return ReadResult::FILE_NOT_HANDLED;
}
if (xmlStrcmp(cur->name, (const xmlChar *) "presentation")) {
fprintf(stderr,"document of the wrong type, root node != story");
xmlFreeDoc(doc);
return ReadResult::FILE_NOT_HANDLED;
}
SlideShowConstructor constructor;
xmlChar *key;
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"name")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setPresentationName((const char*)key);
else constructor.setPresentationName("");
xmlFree(key);
}
/*else if ((!xmlStrcmp(cur->name, (const xmlChar *)"ratio")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setPresentationAspectRatio((const char*)key);
xmlFree(key);
}*/
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"bgcolor")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setBackgroundColor(mapStringToColor((const char*)key));
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"textcolor")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setTextColor(mapStringToColor((const char*)key));
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"duration")))
{
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
if (key) constructor.setPresentationDuration(atof((const char*)key));
xmlFree(key);
}
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"slide")))
{
parseSlide (constructor, doc, cur);
}
cur = cur->next;
}
xmlFreeDoc(doc);
return constructor.takePresentation();
}