2007-06-12 22:20:16 +08:00
/* OpenSceneGraph example, osgkeyboardmouse.
*
* 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 .
*/
2007-06-03 00:23:07 +08:00
// Simple example of use of osgViewer::GraphicsWindow + Viewer
2003-12-16 00:46:06 +08:00
// example that provides the user with control over view position with basic picking.
# include <osg/Timer>
2017-04-19 17:20:01 +08:00
# include <osg/KdTree>
2005-04-08 17:45:06 +08:00
# include <osg/io_utils>
2006-06-12 22:04:40 +08:00
# include <osg/observer_ptr>
2003-12-16 00:46:06 +08:00
2006-11-01 22:41:32 +08:00
# include <osgUtil/IntersectionVisitor>
2006-11-29 00:30:38 +08:00
# include <osgUtil/PolytopeIntersector>
# include <osgUtil/LineSegmentIntersector>
2003-12-16 00:46:06 +08:00
# include <osgDB/ReadFile>
2006-01-04 00:52:06 +08:00
# include <osgDB/WriteFile>
2003-12-16 00:46:06 +08:00
2006-06-12 19:32:11 +08:00
# include <osgGA/TrackballManipulator>
# include <osgGA/StateSetManipulator>
2003-12-16 00:46:06 +08:00
2007-06-03 00:23:07 +08:00
# include <osgViewer/Viewer>
2006-11-02 20:27:15 +08:00
2006-06-12 19:32:11 +08:00
# include <osgFX/Scribe>
2003-12-16 00:46:06 +08:00
2007-01-11 23:19:59 +08:00
# include <iostream>
2006-06-12 19:32:11 +08:00
2006-06-12 22:04:40 +08:00
class CreateModelToSaveVisitor : public osg : : NodeVisitor
{
public :
CreateModelToSaveVisitor ( ) :
2014-05-14 18:19:43 +08:00
osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN )
2006-06-12 22:04:40 +08:00
{
_group = new osg : : Group ;
_addToModel = false ;
}
2014-05-14 18:19:43 +08:00
2006-06-12 22:04:40 +08:00
virtual void apply ( osg : : Node & node )
{
osgFX : : Scribe * scribe = dynamic_cast < osgFX : : Scribe * > ( & node ) ;
if ( scribe )
{
for ( unsigned int i = 0 ; i < scribe - > getNumChildren ( ) ; + + i )
{
_group - > addChild ( scribe - > getChild ( i ) ) ;
}
}
else
{
traverse ( node ) ;
}
}
2014-05-14 18:19:43 +08:00
2006-06-12 22:04:40 +08:00
osg : : ref_ptr < osg : : Group > _group ;
bool _addToModel ;
} ;
2021-12-08 21:53:53 +08:00
class SelectedNodesVisitor : public osg : : NodeVisitor
2007-01-23 22:10:10 +08:00
{
public :
2021-12-08 21:53:53 +08:00
SelectedNodesVisitor ( ) :
2014-05-14 18:19:43 +08:00
osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN )
2007-01-23 22:10:10 +08:00
{
}
2014-05-14 18:19:43 +08:00
2007-01-23 22:10:10 +08:00
virtual void apply ( osg : : Node & node )
{
osgFX : : Scribe * scribe = dynamic_cast < osgFX : : Scribe * > ( & node ) ;
if ( scribe )
{
_selectedNodes . push_back ( scribe ) ;
}
else
{
traverse ( node ) ;
}
}
2014-05-14 18:19:43 +08:00
2007-01-23 22:10:10 +08:00
void pruneSelectedNodes ( )
{
for ( SelectedNodes : : iterator itr = _selectedNodes . begin ( ) ;
itr ! = _selectedNodes . end ( ) ;
+ + itr )
{
osg : : Node * node = itr - > get ( ) ;
osg : : Node : : ParentList parents = node - > getParents ( ) ;
for ( osg : : Node : : ParentList : : iterator pitr = parents . begin ( ) ;
pitr ! = parents . end ( ) ;
+ + pitr )
{
2014-06-03 17:52:55 +08:00
( * pitr ) - > removeChild ( node ) ;
2007-01-23 22:10:10 +08:00
}
}
}
2014-05-14 18:19:43 +08:00
2021-12-08 21:53:53 +08:00
osg : : ref_ptr < osg : : Node > createSelectedNodeSubgraph ( )
{
if ( _selectedNodes . empty ( ) ) return osg : : ref_ptr < osg : : Node > ( ) ;
if ( _selectedNodes . size ( ) = = 1 ) return _selectedNodes [ 0 ] ;
// note code doesn't yet handle selected nodes being nested within transforms.
osg : : ref_ptr < osg : : Group > group ;
for ( SelectedNodes : : iterator itr = _selectedNodes . begin ( ) ;
itr ! = _selectedNodes . end ( ) ;
+ + itr )
{
group - > addChild ( * itr ) ;
}
return group ;
}
2007-01-23 22:10:10 +08:00
typedef std : : vector < osg : : ref_ptr < osgFX : : Scribe > > SelectedNodes ;
SelectedNodes _selectedNodes ;
2014-05-14 18:19:43 +08:00
2007-01-23 22:10:10 +08:00
} ;
2006-06-12 22:04:40 +08:00
// class to handle events with a pick
2014-05-14 18:19:43 +08:00
class PickHandler : public osgGA : : GUIEventHandler
2007-01-11 23:19:59 +08:00
{
2014-05-14 18:19:43 +08:00
public :
2006-06-12 22:04:40 +08:00
2006-11-02 20:27:15 +08:00
PickHandler ( ) :
2007-05-23 19:05:59 +08:00
_mx ( 0.0 ) , _my ( 0.0 ) ,
_usePolytopeIntersector ( false ) ,
2017-05-09 17:36:28 +08:00
_useWindowCoordinates ( false ) ,
2017-05-24 23:01:49 +08:00
_precisionHint ( osgUtil : : Intersector : : USE_DOUBLE_CALCULATIONS ) ,
2017-05-25 02:39:36 +08:00
_primitiveMask ( osgUtil : : PolytopeIntersector : : ALL_PRIMITIVES ) { }
2006-06-12 22:04:40 +08:00
~ PickHandler ( ) { }
2017-05-25 02:39:36 +08:00
void setPrimitiveMask ( unsigned int primitiveMask ) { _primitiveMask = primitiveMask ; }
2017-05-24 23:01:49 +08:00
2006-11-02 20:27:15 +08:00
bool handle ( const osgGA : : GUIEventAdapter & ea , osgGA : : GUIActionAdapter & aa )
2006-06-12 22:04:40 +08:00
{
2007-06-03 00:23:07 +08:00
osgViewer : : Viewer * viewer = dynamic_cast < osgViewer : : Viewer * > ( & aa ) ;
2007-01-23 22:10:10 +08:00
if ( ! viewer ) return false ;
2006-11-02 20:27:15 +08:00
2006-06-12 22:04:40 +08:00
switch ( ea . getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : KEYUP ) :
{
2007-01-23 22:10:10 +08:00
if ( ea . getKey ( ) = = ' s ' )
2006-06-12 22:04:40 +08:00
{
2006-11-02 20:27:15 +08:00
saveSelectedModel ( viewer - > getSceneData ( ) ) ;
2014-05-14 18:19:43 +08:00
}
2007-01-23 22:10:10 +08:00
else if ( ea . getKey ( ) = = ' o ' )
{
2011-06-15 00:54:20 +08:00
osg : : notify ( osg : : NOTICE ) < < " Saved model to file 'saved_model.osgt' " < < std : : endl ;
osgDB : : writeNodeFile ( * ( viewer - > getSceneData ( ) ) , " saved_model.osgt " ) ;
2007-01-23 22:10:10 +08:00
}
2021-12-08 21:53:53 +08:00
else if ( ea . getKey ( ) = = ' s ' )
{
SelectedNodesVisitor snv ;
viewer - > getSceneData ( ) - > accept ( snv ) ;
osg : : ref_ptr < osg : : Node > selected = snv . createSelectedNodeSubgraph ( ) ;
if ( selected )
{
osg : : notify ( osg : : NOTICE ) < < " Saved selected to file 'saved_selected.osgt' " < < std : : endl ;
osgDB : : writeNodeFile ( * ( viewer - > getSceneData ( ) ) , " saved_selected.osgt " ) ;
}
}
2007-05-23 19:05:59 +08:00
else if ( ea . getKey ( ) = = ' p ' )
{
_usePolytopeIntersector = ! _usePolytopeIntersector ;
if ( _usePolytopeIntersector )
{
osg : : notify ( osg : : NOTICE ) < < " Using PolytopeIntersector " < < std : : endl ;
} else {
osg : : notify ( osg : : NOTICE ) < < " Using LineSegmentIntersector " < < std : : endl ;
}
}
else if ( ea . getKey ( ) = = ' c ' )
{
_useWindowCoordinates = ! _useWindowCoordinates ;
if ( _useWindowCoordinates )
{
osg : : notify ( osg : : NOTICE ) < < " Using window coordinates for picking " < < std : : endl ;
} else {
2020-10-29 00:05:06 +08:00
osg : : notify ( osg : : NOTICE ) < < " Using projection coordinates for picking " < < std : : endl ;
2007-05-23 19:05:59 +08:00
}
}
2017-04-21 18:07:17 +08:00
else if ( ea . getKey ( ) = = ' a ' )
{
fullWindowIntersectionTest ( viewer ) ;
}
2007-01-23 22:10:10 +08:00
else if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Delete | | ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_BackSpace )
{
osg : : notify ( osg : : NOTICE ) < < " Delete " < < std : : endl ;
2021-12-08 21:53:53 +08:00
SelectedNodesVisitor dsnv ;
2007-01-23 22:10:10 +08:00
viewer - > getSceneData ( ) - > accept ( dsnv ) ;
dsnv . pruneSelectedNodes ( ) ;
2006-06-12 22:04:40 +08:00
}
return false ;
}
case ( osgGA : : GUIEventAdapter : : PUSH ) :
case ( osgGA : : GUIEventAdapter : : MOVE ) :
{
_mx = ea . getX ( ) ;
_my = ea . getY ( ) ;
return false ;
}
case ( osgGA : : GUIEventAdapter : : RELEASE ) :
{
if ( _mx = = ea . getX ( ) & & _my = = ea . getY ( ) )
{
// only do a pick if the mouse hasn't moved
2006-11-02 20:27:15 +08:00
pick ( ea , viewer ) ;
2006-06-12 22:04:40 +08:00
}
return true ;
2014-05-14 18:19:43 +08:00
}
2006-06-12 22:04:40 +08:00
default :
return false ;
}
}
2017-04-21 18:07:17 +08:00
void fullWindowIntersectionTest ( osgViewer : : Viewer * viewer )
{
osg : : ref_ptr < osgUtil : : IntersectorGroup > intersectors = new osgUtil : : IntersectorGroup ;
osg : : Viewport * viewport = viewer - > getCamera ( ) - > getViewport ( ) ;
unsigned int numX = 100 ;
unsigned int numY = 100 ;
double dx = viewport - > width ( ) / double ( numX - 1 ) ;
double dy = viewport - > width ( ) / double ( numX - 1 ) ;
double y = viewport - > x ( ) ;
for ( unsigned int r = 0 ; r < numY ; + + r )
{
double x = viewport - > x ( ) ;
for ( unsigned int c = 0 ; c < numX ; + + c )
{
2017-05-09 17:36:28 +08:00
osg : : ref_ptr < osgUtil : : Intersector > intersector ;
2017-04-21 18:07:17 +08:00
if ( _usePolytopeIntersector )
{
2017-05-24 23:01:49 +08:00
osg : : ref_ptr < osgUtil : : PolytopeIntersector > pi = new osgUtil : : PolytopeIntersector ( osgUtil : : Intersector : : WINDOW , x - dx * 0.5 , y - dy * 0.5 , x + dx * 0.5 , y + dy * 0.5 ) ;
2017-05-25 02:39:36 +08:00
pi - > setPrimitiveMask ( _primitiveMask ) ;
2017-05-24 23:01:49 +08:00
intersector = pi . get ( ) ;
2017-04-21 18:07:17 +08:00
}
else
{
2017-05-09 17:36:28 +08:00
intersector = new osgUtil : : LineSegmentIntersector ( osgUtil : : Intersector : : WINDOW , x , y ) ;
2017-04-21 18:07:17 +08:00
}
2017-05-09 17:36:28 +08:00
intersector - > setPrecisionHint ( _precisionHint ) ;
intersectors - > getIntersectors ( ) . push_back ( intersector ) ;
2017-04-21 18:07:17 +08:00
x + = dx ;
}
y + = dy ;
}
osgUtil : : IntersectionVisitor iv ( intersectors . get ( ) ) ;
osg : : ElapsedTime elapsedTime ;
viewer - > getCamera ( ) - > accept ( iv ) ;
OSG_NOTICE < < " Intersection traversal took " < < elapsedTime . elapsedTime_m ( ) < < " ms for " < < intersectors - > getIntersectors ( ) . size ( ) < < " intersectors " < < std : : endl ;
}
2007-06-03 00:23:07 +08:00
void pick ( const osgGA : : GUIEventAdapter & ea , osgViewer : : Viewer * viewer )
2006-06-12 22:04:40 +08:00
{
2006-11-02 20:27:15 +08:00
osg : : Node * scene = viewer - > getSceneData ( ) ;
2006-06-12 22:04:40 +08:00
if ( ! scene ) return ;
2006-11-02 23:50:04 +08:00
osg : : notify ( osg : : NOTICE ) < < std : : endl ;
2006-11-01 22:41:32 +08:00
2006-11-02 23:50:04 +08:00
osg : : Node * node = 0 ;
osg : : Group * parent = 0 ;
2006-11-01 22:41:32 +08:00
2017-04-19 17:20:01 +08:00
2007-05-23 19:05:59 +08:00
if ( _usePolytopeIntersector )
2006-11-02 23:50:04 +08:00
{
2007-05-23 19:05:59 +08:00
osgUtil : : PolytopeIntersector * picker ;
if ( _useWindowCoordinates )
{
// use window coordinates
// remap the mouse x,y into viewport coordinates.
osg : : Viewport * viewport = viewer - > getCamera ( ) - > getViewport ( ) ;
double mx = viewport - > x ( ) + ( int ) ( ( double ) viewport - > width ( ) * ( ea . getXnormalized ( ) * 0.5 + 0.5 ) ) ;
double my = viewport - > y ( ) + ( int ) ( ( double ) viewport - > height ( ) * ( ea . getYnormalized ( ) * 0.5 + 0.5 ) ) ;
// half width, height.
double w = 5.0f ;
double h = 5.0f ;
picker = new osgUtil : : PolytopeIntersector ( osgUtil : : Intersector : : WINDOW , mx - w , my - h , mx + w , my + h ) ;
} else {
double mx = ea . getXnormalized ( ) ;
double my = ea . getYnormalized ( ) ;
double w = 0.05 ;
double h = 0.05 ;
picker = new osgUtil : : PolytopeIntersector ( osgUtil : : Intersector : : PROJECTION , mx - w , my - h , mx + w , my + h ) ;
}
2017-05-09 17:36:28 +08:00
picker - > setPrecisionHint ( _precisionHint ) ;
2017-05-25 02:39:36 +08:00
picker - > setPrimitiveMask ( _primitiveMask ) ;
2017-05-09 17:36:28 +08:00
2006-11-02 23:50:04 +08:00
osgUtil : : IntersectionVisitor iv ( picker ) ;
2017-04-19 17:20:01 +08:00
osg : : ElapsedTime elapsedTime ;
2006-11-02 23:50:04 +08:00
viewer - > getCamera ( ) - > accept ( iv ) ;
2006-11-02 20:27:15 +08:00
2017-04-19 17:20:01 +08:00
OSG_NOTICE < < " PoltyopeIntersector traversal took " < < elapsedTime . elapsedTime_m ( ) < < " ms " < < std : : endl ;
2006-11-02 23:50:04 +08:00
if ( picker - > containsIntersections ( ) )
{
2007-12-09 00:37:05 +08:00
osgUtil : : PolytopeIntersector : : Intersection intersection = picker - > getFirstIntersection ( ) ;
2006-11-02 23:50:04 +08:00
2007-12-09 00:37:05 +08:00
osg : : notify ( osg : : NOTICE ) < < " Picked " < < intersection . localIntersectionPoint < < std : : endl
< < " Distance to ref. plane " < < intersection . distance
< < " , max. dist " < < intersection . maxDistance
< < " , primitive index " < < intersection . primitiveIndex
< < " , numIntersectionPoints "
< < intersection . numIntersectionPoints
< < std : : endl ;
2006-11-02 23:50:04 +08:00
2007-12-09 00:37:05 +08:00
osg : : NodePath & nodePath = intersection . nodePath ;
node = ( nodePath . size ( ) > = 1 ) ? nodePath [ nodePath . size ( ) - 1 ] : 0 ;
parent = ( nodePath . size ( ) > = 2 ) ? dynamic_cast < osg : : Group * > ( nodePath [ nodePath . size ( ) - 2 ] ) : 0 ;
2006-11-02 23:50:04 +08:00
2014-05-14 18:19:43 +08:00
if ( node ) std : : cout < < " Hits " < < node - > className ( ) < < " nodePath size " < < nodePath . size ( ) < < std : : endl ;
2007-12-09 00:37:05 +08:00
toggleScribe ( parent , node ) ;
2006-11-02 23:50:04 +08:00
}
}
else
2006-11-01 22:41:32 +08:00
{
2007-05-23 19:05:59 +08:00
osgUtil : : LineSegmentIntersector * picker ;
if ( ! _useWindowCoordinates )
{
// use non dimensional coordinates - in projection/clip space
picker = new osgUtil : : LineSegmentIntersector ( osgUtil : : Intersector : : PROJECTION , ea . getXnormalized ( ) , ea . getYnormalized ( ) ) ;
} else {
// use window coordinates
// remap the mouse x,y into viewport coordinates.
osg : : Viewport * viewport = viewer - > getCamera ( ) - > getViewport ( ) ;
float mx = viewport - > x ( ) + ( int ) ( ( float ) viewport - > width ( ) * ( ea . getXnormalized ( ) * 0.5f + 0.5f ) ) ;
float my = viewport - > y ( ) + ( int ) ( ( float ) viewport - > height ( ) * ( ea . getYnormalized ( ) * 0.5f + 0.5f ) ) ;
picker = new osgUtil : : LineSegmentIntersector ( osgUtil : : Intersector : : WINDOW , mx , my ) ;
}
2017-05-09 17:36:28 +08:00
picker - > setPrecisionHint ( _precisionHint ) ;
2006-11-02 23:50:04 +08:00
osgUtil : : IntersectionVisitor iv ( picker ) ;
2006-11-01 22:41:32 +08:00
2017-04-19 17:20:01 +08:00
osg : : ElapsedTime elapsedTime ;
2006-11-02 23:50:04 +08:00
viewer - > getCamera ( ) - > accept ( iv ) ;
2006-11-01 22:41:32 +08:00
2017-04-19 17:20:01 +08:00
OSG_NOTICE < < " LineSegmentIntersector traversal took " < < elapsedTime . elapsedTime_m ( ) < < " ms " < < std : : endl ;
2006-11-02 23:50:04 +08:00
if ( picker - > containsIntersections ( ) )
2006-11-01 22:41:32 +08:00
{
2006-11-02 23:50:04 +08:00
osgUtil : : LineSegmentIntersector : : Intersection intersection = picker - > getFirstIntersection ( ) ;
2017-05-31 06:38:25 +08:00
osg : : notify ( osg : : NOTICE ) < < " Picked " < < intersection . localIntersectionPoint < < std : : endl
< < " primitive index " < < intersection . primitiveIndex
< < std : : endl ;
2006-11-01 22:41:32 +08:00
2006-11-02 23:50:04 +08:00
osg : : NodePath & nodePath = intersection . nodePath ;
node = ( nodePath . size ( ) > = 1 ) ? nodePath [ nodePath . size ( ) - 1 ] : 0 ;
parent = ( nodePath . size ( ) > = 2 ) ? dynamic_cast < osg : : Group * > ( nodePath [ nodePath . size ( ) - 2 ] ) : 0 ;
2006-11-01 22:41:32 +08:00
2006-11-02 23:50:04 +08:00
if ( node ) std : : cout < < " Hits " < < node - > className ( ) < < " nodePath size " < < nodePath . size ( ) < < std : : endl ;
2007-05-23 19:05:59 +08:00
toggleScribe ( parent , node ) ;
2006-11-02 23:50:04 +08:00
}
2014-05-14 18:19:43 +08:00
}
2006-11-02 23:50:04 +08:00
// now we try to decorate the hit node by the osgFX::Scribe to show that its been "picked"
2007-05-23 19:05:59 +08:00
}
2006-11-02 23:50:04 +08:00
2007-05-23 19:05:59 +08:00
void toggleScribe ( osg : : Group * parent , osg : : Node * node ) {
if ( ! parent | | ! node ) return ;
2006-11-02 23:50:04 +08:00
2007-05-23 19:05:59 +08:00
std : : cout < < " parent " < < parent - > className ( ) < < std : : endl ;
osgFX : : Scribe * parentAsScribe = dynamic_cast < osgFX : : Scribe * > ( parent ) ;
if ( ! parentAsScribe )
{
// node not already picked, so highlight it with an osgFX::Scribe
osgFX : : Scribe * scribe = new osgFX : : Scribe ( ) ;
scribe - > addChild ( node ) ;
parent - > replaceChild ( node , scribe ) ;
}
else
{
// node already picked so we want to remove scribe to unpick it.
osg : : Node : : ParentList parentList = parentAsScribe - > getParents ( ) ;
for ( osg : : Node : : ParentList : : iterator itr = parentList . begin ( ) ;
itr ! = parentList . end ( ) ;
+ + itr )
2006-11-02 23:50:04 +08:00
{
2007-05-23 19:05:59 +08:00
( * itr ) - > replaceChild ( parentAsScribe , node ) ;
2006-11-01 22:41:32 +08:00
}
}
2007-05-23 19:05:59 +08:00
2006-06-12 22:04:40 +08:00
}
2006-11-02 20:27:15 +08:00
void saveSelectedModel ( osg : : Node * scene )
2006-06-12 22:04:40 +08:00
{
2006-11-02 20:27:15 +08:00
if ( ! scene ) return ;
2014-05-14 18:19:43 +08:00
2006-06-12 22:04:40 +08:00
CreateModelToSaveVisitor cmtsv ;
2006-11-02 20:27:15 +08:00
scene - > accept ( cmtsv ) ;
2014-05-14 18:19:43 +08:00
2006-06-12 22:04:40 +08:00
if ( cmtsv . _group - > getNumChildren ( ) > 0 )
{
2020-10-29 00:05:06 +08:00
std : : cout < < " Writing selected components to 'selected_model.osgt' " < < std : : endl ;
2011-06-15 00:54:20 +08:00
osgDB : : writeNodeFile ( * cmtsv . _group , " selected_model.osgt " ) ;
2006-06-12 22:04:40 +08:00
}
}
2017-05-09 17:36:28 +08:00
void setPrecisionHint ( osgUtil : : Intersector : : PrecisionHint hint ) { _precisionHint = hint ; }
2006-06-12 22:04:40 +08:00
protected :
float _mx , _my ;
2007-05-23 19:05:59 +08:00
bool _usePolytopeIntersector ;
bool _useWindowCoordinates ;
2017-05-09 17:36:28 +08:00
osgUtil : : Intersector : : PrecisionHint _precisionHint ;
2017-05-25 02:39:36 +08:00
unsigned int _primitiveMask ;
2017-05-09 17:36:28 +08:00
2006-06-12 22:04:40 +08:00
} ;
2017-05-09 18:33:22 +08:00
class ConvertPrimitives : public osg : : NodeVisitor
{
public :
osg : : PrimitiveSet : : Mode _mode ;
ConvertPrimitives ( osg : : PrimitiveSet : : Mode mode ) :
osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN ) ,
_mode ( mode ) { }
void apply ( osg : : Geometry & geometry )
{
if ( ! geometry . getVertexArray ( ) ) return ;
unsigned int numVertices = geometry . getVertexArray ( ) - > getNumElements ( ) ;
if ( _mode = = osg : : PrimitiveSet : : POINTS )
{
// remove previous primitive sets.
geometry . removePrimitiveSet ( 0 , geometry . getNumPrimitiveSets ( ) ) ;
geometry . addPrimitiveSet ( new osg : : DrawArrays ( _mode , 0 , numVertices ) ) ;
}
else if ( _mode = = osg : : PrimitiveSet : : LINES )
{
geometry . removePrimitiveSet ( 0 , geometry . getNumPrimitiveSets ( ) ) ;
geometry . addPrimitiveSet ( new osg : : DrawArrays ( _mode , 0 , numVertices ) ) ;
}
}
} ;
2003-12-16 00:46:06 +08:00
int main ( int argc , char * * argv )
{
2017-04-19 17:20:01 +08:00
osg : : ArgumentParser arguments ( & argc , argv ) ;
2017-04-22 02:34:22 +08:00
osgViewer : : Viewer viewer ( arguments ) ;
2017-04-19 17:20:01 +08:00
bool useKdTree = false ;
while ( arguments . read ( " --kdtree " ) ) { useKdTree = true ; }
2014-05-14 18:19:43 +08:00
2017-05-09 17:36:28 +08:00
osg : : ref_ptr < PickHandler > pickhandler = new PickHandler ;
while ( arguments . read ( " --double " ) ) { pickhandler - > setPrecisionHint ( osgUtil : : Intersector : : USE_DOUBLE_CALCULATIONS ) ; }
while ( arguments . read ( " --float " ) ) { pickhandler - > setPrecisionHint ( osgUtil : : Intersector : : USE_FLOAT_CALCULATIONS ) ; }
2017-04-19 17:20:01 +08:00
2017-05-25 02:39:36 +08:00
unsigned int mask = osgUtil : : PolytopeIntersector : : ALL_PRIMITIVES ;
while ( arguments . read ( " --prim-mask " , mask ) | | arguments . read ( " --pm " , mask ) ) { pickhandler - > setPrimitiveMask ( mask ) ; }
2017-05-24 23:01:49 +08:00
2017-04-19 17:20:01 +08:00
// load model
osg : : ref_ptr < osg : : Node > loadedModel = osgDB : : readRefNodeFiles ( arguments ) ;
2014-05-14 18:19:43 +08:00
2007-06-08 23:11:04 +08:00
// if not loaded assume no arguments passed in, try use default mode instead.
2015-10-22 21:42:19 +08:00
if ( ! loadedModel ) loadedModel = osgDB : : readRefNodeFile ( " dumptruck.osgt " ) ;
2014-05-14 18:19:43 +08:00
if ( ! loadedModel )
2003-12-16 00:46:06 +08:00
{
std : : cout < < argv [ 0 ] < < " : No data loaded. " < < std : : endl ;
return 1 ;
}
2014-05-14 18:19:43 +08:00
2017-05-09 18:33:22 +08:00
while ( arguments . read ( " --points " ) ) { ConvertPrimitives cp ( osg : : PrimitiveSet : : POINTS ) ; loadedModel - > accept ( cp ) ; }
while ( arguments . read ( " --lines " ) ) { ConvertPrimitives cp ( osg : : PrimitiveSet : : LINES ) ; loadedModel - > accept ( cp ) ; }
2017-04-19 17:20:01 +08:00
if ( useKdTree )
{
2017-05-10 16:19:29 +08:00
OSG_NOTICE < < " Building KdTrees " < < std : : endl ;
2017-04-19 17:20:01 +08:00
osg : : ref_ptr < osg : : KdTreeBuilder > builder = new osg : : KdTreeBuilder ;
loadedModel - > accept ( * builder ) ;
}
2017-05-09 18:33:22 +08:00
2017-04-22 02:34:22 +08:00
// assign the scene graph to viewer
2015-10-22 21:42:19 +08:00
viewer . setSceneData ( loadedModel ) ;
2014-05-14 18:19:43 +08:00
2006-06-12 19:32:11 +08:00
// create a tracball manipulator to move the camera around in response to keyboard/mouse events
2006-09-26 00:25:53 +08:00
viewer . setCameraManipulator ( new osgGA : : TrackballManipulator ) ;
2006-06-12 19:32:11 +08:00
2007-06-03 00:23:07 +08:00
osg : : ref_ptr < osgGA : : StateSetManipulator > statesetManipulator = new osgGA : : StateSetManipulator ( viewer . getCamera ( ) - > getStateSet ( ) ) ;
2006-09-26 00:25:53 +08:00
viewer . addEventHandler ( statesetManipulator . get ( ) ) ;
2003-12-16 00:46:06 +08:00
2006-09-26 00:25:53 +08:00
// add the pick handler
2017-05-09 17:36:28 +08:00
viewer . addEventHandler ( pickhandler . get ( ) ) ;
2006-06-12 19:32:11 +08:00
2007-06-03 00:23:07 +08:00
viewer . realize ( ) ;
2006-06-12 19:32:11 +08:00
2003-12-16 00:46:06 +08:00
// main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
2007-06-03 00:23:07 +08:00
while ( ! viewer . done ( ) )
2003-12-16 00:46:06 +08:00
{
2007-06-03 00:23:07 +08:00
viewer . frame ( ) ;
2003-12-16 00:46:06 +08:00
}
return 0 ;
}