Show
Ignore:
Timestamp:
08/27/09 18:21:01 (8 years ago)
Author:
cedricpinson
Message:

From Michael Platings, I've moved the matrix updating from UpdateSkeleton? to UpdateBone?. UpdateSkeleton? now merely checks that Bones appear before other children and issues a warning if this isn't the case

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgAnimation/Bone.cpp

    r10518 r10558  
    1717#include <osgAnimation/Skeleton> 
    1818 
     19 
     20struct FindNearestParentAnimationManager : public osg::NodeVisitor 
     21{ 
     22    osg::ref_ptr<osgAnimation::AnimationManagerBase> _manager; 
     23    FindNearestParentAnimationManager() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {} 
     24    void apply(osg::Node& node) 
     25    { 
     26        if (_manager.valid()) 
     27            return; 
     28        osg::NodeCallback* callback = node.getUpdateCallback(); 
     29        while (callback)  
     30        { 
     31            _manager = dynamic_cast<osgAnimation::AnimationManagerBase*>(callback); 
     32            if (_manager.valid()) 
     33                return; 
     34            callback = callback->getNestedCallback(); 
     35        } 
     36        traverse(node); 
     37    } 
     38}; 
     39 
     40 
     41struct ComputeBindMatrixVisitor : public osg::NodeVisitor 
     42{ 
     43    ComputeBindMatrixVisitor(): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} 
     44    void apply(osg::Node& node) { return; } 
     45    void apply(osg::Transform& node)  
     46    { 
     47        osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node); 
     48        if (!bone) 
     49            return; 
     50        if (bone->needToComputeBindMatrix()) 
     51            bone->computeBindMatrix(); 
     52 
     53        traverse(node); 
     54    } 
     55}; 
     56 
     57 
     58 
    1959osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) : 
    2060    osg::Object(apc, copyop), 
     
    2464    _position = new osgAnimation::Vec3Target(apc._position->getValue()); 
    2565    _scale = new osgAnimation::Vec3Target(apc._scale->getValue()); 
     66} 
     67 
     68bool osgAnimation::Bone::UpdateBone::link(osgAnimation::Channel* channel) 
     69{ 
     70    if (channel->getName().find("quaternion") != std::string::npos) 
     71    { 
     72        return channel->setTarget(_quaternion.get()); 
     73    } 
     74    else if (channel->getName().find("position") != std::string::npos) 
     75    { 
     76        return channel->setTarget(_position.get()); 
     77    } 
     78    else if (channel->getName().find("scale") != std::string::npos) 
     79    { 
     80        return channel->setTarget(_scale.get()); 
     81    } 
     82    else  
     83    { 
     84        osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl; 
     85    } 
     86    return false; 
     87} 
     88 
     89 
     90/** Callback method called by the NodeVisitor when visiting a node.*/ 
     91void osgAnimation::Bone::UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv) 
     92{ 
     93    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) 
     94    { 
     95        Bone* b = dynamic_cast<Bone*>(node); 
     96        if (!b) 
     97        { 
     98            osg::notify(osg::WARN) << "Warning: UpdateBone set on non-Bone object." << std::endl; 
     99            return; 
     100        } 
     101 
     102        if (b->needToComputeBindMatrix()) 
     103        { 
     104            ComputeBindMatrixVisitor visitor; 
     105            b->accept(visitor); 
     106        } 
     107 
     108        if (!_manager.valid()) 
     109        { 
     110            FindNearestParentAnimationManager finder; 
     111 
     112            if (b->getParents().size() > 1) 
     113            { 
     114                osg::notify(osg::WARN) << "A Bone should not have multi parent ( " << b->getName() << " ) has parents "; 
     115                osg::notify(osg::WARN) << "( " << b->getParents()[0]->getName(); 
     116                for (int i = 1; i < (int)b->getParents().size(); i++) 
     117                    osg::notify(osg::WARN) << ", " << b->getParents()[i]->getName(); 
     118                osg::notify(osg::WARN) << ")" << std::endl; 
     119                return; 
     120            } 
     121            b->getParents()[0]->accept(finder); 
     122 
     123            if (!finder._manager.valid()) 
     124            { 
     125                osg::notify(osg::WARN) << "Warning can't update Bone, path to parent AnimationManagerBase not found" << std::endl; 
     126                return; 
     127            } 
     128 
     129            _manager = finder._manager.get(); 
     130        } 
     131 
     132        updateLink(); 
     133        update(*b); 
     134 
     135        Bone* parent = b->getBoneParent(); 
     136        if (parent) 
     137            b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace()); 
     138        else 
     139            b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace()); 
     140 
     141    } 
     142    traverse(node,nv); 
    26143} 
    27144