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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user