2003-03-15 04:35:45 +08:00
# ifdef USE_MEM_CHECK
# include <mcheck.h>
# endif
# include <osg/Group>
# include <osg/Notify>
# include <osgDB/Registry>
# include <osgDB/ReadFile>
# include <osgProducer/Viewer>
# include <osg/Quat>
2005-08-30 04:38:46 +08:00
# include <osg/io_utils>
2003-03-15 04:35:45 +08:00
2004-08-04 16:27:43 +08:00
# if defined (WIN32) && !defined(__CYGWIN__)
2003-03-15 04:35:45 +08:00
# include <winsock.h>
# endif
# include "receiver.h"
# include "broadcaster.h"
2005-08-29 20:05:17 +08:00
2005-08-29 22:05:30 +08:00
const unsigned int MAX_NUM_EVENTS = 10 ;
2005-08-30 03:57:02 +08:00
const unsigned int SWAP_BYTES_COMPARE = 0x12345678 ;
2003-03-15 04:35:45 +08:00
class CameraPacket {
public :
2005-08-29 20:05:17 +08:00
2003-03-15 04:35:45 +08:00
CameraPacket ( ) : _masterKilled ( false )
2003-10-10 17:41:04 +08:00
{
2005-08-30 03:57:02 +08:00
_byte_order = SWAP_BYTES_COMPARE ;
2003-10-10 17:41:04 +08:00
}
2003-03-15 04:35:45 +08:00
2003-03-17 05:58:27 +08:00
void setPacket ( const osg : : Matrix & matrix , const osg : : FrameStamp * frameStamp )
2003-03-15 04:35:45 +08:00
{
2003-03-17 05:58:27 +08:00
_matrix = matrix ;
2003-03-15 04:35:45 +08:00
if ( frameStamp )
{
_frameStamp = * frameStamp ;
}
}
2003-03-17 05:58:27 +08:00
void getModelView ( osg : : Matrix & matrix , float angle_offset = 0.0f )
2003-03-15 04:35:45 +08:00
{
2003-10-10 17:41:04 +08:00
matrix = _matrix * osg : : Matrix : : rotate ( osg : : DegreesToRadians ( angle_offset ) , 0.0f , 1.0f , 0.0f ) ;
2003-03-15 04:35:45 +08:00
}
2005-08-29 20:05:17 +08:00
void readEventQueue ( osgProducer : : Viewer & viewer ) ;
void writeEventQueue ( osgProducer : : Viewer & viewer ) ;
2003-03-15 04:35:45 +08:00
void setMasterKilled ( const bool flag ) { _masterKilled = flag ; }
const bool getMasterKilled ( ) const { return _masterKilled ; }
2005-02-03 21:10:03 +08:00
unsigned int _byte_order ;
2003-03-15 04:35:45 +08:00
bool _masterKilled ;
osg : : Matrix _matrix ;
// note don't use a ref_ptr as used elsewhere for FrameStamp
// since we don't want to copy the pointer - but the memory.
// FrameStamp doesn't have a private destructor to allow
// us to do this, even though its a reference counted object.
osg : : FrameStamp _frameStamp ;
2005-08-30 03:57:02 +08:00
osgProducer : : KeyboardMouseCallback : : EventQueue _events ;
2005-08-29 20:05:17 +08:00
2003-03-15 04:35:45 +08:00
} ;
2005-08-30 03:57:02 +08:00
class DataConverter
{
public :
DataConverter ( unsigned int numBytes ) :
_startPtr ( 0 ) ,
_endPtr ( 0 ) ,
_swapBytes ( false ) ,
_currentPtr ( 0 )
{
_currentPtr = _startPtr = new char [ numBytes ] ;
_endPtr = _startPtr + numBytes ;
_numBytes = numBytes ;
}
char * _startPtr ;
char * _endPtr ;
unsigned int _numBytes ;
bool _swapBytes ;
char * _currentPtr ;
2005-08-30 04:16:15 +08:00
void reset ( )
{
_currentPtr = _startPtr ;
}
2005-08-30 03:57:02 +08:00
inline void write1 ( char * ptr )
{
if ( _currentPtr + 1 > = _endPtr ) return ;
* ( _currentPtr + + ) = * ( ptr ) ;
}
inline void read1 ( char * ptr )
{
if ( _currentPtr + 1 > = _endPtr ) return ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
inline void write2 ( char * ptr )
{
if ( _currentPtr + 2 > = _endPtr ) return ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr ) ;
}
inline void read2 ( char * ptr )
{
if ( _currentPtr + 2 > = _endPtr ) return ;
if ( _swapBytes )
{
* ( ptr + 1 ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
else
{
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
}
inline void write4 ( char * ptr )
{
if ( _currentPtr + 4 > = _endPtr ) return ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr ) ;
}
inline void read4 ( char * ptr )
{
if ( _currentPtr + 4 > = _endPtr ) return ;
if ( _swapBytes )
{
* ( ptr + 3 ) = * ( _currentPtr + + ) ;
* ( ptr + 2 ) = * ( _currentPtr + + ) ;
* ( ptr + 1 ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
else
{
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
}
inline void write8 ( char * ptr )
{
if ( _currentPtr + 8 > = _endPtr ) return ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr ) ;
}
inline void read8 ( char * ptr )
{
char * endPtr = _currentPtr + 8 ;
if ( endPtr > = _endPtr ) return ;
if ( _swapBytes )
{
* ( ptr + 7 ) = * ( _currentPtr + + ) ;
* ( ptr + 6 ) = * ( _currentPtr + + ) ;
* ( ptr + 5 ) = * ( _currentPtr + + ) ;
* ( ptr + 4 ) = * ( _currentPtr + + ) ;
* ( ptr + 3 ) = * ( _currentPtr + + ) ;
* ( ptr + 2 ) = * ( _currentPtr + + ) ;
* ( ptr + 1 ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
else
{
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
}
}
inline void writeChar ( char c ) { write1 ( & c ) ; }
inline void writeUChar ( unsigned char c ) { write1 ( ( char * ) & c ) ; }
inline void writeShort ( short c ) { write2 ( ( char * ) & c ) ; }
inline void writeUShort ( unsigned short c ) { write2 ( ( char * ) & c ) ; }
inline void writeInt ( int c ) { write4 ( ( char * ) & c ) ; }
inline void writeUInt ( unsigned int c ) { write4 ( ( char * ) & c ) ; }
inline void writeFloat ( float c ) { write4 ( ( char * ) & c ) ; }
inline void writeDouble ( double c ) { write8 ( ( char * ) & c ) ; }
inline char readChar ( ) { char c ; read1 ( & c ) ; return c ; }
inline unsigned char readUChar ( ) { unsigned char c ; read1 ( ( char * ) & c ) ; return c ; }
inline short readShort ( ) { short c ; read2 ( ( char * ) & c ) ; return c ; }
inline unsigned short readUShort ( ) { unsigned short c ; read2 ( ( char * ) & c ) ; return c ; }
inline int readInt ( ) { int c ; read4 ( ( char * ) & c ) ; return c ; }
inline unsigned int readUInt ( ) { unsigned int c ; read4 ( ( char * ) & c ) ; return c ; }
inline float readFloat ( ) { float c ; read4 ( ( char * ) & c ) ; return c ; }
inline double readDouble ( ) { double c ; read8 ( ( char * ) & c ) ; return c ; }
void write ( const osg : : FrameStamp & fs )
{
2005-08-31 06:28:30 +08:00
osg : : notify ( osg : : NOTICE ) < < " writeFramestamp = " < < fs . getFrameNumber ( ) < < " " < < fs . getReferenceTime ( ) < < std : : endl ;
2005-08-30 03:57:02 +08:00
writeUInt ( fs . getFrameNumber ( ) ) ;
return writeDouble ( fs . getReferenceTime ( ) ) ;
2005-08-30 04:38:46 +08:00
2005-08-30 03:57:02 +08:00
}
void read ( osg : : FrameStamp & fs )
{
fs . setFrameNumber ( readUInt ( ) ) ;
fs . setReferenceTime ( readDouble ( ) ) ;
2005-08-31 06:28:30 +08:00
osg : : notify ( osg : : NOTICE ) < < " readFramestamp = " < < fs . getFrameNumber ( ) < < " " < < fs . getReferenceTime ( ) < < std : : endl ;
2005-08-30 03:57:02 +08:00
}
void write ( const osg : : Matrix & matrix )
{
writeDouble ( matrix ( 0 , 0 ) ) ;
writeDouble ( matrix ( 0 , 1 ) ) ;
writeDouble ( matrix ( 0 , 2 ) ) ;
writeDouble ( matrix ( 0 , 3 ) ) ;
writeDouble ( matrix ( 1 , 0 ) ) ;
writeDouble ( matrix ( 1 , 1 ) ) ;
writeDouble ( matrix ( 1 , 2 ) ) ;
writeDouble ( matrix ( 1 , 3 ) ) ;
writeDouble ( matrix ( 2 , 0 ) ) ;
writeDouble ( matrix ( 2 , 1 ) ) ;
writeDouble ( matrix ( 2 , 2 ) ) ;
writeDouble ( matrix ( 2 , 3 ) ) ;
writeDouble ( matrix ( 3 , 0 ) ) ;
writeDouble ( matrix ( 3 , 1 ) ) ;
writeDouble ( matrix ( 3 , 2 ) ) ;
writeDouble ( matrix ( 3 , 3 ) ) ;
2005-08-31 06:28:30 +08:00
osg : : notify ( osg : : NOTICE ) < < " writeMatrix = " < < matrix < < std : : endl ;
2005-08-30 03:57:02 +08:00
}
void read ( osg : : Matrix & matrix )
{
matrix ( 0 , 0 ) = readDouble ( ) ;
matrix ( 0 , 1 ) = readDouble ( ) ;
matrix ( 0 , 2 ) = readDouble ( ) ;
matrix ( 0 , 3 ) = readDouble ( ) ;
matrix ( 1 , 0 ) = readDouble ( ) ;
matrix ( 1 , 1 ) = readDouble ( ) ;
matrix ( 1 , 2 ) = readDouble ( ) ;
matrix ( 1 , 3 ) = readDouble ( ) ;
matrix ( 2 , 0 ) = readDouble ( ) ;
matrix ( 2 , 1 ) = readDouble ( ) ;
matrix ( 2 , 2 ) = readDouble ( ) ;
matrix ( 2 , 3 ) = readDouble ( ) ;
matrix ( 3 , 0 ) = readDouble ( ) ;
matrix ( 3 , 1 ) = readDouble ( ) ;
matrix ( 3 , 2 ) = readDouble ( ) ;
matrix ( 3 , 3 ) = readDouble ( ) ;
2005-08-31 06:28:30 +08:00
osg : : notify ( osg : : NOTICE ) < < " readMatrix = " < < matrix < < std : : endl ;
2005-08-30 03:57:02 +08:00
}
void write ( const osgProducer : : EventAdapter & event )
{
writeUInt ( event . _eventType ) ;
writeUInt ( event . _key ) ;
writeUInt ( event . _button ) ;
writeFloat ( event . _Xmin ) ;
writeFloat ( event . _Xmax ) ;
writeFloat ( event . _Ymin ) ;
writeFloat ( event . _Ymax ) ;
writeFloat ( event . _mx ) ;
writeFloat ( event . _my ) ;
writeUInt ( event . _buttonMask ) ;
writeUInt ( event . _modKeyMask ) ;
writeDouble ( event . _time ) ;
}
void read ( osgProducer : : EventAdapter & event )
{
event . _eventType = ( osgGA : : GUIEventAdapter : : EventType ) readUInt ( ) ;
event . _key = readUInt ( ) ;
event . _button = readUInt ( ) ;
event . _Xmin = readFloat ( ) ;
event . _Xmax = readFloat ( ) ;
event . _Ymin = readFloat ( ) ;
event . _Ymax = readFloat ( ) ;
event . _mx = readFloat ( ) ;
event . _my = readFloat ( ) ;
event . _buttonMask = readUInt ( ) ;
event . _modKeyMask = readUInt ( ) ;
event . _time = readDouble ( ) ;
}
void write ( CameraPacket & cameraPacket )
{
writeUInt ( cameraPacket . _byte_order ) ;
writeUInt ( cameraPacket . _masterKilled ) ;
write ( cameraPacket . _matrix ) ;
write ( cameraPacket . _frameStamp ) ;
writeUInt ( cameraPacket . _events . size ( ) ) ;
for ( unsigned int i = 0 ; i < cameraPacket . _events . size ( ) ; + + i )
{
write ( * ( cameraPacket . _events [ i ] ) ) ;
}
}
void read ( CameraPacket & cameraPacket )
{
cameraPacket . _byte_order = readUInt ( ) ;
2005-08-30 04:16:15 +08:00
if ( cameraPacket . _byte_order ! = SWAP_BYTES_COMPARE )
{
_swapBytes = ! _swapBytes ;
}
2005-08-30 03:57:02 +08:00
cameraPacket . _masterKilled = readUInt ( ) ;
read ( cameraPacket . _matrix ) ;
read ( cameraPacket . _frameStamp ) ;
cameraPacket . _events . clear ( ) ;
unsigned int numEvents = readUInt ( ) ;
for ( unsigned int i = 0 ; i < numEvents ; + + i )
{
osgProducer : : EventAdapter * event = new osgProducer : : EventAdapter ;
read ( * ( event ) ) ;
cameraPacket . _events . push_back ( event ) ;
}
}
} ;
2005-08-29 20:05:17 +08:00
void CameraPacket : : readEventQueue ( osgProducer : : Viewer & viewer )
{
2005-08-30 04:16:15 +08:00
_events . clear ( ) ;
2005-08-30 03:57:02 +08:00
viewer . getKeyboardMouseCallback ( ) - > copyEventQueue ( _events ) ;
2005-08-29 20:05:17 +08:00
2005-08-30 03:57:02 +08:00
osg : : notify ( osg : : INFO ) < < " written events = " < < _events . size ( ) < < std : : endl ;
2005-08-29 20:05:17 +08:00
}
void CameraPacket : : writeEventQueue ( osgProducer : : Viewer & viewer )
{
2005-08-30 03:57:02 +08:00
osg : : notify ( osg : : INFO ) < < " recieved events = " < < _events . size ( ) < < std : : endl ;
2005-08-29 20:05:17 +08:00
2005-08-30 03:57:02 +08:00
// copy the events to osgProducer style events.
viewer . getKeyboardMouseCallback ( ) - > appendEventQueue ( _events ) ;
2005-08-29 20:05:17 +08:00
}
2003-03-17 05:58:27 +08:00
enum ViewerMode
2003-03-15 04:35:45 +08:00
{
2003-03-17 05:58:27 +08:00
STAND_ALONE ,
SLAVE ,
MASTER
} ;
2003-03-15 04:35:45 +08:00
int main ( int argc , char * * argv )
{
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
// set up the usage document, in case we need to print out how to use this program.
2003-04-09 19:44:32 +08:00
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is the example which demonstrates how to approach implementation of clustering. Note, cluster support will soon be encompassed in Producer itself. " ) ;
2003-04-07 05:32:44 +08:00
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) + " [options] filename ... " ) ;
2003-03-15 04:35:45 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display this information " ) ;
2003-03-17 05:58:27 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -m " , " Set viewer to MASTER mode, sending view via packets. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -s " , " Set viewer to SLAVE mode, reciving view via packets. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -n <int> " , " Socket number to transmit packets " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -f <float> " , " Field of view of camera " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -o <float> " , " Offset angle of camera " ) ;
2003-03-15 04:35:45 +08:00
// construct the viewer.
osgProducer : : Viewer viewer ( arguments ) ;
// set up the value with sensible default event handlers.
viewer . setUpViewer ( osgProducer : : Viewer : : STANDARD_SETTINGS ) ;
// get details on keyboard and mouse bindings used by the viewer.
viewer . getUsage ( * arguments . getApplicationUsage ( ) ) ;
2003-03-17 05:58:27 +08:00
// read up the osgcluster specific arguments.
ViewerMode viewerMode = STAND_ALONE ;
while ( arguments . read ( " -m " ) ) viewerMode = MASTER ;
while ( arguments . read ( " -s " ) ) viewerMode = SLAVE ;
2005-08-29 20:05:17 +08:00
int socketNumber = 8100 ;
2003-03-17 05:58:27 +08:00
while ( arguments . read ( " -n " , socketNumber ) ) ;
2004-10-19 21:52:46 +08:00
float camera_fov = - 1.0f ;
2003-10-10 17:41:04 +08:00
while ( arguments . read ( " -f " , camera_fov ) )
{
}
2003-03-17 05:58:27 +08:00
float camera_offset = 45.0f ;
while ( arguments . read ( " -o " , camera_offset ) ) ;
2003-03-15 04:35:45 +08:00
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}
// any option left unread are converted into errors to write out later.
arguments . reportRemainingOptionsAsUnrecognized ( ) ;
// report any errors if they have occured when parsing the program aguments.
if ( arguments . errors ( ) )
{
arguments . writeErrorMessages ( std : : cout ) ;
return 1 ;
}
2003-04-07 05:32:44 +08:00
if ( arguments . argc ( ) < = 1 )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout , osg : : ApplicationUsage : : COMMAND_LINE_OPTION ) ;
return 1 ;
}
2003-03-15 04:35:45 +08:00
2003-03-17 05:58:27 +08:00
// load model.
osg : : ref_ptr < osg : : Node > rootnode = osgDB : : readNodeFiles ( arguments ) ;
2003-03-15 04:35:45 +08:00
// set the scene to render
2003-03-17 05:58:27 +08:00
viewer . setSceneData ( rootnode . get ( ) ) ;
2003-03-15 04:35:45 +08:00
// create the windows and run the threads.
2003-04-08 23:18:45 +08:00
viewer . realize ( ) ;
2003-03-15 04:35:45 +08:00
2004-10-19 21:52:46 +08:00
// set up the lens after realize as the Producer lens is not set up properly before this.... will need to inveestigate this at a later date.
if ( camera_fov > 0.0f )
{
float aspectRatio = tan ( osg : : DegreesToRadians ( viewer . getLensVerticalFov ( ) * 0.5 ) ) / tan ( osg : : DegreesToRadians ( viewer . getLensHorizontalFov ( ) * 0.5 ) ) ;
float new_fovy = osg : : RadiansToDegrees ( atan ( aspectRatio * tan ( osg : : DegreesToRadians ( camera_fov * 0.5 ) ) ) ) * 2.0f ;
std : : cout < < " setting lens perspective : original " < < viewer . getLensHorizontalFov ( ) < < " " < < viewer . getLensVerticalFov ( ) < < std : : endl ;
viewer . setLensPerspective ( camera_fov , new_fovy , 1.0f , 1000.0f ) ;
std : : cout < < " setting lens perspective : new " < < viewer . getLensHorizontalFov ( ) < < " " < < viewer . getLensVerticalFov ( ) < < std : : endl ;
}
2004-12-03 05:28:40 +08:00
CameraPacket * cp = new CameraPacket ;
2005-08-30 03:57:02 +08:00
2003-03-17 17:51:19 +08:00
// objects for managing the broadcasting and recieving of camera packets.
2003-03-17 05:58:27 +08:00
Broadcaster bc ;
Receiver rc ;
2003-05-21 20:15:45 +08:00
bc . setPort ( static_cast < short int > ( socketNumber ) ) ;
2005-08-29 22:05:30 +08:00
rc . setPort ( static_cast < short int > ( socketNumber ) ) ;
2003-05-21 20:15:45 +08:00
bool masterKilled = false ;
2005-08-30 03:57:02 +08:00
DataConverter scratchPad ( 1024 ) ;
2003-05-21 20:15:45 +08:00
while ( ! viewer . done ( ) & & ! masterKilled )
2003-03-15 04:35:45 +08:00
{
// wait for all cull and draw threads to complete.
viewer . sync ( ) ;
2005-08-29 20:05:17 +08:00
osg : : Timer_t startTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2003-03-17 05:58:27 +08:00
// special handling for working as a cluster.
switch ( viewerMode )
{
case ( MASTER ) :
{
// take camera zero as the guide.
osg : : Matrix modelview ( viewer . getCameraConfig ( ) - > getCamera ( 0 ) - > getViewMatrix ( ) ) ;
2004-12-03 05:28:40 +08:00
cp - > setPacket ( modelview , viewer . getFrameStamp ( ) ) ;
2005-08-29 20:05:17 +08:00
cp - > readEventQueue ( viewer ) ;
2003-03-17 05:58:27 +08:00
2005-08-30 04:16:15 +08:00
scratchPad . reset ( ) ;
2005-08-30 03:57:02 +08:00
scratchPad . write ( * cp ) ;
2005-08-30 04:38:46 +08:00
scratchPad . reset ( ) ;
scratchPad . read ( * cp ) ;
2005-08-30 03:57:02 +08:00
bc . setBuffer ( scratchPad . _startPtr , scratchPad . _numBytes ) ;
2004-06-15 03:31:48 +08:00
2005-08-30 03:57:02 +08:00
std : : cout < < " bc.sync() " < < scratchPad . _numBytes < < std : : endl ;
2005-08-29 20:25:16 +08:00
2004-06-15 03:31:48 +08:00
bc . sync ( ) ;
2005-08-29 20:05:17 +08:00
2003-03-17 05:58:27 +08:00
}
break ;
case ( SLAVE ) :
{
2005-08-30 03:57:02 +08:00
rc . setBuffer ( scratchPad . _startPtr , scratchPad . _numBytes ) ;
2003-03-17 05:58:27 +08:00
2003-05-21 20:15:45 +08:00
rc . sync ( ) ;
2005-08-30 03:57:02 +08:00
2005-08-30 04:16:15 +08:00
scratchPad . reset ( ) ;
2005-08-30 03:57:02 +08:00
scratchPad . read ( * cp ) ;
2003-05-21 20:15:45 +08:00
2005-08-29 22:05:30 +08:00
cp - > writeEventQueue ( viewer ) ;
2003-03-17 05:58:27 +08:00
2004-12-03 05:28:40 +08:00
if ( cp - > getMasterKilled ( ) )
2003-03-17 05:58:27 +08:00
{
2005-08-29 22:05:30 +08:00
std : : cout < < " Received master killed. " < < std : : endl ;
2003-03-17 17:51:19 +08:00
// break out of while (!done) loop since we've now want to shut down.
2003-05-21 20:15:45 +08:00
masterKilled = true ;
2003-03-17 05:58:27 +08:00
}
}
break ;
default :
// no need to anything here, just a normal interactive viewer.
break ;
}
2005-08-29 20:05:17 +08:00
osg : : Timer_t endTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2005-08-29 22:05:30 +08:00
osg : : notify ( osg : : INFO ) < < " Time to do cluster sync " < < osg : : Timer : : instance ( ) - > delta_m ( startTick , endTick ) < < std : : endl ;
2005-08-29 20:05:17 +08:00
// update the scene by traversing it with the the update visitor which will
// call all node update callbacks and animations.
viewer . update ( ) ;
if ( viewerMode = = SLAVE )
{
osg : : Matrix modelview ;
cp - > getModelView ( modelview , camera_offset ) ;
viewer . setView ( modelview ) ;
}
2003-03-15 04:35:45 +08:00
// fire off the cull and draw traversals of the scene.
2003-05-21 20:15:45 +08:00
if ( ! masterKilled )
viewer . frame ( ) ;
2003-03-15 04:35:45 +08:00
}
2003-05-21 20:15:45 +08:00
2003-03-25 18:05:09 +08:00
// wait for all cull and draw threads to complete before exit.
viewer . sync ( ) ;
2003-03-17 05:58:27 +08:00
// if we are master clean up by telling all slaves that we're going down.
if ( viewerMode = = MASTER )
{
// need to broadcast my death.
2004-12-03 05:28:40 +08:00
cp - > setPacket ( osg : : Matrix : : identity ( ) , viewer . getFrameStamp ( ) ) ;
cp - > setMasterKilled ( true ) ;
2003-03-17 05:58:27 +08:00
2004-12-03 05:28:40 +08:00
bc . setBuffer ( cp , sizeof ( CameraPacket ) ) ;
2003-05-21 20:15:45 +08:00
bc . sync ( ) ;
2003-03-17 05:58:27 +08:00
2005-08-29 22:05:30 +08:00
std : : cout < < " Broadcasting death. " < < std : : endl ;
2003-03-17 05:58:27 +08:00
}
2003-03-15 04:35:45 +08:00
return 0 ;
}