如何将osg::Node转换为osg:矩阵变换



我正在尝试动态移动加载的对象,但要做到这一点,我需要获得该特定对象的4x4矩阵。

在下面的代码中,我将粪坑和奶牛模型加载到场景中,并且只想旋转奶牛模型。

我正在根据Openscenegraph 3.0初学者指南第234页中的"驾驶塞斯纳"示例尝试此练习。

注意:-这里已经生成了树。在没有更改树的情况下,用户需要使用导航键旋转所选对象。用户将使用鼠标选择所需的对象

#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();
}

您可以使用新的MatrixTransform来实现这一点。不要将奶牛和粪尿都插入同一个MatrixTransform中,而是使用两个:

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() );

然后你可以把你想要的MatrixTransform传给Controller,让另一个模型"固定":

osg::ref_ptr<ModelController> ctrler =new ModelController(mt2);

最新更新