Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreSkeletonInstance.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 9.5 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgreSkeletonInstance.h"
31#include "OgreBone.h"
32#include "OgreTagPoint.h"
33
34
35namespace Ogre {
36    //-------------------------------------------------------------------------
37    SkeletonInstance::SkeletonInstance(const SkeletonPtr& masterCopy) 
38        : Skeleton()
39        , mSkeleton(masterCopy)
40        , mNextTagPointAutoHandle(0)
41    {
42    }
43    //-------------------------------------------------------------------------
44    SkeletonInstance::~SkeletonInstance()
45    {
46        // have to call this here rather than in Resource destructor
47        // since calling virtual methods in base destructors causes crash
48        // ...and calling it in Skeleton destructor does not unload
49        // SkeletonInstance since it has seized to be by then.
50        unload();
51    }
52    //-------------------------------------------------------------------------
53    unsigned short SkeletonInstance::getNumAnimations(void) const
54    {
55        return mSkeleton->getNumAnimations();
56    }
57    //-------------------------------------------------------------------------
58    Animation* SkeletonInstance::getAnimation(unsigned short index) const
59    {
60        return mSkeleton->getAnimation(index);
61    }
62    //-------------------------------------------------------------------------
63    Animation* SkeletonInstance::createAnimation(const String& name, Real length)
64    {
65        return mSkeleton->createAnimation(name, length);
66    }
67    //-------------------------------------------------------------------------
68    Animation* SkeletonInstance::getAnimation(const String& name, 
69                const LinkedSkeletonAnimationSource** linker) const
70    {
71        return mSkeleton->getAnimation(name, linker);
72    }
73        //-------------------------------------------------------------------------
74        Animation* SkeletonInstance::_getAnimationImpl(const String& name, 
75                const LinkedSkeletonAnimationSource** linker) const
76        {
77                return mSkeleton->_getAnimationImpl(name, linker);
78        }
79    //-------------------------------------------------------------------------
80    void SkeletonInstance::removeAnimation(const String& name)
81    {
82        mSkeleton->removeAnimation(name);
83    }
84        //-------------------------------------------------------------------------
85        void SkeletonInstance::addLinkedSkeletonAnimationSource(const String& skelName, 
86                Real scale)
87        {
88                mSkeleton->addLinkedSkeletonAnimationSource(skelName, scale);
89        }
90        //-------------------------------------------------------------------------
91        void SkeletonInstance::removeAllLinkedSkeletonAnimationSources(void)
92        {
93                mSkeleton->removeAllLinkedSkeletonAnimationSources();
94        }
95        //-------------------------------------------------------------------------
96        Skeleton::LinkedSkeletonAnimSourceIterator
97        SkeletonInstance::getLinkedSkeletonAnimationSourceIterator(void) const
98        {
99                return mSkeleton->getLinkedSkeletonAnimationSourceIterator();
100        }
101        //-------------------------------------------------------------------------
102        void SkeletonInstance::_initAnimationState(AnimationStateSet* animSet)
103        {
104                mSkeleton->_initAnimationState(animSet);
105        }
106        //-------------------------------------------------------------------------
107        void SkeletonInstance::_refreshAnimationState(AnimationStateSet* animSet)
108        {
109                mSkeleton->_refreshAnimationState(animSet);
110        }
111    //-------------------------------------------------------------------------
112    void SkeletonInstance::cloneBoneAndChildren(Bone* source, Bone* parent)
113    {
114        Bone* newBone;
115        if (source->getName().empty())
116        {
117            newBone = createBone(source->getHandle());
118        }
119        else
120        {
121            newBone = createBone(source->getName(), source->getHandle());
122        }
123        if (parent == NULL)
124        {
125            mRootBones.push_back(newBone);
126        }
127        else
128        {
129            parent->addChild(newBone);
130        }
131        newBone->setOrientation(source->getOrientation());
132        newBone->setPosition(source->getPosition());
133        newBone->setScale(source->getScale());
134
135        // Process children
136        Node::ChildNodeIterator it = source->getChildIterator();
137        while (it.hasMoreElements())
138        {
139            cloneBoneAndChildren(static_cast<Bone*>(it.getNext()), newBone);
140        }
141    }
142    //-------------------------------------------------------------------------
143    void SkeletonInstance::loadImpl(void)
144    {
145        mNextAutoHandle = mSkeleton->mNextAutoHandle;
146        mNextTagPointAutoHandle = 0;
147        // construct self from master
148        mBlendState = mSkeleton->mBlendState;
149        // Copy bones
150        BoneIterator i = mSkeleton->getRootBoneIterator();
151        while (i.hasMoreElements())
152        {
153            Bone* b = i.getNext();
154            cloneBoneAndChildren(b, 0);
155            b->_update(true, false);
156        }
157        setBindingPose();
158    }
159    //-------------------------------------------------------------------------
160    void SkeletonInstance::unloadImpl(void)
161    {
162        Skeleton::unloadImpl();
163
164        // destroy TagPoints
165        for (TagPointList::const_iterator it = mActiveTagPoints.begin(); it != mActiveTagPoints.end(); ++it)
166        {
167            TagPoint* tagPoint = *it;
168            // Woohoo! The child object all the same attaching this skeleton instance, but is ok we can just
169            // ignore it:
170            //   1. The parent node of the tagPoint already deleted by Skeleton::unload(), nothing need to do now
171            //   2. And the child object relationship already detached by Entity::~Entity()
172            delete tagPoint;
173        }
174        mActiveTagPoints.clear();
175        for (TagPointList::const_iterator it2 = mFreeTagPoints.begin(); it2 != mFreeTagPoints.end(); ++it2)
176        {
177            TagPoint* tagPoint = *it2;
178            delete tagPoint;
179        }
180        mFreeTagPoints.clear();
181    }
182
183    //-------------------------------------------------------------------------
184    TagPoint* SkeletonInstance::createTagPointOnBone(Bone* bone,
185        const Quaternion &offsetOrientation, 
186        const Vector3 &offsetPosition)
187    {
188        TagPoint* ret;
189        if (mFreeTagPoints.empty()) {
190            ret = new TagPoint(mNextTagPointAutoHandle++, this);
191            mActiveTagPoints.push_back(ret);
192        } else {
193            ret = mFreeTagPoints.front();
194            mActiveTagPoints.splice(
195                mActiveTagPoints.end(), mFreeTagPoints, mFreeTagPoints.begin());
196            // Initial some members ensure identically behavior, avoiding potential bug.
197            ret->setParentEntity(0);
198            ret->setChildObject(0);
199            ret->setInheritOrientation(true);
200            ret->setInheritScale(true);
201            ret->setInheritParentEntityOrientation(true);
202            ret->setInheritParentEntityScale(true);
203        }
204
205        ret->setPosition(offsetPosition);
206        ret->setOrientation(offsetOrientation);
207        ret->setScale(Vector3::UNIT_SCALE);
208        ret->setBindingPose();
209        bone->addChild(ret);
210
211        return ret;
212    }
213    //-------------------------------------------------------------------------
214    void SkeletonInstance::freeTagPoint(TagPoint* tagPoint)
215    {
216        TagPointList::iterator it =
217            std::find(mActiveTagPoints.begin(), mActiveTagPoints.end(), tagPoint);
218        assert(it != mActiveTagPoints.end());
219        if (it != mActiveTagPoints.end())
220        {
221            if (tagPoint->getParent())
222                tagPoint->getParent()->removeChild(tagPoint);
223
224            mFreeTagPoints.splice(mFreeTagPoints.end(), mActiveTagPoints, it);
225        }
226    }
227        //-------------------------------------------------------------------------
228        const String& SkeletonInstance::getName(void) const
229        {
230                // delegate
231                return mSkeleton->getName();
232        }
233        //-------------------------------------------------------------------------
234        ResourceHandle SkeletonInstance::getHandle(void) const
235        {
236                // delegate
237                return mSkeleton->getHandle();
238        }
239        //-------------------------------------------------------------------------
240        const String& SkeletonInstance::getGroup(void)
241        {
242                // delegate
243                return mSkeleton->getGroup();
244        }
245
246
247}
248
Note: See TracBrowser for help on using the repository browser.