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

Revision 10561, 6.8 kB (checked in by cedricpinson, 8 years ago)

From Cedric Pinson, The following modification are
Update Timeline.cpp to add current layer to the ActionVisitor?, use correctly the priority
Add accessors in Action.cpp to retrieve protected data
Split files and rename them to classname
Change de default color of UpdateMaterial? to FFOOFF to detect unset value
Add accessors in LinkVisitor? instead of accessing data directly
Update osganimationtimeline example to fit the api callback

Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@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#include <osgAnimation/FindParentAnimationManagerVisitor>
19#include <osgAnimation/BoneMapVisitor>
20#include <osgAnimation/ComputeBindMatrixVisitor>
21
22
23osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) :
24    osg::Object(apc, copyop),
25    osgAnimation::AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
26{
27    _quaternion = new osgAnimation::QuatTarget(apc._quaternion->getValue());
28    _position = new osgAnimation::Vec3Target(apc._position->getValue());
29    _scale = new osgAnimation::Vec3Target(apc._scale->getValue());
30}
31
32bool osgAnimation::Bone::UpdateBone::link(osgAnimation::Channel* channel)
33{
34    if (channel->getName().find("quaternion") != std::string::npos)
35    {
36        return channel->setTarget(_quaternion.get());
37    }
38    else if (channel->getName().find("position") != std::string::npos)
39    {
40        return channel->setTarget(_position.get());
41    }
42    else if (channel->getName().find("scale") != std::string::npos)
43    {
44        return channel->setTarget(_scale.get());
45    }
46    else 
47    {
48        osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl;
49    }
50    return false;
51}
52
53
54/** Callback method called by the NodeVisitor when visiting a node.*/
55void osgAnimation::Bone::UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv)
56{
57    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
58    {
59        Bone* b = dynamic_cast<Bone*>(node);
60        if (!b)
61        {
62            osg::notify(osg::WARN) << "Warning: UpdateBone set on non-Bone object." << std::endl;
63            return;
64        }
65
66        if (b->needToComputeBindMatrix())
67        {
68            ComputeBindMatrixVisitor visitor;
69            b->accept(visitor);
70        }
71
72        if (!_manager.valid())
73        {
74            FindParentAnimationManagerVisitor finder;
75
76            if (b->getParents().size() > 1)
77            {
78                osg::notify(osg::WARN) << "A Bone should not have multi parent ( " << b->getName() << " ) has parents ";
79                osg::notify(osg::WARN) << "( " << b->getParents()[0]->getName();
80                for (int i = 1; i < (int)b->getParents().size(); i++)
81                    osg::notify(osg::WARN) << ", " << b->getParents()[i]->getName();
82                osg::notify(osg::WARN) << ")" << std::endl;
83                return;
84            }
85            b->getParents()[0]->accept(finder);
86
87            if (!finder.getAnimationManager())
88            {
89                osg::notify(osg::WARN) << "Warning can't update Bone, path to parent AnimationManagerBase not found" << std::endl;
90                return;
91            }
92
93            _manager = finder.getAnimationManager();
94        }
95
96        updateLink();
97        update(*b);
98
99        Bone* parent = b->getBoneParent();
100        if (parent)
101            b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace());
102        else
103            b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace());
104
105    }
106    traverse(node,nv);
107}
108
109
110osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) :
111    osg::Transform(b,copyop),
112    _position(b._position),
113    _rotation(b._rotation),
114    _scale(b._scale),
115    _needToRecomputeBindMatrix(true),
116    _bindInBoneSpace(b._bindInBoneSpace),
117    _invBindInSkeletonSpace(b._invBindInSkeletonSpace),
118    _boneInSkeletonSpace(b._boneInSkeletonSpace)
119{
120#if 0
121    osg::ref_ptr<osg::NodeCallback> updatecallback = getUpdateCallback();
122    setUpdateCallback(0);
123    while (updatecallback.valid()) {
124        osg::NodeCallback* ucb = dynamic_cast<osg::NodeCallback*>(updatecallback->clone(copyop));
125        ucb->setNestedCallback(0);
126        addUpdateCallback(ucb);
127        updatecallback = updatecallback->getNestedCallback();
128    }
129#endif
130}
131
132osgAnimation::Bone::Bone(const std::string& name)
133{
134    if (!name.empty())
135        setName(name);
136    _needToRecomputeBindMatrix = false;
137}
138
139
140void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
141{
142    std::string cbName = name;
143    if (cbName.empty())
144        cbName = getName();
145    setUpdateCallback(new UpdateBone(cbName));
146}
147
148void osgAnimation::Bone::computeBindMatrix()
149{
150    _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);
151    const Bone* parent = getBoneParent();
152    _needToRecomputeBindMatrix = false;
153    if (!parent)
154    {
155        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;
156        return;
157    }
158    _invBindInSkeletonSpace = parent->getInvBindMatrixInSkeletonSpace() * _invBindInSkeletonSpace;
159}
160
161osgAnimation::Bone* osgAnimation::Bone::getBoneParent()
162{
163    if (getParents().empty())
164        return 0;
165    osg::Node::ParentList parents = getParents();
166    for (osg::Node::ParentList::iterator it = parents.begin(); it != parents.end(); it++)
167    {
168        Bone* pb = dynamic_cast<Bone*>(*it);
169        if (pb)
170            return pb;
171    }
172    return 0;
173}
174const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const
175{
176    if (getParents().empty())
177        return 0;
178    const osg::Node::ParentList& parents = getParents();
179    for (osg::Node::ParentList::const_iterator it = parents.begin(); it != parents.end(); it++)
180    {
181        const Bone* pb = dynamic_cast<const Bone*>(*it);
182        if (pb)
183            return pb;
184    }
185    return 0;
186}
187
188
189/** Add Node to Group.
190 * If node is not NULL and is not contained in Group then increment its
191 * reference count, add it to the child list and dirty the bounding
192 * sphere to force it to recompute on next getBound() and return true for success.
193 * Otherwise return false. Scene nodes can't be added as child nodes.
194 */
195bool osgAnimation::Bone::addChild( Node *child )
196{
197    Bone* bone = dynamic_cast<Bone*>(child);
198    if (bone)
199        bone->setNeedToComputeBindMatrix(true);
200    return osg::Group::addChild(child);
201}
202
203osgAnimation::Bone::BoneMap osgAnimation::Bone::getBoneMap()
204{
205    BoneMapVisitor mapVisitor;
206    this->accept(mapVisitor);
207    return mapVisitor.getBoneMap();
208}
Note: See TracBrowser for help on using the browser.