![]() |
VR-Vantage 2.3 API Documentation
|
This example shows how to create an OpenSceneGraph application. The example loads a geometry file in OpenFlight format, locates two degree-of-freedom nodes within the geometry, then applies an update-callback to each node. As the scene is rendered, the update-callbacks articulate the geometry at those nodes. Of particular interest in this example is how to load a geometry file from disk, how the nodes are found within the model after it has been loaded, and how the update-callbacks animate the geometry.
Above the OpenGL layer is OpenSceneGraph, an API that provides scene organization functions as well as data management, LOD management, file loaders and other much more. With OSG we organize 3D geometry into a "scene graph", and provides functions for traversing the graph and making the appropriate calls to OpenGL to render the scene.
Generally loading a file from disk involves a single call to the osgDB library with the name of the file. If successful the call will return a pointer to the root node of the geometry. If unsuccessful, a NULL pointer is returned. The user should validate the pointer before proceeding.
The desired degree-of-freedom nodes are found using the visitor pattern. When loaded, the geometry is a hierarchy of nodes connected in parent-child fashion. A visitor (in this case an osg::NodeVisitor) is an object that traverses the hierarchy from the point that it is applied to the graph. As it traverses each node in the hierarchy, it calls a known function to 'visit' the node. The node being visited is always passed into the function, and what the function does is user defined. For instance, one of the standard visitors in OpenSceneGraph performs updates on the graph prior to rendering each frame. The osgUtil::UpdateVisitor performs several tasks, one of which checks each node being visited for an osg::NodeCallback functor object. If the node being visited has a pointer to a functor, the visitor will call the function before visiting the next node.
In this tutorial, the application creates a custom visitor to traverse the scene-graph looking for nodes of the type osgSim::DOFTransform. For each osgSim::DOFTransform found, the visitor saves a pointer to the node in a list for later processing. After the visitor is finished, it contains a list of all osgSim::DOFTransform nodes in the model. The application will select two of those osgSim::DOFTransform nodes by name as the 'articulation' nodes and insert a custom osg::NodeCallback to each.
To create a custom visitor, derive a new class from osg::NodeVisitor and over-write the apply() function. The apply() function is the known function that 'visits' each node.
In this application it simply saves a pointer to the node in a list if that node is of type osgSim::DOFTransform.
It is important in the apply() function to always call the base class traverse() function, as this kicks the visitor to the next node in the hierarchy.
To use the visitor, simply create one and select a node in the hierarchy to accept the visitor and start its traversal through the graph.
The last interesting point to this tutorial is how the articulation nodes are actually... well... articulated. This application defines two custom osg::NodeCallback objects, each one specific to the node to which it is applied. These osg::NodeCallback objects cause their nodes to perform transformations on the children of the node.
The steps that update each transform node is as follows: The update osg::NodeVisitor visits the osgSim::DOFTransform node, the visitor checks if the node has an osg::NodeCallback, if so the visitor calls the callback. When the callback is called it checks if the node is a osgSim::DOFTransform, if so the callback calls rotation functions on the node. When all is finished the visitor moves on to visit another node. It is important to note that nodes have several different types of callbacks and this application is only using one, the update callback.
To create a custom callback, derive a new class from osg::NodeCallback and over-write the base class functor operator(). This is the function that is called every rendering frame.
This application has two callbacks, one that rotates an osgSim::DOFTransform in a circle, the other pitches an osgSim::DOFTransform up and down over time.
It is possible to nest osg::NodeCallbacks so that multiple callbacks exist on a single node. Therefore the function should always call the base class traverse() function to kick the visitor to the next nested callback.
To use the callback, simply create one and insert it into the node to be updated.
VR-Vantage includes pre-built versions of the example application. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.
This example is an application. You can run it by running ./bin/exampleOsgArticulation.exe (on Windows) or ./bin/exampleOsgArticulation (on Linux). For more information about running examples, please see Running Applications and Examples.