From fef625ce27ac50cf301cc150401e26a8f02acc5e Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Thu, 4 Nov 2010 07:01:38 +0100 Subject: [PATCH] add ConditionNode scenegraph node This class directs its scenegraph traversal by evaluating a condition and doesn't rely on an update callback. --- simgear/scene/model/ConditionNode.cxx | 54 +++++++++++++++++++++++++++ simgear/scene/model/ConditionNode.hxx | 47 +++++++++++++++++++++++ simgear/scene/model/Makefile.am | 2 + simgear/scene/model/animation.cxx | 34 +++++------------ simgear/scene/model/animation.hxx | 2 - 5 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 simgear/scene/model/ConditionNode.cxx create mode 100644 simgear/scene/model/ConditionNode.hxx diff --git a/simgear/scene/model/ConditionNode.cxx b/simgear/scene/model/ConditionNode.cxx new file mode 100644 index 00000000..e68cfa21 --- /dev/null +++ b/simgear/scene/model/ConditionNode.cxx @@ -0,0 +1,54 @@ +// Copyright (C) 2010 Tim Moore (timoore33@gmail.com) +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library 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 "ConditionNode.hxx" + +namespace simgear +{ +using namespace osg; + +ConditionNode::ConditionNode() +{ +} + +ConditionNode::ConditionNode(const ConditionNode& rhs, const CopyOp& op) + : Group(rhs, op), _condition(rhs._condition) +{ +} + +ConditionNode::~ConditionNode() +{ +} + +void ConditionNode::traverse(NodeVisitor& nv) +{ + if (nv.getTraversalMode() == NodeVisitor::TRAVERSE_ACTIVE_CHILDREN) { + unsigned numChildren = getNumChildren(); + if (numChildren == 0) + return; + if (!_condition || _condition->test()) + getChild(0)->accept(nv); + else if (numChildren > 1) + getChild(1)->accept(nv); + else + return; + } else { + Group::traverse(nv); + } +} + +} diff --git a/simgear/scene/model/ConditionNode.hxx b/simgear/scene/model/ConditionNode.hxx new file mode 100644 index 00000000..d36b00f6 --- /dev/null +++ b/simgear/scene/model/ConditionNode.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2010 Tim Moore (timoore33@gmail.com) +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library 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 SIMGEAR_CONDITIONNODE_HXX +#define SIMGEAR_CONDITIONNODE_HXX 1 + +#include +#include + +namespace simgear +{ +/** + * If the condition is true, traverse the first child; otherwise, + * traverse the second if it exists. + */ +class ConditionNode : public osg::Group +{ +public: + ConditionNode(); + ConditionNode(const ConditionNode& rhs, + const osg::CopyOp& op = osg::CopyOp::SHALLOW_COPY); + META_Node(simgear,ConditionNode); + ~ConditionNode(); + const SGCondition* getCondition() { return _condition.ptr(); } + void setCondition(const SGCondition* condition) { _condition = condition; } + + virtual void traverse(osg::NodeVisitor& nv); +protected: + SGSharedPtr _condition; +}; + +} +#endif diff --git a/simgear/scene/model/Makefile.am b/simgear/scene/model/Makefile.am index 7a3f4cfa..b36ab835 100644 --- a/simgear/scene/model/Makefile.am +++ b/simgear/scene/model/Makefile.am @@ -13,6 +13,7 @@ include_HEADERS = \ persparam.hxx \ placement.hxx \ CheckSceneryVisitor.hxx \ + ConditionNode.hxx \ SGClipGroup.hxx \ SGInteractionAnimation.hxx \ SGMaterialAnimation.hxx \ @@ -36,6 +37,7 @@ libsgmodel_a_SOURCES = \ placement.cxx \ shadanim.cxx \ CheckSceneryVisitor.cxx \ + ConditionNode.cxx \ SGClipGroup.cxx \ SGInteractionAnimation.cxx \ SGMaterialAnimation.cxx \ diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index e8486653..489419c2 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -53,6 +53,8 @@ #include "SGScaleTransform.hxx" #include "SGInteractionAnimation.hxx" +#include "ConditionNode.hxx" + using OpenThreads::Mutex; using OpenThreads::ReentrantMutex; using OpenThreads::ScopedLock; @@ -1445,25 +1447,6 @@ SGRangeAnimation::createAnimationGroup(osg::Group& parent) // Implementation of a select animation //////////////////////////////////////////////////////////////////////// -class SGSelectAnimation::UpdateCallback : public osg::NodeCallback { -public: - UpdateCallback(const SGCondition* condition) : - _condition(condition) - {} - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) - { - osg::Switch* sw = static_cast(node); - if (_condition->test()) - sw->setAllChildrenOn(); - else - sw->setAllChildrenOff(); - traverse(node, nv); - } - -private: - SGSharedPtr _condition; -}; - SGSelectAnimation::SGSelectAnimation(const SGPropertyNode* configNode, SGPropertyNode* modelRoot) : SGAnimation(configNode, modelRoot) @@ -1479,12 +1462,13 @@ SGSelectAnimation::createAnimationGroup(osg::Group& parent) // when the animation installer returns if (!condition) return new osg::Group; - - osg::Switch* sw = new osg::Switch; - sw->setName("select animation node"); - sw->setUpdateCallback(new UpdateCallback(condition)); - parent.addChild(sw); - return sw; + simgear::ConditionNode* cn = new simgear::ConditionNode; + cn->setName("select animation node"); + cn->setCondition(condition.ptr()); + osg::Group* grp = new osg::Group; + cn->addChild(grp); + parent.addChild(cn); + return grp; } diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index 1e2b1331..ae4eaead 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -232,8 +232,6 @@ public: SGSelectAnimation(const SGPropertyNode* configNode, SGPropertyNode* modelRoot); virtual osg::Group* createAnimationGroup(osg::Group& parent); -private: - class UpdateCallback; }; -- 2.39.5