1

I am trying to move a loaded object dynamically, but to do so I need to get the 4x4 matrix for that specific object.

In the code below I loaded the cessna and cow models into the scene and I want to rotate only the cow model.

I am trying this exercise based on "driving the Cessna" example from Openscenegraph 3.0 Beginner's Guide page 234.

NOTE:-Here Tree Is already Generated.With out changing tree user need to rotate selected object by using navigation keys. User will select the required object by using mouse

#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgGA/GUIEventHandler>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/io_utils>

osg::ref_ptr<osg::Group> root = new osg::Group;
class ModelController : public osgGA::GUIEventHandler
{
public:
  ModelController( osg::MatrixTransform* node )
    : _model(node)
  {}

  virtual bool handle( const osgGA::GUIEventAdapter& ea,
    osgGA::GUIActionAdapter& aa );
protected:
  osg::ref_ptr<osg::MatrixTransform> _model;
};

bool ModelController::handle( const osgGA::GUIEventAdapter& ea,
  osgGA::GUIActionAdapter& aa )
{
  if ( !_model ) 
  {
    std::cout<<"Not MODEL"<<std::endl;
    return false;
  }
  osg::Matrix matrix = _model->getMatrix();
  std::cout<<"MATRIX+"<<_model->getMatrix()<<std::endl;
  switch ( ea.getEventType() )
  {
    case osgGA::GUIEventAdapter::KEYDOWN:
      switch ( ea.getKey() )
      {
        case 'a': case 'A':
          matrix *= osg::Matrix::rotate(-0.1f, osg::Z_AXIS);
          break;
        case 'd': case 'D':
          matrix *= osg::Matrix::rotate(0.1f, osg::Z_AXIS);
          break;
        case 'w': case 'W':
          matrix *= osg::Matrix::rotate(-0.1f, osg::X_AXIS);
          break;
        case 's': case 'S':
          matrix *= osg::Matrix::rotate(0.1f, osg::X_AXIS);
          break;
        default:
          break;
      }
      _model->setMatrix( matrix );
      break;
    default:
      break;
  }
  return false;
}

int main(int argc,char *argv[])
{
    osg::ref_ptr<osg::Node> model = osgDB::readNodeFile( "cessna.osg");
    osg::ref_ptr<osg::Node> model1 = osgDB::readNodeFile( "cow.osg");

    osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
    mt->addChild( model.get() );
    mt->addChild(model1.get());

    root->addChild( mt.get() );

    osg::MatrixTransform *mt1 = dynamic_cast <osg::MatrixTransform*> (model1.get());
    osg::ref_ptr<ModelController> ctrler =new ModelController(mt1);

    osgViewer::Viewer viewer;
    viewer.addEventHandler( ctrler.get() );
    viewer.getCamera()->setViewMatrixAsLookAt(
    osg::Vec3(0.0f,-100.0f,0.0f), osg::Vec3(), osg::Z_AXIS );
    viewer.setSceneData( root.get() );
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);
    return viewer.run();
}
  • And what's the problem? Do you get the matrix but it doesn't rotate or not even the matrix? Also, if you could indent the code, it would help. – Adri C.S. Mar 18 '15 at 11:40
  • am not able to get the matrix it is throwing NULL for mt1 in osg::MatrixTransform *mt1 = dynamic_cast (model1.get()); –  Mar 19 '15 at 04:16

1 Answers1

2

You can achieve this with a new MatrixTransform. Instead of inserting both the cow and the cessna in the same MatrixTransform, use two:

osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
mt->addChild( model.get() );
osg::ref_ptr<osg::MatrixTransform> mt2 = new osg::MatrixTransform;
mt2->addChild(model1.get());
root->addChild( mt.get() );
root->addChild( mt2.get() );

Then you can pass the MatrixTransform you want to the Controller, leaving the other model "fixed":

osg::ref_ptr<ModelController> ctrler =new ModelController(mt2);
Adri C.S.
  • 2,909
  • 5
  • 36
  • 63
  • Thanks For the reply,here my tree is already build-ed, i need to rotate the object based on user requirement,user may want only cow or only cessna or both.I need how to rotate specific model after tree is generated.. –  Mar 21 '15 at 15:06
  • I see. Update your question with that info, it's an important distinction. – Adri C.S. Mar 21 '15 at 15:20
  • Also, how will the user decide which model to move? By clicking on it? – Adri C.S. Mar 21 '15 at 19:10
  • @LearNer Hey, I forgot to tag you in my comments! Sorry! – Adri C.S. Mar 25 '15 at 15:31
  • Based on clicking and selecting geometries by mouse @Adri C.S –  Apr 01 '15 at 13:51
  • @LearNer Ok. I think there might be a solution that way. I'll try it these days (holidays in Spain) and see if there's something worth of doing :) – Adri C.S. Apr 01 '15 at 14:12