I am working on OpenSceneGraph for the first time and I'm a bit lost cause the documentation is really not that clear...
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.
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.
A couple of notes:
Now, related to OSG:
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. osgGA::CameraManipulator
which could be used for common camera operations.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. 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;
}
Have fun!