#include "visitors.h" #include #include #include #include #include #include namespace VCtrl { //////////////////////////////////////////////////////////////////////////// void FindByNameVisitor::apply(osg::Node &node) { const QString grpName(QString::fromStdString(node.getName())); if (grpName.contains(mName, Qt::CaseInsensitive)) mNodes.push_back(&node); traverse(node); } //////////////////////////////////////////////////////////////////////////// void FindExactNameVisitor::apply(osg::Node &node) { auto it = mNamesToSearch.find(node.getName()); if (it != mNamesToSearch.end()) { mNamesToSearch.erase(it); mNodes.push_back(&node); } if (mNamesToSearch.size()) traverse(node); } //////////////////////////////////////////////////////////////////////////// void FindRoomNamesVisitor::apply(osg::Node &n) { const std::string &nm = n.getName(); if (nm.size() > 8 && nm.substr(0, 8) == "SW_room_") { if (n.getNumDescriptions() > 0) { std::string desc = n.getDescription(0); size_t pos = desc.find('@'); if (pos != std::string::npos) mNames.push_back(desc.substr(pos + 1, desc.size())); } else { std::string roomName = "2" + nm.substr(8, nm.size()); mNames.push_back(roomName); std::vector descList; descList.push_back(nm + "@" + roomName); n.setDescriptions(descList); } } traverse(n); } //////////////////////////////////////////////////////////////////////////// void ClearVertexColorsVisitor::apply(osg::Geode &geode) { for (unsigned int i = 0; i < geode.getNumDrawables(); ++i) { osg::Geometry *geo = geode.getDrawable(i)->asGeometry(); if (geo && geo->getColorArray() != nullptr) { geo->setColorArray(nullptr); geo->setColorBinding(osg::Geometry::BIND_OFF); } } traverse(geode); } //////////////////////////////////////////////////////////////////////////// void SplitVisitor::apply(osg::Group &node) { static const std::string floorPrefix("floor_"); const std::string &nodename = node.getName(); if (nodename.size() >= floorPrefix.size() && std::equal(floorPrefix.begin(), floorPrefix.end(), nodename.begin())) { _parts.emplace_back(&node); float h = 0; for (unsigned int i = 0; i < node.getNumDescriptions(); ++i) { QString descr = QString::fromStdString(node.getDescription(i)); const QVector descprt = descr.splitRef(QLatin1Char(';')); for (const QStringRef &prt : descprt) { const QVector items = prt.split(QLatin1Char('=')); if (items.size() == 2 && items[0] == QLatin1String("base_height")) h = items[1].toFloat(); } } _heights.push_back(h); } traverse(node); } //////////////////////////////////////////////////////////////////////////// void FindRoomComponentsVisitor::apply(osg::Group &node) { static const std::string roomPrefix("undest_room_"); const std::string &nodename = node.getName(); if (nodename.size() >= roomPrefix.size() && std::equal(roomPrefix.begin(), roomPrefix.end(), nodename.begin())) { //parts.push_back(&node); //float h = 0; for (unsigned int i = 0; i < node.getNumDescriptions(); ++i) { const std::string &descr = node.getDescription(i); std::istringstream f(descr); std::string s; while (getline(f, s, ';')) { if (s.size() != 0) mNamesFound.insert(s); } } } traverse(node); } //////////////////////////////////////////////////////////////////////////// void FindRoomByNumberVisitor::apply(osg::Node &searchNode) { if (searchNode.getNumDescriptions() > 0) { const std::string &desc = searchNode.getDescription(0); size_t pos = desc.find('@'); if (pos != std::string::npos && desc.substr(pos + 1, desc.size()) == searchForName) foundNodeList.push_back(&searchNode); } traverse(searchNode); } //////////////////////////////////////////////////////////////////////////// void SetWallsTransparentVisitor::SetAlpha(osg::Node *node, float alpha) { node->setNodeMask(0xFFFFFFFF); osg::StateSet *ss = node->getOrCreateStateSet(); if (alpha > 0.99f) { ss->removeMode(GL_BLEND); ss->setRenderingHint(osg::StateSet::DEFAULT_BIN); /*osg::Material* mat = new osg::Material(); mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); ss->setAttributeAndModes(mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); mat->setAlpha(osg::Material::FRONT_AND_BACK, 1);*/ ss->removeUniform("wall_color"); } else if (alpha < 0.01f) node->setNodeMask(0x0); else { ss->setMode(GL_BLEND, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); osg::BlendFunc *bf = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA); ss->setAttributeAndModes(bf, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); ss->addUniform(new osg::Uniform("wall_color", osg::Vec4(1, 1, 1, alpha))); } } //////////////////////////////////////////////////////////////////////////// void SetWallsTransparentVisitor::apply(osg::Node &node) { std::string nm = node.getName(); if (nm.size() > 4 && nm.substr(0, 4) == "wall") SetAlpha(&node, mTransparency); traverse(node); } }