Created
April 9, 2015 16:46
-
-
Save jasonbeverage/38bd65f5728f8a2cc5bc to your computer and use it in GitHub Desktop.
Light Point Extraction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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