Files
qt5-legatus-legacy/Lts/Plugins/BuildingViewer/Common/BgViewer/viewerCtrl/visitors.cpp
T
2026-08-13 18:33:10 +02:00

181 lines
5.3 KiB
C++
Executable File

#include "visitors.h"
#include <dtEntity/property.h>
#include <osg/Material>
#include <osg/BlendFunc>
#include <osg/BlendColor>
#include <QStringRef>
#include <QVector>
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<std::string> 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<QStringRef> descprt = descr.splitRef(QLatin1Char(';'));
for (const QStringRef &prt : descprt)
{
const QVector<QStringRef> 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);
}
}