Replying to myself, but I found the solution if anybody else might run
into this. Calling getRotate() on the matrix can give unexpected
results if there was also a scale transform involved. The correct way
is to call Matrix.decompose(..) to get to the contributing parts:
ManipMatrix.preMult(osg::Matrix::translate( -pElem->getPivotPoint() )*
osg::Matrix::scale( pElem->getScale() )*
osg::Matrix::rotate( pElem->getAttitude() )*
osg::Matrix::translate( pElem->getPosition() ) );
osg::Vec3 s,t;
osg::Quat r,so;
ManipMatrix.decompose( t, r, s, so );
pElemCache->setPosition( t );
pElemCache->setAttitude( r );
pElemCache->setScale( s );
Cheers,
Morne
On Fri, Dec 5, 2008 at 1:08 PM, Morné Pistorius
<[EMAIL PROTECTED]> wrote:
> Hi all,
>
> I am hitting my head against a brick wall with this one. I am trying
> to use osgManipulators to edit nodes in my scene. I attach a node to
> a manipulator, rotate it, and then detach the node from the
> manipulator and apply the manipulator's MatrixTransform to the node's
> PositionAttitudeTransform (all nodes that I manipulate have a PAT as
> root) so that the PAT affects its children in the same way that the
> osgManipulator affected its children. Here is the code snippet:
>
>
> NodeUpdateCallback that updates node with osgManipulator's MatrixTransform:
>
> virtual void operator() ( osg::Node* node, osg::NodeVisitor* nv )
> {
> osgManipulator::Selection * pSelection = dynamic_cast<
> osgManipulator::Selection * > ( node );
> if ( pSelection && m_Manip->m_PrevMatrix !=
> m_Manip->m_Dragger->getMatrix() )
> {
> // Apply the transform
> for ( int i = 0; i < m_Manip->m_SelectionCache->getNumChildren(); ++i )
> {
> osg::PositionAttitudeTransform * pElem = dynamic_cast<
> osg::PositionAttitudeTransform * > ( pSelection ->getChild(i) );
> VOSGSceneElement * pElemCache = dynamic_cast< VOSGSceneElement
> * > ( m_Manip->m_SelectionCache->getChild(i) );
>
> osg::Matrix ManipMatrix = pSelection->getMatrix();
>
> ManipMatrix.preMult(osg::Matrix::translate( -pElem->getPivotPoint() )*
> osg::Matrix::scale( pElem->getScale() )*
> osg::Matrix::rotate( pElem->getAttitude() )*
> osg::Matrix::translate( pElem->getPosition() ) );
>
>
> pElemCache->setPosition( ManipMatrix.getTrans() );
> pElemCache->setAttitude( ManipMatrix.getRotate() );
> pElemCache->setScale( ManipMatrix.getScale() );
> }
>
> m_Manip->m_PrevMatrix = m_Manip->m_Dragger->getMatrix();
> }
> }
>
> In this example a VOSGSceneElement is the node that I'm trying to
> manipulate and is derived from PositionAttitudeTransform. pSelection
> contains a copy of this. The copy in pSelection is transformed
> correctly by the manipulator. In this update callback, I'm trying to
> apply the same transform from pSelection to the VOSGSceneElement in
> the scene graph.
>
> Unfortunately this doesn't work properly, and I'm having difficulty
> figuring out how to apply the correct transformation. I would be very
> grateful if anybody can point me in the right direction..How do I
> apply a MatrixTransform to a PositionAttitudeTransform?
>
> As always, thank you!
> Morne
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org