From Cedric Pinson, this commit contains the following change:

* Change ref_ptr to observer_ptr to avoid cross reference and leak in Skinning
* Set invalidate to true to re run the check visitor in Skeleton
* Shallow copy Sampler in channel copy constructor
* Add accessor in VertexInfluence
* Remove dead code in Timeline.cpp
* Dont force linking in Bone::UpdateBone, the decision is done by the user or the manager
* Add offset in timeline stats to display each manager on the screen
* Add a flag in animation manager base to enable or not automatic link when modifying the manager
This commit is contained in:
Cedric Pinson
2009-10-21 15:45:13 +00:00
parent 9382800576
commit 4372ec3cba
11 changed files with 43 additions and 76 deletions

View File

@@ -44,18 +44,27 @@ namespace osgAnimation
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
/// Operation that must be done each frame
/** Reset the value of targets
this Operation must be done each frame */
void clearTargets();
LinkVisitor* getOrCreateLinkVisitor();
void setLinkVisitor(LinkVisitor*);
/// set a flag to define the behaviour
void setAutomaticLink(bool);
bool isAutomaticLink() const;
void dirty();
protected:
osg::ref_ptr<LinkVisitor> _linker;
AnimationList _animations;
TargetSet _targets;
bool _needToLink;
bool _automaticLink;
};
}
#endif

View File

@@ -77,10 +77,13 @@ namespace osgAnimation
Channel* clone() const { return new TemplateChannel<SamplerType>(*this); }
TemplateChannel (const TemplateChannel& channel) :
Channel(channel),
_target(new TargetType(*channel.getTargetTyped())),
_sampler(channel._sampler.get())
Channel(channel)
{
if (channel.getTargetTyped())
_target = new TargetType(*channel.getTargetTyped());
if (channel.getSamplerTyped())
_sampler = new SamplerType(*channel.getSamplerTyped());
}
TemplateChannel (SamplerType* s = 0,TargetType* target = 0)
@@ -102,7 +105,7 @@ namespace osgAnimation
// create a key from current target value
typename KeyframeContainerType::KeyType key(0, _target->getValue());
// recreate the keyframe container
_sampler = 0;
getOrCreateSampler()->setKeyframeContainer(0);
getOrCreateSampler()->getOrCreateKeyframeContainer();
// add the key
_sampler->getKeyframeContainerTyped()->push_back(key);

View File

@@ -32,7 +32,7 @@ namespace osgAnimation
public:
META_Object(osgAnimation, UpdateSkeleton);
UpdateSkeleton() : _needValidate(true) {}
UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::Object(us, copyop), osg::NodeCallback(us, copyop) {}
UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::Object(us, copyop), osg::NodeCallback(us, copyop) { _needValidate = true;}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
protected:

View File

@@ -46,11 +46,11 @@ namespace osgAnimation
{
public:
BoneWeight(BoneType* bone, float weight) : _bone(bone), _weight(weight) {}
const BoneType* getBone() const { return &(*_bone); }
const BoneType* getBone() const { return _bone.get(); }
float getWeight() const { return _weight; }
void setWeight(float w) { _weight = w; }
protected:
osg::ref_ptr<BoneType> _bone;
osg::observer_ptr<BoneType> _bone;
float _weight;
};
@@ -191,7 +191,7 @@ namespace osgAnimation
const VertexList& vertexes = uniq.getVertexes();
int vertexSize = vertexes.size();
for (int j = 0; j < vertexSize; j++)
for (int j = 0; j < vertexSize; j++)
{
int idx = vertexes[j];
dst[idx] = src[idx] * matrix;

View File

@@ -1,5 +1,5 @@
/* -*-c++-*-
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
*
* 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
@@ -96,6 +96,8 @@ namespace osgAnimation
_bone2Vertexes.clear();
_uniqVertexSetToBoneSet.clear();
}
const VertexIndexToBoneWeightMap& getVertexToBoneList() const;
protected:
BoneToVertexList _bone2Vertexes;
VertexIndexToBoneWeightMap _vertex2Bones;

View File

@@ -133,8 +133,6 @@ bool Animation::update (float time, int priority)
break;
}
// std::cout << "t " << t << " / " << _duration << std::endl;
ChannelList::const_iterator chan;
for( chan=_channels.begin(); chan!=_channels.end(); ++chan)
{

View File

@@ -23,6 +23,7 @@ AnimationManagerBase::~AnimationManagerBase() {}
AnimationManagerBase::AnimationManagerBase()
{
_needToLink = false;
_automaticLink = true;
}
void AnimationManagerBase::clearTargets()
@@ -31,6 +32,14 @@ void AnimationManagerBase::clearTargets()
(*it).get()->reset();
}
void AnimationManagerBase::dirty()
{
_needToLink = true;
}
void AnimationManagerBase::setAutomaticLink(bool state) { _automaticLink = state; }
bool AnimationManagerBase::isAutomaticLink() const { return _automaticLink; }
void AnimationManagerBase::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
@@ -64,13 +73,14 @@ AnimationManagerBase::AnimationManagerBase(const AnimationManagerBase& b, const
_animations.push_back(animation);
}
_needToLink = true;
_automaticLink = b._automaticLink;
buildTargetReference();
}
void AnimationManagerBase::buildTargetReference()
{
_targets.clear();
for( AnimationList::iterator iterAnim = _animations.begin(); iterAnim != _animations.end(); ++iterAnim )
for( AnimationList::iterator iterAnim = _animations.begin(); iterAnim != _animations.end(); ++iterAnim )
{
Animation* anim = (*iterAnim).get();
for (ChannelList::iterator it = anim->getChannels().begin();
@@ -98,7 +108,7 @@ void AnimationManagerBase::unregisterAnimation (Animation* animation)
buildTargetReference();
}
bool AnimationManagerBase::needToLink() const { return _needToLink; }
bool AnimationManagerBase::needToLink() const { return _needToLink && isAutomaticLink(); }
void AnimationManagerBase::setLinkVisitor(LinkVisitor* visitor)

View File

@@ -69,31 +69,6 @@ void osgAnimation::Bone::UpdateBone::operator()(osg::Node* node, osg::NodeVisito
b->accept(visitor);
}
if (!_manager.valid())
{
FindParentAnimationManagerVisitor finder;
if (b->getParents().size() > 1)
{
osg::notify(osg::WARN) << "A Bone should not have multi parent ( " << b->getName() << " ) has parents ";
osg::notify(osg::WARN) << "( " << b->getParents()[0]->getName();
for (int i = 1; i < (int)b->getParents().size(); i++)
osg::notify(osg::WARN) << ", " << b->getParents()[i]->getName();
osg::notify(osg::WARN) << ")" << std::endl;
return;
}
b->getParents()[0]->accept(finder);
if (!finder.getAnimationManager())
{
osg::notify(osg::WARN) << "Warning can't update Bone, path to parent AnimationManagerBase not found" << std::endl;
return;
}
_manager = finder.getAnimationManager();
}
updateLink();
update(*b);
Bone* parent = b->getBoneParent();
@@ -117,16 +92,6 @@ osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) :
_invBindInSkeletonSpace(b._invBindInSkeletonSpace),
_boneInSkeletonSpace(b._boneInSkeletonSpace)
{
#if 0
osg::ref_ptr<osg::NodeCallback> updatecallback = getUpdateCallback();
setUpdateCallback(0);
while (updatecallback.valid()) {
osg::NodeCallback* ucb = dynamic_cast<osg::NodeCallback*>(updatecallback->clone(copyop));
ucb->setNestedCallback(0);
addUpdateCallback(ucb);
updatecallback = updatecallback->getNestedCallback();
}
#endif
}
osgAnimation::Bone::Bone(const std::string& name)

View File

@@ -563,7 +563,7 @@ bool StatsHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdap
StatsList statsList;
for (int i = 0; i < (int)finder._timelines.size(); i++)
statsList.push_back(finder._timelines[0]->getStats());
statsList.push_back(finder._timelines[i]->getStats());
for(int i = statsList[0]->getEarliestFrameNumber(); i<= statsList[0]->getLatestFrameNumber()-1; ++i)
{
@@ -653,6 +653,7 @@ void StatsHandler::setUpScene(osgViewer::Viewer* viewer)
StatsTimeline* s = new StatsTimeline;
osg::MatrixTransform* m = s->createStatsForTimeline(finder._timelines[i].get());
m->setUpdateCallback(s);
m->setMatrix(osg::Matrix::translate(0, -i * 100, 0));
_group->addChild(m);
}
}

View File

@@ -201,31 +201,8 @@ void osgAnimation::Timeline::internalRemoveAction(Action* action)
void osgAnimation::Timeline::internalAddAction(int priority, const FrameAction& ftl)
{
_actions[priority].insert(_actions[priority].begin(), ftl);
// _actions[priority].push_back(ftl);
}
#if 0
void osgAnimation::Timeline::evaluateCallback(unsigned int frame)
{
// update from high priority to low priority
for( ActionLayers::reverse_iterator iterAnim = _actions.rbegin(); iterAnim != _actions.rend(); ++iterAnim )
{
// update all animation
ActionList& list = iterAnim->second;
for (unsigned int i = 0; i < list.size(); i++)
{
unsigned int firstFrame = list[i].first;
Action* action = list[i].second.get();
// check if current frame of timeline hit an action interval
if (frame >= firstFrame &&
frame < (firstFrame + action->getNumFrames()) )
action->evaluateCallback(frame - firstFrame);
}
}
processPendingOperation();
}
#endif
bool osgAnimation::Timeline::isActive(Action* activeAction)
{
// update from high priority to low priority

View File

@@ -13,11 +13,13 @@
*/
#include <osgAnimation/VertexInfluence>
#include <osg/Notify>
#include <iostream>
#include <algorithm>
using namespace osgAnimation;
const osgAnimation::VertexInfluenceSet::VertexIndexToBoneWeightMap& osgAnimation::VertexInfluenceSet::getVertexToBoneList() const { return _vertex2Bones;}
// this class manage VertexInfluence database by mesh
// reference bones per vertex ...
void osgAnimation::VertexInfluenceSet::buildVertex2BoneList()
@@ -33,13 +35,13 @@ void osgAnimation::VertexInfluenceSet::buildVertex2BoneList()
int index = viw.first;
float weight = viw.second;
if (vi.getName().empty())
std::cout << "osgAnimation::VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl;
osg::notify(osg::WARN) << "osgAnimation::VertexInfluenceSet::buildVertex2BoneList warning vertex " << index << " is not assigned to a bone" << std::endl;
_vertex2Bones[index].push_back(BoneWeight(vi.getName(), weight));
}
}
// normalize weight per vertex
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); it++)
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); it++)
{
BoneWeightList& bones = it->second;
int size = bones.size();
@@ -48,7 +50,7 @@ void osgAnimation::VertexInfluenceSet::buildVertex2BoneList()
sum += bones[i].getWeight();
if (sum < 1e-4)
{
std::cerr << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << it->first << " seems to have 0 weight, skip normalize for this vertex" << std::endl;
osg::notify(osg::WARN) << "VertexInfluenceSet::buildVertex2BoneList warning the vertex " << it->first << " seems to have 0 weight, skip normalize for this vertex" << std::endl;
}
else
{