/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2019 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see
*/
#include
#include
#include
#include
#include
#include
#include
#include
using namespace osgEarth;
using namespace osgEarth::Annotation;
using namespace osgEarth::Features;
using namespace osgEarth::Symbology;
EllipseNode::EllipseNode() :
LocalGeometryNode()
{
construct();
}
void
EllipseNode::construct()
{
_radiusMajor.set(1.0, Units::KILOMETERS);
_radiusMinor.set(0.5, Units::KILOMETERS);
_rotationAngle = 0.0;
_arcStart.set(0.0, Units::RADIANS);
_arcEnd.set(2.0*osg::PI, Units::RADIANS);
_pie = false;
_numSegments = 0;
}
void
EllipseNode::set(const GeoPoint& position,
const Distance& radiusMajor,
const Distance& radiusMinor,
const Angle& rotationAngle,
const Style& style,
const Angle& arcStart,
const Angle& arcEnd,
const bool pie)
{
_radiusMajor = radiusMajor;
_radiusMinor = radiusMinor;
_rotationAngle = rotationAngle;
_arcStart = arcStart;
_arcEnd = arcEnd;
_pie = pie;
_style = style;
setPosition(position);
buildGeometry();
}
unsigned int
EllipseNode::getNumSegments() const
{
return _numSegments;
}
void
EllipseNode::setNumSegments(unsigned numSegments)
{
if (_numSegments != numSegments )
{
_numSegments = numSegments;
buildGeometry();
}
}
const Linear&
EllipseNode::getRadiusMajor() const
{
return _radiusMajor;
}
const Linear&
EllipseNode::getRadiusMinor() const
{
return _radiusMinor;
}
void
EllipseNode::setRadiusMajor( const Linear& radiusMajor )
{
setRadii( radiusMajor, _radiusMinor );
}
void
EllipseNode::setRadiusMinor( const Linear& radiusMinor )
{
setRadii( _radiusMajor, radiusMinor );
}
void
EllipseNode::setRadii( const Linear& radiusMajor, const Linear& radiusMinor )
{
if (_radiusMajor != radiusMajor || _radiusMinor != radiusMinor )
{
_radiusMajor = radiusMajor;
_radiusMinor = radiusMinor;
buildGeometry();
}
}
const Angular&
EllipseNode::getRotationAngle() const
{
return _rotationAngle;
}
void
EllipseNode::setRotationAngle(const Angular& rotationAngle)
{
if (_rotationAngle != rotationAngle)
{
_rotationAngle = rotationAngle;
buildGeometry();
}
}
const Angle&
EllipseNode::getArcStart(void) const
{
return _arcStart;
}
void
EllipseNode::setArcStart(const Angle& arcStart)
{
_arcStart = arcStart;
buildGeometry();
}
const Angle&
EllipseNode::getArcEnd(void) const
{
return _arcEnd;
}
void
EllipseNode::setArcEnd(const Angle& arcEnd)
{
_arcEnd = arcEnd;
buildGeometry();
}
const bool&
EllipseNode::getPie(void) const
{
return _pie;
}
void
EllipseNode::setPie(const bool& pie)
{
_pie = pie;
buildGeometry();
}
void
EllipseNode::buildGeometry()
{
// construct a local-origin ellipse.
GeometryFactory factory;
osg::ref_ptr geom;
if (std::abs(_arcEnd.as(Units::DEGREES) - _arcStart.as(Units::DEGREES)) >= 360.0)
{
geom = factory.createEllipse(osg::Vec3d(0,0,0), _radiusMajor, _radiusMinor, _rotationAngle, _numSegments);
}
else
{
geom = factory.createEllipticalArc(osg::Vec3d(0,0,0), _radiusMajor, _radiusMinor, _rotationAngle, _arcStart, _arcEnd, _numSegments, 0L, _pie);
}
if ( geom.valid() )
{
setGeometry( geom.get() );
}
}
//-------------------------------------------------------------------
OSGEARTH_REGISTER_ANNOTATION( ellipse, osgEarth::Annotation::EllipseNode );
EllipseNode::EllipseNode(const Config& conf,
const osgDB::Options* dbOptions) :
LocalGeometryNode(conf, dbOptions)
{
construct();
conf.get( "radius_major", _radiusMajor );
conf.get( "radius_minor", _radiusMinor );
conf.get( "rotation", _rotationAngle );
conf.get( "num_segments", _numSegments );
buildGeometry();
}
Config
EllipseNode::getConfig() const
{
Config conf = LocalGeometryNode::getConfig();
conf.key() = "ellipse";
conf.set( "radius_major", _radiusMajor );
conf.set( "radius_minor", _radiusMinor );
conf.set( "rotation", _rotationAngle );
if ( _numSegments != 0 )
conf.set( "num_segments", _numSegments );
return conf;
}