OSG / OSGEarth如何移动相机

时间:2018-06-19 13:19:01

标签: openscenegraph osgearth

我正在用OSGEarth制造一个无人机模拟器。我以前从未使用过OSG,所以在理解相机方面有些麻烦。 我试图在OSG Earth中以特定的滚动,俯仰和偏航将相机移动到特定位置(经/纬度)。

我需要拥有多个摄像机,因此我使用了复合查看器。但是我不知道如何移动特定的相机。 目前,我在EarthManipulator上工作正常。

 class NovaManipulator : publicosgGA::CameraManipulator {
         osg::Matrixd NovaManipulator::getMatrix() const
            {
              //drone_ is only a struct which contains updated infomations
              float roll = drone_->roll(),
              pitch = drone_->pitch(),
              yaw = drone_->yaw();

          auto position = drone_->position();
          osg::Vec3d world_position;
          position.toWorld(world_position);

          cam_view_->setPosition(world_position);

          const osg::Vec3d rollAxis(0.0, 1.0, 0.0);
          const osg::Vec3d pitchAxis(1.0, 0.0, 0.0);
          const osg::Vec3d yawAxis(0.0, 0.0, 1.0);

           //if found this code : 
           // https://stackoverflow.com/questions/32595198/controling-openscenegraph-camera-with-cartesian-coordinates-and-euler-angles
           osg::Quat rotationQuat;
           rotationQuat.makeRotate(
               osg::DegreesToRadians(pitch + 90), pitchAxis,
               osg::DegreesToRadians(roll),          rollAxis,
               osg::DegreesToRadians(yaw),          yawAxis);

          cam_view_->setAttitude(rotationQuat);

          // I don't really understand this also
          auto nodePathList = cam_view_->getParentalNodePaths();
          return osg::computeLocalToWorld(nodePathList[0]);
        }

        osg::Matrixd NovaManipulator::getInverseMatrix() const
        {
          //Don't know why need to be inverted
          return osg::Matrix::inverse(getMatrix());
        } 
    };

然后将操纵器安装到查看器。当我模拟世界时,相机处于良好的位置(纬度/经度/高度)。 但是方向完全错误,无法找到需要“校正”轴的位置。

实际上,我的无人机在法国,但是“上升”方向不好,相对于地面,它仍然朝北而不是“垂直”。 See what I'm getting on the right camera

我需要相对于北方(0 ==>北方)偏航,并且当我的侧倾和俯仰设置为零时,我需要与地面“平行”。

我的方法(通过操纵器)是最好的方法吗? 我可以将相机对象放在Graph节点内(在osgEarth::GeoTransform之后(适用于我的模型))吗?

谢谢:)

2 个答案:

答案 0 :(得分:0)

可能只是旋转顺序-矩阵和四元数乘法与顺序有关。我建议:

  1. 尝试在MakeRotate调用中交换俯仰和滚动顺序。
  2. 如果这不起作用,请一次将除1旋转外的所有旋转都设置为0°,并确保每个旋转都符合您的期望,然后您就可以使用这些订单(只有6个可能的订单)。
  3. 您还可以制作单个四元数q1,q2,q3,其中每个四元数分别表示h,p和r,并自己乘以控制顺序。这就是您正在使用的MakeRotate的超负荷功能。

通常,您想先进行偏航,然后进行俯仰,然后进行侧倾(或者,如果愿意,可以完全跳过侧倾),但是我不记得osg :: quat是在预混胎中还是在串联中后消融时尚,所以可能是撬订单。

答案 1 :(得分:0)

过去,我做过一个可爱的技巧,涉及使用ObjectLocator对象(以获取世界位置和平面切线到表面方向),并结合使用矩阵来应用HPR。里面有一个倒置器,可以将其转换为相机方向矩阵,而不是对象放置矩阵,但是效果很好。

http://forum.osgearth.org/void-ObjectLocator-setOrientation-default-orientation-td7496768.html#a7496844

由于许多变量的类型都不明显,因此查看代码片段中的内容有些棘手。

AlphaPixel进行了大量遥测/ osgEarth类型的工作,因此如果需要帮助,请大喊大叫。