Patch 2793067: fix trunk with OGRE_THREAD_SUPPORT=1 on non-Windows platforms (don...
[ogre3d.git] / OgreMain / src / OgreSkeletonInstance.cpp
blob5a9dc51cd485cb8557a9873fe087ca94ccb4a537
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
7 Copyright (c) 2000-2006 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22 http://www.gnu.org/copyleft/lesser.txt.
24 You may alternatively use this source under the terms of a specific version of
25 the OGRE Unrestricted License provided you have obtained such a license from
26 Torus Knot Software Ltd.
27 -----------------------------------------------------------------------------
29 #include "OgreStableHeaders.h"
30 #include "OgreSkeletonInstance.h"
31 #include "OgreBone.h"
32 #include "OgreTagPoint.h"
35 namespace Ogre {
36 //-------------------------------------------------------------------------
37 SkeletonInstance::SkeletonInstance(const SkeletonPtr& masterCopy)
38 : Skeleton()
39 , mSkeleton(masterCopy)
40 , mNextTagPointAutoHandle(0)
43 //-------------------------------------------------------------------------
44 SkeletonInstance::~SkeletonInstance()
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();
52 //-------------------------------------------------------------------------
53 unsigned short SkeletonInstance::getNumAnimations(void) const
55 return mSkeleton->getNumAnimations();
57 //-------------------------------------------------------------------------
58 Animation* SkeletonInstance::getAnimation(unsigned short index) const
60 return mSkeleton->getAnimation(index);
62 //-------------------------------------------------------------------------
63 Animation* SkeletonInstance::createAnimation(const String& name, Real length)
65 return mSkeleton->createAnimation(name, length);
67 //-------------------------------------------------------------------------
68 Animation* SkeletonInstance::getAnimation(const String& name,
69 const LinkedSkeletonAnimationSource** linker) const
71 return mSkeleton->getAnimation(name, linker);
73 //-------------------------------------------------------------------------
74 Animation* SkeletonInstance::_getAnimationImpl(const String& name,
75 const LinkedSkeletonAnimationSource** linker) const
77 return mSkeleton->_getAnimationImpl(name, linker);
79 //-------------------------------------------------------------------------
80 void SkeletonInstance::removeAnimation(const String& name)
82 mSkeleton->removeAnimation(name);
84 //-------------------------------------------------------------------------
85 void SkeletonInstance::addLinkedSkeletonAnimationSource(const String& skelName,
86 Real scale)
88 mSkeleton->addLinkedSkeletonAnimationSource(skelName, scale);
90 //-------------------------------------------------------------------------
91 void SkeletonInstance::removeAllLinkedSkeletonAnimationSources(void)
93 mSkeleton->removeAllLinkedSkeletonAnimationSources();
95 //-------------------------------------------------------------------------
96 Skeleton::LinkedSkeletonAnimSourceIterator
97 SkeletonInstance::getLinkedSkeletonAnimationSourceIterator(void) const
99 return mSkeleton->getLinkedSkeletonAnimationSourceIterator();
101 //-------------------------------------------------------------------------
102 void SkeletonInstance::_initAnimationState(AnimationStateSet* animSet)
104 mSkeleton->_initAnimationState(animSet);
106 //-------------------------------------------------------------------------
107 void SkeletonInstance::_refreshAnimationState(AnimationStateSet* animSet)
109 mSkeleton->_refreshAnimationState(animSet);
111 //-------------------------------------------------------------------------
112 void SkeletonInstance::cloneBoneAndChildren(Bone* source, Bone* parent)
114 Bone* newBone;
115 if (source->getName().empty())
117 newBone = createBone(source->getHandle());
119 else
121 newBone = createBone(source->getName(), source->getHandle());
123 if (parent == NULL)
125 mRootBones.push_back(newBone);
127 else
129 parent->addChild(newBone);
131 newBone->setOrientation(source->getOrientation());
132 newBone->setPosition(source->getPosition());
133 newBone->setScale(source->getScale());
135 // Process children
136 Node::ChildNodeIterator it = source->getChildIterator();
137 while (it.hasMoreElements())
139 cloneBoneAndChildren(static_cast<Bone*>(it.getNext()), newBone);
142 //-------------------------------------------------------------------------
143 void SkeletonInstance::loadImpl(void)
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())
153 Bone* b = i.getNext();
154 cloneBoneAndChildren(b, 0);
155 b->_update(true, false);
157 setBindingPose();
159 //-------------------------------------------------------------------------
160 void SkeletonInstance::unloadImpl(void)
162 Skeleton::unloadImpl();
164 // destroy TagPoints
165 for (TagPointList::const_iterator it = mActiveTagPoints.begin(); it != mActiveTagPoints.end(); ++it)
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 OGRE_DELETE tagPoint;
174 mActiveTagPoints.clear();
175 for (TagPointList::const_iterator it2 = mFreeTagPoints.begin(); it2 != mFreeTagPoints.end(); ++it2)
177 TagPoint* tagPoint = *it2;
178 OGRE_DELETE tagPoint;
180 mFreeTagPoints.clear();
183 //-------------------------------------------------------------------------
184 TagPoint* SkeletonInstance::createTagPointOnBone(Bone* bone,
185 const Quaternion &offsetOrientation,
186 const Vector3 &offsetPosition)
188 TagPoint* ret;
189 if (mFreeTagPoints.empty()) {
190 ret = OGRE_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);
205 ret->setPosition(offsetPosition);
206 ret->setOrientation(offsetOrientation);
207 ret->setScale(Vector3::UNIT_SCALE);
208 ret->setBindingPose();
209 bone->addChild(ret);
211 return ret;
213 //-------------------------------------------------------------------------
214 void SkeletonInstance::freeTagPoint(TagPoint* tagPoint)
216 TagPointList::iterator it =
217 std::find(mActiveTagPoints.begin(), mActiveTagPoints.end(), tagPoint);
218 assert(it != mActiveTagPoints.end());
219 if (it != mActiveTagPoints.end())
221 if (tagPoint->getParent())
222 tagPoint->getParent()->removeChild(tagPoint);
224 mFreeTagPoints.splice(mFreeTagPoints.end(), mActiveTagPoints, it);
227 //-------------------------------------------------------------------------
228 const String& SkeletonInstance::getName(void) const
230 // delegate
231 return mSkeleton->getName();
233 //-------------------------------------------------------------------------
234 ResourceHandle SkeletonInstance::getHandle(void) const
236 // delegate
237 return mSkeleton->getHandle();
239 //-------------------------------------------------------------------------
240 const String& SkeletonInstance::getGroup(void)
242 // delegate
243 return mSkeleton->getGroup();