Added support in osg::computeWorldToLocal and compteLocalToWorld functions for automatically

stripping any absolute or root CameraNode's from the NodePaths.

Added osg::Node::getWorldMatrices() convinience method.
This commit is contained in:
Robert Osfield 2006-02-27 19:48:34 +00:00
parent 8f2ffb7c2d
commit 1dcf4fe81f
4 changed files with 79 additions and 19 deletions

View File

@ -36,6 +36,8 @@ 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.*/ /** 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; typedef std::vector< NodePath > NodePathList;
/** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
typedef std::vector< Matrix > MatrixList;
/** 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
@ -89,6 +91,7 @@ class OSG_EXPORT Node : public Object
/** Convert 'this' into a Transform pointer if Node is a Transform, otherwise return 0. /** Convert 'this' into a Transform pointer if Node is a Transform, otherwise return 0.
* Equivalent to dynamic_cast<Transform*>(this).*/ * Equivalent to dynamic_cast<Transform*>(this).*/
virtual Transform* asTransform() { return 0; } virtual Transform* asTransform() { return 0; }
/** convert 'const this' into a const Transform pointer if Node is a Transform, otherwise return 0. /** convert 'const this' into a const Transform pointer if Node is a Transform, otherwise return 0.
* Equivalent to dynamic_cast<const Transform*>(this).*/ * Equivalent to dynamic_cast<const Transform*>(this).*/
virtual const Transform* asTransform() const { return 0; } virtual const Transform* asTransform() const { return 0; }
@ -129,6 +132,10 @@ class OSG_EXPORT Node : public Object
* The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */ * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */
NodePathList getParentalNodePaths(osg::Node* haltTraversalAtNode=0) const; NodePathList getParentalNodePaths(osg::Node* haltTraversalAtNode=0) const;
/** Get the list of matrices that transform this node from local coordinates to world coordinates.
* The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */
MatrixList getWorldMatrices(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);

View File

@ -28,24 +28,24 @@ namespace osg {
/** Compute the matrix which transforms objects in local coords to world coords, /** Compute the matrix which transforms objects in local coords to world coords,
* by accumulating the Transform local to world matrices along the specified node path. * by accumulating the Transform local to world matrices along the specified node path.
*/ */
extern OSG_EXPORT Matrix computeLocalToWorld(const NodePath& nodePath); extern OSG_EXPORT Matrix computeLocalToWorld(const NodePath& nodePath, bool ignoreCameraNodes = true);
/** Compute the matrix which transforms objects in world coords to local coords, /** Compute the matrix which transforms objects in world coords to local coords,
* by accumulating the Transform world to local matrices along the specified node path. * by accumulating the Transform world to local matrices along the specified node path.
*/ */
extern OSG_EXPORT Matrix computeWorldToLocal(const NodePath& nodePath); extern OSG_EXPORT Matrix computeWorldToLocal(const NodePath& nodePath, bool ignoreCameraNodes = true);
/** Compute the matrix which transforms objects in local coords to eye coords, /** Compute the matrix which transforms objects in local coords to eye coords,
* by accumulating the Transform local to world matrices along the specified node path * by accumulating the Transform local to world matrices along the specified node path
* and multipling by the supplied initial camera modelview. * and multipling by the supplied initial camera modelview.
*/ */
extern OSG_EXPORT Matrix computeLocalToEye(const Matrix& modelview, const NodePath& nodePath); extern OSG_EXPORT Matrix computeLocalToEye(const Matrix& modelview, const NodePath& nodePath, bool ignoreCameraNodes = true);
/** Compute the matrix which transforms objects in eye coords to local coords, /** Compute the matrix which transforms objects in eye coords to local coords,
* by accumulating the Transform world to local matrices along the specified node path * by accumulating the Transform world to local matrices along the specified node path
* and multipling by the inverse of the supplied initialial camera modelview. * and multipling by the inverse of the supplied initialial camera modelview.
*/ */
extern OSG_EXPORT Matrix computeEyeToLocal(const Matrix& modelview, const NodePath& nodePath); extern OSG_EXPORT Matrix computeEyeToLocal(const Matrix& modelview, const NodePath& nodePath, bool ignoreCameraNodes = true);
/** A Transform is a group node for which all children are transformed by /** A Transform is a group node for which all children are transformed by

View File

@ -16,6 +16,7 @@
#include <osg/NodeVisitor> #include <osg/NodeVisitor>
#include <osg/Notify> #include <osg/Notify>
#include <osg/OccluderNode> #include <osg/OccluderNode>
#include <osg/CameraNode>
#include <algorithm> #include <algorithm>
@ -170,6 +171,31 @@ NodePathList Node::getParentalNodePaths(osg::Node* haltTraversalAtNode) const
return cpp._nodePaths; return cpp._nodePaths;
} }
MatrixList Node::getWorldMatrices(osg::Node* haltTraversalAtNode) const
{
CollectParentPaths cpp(haltTraversalAtNode);
const_cast<Node*>(this)->accept(cpp);
MatrixList matrices;
for(NodePathList::iterator itr = cpp._nodePaths.begin();
itr != cpp._nodePaths.end();
++itr)
{
NodePath& nodePath = *itr;
if (nodePath.empty())
{
matrices.push_back(osg::Matrix::identity());
}
else
{
matrices.push_back(osg::computeLocalToWorld(nodePath));
}
}
return matrices;
}
void Node::setUpdateCallback(NodeCallback* nc) void Node::setUpdateCallback(NodeCallback* nc)
{ {
// if no changes just return. // if no changes just return.

View File

@ -11,6 +11,9 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#include <osg/Transform> #include <osg/Transform>
#include <osg/CameraNode>
#include <osg/Notify>
using namespace osg; using namespace osg;
@ -27,11 +30,13 @@ class TransformVisitor : public NodeVisitor
CoordMode _coordMode; CoordMode _coordMode;
Matrix& _matrix; Matrix& _matrix;
bool _ignoreCameraNodes;
TransformVisitor(Matrix& matrix,CoordMode coordMode): TransformVisitor(Matrix& matrix,CoordMode coordMode, bool ignoreCameraNodes):
NodeVisitor(), NodeVisitor(),
_coordMode(coordMode), _coordMode(coordMode),
_matrix(matrix) _matrix(matrix),
_ignoreCameraNodes(ignoreCameraNodes)
{} {}
virtual void apply(Transform& transform) virtual void apply(Transform& transform)
@ -48,46 +53,68 @@ class TransformVisitor : public NodeVisitor
void accumulate(const NodePath& nodePath) void accumulate(const NodePath& nodePath)
{ {
NodePath& non_const_nodePath = const_cast<NodePath&>(nodePath); if (nodePath.empty()) return;
for(NodePath::iterator itr=non_const_nodePath.begin();
itr!=non_const_nodePath.end(); unsigned int i = 0;
++itr) if (_ignoreCameraNodes)
{ {
(*itr)->accept(*this); // we need to found out the last absolute CameraNode in NodePath and
// set the i index to after it so the final accumulation set ignores it.
i = nodePath.size();
NodePath::const_reverse_iterator ritr;
for(ritr = nodePath.rbegin();
ritr != nodePath.rend();
++ritr, --i)
{
const osg::CameraNode* camera = dynamic_cast<const osg::CameraNode*>(*ritr);
if (camera &&
(camera->getReferenceFrame()==osg::Transform::ABSOLUTE_RF || camera->getParents().empty()))
{
break;
}
}
}
// do the accumulation of the active part of nodepath.
for(;
i<nodePath.size();
++i)
{
const_cast<Node*>(nodePath[i])->accept(*this);
} }
} }
}; };
Matrix osg::computeLocalToWorld(const NodePath& nodePath) Matrix osg::computeLocalToWorld(const NodePath& nodePath, bool ignoreCameraNodes)
{ {
Matrix matrix; Matrix matrix;
TransformVisitor tv(matrix,TransformVisitor::LOCAL_TO_WORLD); TransformVisitor tv(matrix,TransformVisitor::LOCAL_TO_WORLD,ignoreCameraNodes);
tv.accumulate(nodePath); tv.accumulate(nodePath);
return matrix; return matrix;
} }
Matrix osg::computeWorldToLocal(const NodePath& nodePath) Matrix osg::computeWorldToLocal(const NodePath& nodePath, bool ignoreCameraNodes)
{ {
osg::Matrix matrix; osg::Matrix matrix;
TransformVisitor tv(matrix,TransformVisitor::WORLD_TO_LOCAL); TransformVisitor tv(matrix,TransformVisitor::WORLD_TO_LOCAL,ignoreCameraNodes);
tv.accumulate(nodePath); tv.accumulate(nodePath);
return matrix; return matrix;
} }
Matrix osg::computeLocalToEye(const Matrix& modelview,const NodePath& nodePath) Matrix osg::computeLocalToEye(const Matrix& modelview,const NodePath& nodePath, bool ignoreCameraNodes)
{ {
Matrix matrix(modelview); Matrix matrix(modelview);
TransformVisitor tv(matrix,TransformVisitor::LOCAL_TO_WORLD); TransformVisitor tv(matrix,TransformVisitor::LOCAL_TO_WORLD,ignoreCameraNodes);
tv.accumulate(nodePath); tv.accumulate(nodePath);
return matrix; return matrix;
} }
Matrix osg::computeEyeToLocal(const Matrix& modelview,const NodePath& nodePath) Matrix osg::computeEyeToLocal(const Matrix& modelview,const NodePath& nodePath, bool ignoreCameraNodes)
{ {
Matrix matrix; Matrix matrix;
matrix.invert(modelview); matrix.invert(modelview);
TransformVisitor tv(matrix,TransformVisitor::WORLD_TO_LOCAL); TransformVisitor tv(matrix,TransformVisitor::WORLD_TO_LOCAL,ignoreCameraNodes);
tv.accumulate(nodePath); tv.accumulate(nodePath);
return matrix; return matrix;
} }