我是第一次使用OpenSceneGraph而且我有点迷失,因为文档真的不那么清楚......
所以,我有这个代码加载带有房子的obj文件,我已经淹没了一个小盒子,我想要“人”。所以现在,我不想在那里放置那个盒子,我想把相机放在那里,看着前面,后来我会去固定相机周围的地形,这样看起来就像相机在移动但是地形在移动。
所以,这是我的代码:
int main()
{
osgViewer::Viewer viewer;
viewer.setUpViewInWindow(0,0,800,800);
osg::ref_ptr<osg::Group> root (new osg::Group);
osg::Node* terrain = osgDB::readNodeFile(".terrain.obj");
if(terrain == NULL) {
return -1;
}
Geode* gbox = new Geode();
gbox->addDrawable(new ShapeDrawable(new Box()));
PositionAttitudeTransform* terrainT = new PositionAttitudeTransform();
PositionAttitudeTransform* boxT = new PositionAttitudeTransform();
boxT->setScale(Vec3d(50,50,50));
boxT->setPosition(Vec3d(1000,1000,0));
root->addChild(terrainT);
root->addChild(boxT);
terrainT->addChild(terrain);
boxT->addChild(gbox);
viewer.setSceneData( root.get() );
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
viewer.realize();
while(!viewer.done()) {
viewer.frame();
}
return 0;
}
所以这段代码可以正常运行,它可以正确加载场景,将盒子放在我想要的位置,然后用鼠标导航。
现在,我真的找不到把相机放在盒子里面的东西。我不能。
任何人都可以给我一些如何做的提示吗?它应该不是很难,但是我找不到任何好的教程,而且Viewer和Camera类的文档实际上没什么用处。
答案 0 :(得分:7)
几点说明:
现在,与OSG有关:
osg::ref_ptr
。每次创建一个继承自osg::Referenced
的新OSG对象时都必须使用它,其中包含几乎所有内容。您在创建root
节点时使用过一次,这很好,但由于您创建的所有其他OSG对象的析构函数都是私有的,因此它们会造成内存泄漏。当然,这对于这个小项目来说并不是什么大不了的事,但是立即采取这种习惯应该是个好习惯。 (我认为有一个免费的pdf格式的快速入门指南,作者Paul Martz,它可能对你有帮助。)osgViewer::Viewer
附带“默认”相机,您可以使用.getCamera()
获取。对于您当前需要的内容,您必须将视图矩阵设置为(.setViewMatrixAsLookAt()
)。它需要三个矢量:眼睛,中心和向上,用于定位和定向相机。 osgGA::CameraManipulator
的基类可以用于常见的相机操作。osg::Camera
是osg::Transform
osg::Group
,这意味着您可以将相机放入场景图中,只显示其下方的内容。嗯,这有点先进,但仍然。 以下是您的代码的副本,其中框已注释掉,模型已更改并添加了osg::ref_ptr
。由于您手动定位相机,因此不再需要轨迹球操纵器。
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/PositionAttitudeTransform>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
using namespace osg;
int main()
{
osgViewer::Viewer viewer;
viewer.setUpViewInWindow(50,50,800,800);
osg::ref_ptr<osg::Group> root (new osg::Group);
osg::Node* terrain = osgDB::readNodeFile("C:\\DevTools\\OpenSceneGraph\\examples\\OpenSceneGraph-Data\\cessna.osg");
if(terrain == nullptr) {
return -1;
}
//Geode* gbox = new Geode();
//gbox->addDrawable(new ShapeDrawable(new Box()));
osg::ref_ptr<PositionAttitudeTransform> terrainT = new PositionAttitudeTransform();
//PositionAttitudeTransform* boxT = new PositionAttitudeTransform();
//boxT->setScale(Vec3d(50,50,50));
//boxT->setPosition(Vec3d(1000,1000,0));
root->addChild(terrainT);
//root->addChild(boxT);
terrainT->addChild(terrain);
//boxT->addChild(gbox);
viewer.setSceneData( root.get() );
osg::ref_ptr<osgViewer::WindowSizeHandler> handler = new osgViewer::WindowSizeHandler();
viewer.addEventHandler( handler );
// viewer.setCameraManipulator(new osgGA::TrackballManipulator());
Vec3d eye( 1000.0, 1000.0, 0.0 );
Vec3d center( 0.0, 0.0, 0.0 );
Vec3d up( 0.0, 0.0, 1.0 );
viewer.getCamera()->setViewMatrixAsLookAt( eye, center, up );
viewer.realize();
while(!viewer.done()) {
viewer.frame();
}
return 0;
}
玩得开心!