/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield * * This software is open source and may be redistributed and/or modified under * the terms of the GNU General Public License (GPL) version 2.0. * The full license is in LICENSE.txt file included with this distribution,. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * include LICENSE.txt for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** * OpenSceneGraph plugin wrapper/converter. */ class ReaderWriterP3DXML : public osgDB::ReaderWriter { public: ReaderWriterP3DXML() { supportsOption("suppressEnvTags", "if set to (true|1) all env-tags in the p3d-file will be suppressed"); _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); _colorMap["SKY"] .set(0.2f, 0.2f, 0.4f, 1.0f); _layoutMap["LEFT_TO_RIGHT"] = osgText::Text::LEFT_TO_RIGHT; _layoutMap["RIGHT_TO_LEFT"] = osgText::Text::RIGHT_TO_LEFT; _layoutMap["VERTICAL"] = osgText::Text::VERTICAL; _alignmentMap["LEFT_TOP"] = osgText::Text::LEFT_TOP; _alignmentMap["LEFT_CENTER"] = osgText::Text::LEFT_CENTER; _alignmentMap["LEFT_BOTTOM"] = osgText::Text::LEFT_BOTTOM; _alignmentMap["CENTER_TOP"] = osgText::Text::CENTER_TOP; _alignmentMap["CENTER_CENTER"] = osgText::Text::CENTER_CENTER; _alignmentMap["CENTER_BOTTOM"] = osgText::Text::CENTER_BOTTOM; _alignmentMap["RIGHT_TOP"] = osgText::Text::RIGHT_TOP; _alignmentMap["RIGHT_CENTER"] = osgText::Text::RIGHT_CENTER; _alignmentMap["RIGHT_BOTTOM"] = osgText::Text::RIGHT_BOTTOM; _alignmentMap["LEFT_BASE_LINE"] = osgText::Text::LEFT_BASE_LINE; _alignmentMap["CENTER_BASE_LINE"] = osgText::Text::CENTER_BASE_LINE; _alignmentMap["RIGHT_BASE_LINE"] = osgText::Text::RIGHT_BASE_LINE; _alignmentMap["BASE_LINE"] = osgText::Text::LEFT_BASE_LINE; _characterSizeModeMap["OBJECT_COORDS"] = osgText::Text::OBJECT_COORDS; _characterSizeModeMap["SCREEN_COORDS"] = osgText::Text::SCREEN_COORDS; _characterSizeModeMap["OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT"] = osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT; _stringKeyMap["Home"]=' '; _stringKeyMap["Start"]= osgGA::GUIEventAdapter::KEY_Home; _stringKeyMap["Next"]= osgGA::GUIEventAdapter::KEY_Page_Down; _stringKeyMap["Previous"]=osgGA::GUIEventAdapter::KEY_Page_Up; _stringKeyMap["Up"]=osgGA::GUIEventAdapter::KEY_Up; _stringKeyMap["Down"]=osgGA::GUIEventAdapter::KEY_Down; _stringKeyMap["End"]=osgGA::GUIEventAdapter::KEY_End; _stringKeyMap["Page Down"]=osgGA::GUIEventAdapter::KEY_Page_Down; _stringKeyMap["Page Up"]=osgGA::GUIEventAdapter::KEY_Page_Up; _stringKeyMap["F1"]=osgGA::GUIEventAdapter::KEY_F1; _stringKeyMap["F2"]=osgGA::GUIEventAdapter::KEY_F2; _stringKeyMap["F3"]=osgGA::GUIEventAdapter::KEY_F3; _stringKeyMap["F4"]=osgGA::GUIEventAdapter::KEY_F4; _stringKeyMap["F5"]=osgGA::GUIEventAdapter::KEY_F5; _stringKeyMap["F6"]=osgGA::GUIEventAdapter::KEY_F6; _stringKeyMap["F7"]=osgGA::GUIEventAdapter::KEY_F7; _stringKeyMap["F8"]=osgGA::GUIEventAdapter::KEY_F8; _stringKeyMap["F9"]=osgGA::GUIEventAdapter::KEY_F9; _stringKeyMap["F10"]=osgGA::GUIEventAdapter::KEY_F10; _stringKeyMap["F11"]=osgGA::GUIEventAdapter::KEY_F11; _stringKeyMap["F12"]=osgGA::GUIEventAdapter::KEY_F12; _notifyLevel = osg::INFO; } bool match(const std::string& lhs, const std::string& rhs) const { // check for perfect match // if (lhs==rhs) return true; // OSG_NOTICE<<"comparing "<='a' && l<='z') l = (l-'a')+'A'; if (r>='a' && r<='z') r = (r-'a')+'A'; // if both charaters are equal then move to the next character if (l==r) { lhs_itr++; rhs_itr++; continue; } // if space, underscore or hyphon exist then stop over that particular character if (l==' ' || l=='_' || l=='-') { lhs_itr++; continue; } if (r==' ' || r=='_' || r=='-') { rhs_itr++; continue; } break; } bool matched = (lhs_itr==lhs.end()) && (rhs_itr==rhs.end()); // OSG_NOTICE<<" matched "<second; osg::Vec4 color; if (read(str,color)) return color; else return osg::Vec4(0.0f,0.0f,0.0f,1.0f); } inline osg::Vec4 accumulateRotation(const osg::Vec4& lhs, const osg::Vec4& rhs) const { osg::Quat qlhs,qrhs; qlhs.makeRotate(osg::DegreesToRadians(lhs[0]),lhs[1],lhs[2],lhs[3]); qrhs.makeRotate(osg::DegreesToRadians(rhs[0]),rhs[1],rhs[2],rhs[3]); osg::Quat quat = qlhs*qrhs; osg::Vec4d result; quat.getRotate ( result[0], result[1], result[2], result[3]); result[0] = osg::RadiansToDegrees(result[0]); return result; } inline bool read(const char* str, int& value) const; inline bool read(const char* str, float& value) const; inline bool read(const char* str, double& value) const; inline bool read(const char* str, int numberValues, float* values) 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, bool& value) const; inline bool read(const std::string& str, int& value) const; inline bool read(const std::string& str, float& value) const; inline bool read(const std::string& str, double& value) const; inline bool read(const std::string& str, int numberValues, float* values) 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(osgDB::XmlNode* cur, const char* token) const; bool getKeyProperty(osgDB::XmlNode* cur, const char* token, int& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, bool& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, int& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, float& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, double& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, int numberValues, float* values) const; bool getProperty(osgDB::XmlNode* cur, const char* token, osg::Vec2& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, osg::Vec3& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, osg::Vec4& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, std::string& value) const; bool getTrimmedProperty(osgDB::XmlNode* cur, const char* token, std::string& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, osgText::Text::Layout& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, osgText::Text::AlignmentType& value) const; bool getProperty(osgDB::XmlNode* cur, const char* token, osgText::Text::CharacterSizeMode& value) const; bool getProperties(osgDB::XmlNode* cur, osgPresentation::SlideShowConstructor::PositionData& value) const; bool getProperties(osgDB::XmlNode* cur, osgPresentation::SlideShowConstructor::FontData& value) const; bool getProperties(osgDB::XmlNode* cur, osgPresentation::SlideShowConstructor::ModelData& value) const; bool getProperties(osgDB::XmlNode* cur, osgPresentation::SlideShowConstructor::ImageData& value) const; bool getProperties(osgDB::XmlNode* cur, osgPresentation::SlideShowConstructor::ScriptData& value) const; bool getJumpProperties(osgDB::XmlNode* cur, osgPresentation::JumpData& jumpData) const; bool getKeyPositionInner(osgDB::XmlNode* cur, osgPresentation::KeyPosition& keyPosition) const; bool getKeyPosition(osgDB::XmlNode* cur, osgPresentation::KeyPosition& keyPosition) const; typedef std::map ColorMap; typedef std::map LayoutMap; typedef std::map AlignmentMap; typedef std::map CharacterSizeModeMap; typedef std::map StringKeyMap; template typename T::const_iterator find(const T& container, const std::string& rhs) const { for(typename T::const_iterator itr = container.begin(); itr != container.end(); ++itr) { if (match(itr->first, rhs)) { // OSG_NOTICE<<"Found match "<first<<" == "< > TemplateMap; mutable TemplateMap _templateMap; osg::NotifySeverity _notifyLevel; }; // now register with Registry to instantiate the above // reader/writer. REGISTER_OSGPLUGIN(p3d, ReaderWriterP3DXML) std::string ReaderWriterP3DXML::expandEnvVarsInFileName(const std::string& filename) const { std::string argument(filename); std::string::size_type start_pos = argument.find("${"); while (start_pos != std::string::npos) { std::string::size_type end_pos = argument.find("}",start_pos); if (start_pos != std::string::npos) { std::string var = argument.substr(start_pos+2, end_pos-start_pos-2); const char* str = getenv(var.c_str()); if (str) { argument.erase(start_pos, end_pos-start_pos+1); argument.insert(start_pos, str); } start_pos = argument.find("${",end_pos); } else { start_pos = std::string::npos; } } return argument; } bool ReaderWriterP3DXML::read(const char* str, int& value) const { if (!str) return false; std::istringstream iss((const char*)str); iss >> value; return !iss.fail(); } bool ReaderWriterP3DXML::read(const char* str, float& value) const { if (!str) return false; std::istringstream iss((const char*)str); iss >> value; return !iss.fail(); } bool ReaderWriterP3DXML::read(const char* str, double& value) const { if (!str) return false; std::istringstream iss((const char*)str); iss >> value; return !iss.fail(); } bool ReaderWriterP3DXML::read(const char* str, int numberValues, float* values) const { if (!str) return false; std::istringstream iss((const char*)str); for(int i=0; i> *values; ++values; } return !iss.fail(); } bool ReaderWriterP3DXML::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 ReaderWriterP3DXML::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 ReaderWriterP3DXML::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 ReaderWriterP3DXML::read(const std::string& str, bool& value) const { if ((str == "1") || (str == "0")) { value = (str == "1"); return true; } std::string s(osgDB::convertToLowerCase(str)); value = match(s,"true"); return true; } bool ReaderWriterP3DXML::read(const std::string& str, int& value) const { std::istringstream iss(str); iss >> value; return !iss.fail(); } bool ReaderWriterP3DXML::read(const std::string& str, float& value) const { std::istringstream iss(str); iss >> value; return !iss.fail(); } bool ReaderWriterP3DXML::read(const std::string& str, double& value) const { std::istringstream iss(str); iss >> value; return !iss.fail(); } bool ReaderWriterP3DXML::read(const std::string& str, int numberValues, float* values) const { std::istringstream iss(str); for(int i=0; i> *values; ++values; } return !iss.fail(); } bool ReaderWriterP3DXML::read(const std::string& str, osg::Vec2& value) const { std::istringstream iss(str); iss >> value.x() >> value.y(); return !iss.fail(); } bool ReaderWriterP3DXML::read(const std::string& str, osg::Vec3& value) const { std::istringstream iss(str); iss >> value.x() >> value.y() >> value.z(); return !iss.fail(); } bool ReaderWriterP3DXML::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(); } osgDB::XmlNode::Properties::const_iterator ReaderWriterP3DXML::findProperty(osgDB::XmlNode* cur, const char* token) const { osgDB::XmlNode::Properties::const_iterator itr = find(cur->properties, token); return itr; } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token) const { return find(cur->properties, token) != cur->properties.end(); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, bool& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, int& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getKeyProperty(osgDB::XmlNode* cur, const char* token, int& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; OSG_NOTICE<<"getKeyProperty()="<second<second.empty()) { OSG_NOTICE<<" empty()"<second.find("0x",0,2)!=std::string::npos) { std::istringstream iss(itr->second); iss>>std::hex>>value; OSG_NOTICE<<"ReaderWriterP3DXML::getKeyProperty() hex result = "<second.size()>1 && (itr->second[0]>='0' && itr->second[0]<='9')) { std::istringstream iss(itr->second); iss>>value; OSG_NOTICE<<"ReaderWriterP3DXML::getKeyProperty() numeric result = "<second[0]; OSG_NOTICE<<"ReaderWriterP3DXML::getKeyProperty() alphanumeric result = "<properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, double& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, int numberValues, float* values) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second, numberValues, values); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, osg::Vec2& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, osg::Vec3& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, osg::Vec4& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; return read(itr->second,value); } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, std::string& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; value = itr->second; return true; } bool ReaderWriterP3DXML::getTrimmedProperty(osgDB::XmlNode* cur, const char* token, std::string& value) const { osgDB::XmlNode::Properties::const_iterator itr = findProperty(cur, token); if (itr==cur->properties.end()) return false; value = osgDB::trimEnclosingSpaces(itr->second); return true; } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, osgText::Text::Layout& value) const { osgDB::XmlNode::Properties::const_iterator pitr = findProperty(cur, token); if (pitr==cur->properties.end()) return false; const std::string& str = pitr->second; LayoutMap::const_iterator itr = find(_layoutMap,str); if (itr!=_layoutMap.end()) { value = itr->second; } return true; } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, osgText::Text::AlignmentType& value) const { osgDB::XmlNode::Properties::const_iterator pitr = findProperty(cur, token); if (pitr==cur->properties.end()) return false; const std::string& str = pitr->second; AlignmentMap::const_iterator itr = find(_alignmentMap, str); if (itr!=_alignmentMap.end()) { value = itr->second; } return true; } bool ReaderWriterP3DXML::getProperty(osgDB::XmlNode* cur, const char* token, osgText::Text::CharacterSizeMode& value) const { osgDB::XmlNode::Properties::const_iterator pitr = findProperty(cur, token); if (pitr==cur->properties.end()) return false; const std::string& str = pitr->second; CharacterSizeModeMap::const_iterator itr = find(_characterSizeModeMap, str); if (itr!=_characterSizeModeMap.end()) { value = itr->second; } return true; } bool ReaderWriterP3DXML::getProperties(osgDB::XmlNode* cur, osgPresentation::SlideShowConstructor::PositionData& value) const { bool propertiesRead=false; 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); // temporary std::string str; if (getProperty(cur, "coordinate_frame", str)) { propertiesRead = true; if (match(str,"model")) value.frame = osgPresentation::SlideShowConstructor::MODEL; else if (match(str,"slide")) value.frame = osgPresentation::SlideShowConstructor::SLIDE; else OSG_NOTIFY(_notifyLevel)<<"Parser error - coordinate_frame=\""<children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (match(cur->name, "property")) { std::string name; std::string type; getProperty(cur, "name", name); getProperty(cur, "type", type); if (match(type,"float")) { float value; std::stringstream str(cur->contents); str>>value; udc.setUserValue(name, value); readProperties = true; OSG_NOTICE<<"Adding property float "<contents); str>>value; udc.setUserValue(name, value); readProperties = true; OSG_NOTICE<<"Adding property int "<contents); readProperties = true; OSG_NOTICE<<"Adding property string "<contents<name<<"] expecting "<children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (match(cur->name, "key_frame")) { double time; if (getProperty(cur, "time", time)) { osg::ref_ptr udc = new osg::DefaultUserDataContainer; if (parseProperties(cur, *udc)) { OSG_NOTICE<<"Adding keyframe"<"<name<<"] expecting "<getTrimmedContents(); if (!filename.empty()) { constructor.addModel(filename, positionRead ? positionData : constructor.getModelPositionData(), modelData, scriptData ); } } void ReaderWriterP3DXML::parseModelScript(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur) const { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getModelPositionData(); bool positionRead = getProperties(cur, positionData); osgPresentation::SlideShowConstructor::ModelData modelData;// = constructor.getModelData(); getProperties(cur, modelData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); std::string language = "lua"; getProperty(cur, "language", language); std::string function = ""; getProperty(cur, "function", function); std::string scriptContents = cur->contents; if (!scriptContents.empty()) { osg::ref_ptr script = new osg::Script; script->setLanguage(language); script->setScript(scriptContents); osg::ScriptEngine* se = constructor.getOrCreateScriptEngine(language); if (se) { osg::Parameters inputParameters, outputParameters; se->run(script.get(), function, inputParameters, outputParameters); for(osg::Parameters::iterator itr = outputParameters.begin(); itr != outputParameters.end(); ++itr) { OSG_NOTICE<<"Parsing return object "<<(*itr)->className()<(itr->get()); if (model) { OSG_NOTICE<<"Adding model "<children.begin(); itr != cur->children.end(); ++itr) { osgDB::XmlNode* child = itr->get(); if (match(child->name,"hull")) { volumeData.hull = child->contents; getProperties(child, volumeData.hullPositionData); } } std::string vs; if (getProperty(cur, "vs", vs) || getProperty(cur, "VolumeSettings", vs)) { volumeData.volumeSettings = osgDB::readRefFile(vs); if (volumeData.volumeSettings.valid()) { OSG_NOTICE<<"VolumeSetting read "<setFilename(vs); OSG_NOTICE<<" assigned name to VS "<getFilename()<(transferFunctionFile); } if (getTrimmedProperty(cur, "tf-255", transferFunctionFile)) { volumeData.transferFunction = osgDB::readRefFile(transferFunctionFile); } if (getProperty(cur, "options", volumeData.options)) {} // check for draggers required std::string dragger; if (getProperty(cur, "dragger", dragger)) { if (match(dragger,"trackball")) { volumeData.useTabbedDragger = false; volumeData.useTrackballDragger = true; } if (match(dragger,"trackball-box")) { volumeData.useTabbedDragger = true; volumeData.useTrackballDragger = true; } else { volumeData.useTabbedDragger = true; volumeData.useTrackballDragger = false; } } osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); std::string filename = cur->getTrimmedContents(); if (!filename.empty()) { constructor.addVolume(filename, positionRead ? positionData : constructor.getModelPositionData(), volumeData, scriptData ); } } void ReaderWriterP3DXML::parseStereoPair(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur) const { OSG_INFO<<"ReaderWriterP3DXML::parseStereoPair()"<children.begin(); itr != cur->children.end(); ++itr) { osgDB::XmlNode* child = itr->get(); if (match(child->name,"image_left")) { getProperties(child,imageDataLeft); filenameLeft = child->getTrimmedContents(); } else if (match(child->name,"imagesequence_left")) { imageDataLeft.imageSequence = true; getProperties(child,imageDataLeft); filenameLeft = child->getTrimmedContents(); } else if (match(child->name,"image_right")) { getProperties(child,imageDataRight); filenameRight = child->getTrimmedContents(); getProperties(cur,imageDataRight); } else if (match(child->name,"imagesequence_right")) { imageDataRight.imageSequence = true; getProperties(child,imageDataRight); filenameRight = child->getTrimmedContents(); } } osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); OSG_INFO<<" filenameLeft="<name, "escape") || match(cur->name, "esc") || match(cur->name, "exit")) { keyPosition.set(osgGA::GUIEventAdapter::KEY_Escape, 0.0f, 0.0f, false); return true; } return false; } bool ReaderWriterP3DXML::getKeyPositionInner(osgDB::XmlNode* cur, osgPresentation::KeyPosition& keyPosition) const { // x in range -1 to 1, from left to right float x = FLT_MAX; getProperty(cur, "x", x); // y in range -1 to 1, from bottom to top float y = FLT_MAX; getProperty(cur, "y", y); float h = FLT_MAX; if (getProperty(cur, "h", h)) { // h in range 0.0 to 1, from left to right x = h*2.0f-1.0f; } float v = FLT_MAX; if (getProperty(cur, "v", v)) { // v in range 0.0 to 1, from bottom to top y = v*2.0f-1.0f; } bool forward_to_devices = false; getProperty(cur, "forward_to_devices", forward_to_devices); std::string key = cur->getTrimmedContents(); unsigned int keyValue = 0; if (key.empty()) { OSG_NOTICE<<"Warning: empty is invalid, ignoring tag."<second; } else if (key.find("0x",0,2)!=std::string::npos) { std::istringstream iss(key); iss>>std::hex>>keyValue; OSG_INFO<<"ReaderWriterP3DXML::getKeyPositionInner() hex result = "<1 && (key[0]>='0' && key[0]<='9')) { std::istringstream iss(key); iss>>keyValue; OSG_INFO<<"ReaderWriterP3DXML::getKeyPositionInner() numeric result = "<"<, ignoring tag. key=["< timeout = new osgPresentation::Timeout(constructor.getHUDSettings()); // to allow the timeout to be nested with a Layer but still behave like a Layer itself we push the timeout as a Layer, saving the original Layer constructor.pushCurrentLayer(timeout.get()); OSG_NOTICE<<"parseTimeout"<children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (parseLayerChild(constructor, cur, totalIndent)) { // no need to do anything } else if (match(cur->name, "timeout_jump")) { osgPresentation::JumpData jumpData; if (getJumpProperties(cur, jumpData)) { OSG_NOTICE<<"Timeout Jump "<setActionJumpData(jumpData); } } else if (match(cur->name, "timeout_event")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition)) { OSG_NOTICE<<"timeout event ["<setActionKeyPosition(keyPosition); } } else if (match(cur->name, "display_broadcast_event")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition)) { OSG_NOTICE<<"display broadcast event ["<setDisplayBroadcastKeyPosition(keyPosition); } } else if (match(cur->name, "dismiss_broadcast_event")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition)) { OSG_NOTICE<<"dismiss broadcast event ["<setDismissBroadcastKeyPosition(keyPosition); } } else if (match(cur->name, "timeout_broadcast_event")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition)) { OSG_NOTICE<<"timeout broadcast event ["<setActionBroadcastKeyPosition(keyPosition); } } else if (match(cur->name, "idle_duration_before_timeout_display")) { std::istringstream iss(cur->getTrimmedContents()); double duration; iss>>duration; if (!iss.fail()) { OSG_NOTICE<<"timeout->setIdleDurationBeforeTimeoutDisplay("<setIdleDurationBeforeTimeoutDisplay(duration); } } else if (match(cur->name, "idle_duration_before_timeout_action")) { std::istringstream iss(cur->getTrimmedContents()); double duration; iss>>duration; if (!iss.fail()) { OSG_NOTICE<<"timeout->setIdleDurationBeforeTimeoutAction("<setIdleDurationBeforeTimeoutAction(duration); } } else if (match(cur->name, "key_starts_timeout_display")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition) && keyPosition._key!=0) { OSG_NOTICE<<"timeout->setKeyStartsTimoutDisplay("<setKeyStartsTimoutDisplay(keyPosition._key); } } else if (match(cur->name, "key_dismiss_timeout_display")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition) && keyPosition._key!=0) { OSG_NOTICE<<"timeout->setKeyDismissTimoutDisplay("<setKeyDismissTimoutDisplay(keyPosition._key); } } else if (match(cur->name, "key_run_action")) { osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition) && keyPosition._key!=0) { OSG_NOTICE<<"timeout->setKeyRunTimoutAction("<setKeyRunTimoutAction(keyPosition._key); } } } constructor.popCurrentLayer(); // return the parent level } bool ReaderWriterP3DXML::parseLayerChild(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur, float& totalIndent) const { if (match(cur->name, "newline")) { constructor.translateTextCursor(osg::Vec3(0.0f,-0.05f,0.0f)); return true; } else if (match(cur->name, "indent")) { float localIndent = 0.05f; constructor.translateTextCursor(osg::Vec3(localIndent,0.0f,0.0f)); totalIndent += localIndent; return true; } else if (match(cur->name, "unindent")) { float localIndent = -0.05f; constructor.translateTextCursor(osg::Vec3(localIndent,0.0f,0.0f)); totalIndent += localIndent; return true; } else if (match(cur->name, "bullet")) { OSG_INFO<<"bullet ["<contents<<"]"<contents, positionRead ? positionData : constructor.getTextPositionData(), fontRead ? fontData : constructor.getTextFontData(), scriptData ); return true; } else if (match(cur->name, "paragraph")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getTextPositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::FontData fontData = constructor.getTextFontData(); bool fontRead = getProperties(cur,fontData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addParagraph(cur->contents, positionRead ? positionData : constructor.getTextPositionData(), fontRead ? fontData : constructor.getTextFontData(), scriptData ); return true; } else if (match(cur->name, "image")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); getProperties(cur,imageData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addImage(cur->getTrimmedContents(), positionRead ? positionData : constructor.getImagePositionData(), imageData, scriptData ); return true; } else if (match(cur->name, "imagesequence")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); imageData.imageSequence = true; getProperties(cur,imageData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addImage(cur->getTrimmedContents(), positionRead ? positionData : constructor.getImagePositionData(), imageData, scriptData ); return true; } else if (match(cur->name, "graph")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); getProperties(cur,imageData); std::string options; getProperty(cur, "options", options); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addGraph(cur->getTrimmedContents(), positionRead ? positionData : constructor.getImagePositionData(), imageData, scriptData ); return true; } else if (match(cur->name, "vnc")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); getProperties(cur,imageData); std::string password; getProperty(cur, "password", password); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addVNC(cur->getTrimmedContents(), positionRead ? positionData : constructor.getImagePositionData(), imageData, password, scriptData ); return true; } else if (match(cur->name, "browser")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); getProperties(cur,imageData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addBrowser(cur->getTrimmedContents(), positionRead ? positionData : constructor.getImagePositionData(), imageData, scriptData); return true; } else if (match(cur->name, "pdf")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); getProperties(cur,imageData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addPDF(cur->getTrimmedContents(), positionRead ? positionData : constructor.getImagePositionData(), imageData, scriptData ); return true; } else if (match(cur->name, "stereo_pair")) { parseStereoPair(constructor, cur); return true; } else if (match(cur->name, "model")) { parseModel(constructor, cur); return true; } else if (match(cur->name, "model-script")) { parseModelScript(constructor, cur); return true; } else if (match(cur->name, "volume")) { parseVolume(constructor, cur); return true; } else if (match(cur->name, "duration")) { constructor.setLayerDuration(osg::asciiToDouble(cur->contents.c_str())); return true; } else if (match(cur->name, "property_animation")) { osg::ref_ptr pa = new osgPresentation::PropertyAnimation; if (parsePropertyAnimation(cur,*pa)) { constructor.addPropertyAnimation(osgPresentation::SlideShowConstructor::CURRENT_LAYER, pa.get()); } return true; } else if (match(cur->name, "properties")) { if (!constructor.getCurrentLayer()) constructor.addLayer(); if (constructor.getCurrentLayer()) { osg::ref_ptr udc = constructor.getCurrentLayer()->getOrCreateUserDataContainer(); if (parseProperties(cur, *udc)) { OSG_NOTICE<<"Assigned properties to Layer"< switchNode = new osg::Switch;; // to allow the timeout to be nested with a Layer but still behave like a Layer itself we push the timeout as a Layer, saving the original Layer constructor.pushCurrentLayer(switchNode.get()); OSG_NOTICE<<"parseSwitch"<setSingleChildOn(0); constructor.popCurrentLayer(); // return the parent level } void ReaderWriterP3DXML::parseLayer(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* root) const { OSG_INFO<first, itr->second); } } for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (parseLayerChild(constructor, cur, totalIndent)) { // no need to do anything } else if (match(cur->name, "switch")) { parseSwitch(constructor, cur); } else if (match(cur->name, "timeout")) { parseTimeout(constructor, cur); } else if (match(cur->name, "run")) { OSG_INFO<<"run ["<contents<<"]"<contents); } else if (match(cur->name, "jump")) { OSG_INFO<<"Parsed Jump "<name, "click_to_run")) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); OSG_INFO<<"click_to_run ["<contents<<"]"<contents,osgPresentation::RUN, jumpData); } else if (match(cur->name,"forward_mouse_event_to_device") || match(cur->name,"forward_event_to_device")) { osgPresentation::JumpData jumpData; OSG_INFO<<"forward_mouse_event_to_device ["<contents<<"]"<contents,osgPresentation::FORWARD_MOUSE_EVENT, jumpData); } else if (match(cur->name,"forward_touch_event_to_device")) { osgPresentation::JumpData jumpData; OSG_INFO<<"forward_touch_event_to_device ["<contents<<"]"<contents,osgPresentation::FORWARD_TOUCH_EVENT, jumpData); } else if (match(cur->name, "click_to_load")) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); OSG_INFO<<"click_to_load ["<contents<<"]"<contents,osgPresentation::LOAD, jumpData); } else if (match(cur->name, "click_to_event")) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition)) { OSG_INFO<<"click_to_event ["<name, "click_to_jump")) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); constructor.layerClickEventOperation(osgPresentation::JUMP, jumpData); } else if (match(cur->name, "key_to_run")) { int key; if (getKeyProperty(cur, "key", key)) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); OSG_NOTICE<<"key_to_run ["<contents<<"], key="<contents,osgPresentation::RUN, jumpData); } } else if (match(cur->name, "key_to_load")) { int key; if (getKeyProperty(cur, "key", key)) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); OSG_NOTICE<<"key_to_load ["<contents<<"]"<contents,osgPresentation::LOAD, jumpData); } } else if (match(cur->name, "key_to_event")) { int key; if (getKeyProperty(cur, "key", key)) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); osgPresentation::KeyPosition keyPosition; if (getKeyPositionInner( cur, keyPosition)) { OSG_NOTICE<<"key_to_event ["<name, "key_to_jump")) { int key; if (getKeyProperty(cur, "key", key)) { osgPresentation::JumpData jumpData; getJumpProperties(cur, jumpData); OSG_NOTICE<<"key_to_jump"<name, "script_file")) { std::string name; getProperty(cur, "name", name); constructor.addScriptFile(name, cur->contents); } else if (match(cur->name, "script")) { std::string name; getProperty(cur, "name", name); std::string language("lua"); getProperty(cur, "language", language); constructor.addScript(name, language, cur->contents); } else if (match(cur->name, "run_script_file")) { parseRunScriptFile(constructor, cur); } else if (match(cur->name, "run_script")) { parseRunScript(constructor, cur); } else { osgPresentation::KeyPosition keyPosition; if (getKeyPosition(cur, keyPosition)) { constructor.addLayerKey(keyPosition); } } } if (totalIndent != 0.0f) { constructor.translateTextCursor(osg::Vec3(-totalIndent,0.0f,0.0f)); } std::string name; if (getProperty(root, "layer_name", name)) { if (constructor.getCurrentLayer()) { constructor.getCurrentLayer()->setUserValue("name",name); OSG_NOTICE<<"Setting current layers name "<contents<<"]"<contents, positionRead ? positionData : constructor.getTextPositionData(), fontRead ? fontData : constructor.getTextFontData(), scriptData ); } void ReaderWriterP3DXML::parseText(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur, bool inheritPreviousLayers, bool defineAsBaseLayer) const { constructor.addLayer(inheritPreviousLayers, defineAsBaseLayer); OSG_INFO<<"text ["<contents<<"]"<contents, positionRead ? positionData : constructor.getTextPositionData(), fontRead ? fontData : constructor.getTextFontData(), scriptData ); } void ReaderWriterP3DXML::parsePage(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur) const { constructor.addSlide(); std::string title; getProperty(cur, "title", title); std::string inherit; getProperty(cur, "inherit", inherit); if (!inherit.empty() && _templateMap.count(inherit)!=0) { parseSlide(constructor, _templateMap[inherit].get(), true, false); } if (!title.empty()) { constructor.setSlideTitle(title, constructor.getTitlePositionData(), constructor.getTitleFontData()); } if (!inherit.empty() && _templateMap.count(inherit)!=0) { parseSlide(constructor, _templateMap[inherit].get(), false, true); } constructor.addLayer(true,false); osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getTextPositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::FontData fontData = constructor.getTextFontData(); bool fontRead = getProperties(cur,fontData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); constructor.addParagraph(cur->contents, positionRead ? positionData : constructor.getTextPositionData(), fontRead ? fontData : constructor.getTextFontData(), scriptData ); } void ReaderWriterP3DXML::parsePdfDocument(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur) const { std::string title; getProperty(cur, "title", title); std::string inherit; getProperty(cur, "inherit", inherit); constructor.addSlide(); if (!inherit.empty() && _templateMap.count(inherit)!=0) { parseSlide(constructor, _templateMap[inherit].get(), true, false); } if (!title.empty()) { constructor.setSlideTitle(title, constructor.getTitlePositionData(), constructor.getTitleFontData()); } if (!inherit.empty() && _templateMap.count(inherit)!=0) { parseSlide(constructor, _templateMap[inherit].get(), false, true); } constructor.addLayer(true,false); osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getImagePositionData(); getProperties(cur,positionData); osgPresentation::SlideShowConstructor::ImageData imageData;// = constructor.getImageData(); imageData.page = 0; getProperties(cur,imageData); osgPresentation::SlideShowConstructor::ScriptData scriptData; getProperties(cur, scriptData); osg::Image* image = constructor.addInteractiveImage(cur->contents, positionData, imageData, scriptData); osgWidget::PdfImage* pdfImage = dynamic_cast(image); if (pdfImage) { int numPages = pdfImage->getNumOfPages(); OSG_INFO<<"NumOfPages = "<1) { for(int pageNum=1; pageNumgetTrimmedContents(), positionData, imageData, scriptData); } } } } void ReaderWriterP3DXML::parseSlide (osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* root, bool parseTitles, bool parseLayers) const { osg::Vec4 previous_bgcolor = constructor.getBackgroundColor(); osg::Vec4 previous_textcolor = constructor.getTextColor(); // create a keyPosition just in case we need it. osgPresentation::KeyPosition keyPosition; osgPresentation::SlideShowConstructor::ScriptData scriptData; if (getProperties(root, scriptData)) { for(osgPresentation::SlideShowConstructor::ScriptData::Scripts::iterator itr = scriptData.scripts.begin(); itr != scriptData.scripts.end(); ++itr) { constructor.addScriptCallback(osgPresentation::SlideShowConstructor::CURRENT_SLIDE, itr->first, itr->second); } } for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (parseTitles) { if (match(cur->name, "title")) { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getTitlePositionData(); bool positionRead = getProperties(cur,positionData); osgPresentation::SlideShowConstructor::FontData fontData = constructor.getTitleFontData(); bool fontRead = getProperties(cur,fontData); constructor.setSlideTitle(cur->contents, positionRead ? positionData : constructor.getTitlePositionData(), fontRead ? fontData : constructor.getTitleFontData()); } else if (match(cur->name, "background")) { constructor.setSlideBackground(cur->contents); std::string str; if (getProperty(cur, "hud", str)) { bool hud = (str != "off" && str != "Off" && str != "OFF"); OSG_NOTIFY(_notifyLevel)<<"background hud, str="<contents),true); } else if (match(cur->name, "textcolor")) { constructor.setTextColor(mapStringToColor(cur->contents)); } } if (parseLayers) { if (match(cur->name, "base")) { constructor.addLayer(true, true); std::string inherit; if (getProperty(cur, "inherit", inherit) && !inherit.empty() && _templateMap.count(inherit)!=0) { parseLayer(constructor, _templateMap[inherit].get()); } parseLayer (constructor, cur); } else if (match(cur->name, "layer")) { constructor.addLayer(true, false); std::string inherit; if (getProperty(cur, "inherit", inherit) && !inherit.empty() && _templateMap.count(inherit)!=0) { parseLayer(constructor, _templateMap[inherit].get()); } parseLayer (constructor, cur); } else if (match(cur->name, "clean_layer")) { constructor.addLayer(false, false); std::string inherit; if (getProperty(cur, "inherit", inherit) && !inherit.empty() && _templateMap.count(inherit)!=0) { parseLayer(constructor, _templateMap[inherit].get()); } parseLayer (constructor, cur); } else if (match(cur->name, "modify_layer")) { int layerNum; if (getProperty(cur, "layer", layerNum)) { constructor.selectLayer(layerNum); } else { constructor.addLayer(true, false); } parseLayer (constructor, cur); } else if (match(cur->name, "bullets")) { parseBullets (constructor, cur,true, false); } else if (match(cur->name, "duration")) { constructor.setSlideDuration(osg::asciiToDouble(cur->contents.c_str())); } else if (match(cur->name, "property_animation")) { osg::ref_ptr pa = new osgPresentation::PropertyAnimation; if (parsePropertyAnimation(cur,*pa)) { constructor.addPropertyAnimation(osgPresentation::SlideShowConstructor::CURRENT_SLIDE, pa.get()); } } else if (match(cur->name, "properties")) { if (!constructor.getCurrentSlide()) constructor.addSlide(); if (constructor.getCurrentSlide()) { osg::ref_ptr udc = constructor.getCurrentSlide()->getOrCreateUserDataContainer(); if (parseProperties(cur, *udc)) { OSG_NOTICE<<"Assigned properties to Slide"<name, "script_file")) { std::string name; getProperty(cur, "name", name); constructor.addScriptFile(name, cur->contents); } else if (match(cur->name, "script")) { std::string name; getProperty(cur, "name", name); std::string language("lua"); getProperty(cur, "language", language); constructor.addScript(name, language, cur->contents); } else if (match(cur->name, "run_script_file")) { parseRunScriptFile(constructor, cur); } else if (match(cur->name, "run_script")) { parseRunScript(constructor, cur); } else if (getKeyPosition(cur, keyPosition)) { constructor.addSlideKey(keyPosition); } } } std::string name; if (getProperty(root, "slide_name", name)) { if (constructor.getCurrentSlide()) { constructor.getCurrentSlide()->setUserValue("name",name); OSG_NOTICE<<"Setting current slide name "< script = osgDB::readRefFile(cur->getTrimmedContents()); if (script.valid()) { osg::ScriptEngine* se = constructor.getOrCreateScriptEngine(script->getLanguage()); if (se) { osg::Parameters inputParameters, outputParameters; se->run(script.get(), function, inputParameters, outputParameters); } } } void ReaderWriterP3DXML::parseRunScript(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur) const { std::string language = "lua"; getProperty(cur, "language", language); std::string function = ""; getProperty(cur, "function", function); std::string scriptContents = cur->contents; if (!scriptContents.empty()) { osg::ref_ptr script = new osg::Script; script->setLanguage(language); script->setScript(scriptContents); osg::ScriptEngine* se = constructor.getOrCreateScriptEngine(language); if (se) { osg::Parameters inputParameters, outputParameters; se->run(script.get(), function, inputParameters, outputParameters); } } } struct MyFindFileCallback : public osgDB::FindFileCallback { virtual std::string findDataFile(const std::string& filename, const osgDB::Options* options, osgDB::CaseSensitivity caseSensitivity) { OSG_INFO<getDatabasePathList() : osgDB::getDataFilePathList(); for(osgDB::FilePathList::const_iterator itr = paths.begin(); itr != paths.end(); ++itr) { const std::string& path = *itr; std::string newpath = osgDB::concatPaths(path, filename); if (osgDB::containsServerAddress(path)) { osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension("curl"); OSG_INFO<<" file on server "<<*itr<<", try path "<findDataFileImplementation(filename, options, caseSensitivity); } }; class MyReadFileCallback : public virtual osgDB::ReadFileCallback { public: osgDB::FilePathList _paths; typedef std::map< std::string, osg::ref_ptr > ObjectCache; enum ObjectType { OBJECT, IMAGE, HEIGHT_FIELD, NODE, SHADER }; osgDB::ReaderWriter::ReadResult readLocal(ObjectType type, const std::string& filename, const osgDB::Options* options) { OSG_INFO<<"Trying local file "<readObjectImplementation(filename,options); case(IMAGE): return osgDB::Registry::instance()->readImageImplementation(filename,options); case(HEIGHT_FIELD): return osgDB::Registry::instance()->readHeightFieldImplementation(filename,options); case(NODE): return osgDB::Registry::instance()->readNodeImplementation(filename,options); case(SHADER): return osgDB::Registry::instance()->readShaderImplementation(filename,options); } return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; } osgDB::ReaderWriter::ReadResult readFileCache(ObjectType type, const std::string& filename, const osgDB::Options* options) { osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); if (!fileCache) return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; OSG_INFO<<"Trying fileCache "<isFileAppropriateForFileCache(filename)) { if (fileCache->existsInCache(filename)) { switch(type) { case(OBJECT): result = fileCache->readObject(filename, 0); break; case(IMAGE): result = fileCache->readImage(filename, 0); break; case(HEIGHT_FIELD): result = fileCache->readHeightField(filename, 0); break; case(NODE): result = fileCache->readNode(filename,0); break; case(SHADER): result = fileCache->readShader(filename, 0); break; } if (result.success()) { OSG_INFO<<" File read from FileCache."<createCacheFileName(filename)<getReaderWriterForProtocolAndExtension( osgDB::getServerProtocol(filename), osgDB::getFileExtension(filename)); if (!rw) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; switch(type) { case(OBJECT): result = rw->readObject(filename,options); break; case(IMAGE): result = rw->readImage(filename,options); break; case(HEIGHT_FIELD): result = rw->readHeightField(filename,options); break; case(NODE): result = rw->readNode(filename,options); break; case(SHADER): result = rw->readShader(filename,options); break; } if (result.success()) { osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); if (fileCache && fileCache->isFileAppropriateForFileCache(filename)) { switch(type) { case(OBJECT): fileCache->writeObject(*result.getObject(),filename,options); break; case(IMAGE): result.getImage()->setFileName(filename); fileCache->writeImage(*result.getImage(),filename,options); break; case(HEIGHT_FIELD): fileCache->writeHeightField(*result.getHeightField(),filename,options); break; case(NODE): fileCache->writeNode(*result.getNode(),filename,options); break; case(SHADER): fileCache->writeShader(*result.getShader(),filename,options); break; } } return result; } return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; } osgDB::ReaderWriter::ReadResult read(const osgDB::FilePathList& filePathList, ObjectType type, const std::string& filename, const osgDB::Options* options, bool checkLocalFiles) { // go look in http paths for(osgDB::FilePathList::const_iterator itr = filePathList.begin(); itr != filePathList.end(); ++itr) { const std::string& path = *itr; std::string newpath = osgDB::containsServerAddress(filename) ? filename : path.empty() ? filename : osgDB::concatPaths(path, filename); osgDB::ReaderWriter::ReadResult result; if (osgDB::containsServerAddress(newpath)) { if (checkLocalFiles) result = readFileCache(type, newpath, options); else result = readServer(type, newpath, options); } else if (checkLocalFiles && osgDB::fileExists(newpath)) { result = readLocal(type, newpath, options); } if (result.success()) { OSG_INFO<<" inserting object into file cache "<setPluginStringData("filename",newpath); return result; } } return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND; } osgDB::ReaderWriter::ReadResult read(ObjectType type, const std::string& filename, const osgDB::Options* options) { osgDB::FileCache* fileCache = options ? options->getFileCache() : 0; if (!fileCache) fileCache = osgDB::Registry::instance()->getFileCache(); if (fileCache && !fileCache->isFileAppropriateForFileCache(filename)) fileCache = 0; OSG_INFO<<"MyReadFileCallback::reading file "<second.valid()) { OSG_INFO<<"File retrieved from cache, filename="<second.get(); } else { OSG_INFO<<"File failed to load previously, won't attempt a second time "<getDatabasePathList().empty())) { result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); if (result.success()) return result; } result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); if (result.success()) return result; } OSG_INFO<<" MyReadFileCallback::reading file B"<getDatabasePathList().empty())) { result = read(options->getDatabasePathList(), type, filename, options, checkLocalFiles); if (result.success()) return result; } result = read(osgDB::Registry::instance()->getDataFilePathList(), type, filename, options, checkLocalFiles); if (result.success()) return result; } OSG_INFO<<" MyReadFileCallback::reading file C"< local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setReadFileCallback(new MyReadFileCallback); local_opt->setFindFileCallback(new MyFindFileCallback); return readNode(input, local_opt.get()); } osgDB::ReaderWriter::ReadResult ReaderWriterP3DXML::readNode(osgDB::XmlNode::Input& input, osgDB::ReaderWriter::Options* options) const { std::string fileName = options ? options->getPluginStringData("filename") : std::string(); std::string extension = osgDB::getFileExtension(fileName); std::string fileNameSansExtension = osgDB::getNameLessExtension(fileName); std::string nestedExtension = osgDB::getFileExtension(fileNameSansExtension); std::string fileNameSansNestedExtension = osgDB::getFileExtension(fileNameSansExtension); bool readOnlyHoldingPage = nestedExtension=="preview" || (options && options->getOptionString()=="preview"); bool readOnlyMainPresentation = nestedExtension=="main" || (options && options->getOptionString()=="main"); osg::ref_ptr doc = new osgDB::XmlNode; osgDB::XmlNode* root = 0; doc->read(input); OSG_INFO<<"P3D xml file read, now building presentation scene graph."<write(fout); #endif if (doc == NULL ) { fprintf(stderr,"Document not parsed successfully. \n"); return ReadResult::FILE_NOT_HANDLED; } for(osgDB::XmlNode::Children::iterator itr = doc->children.begin(); itr != doc->children.end() && !root; ++itr) { if (match((*itr)->name,"presentation")) root = itr->get(); } if (root == NULL) { fprintf(stderr,"empty document\n"); return ReadResult::FILE_NOT_HANDLED; } if (!match(root->name,"presentation")) { fprintf(stderr,"document of the wrong type, root node != presentation"); return ReadResult::FILE_NOT_HANDLED; } bool hasHoldingSlide = false; for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); itr != root->children.end() && !hasHoldingSlide; ++itr) { osgDB::XmlNode* cur = itr->get(); if (match(cur->name, "holding_slide")) { hasHoldingSlide = true; } } // if we are looking for a holding slide, but one isn't present return NULL. if (readOnlyHoldingPage && !hasHoldingSlide) return 0; OSG_INFO<<"hasHoldingSlide "< presentation_node; if (!readOnlyHoldingPage && !readOnlyMainPresentation) { if (fileName.empty()) hasHoldingSlide = false; osg::ref_ptr holdingslide_node = hasHoldingSlide ? parseXmlGraph(root, true, options) : 0; if (holdingslide_node.valid()) { double farDistance = 10000.0f; osg::ref_ptr pagedLOD = new osg::PagedLOD; pagedLOD->setDatabaseOptions(options); pagedLOD->addChild(holdingslide_node.get()); pagedLOD->setRange(0,farDistance,2.0*farDistance); std::string fileNameToLoadMainPresentation = fileNameSansExtension + std::string(".main.")+extension; pagedLOD->setFileName(1,fileNameToLoadMainPresentation); pagedLOD->setRange(1,0.0,farDistance); presentation_node = pagedLOD.get(); } else { presentation_node = parseXmlGraph(root, false, options); } } else { presentation_node = parseXmlGraph(root, readOnlyHoldingPage, options); } if (presentation_node.valid()) { if (!options || options->getPluginStringData("P3D_EVENTHANDLER")!="none") { // if (!readOnlyHoldingPage && !readOnlyMainPresentation) { osgPresentation::SlideEventHandler* seh = new osgPresentation::SlideEventHandler; seh->set(presentation_node.get()); presentation_node->addEventCallback(seh); } } return presentation_node.release(); } else { return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE; } } osg::Node* ReaderWriterP3DXML::parseXmlGraph(osgDB::XmlNode* root, bool readOnlyHoldingPage, osgDB::Options* options) const { osgPresentation::SlideShowConstructor constructor(options); // create a keyPosition just in case we need it. osgPresentation::KeyPosition keyPosition; osgDB::FilePathList previousPaths = osgDB::getDataFilePathList(); bool env_tag_suppressed = false || (options && ((options->getPluginStringData("suppressEnvTags") == "1") || (match(options->getPluginStringData("suppressEnvTags"),"true")))); for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (match(cur->name,"env") && !env_tag_suppressed) { char* str = strdup(cur->contents.c_str()); OSG_INFO<<"putenv("<(options->getReadFileCallback()) : 0; if (options && !(options->getDatabasePathList().empty())) { pathToPresentation = options->getDatabasePathList().front(); if (readFileCallback) readFileCallback->_paths.push_front(pathToPresentation); } for(osgDB::XmlNode::Children::iterator itr = root->children.begin(); itr != root->children.end(); ++itr) { osgDB::XmlNode* cur = itr->get(); if (match(cur->name, "path")) { std::string newpath = expandEnvVarsInFileName(cur->contents); // now check if an absolue or http path std::string::size_type colonPos = newpath.find_first_of(':'); std::string::size_type backslashPos = newpath.find_first_of('/'); std::string::size_type forwardslashPos = newpath.find_first_of('\\'); bool relativePath = colonPos == std::string::npos && backslashPos != 0 && forwardslashPos != 0; if (relativePath && !pathToPresentation.empty()) { newpath = osgDB::concatPaths(pathToPresentation, newpath); OSG_INFO<<"relative path = "<contents<<", newpath="<contents); } else if (match(cur->name, "script_file")) { std::string name; getProperty(cur, "name", name); constructor.addScriptFile(name, cur->contents); } else if (match(cur->name, "script")) { std::string name; getProperty(cur, "name", name); std::string language("lua"); getProperty(cur, "language", language); constructor.addScript(name, language, cur->contents); } else if (match(cur->name, "run_script_file")) { parseRunScriptFile(constructor, cur); } else if (match(cur->name, "run_script")) { parseRunScript(constructor, cur); } else if (match(cur->name, "name")) { constructor.setPresentationName(cur->contents); } else if (match(cur->name, "loop")) { constructor.setLoopPresentation(true); } else if (match(cur->name, "auto")) { constructor.setAutoSteppingActive(true); } else if (match(cur->name, "title-settings")) { bool fontRead = getProperties(cur,constructor.getTitleFontDataDefault()); if (fontRead) { OSG_INFO<<"Title font details read"<name, "text-settings")) { bool fontRead = getProperties(cur,constructor.getTextFontDataDefault()); if (fontRead) { OSG_INFO<<"Text font details read"<name, "ratio")) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if (key) constructor.setPresentationAspectRatio(cur->contents); xmlFree(key); }*/ else if (match(cur->name, "path")) { OSG_INFO<<"Appending search path "<contents<contents)); } else if (match(cur->name, "bgcolor")) { constructor.setBackgroundColor(mapStringToColor(cur->contents),false); } else if (match(cur->name, "textcolor")) { constructor.setTextColor(mapStringToColor(cur->contents)); } else if (match(cur->name, "duration")) { constructor.setPresentationDuration(osg::asciiToDouble(cur->contents.c_str())); } else if (getKeyPosition(cur, keyPosition)) { constructor.addPresentationKey(keyPosition); } else if (readOnlyHoldingPage && match(cur->name, "holding_slide")) { constructor.addSlide(); parseSlide (constructor, cur); } else if (!readOnlyHoldingPage && match(cur->name, "slide")) { constructor.addSlide(); std::string inherit; if (getProperty(cur, "inherit", inherit) && !inherit.empty() && _templateMap.count(inherit)!=0) { parseSlide(constructor, _templateMap[inherit].get(), true, false); parseSlide (constructor, cur, true, false); parseSlide(constructor, _templateMap[inherit].get(), false, true); parseSlide (constructor, cur, false, true); } else { parseSlide (constructor, cur); } } else if (!readOnlyHoldingPage && match(cur->name, "modify_slide")) { int slideNum; if (getProperty(cur, "slide", slideNum)) { constructor.selectSlide(slideNum); parseSlide (constructor, cur); } else { constructor.addSlide(); } } else if (!readOnlyHoldingPage && match(cur->name, "page")) { parsePage (constructor, cur); } else if (!readOnlyHoldingPage && match(cur->name, "pdf_document")) { parsePdfDocument(constructor, cur); } else if (!readOnlyHoldingPage && match(cur->name, "template_slide")) { std::string name; if (getProperty(cur, "name", name)) { _templateMap[name] = cur; OSG_INFO<<"Defining template slide "<name, "template_layer")) { std::string name; if (getProperty(cur, "name", name)) { _templateMap[name] = cur; OSG_INFO<<"Defining template layer "<name, "property_animation")) { osg::ref_ptr pa = new osgPresentation::PropertyAnimation; if (parsePropertyAnimation(cur,*pa)) { constructor.addPropertyAnimation(osgPresentation::SlideShowConstructor::CURRENT_PRESENTATION, pa.get()); } } else if (!readOnlyHoldingPage && match(cur->name, "properties")) { if (!constructor.getPresentationSwitch()) constructor.createPresentation(); if (constructor.getPresentationSwitch()) { osg::ref_ptr udc = constructor.getPresentationSwitch()->getOrCreateUserDataContainer(); if (parseProperties(cur, *udc)) { OSG_NOTICE<<"Assigned properties to Presentation"<first, itr->second); } } osgDB::getDataFilePathList() = previousPaths; return constructor.takePresentation(); }