diff --git a/Make/makedirdefs b/Make/makedirdefs index 42d44778c..4671e3ed5 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -138,6 +138,9 @@ EXAMPLE_DIRS = \ osgreflect\ osgscribe\ osgsequence\ + osgscalarbar\ + osgspheresegment\ + osgsimulation\ osgshaders\ osgshadowtexture\ osgshape\ diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index 8d9836cf6..13e946e59 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -657,6 +657,96 @@ Package=<4> ############################################################################### +Project: "Example osgscalarbar"=.\examples\osgscalarbar\osgscalarbar.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 osgSim + 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 osgspheresegment"=.\examples\osgspheresegment\osgspheresegment.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 osgSim + 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 osgsimulation"=.\examples\osgsimulation\osgsimulation.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 osgSim + 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 osglogo"=.\examples\osglogo\osglogo.dsp - Package Owner=<4> Package=<5> diff --git a/VisualStudio/examples/osgscalarbar/osgscalarbar.dsp b/VisualStudio/examples/osgscalarbar/osgscalarbar.dsp new file mode 100644 index 000000000..51379e0a6 --- /dev/null +++ b/VisualStudio/examples/osgscalarbar/osgscalarbar.dsp @@ -0,0 +1,285 @@ +# Microsoft Developer Studio Project File - Name="Example osgscalarbar" - Package Owner=<4> + + +# Microsoft Developer Studio Generated Build File, Format Version 6.00 + + +# ** DO NOT EDIT ** + + + + + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + + + + + +CFG=Example osgscalarbar - 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 "osgscalarbar.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 "osgscalarbar.mak" CFG="Example osgscalarbar - Win32 Release" + + +!MESSAGE + + +!MESSAGE Possible choices for configuration are: + + +!MESSAGE + + +!MESSAGE "Example osgscalarbar - Win32 Release" (based on "Win32 (x86) Console Application") + + +!MESSAGE "Example osgscalarbar - 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 osgscalarbar - 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 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgscalarbar.exe" /libpath:"../../../lib" + + + + + +!ELSEIF "$(CFG)" == "Example osgscalarbar - 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 glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgscalarbard.exe" /pdbtype:sept /libpath:"../../../lib" + + +# SUBTRACT LINK32 /incremental:no + + + + + +!ENDIF + + + + + +# Begin Target + + + + + +# Name "Example osgscalarbar - Win32 Release" + + +# Name "Example osgscalarbar - Win32 Debug" + + +# Begin Source File + + + + + +SOURCE=..\..\..\examples\osgscalarbar\osgscalarbar.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/VisualStudio/examples/osgsimulation/osgsimulation.dsp b/VisualStudio/examples/osgsimulation/osgsimulation.dsp new file mode 100644 index 000000000..69d101dd1 --- /dev/null +++ b/VisualStudio/examples/osgsimulation/osgsimulation.dsp @@ -0,0 +1,285 @@ +# Microsoft Developer Studio Project File - Name="Example osgsimulation" - Package Owner=<4> + + +# Microsoft Developer Studio Generated Build File, Format Version 6.00 + + +# ** DO NOT EDIT ** + + + + + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + + + + + +CFG=Example osgsimulation - 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 "osgsimulation.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 "osgsimulation.mak" CFG="Example osgsimulation - Win32 Release" + + +!MESSAGE + + +!MESSAGE Possible choices for configuration are: + + +!MESSAGE + + +!MESSAGE "Example osgsimulation - Win32 Release" (based on "Win32 (x86) Console Application") + + +!MESSAGE "Example osgsimulation - 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 osgsimulation - 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 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgsimulation.exe" /libpath:"../../../lib" + + + + + +!ELSEIF "$(CFG)" == "Example osgsimulation - 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 glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgsimulationd.exe" /pdbtype:sept /libpath:"../../../lib" + + +# SUBTRACT LINK32 /incremental:no + + + + + +!ENDIF + + + + + +# Begin Target + + + + + +# Name "Example osgsimulation - Win32 Release" + + +# Name "Example osgsimulation - Win32 Debug" + + +# Begin Source File + + + + + +SOURCE=..\..\..\examples\osgsimulation\osgsimulation.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/VisualStudio/examples/osgspheresegment/osgsimulation.dsp b/VisualStudio/examples/osgspheresegment/osgsimulation.dsp new file mode 100644 index 000000000..72272161f --- /dev/null +++ b/VisualStudio/examples/osgspheresegment/osgsimulation.dsp @@ -0,0 +1,285 @@ +# Microsoft Developer Studio Project File - Name="Example osgspheresegment" - Package Owner=<4> + + +# Microsoft Developer Studio Generated Build File, Format Version 6.00 + + +# ** DO NOT EDIT ** + + + + + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + + + + + +CFG=Example osgspheresegment - 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 "osgspheresegment.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 "osgspheresegment.mak" CFG="Example osgspheresegment - Win32 Release" + + +!MESSAGE + + +!MESSAGE Possible choices for configuration are: + + +!MESSAGE + + +!MESSAGE "Example osgspheresegment - Win32 Release" (based on "Win32 (x86) Console Application") + + +!MESSAGE "Example osgspheresegment - 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 osgspheresegment - 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 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgspheresegment.exe" /libpath:"../../../lib" + + + + + +!ELSEIF "$(CFG)" == "Example osgspheresegment - 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 glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgspheresegmentd.exe" /pdbtype:sept /libpath:"../../../lib" + + +# SUBTRACT LINK32 /incremental:no + + + + + +!ENDIF + + + + + +# Begin Target + + + + + +# Name "Example osgspheresegment - Win32 Release" + + +# Name "Example osgspheresegment - Win32 Debug" + + +# Begin Source File + + + + + +SOURCE=..\..\..\examples\osgspheresegment\osgspheresegment.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/VisualStudio/osgSim/osgSim.dsp b/VisualStudio/osgSim/osgSim.dsp index 2103132f8..d62d3fb4b 100644 --- a/VisualStudio/osgSim/osgSim.dsp +++ b/VisualStudio/osgSim/osgSim.dsp @@ -113,6 +113,22 @@ SOURCE=..\..\src\osgSim\Sector.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgSim\ScalarsToColors.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgSim\ScalarBar.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgSim\ColorRange.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\osgSim\SphereSegment.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgSim\Version.cpp # End Source File # End Group @@ -141,6 +157,22 @@ SOURCE=..\..\include\osgSim\Sector # End Source File # Begin Source File +SOURCE=..\..\include\osgSim\ScalarsToColors +# End Source File +# Begin Source File + +SOURCE=..\..\include\osgSim\ScalarBar +# End Source File +# Begin Source File + +SOURCE=..\..\include\osgSim\ColorRange +# End Source File +# Begin Source File + +SOURCE=..\..\include\osgSim\SphereSegment +# End Source File +# Begin Source File + SOURCE=..\..\include\osgSim\Export # End Source File # Begin Source File diff --git a/doc/Doxyfiles/core_Doxyfile b/doc/Doxyfiles/core_Doxyfile index 47e4b2337..b3123c6f6 100644 --- a/doc/Doxyfiles/core_Doxyfile +++ b/doc/Doxyfiles/core_Doxyfile @@ -319,8 +319,11 @@ WARN_LOGFILE = INPUT = $(OSGHOME)/include/osg \ $(OSGHOME)/include/osgDB \ $(OSGHOME)/include/osgGA \ - $(OSGHOME)/include/osgGLUT \ $(OSGHOME)/include/osgParticle \ + $(OSGHOME)/include/osgProducer \ + $(OSGHOME)/include/osgSim \ + $(OSGHOME)/include/osgGL2 \ + $(OSGHOME)/include/osgFX \ $(OSGHOME)/include/osgText \ $(OSGHOME)/include/osgUtil \ $(OSGHOME)/doc/Doxyfiles/auto_Mainpage @@ -850,14 +853,14 @@ TEMPLATE_RELATIONS = YES # file showing the direct and indirect include dependencies of the file with # other documented files. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. diff --git a/examples/osgscalarbar/GNUmakefile b/examples/osgscalarbar/GNUmakefile new file mode 100644 index 000000000..76fa4e81c --- /dev/null +++ b/examples/osgscalarbar/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgscalarbar.cpp\ + +LIBS += -losgText -losgProducer -lProducer -losgSim -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgscalarbar + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgscalarbar/GNUmakefile.inst b/examples/osgscalarbar/GNUmakefile.inst new file mode 100644 index 000000000..d5ad41e70 --- /dev/null +++ b/examples/osgscalarbar/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgscalarbar.cpp\ + +LIBS += -losgText -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgscalarbar + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgscalarbar/osgscalarbar.cpp b/examples/osgscalarbar/osgscalarbar.cpp new file mode 100644 index 000000000..58bad3a33 --- /dev/null +++ b/examples/osgscalarbar/osgscalarbar.cpp @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include +#include +#include + +#include +#include +#include + +#include +#include + +using namespace osgSim; + +osg::Node* createScalarBar() +{ +// ScalarsToColors* stc = new ScalarsToColors(0.0f,1.0f); +// ScalarBar* sb = new ScalarBar(2,3,stc); +// +// // Create a custom color set +// std::vector cs; +// cs.push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f)); // R +// cs.push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f)); // B +// +// // Create a custom scalar printer +// struct MyScalarPrinter: public ScalarBar::ScalarPrinter +// { +// std::string printScalar(float scalar) +// { +// std::cout<<"In MyScalarPrinter::printScalar"<setScalarPrinter(new MyScalarPrinter); +// +// return sb; + + ScalarBar *sb = new ScalarBar; + ScalarBar::TextProperties tp; + tp._fontFile = "fonts/times.ttf"; + + sb->setTextProperties(tp); + + return sb; + +} + +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 both text, animation and billboard via custom transform to create the OpenSceneGraph logo.."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("ps","Render the Professional Services logo"); + + // 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; + } + + osg::Node* node = createScalarBar(); + + // add model to viewer. + viewer.setSceneData( node ); + + // 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/examples/osgsimulation/GNUmakefile b/examples/osgsimulation/GNUmakefile new file mode 100644 index 000000000..bea0845a3 --- /dev/null +++ b/examples/osgsimulation/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgsimulation.cpp\ + +LIBS += -losgProducer -lProducer -losgSim -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgsimulation + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgsimulation/GNUmakefile.inst b/examples/osgsimulation/GNUmakefile.inst new file mode 100644 index 000000000..3ed50c4bf --- /dev/null +++ b/examples/osgsimulation/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgsimulation.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgSim -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgsimulation + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgsimulation/osgsimulation.cpp b/examples/osgsimulation/osgsimulation.cpp new file mode 100644 index 000000000..3d9802e3e --- /dev/null +++ b/examples/osgsimulation/osgsimulation.cpp @@ -0,0 +1,134 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application 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. +*/ + +#include +#include +#include + + +#include + +using namespace osgSim; + +osg::Node* createSphereSegment() +{ + osgSim::SphereSegment* ss = new osgSim::SphereSegment(osg::Vec3(0.0f,0.0f,0.0f), 1.0f, + osg::Vec3(0.0f,1.0f,0.0f), + osg::DegreesToRadians(360.0f), + osg::DegreesToRadians(45.0f), + 40); + ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); + + return ss; +} + +osg::Node* createModel() +{ + return createSphereSegment(); +} + + +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()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + 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; + } + + if (arguments.argc()<=1) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } + +// osg::Timer timer; +// osg::Timer_t start_tick = timer.tick(); +// +// // read the scene from the list of file specified commandline args. +// osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); +// +// // if no model has been successfully loaded report failure. +// if (!loadedModel) +// { +// std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; +// return 1; +// } +// +// osg::Timer_t end_tick = timer.tick(); +// +// std::cout << "Time to load = "< loadedModel = createModel(); + + + // optimize the scene graph, remove rendundent nodes and state etc. + osgUtil::Optimizer optimizer; + optimizer.optimize(loadedModel.get()); + + + // set the scene to render + viewer.setSceneData(loadedModel.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/examples/osgspheresegment/GNUmakefile b/examples/osgspheresegment/GNUmakefile new file mode 100644 index 000000000..2c57545d9 --- /dev/null +++ b/examples/osgspheresegment/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgspheresegment.cpp\ + +LIBS += -losgText -losgProducer -lProducer -losgSim -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgspheresegment + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgspheresegment/GNUmakefile.inst b/examples/osgspheresegment/GNUmakefile.inst new file mode 100644 index 000000000..ba5898a9b --- /dev/null +++ b/examples/osgspheresegment/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgspheresegment.cpp\ + +LIBS += -losgText -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgspheresegment + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgspheresegment/osgspheresegment.cpp b/examples/osgspheresegment/osgspheresegment.cpp new file mode 100644 index 000000000..a83ed927e --- /dev/null +++ b/examples/osgspheresegment/osgspheresegment.cpp @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +using namespace osgSim; + +class MyNodeCallback: public osg::NodeCallback +{ + void operator()(osg::Node*,osg::NodeVisitor*); +}; + +// void MyNodeCallback::operator()(osg::Node* n,osg::NodeVisitor* nv) +// { +// if(osgSim::SphereSegment* ss=dynamic_cast(n)) +// { +// osg::Vec3 vec; +// float azRange, elevRange; +// ss->getArea(vec,azRange,elevRange); +// +// float azRangeDeg = osg::RadiansToDegrees(azRange); +// +// static bool azAscending = false; +// +// if(azAscending){ +// azRangeDeg += 1.0f; +// if(azRangeDeg>89.0f) azAscending = false; +// }else{ +// azRangeDeg -= 1.0f; +// if(azRangeDeg<2.0f) azAscending = true; +// } +// +// ss->setArea(vec,osg::DegreesToRadians(azRangeDeg),elevRange); +// +// } +// traverse(n,nv); +// } + +void MyNodeCallback::operator()(osg::Node* n,osg::NodeVisitor* nv) +{ + if(osgSim::SphereSegment* ss=dynamic_cast(n)) + { + osg::Vec3 vec; + float azRange, elevRange; + ss->getArea(vec,azRange,elevRange); + + static float angle = 0.0f; + if(++angle > 359.0f) angle = 0.0f; + vec.set(sin(osg::DegreesToRadians(angle)),cos(osg::DegreesToRadians(angle)),0.0f); + + std::cout<<"angle "<setArea(vec,azRange,elevRange); + } + traverse(n,nv); +} + +osg::Node* createSphereSegment() +{ + SphereSegment* ss = new SphereSegment(osg::Vec3(0.0f,0.0f,0.0f), 1.0f, + osg::Vec3(0.0f,1.0f,0.0f), + osg::DegreesToRadians(90.0f), + osg::DegreesToRadians(45.0f), + 60); + ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + ss->setPlaneColor(osg::Vec4(0.0f,0.0f,1.0f,0.1f)); + //ss->setDrawMask(SphereSegment::DrawMask(SphereSegment::SPOKES | SphereSegment::EDGELINE)); + + //ss->setUpdateCallback(new MyNodeCallback); + + return ss; +} + +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 both text, animation and billboard via custom transform to create the OpenSceneGraph logo.."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("ps","Render the Professional Services logo"); + + // 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; + } + + osg::Node* node = createSphereSegment(); + + // add model to viewer. + viewer.setSceneData( node ); + + // 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/osgSim/ColorRange b/include/osgSim/ColorRange new file mode 100644 index 000000000..115804aa6 --- /dev/null +++ b/include/osgSim/ColorRange @@ -0,0 +1,57 @@ +/* -*-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. +*/ + +#ifndef OSGSIM_COLORRANGE +#define OSGSIM_COLORRANGE 1 + +#include + +#include +#include + +namespace osgSim +{ +/** +ColorRange is a ScalarsToColors object to define a color spectrum +for a scalar range. An optional vector of colors may be passed in at +construction time. The range of colors will be mapped to the scalar range, +and interpolation between the colors will be performed as necessary. +By default, the color range will run Red-Yellow-Green-Cyan-Blue. +*/ +class OSGSIM_EXPORT ColorRange: public ScalarsToColors +{ +public: + + /** Constructor for a ColorRange + @param min minimum scalar value + @param max maximum scalar value + @param colors optional range of colors, defaulting to Red-Yellow-Green-Blue-Cyan + */ + ColorRange(float min, float max, const std::vector& colors = std::vector()); + + /** Set the range of colors. */ + void setColors(const std::vector& colors); + + /** Get the color for a given scalar value. */ + osg::Vec4 getColor(float scalar) const; + +private: + + // Default assignment and copy construction are OK. + + std::vector _colors; +}; + +} + +#endif diff --git a/include/osgSim/ScalarBar b/include/osgSim/ScalarBar new file mode 100644 index 000000000..b93370489 --- /dev/null +++ b/include/osgSim/ScalarBar @@ -0,0 +1,219 @@ +/* -*-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. +*/ + +#ifndef OSGSIM_SCALARBAR +#define OSGSIM_SCALARBAR 1 + +#include +#include // The default ScalarsToColors is a ColorRange +#include +#include + +namespace osgSim +{ +/** +A ScalarBar is an osg::Geode to render a colored bar representing a range +of scalars. The scalar/color ranges are specified by an instance of +ScalarsToColors. There are a number of configurable properties on the +ScalarBar, such as the orientation, the number of labels to be displayed +across the range, the number of distinct colors to use when rendering the +bar, text details etc. + +In summary, the main configurables on the ScalarBar are: + + -# The range of scalars represented by the bar, and the colors + corresponding to this range - these are specified by the + ScalarsToColors object. + -# The number of colors used when rendering the bar geometry - + this may be thought of as the bar 'density'. + -# The number of text labels to be used when displaying the bar. + +The other configurables should be self-explanatory. +*/ +class OSGSIM_EXPORT ScalarBar: public osg::Geode +{ + +public: + + /** ScalarBar orientation specification. */ + enum Orientation{ + HORIZONTAL, ///< a horizontally ascending scalar bar (x-axis) + VERTICAL ///< a vertically ascending scalar bar (y-axis) + }; + + /** + Users may provide their own ScalarPrinter by deriving from this base class and + overriding the printScalar() method. Users may map the scalar float passed in + to any string they wish. + */ + struct ScalarPrinter: public osg::Referenced + { + virtual std::string printScalar(float scalar); + }; + + /** + TextProperties allows users to specify a number of properties for the + text used to display the labels & title on the ScalarBar. Specifiying a character + size of 0 will cause the ScalarBar to estimate an appropriate size. Note that + the attributes are public, and may be set directly. + */ + struct TextProperties + { + std::string _fontFile; + std::pair _fontResolution; + int _characterSize; + osg::Vec4 _color; + + TextProperties(): + _fontFile("fonts/arial.ttf"), + _fontResolution(40,40), + _characterSize(0), + _color(1.0f,1.0f,1.0f,1.0f) + { + } + }; + + /** Default constructor. */ + ScalarBar(): osg::Geode(), + _numColors(256), + _numLabels(11), + _stc(new ColorRange(0.0f,1.0f)), + _title("Scalar Bar"), + _orientation(HORIZONTAL), + _aspectRatio(0.03), + _sp(new ScalarPrinter) + { + createDrawables(); + } + + /** + Construct a ScalarBar with the supplied parameters. + @param numColors Specify the number of colors in the scalar bar. Color + interpolation occurs where necessary. + @param stc The ScalarsToColors defining the range of scalars + and the colors they map to. + @param title The title to be used when displaying the ScalarBar. + Specify "" for no title. + @param orientation The orientation of the ScalarBar. @see Orientation. + @param apectRatio The aspect ration (y/x) for the displayed bar. Bear in mind you + may want to change this if you change the orientation. + @param sp A ScalarPrinter object for the ScalarBar. For every displayed + ScalarBar label, the scalar value will be passed to the + ScalarPrinter object to turn it into a string. Users may + override the default ScalarPrinter object to map scalars to + whatever strings they wish. @see ScalarPrinter + */ + ScalarBar(int numColors, int numLabels, ScalarsToColors* stc, + const std::string& title, + Orientation orientation = HORIZONTAL, + float aspectRatio=0.25, + ScalarPrinter* sp=new ScalarPrinter): + osg::Geode(), + _numColors(numColors), + _numLabels(numLabels), + _stc(stc), + _title(title), + _orientation(orientation), + _aspectRatio(aspectRatio), + _sp(sp) + { + createDrawables(); + } + + /** Copy constructor */ + ScalarBar(const ScalarBar& rhs, const osg::CopyOp& co): osg::Geode(rhs,co), + _numColors(rhs._numColors), + _numLabels(rhs._numLabels), + _stc(rhs._stc), // Consider clone for deep copy? + _title(rhs._title), + _orientation(rhs._orientation), + _aspectRatio(rhs._aspectRatio), + _sp(rhs._sp), // Consider clone for deep copy? + _textProperties(rhs._textProperties) + { + } + + /** Set the number of distinct colours on the ScalarBar. */ + void setNumColors(int numColors); + + /** Get the number of distinct colours on the ScalarBar. */ + int getNumColors() const; + + /** Set the number of labels to display along the ScalarBar. There + will be one label at each end point, and evenly distributed labels + in between. */ + void setNumLabels(int numLabels); + + /** Get the number of labels displayed along the ScalarBar. */ + int getNumLabels() const; + + /** Set the ScalarsToColors mapping object for the ScalarBar. */ + void setScalarsToColors(ScalarsToColors* stc); + + /** Get the ScalarsToColors mapping object from the ScalarBar. */ + const ScalarsToColors* getScalarsToColors() const; + + /** Set the title for the ScalarBar, set "" for no title. */ + void setTitle(const std::string& title); + + /** Get the title for the ScalarBar. */ + std::string getTitle() const; + + /** Set the orientation of the ScalarBar. @see Orientation */ + void setOrientation(ScalarBar::Orientation orientation); + + /** Get the orientation of the ScalarBar. @see Orientation */ + ScalarBar::Orientation getOrientation() const; + + /** Set the aspect ration (y/x) for the displayed bar. Bear in mind you + may want to change this if you change the orientation. */ + void setAspectRatio(float aspectRatio); + + /** Get the aspect ration (y/x) for the displayed bar. */ + float getAspectRatio() const; + + /** Set a ScalarPrinter object for the ScalarBar. For every displayed + ScalarBar label, the scalar value will be passed to the ScalarPrinter + object to turn it into a string. Users may override the default ScalarPrinter + object to map scalars to whatever strings they wish. @see ScalarPrinter */ + void setScalarPrinter(ScalarPrinter* sp); + + /** Get the ScalarPrinter object */ + const ScalarPrinter* getScalarPrinter() const; + + /** Set the TextProperties for the labels & title. @see TextProperties */ + void setTextProperties(const TextProperties& tp); + + /** Get the TextProperties for the labels & title. @see TextProperties */ + const TextProperties& getTextProperties() const; + + META_Node(osgSim, ScalarBar); + +private: + + int _numColors; + int _numLabels; + osg::ref_ptr _stc; + std::string _title; + Orientation _orientation; + float _aspectRatio; + osg::ref_ptr _sp; + TextProperties _textProperties; + + void createDrawables(); + +}; + +} + +#endif diff --git a/include/osgSim/ScalarsToColors b/include/osgSim/ScalarsToColors new file mode 100644 index 000000000..97ed3b4a1 --- /dev/null +++ b/include/osgSim/ScalarsToColors @@ -0,0 +1,53 @@ +/* -*-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. +*/ + +#ifndef OSGSIM_SCALARSTCOLORS +#define OSGSIM_SCALARSTCOLORS 1 + +#include + +#include +#include + +namespace osgSim +{ +/** +ScalarsToColors defines the interface to map a scalar value to a color, +and provides a default implementation of the mapping functionaltity, +with colors ranging from black to white across the min - max scalar +range. +*/ +class OSGSIM_EXPORT ScalarsToColors: public osg::Referenced +{ +public: + + ScalarsToColors(float scalarMin, float scalarMax); + virtual ~ScalarsToColors() {} + + /** Get the color for a given scalar value. */ + virtual osg::Vec4 getColor(float scalar) const; + + /** Get the minimum scalar value. */ + float getMin() const; + + /** Get the maximum scalar value. */ + float getMax() const; + +private: + + float _min, _max; +}; + +} + +#endif diff --git a/include/osgSim/SphereSegment b/include/osgSim/SphereSegment new file mode 100644 index 000000000..fbf823b17 --- /dev/null +++ b/include/osgSim/SphereSegment @@ -0,0 +1,259 @@ +/* -*-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. +*/ + +#ifndef OSGSIM_SPHERESEGMENT +#define OSGSIM_SPHERESEGMENT 1 + +#include + +#include +#include +#include +#include + +namespace osgSim{ + +/** +A SphereSegment is a Geode to represent an portion of a sphere (potentially +the whole sphere). The sphere is aligned such that the line through the +sphere's poles is parallel to the z axis. The sphere segment +may be rendered various components switched on or off: + + - The specified area of the sphere surface. + + - An edge line around the boundary of the specified area + of the sphere surface. + + - Four spokes, where a spoke is the line from + the sphere's centre to a corner of the rendered area. + + - Four planar areas, where the planar areas are formed + between the spokes. + +Caveats: + + - It's worth noting that the line through the sphere's poles is + parallel to the z axis. This has implications when specifying the + area to be rendered, and specifying areas where the centre of + the rendered area is the Z axis may lead to unexpected + geometry. + + - It's possible to render the whole sphere by specifying elevation + and azimuth ranges round the full 360 degrees. When doing + so you may consider switching the planes, spokes, and edge lines + off, to avoid rendering artefacts, e.g. the upper and lower + planes will be coincident. + +*/ +class OSGSIM_EXPORT SphereSegment: public osg::Geode +{ +public: + + /** + DrawMask represents a bit field, the values of which may be OR'ed together + to specify which parts of the sphere segment should be drawn. E.g. + \code + sphereSegment->setDrawMask(SphereSegment::DrawMask(SphereSegment::SURFACE|SphereSegment::SPOKES)); + \endcode + */ + enum DrawMask{ + SURFACE = 0x00000001, ///< Draw the specified area on the sphere's surface + SPOKES = 0x00000002, ///< Draw the spokes from the sphere's centre to the surface's corners + EDGELINE = 0x00000008, ///< Draw the line round the edge of the area on the sphere's surface + PLANES = 0x00000010, ///< Draw the planes from the sphere's centre to the edge of the sphere's surface + ALL = 0xffffffff ///< Draw every part of the sphere segment + }; + + + /** Default constructor. */ + SphereSegment():Geode(), + _centre(0.0f,0.0f,0.0f), _radius(1.0f), + _azMin(0.0f), _azMax(osg::PI/2.0f), + _elevMin(0.0f), _elevMax(osg::PI/2.0f), + _density(10), + _drawMask(DrawMask(ALL)) + {} + + /** + Construct by angle ranges. Note that the azimuth 'zero' is the Y axis; specifying + an azimuth range from azMin -osg::PI/2.0f to azMax osg::PI/2.0f will cover the + 'top half' of the circle in the XY plane. The elev angles are 'out' of the 'zero' + XY plane with +ve angles above the plane, and -ve angles below. + @param centre sphere centre + @param radius radius of sphere + @param azMin azimuth minimum + @param azMin azimuth maximum + @param elevMin elevation minimum + @param elevMax elevation maximum + @param density number of units to divide the azimuth and elevation ranges into + */ + SphereSegment(const osg::Vec3& centre, float radius, float azMin, float azMax, + float elevMin, float elevMax, int density): + Geode(), + _centre(centre), _radius(radius), + _azMin(azMin), _azMax(azMax), + _elevMin(elevMin), _elevMax(elevMax), + _density(density), + _drawMask(DrawMask(ALL)) + { + init(); + } + + /** + Construct by vector. + @param centre sphere centre + @param radius radius of sphere + @param vec vector pointing from sphere centre to centre point + of rendered area on sphere surface + @param azRange azimuth range in radians (with centre along vec) + @param elevRange elevation range in radians (with centre along vec) + @param density number of units to divide the azimuth and elevation ranges into + */ + SphereSegment(const osg::Vec3& centre, float radius, const osg::Vec3& vec, float azRange, + float elevRange, int density); + + /** Copy constructor */ + SphereSegment(const SphereSegment& rhs, const osg::CopyOp& co): + Geode(rhs,co), + _centre(rhs._centre), _radius(rhs._radius), + _azMin(rhs._azMin), _azMax(rhs._azMax), + _elevMin(rhs._elevMin), _elevMax(rhs._elevMax), + _density(rhs._density), + _drawMask(rhs._drawMask) + { + init(); + } + + /** Set the centre point of the SphereSegment */ + void setCentre(const osg::Vec3& c); + + /** Get the centre point of the SphereSegment */ + const osg::Vec3& getCentre() const; + + /** Set the radius of the SphereSegment */ + void setRadius(float r); + + /** Get the radius of the SphereSegment */ + float getRadius() const; + + /** Set the area of the sphere segment + + @param vec vector pointing from sphere centre to centre point + of rendered area on sphere surface + @param azRange azimuth range in radians (with centre along vec) + @param elevRange elevation range in radians (with centre along vec) + */ + void setArea(const osg::Vec3& v, float azRange, float elevRange); + + /** Get the area of the sphere segment + + @param vec vector pointing from sphere centre to centre point + of rendered area on sphere surface (normalized) + @param azRange azimuth range in radians (with centre along vec) + @param elevRange elevation range in radians (with centre along vec) + */ + void getArea(osg::Vec3& v, float& azRange, float& elevRange) const; + + /** Set the density of the sphere segment */ + void setDensity(int d); + + /** Get the density of the sphere segment */ + int getDensity() const; + + /** + Specify the DrawMask. + @param dm Bitmask specifying which parts of the sphere segment should be drawn. + @see DrawMask + */ + void setDrawMask(DrawMask dm); + + /** Set the color of the surface. */ + void setSurfaceColor(const osg::Vec4& c); + + /** Set the color of the spokes. */ + void setSpokeColor(const osg::Vec4& c); + + /** Set the color of the edge line. */ + void setEdgeLineColor(const osg::Vec4& c); + + /** Set the color of the planes. */ + void setPlaneColor(const osg::Vec4& c); + + /** Set color of all components. */ + void setAllColors(const osg::Vec4& c); + + META_Node(osgSim, SphereSegment) + +private: + + void init(); // Shared constructor code, generates the drawables + + void dirtyAllDrawableDisplayLists(); // Force re-calling of gl functions + void dirtyAllDrawableBounds(); // Force recalculation of bound geometry + + // SphereSegment is actually made up of a number of Drawable classes, + // all of which are nested private classes, as declared below. These + // classes are defined in the .cpp for minimum visibility and physical + // coupling. (Reduces time spent compiling! :-) + // + // Each of the nested classes holds a pointer to the SphereSegment + // 'parent', which stores the geometry details, and performs any + // work required. The nested classes are lightweight objects which + // just pass the work on. + // + // Why are things done with these sub-Drawables? Alpha-blended + // Drawables need to be drawn last, depth sorted, and the various + // components of a SphereSegment also need to be depth sorted + // against one another (they may all be drawn with alpha blending). + // Making these Drawables allows us to get the OSG to depth sort + // for us. + + class Surface; + friend class Surface; + bool Surface_computeBound(osg::BoundingBox&) const; + void Surface_drawImplementation(osg::State&) const; + + class EdgeLine; + friend class EdgeLine; + bool EdgeLine_computeBound(osg::BoundingBox&) const; + void EdgeLine_drawImplementation(osg::State&) const; + + enum BoundaryAngle{MIN,MAX}; // Why here and not in Plane class? Because we can't forward + enum PlaneOrientation{AZIM,ELEV}; // declare enums, Plane is in the .cpp, and this is tidier... + class Plane; + friend class Plane; + bool Plane_computeBound(osg::BoundingBox&, PlaneOrientation, BoundaryAngle) const; + void Plane_drawImplementation(osg::State&, PlaneOrientation, BoundaryAngle) const; + + class Spoke; + friend class Spoke; + bool Spoke_computeBound(osg::BoundingBox&, BoundaryAngle, BoundaryAngle) const; + void Spoke_drawImplementation(osg::State&, BoundaryAngle, BoundaryAngle) const; + + // Sphere segment geometry details + osg::Vec3 _centre; + float _radius; + float _azMin, _azMax, _elevMin, _elevMax; + int _density; + + // Draw details + DrawMask _drawMask; + osg::Vec4 _surfaceColor; + osg::Vec4 _spokeColor; + osg::Vec4 _edgeLineColor; + osg::Vec4 _planeColor; +}; + +} + +#endif diff --git a/src/osgSim/ColorRange.cpp b/src/osgSim/ColorRange.cpp new file mode 100644 index 000000000..f2298d6f3 --- /dev/null +++ b/src/osgSim/ColorRange.cpp @@ -0,0 +1,38 @@ +#include + +using namespace osgSim; + +ColorRange::ColorRange(float min, float max, const std::vector& colors): ScalarsToColors(min,max) +{ + setColors(colors); +}; + +void ColorRange::setColors(const std::vector& colors) +{ + if(colors.size()>1) + { + _colors=colors; + } + else + { + // Default to something sensible + _colors.push_back(osg::Vec4(1.0,0.0,0.0,1.0)); // R + _colors.push_back(osg::Vec4(1.0,1.0,0.0,1.0)); // Y + _colors.push_back(osg::Vec4(0.0,1.0,0.0,1.0)); // G + _colors.push_back(osg::Vec4(0.0,1.0,1.0,1.0)); // C + _colors.push_back(osg::Vec4(0.0,0.0,1.0,1.0)); // B + } +} + +osg::Vec4 ColorRange::getColor(float scalar) const +{ + if(scalargetMax()) return _colors.back(); + + float r = ((scalar - getMin())/(getMax() - getMin())) * (_colors.size()-1); + int lower = static_cast(floor(r)); + int upper = static_cast(ceil(r)); + + osg::Vec4 color = _colors[lower] + ((_colors[upper] - _colors[lower]) * (r-lower)); + return color; +} diff --git a/src/osgSim/GNUmakefile b/src/osgSim/GNUmakefile index 7d67e1611..8e58142d4 100644 --- a/src/osgSim/GNUmakefile +++ b/src/osgSim/GNUmakefile @@ -3,14 +3,16 @@ include $(TOPDIR)/Make/makedefs CXXFILES = \ + ColorRange.cpp\ + ScalarBar.cpp\ + ScalarsToColors.cpp\ BlinkSequence.cpp\ LightPoint.cpp\ LightPointDrawable.cpp\ LightPointNode.cpp\ Sector.cpp\ + SphereSegment.cpp\ Version.cpp\ - -# SphereSegment.cpp\ DEF += -DOSGSIM_LIBRARY diff --git a/src/osgSim/ScalarBar.cpp b/src/osgSim/ScalarBar.cpp new file mode 100644 index 000000000..702e9795b --- /dev/null +++ b/src/osgSim/ScalarBar.cpp @@ -0,0 +1,300 @@ +#include +#include +#include +#include + +using namespace osgSim; + +std::string ScalarBar::ScalarPrinter::printScalar(float scalar) +{ + std::stringstream ostr; + ostr<getBound().xMax() < d2->getBound().xMax(); + else if(_axis == Y_AXIS) return d1->getBound().yMax() < d2->getBound().yMax(); + else if(_axis == Z_AXIS) return d1->getBound().zMax() < d2->getBound().zMax(); + + return false; + } +}; + +struct AlignCentreOnYValue +{ + float _y; + AlignCentreOnYValue(float y): _y(y) {} + void operator()(osgText::Text* t) + { + t->setPosition(osg::Vec3(t->getBound().center().x(), _y, t->getBound().center().z())); + t->setAlignment(osgText::Text::CENTER_CENTER); + } +}; + +} + +void ScalarBar::createDrawables() +{ + // Remove any existing Drawables + _drawables.erase(_drawables.begin(), _drawables.end()); + + // 1. First the bar + // ================= + osg::ref_ptr bar = new osg::Geometry(); + + // Create the bar - created in 'real' coordinate space the moment, + // with xyz values reflecting those of the actual scalar values in play. + // FIXME: Consider positioning at origin! Should be easy enough to do. + + // Vertices + osg::ref_ptr vs(new osg::Vec3Array); + vs->reserve(2*(_numColors+1)); + + float incr = (_stc->getMax() - _stc->getMin()) / _numColors; + float arOffset; + if(_orientation==HORIZONTAL) + { + arOffset = _numColors * incr * _aspectRatio; // Bar height for a horizontal bar + } + else + { + arOffset = (_numColors*incr)/_aspectRatio; // Bar width for a vertical bar + } + + for(int i=1; i<=_numColors; ++i) + { + // Make a quad + if(_orientation==HORIZONTAL) + { + vs->push_back(osg::Vec3(_stc->getMin() + (i-1) * incr, 0.0f, 0.0f)); + vs->push_back(osg::Vec3(_stc->getMin() + (i-1) * incr, arOffset, 0.0f)); + vs->push_back(osg::Vec3(_stc->getMin() + i * incr, arOffset, 0.0f)); + vs->push_back(osg::Vec3(_stc->getMin() + i * incr, 0.0f, 0.0f)); + } + else + { + vs->push_back(osg::Vec3(0.0f, _stc->getMin() + (i-1) * incr, 0.0f)); + vs->push_back(osg::Vec3(arOffset, _stc->getMin() + (i-1) * incr, 0.0f)); + vs->push_back(osg::Vec3(arOffset, _stc->getMin() + i * incr, 0.0f)); + vs->push_back(osg::Vec3(0.0f, _stc->getMin() + i * incr, 0.0f)); + } + } + bar->setVertexArray(vs.get()); + + // Colours + osg::ref_ptr cs(new osg::Vec4Array); + cs->reserve(_numColors); + const float halfIncr = incr*0.5; + for(int i=0; i<_numColors; ++i) + { + // We add half an increment to the color look-up to get the color + // square in the middle of the 'block'. + cs->push_back(_stc->getColor(_stc->getMin() + (i*incr) + halfIncr)); + } + bar->setColorArray(cs.get()); + bar->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE); + + // Normal + osg::ref_ptr ns(new osg::Vec3Array); + ns->push_back(osg::Vec3(0.0f,0.0f,1.0f)); + bar->setNormalArray(ns.get()); + bar->setNormalBinding(osg::Geometry::BIND_OVERALL); + + // The Quad strip that represents the bar + bar->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,vs->size())); + + addDrawable(bar.get()); + + // 2. Then the text labels + // ======================= + + // Check the character size, if it's 0, estimate a good character size + float characterSize = _textProperties._characterSize; + if(characterSize == 0) characterSize = ((_stc->getMax()-_stc->getMin())*0.3)/_numLabels; + + osgText::Font* font = osgText::readFontFile(_textProperties._fontFile.c_str()); + + std::vector texts(_numLabels); // We'll need to collect pointers to these for later + float labelIncr = (_stc->getMax()-_stc->getMin())/(_numLabels-1); + for(int i=0; i<_numLabels; ++i) + { + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(_textProperties._color); + text->setFontResolution(_textProperties._fontResolution.first,_textProperties._fontResolution.second); + text->setCharacterSize(characterSize); + text->setText(_sp->printScalar(_stc->getMin()+(i*labelIncr))); + + if(_orientation == HORIZONTAL) + { + text->setPosition(osg::Vec3(_stc->getMin() + (i*labelIncr), arOffset, 0.0f)); + text->setAlignment(osgText::Text::CENTER_BOTTOM); + } + else + { + text->setPosition(osg::Vec3(arOffset, _stc->getMin() + (i*labelIncr), 0.0f)); + text->setAlignment(osgText::Text::LEFT_CENTER); + } + + addDrawable(text); + + texts[i] = text; + } + + // Make sure the text labels are all properly aligned - different words will have a different + // vertical alignment depending on the letters used in the labels. E.g. a 'y' has a dangling tail. + if(_orientation == HORIZONTAL) + { + std::vector::iterator maxYIt = max_element(texts.begin(), texts.end(), MaxCoordLess(MaxCoordLess::Y_AXIS)); + for_each(texts.begin(), texts.end(), AlignCentreOnYValue((*maxYIt)->getBound().center().y())); + } + + // 3. And finally the title + // ======================== + + if(_title != "") + { + osgText::Text* text = new osgText::Text; + text->setFont(font); + text->setColor(_textProperties._color); + text->setFontResolution(_textProperties._fontResolution.first,_textProperties._fontResolution.second); + text->setCharacterSize(characterSize); + text->setText(_title); + + if(_orientation==HORIZONTAL) + { + // Horizontal bars have the title above the scalar bar and the labels. + // Need to move the title above any labels, using maximum y value of the + // existing text objects + + std::vector::iterator maxYIt = max_element(texts.begin(), texts.end(), MaxCoordLess(MaxCoordLess::Y_AXIS)); + + float titleY; + if(maxYIt != texts.end()) titleY = (*maxYIt)->getBound().yMax() * 1.1f; + else titleY = arOffset; // No labels, so just use arOffset + + // Position the title at the middle of the bar above any labels. + text->setPosition(osg::Vec3(_stc->getMin() + ((_stc->getMax()-_stc->getMin())/2.0f), titleY, 0.0f)); + text->setAlignment(osgText::Text::CENTER_BOTTOM); + } + else if(_orientation==VERTICAL) + { + // Vertical bars have the title to the right of the scalar bar and the labels. + // Need to move the title out beyond any labels, using the maximum x value of the + // existing text objects + + std::vector::iterator maxXIt = max_element(texts.begin(), texts.end(), MaxCoordLess(MaxCoordLess::X_AXIS)); + + float titleX; + if(maxXIt != texts.end()) titleX = (*maxXIt)->getBound().xMax() * 1.1f; + else titleX = arOffset; // No labels, so just use arOffset + + // Position the title in the at the middle of the bar, to the right of any labels. + text->setPosition(osg::Vec3(titleX, _stc->getMin() + ((_stc->getMax()-_stc->getMin())/2.0f), 0.0f)); + text->setAlignment(osgText::Text::LEFT_CENTER); + } + + addDrawable(text); + } +} diff --git a/src/osgSim/ScalarsToColors.cpp b/src/osgSim/ScalarsToColors.cpp new file mode 100644 index 000000000..3bbef6a51 --- /dev/null +++ b/src/osgSim/ScalarsToColors.cpp @@ -0,0 +1,26 @@ +#include + +using namespace osgSim; + +ScalarsToColors::ScalarsToColors(float scalarMin, float scalarMax): _min(scalarMin), _max(scalarMax) +{ +} + +osg::Vec4 ScalarsToColors::getColor(float scalar) const +{ + if(scalar<_min) return osg::Vec4(0.0f,0.0f,0.0f,0.0f); + if(scalar>_max) return osg::Vec4(0.0f,0.0f,0.0f,0.0f); + + float c = (_min+scalar)/(_max-_min); + return osg::Vec4(c,c,c,1.0); +} + +float ScalarsToColors::getMin() const +{ + return _min; +} + +float ScalarsToColors::getMax() const +{ + return _max; +} diff --git a/src/osgSim/SphereSegment.cpp b/src/osgSim/SphereSegment.cpp new file mode 100644 index 000000000..0a32bfcd7 --- /dev/null +++ b/src/osgSim/SphereSegment.cpp @@ -0,0 +1,757 @@ +#include +#include + +using namespace osgSim; + +// Define the collection of nested classes, all Drawables, which make +// up the parts of the sphere segment. + +/** +SphereSegment::Surface is the Drawable which represents the specified area of the +sphere's surface. + */ +class SphereSegment::Surface: public osg::Drawable +{ +public: + Surface(SphereSegment* ss): Drawable(), _ss(ss) {} + + Surface():_ss(0) + { + osg::notify(osg::WARN)<< + "Warning: unexpected call to osgSim::SphereSegment::Surface() default constructor"<Surface_drawImplementation(state); +} + +bool SphereSegment::Surface::computeBound() const +{ + _bbox_computed = _ss->Surface_computeBound(_bbox); + return _bbox_computed; +} + + +/** +SphereSegment::EdgeLine is the Drawable which represents the line around the edge +of the specified area of the sphere's EdgeLine. + */ +class SphereSegment::EdgeLine: public osg::Drawable +{ +public: + EdgeLine(SphereSegment* ss): Drawable(), _ss(ss) {} + + EdgeLine():_ss(0) + { + osg::notify(osg::WARN)<< + "Warning: unexpected call to osgSim::SphereSegment::EdgeLine() default constructor"<EdgeLine_drawImplementation(state); +} + +bool SphereSegment::EdgeLine::computeBound() const +{ + _bbox_computed = _ss->EdgeLine_computeBound(_bbox); + return _bbox_computed; +} + + + +/** +SphereSegment::Plane is a Drawable which represents one of the +planar areas, at either the minimum or maxium azimuth. + */ +class SphereSegment::Plane: public osg::Drawable +{ +public: + Plane(SphereSegment* ss, SphereSegment::PlaneOrientation po, SphereSegment::BoundaryAngle pa): + Drawable(), _ss(ss), _planeOrientation(po), _BoundaryAngle(pa) {} + + Plane():_ss(0) + { + osg::notify(osg::WARN)<< + "Warning: unexpected call to osgSim::SphereSegment::Plane() default constructor"<Plane_drawImplementation(state, _planeOrientation, _BoundaryAngle); +} + +bool SphereSegment::Plane::computeBound() const +{ + _bbox_computed = _ss->Plane_computeBound(_bbox, _planeOrientation, _BoundaryAngle); + return _bbox_computed; +} + + + +/** +SphereSegment::Spoke is a Drawable which represents a spoke. + */ +class SphereSegment::Spoke: public osg::Drawable +{ +public: + Spoke(SphereSegment* ss, SphereSegment::BoundaryAngle azAngle, SphereSegment::BoundaryAngle elevAngle): + Drawable(), _ss(ss), _azAngle(azAngle), _elevAngle(elevAngle) {} + + Spoke():_ss(0) + { + osg::notify(osg::WARN)<< + "Warning: unexpected call to osgSim::SphereSegment::Spoke() default constructor"<Spoke_drawImplementation(state, _azAngle, _elevAngle); +} + +bool SphereSegment::Spoke::computeBound() const +{ + _bbox_computed = _ss->Spoke_computeBound(_bbox, _azAngle, _elevAngle); + return _bbox_computed; +} + +SphereSegment::SphereSegment(const osg::Vec3& centre, float radius, const osg::Vec3& vec, float azRange, + float elevRange, int density): + Geode(), + _centre(centre), _radius(radius), + _density(density), + _drawMask(DrawMask(ALL)) +{ + // Rather than store the vector, we'll work out the azimuth boundaries and elev + // boundaries now, rather than at draw time. + setArea(vec, azRange, elevRange); + + init(); +} + +void SphereSegment::setCentre(const osg::Vec3& c) +{ + _centre = c; + dirtyAllDrawableDisplayLists(); + dirtyAllDrawableBounds(); + dirtyBound(); +} + +const osg::Vec3& SphereSegment::getCentre() const +{ + return _centre; +} + +void SphereSegment::setRadius(float r) +{ + _radius = r; + dirtyAllDrawableDisplayLists(); + dirtyAllDrawableBounds(); + dirtyBound(); +} + +float SphereSegment::getRadius() const +{ + return _radius; +} + + +void SphereSegment::setArea(const osg::Vec3& v, float azRange, float elevRange) +{ + osg::Vec3 vec(v); + + vec.normalize(); // Make sure we're unit length + + // Calculate the elevation range + float elev = asin(vec.z()); // Elevation angle + elevRange /= 2.0f; + _elevMin = elev - elevRange; + _elevMax = elev + elevRange; + + // Calculate the azimuth range, cater for trig ambiguities + float xyLen = cos(elev); + float az; + if(vec.x() != 0.0f) az = asin(vec.x()/xyLen); + else az = acos(vec.y()/xyLen); + + azRange /= 2.0f; + _azMin = az - azRange; + _azMax = az + azRange; + + dirtyAllDrawableDisplayLists(); + dirtyAllDrawableBounds(); + dirtyBound(); +} + +void SphereSegment::getArea(osg::Vec3& vec, float& azRange, float& elevRange) const +{ + azRange = _azMax - _azMin; + elevRange = _elevMax - _elevMin; + + float az = azRange/2.0f; + float elev = elevRange/2.0f; + vec.set(cos(elev)*sin(az), cos(elev)*cos(az), sin(elev)); +} + +void SphereSegment::setDensity(int density) +{ + _density = density; + dirtyAllDrawableDisplayLists(); +} + +int SphereSegment::getDensity() const +{ + return _density; +} + +void SphereSegment::init() +{ + addDrawable(new Surface(this)); + + addDrawable(new EdgeLine(this)); + + addDrawable(new Plane(this,AZIM,MIN)); + addDrawable(new Plane(this,AZIM,MAX)); + addDrawable(new Plane(this,ELEV,MIN)); + addDrawable(new Plane(this,ELEV,MAX)); + + addDrawable(new Spoke(this,MIN,MIN)); + addDrawable(new Spoke(this,MIN,MAX)); + addDrawable(new Spoke(this,MAX,MIN)); + addDrawable(new Spoke(this,MAX,MAX)); +} + +namespace +{ + +struct DirtyDisplayList +{ + void operator()(osg::ref_ptr& dptr) + { + dptr->dirtyDisplayList(); + } +}; + +} + +void SphereSegment::dirtyAllDrawableDisplayLists() +{ + for_each(_drawables.begin(), _drawables.end(), DirtyDisplayList()); +} + +namespace +{ + +struct DirtyBound +{ + void operator()(osg::ref_ptr& dptr) + { + dptr->dirtyBound(); + } +}; + +} + +void SphereSegment::dirtyAllDrawableBounds() +{ + for_each(_drawables.begin(), _drawables.end(), DirtyBound()); +} + +void SphereSegment::Surface_drawImplementation(osg::State& /* state */) const +{ + const float azIncr = (_azMax - _azMin)/_density; + const float elevIncr = (_elevMax - _elevMin)/_density; + + // Draw the area on the sphere surface if needed + // --------------------------------------------- + if(_drawMask & SURFACE) + { + glColor4fv(_surfaceColor.ptr()); + + for(int i=0; i+1<=_density; i++) + { + // Because we're drawing quad strips, we need to work out + // two azimuth values, to form each edge of the (z-vertical) + // strips + float az1 = _azMin + (i*azIncr); + float az2 = _azMin + ((i+1)*azIncr); + + glBegin(GL_QUAD_STRIP); + for (int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + + // QuadStrip Edge formed at az1 + // ---------------------------- + + // Work out the sphere normal + float x = cos(elev)*sin(az1); + float y = cos(elev)*cos(az1); + float z = sin(elev); + + glNormal3f(x, y, z); + glVertex3f(_centre.x() + _radius*x, + _centre.y() + _radius*y, + _centre.z() + _radius*z); + + // QuadStrip Edge formed at az2 + // ---------------------------- + + // Work out the sphere normal + x = cos(elev)*sin(az2); + y = cos(elev)*cos(az2); + // z = sin(elev); z doesn't change + + glNormal3f(x, y, z); + glVertex3f(_centre.x() + _radius*x, + _centre.y() + _radius*y, + _centre.z() + _radius*z); + } + glEnd(); + } + } +} + +bool SphereSegment::Surface_computeBound(osg::BoundingBox& bbox) const +{ + bbox.init(); + + float azIncr = (_azMax - _azMin)/_density; + float elevIncr = (_elevMax - _elevMin)/_density; + + for(int i=0; i<=_density; i++){ + + float az = _azMin + (i*azIncr); + + for(int j=0; j<=_density; j++){ + + float elev = _elevMin + (j*elevIncr); + + bbox.expandBy( + osg::Vec3(_centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)) + ); + } + } + return true; +} + +void SphereSegment::EdgeLine_drawImplementation(osg::State& /* state */) const +{ + // FIXME: Disable lighting for this draw routine + + const float azIncr = (_azMax - _azMin)/_density; + const float elevIncr = (_elevMax - _elevMin)/_density; + + // Draw the edgeline if necessary + // ------------------------------ + if(_drawMask & EDGELINE) + { + glColor4fv(_edgeLineColor.ptr()); + + // Top edge + glBegin(GL_LINE_STRIP); + for(int i=0; i<=_density; i++) + { + float az = _azMin + (i*azIncr); + glVertex3f( + _centre.x() + _radius*cos(_elevMax)*sin(az), + _centre.y() + _radius*cos(_elevMax)*cos(az), + _centre.z() + _radius*sin(_elevMax)); + } + glEnd(); + + // Bottom edge + glBegin(GL_LINE_STRIP); + for(int i=0; i<=_density; i++) + { + float az = _azMin + (i*azIncr); + glVertex3f( + _centre.x() + _radius*cos(_elevMin)*sin(az), + _centre.y() + _radius*cos(_elevMin)*cos(az), + _centre.z() + _radius*sin(_elevMin)); + } + glEnd(); + + // Left edge + glBegin(GL_LINE_STRIP); + for(int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + glVertex3f( + _centre.x() + _radius*cos(elev)*sin(_azMin), + _centre.y() + _radius*cos(elev)*cos(_azMin), + _centre.z() + _radius*sin(elev)); + } + glEnd(); + + // Right edge + glBegin(GL_LINE_STRIP); + for(int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + glVertex3f( + _centre.x() + _radius*cos(elev)*sin(_azMax), + _centre.y() + _radius*cos(elev)*cos(_azMax), + _centre.z() + _radius*sin(elev)); + } + glEnd(); + } +} + +bool SphereSegment::EdgeLine_computeBound(osg::BoundingBox& bbox) const +{ + bbox.init(); + + float azIncr = (_azMax - _azMin)/_density; + float elevIncr = (_elevMax - _elevMin)/_density; + + // Top edge + for(int i=0; i<=_density; i++) + { + float az = _azMin + (i*azIncr); + bbox.expandBy( + _centre.x() + _radius*cos(_elevMax)*sin(az), + _centre.y() + _radius*cos(_elevMax)*cos(az), + _centre.z() + _radius*sin(_elevMax)); + } + + // Bottom edge + for(int i=0; i<=_density; i++) + { + float az = _azMin + (i*azIncr); + bbox.expandBy( + _centre.x() + _radius*cos(_elevMin)*sin(az), + _centre.y() + _radius*cos(_elevMin)*cos(az), + _centre.z() + _radius*sin(_elevMin)); + } + + // Left edge + for(int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + bbox.expandBy( + _centre.x() + _radius*cos(elev)*sin(_azMin), + _centre.y() + _radius*cos(elev)*cos(_azMin), + _centre.z() + _radius*sin(elev)); + } + + // Right edge + for(int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + bbox.expandBy( + _centre.x() + _radius*cos(elev)*sin(_azMax), + _centre.y() + _radius*cos(elev)*cos(_azMax), + _centre.z() + _radius*sin(elev)); + } + + return true; +} + +void SphereSegment::Plane_drawImplementation(osg::State& /* state */, + SphereSegment::PlaneOrientation orientation, + SphereSegment::BoundaryAngle boundaryAngle) const +{ + // Draw the planes if necessary + // ---------------------------- + if(_drawMask & PLANES) + { + if(orientation == AZIM) // This is a plane at a given azimuth + { + const float az = (boundaryAngle==MIN?_azMin:_azMax); + const float elevIncr = (_elevMax - _elevMin)/_density; + + // Normal + osg::Vec3 normal = osg::Vec3(cos(_elevMin)*sin(az), cos(_elevMin)*cos(az), sin(_elevMin)) + ^ osg::Vec3(cos(_elevMax)*sin(az), cos(_elevMax)*cos(az), sin(_elevMax)); + if(boundaryAngle==MIN) normal = -normal; // Make sure normals orientationint 'outwards' + glNormal3fv(normal.ptr()); + + // Tri fan + glBegin(GL_TRIANGLE_FAN); + glVertex3fv(_centre.ptr()); + for (int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + glVertex3f( _centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)); + } + glEnd(); + } + else if(orientation == ELEV) // This is a plane at a given elevation + { + const float elev = (boundaryAngle==MIN?_elevMin:_elevMax); + const float azIncr = (_azMax - _azMin)/_density; + + // Normal + osg::Vec3 normal = osg::Vec3(cos(elev)*sin(_azMax), cos(elev)*cos(_azMax), sin(elev)) + ^ osg::Vec3(cos(elev)*sin(_azMin), cos(elev)*cos(_azMin), sin(elev)); + if(boundaryAngle==MIN) normal = -normal; // Make sure normals orientationint 'outwards' + glNormal3fv(normal.ptr()); + + // Tri fan + glBegin(GL_TRIANGLE_FAN); + glVertex3fv(_centre.ptr()); + for(int i=0; i<=_density; i++) + { + float az = _azMin + (i*azIncr); + glVertex3f( _centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)); + } + glEnd(); + } + } +} + +bool SphereSegment::Plane_computeBound(osg::BoundingBox& bbox, + SphereSegment::PlaneOrientation orientation, + SphereSegment::BoundaryAngle boundaryAngle) const +{ + bbox.init(); + bbox.expandBy(_centre); + + if(orientation == AZIM) // This is a plane at a given azimuth + { + const float az = (boundaryAngle==MIN?_azMin:_azMax); + const float elevIncr = (_elevMax - _elevMin)/_density; + + for (int j=0; j<=_density; j++) + { + float elev = _elevMin + (j*elevIncr); + bbox.expandBy( + _centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)); + } + } + else if(orientation == ELEV) // This is a plane at a given elevation + { + const float elev = (boundaryAngle==MIN?_elevMin:_elevMax); + const float azIncr = (_azMax - _azMin)/_density; + + for(int i=0; i<=_density; i++) + { + float az = _azMin + (i*azIncr); + bbox.expandBy( + _centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)); + } + } + + return true; +} + +void SphereSegment::Spoke_drawImplementation(osg::State&, BoundaryAngle azAngle, BoundaryAngle elevAngle) const +{ + // FIXME: Disable lighting for this draw routine + + if(_drawMask & SPOKES){ + + glColor4fv(_spokeColor.ptr()); + + const float az = (azAngle==MIN?_azMin:_azMax); + const float elev = (elevAngle==MIN?_elevMin:_elevMax); + + glBegin(GL_LINES); + glVertex3fv(_centre.ptr()); + glVertex3f( _centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)); + glEnd(); + } +} + +bool SphereSegment::Spoke_computeBound(osg::BoundingBox& bbox, BoundaryAngle azAngle, BoundaryAngle elevAngle) const +{ + const float az = (azAngle==MIN?_azMin:_azMax); + const float elev = (elevAngle==MIN?_elevMin:_elevMax); + + bbox.expandBy(_centre); + bbox.expandBy( _centre.x() + _radius*cos(elev)*sin(az), + _centre.y() + _radius*cos(elev)*cos(az), + _centre.z() + _radius*sin(elev)); + + return true; +} + +void SphereSegment::setDrawMask(DrawMask dm) +{ + _drawMask=dm; + dirtyAllDrawableDisplayLists(); + dirtyAllDrawableBounds(); + dirtyBound(); +} + +namespace{ + +struct ActivateTransparencyOnType +{ + ActivateTransparencyOnType(const std::type_info& t): _t(t) {} + + void operator()(osg::ref_ptr& dptr) const + { + if(typeid(*dptr)==_t) + { + osg::StateSet* ss = dptr->getStateSet(); + if(!ss) + { + ss = new osg::StateSet(); + dptr->setStateSet(ss); + } + ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + + osg::BlendFunc* trans = new osg::BlendFunc; + trans->setFunction(osg::BlendFunc::ONE,osg::BlendFunc::ONE); + + ss->setAttributeAndModes(trans,osg::StateAttribute::ON); + + dptr->dirtyDisplayList(); + } + } + + const std::type_info& _t; +}; + +struct DeactivateTransparencyOnType +{ + DeactivateTransparencyOnType(const std::type_info& t): _t(t) {} + + void operator()(osg::ref_ptr& dptr) const + { + if(typeid(*dptr)==_t) + { + osg::StateSet* ss = dptr->getStateSet(); + if(ss) ss->setRenderingHint(osg::StateSet::OPAQUE_BIN); + + dptr->dirtyDisplayList(); + } + } + + const std::type_info& _t; +}; + +} + +void SphereSegment::setSurfaceColor(const osg::Vec4& c) +{ + _surfaceColor=c; + + if(c.w() != 1.0) for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(Surface))); + else for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(Surface))); +} + +void SphereSegment::setSpokeColor(const osg::Vec4& c) +{ + _spokeColor=c; + + if(c.w() != 1.0) for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(Spoke))); + else for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(Spoke))); +} + +void SphereSegment::setEdgeLineColor(const osg::Vec4& c) +{ + _edgeLineColor=c; + + if(c.w() != 1.0) for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(EdgeLine))); + else for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(EdgeLine))); +} + +void SphereSegment::setPlaneColor(const osg::Vec4& c) +{ + _planeColor=c; + + if(c.w() != 1.0) for_each(_drawables.begin(), _drawables.end(), ActivateTransparencyOnType(typeid(Plane))); + else for_each(_drawables.begin(), _drawables.end(), DeactivateTransparencyOnType(typeid(Plane))); +} + +void SphereSegment::setAllColors(const osg::Vec4& c) +{ + setSurfaceColor(c); + setSpokeColor(c); + setEdgeLineColor(c); + setPlaneColor(c); +}