Skip to content

Instantly share code, notes, and snippets.

@jasonbeverage
Created April 9, 2015 16:46
Show Gist options
  • Save jasonbeverage/38bd65f5728f8a2cc5bc to your computer and use it in GitHub Desktop.
Save jasonbeverage/38bd65f5728f8a2cc5bc to your computer and use it in GitHub Desktop.
Light Point Extraction
typedef std::set< osg::Node* > NodeSet;
typedef std::map< osg::Node*, osg::ref_ptr< osg::Node > > CloneMap;
struct CopyNodesVisitor : public osg::NodeVisitor
{
CopyNodesVisitor(NodeSet& keepers):
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_keepers(keepers),
_currentParent(0)
{
_root = new osg::Group;
_currentParent = _root;
setNodeMaskOverride(~0);
}
virtual void apply(osg::Node& node)
{
if (isKeeper(&node))
{
osg::Node* clone = getClone(&node);
//osg::Node* clone = &node;
if (_currentParent.valid())
{
_currentParent->addChild(clone);
}
OSG_NOTICE << "Node cloning a " << node.className() << std::endl;
traverse(node);
}
}
virtual void apply(osg::Group& group)
{
if (isKeeper(&group))
{
OSG_NOTICE << "Group cloning a " << group.className() << std::endl;
// Clone the group
osg::Group* cloneGroup = (osg::Group*)getClone(&group);
// Remove all the children from the group so that only valid children will be kept
cloneGroup->removeChildren(0, cloneGroup->getNumChildren());
if (_currentParent.valid())
{
_currentParent->addChild(cloneGroup);
}
osg::ref_ptr< osg::Group > prevParent = _currentParent;
_currentParent = cloneGroup;
traverse(group);
_currentParent = prevParent;
}
}
osg::Node* getClone(osg::Node* node)
{
CloneMap::iterator itr = _clones.find(node);
if (itr == _clones.end())
{
osg::Node* clone = (osg::Node*)node->clone(osg::CopyOp::SHALLOW_COPY);
_clones[node] = clone;
return clone;
}
return itr->second.get();
}
bool isKeeper(osg::Node* node)
{
return (_keepers.find(node) != _keepers.end());
}
osg::ref_ptr< osg::Group > _root;
osg::ref_ptr< osg::Group > _currentParent;
CloneMap _clones;
NodeSet& _keepers;
};
osg::Node* extractLightPointsSmart(osg::Node* node)
{
// First, find all the lightpoints
FindNodesVisitor<osgSim::LightPointNode> v;
node->accept(v);
if (v._results.empty())
{
return 0;
}
OSG_NOTICE << "Found " << v._results.size() << " light points" << std::endl;
// Now get the parental node paths of each of the light points and use that to create a new scene graph that only contains the light point nodes and all their parents
NodeSet keepers;
for (unsigned int i = 0; i < v._results.size(); i++)
{
osg::NodePathList parentPaths = v._results[i]->getParentalNodePaths(node);
for (unsigned int j = 0; j < parentPaths.size(); j++)
{
for (unsigned int k = 0; k < parentPaths[j].size(); k++)
{
keepers.insert(parentPaths[j][k]);
}
}
keepers.insert(v._results[i]);
}
OSG_NOTICE << "Keeping " << keepers.size() << " nodes" << std::endl;
CopyNodesVisitor copyNodes(keepers);
node->accept(copyNodes);
osgDB::writeNodeFile(*copyNodes._currentParent.get(), "c:/temp/lightpoints.osg");
osgDB::writeNodeFile(*copyNodes._currentParent.get(), "c:/temp/lightpoints.dot");
if (copyNodes._root.get() != copyNodes._currentParent.get() )
{
OSG_NOTICE << "Parent's not equal" << std::endl;
}
else
{
OSG_NOTICE << "Parent's good" << std::endl;
}
copyNodes._currentParent.release();
return copyNodes._root.release();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment