/* -*-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_SECTOR #define OSGSIM_SECTOR 1 #include #include #include #include #include #include namespace osgSim { class Sector : public osg::Object { public: Sector() {} Sector(const Sector& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY): osg::Object(copy,copyop) {} virtual const char *libraryName() const { return "osgSim"; } virtual const char *className() const { return "Sector"; } virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast(obj) != 0; } 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); void getAzimuthRange(float& minAzimuth, float& maxAzimuth, float& fadeAngle) const; 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; float getFadeAngle() 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(const AzimSector& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY): Sector(copy,copyop), AzimRange(copy) {} AzimSector(float minAzimuth,float maxAzimuth,float fadeAngle=0.0f); META_Object(osgSim,AzimSector) virtual float operator() (const osg::Vec3& eyeLocal) const; protected: virtual ~AzimSector() {} }; class OSGSIM_EXPORT ElevationSector : public Sector, public ElevationRange { public: ElevationSector(): Sector(), ElevationRange() {} ElevationSector(const ElevationSector& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY): Sector(copy,copyop), ElevationRange(copy) {} ElevationSector(float minElevation,float maxElevation,float fadeAngle=0.0f); META_Object(osgSim,ElevationSector) 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(const AzimElevationSector& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY): Sector(copy,copyop), AzimRange(copy), ElevationRange(copy) {} AzimElevationSector(float minAzimuth,float maxAzimuth,float minElevation,float maxElevation,float fadeAngle=0.0f); META_Object(osgSim,AzimElevationSector) 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 ConeSector& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY): Sector(copy,copyop), _axis(copy._axis), _cosAngle(copy._cosAngle), _cosAngleFade(copy._cosAngleFade) {} ConeSector(const osg::Vec3& axis,float angle,float fadeangle=0.0f); META_Object(osgSim,ConeSector) 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