diff --git a/Make/makedefs b/Make/makedefs index cdbd0c4fe..b9171b29a 100644 --- a/Make/makedefs +++ b/Make/makedefs @@ -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 diff --git a/Make/makedirdefs b/Make/makedirdefs index 7a50c8b98..b9c2a0d59 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -119,6 +119,7 @@ EXAMPLE_DIRS = \ osgmultitexture\ osgoccluder\ osgparticle\ + osgpick\ osgprerender\ osgreflect\ osgscribe\ diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index 8a3012eff..d4e273460 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -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> diff --git a/VisualStudio/examples/osgpick/osgpick.dsp b/VisualStudio/examples/osgpick/osgpick.dsp new file mode 100644 index 000000000..cbc920fa7 --- /dev/null +++ b/VisualStudio/examples/osgpick/osgpick.dsp @@ -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 + diff --git a/doc/data.html b/doc/data.html index f86f454d6..45bac5403 100644 --- a/doc/data.html +++ b/doc/data.html @@ -30,7 +30,7 @@ diff --git a/doc/install.html b/doc/install.html index dd2fdfc5a..ab6cea84f 100644 --- a/doc/install.html +++ b/doc/install.html @@ -36,20 +36,11 @@

Compiling and installing the OpenSceneGraph

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. -

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.

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 & pic), while others (pfb,jpeg,gif,tiff) require other diff --git a/doc/introduction.html b/doc/introduction.html index 8ec5a5f9b..8746d7434 100644 --- a/doc/introduction.html +++ b/doc/introduction.html @@ -71,7 +71,7 @@ scientific and commercial visualization, training through to modeling programs.

Why use a Scene Graph - Performance, Productivity, Portability and Scalability.

-
    Performance - scene graphs provide an excellent framework for +
      Performance - 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. -

      Productivity - scene graphs take away much of the hard work required +

      Productivity - 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! -

      Portability - scene graphs encapsulate much of the lower level +

      Portability - 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. -

      Scalability - along with being able to dynamic manage the complexity +

      Scalability - 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: -

        Performance - supports view frustum culling, occlusion culling, small feature culling, +
          Performance - 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. -

          Productivity - by combining lessons learned from established +

          Productivity - 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. -

          Portability - The core scene graph has also been designed to +

          Portability - 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. -

          Scalability - the scene graph will not only run on portables all +

          Scalability - 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

        +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.
      + 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.

      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 dependencies list for further details. -

      For full instructions of how to run the demos read the demos +

      For full instructions of how to run the examples read the examples page.


      Learning how to use the OpenSceneGraph

      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 Wiki diff --git a/doc/plan.html b/doc/plan.html index 3ff9bb5cc..a05475c75 100644 --- a/doc/plan.html +++ b/doc/plan.html @@ -37,7 +37,7 @@ Plans for future developments 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.

      Fturue work include:

      @@ -45,28 +45,27 @@ Fturue work include:
      • -Multi-pass fallback for when multi-texturing is not supported.
      • +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.
      • Clean up the API for managing multi-stage and multi-pass rendering within the scene graph.
      • -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.
      • +Support for clustering in Open Producer and osgProducer.
      • -osgSim - cross platform library for the visual simulation market with support for light points, -small target anti-aliasing, geometry correction and clip mapping.
      • +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. +
      • -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.
      • +Development of virtual texture support for rendering in real-time massive images, such as whole earth textures.
      • -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.
      • diff --git a/examples/osgcameragroup/osgcameragroup.cpp b/examples/osgcameragroup/osgcameragroup.cpp index 3d519bea5..fe617b019 100644 --- a/examples/osgcameragroup/osgcameragroup.cpp +++ b/examples/osgcameragroup/osgcameragroup.cpp @@ -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; } diff --git a/examples/osgpick/GNUmakefile b/examples/osgpick/GNUmakefile new file mode 100644 index 000000000..607470a24 --- /dev/null +++ b/examples/osgpick/GNUmakefile @@ -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 + diff --git a/examples/osgpick/GNUmakefile.inst b/examples/osgpick/GNUmakefile.inst new file mode 100644 index 000000000..402a95280 --- /dev/null +++ b/examples/osgpick/GNUmakefile.inst @@ -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 diff --git a/examples/osgpick/osgpick.cpp b/examples/osgpick/osgpick.cpp new file mode 100644 index 000000000..988afcb2f --- /dev/null +++ b/examples/osgpick/osgpick.cpp @@ -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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + + + +// 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 _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 scene = osgDB::readNodeFiles(arguments); + + osg::ref_ptr group = dynamic_cast(scene.get()); + if (!group) + { + group = new osg::Group; + group->addChild(scene.get()); + } + + osg::ref_ptr 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; +} diff --git a/include/osgUtil/PickVisitor b/include/osgUtil/PickVisitor new file mode 100644 index 000000000..959e32d72 --- /dev/null +++ b/include/osgUtil/PickVisitor @@ -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 +#include + +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 _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 \ No newline at end of file diff --git a/src/osgUtil/GNUmakefile b/src/osgUtil/GNUmakefile index 346c429fc..498efc166 100644 --- a/src/osgUtil/GNUmakefile +++ b/src/osgUtil/GNUmakefile @@ -9,6 +9,7 @@ CXXFILES = \ DisplayRequirementsVisitor.cpp\ InsertImpostorsVisitor.cpp\ IntersectVisitor.cpp\ + PickVisitor.cpp\ Optimizer.cpp\ RenderBin.cpp\ RenderGraph.cpp\ diff --git a/src/osgUtil/PickVisitor.cpp b/src/osgUtil/PickVisitor.cpp new file mode 100644 index 000000000..3827951ba --- /dev/null +++ b/src/osgUtil/PickVisitor.cpp @@ -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 +#include +#include + +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