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.
This commit is contained in:
Tim Moore
2010-12-29 18:09:23 +01:00
parent 33e1a9457a
commit c934b47f2e
3 changed files with 68 additions and 10 deletions

View File

@@ -21,6 +21,9 @@
#include "ConditionNode.hxx"
#include <osgDB/Registry>
#include <osgDB/Output>
#include <simgear/math/SGMath.hxx>
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<const ConditionNode&>(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);
}
}

View File

@@ -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);

View File

@@ -22,6 +22,7 @@
#include <osg/Geometry>
#include <osg/LOD>
#include <osg/Math>
#include <osg/Object>
#include <osg/PolygonMode>
#include <osg/PolygonOffset>
#include <osg/StateSet>
@@ -29,6 +30,7 @@
#include <osg/TexMat>
#include <osg/Texture2D>
#include <osg/Transform>
#include <osg/Uniform>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osgDB/Input>
@@ -43,6 +45,7 @@
#include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/scene/util/SGSceneUserData.hxx>
#include <simgear/scene/util/SGStateAttributeVisitor.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#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<osg::Uniform> 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<Mutex> 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());