From e02ae73edcf5f55b168b1d859cf82be2f83a0dd8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 19 Nov 2002 10:57:40 +0000 Subject: [PATCH] Added osgSim library which encapulsulates light points. Added osglightpoint demo. --- Make/makedirdefs | 8 +- NEWS | 6 +- include/osgSim/BlinkSequence | 151 +++++++++++ include/osgSim/Export | 40 +++ include/osgSim/LightPoint | 44 +++ include/osgSim/LightPointDrawable | 113 ++++++++ include/osgSim/LightPointNode | 72 +++++ include/osgSim/Sector | 203 ++++++++++++++ include/osgSim/Version | 41 +++ src/Demos/osglightpoint/Makefile | 16 ++ src/Demos/osglightpoint/Makefile.inst | 12 + src/Demos/osglightpoint/osglightpoint.cpp | 201 ++++++++++++++ src/osgPlugins/osg/StateSet.cpp | 2 + src/osgSim/BlinkSequence.cpp | 40 +++ src/osgSim/LightPoint.cpp | 35 +++ src/osgSim/LightPointDrawable.cpp | 131 +++++++++ src/osgSim/LightPointNode.cpp | 310 ++++++++++++++++++++++ src/osgSim/Makefile | 19 ++ src/osgSim/Sector.cpp | 178 +++++++++++++ 19 files changed, 1618 insertions(+), 4 deletions(-) create mode 100644 include/osgSim/BlinkSequence create mode 100644 include/osgSim/Export create mode 100644 include/osgSim/LightPoint create mode 100644 include/osgSim/LightPointDrawable create mode 100644 include/osgSim/LightPointNode create mode 100644 include/osgSim/Sector create mode 100644 include/osgSim/Version create mode 100644 src/Demos/osglightpoint/Makefile create mode 100644 src/Demos/osglightpoint/Makefile.inst create mode 100644 src/Demos/osglightpoint/osglightpoint.cpp create mode 100644 src/osgSim/BlinkSequence.cpp create mode 100644 src/osgSim/LightPoint.cpp create mode 100644 src/osgSim/LightPointDrawable.cpp create mode 100644 src/osgSim/LightPointNode.cpp create mode 100644 src/osgSim/Makefile create mode 100644 src/osgSim/Sector.cpp diff --git a/Make/makedirdefs b/Make/makedirdefs index 954b76ecb..c0c507252 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -14,6 +14,7 @@ SRC_DIRS = \ osgParticle\ osgGLUT\ osgText\ + osgSim\ osgPlugins\ Demos @@ -80,27 +81,28 @@ DEMOS_DIRS = \ osgcopy\ osgcube\ osgcubemap\ + osggeodemo\ osggeometry\ osghangglide\ osghud\ osgimpostor\ osglight\ + osglightpoint\ osgmultitexture\ osgoccluder\ - osggeodemo\ osgparticle\ osgprerender\ osgreflect\ osgscribe\ - osgstereoimage\ osgsequence\ osgshape\ + osgstereoimage\ osgteapot\ osgtext\ osgtexture1D\ osgtexture2D\ osgtexture3D\ osgunittests\ - osgviews\ osgversion\ + osgviews\ sgv diff --git a/NEWS b/NEWS index 9063ec3e8..704e882d3 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,13 @@ OSG News (most significant items from ChangeLog) ================================================ + Addition osgSim which is NodeKit designed for visual simulation + market, currently features high fidelity light points support. + + 13th November 2002 - OpenSceneGraph-0.9.2.tar.gz - >>> New AC3D and GEO loaders, new Shape primitives, improved OpenFlight support. . + >>> New AC3D and GEO loaders, new Shape primitives, improved OpenFlight support. From Geoff Michel, AC3D .wc and Carbon Graphics GEO .geo loaders. diff --git a/include/osgSim/BlinkSequence b/include/osgSim/BlinkSequence new file mode 100644 index 000000000..21b7f5619 --- /dev/null +++ b/include/osgSim/BlinkSequence @@ -0,0 +1,151 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_BLINKSQUENCE +#define OSGSIM_BLINKSQUENCE 1 + +#include + +#include +#include +#include +#include + +#include + +namespace osgSim { + +class OSGSIM_EXPORT BlinkSequence : public osg::Referenced +{ + public: + + /** sequence group which can be used to synchronize related blink sequences.*/ + class OSGSIM_EXPORT SequenceGroup : public osg::Referenced + { + public: + + SequenceGroup(); + SequenceGroup(double baseTime); + + double _baseTime; + }; + + + BlinkSequence(); + + BlinkSequence(const BlinkSequence& bs); + + + /** add a pulse of specified color and duration to the BlinkSequence.*/ + inline void addPulse(double length,const osg::Vec4& color); + + /** get the total pulse period of the blink sequence, which is equal to the sum of all the pulse periods.*/ + inline double getPulsePeriod() const { return _pulsePeriod; } + + /** set the sequence group which can be used to synchronize related blink sequences.*/ + inline void setSequenceGroup(SequenceGroup* sg) { _sequenceGroup = sg; } + + /** get the non const sequence group.*/ + inline SequenceGroup* getSequenceGroup() { return _sequenceGroup.get(); } + + /** get the const sequence group.*/ + inline const SequenceGroup* getSequenceGroup() const { return _sequenceGroup.get(); } + + /** set the phase shift of the blink sequence, this would be used to shift a sequence within a sequence group.*/ + inline void setPhaseShift(double ps) { _phaseShift = ps; } + + /** get the pahse shift.*/ + inline double getPhaseShift() const { return _phaseShift; } + + + + /** compute the local time clamped to this BlinkSequences period, and accounting for the phase shift and sequence group.*/ + inline double localTime(double time) const; + + /** compute the color for the time interval sepecifed. Averages the colors if the length is greater than the current pulse.*/ + inline osg::Vec4 color(double time,double length) const; + + + protected: + + + typedef std::pair IntervalColor; + typedef std::vector PulseData; + + double _pulsePeriod; + double _phaseShift; + PulseData _pulseData; + osg::ref_ptr _sequenceGroup; +}; + + +inline double BlinkSequence::localTime(double time) const +{ + if (_sequenceGroup.valid()) time -= _sequenceGroup->_baseTime; + time -= _phaseShift; + return time - floor(time/_pulsePeriod)*_pulsePeriod; +} + +inline void BlinkSequence::addPulse(double length,const osg::Vec4& color) +{ + _pulseData.push_back(IntervalColor(length,color)); + _pulsePeriod += length; +} + +inline osg::Vec4 BlinkSequence::color(double time,double length) const +{ + if (_pulseData.empty()) return osg::Vec4(1.0f,1.0f,1.0f,1.0f); + double lt = localTime(time); + PulseData::const_iterator itr = _pulseData.begin(); + + // find the first sample at this time point. + while (lt>itr->first) + { + lt -= itr->first; + ++itr; + if (itr==_pulseData.end()) itr = _pulseData.begin(); + } + + // if time interval fits inside the current pulse + // then simply return this pulses color value. + if (lt+length<=itr->first) + { + return itr->second; + } + + // time length exceeds the current pulse therefore + // we have to average out the pules to get the correct + // results... + + // accumulate final part of the first active pulses. + osg::Vec4 color(itr->second*(itr->first-lt)); + double len = length-(itr->first-lt); + ++itr; + if (itr==_pulseData.end()) itr = _pulseData.begin(); + + // accumulate all the whole pluses pulses. + while (len>itr->first) + { + len -= itr->first; + color += itr->second*itr->first; + ++itr; + if (itr==_pulseData.end()) itr = _pulseData.begin(); + } + + // add remaining part of the final pulse. + color += itr->second*len; + + // normalise the time waited color. + color /= length; + + return color; +} + +} + +#endif diff --git a/include/osgSim/Export b/include/osgSim/Export new file mode 100644 index 000000000..cd46a8b6e --- /dev/null +++ b/include/osgSim/Export @@ -0,0 +1,40 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_EXPORT_ +#define OSGSIM_EXPORT_ 1 + +#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__)) + #pragma warning( disable : 4244 ) + #pragma warning( disable : 4251 ) + #pragma warning( disable : 4275 ) + #pragma warning( disable : 4786 ) + #pragma warning( disable : 4290 ) +#endif + +#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__) + # ifdef OSGSIM_LIBRARY + # define OSGSIM_EXPORT __declspec(dllexport) + # else + # define OSGSIM_EXPORT __declspec(dllimport) + # endif /* SG_LIBRARY */ +#else + # define OSGSIM_EXPORT +#endif + +/* Define NULL pointer value */ + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +#endif diff --git a/include/osgSim/LightPoint b/include/osgSim/LightPoint new file mode 100644 index 000000000..d8310855c --- /dev/null +++ b/include/osgSim/LightPoint @@ -0,0 +1,44 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_LGIHTPOINT +#define OSGSIM_LIGHTPOINT 1 + +#include +#include +#include + +#include +#include +#include + +namespace osgSim { + + +class OSGSIM_EXPORT LightPoint +{ + public: + + LightPoint(); + + LightPoint(const LightPoint& lp); + + bool _on; + osg::Vec3 _position; + osg::Vec4 _color; + float _intensity; + float _radius; + float _maxPixelSize; + + osg::ref_ptr _sector; + osg::ref_ptr _blinkSequence; +}; + +} + +#endif diff --git a/include/osgSim/LightPointDrawable b/include/osgSim/LightPointDrawable new file mode 100644 index 000000000..4ab851818 --- /dev/null +++ b/include/osgSim/LightPointDrawable @@ -0,0 +1,113 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_LIGHTPOINTDRAWABLE +#define OSGSIM_LIGHTPOINTDRAWABLE 1 + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace osgSim { + + +class OSGSIM_EXPORT LightPointDrawable : public osg::Drawable +{ + public : + + LightPointDrawable(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + LightPointDrawable(const LightPointDrawable&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + virtual osg::Object* cloneType() const { return osgNew LightPointDrawable(); } + virtual osg::Object* clone(const osg::CopyOp&) const { return osgNew LightPointDrawable(); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "LightPointDrawable"; } + + + //typedef std::pair ColorPosition; + struct ColorPosition + { + unsigned long first; + osg::Vec3 second; + ColorPosition() {} + ColorPosition(unsigned long f,const osg::Vec3& s):first(f),second(s) {} + }; + + void reset() + { + for(SizedLightPointList::iterator itr=_sizedLightPointList.begin(); + itr!=_sizedLightPointList.end(); + ++itr) + { + if (!itr->empty()) + itr->erase(itr->begin(),itr->end()); + } + + } + + inline void addLightPoint(unsigned int pointSize,const osg::Vec3& position,const osg::Vec4& color) + { + if (pointSize>=_sizedLightPointList.size()) _sizedLightPointList.resize(pointSize+1); + _sizedLightPointList[pointSize].push_back(ColorPosition(color.asRGBA(),position)); + } + + /** draw LightPoints. */ + virtual void drawImplementation(osg::State& state) const; + + + void setReferenceTime(double time) + { + _referenceTime = time; + _referenceTimeInterval = 0.0; + } + + void updateReferenceTime(double time) + { + _referenceTimeInterval = osg::clampAbove(time-_referenceTime,0.0); + _referenceTime = time; + } + + double getReferenceTime() const { return _referenceTime; } + double getReferenceTimeInterval() const { return _referenceTimeInterval; } + + protected: + + virtual bool computeBound() const; + + ~LightPointDrawable() {} + + double _referenceTime; + double _referenceTimeInterval; + + typedef std::vector LightPointList; + typedef std::vector SizedLightPointList; + + SizedLightPointList _sizedLightPointList; + + osg::ref_ptr _depthOff; + osg::ref_ptr _depthOn; + osg::ref_ptr _blendOn; + osg::ref_ptr _colorMaskOff; + osg::ref_ptr _point; + + +}; + +} + +#endif diff --git a/include/osgSim/LightPointNode b/include/osgSim/LightPointNode new file mode 100644 index 000000000..184c337e8 --- /dev/null +++ b/include/osgSim/LightPointNode @@ -0,0 +1,72 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_LIGHTPOINTNODE +#define OSGSIM_LIGHTPOINTNODE 1 + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace osgSim { + + +class OSGSIM_EXPORT LightPointNode : public osg::Node +{ + public : + + typedef std::vector< LightPoint > LightPointList; + + LightPointNode(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + LightPointNode(const LightPointNode&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Node(osgSim,LightPointNode); + + virtual void traverse(osg::NodeVisitor& nv); + + + unsigned int addLightPoint(const LightPoint& lp); + + LightPoint& getLightPoint(unsigned int pos) { return _lightPointList[pos]; } + + const LightPoint& getLightPoint(unsigned int pos) const { return _lightPointList[pos]; } + + void removeLightPoint(unsigned int pos); + + void removeLightPoints(LightPointList::iterator start,LightPointList::iterator end); + + LightPointList _lightPointList; + + protected: + + ~LightPointNode() {} + + // used to cache the bouding box of the lightpoints as a tighter + // view frustum check. + mutable osg::BoundingBox _bbox; + + virtual bool computeBound() const; + + + +}; + +} + +#endif diff --git a/include/osgSim/Sector b/include/osgSim/Sector new file mode 100644 index 000000000..b5c84105c --- /dev/null +++ b/include/osgSim/Sector @@ -0,0 +1,203 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_SECTOR +#define OSGSIM_SECTOR 1 + +#include + +#include +#include +#include +#include + +namespace osgSim { + +class Sector : public osg::Referenced +{ + public: + virtual float operator() (const osg::Vec3& /*eyeLocal*/) const = 0; + + protected: + + virtual ~Sector() {} +}; + +class OSGSIM_EXPORT AzimRange +{ + public: + + AzimRange(): + _cosAzim(1.0f), + _sinAzim(0.0f), + _cosAngle(-1.0f), + _cosFadeAngle(-1.0f) {} + + void setAzimuthRange(float minAzimuth,float maxAzimuth,float fadeAngle=0.0f); + + + inline float azimSector(const osg::Vec3& eyeLocal) const + { + float dotproduct = eyeLocal.x()*_sinAzim+eyeLocal.y()*_cosAzim; + float length = sqrt(osg::square(eyeLocal.x())+osg::square(eyeLocal.y())); + if (dotproduct<_cosFadeAngle*length) return 0.0f; // out of sector. + if (dotproduct>_cosAngle*length) return 1.0f; // fully in sector. + return (dotproduct-_cosFadeAngle*length)/((_cosAngle-_cosFadeAngle)*length); + } + + protected: + + float _cosAzim; + float _sinAzim; + float _cosAngle; + float _cosFadeAngle; +}; + + +class OSGSIM_EXPORT ElevationRange +{ + public: + + + ElevationRange(): + _cosMinElevation(-1.0f), + _cosMinFadeElevation(-1.0f), + _cosMaxElevation(1.0), + _cosMaxFadeElevation(1.0) {} + + void setElevationRange(float minElevation,float maxElevation,float fadeAngle=0.0f); + + float getMinElevation() const; + + float getMaxElevation() const; + + inline float elevationSector(const osg::Vec3& eyeLocal) const + { + float dotproduct = eyeLocal.z(); // against z axis - eyeLocal*(0,0,1). + float length = eyeLocal.length(); + if (dotproduct>_cosMaxFadeElevation*length) return 0.0f; // out of sector + if (dotproduct<_cosMinFadeElevation*length) return 0.0f; // out of sector + if (dotproduct>_cosMaxElevation*length) + { + // in uppoer fade band. + return (dotproduct-_cosMaxFadeElevation*length)/((_cosMaxElevation-_cosMaxFadeElevation)*length); + } + if (dotproduct<_cosMinElevation*length) + { + // in lower fade band. + return (dotproduct-_cosMinFadeElevation*length)/((_cosMinElevation-_cosMinFadeElevation)*length); + } + return 1.0f; // fully in sector + } + + protected: + + float _cosMinElevation; + float _cosMinFadeElevation; + float _cosMaxElevation; + float _cosMaxFadeElevation; +}; + +class OSGSIM_EXPORT AzimSector : public Sector, public AzimRange +{ + public: + + AzimSector(): + Sector(), + AzimRange() {} + + AzimSector(float minAzimuth,float maxAzimuth,float fadeAngle=0.0f); + + virtual float operator() (const osg::Vec3& eyeLocal) const; + + protected: + + virtual ~AzimSector() {} + +}; + +class OSGSIM_EXPORT ElevationSector : public Sector, public ElevationRange +{ + public: + + + ElevationSector(): + Sector(), + ElevationRange() {} + + + ElevationSector(float minElevation,float maxElevation,float fadeAngle=0.0f); + + virtual float operator() (const osg::Vec3& eyeLocal) const; + + protected: + + virtual ~ElevationSector() {} + + float _cosMinElevation; + float _cosMinFadeElevation; + float _cosMaxElevation; + float _cosMaxFadeElevation; +}; + + +class OSGSIM_EXPORT AzimElevationSector : public Sector, public AzimRange, public ElevationRange +{ + public: + + AzimElevationSector(): + Sector(), + AzimRange(), + ElevationRange() {} + + AzimElevationSector(float minAzimuth,float maxAzimuth,float minElevation,float maxElevation,float fadeAngle=0.0f); + + virtual float operator() (const osg::Vec3& eyeLocal) const; + + protected: + + virtual ~AzimElevationSector() {} +}; + + +class OSGSIM_EXPORT ConeSector : public Sector +{ + public: + + ConeSector(): + Sector(), + _axis(0.0f,0.0f,1.0f), + _cosAngle(-1.0f), + _cosAngleFade(-1.0f) {} + + ConeSector(const osg::Vec3& axis,float angle,float fadeangle=0.0f); + + void setAxis(const osg::Vec3& axis); + + const osg::Vec3& getAxis() const; + + void setAngle(float angle,float fadeangle=0.0f); + + float getAngle() const; + + float getFadeAngle() const; + + virtual float operator() (const osg::Vec3& eyeLocal) const; + + protected: + + virtual ~ConeSector() {} + + osg::Vec3 _axis; + float _cosAngle; + float _cosAngleFade; +}; + +} + +#endif diff --git a/include/osgSim/Version b/include/osgSim/Version new file mode 100644 index 000000000..e9870ba95 --- /dev/null +++ b/include/osgSim/Version @@ -0,0 +1,41 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#ifndef OSGSIM_VERSION +#define OSGSIM_VERSION 1 + +#include + +extern "C" { + +/** + * osgSimGetVersion() returns the library version number. + * Numbering convention : OpenSceneGraph-Sim-0.1 will return 0.1 from osgSimgetVersion. + * + * This C function can be also used to check for the existence of the OpenSceneGraph + * library using autoconf and its m4 macro AC_CHECK_LIB. + * + * Here is the code to add to your configure.in: + \verbatim + # + # Check for the OpenSceneGraph-Sim library + # + AC_CHECK_LIB(osg, osgSimGetVersion, , + [AC_MSG_ERROR(OpenSceneGraph library not found. See http://www.openscenegraph.org)],) + \endverbatim +*/ +extern SG_EXPORT const char* osgSimGetVersion(); + +/** + * osgSimGetLibraryName() returns the library name in human friendly form. +*/ +extern SG_EXPORT const char* osgSimGetLibraryName(); + +} + +#endif diff --git a/src/Demos/osglightpoint/Makefile b/src/Demos/osglightpoint/Makefile new file mode 100644 index 000000000..898872371 --- /dev/null +++ b/src/Demos/osglightpoint/Makefile @@ -0,0 +1,16 @@ +TOPDIR = ../../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osglightpoint.cpp\ + +LIBS += -losgSim $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + Makefile.inst=Makefile + +EXEC = osglightpoint + +include $(TOPDIR)/Make/makerules + diff --git a/src/Demos/osglightpoint/Makefile.inst b/src/Demos/osglightpoint/Makefile.inst new file mode 100644 index 000000000..e83017aa7 --- /dev/null +++ b/src/Demos/osglightpoint/Makefile.inst @@ -0,0 +1,12 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osglightpoint.cpp\ + +LIBS += -losgSim $(OSG_LIBS) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osglightpoint + + +include $(TOPDIR)/Make/makerules diff --git a/src/Demos/osglightpoint/osglightpoint.cpp b/src/Demos/osglightpoint/osglightpoint.cpp new file mode 100644 index 000000000..09310831f --- /dev/null +++ b/src/Demos/osglightpoint/osglightpoint.cpp @@ -0,0 +1,201 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include + + +void write_usage(std::ostream& out,const std::string& name) +{ + out << std::endl; + out <<"usage:"<< std::endl; + out <<" "<addPulse(1.0,osg::Vec4(1.0f,0.0f,0.0f,1.0f)); +// bs->addPulse(0.5,osg::Vec4(0.0f,0.0f,0.0f,0.0f)); // off +// bs->addPulse(1.5,osg::Vec4(1.0f,1.0f,0.0f,1.0f)); +// bs->addPulse(0.5,osg::Vec4(0.0f,0.0f,0.0f,0.0f)); // off +// bs->addPulse(1.0,osg::Vec4(1.0f,1.0f,1.0f,1.0f)); +// bs->addPulse(0.5,osg::Vec4(0.0f,0.0f,0.0f,0.0f)); // off + + +// osgSim::Sector* sector = osgNew osgSim::ConeSector(osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0),osg::inDegrees(45.0)); +// osgSim::Sector* sector = osgNew osgSim::ElevationSector(-osg::inDegrees(45.0),osg::inDegrees(45.0),osg::inDegrees(45.0)); +// osgSim::Sector* sector = osgNew osgSim::AzimSector(-osg::inDegrees(45.0),osg::inDegrees(45.0),osg::inDegrees(90.0)); +// osgSim::Sector* sector = osgNew osgSim::AzimElevationSector(osg::inDegrees(180),osg::inDegrees(90), // azim range +// osg::inDegrees(0.0),osg::inDegrees(90.0), // elevation range +// osg::inDegrees(5.0)); + + for(int i=0;isetSequenceGroup(osgNew osgSim::BlinkSequence::SequenceGroup((double)i*0.1)); +// start._blinkSequence = local_bs; + +// start._sector = sector; + + osgSim::LightPointNode* lpn = osgNew osgSim::LightPointNode; + addToLightPointNode(*lpn,start,end,noStepsX); + + start._position += start_delta; + end._position += end_delta; + + transform->addChild(lpn); + } + + osg::Group* group = osgNew osg::Group; + group->addChild(transform); + + + return group; +} + + +int main( int argc, char **argv ) +{ + + // initialize the GLUT + glutInit( &argc, argv ); + + // create the commandline args. + std::vector commandLine; + for(int i=1;iaddChild(osgDB::readNodeFiles(commandLine)); + rootnode->addChild(createLightPointsDatabase()); + if (!rootnode) + { + return 1; + } + + // run optimization over the scene graph + osgUtil::Optimizer optimzer; + optimzer.optimize(rootnode); + + // add a viewport to the viewer and attach the scene graph. + viewer.addViewport( rootnode ); + + // register trackball, flight and drive. + viewer.registerCameraManipulator(new osgGA::TrackballManipulator); + viewer.registerCameraManipulator(new osgGA::FlightManipulator); + viewer.registerCameraManipulator(new osgGA::DriveManipulator); + + // open the viewer window. + viewer.open(); + + // fire up the event loop. + viewer.run(); + + return 0; +} diff --git a/src/osgPlugins/osg/StateSet.cpp b/src/osgPlugins/osg/StateSet.cpp index 71dc8da95..601c24a57 100644 --- a/src/osgPlugins/osg/StateSet.cpp +++ b/src/osgPlugins/osg/StateSet.cpp @@ -6,6 +6,8 @@ #include #include +#include + using namespace osg; using namespace osgDB; using namespace std; diff --git a/src/osgSim/BlinkSequence.cpp b/src/osgSim/BlinkSequence.cpp new file mode 100644 index 000000000..096d90b31 --- /dev/null +++ b/src/osgSim/BlinkSequence.cpp @@ -0,0 +1,40 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#include + +#include + +using namespace osgSim; + +BlinkSequence::BlinkSequence(): + Referenced(), + _pulsePeriod(0.0), + _phaseShift(0.0), + _pulseData(), + _sequenceGroup(0) {} + +BlinkSequence::BlinkSequence(const BlinkSequence& bs): + Referenced(), + _pulsePeriod(bs._pulsePeriod), + _phaseShift(bs._phaseShift), + _pulseData(bs._pulseData), + _sequenceGroup(bs._sequenceGroup) {} + + +BlinkSequence::SequenceGroup::SequenceGroup(): + Referenced() +{ + // set a random base time between 0 and 1000.0 + _baseTime = ((double)rand()/(double)RAND_MAX)*1000.0; +} + +BlinkSequence::SequenceGroup::SequenceGroup(double baseTime): + Referenced(), + _baseTime(baseTime) {} + diff --git a/src/osgSim/LightPoint.cpp b/src/osgSim/LightPoint.cpp new file mode 100644 index 000000000..08088044b --- /dev/null +++ b/src/osgSim/LightPoint.cpp @@ -0,0 +1,35 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#include + +using namespace osgSim; + +LightPoint::LightPoint(): + _on(true), + _position(0.0f,0.0f,0.0f), + _color(1.0f,1.0f,1.0f,1.0f), + _intensity(1.0f), + _radius(1.0f), + _maxPixelSize(30), + _sector(0), + _blinkSequence(0) +{ +} + +LightPoint::LightPoint(const LightPoint& lp): + _on(lp._on), + _position(lp._position), + _color(lp._color), + _intensity(lp._intensity), + _radius(lp._radius), + _maxPixelSize(lp._maxPixelSize), + _sector(lp._sector), + _blinkSequence(lp._blinkSequence) +{ +} diff --git a/src/osgSim/LightPointDrawable.cpp b/src/osgSim/LightPointDrawable.cpp new file mode 100644 index 000000000..9d7270c80 --- /dev/null +++ b/src/osgSim/LightPointDrawable.cpp @@ -0,0 +1,131 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#include + +#include + +using namespace osgSim; + +LightPointDrawable::LightPointDrawable(): + Drawable(), + _referenceTime(0.0), + _referenceTimeInterval(0.0), + _sizedLightPointList() +{ + setSupportsDisplayList(false); + + _depthOff = osgNew osg::Depth; + _depthOff->setWriteMask(false); + + _depthOn = osgNew osg::Depth; + _depthOn->setWriteMask(true); + + _blendOn = osgNew osg::BlendFunc; + _blendOn->setFunction(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE); + + _colorMaskOff = osgNew osg::ColorMask; + _colorMaskOff->setMask(false,false,false,false); + + _point = osgNew osg::Point; +} + +LightPointDrawable::LightPointDrawable(const LightPointDrawable& lpd,const osg::CopyOp& copyop): + Drawable(lpd,copyop), + _referenceTime(lpd._referenceTime), + _referenceTimeInterval(lpd._referenceTimeInterval), + _sizedLightPointList(lpd._sizedLightPointList) +{ +} + +void LightPointDrawable::drawImplementation(osg::State& state) const +{ + + if (_sizedLightPointList.empty()) return; + + + state.applyMode(GL_POINT_SMOOTH,true); + state.applyMode(GL_BLEND,true); + state.applyMode(GL_LIGHTING,false); + state.applyTextureMode(0,GL_TEXTURE_1D,false); + state.applyTextureMode(0,GL_TEXTURE_2D,false); + + + glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); + + state.applyAttribute(_blendOn.get()); + state.applyAttribute(_depthOff.get()); + + int pointsize; + SizedLightPointList::const_iterator sitr; + for(pointsize=1,sitr=_sizedLightPointList.begin(); + sitr!=_sizedLightPointList.end(); + ++sitr,++pointsize) + { + + const LightPointList& lpl = *sitr; + if (!lpl.empty()) + { + glPointSize(pointsize); + glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + //state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + glDrawArrays(GL_POINTS,0,lpl.size()); + } + } + + // switch on depth mask to do set up depth mask. + state.applyAttribute(_depthOn.get()); +// glDepthMask(GL_TRUE); + + state.applyMode(GL_BLEND,false); + + state.applyAttribute(_colorMaskOff.get()); +// glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + + for(pointsize=1,sitr=_sizedLightPointList.begin(); + sitr!=_sizedLightPointList.end(); + ++sitr,++pointsize) + { + + const LightPointList& lpl = *sitr; + if (!lpl.empty()) + { + glPointSize(pointsize); + glInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + //state.setInterleavedArrays(GL_C4UB_V3F,0,&lpl.front()); + glDrawArrays(GL_POINTS,0,lpl.size()); + } + } + + glPointSize(1); + + glHint(GL_POINT_SMOOTH_HINT,GL_FASTEST); + + state.haveAppliedAttribute(osg::StateAttribute::POINT); + +} + +bool LightPointDrawable::computeBound() const +{ + _bbox.init(); + + for(SizedLightPointList::const_iterator sitr=_sizedLightPointList.begin(); + sitr!=_sizedLightPointList.end(); + ++sitr) + { + const LightPointList& lpl = *sitr; + for(LightPointList::const_iterator litr=lpl.begin(); + litr!=lpl.end(); + ++litr) + { + _bbox.expandBy(litr->second); + } + } + + return true; +} diff --git a/src/osgSim/LightPointNode.cpp b/src/osgSim/LightPointNode.cpp new file mode 100644 index 000000000..c186ee747 --- /dev/null +++ b/src/osgSim/LightPointNode.cpp @@ -0,0 +1,310 @@ +//C++ header - Open Scene Graph Simulation - Copyright (C) 1998-2002 Robert Osfield +// Distributed under the terms of the GNU General Public License (GPL) +// as published by the Free Software Foundation. +// +// All software using osgSim must be GPL'd or excempted via the +// purchase of the Open Scene Graph Professional License (OSGPL) +// for further information contact robert@openscenegraph.com. + +#include +#include + +#include +#include +#include +#include + +#include + +#include + +using namespace osgSim; + +LightPointNode::LightPointNode() +{ +} + +/** Copy constructor using CopyOp to manage deep vs shallow copy.*/ +LightPointNode::LightPointNode(const LightPointNode& lpn,const osg::CopyOp& copyop): + Node(lpn,copyop), + _lightPointList(lpn._lightPointList) +{ +} + +unsigned int LightPointNode::addLightPoint(const LightPoint& lp) +{ + unsigned int num = _lightPointList.size(); + _lightPointList.push_back(lp); + dirtyBound(); + return num; +} + +void LightPointNode::removeLightPoint(unsigned int pos) +{ + if (pos<_lightPointList.size()) + { + _lightPointList.erase(_lightPointList.begin()+pos); + dirtyBound(); + } + dirtyBound(); +} + +void LightPointNode::removeLightPoints(LightPointList::iterator start,LightPointList::iterator end) +{ + _lightPointList.erase(start,end); +} + +bool LightPointNode::computeBound() const +{ + _bsphere.init(); + _bbox.init(); + + + LightPointList::const_iterator itr; + for(itr=_lightPointList.begin(); + itr!=_lightPointList.end(); + ++itr) + { + _bbox.expandBy(itr->_position); + } + + + _bsphere.set(_bbox.center(),0.0f); + + for(itr=_lightPointList.begin(); + itr!=_lightPointList.end(); + ++itr) + { + _bsphere.expandRadiusBy(itr->_position); + } + + _bsphere_computed=true; + return true; +} + + +void LightPointNode::traverse(osg::NodeVisitor& nv) +{ + //#define USE_TIMER + #ifdef USE_TIMER + osg::Timer timer; + osg::Timer_t t1=0,t2=0,t3=0,t4=0,t5=0,t6=0,t7=0,t8=0; + #endif + + +#ifdef USE_TIMER + t1 = timer.tick(); +#endif + + osgUtil::CullVisitor* cv = NULL; + if (typeid(nv)==typeid(osgUtil::CullVisitor)) + { + cv = static_cast(&nv); + } + +#ifdef USE_TIMER + t2 = timer.tick(); +#endif + + + // should we disabled small feature culling here? + if (cv /*&& !cv->isCulled(_bbox)*/) + { + + osg::Matrix matrix = cv->getModelViewMatrix(); + osg::Matrix& projection = cv->getProjectionMatrix(); + osgUtil::RenderGraph* rg = cv->getCurrentRenderGraph(); + + if (rg->leaves_empty()) + { + // this is first leaf to be added to RenderGraph + // and therefore should not already know to current render bin, + // so need to add it. + cv->getCurrentRenderBin()->addRenderGraph(rg); + } + +#ifdef USE_TIMER + t3 = timer.tick(); +#endif + + + LightPointDrawable* drawable = NULL; + osg::Referenced* object = rg->getUserData(); + if (object) + { + if (typeid(*object)==typeid(LightPointDrawable)) + { + // resuse the user data attached to the render graph. + drawable = static_cast(object); + + } + else + { + // will need to replace UserData. + osg::notify(osg::WARN) << "Warning: Replacing osgUtil::RenderGraph::_userData to support osgSim::LightPointNode, may have undefined results."<setUserData(drawable); + + if (cv->getFrameStamp()) + { + drawable->setReferenceTime(cv->getFrameStamp()->getReferenceTime()); + } + } + + // search for a drawable in the RenderLead list equal to the attached the one attached to RenderGraph user data + // as this will be our special light point drawable. + osgUtil::RenderGraph::LeafList::iterator litr; + for(litr = rg->_leaves.begin(); + litr != rg->_leaves.end() && (*litr)->_drawable!=drawable; + ++litr) + {} + + if (litr == rg->_leaves.end()) + { + // havn't found the drawable added in the RenderLeaf list, there this my be the + // first time through LightPointNode in this frame, so need to add drawable into the RenderGraph RenderLeaf list + // and update its time signatures. + + drawable->reset(); + rg->addLeaf(osgNew osgUtil::RenderLeaf(drawable,&projection,NULL,FLT_MAX)); + + // need to update the drawable's frame count. + if (cv->getFrameStamp()) + { + drawable->updateReferenceTime(cv->getFrameStamp()->getReferenceTime()); + } + + } + +#ifdef USE_TIMER + t4 = timer.tick(); +#endif + + +#ifdef USE_TIMER + t7 = timer.tick(); +#endif + + cv->updateCalculatedNearFar(matrix,_bbox); + + + const float minimumIntensity = 1.0f/256.0f; + const osg::Vec3 eyePoint = cv->getEyeLocal(); + + double time=drawable->getReferenceTime(); + double timeInterval=drawable->getReferenceTimeInterval(); + + const osg::Polytope clipvol(cv->getModelViewCullingStack().back()->getFrustum()); + const bool computeClipping = false;//(clipvol.getCurrentMask()!=0); + + //LightPointDrawable::ColorPosition cp; + for(LightPointList::iterator itr=_lightPointList.begin(); + itr!=_lightPointList.end(); + ++itr) + { + const LightPoint& lp = *itr; + + if (!lp._on) continue; + + const osg::Vec3& position = lp._position; + + // skip light point if it is not contianed in the view frustum. + if (computeClipping && !clipvol.contains(position)) continue; + + // delta vector between eyepoint and light point. + osg::Vec3 dv(eyePoint-position); + + float intensity = lp._intensity; + + // slip light point if it is intensity is 0.0 or negative. + if (intensity<=minimumIntensity) continue; + + osg::Vec4 color = lp._color; + + // check the sector. + if (lp._sector.valid()) + { + intensity *= (*lp._sector)(dv); + + // slip light point if it is intensity is 0.0 or negative. + if (intensity<=minimumIntensity) continue; + + } + + // temporary accounting of intensity. + //color *= intensity; + + // check the blink sequence. + if (lp._blinkSequence.valid()) + { + osg::Vec4 bs = lp._blinkSequence->color(time,timeInterval); + color[0] *= bs[0]; + color[1] *= bs[1]; + color[2] *= bs[2]; + color[3] *= bs[3]; + } + + // if alpha value is less than the min intentsive then skip + if (color[3]<=minimumIntensity) continue; + + float pixelSize = cv->pixelSize(position,lp._radius); + +// cout << "pixelsize = "<addLightPoint(0, position*matrix,color); + } + else if (pixelSizeaddLightPoint(lowerBoundPixelSize-1, xpos,color); + + //color[3] = osg::square(remainder); + color[3] = alpha*remainder; + drawable->addLightPoint(lowerBoundPixelSize, xpos,color); + } + else // use a billboard geometry. + { + drawable->addLightPoint((unsigned int)(lp._maxPixelSize-1.0), position*matrix,color); + } + } + +#ifdef USE_TIMER + t8 = timer.tick(); +#endif + + } +#ifdef USE_TIMER + cout << "compute"<