add ConditionNode scenegraph node

This class directs its scenegraph traversal by evaluating a condition
and doesn't rely on an update callback.
This commit is contained in:
Tim Moore 2010-11-04 07:01:38 +01:00
parent 0b53dd8fa7
commit fef625ce27
5 changed files with 112 additions and 27 deletions

View File

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

View File

@ -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 <simgear/props/condition.hxx>
#include <osg/Group>
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<SGCondition const> _condition;
};
}
#endif

View File

@ -13,6 +13,7 @@ include_HEADERS = \
persparam.hxx \ persparam.hxx \
placement.hxx \ placement.hxx \
CheckSceneryVisitor.hxx \ CheckSceneryVisitor.hxx \
ConditionNode.hxx \
SGClipGroup.hxx \ SGClipGroup.hxx \
SGInteractionAnimation.hxx \ SGInteractionAnimation.hxx \
SGMaterialAnimation.hxx \ SGMaterialAnimation.hxx \
@ -36,6 +37,7 @@ libsgmodel_a_SOURCES = \
placement.cxx \ placement.cxx \
shadanim.cxx \ shadanim.cxx \
CheckSceneryVisitor.cxx \ CheckSceneryVisitor.cxx \
ConditionNode.cxx \
SGClipGroup.cxx \ SGClipGroup.cxx \
SGInteractionAnimation.cxx \ SGInteractionAnimation.cxx \
SGMaterialAnimation.cxx \ SGMaterialAnimation.cxx \

View File

@ -53,6 +53,8 @@
#include "SGScaleTransform.hxx" #include "SGScaleTransform.hxx"
#include "SGInteractionAnimation.hxx" #include "SGInteractionAnimation.hxx"
#include "ConditionNode.hxx"
using OpenThreads::Mutex; using OpenThreads::Mutex;
using OpenThreads::ReentrantMutex; using OpenThreads::ReentrantMutex;
using OpenThreads::ScopedLock; using OpenThreads::ScopedLock;
@ -1445,25 +1447,6 @@ SGRangeAnimation::createAnimationGroup(osg::Group& parent)
// Implementation of a select animation // 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<osg::Switch*>(node);
if (_condition->test())
sw->setAllChildrenOn();
else
sw->setAllChildrenOff();
traverse(node, nv);
}
private:
SGSharedPtr<SGCondition const> _condition;
};
SGSelectAnimation::SGSelectAnimation(const SGPropertyNode* configNode, SGSelectAnimation::SGSelectAnimation(const SGPropertyNode* configNode,
SGPropertyNode* modelRoot) : SGPropertyNode* modelRoot) :
SGAnimation(configNode, modelRoot) SGAnimation(configNode, modelRoot)
@ -1479,12 +1462,13 @@ SGSelectAnimation::createAnimationGroup(osg::Group& parent)
// when the animation installer returns // when the animation installer returns
if (!condition) if (!condition)
return new osg::Group; return new osg::Group;
simgear::ConditionNode* cn = new simgear::ConditionNode;
osg::Switch* sw = new osg::Switch; cn->setName("select animation node");
sw->setName("select animation node"); cn->setCondition(condition.ptr());
sw->setUpdateCallback(new UpdateCallback(condition)); osg::Group* grp = new osg::Group;
parent.addChild(sw); cn->addChild(grp);
return sw; parent.addChild(cn);
return grp;
} }

View File

@ -232,8 +232,6 @@ public:
SGSelectAnimation(const SGPropertyNode* configNode, SGSelectAnimation(const SGPropertyNode* configNode,
SGPropertyNode* modelRoot); SGPropertyNode* modelRoot);
virtual osg::Group* createAnimationGroup(osg::Group& parent); virtual osg::Group* createAnimationGroup(osg::Group& parent);
private:
class UpdateCallback;
}; };