Version 6 (modified by osg, 7 years ago)

Changed OSG_DATA_PATH environment variable to OSG_FILE_PATH

Loading Models from Files and Positioning Them in a Scene

(Wiki editing note: Add link to complete source code at bottom)

Goals

Load geometric models and add them to a scene, adjust the position of one of the models within the scene and view the scene by setting up a simulation loop.

Loading geometric models and adding them to a scene

If you have loaded the current version of Open Scene Graph, you will be able to load any file format for which there is a plugin. This includes the following geometric file formats: 3dc, 3ds, flt, geo, iv, ive, lwo, md2, obj, osg. And the following image file formats: bmp, gif, jpeg, rgb, tga, tif.

Open scene graph installation includes a number of open scene graph format (.osg) geometric models. We'll load one of these as well as a MPI Open Flight (.flt) file. To make it easy to find the model, create a 'models' folder under the path pointed to by your OSG_FILE_PATH system environment variable. (Normally C:\Projects\OpenSceneGraph\OpenSceneGraph-Data\) . Unzip this file into that folder.
Geometric models are represented as nodes of the scene graph. Thus, to load and manipulate a geometric file we will need to declare handles (or pointers) to an osg::Node type instance (after some required #includes.)

#include <osg/Node>
#include <osgDB/ReadFile> 

...
osg::Node* cessnaNode = NULL;
osg::Node* tankNode = NULL;
...

cessnaNode = osgDB::readNodeFile("cessna.osg");
tankNode = osgDB::readNodeFile("Models/T72-tank/t72-tank_des.flt");

That's everything required to load a database. Next we'll add it as part of a scene graph. Load the model as a child of a transform node so we can reposition the model.

// Declare a node which will serve as the root node
// for the scene graph. Since we will be adding nodes
// as 'children' of this node we need to make it a 'group'
// instance.
// The 'node' class represents the most generic version of nodes.
// This includes nodes that do not have children (leaf nodes.)
// The 'group' class is a specialized version of the node class. 
// It adds functions associated with adding and manipulating
// children.

osg::Group* root = new osg::Group();
root->addChild(cessnaNode); 

// Declare transform, initialize with defaults.

osg::PositionAttitudeTransform* tankXform =
   new osg::PositionAttitudeTransform();

// Use the 'addChild' method of the osg::Group class to
// add the transform as a child of the root node and the
// tank node as a child of the transform.

root->addChild(tankXform);

tankXform->addChild(tankNode);

// Declare and initialize a Vec3 instance to change the
// position of the tank model in the scene
osg::Vec3 tankPosit(5,0,0);
tankXform->setPosition( tankPosit ); 

So now we have a scene graph made up of a root node with two children, one is a geometric model of a cessna. The other child is a sub-tree consisting of a transform node with a geometric model of a tank as its only child. To view the scene, we will need to set up a viewer and a simulation loop. Here's how:

#include <osgViewer/Viewer>

// Declare a 'viewer'
osgViewer::Viewer viewer;

// Next we will need to assign the scene graph we created 
// above to this viewer:
viewer.setSceneData( root );

// attach a trackball manipulator to all user control of the view
viewer.addCameraManipulator(new osgGA::TrackballManipulator);

// create the windows and start the required threads.
viewer.realize();

// Enter the simulation loop. viewer.done() returns false
// until the user presses the 'esc' key. 
// (This can be changed by adding your own keyboard/mouse
// event handler or by changing the settings of the default 
// keyboard/mouse event handler)

while( !viewer.done() )
{
   // dispatch the new frame, this wraps up the follow Viewer operations:
   //   advance() to the new frame
   //   eventTraversal() that collects events and passes them on to the event handlers and event callbacks
   //   updateTraversal() to calls the update callbacks
   //   renderingTraversals() that runs syncronizes all the rendering threads (if any) and dispatch cull, draw and swap buffers
   viewer.frame();
}

You should be able to compile and execute the code above (making sure the calls are made in the right order, you've added a 'main', etc.) When you execute the code, pressing the 'h' key will toggle a menu of options. Pressing the 'esc' will exit.

Continue with tutorial HUDs and Text