1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#include "visitor.hpp"
#include <osg/Drawable>
#include <osg/MatrixTransform>
#include <osgParticle/ParticleSystem>
#include <osgAnimation/Bone>
#include <components/debug/debuglog.hpp>
#include <components/misc/strings/algorithm.hpp>
#include <cstring>
#include <string_view>
namespace SceneUtil
{
bool FindByNameVisitor::checkGroup(osg::Group& group)
{
if (Misc::StringUtils::ciEqual(group.getName(), mNameToFind))
{
mFoundNode = &group;
return true;
}
return false;
}
void FindByClassVisitor::apply(osg::Node& node)
{
if (Misc::StringUtils::ciEqual(node.className(), mNameToFind))
mFoundNodes.push_back(&node);
traverse(node);
}
void FindByNameVisitor::apply(osg::Group& group)
{
if (!mFoundNode && !checkGroup(group))
traverse(group);
}
void FindByNameVisitor::apply(osg::MatrixTransform& node)
{
if (!mFoundNode && !checkGroup(node))
traverse(node);
}
void FindByNameVisitor::apply(osg::Geometry&) {}
void NodeMapVisitorBoneOnly::apply(osg::MatrixTransform& trans)
{
// Choose first found bone in file
if (dynamic_cast<osgAnimation::Bone*>(&trans) != nullptr)
mMap.emplace(trans.getName(), &trans);
traverse(trans);
}
void NodeMapVisitor::apply(osg::MatrixTransform& trans)
{
// Choose first found node in file
mMap.emplace(trans.getName(), &trans);
traverse(trans);
}
void RemoveVisitor::remove()
{
for (RemoveVec::iterator it = mToRemove.begin(); it != mToRemove.end(); ++it)
{
if (!it->second->removeChild(it->first))
Log(Debug::Error) << "error removing " << it->first->getName();
}
}
void CleanObjectRootVisitor::apply(osg::Drawable& drw)
{
applyDrawable(drw);
}
void CleanObjectRootVisitor::apply(osg::Group& node)
{
applyNode(node);
}
void CleanObjectRootVisitor::apply(osg::MatrixTransform& node)
{
applyNode(node);
}
void CleanObjectRootVisitor::apply(osg::Node& node)
{
applyNode(node);
}
void CleanObjectRootVisitor::applyNode(osg::Node& node)
{
if (node.getStateSet())
node.setStateSet(nullptr);
if (node.getNodeMask() == 0x1 && node.getNumParents() == 1)
mToRemove.emplace_back(&node, node.getParent(0));
else
traverse(node);
}
void CleanObjectRootVisitor::applyDrawable(osg::Node& node)
{
osg::NodePath::iterator parent = getNodePath().end() - 2;
// We know that the parent is a Group because only Groups can have children.
osg::Group* parentGroup = static_cast<osg::Group*>(*parent);
// Try to prune nodes that would be empty after the removal
if (parent != getNodePath().begin())
{
// This could be extended to remove the parent's parent, and so on if they are empty as well.
// But for NIF files, there won't be a benefit since only TriShapes can be set to STATIC dataVariance.
osg::Group* parentParent = static_cast<osg::Group*>(*(parent - 1));
if (parentGroup->getNumChildren() == 1 && parentGroup->getDataVariance() == osg::Object::STATIC)
{
mToRemove.emplace_back(parentGroup, parentParent);
return;
}
}
mToRemove.emplace_back(&node, parentGroup);
}
void RemoveTriBipVisitor::apply(osg::Drawable& drw)
{
applyImpl(drw);
}
void RemoveTriBipVisitor::apply(osg::Group& node)
{
traverse(node);
}
void RemoveTriBipVisitor::apply(osg::MatrixTransform& node)
{
traverse(node);
}
void RemoveTriBipVisitor::applyImpl(osg::Node& node)
{
if (Misc::StringUtils::ciStartsWith(node.getName(), "tri bip"))
{
osg::Group* parent = static_cast<osg::Group*>(*(getNodePath().end() - 2));
// Not safe to remove in apply(), since the visitor is still iterating the child list
mToRemove.emplace_back(&node, parent);
}
}
}
|