From 70b6d2fe2a5f19d71ef4960e62626bb9050b8e6e Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Fri, 9 Feb 2018 13:32:17 +0100 Subject: [PATCH 01/13] Shadows in OpenSceneGraph - Part I --- dart/gui/osg/CMakeLists.txt | 2 +- dart/gui/osg/Viewer.cpp | 78 ++++++++++++++++++++++++++++++++----- dart/gui/osg/Viewer.hpp | 14 ++++++- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/dart/gui/osg/CMakeLists.txt b/dart/gui/osg/CMakeLists.txt index 9d943f0d81772..2787bd1eeeaa0 100644 --- a/dart/gui/osg/CMakeLists.txt +++ b/dart/gui/osg/CMakeLists.txt @@ -7,7 +7,7 @@ endif() if(DART_BUILD_GUI_OSG) find_package(OpenSceneGraph 3.0 QUIET - COMPONENTS osg osgViewer osgManipulator osgGA osgDB) + COMPONENTS osg osgViewer osgManipulator osgGA osgDB osgShadow) # It seems that OPENSCENEGRAPH_FOUND will inadvertently get set to true when # OpenThreads is found, even if OpenSceneGraph is not installed. This is quite diff --git a/dart/gui/osg/Viewer.cpp b/dart/gui/osg/Viewer.cpp index 29b261e55fd26..efb80fc801e03 100644 --- a/dart/gui/osg/Viewer.cpp +++ b/dart/gui/osg/Viewer.cpp @@ -35,6 +35,11 @@ #include #include +#include +#include +#include +#include + #include "dart/gui/osg/Viewer.hpp" #include "dart/gui/osg/TrackballManipulator.hpp" #include "dart/gui/osg/DefaultEventHandler.hpp" @@ -190,7 +195,7 @@ void ViewerAttachment::attach(Viewer* newViewer) } //============================================================================== -Viewer::Viewer(const ::osg::Vec4& clearColor) +Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn) : mImageSequenceNum(0), mImageDigits(0), mRecording(false), @@ -206,6 +211,11 @@ Viewer::Viewer(const ::osg::Vec4& clearColor) mAllowSimulation(true), mHeadlights(true) { + enableShadows(shadowsOn); + + // add the physics group to the root group + mRootGroup->addChild(mPhysicsGroup); + setCameraManipulator(new osg::TrackballManipulator); addInstructionText("Left-click: Interaction\n"); addInstructionText("Right-click: Rotate view\n"); @@ -215,12 +225,12 @@ Viewer::Viewer(const ::osg::Vec4& clearColor) mDefaultEventHandler = new DefaultEventHandler(this); // ^ Cannot construct this in the initialization list, because its constructor calls member functions of this object - setSceneData(mRootGroup); addEventHandler(mDefaultEventHandler); - setupDefaultLights(); getCamera()->setClearColor(clearColor); getCamera()->setFinalDrawCallback(new SaveScreen(this)); + + setSceneData(mRootGroup.get()); } //============================================================================== @@ -375,7 +385,7 @@ void Viewer::addWorldNode(WorldNode* _newWorldNode, bool _active) return; mWorldNodes[_newWorldNode] = _active; - mRootGroup->addChild(_newWorldNode); + mPhysicsGroup->addChild(_newWorldNode); if(_active) _newWorldNode->simulate(mSimulating); _newWorldNode->mViewer = this; @@ -389,7 +399,7 @@ void Viewer::removeWorldNode(WorldNode* _oldWorldNode) if(it == mWorldNodes.end()) return; - mRootGroup->removeChild(it->first); + mPhysicsGroup->removeChild(it->first); mWorldNodes.erase(it); } @@ -401,7 +411,7 @@ void Viewer::removeWorldNode(std::shared_ptr _oldWorld) if(nullptr == node) return; - mRootGroup->removeChild(node); + mPhysicsGroup->removeChild(node); mWorldNodes.erase(node); } @@ -474,7 +484,7 @@ void Viewer::setupDefaultLights() setUpwardsDirection(mUpwards); switchHeadlights(true); - ::osg::ref_ptr<::osg::StateSet> lightSS = mRootGroup->getOrCreateStateSet(); + ::osg::ref_ptr<::osg::StateSet> lightSS = mPhysicsGroup->getOrCreateStateSet(); mLight1->setLightNum(1); mLightSource1->setLight(mLight1); @@ -490,8 +500,8 @@ void Viewer::setupDefaultLights() mLightGroup->removeChild(mLightSource2); mLightGroup->addChild(mLightSource2); - mRootGroup->removeChild(mLightGroup); - mRootGroup->addChild(mLightGroup); + mPhysicsGroup->removeChild(mLightGroup); + mPhysicsGroup->addChild(mLightGroup); } //============================================================================== @@ -831,6 +841,56 @@ const ::osg::ref_ptr<::osg::Group>& Viewer::getRootGroup() const return mRootGroup; } +//============================================================================== +const ::osg::ref_ptr<::osg::Group>& Viewer::getPhysicsGroup() const +{ + return mPhysicsGroup; +} + +//============================================================================== +bool Viewer::isShadowed() const +{ + return mShadowed; +} + +//============================================================================== +void Viewer::enableShadows(bool _enable) +{ + if(!mPhysicsGroup) { + // Flags for shadowing; maybe this needs to be global? + constexpr int ReceivesShadowTraversalMask = 0x2; + constexpr int CastsShadowTraversalMask = 0x1; + + // Setup shadows + // Create one ShadowedScene for each light + ::osg::ref_ptr shadowedScene = new osgShadow::ShadowedScene; + shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask); + shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask); + + // set the physics group + mPhysicsGroup = shadowedScene.get(); + mPhysicsGroup->getOrCreateStateSet(); + + setupDefaultLights(); + } + + if(_enable) { + // Use the ShadowMap technique + ::osg::ref_ptr sm = new osgShadow::ShadowMap; + // increase the resolution of default shadow texture for higher quality + int mapres = std::pow(2, 13); + sm->setTextureSize(::osg::Vec2s(mapres,mapres)); + sm->setLight(mLight1); + + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); + } + else + static_cast(mPhysicsGroup.get())->setShadowTechnique(0); + + mShadowed = _enable; +} + } // namespace osg } // namespace gui } // namespace dart diff --git a/dart/gui/osg/Viewer.hpp b/dart/gui/osg/Viewer.hpp index 30f31eaf1b085..8712c5438744f 100644 --- a/dart/gui/osg/Viewer.hpp +++ b/dart/gui/osg/Viewer.hpp @@ -117,7 +117,7 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// Constructor for dart::gui::osg::Viewer. This will automatically create the /// default event handler. - Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0)); + Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0), bool shadowsOn = false); /// Destructor virtual ~Viewer(); @@ -288,6 +288,12 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// Get the root ::osg::Group of this Viewer const ::osg::ref_ptr<::osg::Group>& getRootGroup() const; + /// Get the physics root ::osg::Group of this Viewer + const ::osg::ref_ptr<::osg::Group>& getPhysicsGroup() const; + + bool isShadowed() const; + void enableShadows(bool _enable = true); + protected: friend class SaveScreen; @@ -319,6 +325,12 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// The root node of this Viewer ::osg::ref_ptr<::osg::Group> mRootGroup; + /// The DART physics node of this Viewer + ::osg::ref_ptr<::osg::Group> mPhysicsGroup; + + /// Whether the shadows are enabled + bool mShadowed; + /// The Group Node containing light sources ::osg::ref_ptr<::osg::Group> mLightGroup; From a4b6cb40e194b647aa4a0dec718b7f7792d33d1c Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Fri, 9 Feb 2018 14:02:15 +0100 Subject: [PATCH 02/13] Shadows in OpenSceneGraph - Part II: multiple techniques --- dart/gui/osg/Viewer.cpp | 70 ++++++++++++++++++++++++++++++++++------- dart/gui/osg/Viewer.hpp | 13 ++++++-- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/dart/gui/osg/Viewer.cpp b/dart/gui/osg/Viewer.cpp index efb80fc801e03..498f5d1fc7c2c 100644 --- a/dart/gui/osg/Viewer.cpp +++ b/dart/gui/osg/Viewer.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "dart/gui/osg/Viewer.hpp" #include "dart/gui/osg/TrackballManipulator.hpp" @@ -195,7 +197,7 @@ void ViewerAttachment::attach(Viewer* newViewer) } //============================================================================== -Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn) +Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ShadowType shadowType) : mImageSequenceNum(0), mImageDigits(0), mRecording(false), @@ -211,7 +213,7 @@ Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn) mAllowSimulation(true), mHeadlights(true) { - enableShadows(shadowsOn); + enableShadows(shadowsOn, shadowType); // add the physics group to the root group mRootGroup->addChild(mPhysicsGroup); @@ -854,7 +856,7 @@ bool Viewer::isShadowed() const } //============================================================================== -void Viewer::enableShadows(bool _enable) +void Viewer::enableShadows(bool _enable, ShadowType type) { if(!mPhysicsGroup) { // Flags for shadowing; maybe this needs to be global? @@ -875,15 +877,59 @@ void Viewer::enableShadows(bool _enable) } if(_enable) { - // Use the ShadowMap technique - ::osg::ref_ptr sm = new osgShadow::ShadowMap; - // increase the resolution of default shadow texture for higher quality - int mapres = std::pow(2, 13); - sm->setTextureSize(::osg::Vec2s(mapres,mapres)); - sm->setLight(mLight1); - - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); + switch(type) { + case ShadowType::STANDARD_SHADOW_MAP: + { + // Use the StandardShadowMap technique + ::osg::ref_ptr ssm = new osgShadow::StandardShadowMap; + // we are using Light1 because this is the highest one (on up direction) + ssm->setLight(mLight1); + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(ssm.get()); + break; + } + case ShadowType::SOFT_SHADOW_MAP: + { + // Use the SoftShadowMap technique + ::osg::ref_ptr softsm = new osgShadow::SoftShadowMap; + // we are using Light1 because this is the highest one (on up direction) + softsm->setLight(mLight1); + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(softsm.get()); + break; + } + case ShadowType::SHADOW_TEXTURE: + { + // Use the ShadowTexture technique + ::osg::ref_ptr st = new osgShadow::ShadowTexture; + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(st.get()); + break; + } + case ShadowType::SHADOW_VOLUME: + { + // hint to tell viewer to request stencil buffer when setting up windows + ::osg::DisplaySettings::instance()->setMinimumNumStencilBits(8); + // Use the ShadowVolume technique + ::osg::ref_ptr sv = new osgShadow::ShadowVolume; + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(sv.get()); + break; + } + default: // SHADOW_MAP + { + // Use the ShadowMap technique + ::osg::ref_ptr sm = new osgShadow::ShadowMap; + // increase the resolution of default shadow texture for higher quality + int mapres = std::pow(2, 13); + sm->setTextureSize(::osg::Vec2s(mapres,mapres)); + // we are using Light1 because this is the highest one (on up direction) + sm->setLight(mLight1); + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); + break; + } + } } else static_cast(mPhysicsGroup.get())->setShadowTechnique(0); diff --git a/dart/gui/osg/Viewer.hpp b/dart/gui/osg/Viewer.hpp index 8712c5438744f..1d937ee85b658 100644 --- a/dart/gui/osg/Viewer.hpp +++ b/dart/gui/osg/Viewer.hpp @@ -115,9 +115,18 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject { public: + enum ShadowType { + SHADOW_MAP = 0, + STANDARD_SHADOW_MAP, + SOFT_SHADOW_MAP, + SHADOW_TEXTURE, + SHADOW_VOLUME + // TODO: Add more techniques + }; + /// Constructor for dart::gui::osg::Viewer. This will automatically create the /// default event handler. - Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0), bool shadowsOn = false); + Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0), bool shadowsOn = false, ShadowType shadowType = ShadowType::SHADOW_MAP); /// Destructor virtual ~Viewer(); @@ -292,7 +301,7 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject const ::osg::ref_ptr<::osg::Group>& getPhysicsGroup() const; bool isShadowed() const; - void enableShadows(bool _enable = true); + void enableShadows(bool _enable = true, ShadowType type = ShadowType::STANDARD_SHADOW_MAP); protected: From 655952851ab07a72f51849587d672d86e1b05ea3 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Fri, 9 Feb 2018 14:10:49 +0100 Subject: [PATCH 03/13] Shadows in OpenSceneGraph - minor fix --- dart/gui/osg/Viewer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/gui/osg/Viewer.hpp b/dart/gui/osg/Viewer.hpp index 1d937ee85b658..37a43434a9a19 100644 --- a/dart/gui/osg/Viewer.hpp +++ b/dart/gui/osg/Viewer.hpp @@ -301,7 +301,7 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject const ::osg::ref_ptr<::osg::Group>& getPhysicsGroup() const; bool isShadowed() const; - void enableShadows(bool _enable = true, ShadowType type = ShadowType::STANDARD_SHADOW_MAP); + void enableShadows(bool _enable = true, ShadowType type = ShadowType::SHADOW_MAP); protected: From 53b8a05c348f171e593cb037ed45118f05ce0371 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Mon, 12 Feb 2018 12:41:50 +0100 Subject: [PATCH 04/13] @jslee02 comments --- dart/gui/osg/Viewer.cpp | 89 ++++++++++++++--------------------------- dart/gui/osg/Viewer.hpp | 21 +++++----- 2 files changed, 40 insertions(+), 70 deletions(-) diff --git a/dart/gui/osg/Viewer.cpp b/dart/gui/osg/Viewer.cpp index 498f5d1fc7c2c..43d9256b2607a 100644 --- a/dart/gui/osg/Viewer.cpp +++ b/dart/gui/osg/Viewer.cpp @@ -197,7 +197,7 @@ void ViewerAttachment::attach(Viewer* newViewer) } //============================================================================== -Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ShadowType shadowType) +Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ::osg::ref_ptr shadowTechnique) : mImageSequenceNum(0), mImageDigits(0), mRecording(false), @@ -213,7 +213,7 @@ Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ShadowType shadowT mAllowSimulation(true), mHeadlights(true) { - enableShadows(shadowsOn, shadowType); + enableShadows(shadowsOn, shadowTechnique); // add the physics group to the root group mRootGroup->addChild(mPhysicsGroup); @@ -480,6 +480,15 @@ const ::osg::Group* Viewer::getLightGroup() const return mLightGroup; } +//============================================================================== +const ::osg::ref_ptr<::osg::LightSource>& Viewer::getLightSource(unsigned int index) const +{ + assert(index < 2); + if(index == 0) + return mLightSource1; + return mLightSource2; +} + //============================================================================== void Viewer::setupDefaultLights() { @@ -856,7 +865,7 @@ bool Viewer::isShadowed() const } //============================================================================== -void Viewer::enableShadows(bool _enable, ShadowType type) +void Viewer::enableShadows(bool _enable, ::osg::ref_ptr shadowTechnique) { if(!mPhysicsGroup) { // Flags for shadowing; maybe this needs to be global? @@ -876,67 +885,31 @@ void Viewer::enableShadows(bool _enable, ShadowType type) setupDefaultLights(); } - if(_enable) { - switch(type) { - case ShadowType::STANDARD_SHADOW_MAP: - { - // Use the StandardShadowMap technique - ::osg::ref_ptr ssm = new osgShadow::StandardShadowMap; - // we are using Light1 because this is the highest one (on up direction) - ssm->setLight(mLight1); - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(ssm.get()); - break; - } - case ShadowType::SOFT_SHADOW_MAP: - { - // Use the SoftShadowMap technique - ::osg::ref_ptr softsm = new osgShadow::SoftShadowMap; - // we are using Light1 because this is the highest one (on up direction) - softsm->setLight(mLight1); - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(softsm.get()); - break; - } - case ShadowType::SHADOW_TEXTURE: - { - // Use the ShadowTexture technique - ::osg::ref_ptr st = new osgShadow::ShadowTexture; - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(st.get()); - break; - } - case ShadowType::SHADOW_VOLUME: - { - // hint to tell viewer to request stencil buffer when setting up windows - ::osg::DisplaySettings::instance()->setMinimumNumStencilBits(8); - // Use the ShadowVolume technique - ::osg::ref_ptr sv = new osgShadow::ShadowVolume; - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(sv.get()); - break; - } - default: // SHADOW_MAP - { - // Use the ShadowMap technique - ::osg::ref_ptr sm = new osgShadow::ShadowMap; - // increase the resolution of default shadow texture for higher quality - int mapres = std::pow(2, 13); - sm->setTextureSize(::osg::Vec2s(mapres,mapres)); - // we are using Light1 because this is the highest one (on up direction) - sm->setLight(mLight1); - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); - break; - } - } - } + if(_enable) + setShadowTechnique(shadowTechnique); else static_cast(mPhysicsGroup.get())->setShadowTechnique(0); mShadowed = _enable; } +void Viewer::setShadowTechnique(::osg::ref_ptr shadowTechnique) { + if(!shadowTechnique) { + // default ShadowTechnique is the ShadowMap technique + ::osg::ref_ptr sm = new osgShadow::ShadowMap; + // increase the resolution of default shadow texture for higher quality + int mapres = std::pow(2, 13); + sm->setTextureSize(::osg::Vec2s(mapres,mapres)); + // we are using Light1 because this is the highest one (on up direction) + sm->setLight(mLight1); + // set the technique + static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); + } + else { + static_cast(mPhysicsGroup.get())->setShadowTechnique(shadowTechnique.get()); + } +} + } // namespace osg } // namespace gui } // namespace dart diff --git a/dart/gui/osg/Viewer.hpp b/dart/gui/osg/Viewer.hpp index 37a43434a9a19..35fe3cacb7246 100644 --- a/dart/gui/osg/Viewer.hpp +++ b/dart/gui/osg/Viewer.hpp @@ -38,6 +38,7 @@ #include #include +#include #include @@ -114,19 +115,9 @@ class ViewerAttachment : public virtual ::osg::Group class Viewer : public osgViewer::Viewer, public dart::common::Subject { public: - - enum ShadowType { - SHADOW_MAP = 0, - STANDARD_SHADOW_MAP, - SOFT_SHADOW_MAP, - SHADOW_TEXTURE, - SHADOW_VOLUME - // TODO: Add more techniques - }; - /// Constructor for dart::gui::osg::Viewer. This will automatically create the /// default event handler. - Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0), bool shadowsOn = false, ShadowType shadowType = ShadowType::SHADOW_MAP); + Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0), bool shadowsOn = false, ::osg::ref_ptr shadowTechnique = nullptr); /// Destructor virtual ~Viewer(); @@ -206,6 +197,11 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// Get the Group node that contains the LightSources for this Viewer const ::osg::Group* getLightGroup() const; + /// Get one of the LightSources of this Viewer + /// index either 0 or 1 + /// Useful for shadowing techniques + const ::osg::ref_ptr<::osg::LightSource>& getLightSource(unsigned int index = 0) const; + /// Set up the default lighting scheme void setupDefaultLights(); @@ -301,7 +297,8 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject const ::osg::ref_ptr<::osg::Group>& getPhysicsGroup() const; bool isShadowed() const; - void enableShadows(bool _enable = true, ShadowType type = ShadowType::SHADOW_MAP); + void enableShadows(bool _enable = true, ::osg::ref_ptr shadowTechnique = nullptr); + void setShadowTechnique(::osg::ref_ptr shadowTechnique); protected: From ab72b9d25c89ff174541004aaa1187960ddb4357 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Thu, 15 Feb 2018 14:21:16 +0100 Subject: [PATCH 05/13] Updated .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 036331c1b224e..6a193d4d631e9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ TAGS .DS_Store .cproject .project +.vscode *.orig *.idb *.pdb From 47b7e41620c95a5000114c7ec38f7637c7b40f63 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Thu, 15 Feb 2018 15:35:54 +0100 Subject: [PATCH 06/13] Shadowing capabilities go to WorldNode/Addig flag in VisualAspect --- dart/dynamics/ShapeFrame.cpp | 6 +- dart/dynamics/ShapeFrame.hpp | 9 ++- dart/dynamics/detail/ShapeFrameAspect.hpp | 6 +- dart/gui/osg/InteractiveFrame.cpp | 4 ++ dart/gui/osg/Viewer.cpp | 88 +++-------------------- dart/gui/osg/Viewer.hpp | 15 +--- dart/gui/osg/WorldNode.cpp | 71 ++++++++++++++++-- dart/gui/osg/WorldNode.hpp | 14 +++- 8 files changed, 109 insertions(+), 104 deletions(-) diff --git a/dart/dynamics/ShapeFrame.cpp b/dart/dynamics/ShapeFrame.cpp index a9d14ada7c15a..c7c355994746d 100644 --- a/dart/dynamics/ShapeFrame.cpp +++ b/dart/dynamics/ShapeFrame.cpp @@ -39,9 +39,11 @@ namespace detail { //============================================================================== VisualAspectProperties::VisualAspectProperties(const Eigen::Vector4d& color, - const bool hidden) + const bool hidden, + const bool shadowed) : mRGBA(color), - mHidden(hidden) + mHidden(hidden), + mShadowed(shadowed) { // Do nothing } diff --git a/dart/dynamics/ShapeFrame.hpp b/dart/dynamics/ShapeFrame.hpp index d81b0ab3d3c26..30f8d64639f9b 100644 --- a/dart/dynamics/ShapeFrame.hpp +++ b/dart/dynamics/ShapeFrame.hpp @@ -67,12 +67,15 @@ class VisualAspect final : void setRGBA(const Eigen::Vector4d& color); DART_COMMON_GET_ASPECT_PROPERTY( Eigen::Vector4d, RGBA ) - // void setRGBA(const Eigen::Vector4d& value); // const Eigen::Vector4d& getRGBA() const; DART_COMMON_SET_GET_ASPECT_PROPERTY( bool, Hidden ) - // void setHidden(const Eigen::Vector4d& value); - // const Eigen::Vector4d& getHidden() const; + // void setHidden(const bool& value); + // const bool& getHidden() const; + + DART_COMMON_SET_GET_ASPECT_PROPERTY( bool, Shadowed ) + // void setShadowed(const bool& value); + // const bool& getShadowed() const; /// Identical to setRGB(const Eigen::Vector3d&) void setColor(const Eigen::Vector3d& color); diff --git a/dart/dynamics/detail/ShapeFrameAspect.hpp b/dart/dynamics/detail/ShapeFrameAspect.hpp index 97caa2abbb5d3..44a1331bebc9a 100644 --- a/dart/dynamics/detail/ShapeFrameAspect.hpp +++ b/dart/dynamics/detail/ShapeFrameAspect.hpp @@ -58,10 +58,14 @@ struct VisualAspectProperties /// True if this shape node should be kept from rendering bool mHidden; + /// True if this shape node should be shadowed + bool mShadowed; + /// Constructor VisualAspectProperties( const Eigen::Vector4d& color = Eigen::Vector4d(0.5, 0.5, 1.0, 1.0), - const bool hidden = false); + const bool hidden = false, + const bool shadowed = true); /// Destructor virtual ~VisualAspectProperties() = default; diff --git a/dart/gui/osg/InteractiveFrame.cpp b/dart/gui/osg/InteractiveFrame.cpp index 69cf6f85fac62..4b67da6ca5984 100644 --- a/dart/gui/osg/InteractiveFrame.cpp +++ b/dart/gui/osg/InteractiveFrame.cpp @@ -116,6 +116,8 @@ dart::dynamics::SimpleFrame* InteractiveTool::addShapeFrame( auto shapeFrame = mSimpleFrames.back().get(); shapeFrame->setShape(shape); shapeFrame->createVisualAspect(); + // Disable shadowing for InteractiveTool + shapeFrame->getVisualAspect(true)->setShadowed(false); return shapeFrame; } @@ -230,6 +232,8 @@ dart::dynamics::SimpleFrame* InteractiveFrame::addShapeFrame( auto shapeFrame = mSimpleFrames.back().get(); shapeFrame->setShape(shape); shapeFrame->createVisualAspect(); + // Disable shadowing for InteractiveFrame + shapeFrame->getVisualAspect(true)->setShadowed(false); return shapeFrame; } diff --git a/dart/gui/osg/Viewer.cpp b/dart/gui/osg/Viewer.cpp index 43d9256b2607a..f6b8d8c213726 100644 --- a/dart/gui/osg/Viewer.cpp +++ b/dart/gui/osg/Viewer.cpp @@ -35,13 +35,6 @@ #include #include -#include -#include -#include -#include -#include -#include - #include "dart/gui/osg/Viewer.hpp" #include "dart/gui/osg/TrackballManipulator.hpp" #include "dart/gui/osg/DefaultEventHandler.hpp" @@ -197,7 +190,7 @@ void ViewerAttachment::attach(Viewer* newViewer) } //============================================================================== -Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ::osg::ref_ptr shadowTechnique) +Viewer::Viewer(const ::osg::Vec4& clearColor) : mImageSequenceNum(0), mImageDigits(0), mRecording(false), @@ -213,11 +206,6 @@ Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ::osg::ref_ptraddChild(mPhysicsGroup); - setCameraManipulator(new osg::TrackballManipulator); addInstructionText("Left-click: Interaction\n"); addInstructionText("Right-click: Rotate view\n"); @@ -227,12 +215,12 @@ Viewer::Viewer(const ::osg::Vec4& clearColor, bool shadowsOn, ::osg::ref_ptrsetClearColor(clearColor); getCamera()->setFinalDrawCallback(new SaveScreen(this)); - - setSceneData(mRootGroup.get()); } //============================================================================== @@ -387,7 +375,7 @@ void Viewer::addWorldNode(WorldNode* _newWorldNode, bool _active) return; mWorldNodes[_newWorldNode] = _active; - mPhysicsGroup->addChild(_newWorldNode); + mRootGroup->addChild(_newWorldNode); if(_active) _newWorldNode->simulate(mSimulating); _newWorldNode->mViewer = this; @@ -401,7 +389,7 @@ void Viewer::removeWorldNode(WorldNode* _oldWorldNode) if(it == mWorldNodes.end()) return; - mPhysicsGroup->removeChild(it->first); + mRootGroup->removeChild(it->first); mWorldNodes.erase(it); } @@ -413,7 +401,7 @@ void Viewer::removeWorldNode(std::shared_ptr _oldWorld) if(nullptr == node) return; - mPhysicsGroup->removeChild(node); + mRootGroup->removeChild(node); mWorldNodes.erase(node); } @@ -495,7 +483,7 @@ void Viewer::setupDefaultLights() setUpwardsDirection(mUpwards); switchHeadlights(true); - ::osg::ref_ptr<::osg::StateSet> lightSS = mPhysicsGroup->getOrCreateStateSet(); + ::osg::ref_ptr<::osg::StateSet> lightSS = mRootGroup->getOrCreateStateSet(); mLight1->setLightNum(1); mLightSource1->setLight(mLight1); @@ -511,8 +499,8 @@ void Viewer::setupDefaultLights() mLightGroup->removeChild(mLightSource2); mLightGroup->addChild(mLightSource2); - mPhysicsGroup->removeChild(mLightGroup); - mPhysicsGroup->addChild(mLightGroup); + mRootGroup->removeChild(mLightGroup); + mRootGroup->addChild(mLightGroup); } //============================================================================== @@ -852,64 +840,6 @@ const ::osg::ref_ptr<::osg::Group>& Viewer::getRootGroup() const return mRootGroup; } -//============================================================================== -const ::osg::ref_ptr<::osg::Group>& Viewer::getPhysicsGroup() const -{ - return mPhysicsGroup; -} - -//============================================================================== -bool Viewer::isShadowed() const -{ - return mShadowed; -} - -//============================================================================== -void Viewer::enableShadows(bool _enable, ::osg::ref_ptr shadowTechnique) -{ - if(!mPhysicsGroup) { - // Flags for shadowing; maybe this needs to be global? - constexpr int ReceivesShadowTraversalMask = 0x2; - constexpr int CastsShadowTraversalMask = 0x1; - - // Setup shadows - // Create one ShadowedScene for each light - ::osg::ref_ptr shadowedScene = new osgShadow::ShadowedScene; - shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask); - shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask); - - // set the physics group - mPhysicsGroup = shadowedScene.get(); - mPhysicsGroup->getOrCreateStateSet(); - - setupDefaultLights(); - } - - if(_enable) - setShadowTechnique(shadowTechnique); - else - static_cast(mPhysicsGroup.get())->setShadowTechnique(0); - - mShadowed = _enable; -} - -void Viewer::setShadowTechnique(::osg::ref_ptr shadowTechnique) { - if(!shadowTechnique) { - // default ShadowTechnique is the ShadowMap technique - ::osg::ref_ptr sm = new osgShadow::ShadowMap; - // increase the resolution of default shadow texture for higher quality - int mapres = std::pow(2, 13); - sm->setTextureSize(::osg::Vec2s(mapres,mapres)); - // we are using Light1 because this is the highest one (on up direction) - sm->setLight(mLight1); - // set the technique - static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); - } - else { - static_cast(mPhysicsGroup.get())->setShadowTechnique(shadowTechnique.get()); - } -} - } // namespace osg } // namespace gui } // namespace dart diff --git a/dart/gui/osg/Viewer.hpp b/dart/gui/osg/Viewer.hpp index 35fe3cacb7246..d6a39c5300da5 100644 --- a/dart/gui/osg/Viewer.hpp +++ b/dart/gui/osg/Viewer.hpp @@ -117,7 +117,7 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject public: /// Constructor for dart::gui::osg::Viewer. This will automatically create the /// default event handler. - Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0), bool shadowsOn = false, ::osg::ref_ptr shadowTechnique = nullptr); + Viewer(const ::osg::Vec4& clearColor = ::osg::Vec4(0.9,0.9,0.9,1.0)); /// Destructor virtual ~Viewer(); @@ -293,13 +293,6 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// Get the root ::osg::Group of this Viewer const ::osg::ref_ptr<::osg::Group>& getRootGroup() const; - /// Get the physics root ::osg::Group of this Viewer - const ::osg::ref_ptr<::osg::Group>& getPhysicsGroup() const; - - bool isShadowed() const; - void enableShadows(bool _enable = true, ::osg::ref_ptr shadowTechnique = nullptr); - void setShadowTechnique(::osg::ref_ptr shadowTechnique); - protected: friend class SaveScreen; @@ -331,12 +324,6 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// The root node of this Viewer ::osg::ref_ptr<::osg::Group> mRootGroup; - /// The DART physics node of this Viewer - ::osg::ref_ptr<::osg::Group> mPhysicsGroup; - - /// Whether the shadows are enabled - bool mShadowed; - /// The Group Node containing light sources ::osg::ref_ptr<::osg::Group> mLightGroup; diff --git a/dart/gui/osg/WorldNode.cpp b/dart/gui/osg/WorldNode.cpp index 7b5508438623b..a58dd882c3af0 100644 --- a/dart/gui/osg/WorldNode.cpp +++ b/dart/gui/osg/WorldNode.cpp @@ -34,6 +34,13 @@ #include +#include +#include +#include +#include +#include +#include + #include "dart/gui/osg/WorldNode.hpp" #include "dart/gui/osg/ShapeFrameNode.hpp" @@ -61,12 +68,33 @@ class WorldNodeCallback : public ::osg::NodeCallback }; //============================================================================== -WorldNode::WorldNode(std::shared_ptr _world) +WorldNode::WorldNode(std::shared_ptr _world, ::osg::ref_ptr shadowTechnique) : mWorld(_world), mSimulating(false), mNumStepsPerCycle(1), - mViewer(nullptr) + mViewer(nullptr), + mNormalGroup(new ::osg::Group) { + // Flags for shadowing; maybe this needs to be global? + constexpr int ReceivesShadowTraversalMask = 0x2; + constexpr int CastsShadowTraversalMask = 0x1; + + // Setup shadows + // Create a ShadowedScene + ::osg::ref_ptr shadowedScene = new osgShadow::ShadowedScene; + shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask); + shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask); + + // set the physics group + mShadowedGroup = shadowedScene.get(); + mShadowedGroup->getOrCreateStateSet(); + + // Add normal and shadowed groups + addChild(mNormalGroup); + addChild(mShadowedGroup); + + setShadowTechnique(shadowTechnique); + setUpdateCallback(new WorldNodeCallback); } @@ -193,7 +221,12 @@ void WorldNode::clearUnusedNodes() { NodeMap::iterator it = mFrameToNode.find(frame); ShapeFrameNode* node = it->second; - removeChild(node); + // removeChild(node); + if(!node->getShapeFrame() || !node->getShapeFrame()->hasVisualAspect() || !node->getShapeFrame()->getVisualAspect(true)->getShadowed()) { + mNormalGroup->removeChild(node); + } + else + mShadowedGroup->removeChild(node); mFrameToNode.erase(it); } } @@ -276,7 +309,37 @@ void WorldNode::refreshShapeFrameNode(dart::dynamics::Frame* frame) ::osg::ref_ptr node = new ShapeFrameNode(frame->asShapeFrame(), this); it->second = node; - addChild(node); + // addChild(node); + if(!node->getShapeFrame() || !node->getShapeFrame()->hasVisualAspect() || !node->getShapeFrame()->getVisualAspect(true)->getShadowed()) { + mNormalGroup->addChild(node); + } + else + mShadowedGroup->addChild(node); +} + +//============================================================================== +bool WorldNode::isShadowed() const +{ + return mShadowed; +} + +void WorldNode::setShadowTechnique(::osg::ref_ptr shadowTechnique) { + if(!shadowTechnique) { + mShadowed = false; + // // default ShadowTechnique is the ShadowMap technique + // ::osg::ref_ptr sm = new osgShadow::ShadowMap; + // // increase the resolution of default shadow texture for higher quality + // int mapres = std::pow(2, 13); + // sm->setTextureSize(::osg::Vec2s(mapres,mapres)); + // // we are using Light1 because this is the highest one (on up direction) + // sm->setLight(mLight1); + // // set the technique + // static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); + } + else { + mShadowed = true; + static_cast(mShadowedGroup.get())->setShadowTechnique(shadowTechnique.get()); + } } } // namespace osg diff --git a/dart/gui/osg/WorldNode.hpp b/dart/gui/osg/WorldNode.hpp index 4a272e777c5d5..2cec549c84511 100644 --- a/dart/gui/osg/WorldNode.hpp +++ b/dart/gui/osg/WorldNode.hpp @@ -67,7 +67,7 @@ class WorldNode : public ::osg::Group friend class Viewer; /// Default constructor - explicit WorldNode(std::shared_ptr _world = nullptr); + explicit WorldNode(std::shared_ptr _world = nullptr, ::osg::ref_ptr shadowTechnique = nullptr); /// Set the World that this WorldNode is associated with void setWorld(std::shared_ptr _newWorld); @@ -129,6 +129,9 @@ class WorldNode : public ::osg::Group /// if the simulation is not paused) std::size_t getNumStepsPerCycle() const; + bool isShadowed() const; + void setShadowTechnique(::osg::ref_ptr shadowTechnique = nullptr); + protected: /// Destructor @@ -173,6 +176,15 @@ class WorldNode : public ::osg::Group /// Viewer that this WorldNode is inside of Viewer* mViewer; + /// OSG group for non-shadowed objects + ::osg::ref_ptr<::osg::Group> mNormalGroup; + + /// OSG group for shadowed objects + ::osg::ref_ptr<::osg::Group> mShadowedGroup; + + /// Whether the shadows are enabled + bool mShadowed; + }; } // namespace osg From a996028b38afb28635793f4a24516b89c4deb9c2 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Thu, 15 Feb 2018 19:10:37 +0100 Subject: [PATCH 07/13] Added check for changing shadow flag and docs --- dart/gui/osg/WorldNode.cpp | 29 ++++++++++++----------------- dart/gui/osg/WorldNode.hpp | 6 ++++++ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/dart/gui/osg/WorldNode.cpp b/dart/gui/osg/WorldNode.cpp index a58dd882c3af0..f19dac636c186 100644 --- a/dart/gui/osg/WorldNode.cpp +++ b/dart/gui/osg/WorldNode.cpp @@ -35,11 +35,6 @@ #include #include -#include -#include -#include -#include -#include #include "dart/gui/osg/WorldNode.hpp" #include "dart/gui/osg/ShapeFrameNode.hpp" @@ -221,7 +216,6 @@ void WorldNode::clearUnusedNodes() { NodeMap::iterator it = mFrameToNode.find(frame); ShapeFrameNode* node = it->second; - // removeChild(node); if(!node->getShapeFrame() || !node->getShapeFrame()->hasVisualAspect() || !node->getShapeFrame()->getVisualAspect(true)->getShadowed()) { mNormalGroup->removeChild(node); } @@ -293,6 +287,16 @@ void WorldNode::refreshShapeFrameNode(dart::dynamics::Frame* frame) if(!node) return; + // update the group that ShapeFrameNode should be + if((!node->getShapeFrame()->hasVisualAspect() || !node->getShapeFrame()->getVisualAspect(true)->getShadowed()) && node->getParent(0) != mNormalGroup) { + mShadowedGroup->removeChild(node); + mNormalGroup->addChild(node); + } + else if(node->getShapeFrame()->hasVisualAspect() && node->getShapeFrame()->getVisualAspect(true)->getShadowed() && node->getParent(0) != mShadowedGroup) { + mNormalGroup->removeChild(node); + mShadowedGroup->addChild(node); + } + node->refresh(true); return; } @@ -309,8 +313,7 @@ void WorldNode::refreshShapeFrameNode(dart::dynamics::Frame* frame) ::osg::ref_ptr node = new ShapeFrameNode(frame->asShapeFrame(), this); it->second = node; - // addChild(node); - if(!node->getShapeFrame() || !node->getShapeFrame()->hasVisualAspect() || !node->getShapeFrame()->getVisualAspect(true)->getShadowed()) { + if(!node->getShapeFrame()->hasVisualAspect() || !node->getShapeFrame()->getVisualAspect(true)->getShadowed()) { mNormalGroup->addChild(node); } else @@ -323,18 +326,10 @@ bool WorldNode::isShadowed() const return mShadowed; } +//============================================================================== void WorldNode::setShadowTechnique(::osg::ref_ptr shadowTechnique) { if(!shadowTechnique) { mShadowed = false; - // // default ShadowTechnique is the ShadowMap technique - // ::osg::ref_ptr sm = new osgShadow::ShadowMap; - // // increase the resolution of default shadow texture for higher quality - // int mapres = std::pow(2, 13); - // sm->setTextureSize(::osg::Vec2s(mapres,mapres)); - // // we are using Light1 because this is the highest one (on up direction) - // sm->setLight(mLight1); - // // set the technique - // static_cast(mPhysicsGroup.get())->setShadowTechnique(sm.get()); } else { mShadowed = true; diff --git a/dart/gui/osg/WorldNode.hpp b/dart/gui/osg/WorldNode.hpp index 2cec549c84511..eb24cc08dd0f0 100644 --- a/dart/gui/osg/WorldNode.hpp +++ b/dart/gui/osg/WorldNode.hpp @@ -34,6 +34,7 @@ #define DART_GUI_OSG_WORLDNODE_HPP_ #include +#include #include #include @@ -67,6 +68,7 @@ class WorldNode : public ::osg::Group friend class Viewer; /// Default constructor + /// Shadows are disabled by default explicit WorldNode(std::shared_ptr _world = nullptr, ::osg::ref_ptr shadowTechnique = nullptr); /// Set the World that this WorldNode is associated with @@ -129,7 +131,11 @@ class WorldNode : public ::osg::Group /// if the simulation is not paused) std::size_t getNumStepsPerCycle() const; + /// Get whether the WorldNode is casting shadows bool isShadowed() const; + + /// Set the ShadowTechnique + /// If you wish to disable shadows, pass a nullptr void setShadowTechnique(::osg::ref_ptr shadowTechnique = nullptr); protected: From 62bb1efdd09e1798259d33bce1cd55888fefe8ba Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Fri, 16 Feb 2018 00:04:49 +0100 Subject: [PATCH 08/13] Helper function to create default osg shadow: ShadowMap --- dart/gui/osg/WorldNode.cpp | 14 ++++++++++++++ dart/gui/osg/WorldNode.hpp | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/dart/gui/osg/WorldNode.cpp b/dart/gui/osg/WorldNode.cpp index f19dac636c186..535e70f4afe5f 100644 --- a/dart/gui/osg/WorldNode.cpp +++ b/dart/gui/osg/WorldNode.cpp @@ -35,6 +35,7 @@ #include #include +#include #include "dart/gui/osg/WorldNode.hpp" #include "dart/gui/osg/ShapeFrameNode.hpp" @@ -330,6 +331,7 @@ bool WorldNode::isShadowed() const void WorldNode::setShadowTechnique(::osg::ref_ptr shadowTechnique) { if(!shadowTechnique) { mShadowed = false; + static_cast(mShadowedGroup.get())->setShadowTechnique(nullptr); } else { mShadowed = true; @@ -337,6 +339,18 @@ void WorldNode::setShadowTechnique(::osg::ref_ptr sh } } +//============================================================================== +::osg::ref_ptr WorldNode::createDefaultShadowTechnique(const Viewer* viewer) { + ::osg::ref_ptr sm = new osgShadow::ShadowMap; + // increase the resolution of default shadow texture for higher quality + int mapres = std::pow(2, 13); + sm->setTextureSize(::osg::Vec2s(mapres,mapres)); + // we are using Light1 because this is the highest one (on up direction) + sm->setLight(viewer->getLightSource(0)); + + return sm; +} + } // namespace osg } // namespace gui } // namespace dart diff --git a/dart/gui/osg/WorldNode.hpp b/dart/gui/osg/WorldNode.hpp index eb24cc08dd0f0..f88e97d8b01a4 100644 --- a/dart/gui/osg/WorldNode.hpp +++ b/dart/gui/osg/WorldNode.hpp @@ -138,6 +138,10 @@ class WorldNode : public ::osg::Group /// If you wish to disable shadows, pass a nullptr void setShadowTechnique(::osg::ref_ptr shadowTechnique = nullptr); + /// Helper function to create a default ShadowTechnique given a Viewer + /// the default ShadowTechnique is ShadowMap + static ::osg::ref_ptr createDefaultShadowTechnique(const Viewer* viewer); + protected: /// Destructor From 68dc5db133198ed0d135d67cb4002bfc84b4846d Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Fri, 16 Feb 2018 00:34:15 +0100 Subject: [PATCH 09/13] Add warning when using shadows in ImGuiViewer --- dart/gui/osg/Viewer.cpp | 3 +++ dart/gui/osg/WorldNode.cpp | 12 ++++++++++++ dart/gui/osg/WorldNode.hpp | 4 ++++ 3 files changed, 19 insertions(+) diff --git a/dart/gui/osg/Viewer.cpp b/dart/gui/osg/Viewer.cpp index f6b8d8c213726..e747c3528fa0d 100644 --- a/dart/gui/osg/Viewer.cpp +++ b/dart/gui/osg/Viewer.cpp @@ -380,6 +380,9 @@ void Viewer::addWorldNode(WorldNode* _newWorldNode, bool _active) _newWorldNode->simulate(mSimulating); _newWorldNode->mViewer = this; _newWorldNode->setupViewer(); + // set again the shadow technique to produce warning for ImGuiViewer + if(_newWorldNode->isShadowed()) + _newWorldNode->setShadowTechnique(_newWorldNode->getShadowTechnique()); } //============================================================================== diff --git a/dart/gui/osg/WorldNode.cpp b/dart/gui/osg/WorldNode.cpp index 535e70f4afe5f..0866af37b0a83 100644 --- a/dart/gui/osg/WorldNode.cpp +++ b/dart/gui/osg/WorldNode.cpp @@ -39,6 +39,7 @@ #include "dart/gui/osg/WorldNode.hpp" #include "dart/gui/osg/ShapeFrameNode.hpp" +#include "dart/gui/osg/ImGuiViewer.hpp" #include "dart/simulation/World.hpp" #include "dart/dynamics/Skeleton.hpp" @@ -334,11 +335,22 @@ void WorldNode::setShadowTechnique(::osg::ref_ptr sh static_cast(mShadowedGroup.get())->setShadowTechnique(nullptr); } else { + ImGuiViewer* viewer = mViewer ? dynamic_cast(mViewer) : nullptr; + if(viewer) + dtwarn << "[WorldNode] You are enabling shadows inside an ImGuiViewer. " + << "The ImGui windows may not render properly.\n"; mShadowed = true; static_cast(mShadowedGroup.get())->setShadowTechnique(shadowTechnique.get()); } } +//============================================================================== +::osg::ref_ptr WorldNode::getShadowTechnique() const { + if(!mShadowed) + return nullptr; + return static_cast(mShadowedGroup.get())->getShadowTechnique(); +} + //============================================================================== ::osg::ref_ptr WorldNode::createDefaultShadowTechnique(const Viewer* viewer) { ::osg::ref_ptr sm = new osgShadow::ShadowMap; diff --git a/dart/gui/osg/WorldNode.hpp b/dart/gui/osg/WorldNode.hpp index f88e97d8b01a4..19b595fb82a95 100644 --- a/dart/gui/osg/WorldNode.hpp +++ b/dart/gui/osg/WorldNode.hpp @@ -138,6 +138,10 @@ class WorldNode : public ::osg::Group /// If you wish to disable shadows, pass a nullptr void setShadowTechnique(::osg::ref_ptr shadowTechnique = nullptr); + /// Get the current ShadowTechnique + /// nullptr is there are no shadows + ::osg::ref_ptr getShadowTechnique() const; + /// Helper function to create a default ShadowTechnique given a Viewer /// the default ShadowTechnique is ShadowMap static ::osg::ref_ptr createDefaultShadowTechnique(const Viewer* viewer); From 5ddba86573db80b4c0f836736e75f5abfcbbb33d Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Fri, 16 Feb 2018 00:34:48 +0100 Subject: [PATCH 10/13] Add example of shadows in osgOperationalSpaceControl --- .../osgOperationalSpaceControl.cpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/examples/osgExamples/osgOperationalSpaceControl/osgOperationalSpaceControl.cpp b/examples/osgExamples/osgOperationalSpaceControl/osgOperationalSpaceControl.cpp index 01f0e276f9bce..c80b742215666 100644 --- a/examples/osgExamples/osgOperationalSpaceControl/osgOperationalSpaceControl.cpp +++ b/examples/osgExamples/osgOperationalSpaceControl/osgOperationalSpaceControl.cpp @@ -248,6 +248,41 @@ class ConstraintEventHandler : public ::osgGA::GUIEventHandler dart::sub_ptr mDnD; }; +class ShadowEventHandler : public osgGA::GUIEventHandler +{ +public: + + ShadowEventHandler(OperationalSpaceControlWorld* node, dart::gui::osg::Viewer* viewer) : mNode(node), mViewer(viewer) {} + + bool handle(const osgGA::GUIEventAdapter& ea, + osgGA::GUIActionAdapter&) override + { + if(ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) + { + if(ea.getKey() == 's' || ea.getKey() == 'S') + { + if(mNode->isShadowed()) + mNode->setShadowTechnique(nullptr); + else + mNode->setShadowTechnique(dart::gui::osg::WorldNode::createDefaultShadowTechnique(mViewer)); + return true; + } + } + + // The return value should be 'true' if the input has been fully handled + // and should not be visible to any remaining event handlers. It should be + // false if the input has not been fully handled and should be viewed by + // any remaining event handlers. + return false; + } + +protected: + + OperationalSpaceControlWorld* mNode; + dart::gui::osg::Viewer* mViewer; + +}; + int main() { dart::simulation::WorldPtr world(new dart::simulation::World); @@ -299,6 +334,7 @@ int main() // Add our custom event handler to the Viewer viewer.addEventHandler(new ConstraintEventHandler(node->dnd)); + viewer.addEventHandler(new ShadowEventHandler(node.get(), &viewer)); // Print out instructions std::cout << viewer.getInstructions() << std::endl; From c05a17fc687172d0a351fa242ef2e25f73507476 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Sat, 17 Feb 2018 00:22:15 +0100 Subject: [PATCH 11/13] Minor comments --- dart/gui/osg/Viewer.cpp | 2 +- dart/gui/osg/Viewer.hpp | 2 +- dart/gui/osg/WorldNode.cpp | 16 ++++++++-------- dart/gui/osg/WorldNode.hpp | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dart/gui/osg/Viewer.cpp b/dart/gui/osg/Viewer.cpp index e747c3528fa0d..c816ac8f8a1d5 100644 --- a/dart/gui/osg/Viewer.cpp +++ b/dart/gui/osg/Viewer.cpp @@ -472,7 +472,7 @@ const ::osg::Group* Viewer::getLightGroup() const } //============================================================================== -const ::osg::ref_ptr<::osg::LightSource>& Viewer::getLightSource(unsigned int index) const +const ::osg::ref_ptr<::osg::LightSource>& Viewer::getLightSource(std::size_t index) const { assert(index < 2); if(index == 0) diff --git a/dart/gui/osg/Viewer.hpp b/dart/gui/osg/Viewer.hpp index d6a39c5300da5..360e77386107e 100644 --- a/dart/gui/osg/Viewer.hpp +++ b/dart/gui/osg/Viewer.hpp @@ -200,7 +200,7 @@ class Viewer : public osgViewer::Viewer, public dart::common::Subject /// Get one of the LightSources of this Viewer /// index either 0 or 1 /// Useful for shadowing techniques - const ::osg::ref_ptr<::osg::LightSource>& getLightSource(unsigned int index = 0) const; + const ::osg::ref_ptr<::osg::LightSource>& getLightSource(std::size_t index = 0) const; /// Set up the default lighting scheme void setupDefaultLights(); diff --git a/dart/gui/osg/WorldNode.cpp b/dart/gui/osg/WorldNode.cpp index 0866af37b0a83..153c32d23e89f 100644 --- a/dart/gui/osg/WorldNode.cpp +++ b/dart/gui/osg/WorldNode.cpp @@ -65,8 +65,8 @@ class WorldNodeCallback : public ::osg::NodeCallback }; //============================================================================== -WorldNode::WorldNode(std::shared_ptr _world, ::osg::ref_ptr shadowTechnique) - : mWorld(_world), +WorldNode::WorldNode(std::shared_ptr world, ::osg::ref_ptr shadowTechnique) + : mWorld(world), mSimulating(false), mNumStepsPerCycle(1), mViewer(nullptr), @@ -96,9 +96,9 @@ WorldNode::WorldNode(std::shared_ptr _world, ::osg::ref } //============================================================================== -void WorldNode::setWorld(std::shared_ptr _newWorld) +void WorldNode::setWorld(std::shared_ptr newWorld) { - mWorld = _newWorld; + mWorld = newWorld; } //============================================================================== @@ -163,15 +163,15 @@ bool WorldNode::isSimulating() const } //============================================================================== -void WorldNode::simulate(bool _on) +void WorldNode::simulate(bool on) { - mSimulating = _on; + mSimulating = on; } //============================================================================== -void WorldNode::setNumStepsPerCycle(std::size_t _steps) +void WorldNode::setNumStepsPerCycle(std::size_t steps) { - mNumStepsPerCycle = _steps; + mNumStepsPerCycle = steps; } //============================================================================== diff --git a/dart/gui/osg/WorldNode.hpp b/dart/gui/osg/WorldNode.hpp index 19b595fb82a95..ca8f39b3abe36 100644 --- a/dart/gui/osg/WorldNode.hpp +++ b/dart/gui/osg/WorldNode.hpp @@ -69,10 +69,10 @@ class WorldNode : public ::osg::Group /// Default constructor /// Shadows are disabled by default - explicit WorldNode(std::shared_ptr _world = nullptr, ::osg::ref_ptr shadowTechnique = nullptr); + explicit WorldNode(std::shared_ptr world = nullptr, ::osg::ref_ptr shadowTechnique = nullptr); /// Set the World that this WorldNode is associated with - void setWorld(std::shared_ptr _newWorld); + void setWorld(std::shared_ptr newWorld); /// Get the World that this WorldNode is associated with std::shared_ptr getWorld() const; @@ -121,11 +121,11 @@ class WorldNode : public ::osg::Group /// Pass in true to take steps between render cycles; pass in false to turn /// off steps between render cycles. - void simulate(bool _on); + void simulate(bool on); /// Set the number of steps to take between each render cycle (only if the /// simulation is not paused) - void setNumStepsPerCycle(std::size_t _steps); + void setNumStepsPerCycle(std::size_t steps); /// Get the number of steps that will be taken between each render cycle (only /// if the simulation is not paused) From d0d3b82b87b67f1ae43529ca391d800bfc9820a1 Mon Sep 17 00:00:00 2001 From: Konstantinos Chatzilygeroudis Date: Sat, 17 Feb 2018 10:25:12 +0100 Subject: [PATCH 12/13] Minor typo in WorldNode --- dart/gui/osg/WorldNode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/gui/osg/WorldNode.cpp b/dart/gui/osg/WorldNode.cpp index 153c32d23e89f..ee7cc5650dc66 100644 --- a/dart/gui/osg/WorldNode.cpp +++ b/dart/gui/osg/WorldNode.cpp @@ -82,7 +82,7 @@ WorldNode::WorldNode(std::shared_ptr world, ::osg::ref_ shadowedScene->setReceivesShadowTraversalMask(ReceivesShadowTraversalMask); shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask); - // set the physics group + // set the shadowed group mShadowedGroup = shadowedScene.get(); mShadowedGroup->getOrCreateStateSet(); From 568631ea4acd53b6dee02e8adb78d8a49a1b53b1 Mon Sep 17 00:00:00 2001 From: Jeongseok Lee Date: Sat, 17 Feb 2018 04:47:43 -0800 Subject: [PATCH 13/13] Update changelog for #978 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da36fe9bc29ba..63c9b52495e4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * GUI * Added support of rendering texture images: [#973](https://github.com/dartsim/dart/pull/973) + * Added OSG shadows: [#978](https://github.com/dartsim/dart/pull/978) * License