2007-06-12 22:20:16 +08:00
/* OpenSceneGraph example, osgcluster.
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
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>
2007-01-06 05:23:37 +08:00
# include <osgGA/TrackballManipulator>
2010-06-17 22:18:11 +08:00
# include <osgGA/StateSetManipulator>
2007-01-06 05:19:01 +08:00
# include <osgViewer/Viewer>
2010-06-17 22:18:11 +08:00
# include <osgViewer/ViewerEventHandlers>
2003-03-15 04:35:45 +08:00
# include <osg/Quat>
2005-08-30 04:38:46 +08:00
# include <osg/io_utils>
2003-03-15 04:35:45 +08:00
2007-01-06 05:19:01 +08:00
# include <iostream>
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-30 03:57:02 +08:00
const unsigned int SWAP_BYTES_COMPARE = 0x12345678 ;
2003-03-15 04:35:45 +08:00
class CameraPacket {
public :
2013-10-25 22:54:15 +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
}
2013-10-25 22:54:15 +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 ;
}
}
2013-10-25 22:54:15 +08:00
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
{
2013-10-25 22:54:15 +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
}
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
void readEventQueue ( osgViewer : : Viewer & viewer ) ;
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
void writeEventQueue ( osgViewer : : Viewer & viewer ) ;
2003-03-15 04:35:45 +08:00
void setMasterKilled ( const bool flag ) { _masterKilled = flag ; }
const bool getMasterKilled ( ) const { return _masterKilled ; }
2013-10-25 22:54:15 +08:00
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
2013-10-25 22:54:15 +08:00
// us to do this, even though its a reference counted object.
2003-03-15 04:35:45 +08:00
osg : : FrameStamp _frameStamp ;
2013-10-25 22:54:15 +08:00
2006-03-08 22:09:47 +08:00
osgGA : : EventQueue : : Events _events ;
2013-10-25 22:54:15 +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 ;
2013-10-25 22:54:15 +08:00
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 ;
2013-10-25 22:54:15 +08:00
* ( _currentPtr + + ) = * ( ptr ) ;
2005-08-30 03:57:02 +08:00
}
inline void read1 ( char * ptr )
{
if ( _currentPtr + 1 > = _endPtr ) return ;
2013-10-25 22:54:15 +08:00
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
inline void write2 ( char * ptr )
{
if ( _currentPtr + 2 > = _endPtr ) return ;
2013-10-25 22:54:15 +08:00
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr ) ;
2005-08-30 03:57:02 +08:00
}
inline void read2 ( char * ptr )
{
if ( _currentPtr + 2 > = _endPtr ) return ;
if ( _swapBytes )
{
2013-10-25 22:54:15 +08:00
* ( ptr + 1 ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
else
{
2013-10-25 22:54:15 +08:00
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
}
inline void write4 ( char * ptr )
{
if ( _currentPtr + 4 > = _endPtr ) return ;
2013-10-25 22:54:15 +08:00
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr ) ;
2005-08-30 03:57:02 +08:00
}
inline void read4 ( char * ptr )
{
if ( _currentPtr + 4 > = _endPtr ) return ;
if ( _swapBytes )
{
2013-10-25 22:54:15 +08:00
* ( ptr + 3 ) = * ( _currentPtr + + ) ;
* ( ptr + 2 ) = * ( _currentPtr + + ) ;
* ( ptr + 1 ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
else
{
2013-10-25 22:54:15 +08:00
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
}
inline void write8 ( char * ptr )
{
if ( _currentPtr + 8 > = _endPtr ) return ;
2013-10-25 22:54:15 +08:00
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
2005-08-30 03:57:02 +08:00
2013-10-25 22:54:15 +08:00
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr + + ) ;
* ( _currentPtr + + ) = * ( ptr ) ;
2005-08-30 03:57:02 +08:00
}
inline void read8 ( char * ptr )
{
char * endPtr = _currentPtr + 8 ;
if ( endPtr > = _endPtr ) return ;
if ( _swapBytes )
{
2013-10-25 22:54:15 +08:00
* ( ptr + 7 ) = * ( _currentPtr + + ) ;
* ( ptr + 6 ) = * ( _currentPtr + + ) ;
* ( ptr + 5 ) = * ( _currentPtr + + ) ;
* ( ptr + 4 ) = * ( _currentPtr + + ) ;
* ( ptr + 3 ) = * ( _currentPtr + + ) ;
* ( ptr + 2 ) = * ( _currentPtr + + ) ;
* ( ptr + 1 ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
else
{
2013-10-25 22:54:15 +08:00
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr + + ) = * ( _currentPtr + + ) ;
* ( ptr ) = * ( _currentPtr + + ) ;
2005-08-30 03:57:02 +08:00
}
}
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 ) ; }
2014-11-27 00:04:33 +08:00
inline char readChar ( ) { char c = 0 ; read1 ( & c ) ; return c ; }
inline unsigned char readUChar ( ) { unsigned char c = 0 ; read1 ( ( char * ) & c ) ; return c ; }
inline short readShort ( ) { short c = 0 ; read2 ( ( char * ) & c ) ; return c ; }
inline unsigned short readUShort ( ) { unsigned short c = 0 ; read2 ( ( char * ) & c ) ; return c ; }
inline int readInt ( ) { int c = 0 ; read4 ( ( char * ) & c ) ; return c ; }
inline unsigned int readUInt ( ) { unsigned int c = 0 ; read4 ( ( char * ) & c ) ; return c ; }
inline float readFloat ( ) { float c = 0.0f ; read4 ( ( char * ) & c ) ; return c ; }
inline double readDouble ( ) { double c = 0.0 ; read8 ( ( char * ) & c ) ; return c ; }
2005-08-30 03:57:02 +08:00
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 ( ) ) ;
2005-11-11 01:24:41 +08:00
writeDouble ( fs . getReferenceTime ( ) ) ;
2007-01-25 20:02:51 +08:00
writeDouble ( fs . getSimulationTime ( ) ) ;
2005-08-30 03:57:02 +08:00
}
void read ( osg : : FrameStamp & fs )
{
fs . setFrameNumber ( readUInt ( ) ) ;
fs . setReferenceTime ( readDouble ( ) ) ;
2007-01-25 20:02:51 +08:00
fs . setSimulationTime ( 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
}
2006-03-08 22:09:47 +08:00
void write ( const osgGA : : GUIEventAdapter & event )
2005-08-30 03:57:02 +08:00
{
2006-03-08 22:09:47 +08:00
writeUInt ( event . getEventType ( ) ) ;
writeUInt ( event . getKey ( ) ) ;
writeUInt ( event . getButton ( ) ) ;
2006-09-26 00:25:53 +08:00
writeInt ( event . getWindowX ( ) ) ;
writeInt ( event . getWindowY ( ) ) ;
writeUInt ( event . getWindowWidth ( ) ) ;
writeUInt ( event . getWindowHeight ( ) ) ;
2006-03-08 22:09:47 +08:00
writeFloat ( event . getXmin ( ) ) ;
writeFloat ( event . getYmin ( ) ) ;
2006-09-26 00:25:53 +08:00
writeFloat ( event . getXmax ( ) ) ;
2006-03-08 22:09:47 +08:00
writeFloat ( event . getYmax ( ) ) ;
writeFloat ( event . getX ( ) ) ;
writeFloat ( event . getY ( ) ) ;
writeUInt ( event . getButtonMask ( ) ) ;
writeUInt ( event . getModKeyMask ( ) ) ;
writeDouble ( event . getTime ( ) ) ;
2005-08-30 03:57:02 +08:00
}
2006-03-08 22:09:47 +08:00
void read ( osgGA : : GUIEventAdapter & event )
2005-08-30 03:57:02 +08:00
{
2006-03-08 22:09:47 +08:00
event . setEventType ( ( osgGA : : GUIEventAdapter : : EventType ) readUInt ( ) ) ;
event . setKey ( readUInt ( ) ) ;
event . setButton ( readUInt ( ) ) ;
2006-09-26 00:25:53 +08:00
int x = readInt ( ) ;
int y = readInt ( ) ;
int width = readUInt ( ) ;
int height = readUInt ( ) ;
event . setWindowRectangle ( x , y , width , height ) ;
float xmin = readFloat ( ) ;
float ymin = readFloat ( ) ;
float xmax = readFloat ( ) ;
float ymax = readFloat ( ) ;
event . setInputRange ( xmin , ymin , xmax , ymax ) ;
2006-03-08 22:09:47 +08:00
event . setX ( readFloat ( ) ) ;
event . setY ( readFloat ( ) ) ;
event . setButtonMask ( readUInt ( ) ) ;
event . setModKeyMask ( readUInt ( ) ) ;
event . setTime ( readDouble ( ) ) ;
2005-08-30 03:57:02 +08:00
}
2013-10-25 22:54:15 +08:00
2005-08-30 03:57:02 +08:00
void write ( CameraPacket & cameraPacket )
{
writeUInt ( cameraPacket . _byte_order ) ;
2013-10-25 22:54:15 +08:00
2005-08-30 03:57:02 +08:00
writeUInt ( cameraPacket . _masterKilled ) ;
2013-10-25 22:54:15 +08:00
2005-08-30 03:57:02 +08:00
write ( cameraPacket . _matrix ) ;
write ( cameraPacket . _frameStamp ) ;
2013-10-25 22:54:15 +08:00
2005-08-30 03:57:02 +08:00
writeUInt ( cameraPacket . _events . size ( ) ) ;
2006-03-08 22:09:47 +08:00
for ( osgGA : : EventQueue : : Events : : iterator itr = cameraPacket . _events . begin ( ) ;
itr ! = cameraPacket . _events . end ( ) ;
+ + itr )
2005-08-30 03:57:02 +08:00
{
2013-10-25 22:54:15 +08:00
osgGA : : GUIEventAdapter * event = ( * itr ) - > asGUIEventAdapter ( ) ;
if ( event ) write ( * event ) ;
2005-08-30 03:57:02 +08:00
}
}
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 ;
}
2013-10-25 22:54:15 +08:00
2009-02-03 23:28:53 +08:00
cameraPacket . _masterKilled = readUInt ( ) ! = 0 ;
2013-10-25 22:54:15 +08:00
2005-08-30 03:57:02 +08:00
read ( cameraPacket . _matrix ) ;
read ( cameraPacket . _frameStamp ) ;
2013-10-25 22:54:15 +08:00
2005-08-30 03:57:02 +08:00
cameraPacket . _events . clear ( ) ;
unsigned int numEvents = readUInt ( ) ;
for ( unsigned int i = 0 ; i < numEvents ; + + i )
{
2006-03-08 22:09:47 +08:00
osgGA : : GUIEventAdapter * event = new osgGA : : GUIEventAdapter ;
2005-08-30 03:57:02 +08:00
read ( * ( event ) ) ;
cameraPacket . _events . push_back ( event ) ;
}
}
} ;
2007-01-06 05:19:01 +08:00
void CameraPacket : : readEventQueue ( osgViewer : : Viewer & viewer )
2005-08-29 20:05:17 +08:00
{
2005-08-30 04:16:15 +08:00
_events . clear ( ) ;
2010-06-17 22:28:16 +08:00
osgViewer : : ViewerBase : : Contexts contexts ;
2013-10-25 22:54:15 +08:00
viewer . getContexts ( contexts ) ;
2010-06-17 22:28:16 +08:00
for ( osgViewer : : ViewerBase : : Contexts : : iterator citr = contexts . begin ( ) ; citr ! = contexts . end ( ) ; + + citr )
{
osgGA : : EventQueue : : Events gw_events ;
osgViewer : : GraphicsWindow * gw = dynamic_cast < osgViewer : : GraphicsWindow * > ( * citr ) ;
if ( gw )
{
gw - > checkEvents ( ) ;
gw - > getEventQueue ( ) - > copyEvents ( gw_events ) ;
}
_events . insert ( _events . end ( ) , gw_events . begin ( ) , gw_events . end ( ) ) ;
}
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
viewer . getEventQueue ( ) - > copyEvents ( _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
}
2007-01-06 05:19:01 +08:00
void CameraPacket : : writeEventQueue ( osgViewer : : Viewer & viewer )
2005-08-29 20:05:17 +08:00
{
2009-02-06 23:17:49 +08:00
osg : : notify ( osg : : INFO ) < < " received events = " < < _events . size ( ) < < std : : endl ;
2005-08-29 20:05:17 +08:00
2007-01-06 05:19:01 +08:00
viewer . getEventQueue ( ) - > appendEvents ( _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 ) ;
2013-10-25 22:54:15 +08:00
2003-03-15 04:35:45 +08:00
// set up the usage document, in case we need to print out how to use this program.
2007-01-11 23:19:59 +08:00
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is the example which demonstrates how to approach implementation of clustering. " ) ;
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. " ) ;
2009-02-06 23:17:49 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -s " , " Set viewer to SLAVE mode, receiving view via packets. " ) ;
2003-03-17 05:58:27 +08:00
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 " ) ;
2013-10-25 22:54:15 +08:00
2003-03-15 04:35:45 +08:00
// construct the viewer.
2007-01-06 05:19:01 +08:00
osgViewer : : Viewer viewer ;
2003-03-15 04:35:45 +08:00
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 ;
2013-10-25 22:54:15 +08:00
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 ;
2013-10-25 22:54:15 +08:00
while ( arguments . read ( " -f " , camera_fov ) )
2003-10-10 17:41:04 +08:00
{
}
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 ;
}
2013-10-25 22:54:15 +08:00
2003-04-07 05:32:44 +08:00
if ( arguments . argc ( ) < = 1 )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout , osg : : ApplicationUsage : : COMMAND_LINE_OPTION ) ;
return 1 ;
}
2007-01-06 05:19:01 +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
2004-10-19 21:52:46 +08:00
if ( camera_fov > 0.0f )
{
2007-01-06 05:19:01 +08:00
double fovy , aspectRatio , zNear , zFar ;
viewer . getCamera ( ) - > getProjectionMatrixAsPerspective ( fovy , aspectRatio , zNear , zFar ) ;
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
double original_fov = atan ( tan ( osg : : DegreesToRadians ( fovy ) * 0.5 ) * aspectRatio ) * 2.0 ;
std : : cout < < " setting lens perspective : original " < < original_fov < < " " < < fovy < < std : : endl ;
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
fovy = atan ( tan ( osg : : DegreesToRadians ( camera_fov ) * 0.5 ) / aspectRatio ) * 2.0 ;
viewer . getCamera ( ) - > setProjectionMatrixAsPerspective ( fovy , aspectRatio , zNear , zFar ) ;
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
viewer . getCamera ( ) - > getProjectionMatrixAsPerspective ( fovy , aspectRatio , zNear , zFar ) ;
original_fov = atan ( tan ( osg : : DegreesToRadians ( fovy ) * 0.5 ) * aspectRatio ) * 2.0 ;
std : : cout < < " setting lens perspective : new " < < original_fov < < " " < < fovy < < std : : endl ;
2004-10-19 21:52:46 +08:00
}
2007-01-06 05:23:37 +08:00
viewer . setCameraManipulator ( new osgGA : : TrackballManipulator ( ) ) ;
2010-06-17 22:18:11 +08:00
// add the stats handler
viewer . addEventHandler ( new osgViewer : : StatsHandler ) ;
// add the state manipulator
viewer . addEventHandler ( new osgGA : : StateSetManipulator ( viewer . getCamera ( ) - > getOrCreateStateSet ( ) ) ) ;
2004-10-19 21:52:46 +08:00
2007-01-06 05:19:01 +08:00
// create the windows and run the threads.
viewer . realize ( ) ;
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 ;
2013-10-25 22:54:15 +08:00
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
{
2005-08-29 20:05:17 +08:00
osg : : Timer_t startTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
viewer . advance ( ) ;
2003-03-17 05:58:27 +08:00
// special handling for working as a cluster.
switch ( viewerMode )
{
case ( MASTER ) :
{
2013-10-25 22:54:15 +08:00
2003-03-17 05:58:27 +08:00
// take camera zero as the guide.
2007-01-06 05:19:01 +08:00
osg : : Matrix modelview ( viewer . getCamera ( ) - > getViewMatrix ( ) ) ;
2013-10-25 22:54:15 +08:00
2004-12-03 05:28:40 +08:00
cp - > setPacket ( modelview , viewer . getFrameStamp ( ) ) ;
2013-10-25 22:54:15 +08:00
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 ) ;
2013-10-25 22:54:15 +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 ( ) ;
2013-10-25 22:54:15 +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 ( ) ;
2013-10-25 22:54:15 +08:00
2005-08-30 04:16:15 +08:00
scratchPad . reset ( ) ;
2005-08-30 03:57:02 +08:00
scratchPad . read ( * cp ) ;
2013-10-25 22:54:15 +08:00
2005-08-29 22:05:30 +08:00
cp - > writeEventQueue ( viewer ) ;
2003-03-17 05:58:27 +08:00
2013-10-25 22:54:15 +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 ;
}
2013-10-25 22:54:15 +08:00
2005-08-29 20:05:17 +08:00
osg : : Timer_t endTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2013-10-25 22:54:15 +08:00
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
2015-06-01 21:11:49 +08:00
// update the scene by traversing it with the update visitor which will
2005-08-29 20:05:17 +08:00
// call all node update callbacks and animations.
2007-01-06 05:19:01 +08:00
viewer . eventTraversal ( ) ;
viewer . updateTraversal ( ) ;
2005-08-29 20:05:17 +08:00
if ( viewerMode = = SLAVE )
{
osg : : Matrix modelview ;
cp - > getModelView ( modelview , camera_offset ) ;
2013-10-25 22:54:15 +08:00
2007-01-06 05:19:01 +08:00
viewer . getCamera ( ) - > setViewMatrix ( modelview ) ;
2005-08-29 20:05:17 +08:00
}
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 )
2007-01-06 05:19:01 +08:00
viewer . renderingTraversals ( ) ;
2013-10-25 22:54:15 +08:00
2003-03-15 04:35:45 +08:00
}
2003-05-21 20:15:45 +08:00
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 ( ) ) ;
2013-10-25 22:54:15 +08:00
cp - > setMasterKilled ( true ) ;
2003-03-17 05:58:27 +08:00
2010-06-17 22:36:11 +08:00
scratchPad . reset ( ) ;
scratchPad . write ( * cp ) ;
bc . setBuffer ( scratchPad . _startPtr , scratchPad . _numBytes ) ;
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 ;
}