2005-04-07 04:54:36 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and / or modified under
* the terms of the OpenSceneGraph Public License ( OSGPL ) version 0.0 or
* ( at your option ) any later version . The full license is in LICENSE file
* included with this distribution , and on the openscenegraph . org website .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* OpenSceneGraph Public License for more details .
*/
# include <osgProducer/Viewer>
# include <osgDB/ReadFile>
# include <osgDB/WriteFile>
# include <osgUtil/Optimizer>
# include <osg/Geode>
# include <osg/Notify>
# include <osg/MatrixTransform>
# include <osg/PositionAttitudeTransform>
# include <osg/Switch>
# include <osg/TexMat>
# include <osg/Texture2D>
2005-04-11 05:25:37 +08:00
# include <osg/io_utils>
# include <osgParticle/ExplosionEffect>
# include <osgParticle/ExplosionDebriEffect>
# include <osgParticle/SmokeEffect>
# include <osgParticle/FireEffect>
2005-04-07 04:54:36 +08:00
typedef std : : vector < std : : string > FileList ;
2005-04-11 05:25:37 +08:00
class Character : public osg : : Referenced
2005-04-07 04:54:36 +08:00
{
2005-04-11 05:25:37 +08:00
public :
2005-04-07 04:54:36 +08:00
Character ( ) ;
void setCharacter ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & orgin , const osg : : Vec3 & width , float positionRatio ) ;
void setLives ( const std : : string & filename , const osg : : Vec3 & orgin , const osg : : Vec3 & delta , unsigned int numLives ) ;
void setCatches ( const std : : string & filename , const osg : : Vec3 & orgin , const osg : : Vec3 & delta , unsigned int numLives ) ;
void moveLeft ( ) ;
void moveRight ( ) ;
void moveTo ( float positionRatio ) ;
void reset ( ) ;
bool addCatch ( ) ;
bool looseLife ( ) ;
2005-04-11 05:25:37 +08:00
osg : : Vec3 getCurrentCenterOfBasket ( ) const { return _character - > getPosition ( ) + _centerBasket ; }
float getCurrentRadiusOfBasket ( ) const { return _radiusBasket ; }
osg : : Vec3 getLowerLeft ( ) const { return _character - > getPosition ( ) ; }
osg : : Vec3 getUpperRight ( ) const { return _character - > getPosition ( ) ; }
2005-04-07 04:54:36 +08:00
osg : : Vec3 _origin ;
osg : : Vec3 _width ;
float _positionRatio ;
osg : : ref_ptr < osg : : PositionAttitudeTransform > _character ;
unsigned int _numLives ;
osg : : ref_ptr < osg : : Switch > _livesSwitch ;
unsigned int _numCatches ;
osg : : ref_ptr < osg : : Switch > _catchSwitch ;
2005-04-11 05:25:37 +08:00
osg : : ref_ptr < osg : : Group > _objectsGroup ;
osg : : Vec3 _centerBasket ;
float _radiusBasket ;
2005-04-07 04:54:36 +08:00
} ;
Character : : Character ( ) :
_positionRatio ( 0.5f ) ,
_numLives ( 3 ) ,
_numCatches ( 0 )
{
}
void Character : : setCharacter ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & origin , const osg : : Vec3 & width , float positionRatio )
{
_origin = origin ;
_width = width ;
_positionRatio = positionRatio ;
_numLives = 3 ;
_numCatches = 0 ;
float _characterSize = _width . length ( ) * 0.2f ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
2005-04-11 05:25:37 +08:00
osg : : Vec3 pos ( - 0.5f * _characterSize , 0.0f , 0.0f ) ;
osg : : Vec3 width ( _characterSize * ( ( float ) image - > s ( ) ) / ( float ) ( image - > t ( ) ) , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , _characterSize ) ;
2005-04-07 04:54:36 +08:00
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
2005-04-11 05:25:37 +08:00
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
2005-04-07 04:54:36 +08:00
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_character = new osg : : PositionAttitudeTransform ;
_character - > setName ( name ) ;
_character - > addChild ( geode ) ;
moveTo ( positionRatio ) ;
2005-04-11 05:25:37 +08:00
_centerBasket = width * 0.2 + height * 0.57 + pos ;
_radiusBasket = width . length ( ) * 0.34 ;
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
2005-04-07 04:54:36 +08:00
}
void Character : : setLives ( const std : : string & filename , const osg : : Vec3 & origin , const osg : : Vec3 & delta , unsigned int numLives )
{
float characterSize = delta . length ( ) ;
_numLives = numLives ;
_livesSwitch = new osg : : Switch ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
osg : : StateSet * stateset = _livesSwitch - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
2005-04-11 05:25:37 +08:00
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
2005-04-07 04:54:36 +08:00
for ( unsigned int i = 0 ; i < numLives ; + + i )
{
2005-04-11 05:25:37 +08:00
osg : : Vec3 pos = origin + delta * ( float ) i + osg : : Vec3 ( 0.0f , 0.0f , 0.0f ) ;
osg : : Vec3 width ( characterSize * ( ( float ) image - > s ( ) ) / ( float ) ( image - > t ( ) ) , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , characterSize ) ;
2005-04-07 04:54:36 +08:00
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_livesSwitch - > addChild ( geode , true ) ;
}
}
}
void Character : : setCatches ( const std : : string & filename , const osg : : Vec3 & origin , const osg : : Vec3 & delta , unsigned int numCatches )
{
float characterSize = delta . length ( ) ;
_numCatches = 0 ;
_catchSwitch = new osg : : Switch ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
osg : : StateSet * stateset = _catchSwitch - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
2005-04-11 05:25:37 +08:00
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
2005-04-07 04:54:36 +08:00
for ( unsigned int i = 0 ; i < numCatches ; + + i )
{
2005-04-11 05:25:37 +08:00
osg : : Vec3 pos = origin + delta * ( float ) i + osg : : Vec3 ( 0.0f , 0.0f , 0.0f ) ;
2005-04-07 04:54:36 +08:00
osg : : Vec3 width ( characterSize , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , characterSize * ( ( float ) image - > t ( ) ) / ( float ) ( image - > s ( ) ) ) ;
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_catchSwitch - > addChild ( geode , false ) ;
}
}
}
void Character : : moveLeft ( )
{
moveTo ( _positionRatio - 0.01f ) ;
}
void Character : : moveRight ( )
{
moveTo ( _positionRatio + 0.01f ) ;
}
void Character : : moveTo ( float positionRatio )
{
if ( positionRatio < 0.0f ) positionRatio = 0.0f ;
if ( positionRatio > 1.0f ) positionRatio = 1.0f ;
_positionRatio = positionRatio ;
_character - > setPosition ( _origin + _width * + positionRatio ) ;
}
void Character : : reset ( )
{
_numCatches = 0 ;
_numLives = _livesSwitch - > getNumChildren ( ) ;
_livesSwitch - > setAllChildrenOn ( ) ;
_catchSwitch - > setAllChildrenOff ( ) ;
}
bool Character : : addCatch ( )
{
if ( ! _catchSwitch | | _numCatches > = _catchSwitch - > getNumChildren ( ) ) return false ;
_catchSwitch - > setValue ( _numCatches , true ) ;
+ + _numCatches ;
return true ;
}
bool Character : : looseLife ( )
{
if ( ! _livesSwitch | | _numLives = = 0 ) return true ;
- - _numLives ;
_livesSwitch - > setValue ( _numLives , false ) ;
return ( _numLives = = 0 ) ;
}
2005-04-11 05:25:37 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
class CatchableObject : public osg : : Referenced
{
public :
CatchableObject ( ) ;
void setObject ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & center , float size , const osg : : Vec3 & direction ) ;
bool anyInside ( const osg : : Vec3 & lower_left , const osg : : Vec3 & top_right ) ;
bool centerInside ( const osg : : Vec3 & center , float radius ) ;
void explode ( ) ;
bool dangerous ( ) { return _dangerous ; }
void stop ( ) { _stopped = true ; }
bool stopped ( ) { return _stopped ; }
void setTimeToRemove ( double time ) { _timeToRemove = time ; }
double getTimeToRemove ( ) { return _timeToRemove ; }
bool needToRemove ( double time ) { return _timeToRemove > = 0.0 & & time > _timeToRemove ; }
osg : : ref_ptr < osg : : PositionAttitudeTransform > _object ;
osg : : Vec3 _velocity ;
float _mass ;
float _radius ;
bool _stopped ;
bool _dangerous ;
double _timeToRemove ;
public :
// update position and velocity
void update ( double dt ) ;
/// Set the viscosity of the fluid.
inline void setFluidViscosity ( float v )
{
_viscosity = v ;
_viscosityCoefficient = 6 * osg : : PI * _viscosity ;
}
/// Get the viscosity of the fluid.
inline float getFluidViscosity ( ) const { return _viscosity ; }
/// Set the density of the fluid.
inline void setFluidDensity ( float d )
{
_density = d ;
_densityCoefficeint = 0.2f * osg : : PI * _density ;
}
/// Get the density of the fluid.
inline float getFluidDensity ( ) const { return _density ; }
/// Set the wind vector.
inline void setWind ( const osg : : Vec3 & wind ) { _wind = wind ; }
/// Get the wind vector.
inline const osg : : Vec3 & getWind ( ) const { return _wind ; }
/// Set the acceleration vector.
inline void setAcceleration ( const osg : : Vec3 & v ) { _acceleration = v ; }
/// Get the acceleration vector.
inline const osg : : Vec3 & getAcceleration ( ) const { return _acceleration ; }
/** Set the acceleration vector to the gravity on earth (0, 0, -9.81).
The acceleration will be multiplied by the < CODE > scale < / CODE > parameter .
*/
inline void setToGravity ( float scale = 1.0f ) { _acceleration . set ( 0 , 0 , - 9.81f * scale ) ; }
/// Set the fluid parameters as for air (20<32> C temperature).
inline void setFluidToAir ( )
{
setToGravity ( 1.0f ) ;
setFluidDensity ( 1.2929f ) ;
setFluidViscosity ( 1.8e-5 f ) ;
}
/// Set the fluid parameters as for pure water (20<32> C temperature).
inline void setFluidToWater ( )
{
setToGravity ( 1.0f ) ;
setFluidDensity ( 1.0f ) ;
setFluidViscosity ( 1.002e-3 f ) ;
}
protected :
osg : : Vec3 _acceleration ;
float _viscosity ;
float _density ;
osg : : Vec3 _wind ;
float _viscosityCoefficient ;
float _densityCoefficeint ;
} ;
CatchableObject : : CatchableObject ( )
{
_stopped = false ;
_dangerous = false ;
_timeToRemove = - 1.0 ; // do not remove.
setFluidToAir ( ) ;
}
void CatchableObject : : setObject ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & center , float characterSize , const osg : : Vec3 & velocity )
{
_radius = 0.5f * characterSize ;
float Area = osg : : PI * _radius * _radius ;
float Volume = Area * _radius * 4.0f / 3.0f ;
_velocity = velocity ;
_mass = 1000.0 * Volume ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
osg : : Vec3 width ( characterSize * ( ( float ) image - > s ( ) ) / ( float ) ( image - > t ( ) ) , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , characterSize ) ;
osg : : Vec3 pos = ( width + height ) * - 0.5f ;
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_object = new osg : : PositionAttitudeTransform ;
_object - > setName ( name ) ;
_object - > addChild ( geode ) ;
_object - > setPosition ( center ) ;
}
}
void CatchableObject : : update ( double dt )
{
if ( _stopped ) return ;
float Area = osg : : PI * _radius * _radius ;
float Volume = Area * _radius * 4.0f / 3.0f ;
// compute force due to gravity + boyancy of displacing the fluid that the particle is emersed in.
osg : : Vec3 force = _acceleration * ( _mass - _density * Volume ) ;
// compute force due to friction
osg : : Vec3 relative_wind = _velocity - _wind ;
force - = relative_wind * Area * ( _viscosityCoefficient + _densityCoefficeint * relative_wind . length ( ) ) ;
// divide force by mass to get acceleration.
_velocity + = force * ( dt / _mass ) ;
_object - > setPosition ( _object - > getPosition ( ) + _velocity * dt ) ;
}
bool CatchableObject : : anyInside ( const osg : : Vec3 & lower_left , const osg : : Vec3 & upper_right )
{
osg : : Vec3 pos = _object - > getPosition ( ) ;
if ( pos . x ( ) + _radius < lower_left . x ( ) ) return false ;
if ( pos . x ( ) - _radius > upper_right . x ( ) ) return false ;
if ( pos . z ( ) + _radius < lower_left . z ( ) ) return false ;
if ( pos . z ( ) - _radius > upper_right . z ( ) ) return false ;
return true ;
}
bool CatchableObject : : centerInside ( const osg : : Vec3 & center , float radius )
{
osg : : Vec3 delta = _object - > getPosition ( ) - center ;
return ( delta . length ( ) < radius ) ;
}
void CatchableObject : : explode ( )
{
osg : : Vec3 position ( 0.0f , 0.0f , 0.0f ) ;
osgParticle : : ExplosionEffect * explosion = new osgParticle : : ExplosionEffect ( position , _radius ) ;
osgParticle : : ExplosionDebriEffect * explosionDebri = new osgParticle : : ExplosionDebriEffect ( position , _radius ) ;
osgParticle : : SmokeEffect * smoke = new osgParticle : : SmokeEffect ( position , _radius ) ;
osgParticle : : FireEffect * fire = new osgParticle : : FireEffect ( position , _radius ) ;
explosion - > setWind ( _wind ) ;
explosionDebri - > setWind ( _wind ) ;
smoke - > setWind ( _wind ) ;
fire - > setWind ( _wind ) ;
_object - > addChild ( explosion ) ;
_object - > addChild ( explosionDebri ) ;
_object - > addChild ( smoke ) ;
_object - > addChild ( fire ) ;
_dangerous = true ;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
class GameEventHandler : public osgGA : : GUIEventHandler
2005-04-07 04:54:36 +08:00
{
public :
2005-04-11 05:25:37 +08:00
GameEventHandler ( ) ;
2005-04-07 04:54:36 +08:00
2005-04-11 05:25:37 +08:00
META_Object ( osgStereImageApp , GameEventHandler ) ;
2005-04-07 04:54:36 +08:00
virtual void accept ( osgGA : : GUIEventHandlerVisitor & v ) { v . visit ( * this ) ; }
virtual bool handle ( const osgGA : : GUIEventAdapter & ea , osgGA : : GUIActionAdapter & ) ;
virtual void getUsage ( osg : : ApplicationUsage & usage ) const ;
osg : : Matrix getCameraPosition ( ) ;
osg : : Node * createScene ( ) ;
void setFOVY ( float fovy ) { _fovy = fovy ; }
float getFOVY ( ) const { return _fovy ; }
void setBackground ( const std : : string & background ) { _backgroundImageFile = background ; }
2005-04-11 05:25:37 +08:00
void createNewCatchable ( ) ;
2005-04-07 04:54:36 +08:00
protected :
2005-04-11 05:25:37 +08:00
~ GameEventHandler ( ) { }
GameEventHandler ( const GameEventHandler & , const osg : : CopyOp & ) { }
2005-04-07 04:54:36 +08:00
osg : : Vec3 _origin ;
osg : : Vec3 _width ;
osg : : Vec3 _height ;
osg : : Vec3 _originBaseLine ;
osg : : Vec3 _widthBaseLine ;
float _characterSize ;
float _fovy ;
std : : string _backgroundImageFile ;
2005-04-11 05:25:37 +08:00
osg : : ref_ptr < osg : : Group > _group ;
2005-04-07 04:54:36 +08:00
Character _player1 ;
Character _player2 ;
2005-04-11 05:25:37 +08:00
typedef std : : list < osg : : ref_ptr < CatchableObject > > CatchableObjectList ;
CatchableObjectList _catchableObjects ;
2005-04-07 04:54:36 +08:00
bool _leftKeyPressed ;
bool _rightKeyPressed ;
} ;
2005-04-11 05:25:37 +08:00
GameEventHandler : : GameEventHandler ( )
2005-04-07 04:54:36 +08:00
{
_origin . set ( 0.0f , 0.0f , 0.0f ) ;
_width . set ( 1280.0f , 0.0f , 0.0f ) ;
_height . set ( 0.0f , 0.0f , 1024.0f ) ;
_widthBaseLine = _width * 0.9f ;
_originBaseLine = _origin + _width * 0.5 - _widthBaseLine * 0.5f ;
_characterSize = _width . length ( ) * 0.2f ;
2005-04-11 05:25:37 +08:00
_backgroundImageFile = " Catch/sky1.JPG " ;
2005-04-07 04:54:36 +08:00
_leftKeyPressed = false ;
_rightKeyPressed = false ;
}
2005-04-11 05:25:37 +08:00
bool GameEventHandler : : handle ( const osgGA : : GUIEventAdapter & ea , osgGA : : GUIActionAdapter & )
2005-04-07 04:54:36 +08:00
{
switch ( ea . getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : FRAME ) :
{
2005-04-11 05:25:37 +08:00
// move characters
2005-04-07 04:54:36 +08:00
if ( _leftKeyPressed )
{
_player2 . moveLeft ( ) ;
}
if ( _rightKeyPressed )
{
_player2 . moveRight ( ) ;
}
2005-04-11 05:25:37 +08:00
static double previous_time = ea . time ( ) ;
double dt = ea . time ( ) - previous_time ;
previous_time = ea . time ( ) ;
2005-04-07 04:54:36 +08:00
2005-04-11 05:25:37 +08:00
// move objects
for ( CatchableObjectList : : iterator itr = _catchableObjects . begin ( ) ;
itr ! = _catchableObjects . end ( ) ;
+ + itr )
{
( * itr ) - > update ( dt ) ;
bool removeEntry = false ;
if ( ( * itr ) - > dangerous ( ) )
{
if ( ( * itr ) - > anyInside ( _player1 . getLowerLeft ( ) , _player1 . getUpperRight ( ) ) )
{
_player1 . looseLife ( ) ;
removeEntry = true ;
}
2005-04-13 03:17:01 +08:00
if ( ( * itr ) - > anyInside ( _player2 . getLowerLeft ( ) , _player2 . getUpperRight ( ) ) )
2005-04-11 05:25:37 +08:00
{
_player2 . looseLife ( ) ;
removeEntry = true ;
}
}
else
{
if ( ( * itr ) - > centerInside ( _player1 . getCurrentCenterOfBasket ( ) , _player1 . getCurrentRadiusOfBasket ( ) ) )
{
_player1 . addCatch ( ) ;
removeEntry = true ;
}
if ( ( * itr ) - > centerInside ( _player2 . getCurrentCenterOfBasket ( ) , _player2 . getCurrentRadiusOfBasket ( ) ) )
{
_player2 . addCatch ( ) ;
removeEntry = true ;
}
}
if ( ! ( * itr ) - > anyInside ( _origin , _origin + _width + _height ) | |
( * itr ) - > needToRemove ( ea . time ( ) ) | |
removeEntry )
{
// need to remove
// remove child from parents.
osg : : ref_ptr < osg : : PositionAttitudeTransform > child = ( * itr ) - > _object ;
osg : : Node : : ParentList parents = child - > getParents ( ) ;
for ( osg : : Node : : ParentList : : iterator pitr = parents . begin ( ) ;
pitr ! = parents . end ( ) ;
+ + pitr )
{
( * pitr ) - > removeChild ( child . get ( ) ) ;
}
// remove child from catchable list
itr = _catchableObjects . erase ( itr ) ;
createNewCatchable ( ) ;
}
else if ( ( * itr ) - > anyInside ( _origin , _origin + _width ) & & ! ( * itr ) - > stopped ( ) )
{
// hit base line
( * itr ) - > explode ( ) ;
( * itr ) - > stop ( ) ;
( * itr ) - > setTimeToRemove ( ea . time ( ) + 3.0 ) ;
}
}
2005-04-07 04:54:36 +08:00
}
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
{
if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Left )
{
_leftKeyPressed = true ;
return true ;
}
else if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Right )
{
_rightKeyPressed = true ;
return true ;
}
else if ( ea . getKey ( ) = = ' 1 ' )
{
_player1 . looseLife ( ) ;
_player1 . addCatch ( ) ;
return true ;
}
else if ( ea . getKey ( ) = = ' 2 ' )
{
_player2 . looseLife ( ) ;
_player2 . addCatch ( ) ;
return true ;
}
else if ( ea . getKey ( ) = = ' ' )
{
_player1 . reset ( ) ;
_player2 . reset ( ) ;
return true ;
}
}
case ( osgGA : : GUIEventAdapter : : KEYUP ) :
{
if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Left )
{
_leftKeyPressed = false ;
return true ;
}
else if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Right )
{
_rightKeyPressed = false ;
return true ;
}
}
case ( osgGA : : GUIEventAdapter : : DRAG ) :
case ( osgGA : : GUIEventAdapter : : MOVE ) :
{
float px = ( ea . getXnormalized ( ) + 1.0f ) * 0.5f ;
_player1 . moveTo ( px ) ;
return true ;
}
default :
return false ;
}
}
2005-04-11 05:25:37 +08:00
void GameEventHandler : : getUsage ( osg : : ApplicationUsage & ) const
2005-04-07 04:54:36 +08:00
{
}
2005-04-11 05:25:37 +08:00
osg : : Matrix GameEventHandler : : getCameraPosition ( )
2005-04-07 04:54:36 +08:00
{
osg : : Matrix cameraPosition ;
osg : : Vec3 center = _origin + ( _width + _height ) * 0.5f ;
float distance = _height . length ( ) / ( 2.0f * tanf ( _fovy * 0.5f ) ) ;
cameraPosition . makeLookAt ( center - osg : : Vec3 ( 0.0f , distance , 0.0f ) , center , osg : : Vec3 ( 0.0f , 0.0f , 1.0f ) ) ;
return cameraPosition ;
}
2005-04-11 05:25:37 +08:00
osg : : Node * GameEventHandler : : createScene ( )
2005-04-07 04:54:36 +08:00
{
2005-04-11 05:25:37 +08:00
_group = new osg : : Group ;
2005-04-13 03:28:37 +08:00
# if 1
std : : string player_one = " Catch/girl.png " ;
std : : string player_two = " Catch/boy.png " ;
# else
std : : string player_one = " Catch/gwen.png " ;
std : : string player_two = " Catch/caitlin.png " ;
# endif
_player1 . setCharacter ( player_one , " girl " , _originBaseLine + osg : : Vec3 ( 0.0f , - 1.0f , 0.0f ) , _widthBaseLine , 0.4f ) ;
_player1 . setLives ( player_one , _originBaseLine + osg : : Vec3 ( 0.0f , - 0.5f , 0.0f ) , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 3 ) ;
2005-04-11 05:25:37 +08:00
_player1 . setCatches ( " Catch/broach.png " , _originBaseLine + osg : : Vec3 ( 200.0f , - 0.5f , 0.0f ) , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 10 ) ;
_group - > addChild ( _player1 . _character . get ( ) ) ;
_group - > addChild ( _player1 . _livesSwitch . get ( ) ) ;
_group - > addChild ( _player1 . _catchSwitch . get ( ) ) ;
2005-04-13 03:28:37 +08:00
_player2 . setCharacter ( player_two , " boy " , _originBaseLine + osg : : Vec3 ( 0.0f , - 2.0f , 0.0f ) , _widthBaseLine , 0.4f ) ;
_player2 . setLives ( player_two , _originBaseLine + osg : : Vec3 ( 900.0f , - 0.5f , 000.0f ) , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 3 ) ;
2005-04-11 05:25:37 +08:00
_player2 . setCatches ( " Catch/broach.png " , _originBaseLine + osg : : Vec3 ( 1100.0f , - 0.5f , 0.0f ) , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 10 ) ;
_group - > addChild ( _player2 . _character . get ( ) ) ;
_group - > addChild ( _player2 . _livesSwitch . get ( ) ) ;
_group - > addChild ( _player2 . _catchSwitch . get ( ) ) ;
2005-04-07 04:54:36 +08:00
2005-04-11 05:25:37 +08:00
createNewCatchable ( ) ;
createNewCatchable ( ) ;
createNewCatchable ( ) ;
createNewCatchable ( ) ;
2005-04-07 04:54:36 +08:00
// background
{
osg : : Image * image = osgDB : : readImageFile ( _backgroundImageFile ) ;
if ( image )
{
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( _origin , _width , _height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
2005-04-11 05:25:37 +08:00
_group - > addChild ( geode ) ;
2005-04-07 04:54:36 +08:00
}
}
2005-04-11 05:25:37 +08:00
return _group . get ( ) ;
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
void GameEventHandler : : createNewCatchable ( )
{
float ratio = ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
float size = 100.0f * ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
float angle = osg : : PI * 0.25f + 0.5f * osg : : PI * ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
float speed = 200.0f * ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
CatchableObject * catchableObject = new CatchableObject ;
osg : : Vec3 position = _origin + _height + _width * ratio + osg : : Vec3 ( 0.0f , - 0.7f , 0.0f ) ;
osg : : Vec3 velocity ( - cosf ( angle ) * speed , 0.0f , - sinf ( angle ) * speed ) ;
//std::cout<<"angle = "<<angle<<" velocity="<<velocity<<std::endl;
catchableObject - > setObject ( " Catch/a.png " , " boy " , position , size , velocity ) ;
_catchableObjects . push_back ( catchableObject ) ;
// catchableObject->explode();
_group - > addChild ( catchableObject - > _object . get ( ) ) ;
}
2005-04-07 04:54:36 +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.
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is the example which demonstrates use node masks to create stereo images. " ) ;
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) + " [options] image_file_left_eye image_file_right_eye " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -d <float> " , " Time delay in sceonds between the display of successive image pairs when in auto advance mode. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -a " , " Enter auto advance of image pairs on start up. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -x <float> " , " Horizontal offset of left and right images. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -y <float> " , " Vertical offset of left and right images. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display this information " ) ;
// construct the viewer.
osgProducer : : Viewer viewer ( arguments ) ;
// set up the value with sensible default event handlers.
viewer . setUpViewer ( osgProducer : : Viewer : : ESCAPE_SETS_DONE ) ;
// register the handler to add keyboard and mosue handling.
2005-04-11 05:25:37 +08:00
GameEventHandler * seh = new GameEventHandler ( ) ;
2005-04-07 04:54:36 +08:00
viewer . getEventHandlerList ( ) . push_front ( seh ) ;
std : : string filename ;
if ( arguments . read ( " -b " , filename ) )
{
seh - > setBackground ( filename ) ;
}
// get details on keyboard and mouse bindings used by the viewer.
viewer . getUsage ( * arguments . getApplicationUsage ( ) ) ;
// 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 ;
}
// now the windows have been realized we switch off the cursor to prevent it
// distracting the people seeing the stereo images.
float fovy = 1.0f ;
for ( unsigned int i = 0 ; i < viewer . getCameraConfig ( ) - > getNumberOfCameras ( ) ; i + + )
{
Producer : : Camera * cam = viewer . getCameraConfig ( ) - > getCamera ( i ) ;
Producer : : RenderSurface * rs = cam - > getRenderSurface ( ) ;
rs - > useCursor ( false ) ;
fovy = osg : : DegreesToRadians ( cam - > getLensVerticalFov ( ) ) ;
}
seh - > setFOVY ( fovy ) ;
// creat the scene from the file list.
osg : : ref_ptr < osg : : Node > rootNode = seh - > createScene ( ) ;
osgDB : : writeNodeFile ( * rootNode , " test.osg " ) ;
// set the scene to render
viewer . setSceneData ( rootNode . get ( ) ) ;
// create the windows and run the threads.
viewer . realize ( ) ;
viewer . requestWarpPointer ( 0.5f , 0.5f ) ;
while ( ! viewer . done ( ) )
{
// wait for all cull and draw threads to complete.
viewer . sync ( ) ;
// update the scene by traversing it with the the update visitor which will
// call all node update callbacks and animations.
viewer . update ( ) ;
viewer . setView ( seh - > getCameraPosition ( ) ) ;
// fire off the cull and draw traversals of the scene.
viewer . frame ( ) ;
}
// wait for all cull and draw threads to complete before exit.
viewer . sync ( ) ;
return 0 ;
}