[osg-users] switching between camera manipulators

Joel Graff pair_o_graffs at comcast.net
Tue Apr 5 20:50:43 PDT 2011


I'm building a little 3D testing environment for shaders and OSG is doing fabulously well in accomplishing this task.  However, I've run into a little problem that may require more advanced grasp of OSG theory than I currently possess.

The app I'm developing uses the console as the input (cuz I hate MFC and don't know QT - yet), and takes commands to create / load 3D objects - i.e. "add box" would add a geode with a Box Drawable attached or "import cessna.osg" would load the cessna.osg model into the scene graph.  All this works well, but there is, of course, the issue of managing the camera manipulator when load / saving / importing files.  That is, when I save the current project (as an *.osgt file), I want the camera position saved, so it's restored when the file is reloaded.  I managed to do that quite nicely by employing the viewer->setCameraManipulator() function's resetPosition flag in conjunction with the setByMatrix() command.

However, the problem which has presented itself is this:

In order to retain the camera position, I create  a new camera manipulator and add it using viewer->setCameraManipulator (cm, false);, then set the matrix from a saved .osgt file which I load.  But if I want the manipulator to reset when I import the cessna.osg file, so that the entire model is rendered properly in the window (especially if the camera view is zoomed in on a unit primitive), then I need to have the default manipulator active, not the user manipulator (so as to take advantage of OSG's automatic computation of the frustum, etc.)

So I was thinking when I import a file, switch to the default manipulator, import the .osg model, then switch back to the user manipulator (which simply assumes the default manipulator's matrix).  The only reason I do this is because I don't think there's a way to disable the automatic reset of the manipulator unless it's added to the camera with the resetPosition flag set to false.  But that requires being able to retain references to both manipulators, whether or not they are active.  However, as I run my console in a separate thread, saving references to  camera manipulators in my console class seems to not work.

Sooo...  I figured I could use the KeySwitchManipulator class, which would likely solve the access problem, but it doesn't support the ability to specify a particular manipulator's resetPosition flag when the manipulators are switched out.

My only other thought would be to create a callback class that I can attach to the viewer's main camera's update traversal, and use that class to retain a reference to the camera's default manipulator / create the user manipulator. Then I need to reference the update callback object from my console class (in a separate thread).  

Finally, in my console class I could have a pointer  called cameraUpdateCallback.  Then, whenever a file is imported, I can use the reference thus:

// set to the manipulator which resets itself
cameraUpdateCallback->setManipulator( eDefaultManipulator );
//import file and let the manipulator do the math
root->addChild( osgDB::readNodeFile( "cessna.osg" ) );

// TODO: wait until the next frame before switching back to the user manipulator?

// switch back to the user manipulator which inherits the default
// manipulator's matrix
cameraUpdateCallback->setMainpulator( eUserManipulator );

The custom setManipulator() function would then manage setting the manipulators and their matrices.

I suspect this would work, but it seems a bit too complex.  Being relatively new to OSG, I assume there's probably something obvious I've overlooked...


Read this topic online here:

More information about the osg-users mailing list