| Version 5 (modified by osg, 6 years ago) |
|---|
Loading Models from Files and Positioning Them in a Scene
TracNav
- About
- Screenshots
- News
- Developer Blog
- Mailing Lists
- Forum
Documentation
- Getting Started
- Platform Specifics
- Tutorials
- Examples
- User Guides
- Programming Guides
- Reference Guides
- LatestDevelopments
- Porting
- CMake
- CDash
- CPack
- FAQ
- Tips And Tricks
- Maths
- Knowledge Base
- Trac Usage Examples
- TracGuide Documentation
- Software Patents
- Software Patents Europe
- Downloads
- Community
- Links
(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 <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
