我要发帖 回复

高级会员

109

主题

1589

积分

0

专家分

OSG-VR-GIS

忠于职守杰出贡献

:

私信
发表时间 : 2007-12-9 19:02:44 | 浏览 : 2115    评论 : 0
Navy11.2 - 环绕(始终指向)场景中节点的相机

ARRAY翻译

目标:
创建回调,以实现用于沿轨道环绕,同时指向场景中某个节点的世界坐标矩阵的更新。使用此矩阵的逆矩阵来放置相机。
2.jpg
----------------------------------------------------------------------
本章的回调类基于上一篇的osgFollowMe教程。本章中,我们将添加一个新的矩阵数据成员,以保存视口相机所需的世界坐标。每次更新遍历启动时,我们将调用环绕节点的当前轨道世界坐标矩阵。为了实现环绕节点的效果,我们将添加一个“angle”数据成员,其值每帧都会增加。矩阵的相对坐标基于一个固定数值的位置变换,而旋转量基于每帧更新的角度数据成员。为了实现相机的放置,我们还将添加一个方法,它将返回当前的轨道位置世界坐标。类的声明如下所示:

class orbit : public osg::NodeCallback
{
public:
   orbit(): heading(M_PI/2.0) {}

   osg::Matrix getWCMatrix(){return worldCoordMatrix;}

   virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
   {
      osg::MatrixTransform *tx = dynamic_cast<osg::MatrixTransform *>(node);
      if( tx != NULL )
      {
         heading += M_PI/180.0;
         osg::Matrixd orbitRotation;
         orbitRotation.makeRotate(
            osg::DegreesToRadians(-10.0), osg::Vec3(0,1,0), // 滚转角(Y轴)
            osg::DegreesToRadians(-20.0), osg::Vec3(1,0,0) , // 俯仰角(X轴)
            heading, osg::Vec3(0, 0, 1) ); // 航向角(Z轴)
         osg::Matrixd orbitTranslation;
         orbitTranslation.makeTranslate( 0,-40, 4 );
         tx->setMatrix ( orbitTranslation * orbitRotation);
         worldCoordMatrix = osg::computeLocalToWorld( nv->getNodePath() );
      }
      traverse(node, nv);
   }
private:
   osg::Matrix worldCoordMatrix;
   float heading;
};

使用回调时,我们需要向场景添加一个矩阵变换,并将更新回调设置为“orbit”类的实例。我们使用前述osgManualCamera教程中的代码来实现用矩阵世界坐标来放置相机。我们还将使用前述键盘接口类的代码来添加一个函数来更新全局量,该全局量用于允许用户自行选择缺省和“环绕”的视口。

int main()
{
   osg::Node* groundNode = NULL;
   osg::Node* tankNode = NULL;
   osg::Group* root = NULL;
   osgViewer::Viewer viewer;
   osg::PositionAttitudeTransform* tankXform = NULL;

   groundNode = osgDB::readNodeFile("\\Models\\JoeDirt\\JoeDirt.flt");
   tankNode = osgDB::readNodeFile("\\Models\\T72-Tank\\T72-tank_des.flt");

   root = new osg::Group();

   // 创建天空。
   osg::ClearNode* backdrop = new osg::ClearNode;
   backdrop->setClearColor(osg::Vec4(0.0f,0.8f,0.0f,1.0f));
   root->addChild(backdrop);

   tankXform = new osg::PositionAttitudeTransform();
   root->addChild(groundNode);
   root->addChild(tankXform);
   tankXform->addChild(tankNode);
   tankXform->setPosition( osg::Vec3(10,10,8) );
   tankXform->setAttitude(
      osg::Quat(osg::DegreesToRadians(-45.0), osg::Vec3(0,0,1) ) );

   osgGA::TrackballManipulator *Tman = new osgGA::TrackballManipulator();
   viewer.setCameraManipulator(Tman);

   viewer.setSceneData( root );
   viewer.realize();

   // 创建矩阵变换节点,以实现环绕坦克节点。
   osg::MatrixTransform* orbitTankXForm = new osg::MatrixTransform();
   // 创建环绕轨道回调的实例。
   orbit* tankOrbitCallback = new orbit();
   // 为矩阵变换节点添加更新回调的实例。
   orbitTankXForm->setUpdateCallback( tankOrbitCallback );
   // 将位置轨道关联给坦克的位置,即,将其设置为坦克变换节点的子节点。
   tankXform->addChild(orbitTankXForm);

   keyboardEventHandler* keh = new keyboardEventHandler();
   keh->addFunction('v',toggleTankOrbiterView);
   viewer.addEventHandler(keh);

   while( !viewer.done() )
   {
      if (useTankOrbiterView)
      {
         Tman->setByInverseMatrix(tankOrbitCallback->getWCMatrix()
                           *osg::Matrix::rotate( -3.1415926/2.0, 1, 0, 0 ));
      }

      viewer.frame();
   }
   return 0;
}

提示:按下V键来切换不同的视口。
祝您好运!

最近VR访客


OSG中国官方网站:http://www.osgChina.org
OSG中国官方讨论区:http://bbs.osgChina.org

OSG专业群-OSG地形研究者 49668412
      OSG地形专业研究 45763709

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-4-19 05:20 AM

返回顶部