From: James Turner Date: Wed, 30 Jan 2013 21:51:41 +0000 (+0000) Subject: Pick animation moved to its own file. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a58b41e7d266869346a03d6db9f9ce7145aaec06;p=simgear.git Pick animation moved to its own file. Preparatory work for adding more pick animations which will share some internals with this code. --- diff --git a/simgear/scene/model/CMakeLists.txt b/simgear/scene/model/CMakeLists.txt index f3f49336..e10994b0 100644 --- a/simgear/scene/model/CMakeLists.txt +++ b/simgear/scene/model/CMakeLists.txt @@ -11,6 +11,7 @@ set(HEADERS SGClipGroup.hxx SGInteractionAnimation.hxx SGMaterialAnimation.hxx + SGPickAnimation.hxx SGOffsetTransform.hxx SGReaderWriterXML.hxx SGRotateTransform.hxx @@ -34,6 +35,7 @@ set(SOURCES SGClipGroup.cxx SGInteractionAnimation.cxx SGLightAnimation.cxx + SGPickAnimation.cxx SGMaterialAnimation.cxx SGOffsetTransform.cxx SGReaderWriterXML.cxx diff --git a/simgear/scene/model/SGPickAnimation.cxx b/simgear/scene/model/SGPickAnimation.cxx new file mode 100644 index 00000000..a282df19 --- /dev/null +++ b/simgear/scene/model/SGPickAnimation.cxx @@ -0,0 +1,339 @@ +/* -*-c++-*- + * + * Copyright (C) 2013 James Turner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace simgear; + +using OpenThreads::Mutex; +using OpenThreads::ScopedLock; + + class SGPickAnimation::PickCallback : public SGPickCallback { + public: + PickCallback(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot) : + _repeatable(configNode->getBoolValue("repeatable", false)), + _repeatInterval(configNode->getDoubleValue("interval-sec", 0.1)) + { + SG_LOG(SG_INPUT, SG_DEBUG, "Reading all bindings"); + std::vector bindings; + + bindings = configNode->getChildren("button"); + for (unsigned int i = 0; i < bindings.size(); ++i) { + _buttons.push_back( bindings[i]->getIntValue() ); + } + bindings = configNode->getChildren("binding"); + for (unsigned int i = 0; i < bindings.size(); ++i) { + _bindingsDown.push_back(new SGBinding(bindings[i], modelRoot)); + } + + const SGPropertyNode* upNode = configNode->getChild("mod-up"); + if (!upNode) + return; + bindings = upNode->getChildren("binding"); + for (unsigned int i = 0; i < bindings.size(); ++i) { + _bindingsUp.push_back(new SGBinding(bindings[i], modelRoot)); + } + } + virtual bool buttonPressed(int button, const Info&) + { + bool found = false; + for( std::vector::iterator it = _buttons.begin(); it != _buttons.end(); ++it ) { + if( *it == button ) { + found = true; + break; + } + } + if (!found ) + return false; + SGBindingList::const_iterator i; + for (i = _bindingsDown.begin(); i != _bindingsDown.end(); ++i) + (*i)->fire(); + _repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat + return true; + } + virtual void buttonReleased(void) + { + SGBindingList::const_iterator i; + for (i = _bindingsUp.begin(); i != _bindingsUp.end(); ++i) + (*i)->fire(); + } + virtual void update(double dt) + { + if (!_repeatable) + return; + + _repeatTime += dt; + while (_repeatInterval < _repeatTime) { + _repeatTime -= _repeatInterval; + SGBindingList::const_iterator i; + for (i = _bindingsDown.begin(); i != _bindingsDown.end(); ++i) + (*i)->fire(); + } + } + private: + SGBindingList _bindingsDown; + SGBindingList _bindingsUp; + std::vector _buttons; + bool _repeatable; + double _repeatInterval; + double _repeatTime; + }; + + class VncVisitor : public osg::NodeVisitor { + public: + VncVisitor(double x, double y, int mask) : + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _texX(x), _texY(y), _mask(mask), _done(false) + { + SG_LOG(SG_INPUT, SG_DEBUG, "VncVisitor constructor " + << x << "," << y << " mask " << mask); + } + + virtual void apply(osg::Node &node) + { + // Some nodes have state sets attached + touchStateSet(node.getStateSet()); + if (!_done) + traverse(node); + if (_done) return; + // See whether we are a geode worth exploring + osg::Geode *g = dynamic_cast(&node); + if (!g) return; + // Go find all its drawables + int i = g->getNumDrawables(); + while (--i >= 0) { + osg::Drawable *d = g->getDrawable(i); + if (d) touchDrawable(*d); + } + // Out of optimism, do the same for EffectGeode + simgear::EffectGeode *eg = dynamic_cast(&node); + if (!eg) return; + for (simgear::EffectGeode::DrawablesIterator di = eg->drawablesBegin(); + di != eg->drawablesEnd(); di++) { + touchDrawable(**di); + } + // Now see whether the EffectGeode has an Effect + simgear::Effect *e = eg->getEffect(); + if (e) { + touchStateSet(e->getDefaultStateSet()); + } + } + + inline void touchDrawable(osg::Drawable &d) + { + osg::StateSet *ss = d.getStateSet(); + touchStateSet(ss); + } + + void touchStateSet(osg::StateSet *ss) + { + if (!ss) return; + osg::StateAttribute *sa = ss->getTextureAttribute(0, + osg::StateAttribute::TEXTURE); + if (!sa) return; + osg::Texture *t = sa->asTexture(); + if (!t) return; + osg::Image *img = t->getImage(0); + if (!img) return; + if (!_done) { + int pixX = _texX * img->s(); + int pixY = _texY * img->t(); + _done = img->sendPointerEvent(pixX, pixY, _mask); + SG_LOG(SG_INPUT, SG_DEBUG, "VncVisitor image said " << _done + << " to coord " << pixX << "," << pixY); + } + } + + inline bool wasSuccessful() + { + return _done; + } + + private: + double _texX, _texY; + int _mask; + bool _done; + }; + + + class SGPickAnimation::VncCallback : public SGPickCallback { + public: + VncCallback(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot, + osg::Group *node) + : _node(node) + { + SG_LOG(SG_INPUT, SG_DEBUG, "Configuring VNC callback"); + const char *cornernames[3] = {"top-left", "top-right", "bottom-left"}; + SGVec3d *cornercoords[3] = {&_topLeft, &_toRight, &_toDown}; + for (int c =0; c < 3; c++) { + const SGPropertyNode* cornerNode = configNode->getChild(cornernames[c]); + *cornercoords[c] = SGVec3d( + cornerNode->getDoubleValue("x"), + cornerNode->getDoubleValue("y"), + cornerNode->getDoubleValue("z")); + } + _toRight -= _topLeft; + _toDown -= _topLeft; + _squaredRight = dot(_toRight, _toRight); + _squaredDown = dot(_toDown, _toDown); + } + + virtual bool buttonPressed(int button, const Info& info) + { + SGVec3d loc(info.local); + SG_LOG(SG_INPUT, SG_DEBUG, "VNC pressed " << button << ": " << loc); + loc -= _topLeft; + _x = dot(loc, _toRight) / _squaredRight; + _y = dot(loc, _toDown) / _squaredDown; + if (_x<0) _x = 0; else if (_x > 1) _x = 1; + if (_y<0) _y = 0; else if (_y > 1) _y = 1; + VncVisitor vv(_x, _y, 1 << button); + _node->accept(vv); + return vv.wasSuccessful(); + + } + virtual void buttonReleased(void) + { + SG_LOG(SG_INPUT, SG_DEBUG, "VNC release"); + VncVisitor vv(_x, _y, 0); + _node->accept(vv); + } + virtual void update(double dt) + { + } + private: + double _x, _y; + osg::ref_ptr _node; + SGVec3d _topLeft, _toRight, _toDown; + double _squaredRight, _squaredDown; + }; + + SGPickAnimation::SGPickAnimation(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot) : + SGAnimation(configNode, modelRoot) + { + } + + namespace + { + OpenThreads::Mutex colorModeUniformMutex; + osg::ref_ptr colorModeUniform; + } + + osg::Group* + SGPickAnimation::createAnimationGroup(osg::Group& parent) + { + osg::Group* commonGroup = new osg::Group; + + // Contains the normal geometry that is interactive + osg::ref_ptr normalGroup = new osg::Group; + normalGroup->setName("pick normal group"); + normalGroup->addChild(commonGroup); + + // Used to render the geometry with just yellow edges + osg::Group* highlightGroup = new osg::Group; + highlightGroup->setName("pick highlight group"); + highlightGroup->setNodeMask(simgear::PICK_BIT); + highlightGroup->addChild(commonGroup); + SGSceneUserData* ud; + ud = SGSceneUserData::getOrCreateSceneUserData(commonGroup); + + // add actions that become macro and command invocations + std::vector actions; + actions = getConfig()->getChildren("action"); + for (unsigned int i = 0; i < actions.size(); ++i) + ud->addPickCallback(new PickCallback(actions[i], getModelRoot())); + // Look for the VNC sessions that want raw mouse input + actions = getConfig()->getChildren("vncaction"); + for (unsigned int i = 0; i < actions.size(); ++i) + ud->addPickCallback(new VncCallback(actions[i], getModelRoot(), + &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(); + 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); + 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(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 | 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()); + parent.addChild(highlightGroup); + + + return commonGroup; +} + \ No newline at end of file diff --git a/simgear/scene/model/SGPickAnimation.hxx b/simgear/scene/model/SGPickAnimation.hxx new file mode 100644 index 00000000..c1761809 --- /dev/null +++ b/simgear/scene/model/SGPickAnimation.hxx @@ -0,0 +1,43 @@ +/* -*-c++-*- + * + * Copyright (C) 2013 James Turner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +#ifndef SG_SCENE_PICK_ANIMATION_HXX +#define SG_SCENE_PICK_ANIMATION_HXX + +#include + + +////////////////////////////////////////////////////////////////////// +// Pick animation +////////////////////////////////////////////////////////////////////// + +class SGPickAnimation : public SGAnimation { +public: + SGPickAnimation(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot); + virtual osg::Group* createAnimationGroup(osg::Group& parent); +private: + class PickCallback; + class VncCallback; +}; + +#endif // of SG_SCENE_PICK_ANIMATION_HXX + diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 9647c66c..edc9e16c 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #include @@ -41,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -59,6 +56,7 @@ #include "SGRotateTransform.hxx" #include "SGScaleTransform.hxx" #include "SGInteractionAnimation.hxx" +#include "SGPickAnimation.hxx" #include "ConditionNode.hxx" @@ -2155,305 +2153,3 @@ SGTexTransformAnimation::appendTexRotate(const SGPropertyNode* config, updateCallback->appendTransform(rotation, value); } - -//////////////////////////////////////////////////////////////////////// -// Implementation of SGPickAnimation -//////////////////////////////////////////////////////////////////////// - -class SGPickAnimation::PickCallback : public SGPickCallback { -public: - PickCallback(const SGPropertyNode* configNode, - SGPropertyNode* modelRoot) : - _repeatable(configNode->getBoolValue("repeatable", false)), - _repeatInterval(configNode->getDoubleValue("interval-sec", 0.1)) - { - SG_LOG(SG_INPUT, SG_DEBUG, "Reading all bindings"); - std::vector bindings; - - bindings = configNode->getChildren("button"); - for (unsigned int i = 0; i < bindings.size(); ++i) { - _buttons.push_back( bindings[i]->getIntValue() ); - } - bindings = configNode->getChildren("binding"); - for (unsigned int i = 0; i < bindings.size(); ++i) { - _bindingsDown.push_back(new SGBinding(bindings[i], modelRoot)); - } - - const SGPropertyNode* upNode = configNode->getChild("mod-up"); - if (!upNode) - return; - bindings = upNode->getChildren("binding"); - for (unsigned int i = 0; i < bindings.size(); ++i) { - _bindingsUp.push_back(new SGBinding(bindings[i], modelRoot)); - } - } - virtual bool buttonPressed(int button, const Info&) - { - bool found = false; - for( std::vector::iterator it = _buttons.begin(); it != _buttons.end(); ++it ) { - if( *it == button ) { - found = true; - break; - } - } - if (!found ) - return false; - SGBindingList::const_iterator i; - for (i = _bindingsDown.begin(); i != _bindingsDown.end(); ++i) - (*i)->fire(); - _repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat - return true; - } - virtual void buttonReleased(void) - { - SGBindingList::const_iterator i; - for (i = _bindingsUp.begin(); i != _bindingsUp.end(); ++i) - (*i)->fire(); - } - virtual void update(double dt) - { - if (!_repeatable) - return; - - _repeatTime += dt; - while (_repeatInterval < _repeatTime) { - _repeatTime -= _repeatInterval; - SGBindingList::const_iterator i; - for (i = _bindingsDown.begin(); i != _bindingsDown.end(); ++i) - (*i)->fire(); - } - } -private: - SGBindingList _bindingsDown; - SGBindingList _bindingsUp; - std::vector _buttons; - bool _repeatable; - double _repeatInterval; - double _repeatTime; -}; - -class VncVisitor : public osg::NodeVisitor { - public: - VncVisitor(double x, double y, int mask) : - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _texX(x), _texY(y), _mask(mask), _done(false) - { - SG_LOG(SG_INPUT, SG_DEBUG, "VncVisitor constructor " - << x << "," << y << " mask " << mask); - } - - virtual void apply(osg::Node &node) - { - // Some nodes have state sets attached - touchStateSet(node.getStateSet()); - if (!_done) - traverse(node); - if (_done) return; - // See whether we are a geode worth exploring - osg::Geode *g = dynamic_cast(&node); - if (!g) return; - // Go find all its drawables - int i = g->getNumDrawables(); - while (--i >= 0) { - osg::Drawable *d = g->getDrawable(i); - if (d) touchDrawable(*d); - } - // Out of optimism, do the same for EffectGeode - simgear::EffectGeode *eg = dynamic_cast(&node); - if (!eg) return; - for (simgear::EffectGeode::DrawablesIterator di = eg->drawablesBegin(); - di != eg->drawablesEnd(); di++) { - touchDrawable(**di); - } - // Now see whether the EffectGeode has an Effect - simgear::Effect *e = eg->getEffect(); - if (e) { - touchStateSet(e->getDefaultStateSet()); - } - } - - inline void touchDrawable(osg::Drawable &d) - { - osg::StateSet *ss = d.getStateSet(); - touchStateSet(ss); - } - - void touchStateSet(osg::StateSet *ss) - { - if (!ss) return; - osg::StateAttribute *sa = ss->getTextureAttribute(0, - osg::StateAttribute::TEXTURE); - if (!sa) return; - osg::Texture *t = sa->asTexture(); - if (!t) return; - osg::Image *img = t->getImage(0); - if (!img) return; - if (!_done) { - int pixX = _texX * img->s(); - int pixY = _texY * img->t(); - _done = img->sendPointerEvent(pixX, pixY, _mask); - SG_LOG(SG_INPUT, SG_DEBUG, "VncVisitor image said " << _done - << " to coord " << pixX << "," << pixY); - } - } - - inline bool wasSuccessful() - { - return _done; - } - - private: - double _texX, _texY; - int _mask; - bool _done; -}; - - -class SGPickAnimation::VncCallback : public SGPickCallback { -public: - VncCallback(const SGPropertyNode* configNode, - SGPropertyNode* modelRoot, - osg::Group *node) - : _node(node) - { - SG_LOG(SG_INPUT, SG_DEBUG, "Configuring VNC callback"); - const char *cornernames[3] = {"top-left", "top-right", "bottom-left"}; - SGVec3d *cornercoords[3] = {&_topLeft, &_toRight, &_toDown}; - for (int c =0; c < 3; c++) { - const SGPropertyNode* cornerNode = configNode->getChild(cornernames[c]); - *cornercoords[c] = SGVec3d( - cornerNode->getDoubleValue("x"), - cornerNode->getDoubleValue("y"), - cornerNode->getDoubleValue("z")); - } - _toRight -= _topLeft; - _toDown -= _topLeft; - _squaredRight = dot(_toRight, _toRight); - _squaredDown = dot(_toDown, _toDown); - } - - virtual bool buttonPressed(int button, const Info& info) - { - SGVec3d loc(info.local); - SG_LOG(SG_INPUT, SG_DEBUG, "VNC pressed " << button << ": " << loc); - loc -= _topLeft; - _x = dot(loc, _toRight) / _squaredRight; - _y = dot(loc, _toDown) / _squaredDown; - if (_x<0) _x = 0; else if (_x > 1) _x = 1; - if (_y<0) _y = 0; else if (_y > 1) _y = 1; - VncVisitor vv(_x, _y, 1 << button); - _node->accept(vv); - return vv.wasSuccessful(); - - } - virtual void buttonReleased(void) - { - SG_LOG(SG_INPUT, SG_DEBUG, "VNC release"); - VncVisitor vv(_x, _y, 0); - _node->accept(vv); - } - virtual void update(double dt) - { - } -private: - double _x, _y; - osg::ref_ptr _node; - SGVec3d _topLeft, _toRight, _toDown; - double _squaredRight, _squaredDown; -}; - -SGPickAnimation::SGPickAnimation(const SGPropertyNode* configNode, - SGPropertyNode* modelRoot) : - SGAnimation(configNode, modelRoot) -{ -} - -namespace -{ -Mutex colorModeUniformMutex; -osg::ref_ptr colorModeUniform; -} - -osg::Group* -SGPickAnimation::createAnimationGroup(osg::Group& parent) -{ - osg::Group* commonGroup = new osg::Group; - - // Contains the normal geometry that is interactive - osg::ref_ptr normalGroup = new osg::Group; - normalGroup->setName("pick normal group"); - normalGroup->addChild(commonGroup); - - // Used to render the geometry with just yellow edges - osg::Group* highlightGroup = new osg::Group; - highlightGroup->setName("pick highlight group"); - highlightGroup->setNodeMask(SG_NODEMASK_PICK_BIT); - highlightGroup->addChild(commonGroup); - SGSceneUserData* ud; - ud = SGSceneUserData::getOrCreateSceneUserData(commonGroup); - - // add actions that become macro and command invocations - std::vector actions; - actions = getConfig()->getChildren("action"); - for (unsigned int i = 0; i < actions.size(); ++i) - ud->addPickCallback(new PickCallback(actions[i], getModelRoot())); - // Look for the VNC sessions that want raw mouse input - actions = getConfig()->getChildren("vncaction"); - for (unsigned int i = 0; i < actions.size(); ++i) - ud->addPickCallback(new VncCallback(actions[i], getModelRoot(), - &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(); - 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); - 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(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 | 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()); - parent.addChild(highlightGroup); - - return commonGroup; -} diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index 920ed5e1..6c95bf3b 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -325,22 +325,6 @@ private: class UpdateCallback; osg::ref_ptr _effect_texture; }; - - -////////////////////////////////////////////////////////////////////// -// Pick animation -////////////////////////////////////////////////////////////////////// - -class SGPickAnimation : public SGAnimation { -public: - SGPickAnimation(const SGPropertyNode* configNode, - SGPropertyNode* modelRoot); - virtual osg::Group* createAnimationGroup(osg::Group& parent); -private: - class PickCallback; - class VncCallback; -}; - ////////////////////////////////////////////////////////////////////// // Light animation