2-osg Camera HUD 绘制右下角坐标系

2-osg Camera HUD 绘制右下角坐标系

实现功能

  1. 在视图右下角显示一个坐标系;
  2. 并且总是显示在最前面;
  3. 坐标系与世界坐标系姿态保持一致,但是不随之平移

实现思路

单个视图实现思路:

  1. 创建 RGB 三色坐标系,用于显示的数据;
  2. 创建 HUD Axis Camera; 相机属性设置,是实现这个功能的关键;
    osg::ref_ptr<osg::Camera> camera(new osg::Camera());
    //Instead of orthographic projection,
    //orthographic projection will not zoom in and out as the camera         //pulls in and out,
    //thus eliminating the zoom effect 
    camera->setProjectionMatrix(osg::Matrix::ortho(-1,1,-1,1,1,100));

    // draw subgraph after main camera view.
    camera->setRenderOrder(osg::Camera::POST_RENDER);

    // only clear the depth buffer, transparent background
    camera->setClearMask(GL_DEPTH_BUFFER_BIT);

    // we don't want the camera to grab event focus from the viewers         //main camera(s).
    camera->setAllowEventFocus(false);

    // set the view matrix
    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    camera->setViewMatrix(osg::Matrix::identity());
    camera->setCullingMode(camera->getCullingMode() & ~osg::CullSettings::SMALL_FEATURE_CULLING); // need this for allowing small points with zero bunding voluem to be displayed correctly

    camera->addChild( m_rootHUD.get() );
    m_rootHUD->setMatrix(osg::Matrix::identity());
    camera->setGraphicsContext(_graphicsWindow.get());
    // Set the viewport for the Camera
    camera->setViewport(new osg::Viewport(0, 0, this->width(), this->height()));

    //_hudview->setCamera(camera);

    _root->addChild(camera);
  1. 在每一帧更新前,需要重新设置 HUD camera 的正交投影矩阵,且更新HUD 坐标轴位置
        int width = this->rect().right() - this->rect().left();
       int higth = this->rect().bottom() - this->rect().top();
       //reset orthographic project matrix
       _hudAxisCamera->setProjectionMatrix(osg::Matrix::ortho(-width/2, width/2, -higth/2, higth/2, 1, 100.0));

        //only using rotation of camera manipulator 
        osg::Matrix m = _keyswitchManipulator->getInverseMatrix();
        m.setTrans(width/2 - 40, -higth/2 + 40, -50);
        m_osgWorldAxis->setMatrix(m);

注意: osg::Matrix m = _keyswitchManipulator->getInverseMatrix();获取相机操作矩阵,而 View Matrix 是相机坐标系到世界坐标系变换,所以需要 inverse,即将场景所有节点变换到相机坐标系下;

另外:可以重载相机, HUDCamera, 重新实现节点访问器,实现思路与上面讲的一样。只是在HUDCamera节点中调用访问器更新

class HUDCamera :public osg::Camera
{
public:
    /*此处省略无关代码......*/

    inline void setMainCamera(Camera* camera)
    {
        _mainCamera = camera;
    }
    virtual void traverse(osg::NodeVisitor& nv);
protected:
     /*此处省略无关代码......*/
    osg::observer_ptr<Camera> _mainCamera;
};


// camera node visitor, called when frame update
void HUDCamera::traverse(osg::NodeVisitor& nv)
{
    if (_mainCamera.valid())
    {
        _mainCamera->getGraphicsContext();
        osg::GraphicsContext::Traits* traits = gc->getTraits();
        int width = traits->width;
        int height = traits->height;
        //reset orthographic project matrix
        setProjectionMatrix(osg::Matrix::ortho(-width/2, width/2, -height/2, height/2, 1, 100.0));

        osg::Matrix m = _mainCamera->getViewMatrix();
        m.setTrans(width/2 - 40, -higth/2 + 40, -50);
        this->setViewMatrix(m);
    }

    osg::Camera::traverse(nv);
}
  1. 将HUD camera 添加到视图的场景的根节点下;

多视图(osgViewer::CompositeViewer)实现思路:

  1. 创建osgViewer::Viewer *_HUDViewer,用于显示HUDAxis
  2. 创建 RGB 三色坐标系,用于显示的数据;
  3. 与单视图一致;创建 HUD Axis Camera;
    4.与单视图一致; 在每一帧更新前,需要重新设置 HUD camera 的正交投影矩阵,且更新HUD 坐标轴位置
    5.将HUD Axis Camera设置为 osgViewer::Viewer *_HUDViewer的主相机。

实现效果

在这里插入图片描述

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值