From 49625a1baf4c7cbb94362c8f9ee436a8b6552012 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 18 Oct 2013 07:31:22 +0000 Subject: [PATCH] From Andreas Henne, "in my application I use the TrackballDragger, the ScaleAxisDragger and the TranslateAxisDragger. Unfortunately these draggers are very thin and they do not provide methods to change their visual appearance. Another problem that I noticed is that lighting on the cones and boxes of the TranslateAxisDragger and ScaleAxisDragger is incorrect when the draggers are scaled due to not normalized normals. This small patch adresses these problems, providing methods to make the draggers thicker. I have attached a zip archive containing the corresponding files and also a modified osgManipulator example that makes use of the modifications. I don't want to retain any copyright." --- examples/osgmanipulator/osgmanipulator.cpp | 5 ++ include/osgManipulator/ScaleAxisDragger | 22 +++++ include/osgManipulator/TrackballDragger | 22 +++++ include/osgManipulator/TranslateAxisDragger | 30 +++++++ src/osgManipulator/ScaleAxisDragger.cpp | 43 +++++++--- src/osgManipulator/TrackballDragger.cpp | 81 +++++++++++-------- src/osgManipulator/TranslateAxisDragger.cpp | 60 +++++++++++--- .../osgManipulator/ScaleAxisDragger.cpp | 2 + .../osgManipulator/TrackballDragger.cpp | 2 + .../osgManipulator/TranslateAxisDragger.cpp | 3 + 10 files changed, 215 insertions(+), 55 deletions(-) diff --git a/examples/osgmanipulator/osgmanipulator.cpp b/examples/osgmanipulator/osgmanipulator.cpp index b62ba294f..beab4b295 100644 --- a/examples/osgmanipulator/osgmanipulator.cpp +++ b/examples/osgmanipulator/osgmanipulator.cpp @@ -106,6 +106,8 @@ osgManipulator::Dragger* createDragger(const std::string& name) { osgManipulator::TrackballDragger* d = new osgManipulator::TrackballDragger(); d->setupDefaultGeometry(); + d->setAxisLineWidth(5.0f); + d->setPickCylinderHeight(0.1f); dragger = d; } else if ("Translate1DDragger" == name) @@ -124,6 +126,9 @@ osgManipulator::Dragger* createDragger(const std::string& name) { osgManipulator::TranslateAxisDragger* d = new osgManipulator::TranslateAxisDragger(); d->setupDefaultGeometry(); + d->setAxisLineWidth(5.0f); + d->setPickCylinderRadius(0.05f); + d->setConeHeight(0.2f); dragger = d; } else if ("TranslatePlaneDragger" == name) diff --git a/include/osgManipulator/ScaleAxisDragger b/include/osgManipulator/ScaleAxisDragger index 0c26a333d..3fa634ce2 100644 --- a/include/osgManipulator/ScaleAxisDragger +++ b/include/osgManipulator/ScaleAxisDragger @@ -16,6 +16,9 @@ #define OSGMANIPULATOR_SCALEAXISDRAGGER 1 #include +#include +#include +#include namespace osgManipulator { @@ -33,6 +36,18 @@ class OSGMANIPULATOR_EXPORT ScaleAxisDragger : public CompositeDragger /** Setup default geometry for dragger. */ void setupDefaultGeometry(); + /** Sets the width of the axis lines in pixels. */ + void setAxisLineWidth(float linePixelWidth); + + /** Retrieves the width of the axis lines in pixels. */ + float getAxisLineWidth() const { return _axisLineWidth; } + + /** Sets the size of the boxes. */ + void setBoxSize(float size); + + /** Retrieves the size of the boxes. */ + float getBoxSize() const { return _boxSize; } + protected: virtual ~ScaleAxisDragger(); @@ -40,6 +55,13 @@ class OSGMANIPULATOR_EXPORT ScaleAxisDragger : public CompositeDragger osg::ref_ptr< Scale1DDragger > _xDragger; osg::ref_ptr< Scale1DDragger > _yDragger; osg::ref_ptr< Scale1DDragger > _zDragger; + + float _boxSize; + float _axisLineWidth; + + osg::ref_ptr _lineGeode; + osg::ref_ptr _lineWidth; + osg::ref_ptr _box; }; diff --git a/include/osgManipulator/TrackballDragger b/include/osgManipulator/TrackballDragger index f4a531e25..a8613d236 100644 --- a/include/osgManipulator/TrackballDragger +++ b/include/osgManipulator/TrackballDragger @@ -17,6 +17,9 @@ #include #include +#include +#include +#include namespace osgManipulator { @@ -34,6 +37,18 @@ class OSGMANIPULATOR_EXPORT TrackballDragger : public CompositeDragger /** Setup default geometry for dragger. */ void setupDefaultGeometry(); + /** Sets the width of the axis lines in pixels. */ + void setAxisLineWidth(float linePixelWidth); + + /** Retrieves the width of the axis lines in pixels. */ + float getAxisLineWidth() const { return _axisLineWidth; } + + /** Sets the height of the cylinders representing the axis lines for picking. */ + void setPickCylinderHeight(float pickCylinderHeight); + + /** Retrieves the height of the cylinders representing the axis lines for picking. */ + float getPickCylinderHeight() const { return _pickCylinderHeight; } + protected: virtual ~TrackballDragger(); @@ -42,6 +57,13 @@ class OSGMANIPULATOR_EXPORT TrackballDragger : public CompositeDragger osg::ref_ptr _yDragger; osg::ref_ptr _zDragger; osg::ref_ptr _xyzDragger; + + float _axisLineWidth; + float _pickCylinderHeight; + + osg::ref_ptr _geode; + osg::ref_ptr _cylinder; + osg::ref_ptr _lineWidth; }; diff --git a/include/osgManipulator/TranslateAxisDragger b/include/osgManipulator/TranslateAxisDragger index 863c6e855..9c0ff73e4 100644 --- a/include/osgManipulator/TranslateAxisDragger +++ b/include/osgManipulator/TranslateAxisDragger @@ -16,6 +16,9 @@ #define OSGMANIPULATOR_TRANSLATEAXISDRAGGER 1 #include +#include +#include +#include namespace osgManipulator { @@ -33,6 +36,24 @@ class OSGMANIPULATOR_EXPORT TranslateAxisDragger : public CompositeDragger /** Setup default geometry for dragger. */ void setupDefaultGeometry(); + /** Sets the width of the axis lines in pixels. */ + void setAxisLineWidth(float linePixelWidth); + + /** Retrieves the width of the axis lines in pixels. */ + float getAxisLineWidth() const { return _axisLineWidth; } + + /** Sets the radius of the cylinders representing the axis lines for picking. */ + void setPickCylinderRadius(float pickCylinderRadius); + + /** Retrieves the radius of the cylinders representing the axis lines for picking. */ + float getPickCylinderRadius() const { return _pickCylinderRadius; } + + /** Sets the height of the cones. */ + void setConeHeight(float radius); + + /** Retrieves the height of the cones. */ + float getConeHeight() const { return _coneHeight; } + protected: virtual ~TranslateAxisDragger(); @@ -40,6 +61,15 @@ class OSGMANIPULATOR_EXPORT TranslateAxisDragger : public CompositeDragger osg::ref_ptr< Translate1DDragger > _xDragger; osg::ref_ptr< Translate1DDragger > _yDragger; osg::ref_ptr< Translate1DDragger > _zDragger; + + float _coneHeight; + float _axisLineWidth; + float _pickCylinderRadius; + + osg::ref_ptr _lineGeode; + osg::ref_ptr _cylinder; + osg::ref_ptr _lineWidth; + osg::ref_ptr _cone; }; diff --git a/src/osgManipulator/ScaleAxisDragger.cpp b/src/osgManipulator/ScaleAxisDragger.cpp index 7c849c7d1..c59ad0e3d 100644 --- a/src/osgManipulator/ScaleAxisDragger.cpp +++ b/src/osgManipulator/ScaleAxisDragger.cpp @@ -35,6 +35,9 @@ ScaleAxisDragger::ScaleAxisDragger() addChild(_zDragger.get()); addDragger(_zDragger.get()); + _axisLineWidth = 2.0f; + _boxSize = 0.05f; + setParentDragger(getParentDragger()); } @@ -45,7 +48,7 @@ ScaleAxisDragger::~ScaleAxisDragger() void ScaleAxisDragger::setupDefaultGeometry() { // Create a line. - osg::Geode* lineGeode = new osg::Geode; + _lineGeode = new osg::Geode; { osg::Geometry* geometry = new osg::Geometry(); @@ -56,26 +59,32 @@ void ScaleAxisDragger::setupDefaultGeometry() geometry->setVertexArray(vertices); geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2)); - lineGeode->addDrawable(geometry); + _lineGeode->addDrawable(geometry); } // Turn of lighting for line and set line width. { - osg::LineWidth* linewidth = new osg::LineWidth(); - linewidth->setWidth(2.0f); - lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON); - lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + _lineWidth = new osg::LineWidth(); + _lineWidth->setWidth(_axisLineWidth); + _lineGeode->getOrCreateStateSet()->setAttributeAndModes(_lineWidth, osg::StateAttribute::ON); + _lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF); } // Add line to all the individual 1D draggers. - _xDragger->addChild(lineGeode); - _yDragger->addChild(lineGeode); - _zDragger->addChild(lineGeode); + _xDragger->addChild(_lineGeode); + _yDragger->addChild(_lineGeode); + _zDragger->addChild(_lineGeode); osg::Geode* geode = new osg::Geode; // Create a box. - geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(1.0f,0.0f,0.0f), 0.05))); + _box = new osg::Box(osg::Vec3(1.0f,0.0f,0.0f), _boxSize); + geode->addDrawable(new osg::ShapeDrawable(_box)); + + // This ensures correct lighting for scaled draggers. +#if !defined(OSG_GLES2_AVAILABLE) + geode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); +#endif // Add geode to all 1D draggers. _xDragger->addChild(geode); @@ -99,3 +108,17 @@ void ScaleAxisDragger::setupDefaultGeometry() _yDragger->setColor(osg::Vec4(0.0f,1.0f,0.0f,1.0f)); _zDragger->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f)); } + +void ScaleAxisDragger::setAxisLineWidth(float linePixelWidth) +{ + _axisLineWidth = linePixelWidth; + if (_lineWidth.valid()) + _lineWidth->setWidth(linePixelWidth); +} + +void ScaleAxisDragger::setBoxSize(float size) +{ + _boxSize = size; + if (_box.valid()) + _box->setHalfLengths(osg::Vec3(size * 0.5f, size * 0.5f, size * 0.5f)); +} diff --git a/src/osgManipulator/TrackballDragger.cpp b/src/osgManipulator/TrackballDragger.cpp index 069ce4e99..7b1b816d0 100644 --- a/src/osgManipulator/TrackballDragger.cpp +++ b/src/osgManipulator/TrackballDragger.cpp @@ -28,26 +28,26 @@ using namespace osgManipulator; namespace { -osg::Geometry* createCircleGeometry(float radius, unsigned int numSegments) -{ - const float angleDelta = 2.0f*osg::PI/(float)numSegments; - const float r = radius; - float angle = 0.0f; - osg::Vec3Array* vertexArray = new osg::Vec3Array(numSegments); - osg::Vec3Array* normalArray = new osg::Vec3Array(numSegments); - for(unsigned int i = 0; i < numSegments; ++i,angle+=angleDelta) + osg::Geometry* createCircleGeometry(float radius, unsigned int numSegments) { - float c = cosf(angle); - float s = sinf(angle); - (*vertexArray)[i].set(c*r,s*r,0.0f); - (*normalArray)[i].set(c,s,0.0f); + const float angleDelta = 2.0f*osg::PI/(float)numSegments; + const float r = radius; + float angle = 0.0f; + osg::Vec3Array* vertexArray = new osg::Vec3Array(numSegments); + osg::Vec3Array* normalArray = new osg::Vec3Array(numSegments); + for(unsigned int i = 0; i < numSegments; ++i,angle+=angleDelta) + { + float c = cosf(angle); + float s = sinf(angle); + (*vertexArray)[i].set(c*r,s*r,0.0f); + (*normalArray)[i].set(c,s,0.0f); + } + osg::Geometry* geometry = new osg::Geometry(); + geometry->setVertexArray(vertexArray); + geometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); + geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,vertexArray->size())); + return geometry; } - osg::Geometry* geometry = new osg::Geometry(); - geometry->setVertexArray(vertexArray); - geometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); - geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,vertexArray->size())); - return geometry; -} } @@ -102,6 +102,9 @@ TrackballDragger::TrackballDragger(bool useAutoTransform) addDragger(_xyzDragger.get()); } + _axisLineWidth = 2.0f; + _pickCylinderHeight = 0.15f; + setParentDragger(getParentDragger()); } @@ -111,38 +114,39 @@ TrackballDragger::~TrackballDragger() void TrackballDragger::setupDefaultGeometry() { - osg::Geode* geode = new osg::Geode; + _geode = new osg::Geode; { osg::TessellationHints* hints = new osg::TessellationHints; hints->setCreateTop(false); hints->setCreateBottom(false); hints->setCreateBackFace(false); - osg::Cylinder* cylinder = new osg::Cylinder; - cylinder->setHeight(0.15f); - osg::ShapeDrawable* cylinderDrawable = new osg::ShapeDrawable(cylinder,hints); - geode->addDrawable(cylinderDrawable); + _cylinder = new osg::Cylinder; + _cylinder->setHeight(_pickCylinderHeight); + osg::ShapeDrawable* cylinderDrawable = new osg::ShapeDrawable(_cylinder, hints); + _geode->addDrawable(cylinderDrawable); setDrawableToAlwaysCull(*cylinderDrawable); - geode->addDrawable(createCircleGeometry(1.0f, 100)); + _geode->addDrawable(createCircleGeometry(1.0f, 100)); } // Draw in line mode. { osg::PolygonMode* polymode = new osg::PolygonMode; polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE); - geode->getOrCreateStateSet()->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); - geode->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(2.0f),osg::StateAttribute::ON); + _geode->getOrCreateStateSet()->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON); + _lineWidth = new osg::LineWidth(_axisLineWidth); + _geode->getOrCreateStateSet()->setAttributeAndModes(_lineWidth, osg::StateAttribute::ON); - #if !defined(OSG_GLES2_AVAILABLE) - geode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); - #endif +#if !defined(OSG_GLES2_AVAILABLE) + _geode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); +#endif } // Add line to all the individual 1D draggers. - _xDragger->addChild(geode); - _yDragger->addChild(geode); - _zDragger->addChild(geode); + _xDragger->addChild(_geode); + _yDragger->addChild(_geode); + _zDragger->addChild(_geode); // Rotate X-axis dragger appropriately. @@ -172,3 +176,16 @@ void TrackballDragger::setupDefaultGeometry() _xyzDragger->addChild(sphereGeode); } } + +void TrackballDragger::setAxisLineWidth(float linePixelWidth) +{ + _axisLineWidth = linePixelWidth; + if (_lineWidth.valid()) + _lineWidth->setWidth(linePixelWidth); +} +void TrackballDragger::setPickCylinderHeight(float pickCylinderHeight) +{ + _pickCylinderHeight = pickCylinderHeight; + if (_cylinder.valid()) + _cylinder->setHeight(pickCylinderHeight); +} diff --git a/src/osgManipulator/TranslateAxisDragger.cpp b/src/osgManipulator/TranslateAxisDragger.cpp index 73f4572a5..e109cb9c5 100644 --- a/src/osgManipulator/TranslateAxisDragger.cpp +++ b/src/osgManipulator/TranslateAxisDragger.cpp @@ -35,6 +35,10 @@ TranslateAxisDragger::TranslateAxisDragger() addChild(_zDragger.get()); addDragger(_zDragger.get()); + _axisLineWidth = 2.0f; + _pickCylinderRadius = 0.015f; + _coneHeight = 0.1f; + setParentDragger(getParentDragger()); } @@ -45,7 +49,7 @@ TranslateAxisDragger::~TranslateAxisDragger() void TranslateAxisDragger::setupDefaultGeometry() { // Create a line. - osg::Geode* lineGeode = new osg::Geode; + _lineGeode = new osg::Geode; { osg::Geometry* geometry = new osg::Geometry(); @@ -56,34 +60,41 @@ void TranslateAxisDragger::setupDefaultGeometry() geometry->setVertexArray(vertices); geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2)); - lineGeode->addDrawable(geometry); + _lineGeode->addDrawable(geometry); } // Turn of lighting for line and set line width. { - osg::LineWidth* linewidth = new osg::LineWidth(); - linewidth->setWidth(2.0f); - lineGeode->getOrCreateStateSet()->setAttributeAndModes(linewidth, osg::StateAttribute::ON); - lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF); + _lineWidth = new osg::LineWidth(); + _lineWidth->setWidth(_axisLineWidth); + _lineGeode->getOrCreateStateSet()->setAttributeAndModes(_lineWidth, osg::StateAttribute::ON); + _lineGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); } // Add line to all the individual 1D draggers. - _xDragger->addChild(lineGeode); - _yDragger->addChild(lineGeode); - _zDragger->addChild(lineGeode); + _xDragger->addChild(_lineGeode); + _yDragger->addChild(_lineGeode); + _zDragger->addChild(_lineGeode); osg::Geode* geode = new osg::Geode; // Create a cone. { - osg::Cone* cone = new osg::Cone (osg::Vec3(0.0f, 0.0f, 1.0f), 0.025f, 0.10f); - geode->addDrawable(new osg::ShapeDrawable(cone)); + _cone = new osg::Cone (osg::Vec3(0.0f, 0.0f, 1.0f), _coneHeight * 0.25f, _coneHeight); + osg::ShapeDrawable* coneDrawable = new osg::ShapeDrawable(_cone); + // coneDrawable->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f)); + geode->addDrawable(coneDrawable); + + // This ensures correct lighting for scaled draggers. +#if !defined(OSG_GLES2_AVAILABLE) + geode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); +#endif } // Create an invisible cylinder for picking the line. { - osg::Cylinder* cylinder = new osg::Cylinder (osg::Vec3(0.0f,0.0f,0.5f), 0.015f, 1.0f); - osg::Drawable* geometry = new osg::ShapeDrawable(cylinder); + _cylinder = new osg::Cylinder (osg::Vec3(0.0f,0.0f,0.5f), _pickCylinderRadius, 1.0f); + osg::Drawable* geometry = new osg::ShapeDrawable(_cylinder); setDrawableToAlwaysCull(*geometry); geode->addDrawable(geometry); } @@ -110,3 +121,26 @@ void TranslateAxisDragger::setupDefaultGeometry() _yDragger->setColor(osg::Vec4(0.0f,1.0f,0.0f,1.0f)); _zDragger->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f)); } + +void TranslateAxisDragger::setAxisLineWidth(float linePixelWidth) +{ + _axisLineWidth = linePixelWidth; + if (_lineWidth.valid()) + _lineWidth->setWidth(linePixelWidth); +} +void TranslateAxisDragger::setPickCylinderRadius(float pickCylinderRadius) +{ + _pickCylinderRadius = pickCylinderRadius; + if (_cylinder.valid()) + _cylinder->setRadius(pickCylinderRadius); +} + +void TranslateAxisDragger::setConeHeight(float height) +{ + _coneHeight = height; + if (_cone.valid()) + { + _cone->setRadius(0.25f * height); + _cone->setHeight(height); + } +} diff --git a/src/osgWrappers/serializers/osgManipulator/ScaleAxisDragger.cpp b/src/osgWrappers/serializers/osgManipulator/ScaleAxisDragger.cpp index 2ade70a53..326876eba 100644 --- a/src/osgWrappers/serializers/osgManipulator/ScaleAxisDragger.cpp +++ b/src/osgWrappers/serializers/osgManipulator/ScaleAxisDragger.cpp @@ -9,4 +9,6 @@ REGISTER_OBJECT_WRAPPER( osgManipulator_ScaleAxisDragger, "osg::Object osg::Node osg::Transform osg::MatrixTransform osgManipulator::Dragger " "osgManipulator::ScaleAxisDragger" ) // No need to contain CompositeDragger here { + ADD_FLOAT_SERIALIZER(AxisLineWidth, 2.0f); + ADD_FLOAT_SERIALIZER(BoxSize, 0.05f); } diff --git a/src/osgWrappers/serializers/osgManipulator/TrackballDragger.cpp b/src/osgWrappers/serializers/osgManipulator/TrackballDragger.cpp index e8a5e7dd0..0c28faa22 100644 --- a/src/osgWrappers/serializers/osgManipulator/TrackballDragger.cpp +++ b/src/osgWrappers/serializers/osgManipulator/TrackballDragger.cpp @@ -9,4 +9,6 @@ REGISTER_OBJECT_WRAPPER( osgManipulator_TrackballDragger, "osg::Object osg::Node osg::Transform osg::MatrixTransform osgManipulator::Dragger " "osgManipulator::TrackballDragger" ) // No need to contain CompositeDragger here { + ADD_FLOAT_SERIALIZER(AxisLineWidth, 2.0f); + ADD_FLOAT_SERIALIZER(PickCylinderHeight, 0.15f); } diff --git a/src/osgWrappers/serializers/osgManipulator/TranslateAxisDragger.cpp b/src/osgWrappers/serializers/osgManipulator/TranslateAxisDragger.cpp index 1dc1e9508..03448b93a 100644 --- a/src/osgWrappers/serializers/osgManipulator/TranslateAxisDragger.cpp +++ b/src/osgWrappers/serializers/osgManipulator/TranslateAxisDragger.cpp @@ -9,4 +9,7 @@ REGISTER_OBJECT_WRAPPER( osgManipulator_TranslateAxisDragger, "osg::Object osg::Node osg::Transform osg::MatrixTransform osgManipulator::Dragger " "osgManipulator::TranslateAxisDragger" ) // No need to contain CompositeDragger here { + ADD_FLOAT_SERIALIZER(AxisLineWidth, 2.0f); + ADD_FLOAT_SERIALIZER(PickCylinderRadius, 0.015f); + ADD_FLOAT_SERIALIZER(ConeHeight, 0.1f); }