From 4041649b6ae9fe6008a9ecd131095808843ae3a8 Mon Sep 17 00:00:00 2001 From: Jeongseok Lee Date: Tue, 4 Jan 2022 18:38:51 -0800 Subject: [PATCH] Fix depth testing for transparent objects (#1643) --- CHANGELOG.md | 4 + dart/gui/osg/GridVisual.cpp | 59 ++++++-- dart/gui/osg/Utils.hpp | 18 +++ dart/gui/osg/render/BoxShapeNode.cpp | 26 +++- dart/gui/osg/render/CapsuleShapeNode.cpp | 26 +++- dart/gui/osg/render/ConeShapeNode.cpp | 26 +++- dart/gui/osg/render/CylinderShapeNode.cpp | 26 +++- dart/gui/osg/render/EllipsoidShapeNode.cpp | 26 +++- dart/gui/osg/render/LineSegmentShapeNode.cpp | 31 +++- dart/gui/osg/render/MeshShapeNode.cpp | 147 +++++++++++++++++-- dart/gui/osg/render/MultiSphereShapeNode.cpp | 26 +++- dart/gui/osg/render/PlaneShapeNode.cpp | 26 +++- dart/gui/osg/render/PointCloudShapeNode.cpp | 4 + dart/gui/osg/render/PyramidShapeNode.cpp | 31 +++- dart/gui/osg/render/SoftMeshShapeNode.cpp | 29 +++- dart/gui/osg/render/SphereShapeNode.cpp | 26 +++- dart/gui/osg/render/VoxelGridShapeNode.cpp | 21 +++ 17 files changed, 483 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94f40000a8613..cf53b145e12ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ * Fixed grouping of constraints: [#1624](https://github.com/dartsim/dart/pull/1624), [#1628](https://github.com/dartsim/dart/pull/1628) * Fixed issue with removing skeletons without shapes: [#1625](https://github.com/dartsim/dart/pull/1625) +* GUI + + * Fixed depth testing for transparent objects: [#1643](https://github.com/dartsim/dart/pull/1643) + ### [DART 6.12.1 (2021-11-04)](https://github.com/dartsim/dart/milestone/71?closed=1) * Build diff --git a/dart/gui/osg/GridVisual.cpp b/dart/gui/osg/GridVisual.cpp index c40d207b4ead4..a134fb2e8ba26 100644 --- a/dart/gui/osg/GridVisual.cpp +++ b/dart/gui/osg/GridVisual.cpp @@ -32,10 +32,13 @@ #include "dart/gui/osg/GridVisual.hpp" +#include + #include "dart/dynamics/BodyNode.hpp" #include "dart/dynamics/SimpleFrame.hpp" #include "dart/dynamics/Skeleton.hpp" #include "dart/dynamics/SphereShape.hpp" +#include "dart/gui/osg/Utils.hpp" #include "dart/math/Helpers.hpp" namespace dart { @@ -443,11 +446,55 @@ void GridVisual::refresh() mMinorLineGeom->getOrCreateStateSet()->setAttributeAndModes( mMinorLineWidth); mMinorLineGeom->setPrimitiveSet(0, mMinorLineFaces); + if (mMinorLineColor->at(0).a() < 1 - getAlphaThreshold()) + { + mMinorLineGeom->getOrCreateStateSet()->setMode( + GL_BLEND, ::osg::StateAttribute::ON); + mMinorLineGeom->getOrCreateStateSet()->setRenderingHint( + ::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + mMinorLineGeom->getOrCreateStateSet()->setAttributeAndModes( + depth, ::osg::StateAttribute::ON); + } + else + { + mMinorLineGeom->getOrCreateStateSet()->setMode( + GL_BLEND, ::osg::StateAttribute::OFF); + mMinorLineGeom->getOrCreateStateSet()->setRenderingHint( + ::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + mMinorLineGeom->getOrCreateStateSet()->setAttributeAndModes( + depth, ::osg::StateAttribute::ON); + } mMajorLineGeom->setVertexArray(mMajorLineVertices); mMajorLineGeom->getOrCreateStateSet()->setAttributeAndModes( mMajorLineWidth); mMajorLineGeom->setPrimitiveSet(0, mMajorLineFaces); + if (mMajorLineColor->at(0).a() < 1 - getAlphaThreshold()) + { + mMajorLineGeom->getOrCreateStateSet()->setMode( + GL_BLEND, ::osg::StateAttribute::ON); + mMajorLineGeom->getOrCreateStateSet()->setRenderingHint( + ::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + mMajorLineGeom->getOrCreateStateSet()->setAttributeAndModes( + depth, ::osg::StateAttribute::ON); + } + else + { + mMajorLineGeom->getOrCreateStateSet()->setMode( + GL_BLEND, ::osg::StateAttribute::OFF); + mMajorLineGeom->getOrCreateStateSet()->setRenderingHint( + ::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + mMajorLineGeom->getOrCreateStateSet()->setAttributeAndModes( + depth, ::osg::StateAttribute::ON); + } static const ::osg::Vec4 xAxisLineColor(0.9f, 0.1f, 0.1f, 1.0f); static const ::osg::Vec4 yAxisLineColor(0.1f, 0.9f, 0.1f, 1.0f); @@ -516,9 +563,9 @@ void GridVisual::initialize() mAxisLineGeom->setVertexArray(mAxisLineVertices); mAxisLineGeom->setDataVariance(::osg::Object::STATIC); mAxisLineGeom->getOrCreateStateSet()->setMode( - GL_BLEND, ::osg::StateAttribute::ON); + GL_BLEND, ::osg::StateAttribute::OFF); mAxisLineGeom->getOrCreateStateSet()->setRenderingHint( - ::osg::StateSet::TRANSPARENT_BIN); + ::osg::StateSet::OPAQUE_BIN); // Set grid color static const ::osg::Vec4 majorLineColor(0.4f, 0.4f, 0.4f, 1.0f); @@ -538,20 +585,12 @@ void GridVisual::initialize() mMajorLineColor->at(0) = majorLineColor; mMajorLineGeom->setColorArray(mMajorLineColor); mMajorLineGeom->setColorBinding(::osg::Geometry::BIND_OVERALL); - mMajorLineGeom->getOrCreateStateSet()->setMode( - GL_BLEND, ::osg::StateAttribute::ON); - mMajorLineGeom->getOrCreateStateSet()->setRenderingHint( - ::osg::StateSet::TRANSPARENT_BIN); mMinorLineColor = new ::osg::Vec4Array; mMinorLineColor->resize(1); mMinorLineColor->at(0) = minorLineColor; mMinorLineGeom->setColorArray(mMinorLineColor); mMinorLineGeom->setColorBinding(::osg::Geometry::BIND_OVERALL); - mMinorLineGeom->getOrCreateStateSet()->setMode( - GL_BLEND, ::osg::StateAttribute::ON); - mMinorLineGeom->getOrCreateStateSet()->setRenderingHint( - ::osg::StateSet::TRANSPARENT_BIN); mMinorLineFaces = new ::osg::DrawElementsUInt(::osg::PrimitiveSet::LINES, 0); mMinorLineGeom->addPrimitiveSet(mMinorLineFaces); diff --git a/dart/gui/osg/Utils.hpp b/dart/gui/osg/Utils.hpp index 0bf5b52be1b8a..7b4622e0a3d08 100644 --- a/dart/gui/osg/Utils.hpp +++ b/dart/gui/osg/Utils.hpp @@ -36,6 +36,24 @@ #include #include +//============================================================================== +template +constexpr T getAlphaThreshold() +{ + if constexpr (std::is_same_v) + { + return 1e-6; + } + else if constexpr (std::is_same_v) + { + return 1e-9; + } + else + { + return 1e-9; + } +} + //============================================================================== template ::osg::Matrix eigToOsgMatrix( diff --git a/dart/gui/osg/render/BoxShapeNode.cpp b/dart/gui/osg/render/BoxShapeNode.cpp index 7040d066462af..c1a07a77eeb30 100644 --- a/dart/gui/osg/render/BoxShapeNode.cpp +++ b/dart/gui/osg/render/BoxShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/BoxShapeNode.hpp" #include +#include #include #include @@ -128,8 +129,6 @@ BoxShapeGeode::BoxShapeGeode( mBoxShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -191,7 +190,28 @@ void BoxShapeDrawable::refresh(bool firstTime) if (mBoxShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/CapsuleShapeNode.cpp b/dart/gui/osg/render/CapsuleShapeNode.cpp index 9bc01ea32c084..5c1ebb0f280d3 100644 --- a/dart/gui/osg/render/CapsuleShapeNode.cpp +++ b/dart/gui/osg/render/CapsuleShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/CapsuleShapeNode.hpp" #include +#include #include #include @@ -135,8 +136,6 @@ CapsuleShapeGeode::CapsuleShapeGeode( mCapsuleShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -201,7 +200,28 @@ void CapsuleShapeDrawable::refresh(bool firstTime) if (mCapsuleShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/ConeShapeNode.cpp b/dart/gui/osg/render/ConeShapeNode.cpp index 728681f56ef55..4ad231ac21add 100644 --- a/dart/gui/osg/render/ConeShapeNode.cpp +++ b/dart/gui/osg/render/ConeShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/ConeShapeNode.hpp" #include +#include #include #include @@ -134,8 +135,6 @@ ConeShapeGeode::ConeShapeGeode( mConeShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -200,7 +199,28 @@ void ConeShapeDrawable::refresh(bool firstTime) if (mConeShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/CylinderShapeNode.cpp b/dart/gui/osg/render/CylinderShapeNode.cpp index e70fa0fcdb48b..30523b82f03cd 100644 --- a/dart/gui/osg/render/CylinderShapeNode.cpp +++ b/dart/gui/osg/render/CylinderShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/CylinderShapeNode.hpp" #include +#include #include #include @@ -135,8 +136,6 @@ CylinderShapeGeode::CylinderShapeGeode( mCylinderShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -202,7 +201,28 @@ void CylinderShapeDrawable::refresh(bool firstTime) if (mCylinderShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/EllipsoidShapeNode.cpp b/dart/gui/osg/render/EllipsoidShapeNode.cpp index 0a22183d14cdc..17c2cd762cb7a 100644 --- a/dart/gui/osg/render/EllipsoidShapeNode.cpp +++ b/dart/gui/osg/render/EllipsoidShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/EllipsoidShapeNode.hpp" #include +#include #include #include #include @@ -159,8 +160,6 @@ EllipsoidShapeGeode::EllipsoidShapeGeode( mEllipsoidShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -227,7 +226,28 @@ void EllipsoidShapeDrawable::refresh(bool firstTime) if (mEllipsoidShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/LineSegmentShapeNode.cpp b/dart/gui/osg/render/LineSegmentShapeNode.cpp index d69917f82a250..d0f3d650bae39 100644 --- a/dart/gui/osg/render/LineSegmentShapeNode.cpp +++ b/dart/gui/osg/render/LineSegmentShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/LineSegmentShapeNode.hpp" #include +#include #include #include #include @@ -141,8 +142,6 @@ LineSegmentShapeGeode::LineSegmentShapeGeode( mDrawable(nullptr), mLineWidth(new ::osg::LineWidth) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); getOrCreateStateSet()->setMode(GL_LIGHTING, ::osg::StateAttribute::OFF); @@ -248,12 +247,30 @@ void LineSegmentShapeDrawable::refresh(bool firstTime) if (mLineSegmentShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - if (mColors->size() != 1) - mColors->resize(1); - - (*mColors)[0] = eigToOsgVec4d(mVisualAspect->getRGBA()); - + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + mColors->resize(1); + (*mColors)[0] = color; setColorArray(mColors, ::osg::Array::BIND_OVERALL); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/MeshShapeNode.cpp b/dart/gui/osg/render/MeshShapeNode.cpp index b21b0c118f1a2..b3c082b22d933 100644 --- a/dart/gui/osg/render/MeshShapeNode.cpp +++ b/dart/gui/osg/render/MeshShapeNode.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,7 @@ namespace render { namespace { +//============================================================================== #define GET_TEXTURE_TYPE_AND_COUNT(MATERIAL, TYPE) \ { \ const auto count = MATERIAL.GetTextureCount(TYPE); \ @@ -60,6 +62,7 @@ namespace { return std::make_pair(TYPE, count); \ } +//============================================================================== std::pair getTextureTypeAndCount( const aiMaterial& material) { @@ -84,6 +87,28 @@ std::pair getTextureTypeAndCount( return std::make_pair(aiTextureType_UNKNOWN, 0u); } +//============================================================================== +bool isTransparent(const ::osg::Material* material) +{ + if (std::abs(material->getAmbient(::osg::Material::FRONT).a()) + < 1 - getAlphaThreshold()) + return true; + + if (std::abs(material->getDiffuse(::osg::Material::FRONT).a()) + < 1 - getAlphaThreshold()) + return true; + + if (std::abs(material->getSpecular(::osg::Material::FRONT).a()) + < 1 - getAlphaThreshold()) + return true; + + if (std::abs(material->getEmission(::osg::Material::FRONT).a()) + < 1 - getAlphaThreshold()) + return true; + + return false; +} + } // namespace class osgAiNode : public ShapeNode, public ::osg::MatrixTransform @@ -505,8 +530,6 @@ MeshShapeGeode::MeshShapeGeode( mAiNode(node), mMainNode(parentNode) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(true); @@ -710,6 +733,7 @@ void MeshShapeGeometry::extractData(bool firstTime) || firstTime) { bool isColored = false; + ::osg::StateSet* ss = getOrCreateStateSet(); if (mMeshShape->getColorMode() == dart::dynamics::MeshShape::COLOR_INDEX) { @@ -755,6 +779,14 @@ void MeshShapeGeometry::extractData(bool firstTime) setColorArray(mColors); setColorBinding(::osg::Geometry::BIND_PER_VERTEX); + + // Set as a transparent object by default + // TODO(JS): Revisit if this doesn't make sense + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); } } @@ -766,37 +798,104 @@ void MeshShapeGeometry::extractData(bool firstTime) -1)) // -1 is being used by us to indicate no material { isColored = true; - auto material = mMainNode->getMaterial(matIndex); + ::osg::Material* material = mMainNode->getMaterial(matIndex); if (mMeshShape->getAlphaMode() == dynamics::MeshShape::SHAPE_ALPHA) { + const float shapeAlpha + = static_cast(mVisualAspect->getAlpha()); + ::osg::ref_ptr<::osg::Material> newMaterial = new ::osg::Material(*material); newMaterial->setAlpha( - ::osg::Material::Face::FRONT_AND_BACK, - static_cast(mVisualAspect->getAlpha())); - getOrCreateStateSet()->setAttributeAndModes(newMaterial); + ::osg::Material::Face::FRONT_AND_BACK, shapeAlpha); + ss->setAttributeAndModes(newMaterial); + + // Set alpha specific properties + if (std::abs(shapeAlpha) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } else if (mMeshShape->getAlphaMode() == dynamics::MeshShape::BLEND) { - const auto shapeAlpha = static_cast(mVisualAspect->getAlpha()); + float shapeAlpha = static_cast(mVisualAspect->getAlpha()); ::osg::ref_ptr<::osg::Material> newMaterial = new ::osg::Material(*material); blendMaterialAlpha(newMaterial, shapeAlpha); - getOrCreateStateSet()->setAttributeAndModes(newMaterial); + ss->setAttributeAndModes(newMaterial); + + // Set alpha specific properties + if (std::abs(shapeAlpha) > 1 - getAlphaThreshold() + && !isTransparent(material)) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } else { - getOrCreateStateSet()->setAttributeAndModes(material); + ss->setAttributeAndModes(material); + + // Set alpha specific properties + if (!isTransparent(material)) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } else { - getOrCreateStateSet()->removeAttribute(::osg::StateAttribute::MATERIAL); + ss->removeAttribute(::osg::StateAttribute::MATERIAL); + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); } } else { - getOrCreateStateSet()->removeAttribute(::osg::StateAttribute::MATERIAL); + ss->removeAttribute(::osg::StateAttribute::MATERIAL); + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); } const aiVector3D* aiTexCoords = mAiMesh->mTextureCoords[0]; @@ -806,15 +905,31 @@ void MeshShapeGeometry::extractData(bool firstTime) if (!isColored || mMeshShape->getColorMode() == dart::dynamics::MeshShape::SHAPE_COLOR) { + // Set color const Eigen::Vector4f& c = mVisualAspect->getRGBA().cast(); - - if (mColors->size() != 1) - mColors->resize(1); - + mColors->resize(1); (*mColors)[0] = ::osg::Vec4(c[0], c[1], c[2], c[3]); - setColorArray(mColors); setColorBinding(::osg::Geometry::BIND_OVERALL); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(c[3]) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/MultiSphereShapeNode.cpp b/dart/gui/osg/render/MultiSphereShapeNode.cpp index 7f2af81c5888f..bf1c5909a748b 100644 --- a/dart/gui/osg/render/MultiSphereShapeNode.cpp +++ b/dart/gui/osg/render/MultiSphereShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/MultiSphereShapeNode.hpp" #include +#include #include #include #include @@ -143,8 +144,6 @@ MultiSphereShapeGeode::MultiSphereShapeGeode( mMultiSphereShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -263,10 +262,31 @@ void MultiSphereShapeDrawable::refresh(bool firstTime) if (mMultiSphereShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); (*mColors).resize(1); - (*mColors)[0] = eigToOsgVec4f(mVisualAspect->getRGBA()); + (*mColors)[0] = color; setColorArray(mColors); setColorBinding(::osg::Geometry::BIND_OVERALL); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/PlaneShapeNode.cpp b/dart/gui/osg/render/PlaneShapeNode.cpp index 39dcc083c068f..96b5763f9a91e 100644 --- a/dart/gui/osg/render/PlaneShapeNode.cpp +++ b/dart/gui/osg/render/PlaneShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/PlaneShapeNode.hpp" #include +#include #include #include @@ -133,8 +134,6 @@ PlaneShapeGeode::PlaneShapeGeode( mPlaneShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -201,7 +200,28 @@ void PlaneShapeDrawable::refresh(bool firstTime) if (mPlaneShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/PointCloudShapeNode.cpp b/dart/gui/osg/render/PointCloudShapeNode.cpp index bfb9b1e31c612..ae3a541023592 100644 --- a/dart/gui/osg/render/PointCloudShapeNode.cpp +++ b/dart/gui/osg/render/PointCloudShapeNode.cpp @@ -494,10 +494,14 @@ class VertexPointNodes final : public PointNodes mGeometry = new ::osg::Geometry; mGeometry->setVertexArray(mVertices); mGeometry->setDataVariance(::osg::Object::STATIC); + + // TODO(JS): This should be set by the alpha value of the color + // See other shapes such as BoxShapeNode and MeshShapeNode. mGeometry->getOrCreateStateSet()->setMode( GL_BLEND, ::osg::StateAttribute::ON); mGeometry->getOrCreateStateSet()->setRenderingHint( ::osg::StateSet::TRANSPARENT_BIN); + mGeometry->addPrimitiveSet(mPrimitiveSet); mGeometry->getOrCreateStateSet()->setAttribute( mPoint, ::osg::StateAttribute::ON); diff --git a/dart/gui/osg/render/PyramidShapeNode.cpp b/dart/gui/osg/render/PyramidShapeNode.cpp index 5cd8d089403ed..444203d1b8a03 100644 --- a/dart/gui/osg/render/PyramidShapeNode.cpp +++ b/dart/gui/osg/render/PyramidShapeNode.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -141,8 +142,6 @@ PyramidShapeGeode::PyramidShapeGeode( mDrawable(nullptr), mLineWidth(new ::osg::LineWidth) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); getOrCreateStateSet()->setMode(GL_LIGHTING, ::osg::StateAttribute::ON); @@ -285,12 +284,30 @@ void PyramidShapeDrawable::refresh(bool firstTime) if (mPyramidShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - if (mColors->size() != 1) - mColors->resize(1); - - (*mColors)[0] = eigToOsgVec4d(mVisualAspect->getRGBA()); - + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + mColors->resize(1); + (*mColors)[0] = color; setColorArray(mColors, ::osg::Array::BIND_OVERALL); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/SoftMeshShapeNode.cpp b/dart/gui/osg/render/SoftMeshShapeNode.cpp index 819bcab6f8d7c..227e74a17ac29 100644 --- a/dart/gui/osg/render/SoftMeshShapeNode.cpp +++ b/dart/gui/osg/render/SoftMeshShapeNode.cpp @@ -33,6 +33,7 @@ #include "dart/gui/osg/render/SoftMeshShapeNode.hpp" #include +#include #include #include @@ -283,12 +284,30 @@ void SoftMeshShapeDrawable::refresh(bool firstTime) if (mSoftMeshShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - if (mColors->size() != 1) - mColors->resize(1); - - (*mColors)[0] = eigToOsgVec4d(mVisualAspect->getRGBA()); - + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + mColors->resize(1); + (*mColors)[0] = color; setColorArray(mColors, ::osg::Array::BIND_OVERALL); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/SphereShapeNode.cpp b/dart/gui/osg/render/SphereShapeNode.cpp index ab30aff963148..11b8a66661b52 100644 --- a/dart/gui/osg/render/SphereShapeNode.cpp +++ b/dart/gui/osg/render/SphereShapeNode.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -138,8 +139,6 @@ SphereShapeGeode::SphereShapeGeode( mSphereShape(shape), mDrawable(nullptr) { - getOrCreateStateSet()->setMode(GL_BLEND, ::osg::StateAttribute::ON); - getOrCreateStateSet()->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); getOrCreateStateSet()->setAttributeAndModes( new ::osg::CullFace(::osg::CullFace::BACK)); extractData(); @@ -204,7 +203,28 @@ void SphereShapeDrawable::refresh(bool firstTime) if (mSphereShape->checkDataVariance(dart::dynamics::Shape::DYNAMIC_COLOR) || firstTime) { - setColor(eigToOsgVec4d(mVisualAspect->getRGBA())); + // Set color + const ::osg::Vec4d color = eigToOsgVec4d(mVisualAspect->getRGBA()); + setColor(color); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color.a()) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } } diff --git a/dart/gui/osg/render/VoxelGridShapeNode.cpp b/dart/gui/osg/render/VoxelGridShapeNode.cpp index 8fb7934199d9b..df8c9e94197f7 100644 --- a/dart/gui/osg/render/VoxelGridShapeNode.cpp +++ b/dart/gui/osg/render/VoxelGridShapeNode.cpp @@ -35,6 +35,7 @@ #if HAVE_OCTOMAP #include + #include #include #include #include @@ -77,7 +78,27 @@ class BoxDrawable final : public ::osg::ShapeDrawable void updateColor(const Eigen::Vector4d& color) { + // Set color setColor(eigToOsgVec4f(color)); + + // Set alpha specific properties + ::osg::StateSet* ss = getOrCreateStateSet(); + if (std::abs(color[3]) > 1 - getAlphaThreshold()) + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::OFF); + ss->setRenderingHint(::osg::StateSet::OPAQUE_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(true); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } + else + { + ss->setMode(GL_BLEND, ::osg::StateAttribute::ON); + ss->setRenderingHint(::osg::StateSet::TRANSPARENT_BIN); + ::osg::ref_ptr<::osg::Depth> depth = new ::osg::Depth; + depth->setWriteMask(false); + ss->setAttributeAndModes(depth, ::osg::StateAttribute::ON); + } } protected: