OpenSceneGraph将相机设置在初始位置 [英] OpenSceneGraph set the camera at an initial position

查看:1379
本文介绍了OpenSceneGraph将相机设置在初始位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次在OpenSceneGraph工作,我有点失落的原因文档真的不是那么清楚...

I am working on OpenSceneGraph for the first time and I'm a bit lost cause the documentation is really not that clear...

所以,我有这个代码,加载一个obj文件与它的房子,我已经淹没了一个小盒子,我想要的人。所以现在,不是有那个盒子,我想有相机在那里,看着前面,后来我会一些东西来移动固定相机周围的地形,使它看起来像相机移动,但地形正在移动。

So, I have this code that load a obj file with a house on it, and I have drown a little box where I want the "person" to be. So now, instead of having that box there, I would like to have the camera there, looking at the front and later on I'll to something to move the terrain around the fixed camera so that it looks like the camera is moving but the terrain is moving.

所以,这里是我的代码:

So, here is my code:

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;
}

所以这段代码工作,它正确加载字段,我想和我可以用鼠标导航。

So this code works, it loads the the fiel correctly, puts the box where I want and I can navigate with the mouse.

现在,我真的找不到任何东西,把相机放在盒子。我只是不能。

Now, I just really cannot find anything to place the camera where the box is. I just can't.

任何人都可以给我一个如何做的提示?它不应该很难,但我找不到任何好的教程和文档的Viewer和Camera类是真的不是很有帮助。

Can anyone give me a hint of how to do it? It shouldn't be very hard, but I cannot find any good tutorial and the documentation the Viewer and Camera classes is really not very helpful.

推荐答案

几个注释:


  • 尝试并提供OSG附带的模型示例

  • 加入构建代码所需的所有标头,这将使ppl的用户更快地尝试帮助您:)

  • 您的代码是整洁干净的,这是一件好事!

现在,与OSG相关:


  • OSG使用它自己的智能指针实现,它是 osg :: ref_ptr 。这必须在每次创建一个新的OSG对象,继承自 osg :: Referenced ,其中几乎包括所有的东西。你在创建你的 root 节点时使用它一次,这是好的,但是因为你创建的所有其他OSG对象的析构函数是私有的,他们会创建内存泄漏。当然,这不是这个小程序的大事,但它应该是一个好习惯,立即采取。 (我认为有一个快速入门指南的免费的pdf格式,由Paul Martz,它可能会帮助你这样。)

  • osgViewer :: Viewer 带有'默认'相机,你可以得到它与 .getCamera()。对于你目前需要的,你必须设置视图矩阵作为( .setViewMatrixAsLookAt())。它需要三个向量:eye,center和up,用于定位和定向相机。

  • 在OSG中,我从未听说过将相机保持在固定位置并移动世界的做法。你会想移动相机,并保持世界在一个固定的位置,以避免任何大脑损伤。

  • 我不熟悉它(我没有用它个人),但我认为有一个基类 osgGA :: CameraManipulator
  • 注意: osg :: Camera 是一个 osg :: Transform 这是一个 osg :: Group ,这意味着你可以把一个Camera图表,只显示下面的内容。这是一个更先进的,但仍然。

  • OSG uses it's own implementation of smart pointers, which is osg::ref_ptr. This has to be used every time you create a new OSG object which inherits from osg::Referenced, which include nearly everything. You used it once when creating your root node, which is fine, but since all the other OSG objects you created have their destructor private, they'll create memory leaks. Of course, it's not that a big deal for this small program, but it should be a good habit to take right away. (I think there is a Quick Start Guide somewhere free in pdf format, by Paul Martz, it might help you with this.)
  • osgViewer::Viewer comes with the 'default' camera, you can get it with .getCamera(). For what you currently need, you have to set the view matrix as a look at (.setViewMatrixAsLookAt()). It takes three vectors: eye, centre and up, which are used to position and orient the camera.
  • In OSG, I have never heard the practice of keeping the camera at a fixed position and moving the world instead. You'll want to move the camera and keep the world in a fixed position to avoid any brain damage.
  • I'm not familiar with it (I haven't used it personally), but I think there is a base class named osgGA::CameraManipulator which could be used for common camera operations.
  • Good to know: osg::Camera is a osg::Transform which is a osg::Group, which means that you'll be able to put a Camera in a scene graph and only display what's underneath. Well this is a bit more advanced, but still.

以下是您的代码的副本,注释掉了框,模型已更改, osg: :ref_ptr 。由于您手动定位相机,您不再需要轨迹球操纵器。

Here is a copy of your code, with the box commented out, the model changed and the osg::ref_ptr added. Since you position the camera manually, you no longer need the trackball manipulator.

#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;
}

玩得开心!

这篇关于OpenSceneGraph将相机设置在初始位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆