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
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"
32 #include "OgreTagPoint.h"
36 //-------------------------------------------------------------------------
37 SkeletonInstance::SkeletonInstance(const SkeletonPtr
& masterCopy
)
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.
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
,
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
)
115 if (source
->getName().empty())
117 newBone
= createBone(source
->getHandle());
121 newBone
= createBone(source
->getName(), source
->getHandle());
125 mRootBones
.push_back(newBone
);
129 parent
->addChild(newBone
);
131 newBone
->setOrientation(source
->getOrientation());
132 newBone
->setPosition(source
->getPosition());
133 newBone
->setScale(source
->getScale());
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
;
150 BoneIterator i
= mSkeleton
->getRootBoneIterator();
151 while (i
.hasMoreElements())
153 Bone
* b
= i
.getNext();
154 cloneBoneAndChildren(b
, 0);
155 b
->_update(true, false);
159 //-------------------------------------------------------------------------
160 void SkeletonInstance::unloadImpl(void)
162 Skeleton::unloadImpl();
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
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
)
189 if (mFreeTagPoints
.empty()) {
190 ret
= OGRE_NEW
TagPoint(mNextTagPointAutoHandle
++, this);
191 mActiveTagPoints
.push_back(ret
);
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();
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
231 return mSkeleton
->getName();
233 //-------------------------------------------------------------------------
234 ResourceHandle
SkeletonInstance::getHandle(void) const
237 return mSkeleton
->getHandle();
239 //-------------------------------------------------------------------------
240 const String
& SkeletonInstance::getGroup(void)
243 return mSkeleton
->getGroup();