gpt4 book ai didi

c++ - OpenSceneGraph 将相机设置在初始位置

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:29:20 25 4
gpt4 key购买 nike

我是第一次使用 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 类的文档真的不是很有帮助。

最佳答案

一些注意事项:

  • 尝试给出一个OSG自带的模型例子
  • 加入构建代码所需的所有 header ,这将使试图帮助您的人更快 :)
  • 您的代码整洁干净,这是一件好事!

现在,与 OSG 相关:

  • OSG 使用它自己的智能指针实现,即osg::ref_ptr。每次创建一个继承自 osg::Referenced 的新 OSG 对象时都必须使用它,它几乎包括所有内容。您在创建 root 节点时使用了一次,这很好,但是由于您创建的所有其他 OSG 对象的析构函数都是私有(private)的,因此它们会造成内存泄漏。当然,对于这个小程序来说,这没什么大不了的,但立即养成应该是一个好习惯。 (我认为 Paul Martz 在某处免费提供了 pdf 格式的快速入门指南,它可能会对您有所帮助。)
  • osgViewer::Viewer 带有“默认”摄像头,您可以使用 .getCamera() 获取它。对于您当前需要的,您必须将 View 矩阵设置为查看 (.setViewMatrixAsLookAt())。它需要三个 vector :eye、center 和 up,用于定位和定向相机。
  • 在 OSG 中,我从未听说过将相机保持在固定位置并移动世界的做法。你会想要移动相机并将世界保持在固定位置以避免任何大脑损伤。
  • 我不熟悉它(我没有亲自使用过它),但我认为有一个名为 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;
}

玩得开心!

关于c++ - OpenSceneGraph 将相机设置在初始位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21180092/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com