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
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to