From 5a73834cbe5da7f6d73e2dca823b414e739f5d02 Mon Sep 17 00:00:00 2001 From: Cedric Pinson Date: Thu, 23 Jul 2009 12:42:01 +0000 Subject: [PATCH] From Cedric Pinson, Store the linkvisitor to be able to configure it by user, like changing the nodemaskoverride, or use a custom LinkVisitor --- include/osgAnimation/AnimationManagerBase | 7 +++- include/osgAnimation/LinkVisitor | 42 ++++++++----------- src/osgAnimation/AnimationManagerBase.cpp | 20 +++++++-- src/osgAnimation/CMakeLists.txt | 1 + src/osgAnimation/LinkVisitor.cpp | 50 +++++++++++++++++++++++ 5 files changed, 91 insertions(+), 29 deletions(-) create mode 100644 src/osgAnimation/LinkVisitor.cpp diff --git a/include/osgAnimation/AnimationManagerBase b/include/osgAnimation/AnimationManagerBase index 55cd7e48a..f30170ad3 100644 --- a/include/osgAnimation/AnimationManagerBase +++ b/include/osgAnimation/AnimationManagerBase @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2008 Cedric Pinson * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -15,6 +15,7 @@ #ifndef OSGANIMATION_ANIMATION_MANAGER_BASE_H #define OSGANIMATION_ANIMATION_MANAGER_BASE_H +#include #include #include #include @@ -46,8 +47,12 @@ namespace osgAnimation void clearTargets(); void normalizeTargets(); + LinkVisitor* getOrCreateLinkVisitor(); + void setLinkVisitor(LinkVisitor*); + protected: + osg::ref_ptr _linker; AnimationList _animations; TargetSet _targets; bool _needToLink; diff --git a/include/osgAnimation/LinkVisitor b/include/osgAnimation/LinkVisitor index 0fb72c126..d25ab5ffd 100644 --- a/include/osgAnimation/LinkVisitor +++ b/include/osgAnimation/LinkVisitor @@ -1,5 +1,5 @@ /* -*-c++-*- - * Copyright (C) 2008 Cedric Pinson + * Copyright (C) 2008 Cedric Pinson * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -17,36 +17,28 @@ #include #include -#include namespace osgAnimation { - - struct LinkVisitor : public osg::NodeVisitor + /** This class is instancied by the AnimationManagerBase, it will link animation target to updatecallback that have the same name + */ + class OSGANIMATION_EXPORT LinkVisitor : public osg::NodeVisitor { + public: + LinkVisitor(); + + META_NodeVisitor("osgAnimation","LinkVisitor"); + + void apply(osg::Node& node); + AnimationList& getAnimationList(); + void reset(); + + protected: + // animation list to link AnimationList _animations; + + // number of success link done unsigned int _nbLinkedTarget; - - LinkVisitor(Animation* animation) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { _animations.push_back(animation); _nbLinkedTarget = 0;} - LinkVisitor(const AnimationList& animations) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { _animations = animations; _nbLinkedTarget = 0;} - - META_NodeVisitor("osgAnimation","LinkVisitor") - - void apply(osg::Node& node) - { - osgAnimation::AnimationUpdateCallback* cb = dynamic_cast(node.getUpdateCallback()); - if (cb) - { - int result = 0; - for (int i = 0; i < (int)_animations.size(); i++) - { - result += cb->link(_animations[i].get()); - _nbLinkedTarget += result; - } - std::cout << "LinkVisitor links " << result << " for \"" << cb->getName() << '"' << std::endl; - } - traverse(node); - } }; } diff --git a/src/osgAnimation/AnimationManagerBase.cpp b/src/osgAnimation/AnimationManagerBase.cpp index a289e0816..a157109bf 100644 --- a/src/osgAnimation/AnimationManagerBase.cpp +++ b/src/osgAnimation/AnimationManagerBase.cpp @@ -21,7 +21,7 @@ AnimationManagerBase::~AnimationManagerBase() {} AnimationManagerBase::AnimationManagerBase() { - _needToLink = false; + _needToLink = false; } void AnimationManagerBase::clearTargets() @@ -95,11 +95,25 @@ void AnimationManagerBase::registerAnimation (Animation* animation) bool AnimationManagerBase::needToLink() const { return _needToLink; } +void AnimationManagerBase::setLinkVisitor(LinkVisitor* visitor) +{ + _linker = visitor; +} + +LinkVisitor* AnimationManagerBase::getOrCreateLinkVisitor() +{ + if (!_linker.valid()) + _linker = new LinkVisitor; + return _linker.get(); +} void AnimationManagerBase::link(osg::Node* subgraph) { - LinkVisitor linker(_animations); - subgraph->accept(linker); + LinkVisitor* linker = getOrCreateLinkVisitor(); + linker->getAnimationList().clear(); + linker->getAnimationList() = _animations; + + subgraph->accept(*linker); _needToLink = false; buildTargetReference(); } diff --git a/src/osgAnimation/CMakeLists.txt b/src/osgAnimation/CMakeLists.txt index 49f7b51ba..80caf9e79 100644 --- a/src/osgAnimation/CMakeLists.txt +++ b/src/osgAnimation/CMakeLists.txt @@ -54,6 +54,7 @@ ADD_LIBRARY(${LIB_NAME} BasicAnimationManager.cpp Bone.cpp Channel.cpp + LinkVisitor.cpp MorphGeometry.cpp RigGeometry.cpp Skeleton.cpp diff --git a/src/osgAnimation/LinkVisitor.cpp b/src/osgAnimation/LinkVisitor.cpp new file mode 100644 index 000000000..af73014b3 --- /dev/null +++ b/src/osgAnimation/LinkVisitor.cpp @@ -0,0 +1,50 @@ +/* -*-c++-*- + * Copyright (C) 2009 Cedric Pinson + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * 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 + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include + +using namespace osgAnimation; + +LinkVisitor::LinkVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) +{ + _nbLinkedTarget = 0; +} + +void LinkVisitor::reset() +{ + _nbLinkedTarget = 0; +} + +AnimationList& LinkVisitor::getAnimationList() +{ + return _animations; +} + +void LinkVisitor::apply(osg::Node& node) +{ + osgAnimation::AnimationUpdateCallback* cb = dynamic_cast(node.getUpdateCallback()); + if (cb) + { + int result = 0; + for (int i = 0; i < (int)_animations.size(); i++) + { + result += cb->link(_animations[i].get()); + _nbLinkedTarget += result; + } + osg::notify(osg::NOTICE) << "LinkVisitor links " << result << " for \"" << cb->getName() << '"' << std::endl; + } + traverse(node); +}