【问题标题】:OpenSceneGraph set the camera at an initial positionOpenSceneGraph 将相机设置在初始位置
【发布时间】:2014-02-06 10:34:37
【问题描述】:

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

【问题讨论】:

    标签: c++ opengl camera openscenegraph


    【解决方案1】:

    几点说明:

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

    现在,与 OSG 相关:

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

    玩得开心!

    【讨论】:

    • 如果答案需要改进,反对者应该添加评论:)
    • 非常好的答案。完整并附有有用的解释。
    • 我应该如何在游戏循环中设置相机位置?
    • @mkuse 我不明白你的问题。 viewer.getCamera()-&gt;setViewMatrixAsLookAt( eye, center, up );,不是吗?
    猜你喜欢
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 2020-11-24
    • 1970-01-01
    • 2021-09-20
    相关资源
    最近更新 更多