Added Geoff Michel's osgpick and osgUtil::PickVisitor code.

This commit is contained in:
Robert Osfield 2003-04-13 13:26:41 +00:00
parent 5ecc25540c
commit 026dc2cbb7
15 changed files with 762 additions and 50 deletions

View File

@ -328,7 +328,8 @@ endif
#### MacOS X specific definitions
ifeq ($(OS),Darwin)
C++ = c++
INC +=
INC += -I/usr/X11R6/include
LDFLAGS += -L/usr/X11R6/lib
DEF += -Wall -D__DARWIN_OSX__
OPTF = -O2
DBGF = -g -DOSG_COMPILE_UNIT_TESTS
@ -343,7 +344,7 @@ ifeq ($(OS),Darwin)
FREETYPE_LIB = -lfreetype
CARBON_LIB = -framework Carbon
GL_LIBS = -framework OpenGL $(CARBON_LIB)
X_LIBS =
X_LIBS = -lX11
SOCKET_LIBS =
OTHER_LIBS = -lm -lstdc++ -lobjc
LIB_EXT = dylib

View File

@ -119,6 +119,7 @@ EXAMPLE_DIRS = \
osgmultitexture\
osgoccluder\
osgparticle\
osgpick\
osgprerender\
osgreflect\
osgscribe\

View File

@ -1143,6 +1143,33 @@ Package=<4>
###############################################################################
Project: "Example osgpick"=.\examples\osgpick\osgpick.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name Core osg
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgDB
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgGA
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgProducer
End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgUtil
End Project Dependency
}}}
###############################################################################
Project: "Example osgwindows"=.\examples\osgwindows\osgwindows.dsp - Package Owner=<4>
Package=<5>

View File

@ -0,0 +1,190 @@
# Microsoft Developer Studio Project File - Name="Example osgpick" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=Example osgpick - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "osgpick.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "osgpick.mak" CFG="Example osgpick - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Example osgpick - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Example osgpick - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Example osgpick - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 opengl32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgpick.exe" /libpath:"../../../lib"
!ELSEIF "$(CFG)" == "Example osgpick - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /FR /YX /FD /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgpickd.exe" /pdbtype:sept /libpath:"../../../lib"
# SUBTRACT LINK32 /incremental:no
!ENDIF
# Begin Target
# Name "Example osgpick - Win32 Release"
# Name "Example osgpick - Win32 Debug"
# Begin Source File
SOURCE=..\..\..\examples\osgpick\osgpick.cpp
# End Source File
# End Target
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Project

View File

@ -30,7 +30,7 @@
<ul>
<li>Open scene graph .osg demo data set can downloaded here:</li>
<i><a href="http://www.openscenegraph.org/download/data/OpenSceneGraph-Data-0.9.1.tar.gz">http://www.openscenegraph.org/download/data/OpenSceneGraph-Data-0.9.1.tar.gz</a></i>
<i><a href="http://www.openscenegraph.org/download/data/OpenSceneGraph-Data-0.9.4.tar.gz">http://www.openscenegraph.org/download/data/OpenSceneGraph-Data-0.9.4.tar.gz</a></i>
<br>
<br>
@ -40,7 +40,7 @@
<br>
<br>
<li>Terrain models in OpenFlight .flt format at Grime:</li>
<a href="http://www.grime.net">http://www.grime.net</a>
<a href="http://www.grime.net/Downloads/simulations.htm">http://www.grime.net</a>
<br>
<br>
@ -58,11 +58,6 @@
<i><a href="http://www.3drocketfuel.com">http://www.3drocketfuel.com</a></i>
<br>
<br>
<li>Vehicle models in OpenFlight .flt format at Full Sail (spinnercar & veritech):</li>
<a href="http://www.fullsail.com/loader/models.html">http://www.fullsail.com/loader/models.html</a>
</ul>
</body>

View File

@ -36,20 +36,11 @@
<h2>
<u>Compiling and installing the OpenSceneGraph</u></h2>
The scene graph depends upon Standard C++, STL and OpenGL so you need a
C++ compiler up to the task and OpenGL or Mesa installed. The viewer depends
upon Producer which you'll need to download and install from the Producer website.
The OSG has it own native ascii file format, and .rgb image reader inbuilt
C++ compiler up to the task and OpenGL or Mesa installed. The example applications depend
upon Open Producer which you'll need to download and install from the Producer website.
The OSG has it own native ascii file format, and .rgb image reader
which allows you read the example data with any dependencies other than
C++, STL and OpenGL.
<p>The osgText library adds the dependency of the freetype library for
support of true type fonts, however it is not essential to the core library,
so you can comment it out from compilation by modifying the src/Makefile,
and examples/Makefile. I you wish to use fonts then you can download freetype
from www.freetype.org. The osgText library also requires an up to date
GLU implementation which supports GLU1.2 tessellation routines. If you
your current GLU is out of date you'll need to download the latest, for
instance the sgi's sample implementation for GLU from the www.opengl.org
website.
<p>The OSG also has a set of plug-ins which support non-native 3d database
and image formats, several have no dependencies on external libraries (flt,3ds,obj,
lwo,dw, tga &amp; pic), while others (pfb,jpeg,gif,tiff) require other

View File

@ -71,7 +71,7 @@ scientific and commercial visualization, training through to modeling programs.
<h3>
<u>Why use a Scene Graph - Performance, Productivity, Portability and Scalability</u>.</h3>
<ol><i>Performance</i> - scene graphs provide an excellent framework for
<ol><b><i>Performance</i></b> - scene graphs provide an excellent framework for
maximizing graphics performance. A good scene graph employs two key techniques
- culling of the objects that won't be seen on screen, and state sorting
of properties such as textures and materials, so that all similar objects
@ -83,7 +83,7 @@ with just a few operations! Without state sorting, the the buses and GPU
will thrash between states, stalling the graphics pipeline and destroying graphics
througput. As GPU's get faster and faster, the cost of stalling the graphics
is also going up, so scene graphs are becoming ever more important.
<p><i>Productivity</i> - scene graphs take away much of the hard work required
<p><b><i>Productivity</i></b> - scene graphs take away much of the hard work required
to develop high performance graphics applications. The scene graph manages
all the graphics for you, reducing what would be thousands of lines of
OpenGL down to a few simple calls. Furthermore, one of most powerful concepts
@ -96,12 +96,12 @@ helping users set up and manage graphics windows to importing of 3d models
and images. All this together allows the user to achieve a great deal with
very little coding. A dozen lines of code can be enough to load your data
and create an interactive viewer!
<p><i>Portability</i> - scene graphs encapsulate much of the lower level
<p><b><i>Portability</i></b> - scene graphs encapsulate much of the lower level
tasks of rendering graphics and reading and writing data, reducing or even
eradicating the platform specific coding that you require in your own application.
If the underlying scene graph is portable then moving from platform to
platform can be as simple as recompiling your source code.
<p><i>Scalability</i> - along with being able to dynamic manage the complexity
<p><b><i>Scalability</i></b> - along with being able to dynamic manage the complexity
of scenes automatically to account for differences in graphics performance
across a range of machines, scene graphs also make it much easier to manage
complex hardware configurations, such as clusters of graphics machines,
@ -123,7 +123,7 @@ development model to provide a development library that is legacy free
and well focused on the solving the task. The OpenSceneGraph delivers on
the four key benefits of scene graph technology outlined above using the
following features:
<ol><i>Performance</i> - supports view frustum culling, occlusion culling, small feature culling,
<ol><b><i>Performance</i></b> - supports view frustum culling, occlusion culling, small feature culling,
Level Of Detail (LOD) nodes, state sorting, vertex arrays and display
lists as part of the core scene graph. These together make the OpenSceneGraph
one of the highest performance scene graph available. User feedback is that
@ -134,7 +134,7 @@ of Detail (CLOD) meshes on top the scene graph. These allow the visualization
of massive terrain databases interactively, examples of this approach can
be found at Vterrain.org and TerrainEngine.com, both of which integrate
with the OpenSceneGraph.
<p><i>Productivity</i> - by combining lessons learned from established
<p><b><i>Productivity</i></b> - by combining lessons learned from established
scene graphs like Performer and Open Inventor, with modern software engineering
boosts like Design Patterns, along with a great deal of feedback early on
in the development cycle, it has been possible to design a library that is
@ -143,7 +143,7 @@ to the OpenSceneGraph and to integrate it with their own applications. With
a full feature set in the core scene graph, utilities to set up the scene
graph and viewers and a wide range of loaders it is possible to create
an application and bring in user data with a very small amount of code.
<p><i>Portability</i> - The core scene graph has also been designed to
<p><b><i>Portability</i></b> - The core scene graph has also been designed to
have minimal dependency on any specific platform, requiring little more than
Standard C++ and OpenGL. This has allowed the scene graph to be rapidly
ported to a wide range of platforms - originally developed on IRIX, then
@ -154,7 +154,7 @@ In the distribution there is already the osgProducer library, and in the Bazaar
found at openscenegrph.org/download/ one can find examples of applications
written on top of Qt, MFC, WxWindows and SDL. Users have also integrated it
with Motif, and X.
<p><i>Scalability</i> - the scene graph will not only run on portables all
<p><b><i>Scalability</i></b> - the scene graph will not only run on portables all
the way up to Onyx Infinite Reality Monsters, it supports the multiple
graphics subsystems found on machines like a mulitpipe Onyx. This is
possible because the core scene graph supports multiple graphics contexts
@ -162,10 +162,10 @@ for both OpenGL Display Lists and texture objects, and the cull and draw
traversals have been designed to cache rendering data locally and use the
scene graph almost entirely as a read-only operation. This allows multiple
cull-draw pairs to run on multiple CPU's which are bound to multiple graphics
subsystems. This has been demonstrated using the OpenSceneGraph in conjunction
with SGI's OpenGL multipipe SDK. We also have osgMP in development, which
will be cross platform and will transparently support multiple multipipe systems
like the Onyx and graphics clusters</ol>
subsystems. Support for multiple graphic context and multi-threading is all
available out of the box via osgProducer - all the examples in the distribution
can run multi-pipe just by use a simple configuation file.</ol>
All the source to the OSG is published under the GNU Lesser General Public License
(LGPL) which allows both open source and closed source projects to use,
modify and distribute it freely as long its usage complies with the LGPL.
@ -180,7 +180,7 @@ the contributions of the rest of the community, but this hasn't impacted
the quality of the source or support which once you get stuck in you grow
to appreciate.
<p>The project is currently in beta, which means the main core features are now in
place, with a 1.0 release in fall 2002. Despite the beta development status,
place, with a 1.0 release in second half of 2003. Despite the beta development status,
the project has already earned the reputation the leading open source scene
graph, and is establishing itself as a viable alternative to the commercial
scene graphs. Numerous companies, university researchers and graphics enthusiasts
@ -211,15 +211,15 @@ instructions for how to get the OpenSceneGraph compiling and installed
on your system. You may also need to download libraries that parts of the
OpenSceneGraph depend upon, such as Producer. Check the <a href="dependencies.html">dependencies</a>
list for further details.
<p>For full instructions of how to run the demos read the <a href="examples.html">demos</a>
<p>For full instructions of how to run the examples read the <a href="examples.html">examples</a>
page.
<br>
<hr>
<h3>
<u>Learning how to use the OpenSceneGraph</u></h3>
The OpenSceneGraph distribution comes with a reference guide for each of
the component libraries - osg, osgDB, osgUtil, osgText, osgParticle and osgProducer, a set
of demos - the source of which can be found in examples. For questions
the component libraries - osg, osgDB, osgUtil, osgText, osgSim, osgParticle and osgProducer, a set
of examples - the source of which can be found in examples. For questions
or help which can't be easily be answered by the reference guide and demo
source, one should join the mailing list (details below). There are also
the beginnings of a <a href="http://www.c2.com/cgi/wiki?OpenSceneGraphFaq">Wiki

View File

@ -37,7 +37,7 @@
<u>Plans for future developments</u></h2>
Now we have reached the beta phase (0.9.x) of OpenScenegGraph project,
and are now working towards the full 1.0 release, with a likely
release date in fall 2002.
release date in second half of 2003.
<h3>
Fturue work include:</h3>
@ -45,28 +45,27 @@ Fturue work include:</h3>
<ul>
<li>
Multi-pass fallback for when multi-texturing is not supported.</li>
StateSet composite structure for managing multi-pass effects and alternate rendering implemations.
This will allow one to manage the use of extensions and provide effecient fallback rendering paths.</li>
<li>
Clean up the API for managing multi-stage and multi-pass rendering within
the scene graph.</li>
<li>
Open Producer - cross platform library for transparently managing mulitpipe and
cluster graphics systems. Similar in concept to OpenGL multipipe SDK, except
cross platform and with support of graphics clusters.</li>
Support for clustering in Open Producer and osgProducer.</li>
<li>
osgSim - cross platform library for the visual simulation market with support for light points,
small target anti-aliasing, geometry correction and clip mapping.</li>
Enhance osgDB and plugins to allow them to be used with alternate input streams. Add support for native binary
file format for rapid loading and saving of scene graphs.
</li>
<li>
Replace osgProducer with Open Producer for the demos. Open Producer is a much cleaner and more scalable
windowing API. Move osgProducer out of the distribution and into the bazaar.</li>
Development of virtual texture support for rendering in real-time massive images, such as whole earth textures.</li>
<li>
Introduce a new library osgEnv/osgShapes, which adds support for creating
shapes and environmental effects such as stars, planets, cloud layers and
Introduce a new library osgEnvironment, which adds support for creating
shapes and environmental effects such as stars, planets, cloud layers, oceans and
ground planes.</li>
<li>

View File

@ -147,7 +147,7 @@ int main( int argc, char **argv )
cg.setSceneData(loadedModel.get());
Producer::Trackball tb;
tb.setOrientation( Producer::Trackball::Y_UP );
tb.setOrientation( Producer::Trackball::Z_UP );
// create the windows and run the threads.
cg.realize();
@ -156,7 +156,7 @@ int main( int argc, char **argv )
while( !kbmcb.done() )
{
// syncronize to screen refresh.
// syncronize to the when cull and draw threads have completed.
cg.sync();
// update the scene by traversing it with the the update visitor which will
@ -171,6 +171,10 @@ int main( int argc, char **argv )
// fire off the cull and draw traversals of the scene.
cg.frame();
}
// syncronize to the when cull and draw threads have completed.
cg.sync();
return 0;
}

View File

@ -0,0 +1,19 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgpick.cpp\
LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
INSTFILES = \
$(CXXFILES)\
GNUmakefile.inst=GNUmakefile
EXEC = osgpick
INC += $(PRODUCER_INCLUDE_DIR)
LDFLAGS += $(PRODUCER_LIB_DIR)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,14 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgpick.cpp\
LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
EXEC = osgpick
INC += $(PRODUCER_INCLUDE_DIR)
LDFLAGS += $(PRODUCER_LIB_DIR)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,289 @@
/* -*-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.
*/
/* osgpick sample
* demonstrate use of osgUtil/PickVisitor for picking in a HUD or
* in a 3d scene,
*/
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgProducer/Viewer>
#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Projection>
#include <osg/MatrixTransform>
#include <osgText/Text>
#include <osgUtil/PickVisitor>
// class to handle events with a pick
class PickHandler : public osgGA::GUIEventHandler {
public:
PickHandler(osgProducer::OsgCameraGroup* cg,osgText::Text* updateText):
_cg(cg),
_updateText(updateText) {}
~PickHandler() {}
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
virtual void pick(const osgGA::GUIEventAdapter& ea);
void setLabel(const std::string& name)
{
if (_updateText.get()) _updateText->setText(name);
}
protected:
osgProducer::OsgCameraGroup *_cg;
osg::ref_ptr<osgText::Text> _updateText;
};
bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
{
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::FRAME):
{
pick(ea);
}
return false;
default:
return false;
}
}
void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
{
// OK here is the interesting bit - How To Pick a Geode
// including geodes in a HUD under a Projection Matrix
osg::Node *scene=_cg->getSceneData();//main node of the scene.
if (scene)
{
float x=ea.getXnormalized();
float y=ea.getYnormalized();
osgUtil::PickVisitor iv;
const float *matView;
const float *matProj;
Producer::Camera *cmm=_cg->getCamera(0);
matView=cmm->getViewMatrix();
matProj=cmm->getProjectionMatrix();
osg::Matrix vum;
vum.set(matView);
vum.postMult(osg::Matrix(matProj));
osg::Matrix windowmatrix=osg::Matrix::translate(1.0f,1.0f,1.0f)*
osg::Matrix::scale(0.5f,0.5f,0.5f);
vum.postMult(windowmatrix);
osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, x,y);
std::string gdlist="";
if (iv.hits())
{
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
hitr!=hlist.end();
++hitr)
{
//osg::Vec3 ip = hitr->getLocalIntersectPoint();
//osg::Vec3 in = hitr->getLocalIntersectNormal();
osg::Geode* geode = hitr->_geode.get();
// the geodes are identified by name.
if (geode) {
gdlist=gdlist+" "+geode->getName();
}
}
}
setLabel(gdlist);
}
}
osg::Node* createHUD(osgText::Text* updateText)
{ // create the hud. derived from osgHud.cpp
// adds a set of quads, each in a separate Geode - which can be picked individually
// eg to be used as a menuing/help system!
// Can pick texts too!
osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
modelview_abs->setMatrix(osg::Matrix::identity());
osg::Projection* projection = new osg::Projection;
projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
projection->addChild(modelview_abs);
std::string timesFont("fonts/times.ttf");
// turn lighting off for the text and disable depth test to ensure its always ontop.
osg::Vec3 position(150.0f,800.0f,0.0f);
osg::Vec3 delta(0.0f,-60.0f,0.0f);
{
osg::Geode* geode = new osg::Geode();
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
geode->setName("simple");
modelview_abs->addChild(geode);
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
text->setFont(timesFont);
text->setText("Picking in Head Up Displays is simple !=]");
text->setPosition(position);
position += delta;
}
for (int i=0; i<5; i++) {
osg::Vec3 dy(0.0f,-30.0f,0.0f);
osg::Vec3 dx(120.0f,0.0f,0.0f);
osg::Geode* geode = new osg::Geode();
osg::StateSet* stateset = geode->getOrCreateStateSet();
const char *opts[]={"One", "Two", "Three", "January", "Feb", "2003"};
osg::Geometry *quad=new osg::Geometry;
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
std::string name="subOption";
name += " ";
name += std::string(opts[i]);
geode->setName(name);
osg::Vec3Array* vertices = new osg::Vec3Array(4); // 1 quad
osg::Vec4Array* colors = new osg::Vec4Array;
colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(0.8-0.1*i,0.1*i,0.2*i, 1.0));
quad->setColorArray(colors);
quad->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
(*vertices)[0]=position;
(*vertices)[1]=position+dx;
(*vertices)[2]=position+dx+dy;
(*vertices)[3]=position+dy;
quad->setVertexArray(vertices);
quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
geode->addDrawable(quad);
modelview_abs->addChild(geode);
position += delta;
}
{ // this displays what has been selected
osg::Geode* geode = new osg::Geode();
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
geode->setName("whatis");
geode->addDrawable( updateText );
modelview_abs->addChild(geode);
updateText->setFont(timesFont);
updateText->setText("whatis will tell you what is under the mouse");
updateText->setPosition(position);
position += delta;
}
return projection;
}
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 how to do Head Up Displays.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] [filename] ...");
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::STANDARD_SETTINGS);
// 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;
}
// read the scene from the list of file specified commandline args.
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(scene.get());
if (!group)
{
group = new osg::Group;
group->addChild(scene.get());
}
osg::ref_ptr<osgText::Text> updateText = new osgText::Text;
// add the HUD subgraph.
group->addChild(createHUD(updateText.get()));
// add the handler for doing the picking
viewer.getEventHandlerList().push_front(new PickHandler(&viewer,updateText.get()));
// set the scene to render
viewer.setSceneData(group.get());
// create the windows and run the threads.
viewer.realize();
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();
// 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;
}

View File

@ -0,0 +1,65 @@
/* -*-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.
*/
// PickIntersectVisitor == Pick visitor - used for screen based picking
// based on osgUtil::IntersectVisitor BUT
// traversing into Projection Nodes using the modified projections.
// also supplies high level intersector for 'what is under a pixel in a sceneview'
// GWM Feb 2003.
#ifndef OSGUTIL_PICKINTERSECTVISITOR
#define OSGUTIL_PICKINTERSECTVISITOR 1
#include <osgUtil/IntersectVisitor>
#include <osgUtil/SceneView>
namespace osgUtil {
// PickIntersectVisitor simplifies picking - routines take x,y mouse pixel & detect hits
class OSGUTIL_EXPORT PickIntersectVisitor : public IntersectVisitor {
public:
PickIntersectVisitor() {
setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions
}
~PickIntersectVisitor() { }
HitList& getHits(osgUtil::SceneView *, int x, int y);
HitList& PickIntersectVisitor::getIntersections(osg::Node *scene, osg::Vec3 nr, osg::Vec3 fr);
private:
osg::ref_ptr<osg::LineSegment> _lineSegment;
friend class osgUtil::IntersectVisitor;
};
// PickVisitor traverses whole scene and checks below all Projection nodes
class OSGUTIL_EXPORT PickVisitor : public osg::NodeVisitor {
public:
PickVisitor() {
xp=yp=0;
setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
}
~PickVisitor() { }
virtual void apply(osg::Projection& pr);
osgUtil::IntersectVisitor::HitList& getHits(osg::Node *nd, const osg::Matrix &projm, const float x, const float y);
osgUtil::IntersectVisitor::HitList& getHits(osgUtil::SceneView *, double x, double y);
osgUtil::IntersectVisitor::HitList & getHits(osg::Node *nd, const osg::Vec3 near_point, const osg::Vec3 far_point);
osgUtil::IntersectVisitor::HitList& getHits(void);
inline void setxy(float xpt, float ypt) { xp=xpt; yp=ypt; }
inline bool hits() { return _PIVsegHitList.size()>0;}
private:
PickIntersectVisitor _piv;
float xp, yp; // start point in viewport fraction coordiantes
osgUtil::IntersectVisitor::HitList _PIVsegHitList;
};
}// namespace osgUtil
#endif // match OSGUTIL_PICKINTERSECTVISITOR

View File

@ -9,6 +9,7 @@ CXXFILES = \
DisplayRequirementsVisitor.cpp\
InsertImpostorsVisitor.cpp\
IntersectVisitor.cpp\
PickVisitor.cpp\
Optimizer.cpp\
RenderBin.cpp\
RenderGraph.cpp\

116
src/osgUtil/PickVisitor.cpp Normal file
View File

@ -0,0 +1,116 @@
/* -*-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 <osgUtil/PickVisitor>
#include <osgUtil/SceneView>
#include <osg/Projection>
using namespace osg;
using namespace osgUtil;
osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getHits(osgUtil::SceneView *scv, int x, int y)
{ // High level get intersection with sceneview using a ray from x,y on the screen
int x0,y0,width,height;
scv->getViewport(x0, y0, width, height);
// setxy(-1+2*(float)(x-x0)/(float)width, 1-2*(float)(y-y0)/(float)height);
// sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels
osg::Vec3 near_point,far_point;
// get ends of line segment perpendicular to screen:
if (!scv->projectWindowXYIntoObject(x,height-y,near_point,far_point))
{
osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl;
return getHitList(NULL); // empty;
}
return getIntersections(scv->getSceneData(),near_point,far_point);
}
osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getIntersections(osg::Node *scene,
osg::Vec3 near_point,osg::Vec3 far_point)
{ // option for non-sceneView users: you need to get the screen perp line and call getIntersections
// if you are using Projection nodes you should also call setxy to define the xp,yp positions for use with
// the ray transformed by Projection
_lineSegment = new osg::LineSegment;
_lineSegment->set(near_point,far_point); // make a line segment
addLineSegment(_lineSegment.get());
scene->accept(*this);
return getHitList(_lineSegment.get());
}
// pickvisitor - top level; test main scenegraph than traverse to lower Projections
osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(osg::Node *nd, const osg::Vec3 near_point, const osg::Vec3 far_point)
{ // High level get intersection with sceneview using a ray from x,y on the screen
// sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels
// first get the standard hits in un-projected nodes
_PIVsegHitList=_piv.getIntersections(nd,near_point,far_point); // fill hitlist
// then get hits in projection nodes
traverse(*(nd)); // check for projection nodes
return _PIVsegHitList;
}
osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(osgUtil::SceneView *scv, const double x, const double y)
{ // High level get intersection with sceneview using a ray from x,y on the screen
int x0,y0,width,height;
scv->getViewport(x0, y0, width, height);
setxy(-1+2*(float)(x-x0)/(float)width, 1-2*(float)(y-y0)/(float)height);
// sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels
osg::Vec3 near_point,far_point;
// get ends of line segment perpendicular to screen:
if (!scv->projectWindowXYIntoObject(x,height-y,near_point,far_point))
{
osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl;
return _piv.getHitList(NULL); // empty;
}
osg::Node *nd=scv->getSceneData();
getHits(nd, near_point,far_point);
return _PIVsegHitList;
}
osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(void)
{ // High level return current intersections
return _PIVsegHitList;
}
osgUtil::IntersectVisitor::HitList& PickVisitor::getHits(osg::Node *scene,
const osg::Matrix &projm, const float x, const float y)
{ // utility for non=sceneview viewers
// x,y are values returned by
osg::Matrix inverseMVPW;
inverseMVPW.invert(projm);
double ix=0.5+0.5*x, iy=0.5-0.5*y; // for this purpose, range from 0-1
osg::Vec3 near_point = osg::Vec3(ix,iy,0.0f)*inverseMVPW;
osg::Vec3 far_point = osg::Vec3(ix,iy,1.0f)*inverseMVPW;
setxy(x,-y);
getHits(scene,near_point,far_point);
return _PIVsegHitList;
}
void PickVisitor::apply(osg::Projection& pr)
{ // stack the intersect rays, transform to new projection, traverse
// Assumes that the Projection is an absolute projection
osg::Matrix mt=osg::Matrix::inverse(pr.getMatrix());
osg::Vec3 npt=osg::Vec3(xp,yp,1) * mt, farpt=osg::Vec3(xp,yp,-1) * mt;
// traversing the nodes children, using the projection direction
for (unsigned int i=0; i<pr.getNumChildren(); i++) {
osg::Node *nodech=pr.getChild(i);
osgUtil::IntersectVisitor::HitList &hli=_piv.getIntersections(nodech,npt, farpt);
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hli.begin();
hitr!=hli.end();
++hitr) { // add the projection hits to the scene hits.
// This is why _lineSegment is retained as a member of PickIntersectVisitor
_PIVsegHitList.push_back(*hitr);
}
traverse(*nodech);
}
}