Added new Node::getParentalNodePaths() method.
Added better handling in computeIntersections(..) of nodes that are internal to the scene graph, correctly accounting for the accumulated transforms. Changed the EventVisitor so that it only traveses active children rather than all children. Updated wrappers.
This commit is contained in:
@@ -21,6 +21,36 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
namespace osg
|
||||
{
|
||||
/// Helper class for generating NodePathList.
|
||||
class CollectParentPaths : public NodeVisitor
|
||||
{
|
||||
public:
|
||||
CollectParentPaths(osg::Node* haltTraversalAtNode=0) :
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS),
|
||||
_haltTraversalAtNode(haltTraversalAtNode)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void apply(osg::Node& node)
|
||||
{
|
||||
if (node.getNumParents()==0 || &node==_haltTraversalAtNode)
|
||||
{
|
||||
_nodePaths.push_back(getNodePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
traverse(node);
|
||||
}
|
||||
}
|
||||
|
||||
Node* _haltTraversalAtNode;
|
||||
NodePath _nodePath;
|
||||
NodePathList _nodePaths;
|
||||
};
|
||||
}
|
||||
|
||||
Node::Node()
|
||||
{
|
||||
_boundingSphereComputed = false;
|
||||
@@ -133,6 +163,12 @@ osg::StateSet* Node::getOrCreateStateSet()
|
||||
return _stateset.get();
|
||||
}
|
||||
|
||||
NodePathList Node::getParentalNodePaths(osg::Node* haltTraversalAtNode) const
|
||||
{
|
||||
CollectParentPaths cpp(haltTraversalAtNode);
|
||||
const_cast<Node*>(this)->accept(cpp);
|
||||
return cpp._nodePaths;
|
||||
}
|
||||
|
||||
void Node::setUpdateCallback(NodeCallback* nc)
|
||||
{
|
||||
|
||||
@@ -21,26 +21,6 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
class CollectParentPaths : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
CollectParentPaths() :
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {}
|
||||
|
||||
virtual void apply(osg::Node& node)
|
||||
{
|
||||
if (node.getNumParents()==0)
|
||||
{
|
||||
_nodePaths.push_back(getNodePath());
|
||||
}
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
osg::NodePath _nodePath;
|
||||
typedef std::vector< osg::NodePath > NodePathList;
|
||||
NodePathList _nodePaths;
|
||||
};
|
||||
|
||||
class ApplyMatrixVisitor : public NodeVisitor
|
||||
{
|
||||
public:
|
||||
@@ -88,13 +68,12 @@ void NodeTrackerCallback::setTrackNode(osg::Node* node)
|
||||
return;
|
||||
}
|
||||
|
||||
CollectParentPaths cpp;
|
||||
node->accept(cpp);
|
||||
NodePathList parentNodePaths = node->getParentalNodePaths();
|
||||
|
||||
if (!cpp._nodePaths.empty())
|
||||
if (!parentNodePaths.empty())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"NodeTrackerCallback::setTrackNode(Node*): Path set"<<std::endl;
|
||||
_trackNodePath = cpp._nodePaths[0];
|
||||
_trackNodePath = parentNodePaths[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ using namespace osg;
|
||||
using namespace osgGA;
|
||||
|
||||
EventVisitor::EventVisitor()
|
||||
: NodeVisitor(EVENT_VISITOR,TRAVERSE_ALL_CHILDREN),
|
||||
: NodeVisitor(EVENT_VISITOR,TRAVERSE_ACTIVE_CHILDREN),
|
||||
_handled(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -741,7 +741,7 @@ bool Viewer::computeNearFarPoints(float x,float y,unsigned int cameraNum,osg::Ve
|
||||
bool Viewer::computeIntersections(float x,float y,unsigned int cameraNum,osg::Node* node,osgUtil::IntersectVisitor::HitList& hits,osg::Node::NodeMask traversalMask)
|
||||
{
|
||||
float pixel_x,pixel_y;
|
||||
if (computePixelCoords(x,y,cameraNum,pixel_x,pixel_y))
|
||||
if (node && computePixelCoords(x,y,cameraNum,pixel_x,pixel_y))
|
||||
{
|
||||
|
||||
Producer::Camera* camera=getCamera(cameraNum);
|
||||
@@ -751,11 +751,13 @@ bool Viewer::computeIntersections(float x,float y,unsigned int cameraNum,osg::No
|
||||
osg::Matrixd proj;
|
||||
osg::Matrixd view;
|
||||
const osg::Viewport* viewport = 0;
|
||||
osg::Node* rootNode = 0;
|
||||
if (sv!=0)
|
||||
{
|
||||
viewport = sv->getViewport();
|
||||
proj = sv->getProjectionMatrix();
|
||||
view = sv->getViewMatrix();
|
||||
rootNode = sv->getSceneData();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -764,19 +766,37 @@ bool Viewer::computeIntersections(float x,float y,unsigned int cameraNum,osg::No
|
||||
view = osg::Matrixd(camera->getViewMatrix());
|
||||
}
|
||||
|
||||
osgUtil::PickVisitor pick(viewport, proj, view, pixel_x, pixel_y);
|
||||
pick.setTraversalMask(traversalMask);
|
||||
node->accept(pick);
|
||||
|
||||
// copy all the hits across to the external hits list
|
||||
for(osgUtil::PickVisitor::LineSegmentHitListMap::iterator itr = pick.getSegHitList().begin();
|
||||
itr != pick.getSegHitList().end();
|
||||
++itr)
|
||||
unsigned int numHitsBefore = hits.size();
|
||||
|
||||
osg::NodePathList parentNodePaths = node->getParentalNodePaths(rootNode);
|
||||
for(unsigned int i=0;i<parentNodePaths.size();++i)
|
||||
{
|
||||
hits.insert(hits.end(),itr->second.begin(), itr->second.end());
|
||||
osg::NodePath& nodePath = parentNodePaths[i];
|
||||
|
||||
// remove the intersection node from the nodePath as it'll be accounted for
|
||||
// in the PickVisitor traversal, so we don't double account for its transform.
|
||||
if (!nodePath.empty()) nodePath.pop_back();
|
||||
|
||||
osg::Matrixd modelview(view);
|
||||
// modify the view matrix so that it accounts for this nodePath's accumulated transform
|
||||
if (!nodePath.empty()) modelview.preMult(computeLocalToWorld(nodePath));
|
||||
|
||||
osgUtil::PickVisitor pick(viewport, proj, modelview, pixel_x, pixel_y);
|
||||
pick.setTraversalMask(traversalMask);
|
||||
node->accept(pick);
|
||||
|
||||
// copy all the hits across to the external hits list
|
||||
for(osgUtil::PickVisitor::LineSegmentHitListMap::iterator itr = pick.getSegHitList().begin();
|
||||
itr != pick.getSegHitList().end();
|
||||
++itr)
|
||||
{
|
||||
hits.insert(hits.end(),itr->second.begin(), itr->second.end());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
// return true if we now have more hits than before
|
||||
return hits.size()>numHitsBefore;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ BEGIN_OBJECT_REFLECTOR(osg::Node)
|
||||
I_Method1(osg::Group *, getParent, IN, unsigned int, i);
|
||||
I_Method1(const osg::Group *, getParent, IN, unsigned int, i);
|
||||
I_Method0(unsigned int, getNumParents);
|
||||
I_MethodWithDefaults1(osg::NodePathList, getParentalNodePaths, IN, osg::Node *, haltTraversalAtNode, 0);
|
||||
I_Method1(void, setUpdateCallback, IN, osg::NodeCallback *, nc);
|
||||
I_Method0(osg::NodeCallback *, getUpdateCallback);
|
||||
I_Method0(const osg::NodeCallback *, getUpdateCallback);
|
||||
@@ -123,7 +124,11 @@ END_REFLECTOR
|
||||
|
||||
TYPE_NAME_ALIAS(std::vector< osg::Node * >, osg::NodePath);
|
||||
|
||||
TYPE_NAME_ALIAS(std::vector< osg::NodePath >, osg::NodePathList);
|
||||
|
||||
STD_VECTOR_REFLECTOR(std::vector< osg::Group * >);
|
||||
|
||||
STD_VECTOR_REFLECTOR(std::vector< osg::NodePath >);
|
||||
|
||||
STD_VECTOR_REFLECTOR(std::vector< std::string >);
|
||||
|
||||
|
||||
@@ -337,6 +337,8 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::DataSet::Source)
|
||||
I_Method0(const std::string &, getFileName);
|
||||
I_Method1(void, setTemporaryFile, IN, bool, temporaryFile);
|
||||
I_Method0(bool, getTemporaryFile);
|
||||
I_Method1(void, setGdalDataSet, IN, GDALDataset *, gdalDataSet);
|
||||
I_Method0(GDALDataset *, getGdalDataSet);
|
||||
I_Method1(void, setCoordinateSystemPolicy, IN, osgTerrain::DataSet::Source::ParameterPolicy, policy);
|
||||
I_Method0(osgTerrain::DataSet::Source::ParameterPolicy, getCoordinateSystemPolicy);
|
||||
I_Method1(void, setCoordinateSystem, IN, const std::string &, wellKnownText);
|
||||
@@ -371,6 +373,7 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::DataSet::Source)
|
||||
I_Property(osg::CoordinateSystemNode *, CoordinateSystem);
|
||||
I_Property(osgTerrain::DataSet::Source::ParameterPolicy, CoordinateSystemPolicy);
|
||||
I_Property(const std::string &, FileName);
|
||||
I_Property(GDALDataset *, GdalDataSet);
|
||||
I_Property(osg::Matrixd &, GeoTransform);
|
||||
I_Property(osgTerrain::DataSet::Source::ParameterPolicy, GeoTransformPolicy);
|
||||
I_Property(unsigned int, Layer);
|
||||
|
||||
Reference in New Issue
Block a user