2-osg Camera HUD 绘制右下角坐标系
实现功能
- 在视图右下角显示一个坐标系;
- 并且总是显示在最前面;
- 坐标系与世界坐标系姿态保持一致,但是不随之平移
实现思路
单个视图实现思路:
- 创建 RGB 三色坐标系,用于显示的数据;
- 创建 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);
- 在每一帧更新前,需要重新设置 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);
}
- 将HUD camera 添加到视图的场景的根节点下;
多视图(osgViewer::CompositeViewer)实现思路:
- 创建osgViewer::Viewer *_HUDViewer,用于显示HUDAxis
- 创建 RGB 三色坐标系,用于显示的数据;
- 与单视图一致;创建 HUD Axis Camera;
4.与单视图一致; 在每一帧更新前,需要重新设置 HUD camera 的正交投影矩阵,且更新HUD 坐标轴位置
5.将HUD Axis Camera设置为 osgViewer::Viewer *_HUDViewer的主相机。