From c934b47f2e94fcefb719b9b6186abc4fd8562670 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 29 Dec 2010 18:09:23 +0100 Subject: [PATCH] Issue 110: fix pick animation interaction with effects Set OVERRIDE and PROTECTED attributes on pick animation state attributes. Set up attributes and add a colorMode uniform so that the default shader will take color and alpha values from the material. Also, add a DotOsg writer method for ConditionNode. --- simgear/scene/model/ConditionNode.cxx | 24 +++++++++++++ simgear/scene/model/ConditionNode.hxx | 2 +- simgear/scene/model/animation.cxx | 52 ++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/simgear/scene/model/ConditionNode.cxx b/simgear/scene/model/ConditionNode.cxx index 56460bef..1ef46ae7 100644 --- a/simgear/scene/model/ConditionNode.cxx +++ b/simgear/scene/model/ConditionNode.cxx @@ -21,6 +21,9 @@ #include "ConditionNode.hxx" +#include +#include + #include namespace simgear @@ -57,4 +60,25 @@ void ConditionNode::traverse(NodeVisitor& nv) } } +namespace +{ +bool ConditionNode_writeLocalData(const Object& obj, osgDB::Output& fw) +{ + const ConditionNode& cn = static_cast(obj); + // Can't really print out conditions + fw.indent() << "expression "; + if (cn.getCondition()) + fw << "yes\n"; + else + fw << "no\n"; + return true; +} + +osgDB::RegisterDotOsgWrapperProxy g_ConditionNodeProxy( + new ConditionNode, + "simgear::ConditionNode", + "Object Node simgear::ConditionNode Group", + 0, + &ConditionNode_writeLocalData); +} } diff --git a/simgear/scene/model/ConditionNode.hxx b/simgear/scene/model/ConditionNode.hxx index d36b00f6..f50ba99f 100644 --- a/simgear/scene/model/ConditionNode.hxx +++ b/simgear/scene/model/ConditionNode.hxx @@ -35,7 +35,7 @@ public: const osg::CopyOp& op = osg::CopyOp::SHALLOW_COPY); META_Node(simgear,ConditionNode); ~ConditionNode(); - const SGCondition* getCondition() { return _condition.ptr(); } + const SGCondition* getCondition() const { return _condition.ptr(); } void setCondition(const SGCondition* condition) { _condition = condition; } virtual void traverse(osg::NodeVisitor& nv); diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 489419c2..a6734c1e 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +45,7 @@ #include #include #include +#include #include "animation.hxx" #include "model.hxx" @@ -59,6 +62,7 @@ using OpenThreads::Mutex; using OpenThreads::ReentrantMutex; using OpenThreads::ScopedLock; +using namespace simgear; //////////////////////////////////////////////////////////////////////// // Static utility functions. @@ -2260,6 +2264,12 @@ SGPickAnimation::SGPickAnimation(const SGPropertyNode* configNode, { } +namespace +{ +Mutex colorModeUniformMutex; +osg::ref_ptr colorModeUniform; +} + osg::Group* SGPickAnimation::createAnimationGroup(osg::Group& parent) { @@ -2290,28 +2300,52 @@ SGPickAnimation::createAnimationGroup(osg::Group& parent) &parent)); // prepare a state set that paints the edges of this object yellow + // The material and texture attributes are set with + // OVERRIDE|PROTECTED in case there is a material animation on a + // higher node in the scene graph, which would have its material + // attribute set with OVERRIDE. osg::StateSet* stateSet = highlightGroup->getOrCreateStateSet(); - stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); - + osg::Texture2D* white = StateAttributeFactory::instance()->getWhiteTexture(); + stateSet->setTextureAttributeAndModes(0, white, + (osg::StateAttribute::ON + | osg::StateAttribute::OVERRIDE + | osg::StateAttribute::PROTECTED)); osg::PolygonOffset* polygonOffset = new osg::PolygonOffset; polygonOffset->setFactor(-1); polygonOffset->setUnits(-1); stateSet->setAttribute(polygonOffset, osg::StateAttribute::OVERRIDE); - stateSet->setMode(GL_POLYGON_OFFSET_LINE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); - + stateSet->setMode(GL_POLYGON_OFFSET_LINE, + osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); osg::PolygonMode* polygonMode = new osg::PolygonMode; polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); stateSet->setAttribute(polygonMode, osg::StateAttribute::OVERRIDE); - osg::Material* material = new osg::Material; material->setColorMode(osg::Material::OFF); - material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 0, 1)); - material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 0, 1)); + material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(0, 0, 0, 1)); + // XXX Alpha < 1.0 in the diffuse material value is a signal to the + // default shader to take the alpha value from the material value + // and not the glColor. In many cases the pick animation geometry is + // transparent, so the outline would not be visible without this hack. + material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0, 0, 0, .95)); material->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 0, 1)); material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0, 0, 0, 0)); - stateSet->setAttribute(material, osg::StateAttribute::OVERRIDE); - + stateSet->setAttribute( + material, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); + // The default shader has a colorMode uniform that mimics the + // behavior of Material color mode. + osg::Uniform* cmUniform = 0; + { + ScopedLock lock(colorModeUniformMutex); + if (!colorModeUniform.valid()) { + colorModeUniform = new osg::Uniform(osg::Uniform::INT, "colorMode"); + colorModeUniform->set(0); // MODE_OFF + colorModeUniform->setDataVariance(osg::Object::STATIC); + } + cmUniform = colorModeUniform.get(); + } + stateSet->addUniform(cmUniform, + osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); // Only add normal geometry if configured if (getConfig()->getBoolValue("visible", true)) parent.addChild(normalGroup.get()); -- 2.39.5