root/OpenSceneGraph/trunk/src/osgAnimation/Bone.cpp @ 10386

Revision 10386, 4.1 kB (checked in by cedricpinson, 8 years ago)

From Cedric Pinson, fix constructors for cloning osgAnimation objects

Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
3 *
4 * This library is open source and may be redistributed and/or modified under 
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * OpenSceneGraph Public License for more details.
13*/
14
15#include <osgAnimation/Skinning>
16#include <osgAnimation/Bone>
17#include <osgAnimation/Skeleton>
18
19osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) :
20    osg::Object(apc, copyop),
21    osgAnimation::AnimationUpdateCallback(apc, copyop)
22{
23    _quaternion = new osgAnimation::QuatTarget(apc._quaternion->getValue());
24    _position = new osgAnimation::Vec3Target(apc._position->getValue());
25    _scale = new osgAnimation::Vec3Target(apc._scale->getValue());
26}
27
28
29osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) :
30    osg::Transform(b,copyop),
31    _position(b._position),
32    _rotation(b._rotation),
33    _scale(b._scale),
34    _needToRecomputeBindMatrix(true),
35    _bindInBoneSpace(b._bindInBoneSpace),
36    _invBindInSkeletonSpace(b._invBindInSkeletonSpace),
37    _boneInSkeletonSpace(b._boneInSkeletonSpace)
38{
39    osg::ref_ptr<osg::NodeCallback> updatecallback = getUpdateCallback();
40    setUpdateCallback(0);
41    while (updatecallback.valid()) {
42        osg::NodeCallback* ucb = dynamic_cast<osg::NodeCallback*>(updatecallback->clone(copyop));
43        ucb->setNestedCallback(0);
44        addUpdateCallback(ucb);
45        updatecallback = updatecallback->getNestedCallback();
46    }
47}
48
49osgAnimation::Bone::Bone(const std::string& name)
50{
51    if (!name.empty())
52        setName(name);
53    _needToRecomputeBindMatrix = false;
54}
55
56
57void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
58{
59    std::string cbName = name;
60    if (cbName.empty())
61        cbName = getName();
62    setUpdateCallback(new UpdateBone(cbName));
63}
64
65void osgAnimation::Bone::computeBindMatrix()
66{
67    _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);
68    const Bone* parent = getBoneParent();
69    _needToRecomputeBindMatrix = false;
70    if (!parent)
71    {
72        osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you should not have this message, it means you miss to attach this bone(" << getName() <<") to a Skeleton node" << std::endl;
73        return;
74    }
75    _invBindInSkeletonSpace = parent->getInvBindMatrixInSkeletonSpace() * _invBindInSkeletonSpace;
76}
77
78osgAnimation::Bone* osgAnimation::Bone::getBoneParent()
79{
80    if (getParents().empty())
81        return 0;
82    osg::Node::ParentList parents = getParents();
83    for (osg::Node::ParentList::iterator it = parents.begin(); it != parents.end(); it++)
84    {
85        Bone* pb = dynamic_cast<Bone*>(*it);
86        if (pb)
87            return pb;
88    }
89    return 0;
90}
91const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const
92{
93    if (getParents().empty())
94        return 0;
95    const osg::Node::ParentList& parents = getParents();
96    for (osg::Node::ParentList::const_iterator it = parents.begin(); it != parents.end(); it++)
97    {
98        const Bone* pb = dynamic_cast<const Bone*>(*it);
99        if (pb)
100            return pb;
101    }
102    return 0;
103}
104
105
106/** Add Node to Group.
107 * If node is not NULL and is not contained in Group then increment its
108 * reference count, add it to the child list and dirty the bounding
109 * sphere to force it to recompute on next getBound() and return true for success.
110 * Otherwise return false. Scene nodes can't be added as child nodes.
111 */
112bool osgAnimation::Bone::addChild( Node *child )
113{
114    Bone* bone = dynamic_cast<Bone*>(child);
115    if (bone)
116        bone->setNeedToComputeBindMatrix(true);
117    return osg::Group::addChild(child);
118}
119
120osgAnimation::Bone::BoneMap osgAnimation::Bone::getBoneMap()
121{
122    BoneMapVisitor mapVisitor;
123    this->accept(mapVisitor);
124    return mapVisitor._map;
125}
Note: See TracBrowser for help on using the browser.