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:
parent
8f2ffb7c2d
commit
1dcf4fe81f
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user