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:
parent
73cc97f0e1
commit
27ad107378
@ -28,6 +28,14 @@ namespace osg {
|
|||||||
class NodeVisitor;
|
class NodeVisitor;
|
||||||
class Group;
|
class Group;
|
||||||
class Transform;
|
class Transform;
|
||||||
|
class Node;
|
||||||
|
|
||||||
|
/** A vector of Nodes pointers which is used to describe the path from a root node to a descendant.*/
|
||||||
|
typedef std::vector< Node* > NodePath;
|
||||||
|
|
||||||
|
/** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
|
||||||
|
typedef std::vector< NodePath > NodePathList;
|
||||||
|
|
||||||
|
|
||||||
/** META_Node macro define the standard clone, isSameKindAs, className
|
/** META_Node macro define the standard clone, isSameKindAs, className
|
||||||
* and accept methods. Use when subclassing from Node to make it
|
* and accept methods. Use when subclassing from Node to make it
|
||||||
@ -103,6 +111,7 @@ class OSG_EXPORT Node : public Object
|
|||||||
inline ParentList getParents() { return _parents; }
|
inline ParentList getParents() { return _parents; }
|
||||||
|
|
||||||
inline Group* getParent(unsigned int i) { return _parents[i]; }
|
inline Group* getParent(unsigned int i) { return _parents[i]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a single const parent of node.
|
* Get a single const parent of node.
|
||||||
* @param i index of the parent to get.
|
* @param i index of the parent to get.
|
||||||
@ -116,6 +125,10 @@ class OSG_EXPORT Node : public Object
|
|||||||
*/
|
*/
|
||||||
inline unsigned int getNumParents() const { return _parents.size(); }
|
inline unsigned int getNumParents() const { return _parents.size(); }
|
||||||
|
|
||||||
|
/** Get the list of node paths parent paths.
|
||||||
|
* The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */
|
||||||
|
NodePathList getParentalNodePaths(osg::Node* haltTraversalAtNode=0) const;
|
||||||
|
|
||||||
|
|
||||||
/** Set update node callback, called during update traversal. */
|
/** Set update node callback, called during update traversal. */
|
||||||
void setUpdateCallback(NodeCallback* nc);
|
void setUpdateCallback(NodeCallback* nc);
|
||||||
@ -337,9 +350,6 @@ class OSG_EXPORT Node : public Object
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A vector of Nodes pointers which is used to describe the path from a root node to a descendant.*/
|
|
||||||
typedef std::vector<Node*> NodePath;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,36 @@
|
|||||||
|
|
||||||
using namespace osg;
|
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()
|
Node::Node()
|
||||||
{
|
{
|
||||||
_boundingSphereComputed = false;
|
_boundingSphereComputed = false;
|
||||||
@ -133,6 +163,12 @@ osg::StateSet* Node::getOrCreateStateSet()
|
|||||||
return _stateset.get();
|
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)
|
void Node::setUpdateCallback(NodeCallback* nc)
|
||||||
{
|
{
|
||||||
|
@ -21,26 +21,6 @@
|
|||||||
|
|
||||||
using namespace osg;
|
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
|
class ApplyMatrixVisitor : public NodeVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -88,13 +68,12 @@ void NodeTrackerCallback::setTrackNode(osg::Node* node)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectParentPaths cpp;
|
NodePathList parentNodePaths = node->getParentalNodePaths();
|
||||||
node->accept(cpp);
|
|
||||||
|
|
||||||
if (!cpp._nodePaths.empty())
|
if (!parentNodePaths.empty())
|
||||||
{
|
{
|
||||||
osg::notify(osg::INFO)<<"NodeTrackerCallback::setTrackNode(Node*): Path set"<<std::endl;
|
osg::notify(osg::INFO)<<"NodeTrackerCallback::setTrackNode(Node*): Path set"<<std::endl;
|
||||||
_trackNodePath = cpp._nodePaths[0];
|
_trackNodePath = parentNodePaths[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ using namespace osg;
|
|||||||
using namespace osgGA;
|
using namespace osgGA;
|
||||||
|
|
||||||
EventVisitor::EventVisitor()
|
EventVisitor::EventVisitor()
|
||||||
: NodeVisitor(EVENT_VISITOR,TRAVERSE_ALL_CHILDREN),
|
: NodeVisitor(EVENT_VISITOR,TRAVERSE_ACTIVE_CHILDREN),
|
||||||
_handled(false)
|
_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)
|
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;
|
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);
|
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 proj;
|
||||||
osg::Matrixd view;
|
osg::Matrixd view;
|
||||||
const osg::Viewport* viewport = 0;
|
const osg::Viewport* viewport = 0;
|
||||||
|
osg::Node* rootNode = 0;
|
||||||
if (sv!=0)
|
if (sv!=0)
|
||||||
{
|
{
|
||||||
viewport = sv->getViewport();
|
viewport = sv->getViewport();
|
||||||
proj = sv->getProjectionMatrix();
|
proj = sv->getProjectionMatrix();
|
||||||
view = sv->getViewMatrix();
|
view = sv->getViewMatrix();
|
||||||
|
rootNode = sv->getSceneData();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -764,19 +766,37 @@ bool Viewer::computeIntersections(float x,float y,unsigned int cameraNum,osg::No
|
|||||||
view = osg::Matrixd(camera->getViewMatrix());
|
view = osg::Matrixd(camera->getViewMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
osgUtil::PickVisitor pick(viewport, proj, view, pixel_x, pixel_y);
|
unsigned int numHitsBefore = hits.size();
|
||||||
pick.setTraversalMask(traversalMask);
|
|
||||||
node->accept(pick);
|
osg::NodePathList parentNodePaths = node->getParentalNodePaths(rootNode);
|
||||||
|
for(unsigned int i=0;i<parentNodePaths.size();++i)
|
||||||
// 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());
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ BEGIN_OBJECT_REFLECTOR(osg::Node)
|
|||||||
I_Method1(osg::Group *, getParent, IN, unsigned int, i);
|
I_Method1(osg::Group *, getParent, IN, unsigned int, i);
|
||||||
I_Method1(const osg::Group *, getParent, IN, unsigned int, i);
|
I_Method1(const osg::Group *, getParent, IN, unsigned int, i);
|
||||||
I_Method0(unsigned int, getNumParents);
|
I_Method0(unsigned int, getNumParents);
|
||||||
|
I_MethodWithDefaults1(osg::NodePathList, getParentalNodePaths, IN, osg::Node *, haltTraversalAtNode, 0);
|
||||||
I_Method1(void, setUpdateCallback, IN, osg::NodeCallback *, nc);
|
I_Method1(void, setUpdateCallback, IN, osg::NodeCallback *, nc);
|
||||||
I_Method0(osg::NodeCallback *, getUpdateCallback);
|
I_Method0(osg::NodeCallback *, getUpdateCallback);
|
||||||
I_Method0(const 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::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::Group * >);
|
||||||
|
|
||||||
|
STD_VECTOR_REFLECTOR(std::vector< osg::NodePath >);
|
||||||
|
|
||||||
STD_VECTOR_REFLECTOR(std::vector< std::string >);
|
STD_VECTOR_REFLECTOR(std::vector< std::string >);
|
||||||
|
|
||||||
|
@ -337,6 +337,8 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::DataSet::Source)
|
|||||||
I_Method0(const std::string &, getFileName);
|
I_Method0(const std::string &, getFileName);
|
||||||
I_Method1(void, setTemporaryFile, IN, bool, temporaryFile);
|
I_Method1(void, setTemporaryFile, IN, bool, temporaryFile);
|
||||||
I_Method0(bool, getTemporaryFile);
|
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_Method1(void, setCoordinateSystemPolicy, IN, osgTerrain::DataSet::Source::ParameterPolicy, policy);
|
||||||
I_Method0(osgTerrain::DataSet::Source::ParameterPolicy, getCoordinateSystemPolicy);
|
I_Method0(osgTerrain::DataSet::Source::ParameterPolicy, getCoordinateSystemPolicy);
|
||||||
I_Method1(void, setCoordinateSystem, IN, const std::string &, wellKnownText);
|
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(osg::CoordinateSystemNode *, CoordinateSystem);
|
||||||
I_Property(osgTerrain::DataSet::Source::ParameterPolicy, CoordinateSystemPolicy);
|
I_Property(osgTerrain::DataSet::Source::ParameterPolicy, CoordinateSystemPolicy);
|
||||||
I_Property(const std::string &, FileName);
|
I_Property(const std::string &, FileName);
|
||||||
|
I_Property(GDALDataset *, GdalDataSet);
|
||||||
I_Property(osg::Matrixd &, GeoTransform);
|
I_Property(osg::Matrixd &, GeoTransform);
|
||||||
I_Property(osgTerrain::DataSet::Source::ParameterPolicy, GeoTransformPolicy);
|
I_Property(osgTerrain::DataSet::Source::ParameterPolicy, GeoTransformPolicy);
|
||||||
I_Property(unsigned int, Layer);
|
I_Property(unsigned int, Layer);
|
||||||
|
Loading…
Reference in New Issue
Block a user