功能说明
- 左下角有个小窗口,显示一个坐标轴,当主视口发生变化时,坐标轴会根据主视口的变化转动,以实时反映当前主视口朝哪
- 小窗口不响应鼠标事件
- 小窗口背景全透明,只有个轴
本节的内容在网盘中:
关键点
- 首先左下角不需要响应事件,我们直接用一个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
暂无评论内容