第32节 左下角实时显示当前视口朝哪

功能说明

  • 左下角有个小窗口,显示一个坐标轴,当主视口发生变化时,坐标轴会根据主视口的变化转动,以实时反映当前主视口朝哪
  • 小窗口不响应鼠标事件
  • 小窗口背景全透明,只有个轴

在这里插入图片描述

本节的内容在网盘中:

【击此打开网盘资源链接】

关键点

  • 首先左下角不需要响应事件,我们直接用一个camera即可,其主要设置如下:
  • 设置窗口在左下角
 camera->setViewport(new osg::Viewport(0, 0, 200, 200)); 
  • 设置不接受事件
  camera->setAllowEventFocus(false);
  • 设置背景透明,也即不清楚颜色缓存
 camera->setClearMask(GL_DEPTH_BUFFER_BIT);
  • 设置最后渲染,以免被其它相机盖住
camera->setRenderOrder(osg::Camera::POST_RENDER);
  • 设置观察矩阵是单位矩阵,单位矩阵位置在eye=(0,0,0),朝向如下图【理解这个是关键】:
camera->setViewMatrix(osg::Matrix::identity());

在这里插入图片描述

  • 因为轴的位置也在0,0,0,所以势必要在其上加一个矩阵用来对其进行旋转(和主视口的旋转关联起来)和平移操作(主要是为了看清)
    osg::MatrixTransform* mt = new osg::MatrixTransform;
    mt->setUpdateCallback(new UpdateCallback());
    mt->addChild(aix);

接下来

下面就是对坐标阵前面的mt设置一个更新操作,每一帧都实时的获取当前视口的viewMatrix,获取其旋转的量,将其赋给坐标轴前的mt,然后再给旋转后的轴向z轴负方向移上5,这样在视口里看着合适。

全部代码

#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/PrimitiveSet>
#include <osgGA/CameraManipulator>
#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>
#include <osg/MatrixTransform>


osg::Node* aix = osgDB::readNodeFile("axes.osgt");
osg::Node* glider = osgDB::readNodeFile("glider.osg");
osg::Camera* camera = new osg::Camera;

osgViewer::Viewer viewer;

class UpdateCallback : public osg::NodeCallback
{
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(node);

        //主相机当前的观察矩阵
        osg::Matrix viewerViewMatrix = viewer.getCamera()->getViewMatrix();

        //camera自己有矩阵,改变了轴的朝向,此处要先进行还原
        mt->setMatrix(osg::Matrix::rotate(viewerViewMatrix.getRotate()) *osg::Matrix::translate(osg::Vec3(0, 0, -5.0)));
        
    }
};


//创建左下角的坐标轴指示图
osg::Node* createCorner()
{
	osg::Group* root = new osg::Group;


	root->addChild(camera);

	//只容纳一个坐标轴
	camera->setProjectionMatrixAsPerspective(35.0, 1, 0.01, 1000.0);
    camera->setViewMatrix(osg::Matrix::identity());
	camera->setViewport(new osg::Viewport(0, 0, 200, 200));

	camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	camera->setClearMask(GL_DEPTH_BUFFER_BIT);
	camera->setRenderOrder(osg::Camera::POST_RENDER);
	camera->setAllowEventFocus(false);
    osg::MatrixTransform* mt = new osg::MatrixTransform;
    mt->setUpdateCallback(new UpdateCallback());
    mt->addChild(aix);
	camera->addChild(mt);
    camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);

	return root;
}


osg::Node* buildScene()
{
	osg::Group* root = new osg::Group;

	root->addChild(aix);
	root->addChild(glider);
	root->addChild(createCorner());

	return root;
}

int main()
{
	viewer.setSceneData(buildScene());
	
	return viewer.run();
}

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片