Version 2 (modified by osg, 7 years ago)

Added link to next tutorial

Loading Models from Files and Positioning Them in a Scene

(Wiki editing note: Code needs conversion to osgViewer)
(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_DATA_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 <osgProducer/Viewer>

// Declare a 'viewer'


osgProducer::Viewer viewer;

// For now, we can initialize with 'standard settings'
// Standard settings include a standard keyboard mouse
// interface as well as default drive, fly and trackball
// motion models for updating the scene.

viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);

// Next we will need to assign the scene graph we created 
// above to this viewer:

viewer.setSceneData( root );

// 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() )
{
   // wait for all cull and draw threads to complete.
   viewer.sync();

   // Initiate scene graph traversal to update nodes.
   // Animation nodes will require update. Additionally,
   // any node for which an 'update' callback has been
   // set up will also be updated. More information on 
   // settting up callbacks to follow.
       
   viewer.update();
   // initiate the cull and draw traversals of the scene.

   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?