This feature prevents the camera from passing through walls or floors, making viewer manipulation much more comfortable and realistic. To use this class, first create a standard viewer and then an SoXtCollisionViewer,SoWinCollisionViewer, or SoQtCollisionViewer for this viewer. Collision detection will be activated immediately. The minimum distance between the camera and the object can be adjusted. A user callback function can be set to receive notification when a collision is detected. See SoXtCollisionViewer (or the SoQt or SoWin equivalent) for more information.
#include <Inventor/SoXt/viewers/SoWinCollisionViewer.h>
#include <Inventor/Xt/SoXt.h>
#include <Inventor/Xt/viewers/SoXtWalkViewer.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoSeparator.h>
//---------------------------------------------------------------------
// Global objects
SoWinCollisionViewer* collision_viewer;
//---------------------------------------------------------------------
// Function declarations
void onCollision( void*, SoWinCollisionViewer* );
//*********************************************************************
// Main function
int
main( int argc, char** argv )
{
// Window initialization --------------------------------------------
Widget myWindow = SoXt::init( argv[0] );
if ( myWindow == NULL )
exit( 1 );
// Which file to open -----------------------------------------------
char filename[1024];
if ( argc == 1 )
strcpy( filename, "Barcelona.iv" );
else
strcpy( filename, argv[1] );
// Scene graph initialization ---------------------------------------
SoInput my_scene_input;
if ( !my_scene_input.openFile( filename ) )
return;
SoSeparator* root = SoDB::readAll( &my_scene_input );
if ( root == NULL )
return;
my_scene_input.closeFile();
root->ref();
// Set up viewer ----------------------------------------------------
SoXtWalkViewer* my_viewer = new SoXtWalkViewer( myWindow );
my_viewer->setSceneGraph( root );
my_viewer->setTitle( "Collision Walk Viewer" );
my_viewer->show();
// Adding collision prevention --------------------------------------
collision_viewer = new SoWinCollisionViewer( my_viewer );
collision_viewer->addCallback( onCollision, NULL );
// Main loop --------------------------------------------------------
SoXt::show( myWindow );
SoXt::mainLoop();
return 0;
}
//*********************************************************************
// Function called when there is a collision
void
onCollision( void\*, SoWinCollisionViewer\* )
{
#ifdef WIN32
PlaySound( "Collision.wav", NULL, SND_FILENAME + SND_ASYNC );
#else
printf( "%c", 7 );
fflush( stdout );
#endif
}